diff options
Diffstat (limited to 'addressbook/gui/contact-editor')
23 files changed, 8256 insertions, 7269 deletions
diff --git a/addressbook/gui/contact-editor/.cvsignore b/addressbook/gui/contact-editor/.cvsignore deleted file mode 100644 index 6fd0b5075c..0000000000 --- a/addressbook/gui/contact-editor/.cvsignore +++ /dev/null @@ -1,8 +0,0 @@ -.deps -.libs -.pure -Makefile -Makefile.in -*.lo -*.la -contact-editor-test diff --git a/addressbook/gui/contact-editor/Makefile.am b/addressbook/gui/contact-editor/Makefile.am index fe7295bfe6..5307298a0f 100644 --- a/addressbook/gui/contact-editor/Makefile.am +++ b/addressbook/gui/contact-editor/Makefile.am @@ -1,48 +1,45 @@ -INCLUDES = \ - -I$(top_srcdir) \ - -I$(top_srcdir)/addressbook/ \ - -I$(top_srcdir)/addressbook/backend \ - -I$(top_builddir)/addressbook/backend \ - -I$(top_srcdir)/addressbook/gui/merging \ - -I$(top_srcdir)/widgets/e-table \ - -I$(top_builddir)/shell \ - -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \ - -DDATADIR=\""$(datadir)"\" \ - -DEVOLUTION_DATADIR=\""$(datadir)"\" \ - -DEVOLUTION_ICONSDIR=\""$(iconsdir)"\" \ - -DEVOLUTIONDIR=\""$(evolutiondir)"\" \ - -DG_LOG_DOMAIN=\"contact-editor\" \ - $(EVOLUTION_ADDRESSBOOK_CFLAGS) - -noinst_LIBRARIES = \ - libecontacteditor.a - -libecontacteditor_a_SOURCES = \ - e-contact-editor-address.c \ - e-contact-editor-address.h \ +privsolib_LTLIBRARIES = libecontacteditor.la + +libecontacteditor_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -I$(top_srcdir)/addressbook/ \ + -I$(top_srcdir)/addressbook/gui/merging \ + -I$(top_builddir)/shell \ + -DEVOLUTION_UIDIR=\""$(uidir)"\" \ + -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ + -DG_LOG_DOMAIN=\"contact-editor\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) + +libecontacteditor_la_SOURCES = \ + eab-editor.c \ + eab-editor.h \ e-contact-editor-fullname.c \ e-contact-editor-fullname.h \ e-contact-editor.c \ e-contact-editor.h \ - e-contact-save-as.c \ - e-contact-save-as.h \ e-contact-quick-add.c \ e-contact-quick-add.h -evolutiondir = $(datadir)/evolution - -evolution_DATA = arrow.png +libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) -iconsdir = $(datadir)/images/evolution +libecontacteditor_la_LIBADD = \ + $(top_builddir)/e-util/libevolution-util.la \ + $(top_builddir)/addressbook/util/libeabutil.la \ + $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ + $(top_builddir)/addressbook/gui/merging/libeabbookmerging.la \ + $(top_builddir)/addressbook/printing/libecontactprint.la \ + $(EVOLUTION_ADDRESSBOOK_LIBS) \ + $(EVOLUTION_DATA_SERVER_LIBS) \ + $(GNOME_PLATFORM_LIBS) \ + $(GTKHTML_LIBS) -gladedir = $(datadir)/evolution/glade +ui_DATA = \ + contact-editor.ui \ + fullname.ui -glade_DATA = \ - contact-editor.glade \ - fulladdr.glade \ - fullname.glade \ - file-exists.glade \ - e-contact-editor-confirm-delete.glade +EXTRA_DIST= $(ui_DATA) -EXTRA_DIST = $(evolution_DATA) \ - $(glade_DATA) +-include $(top_srcdir)/git.mk diff --git a/addressbook/gui/contact-editor/arrow.png b/addressbook/gui/contact-editor/arrow.png Binary files differdeleted file mode 100644 index b102356c78..0000000000 --- a/addressbook/gui/contact-editor/arrow.png +++ /dev/null diff --git a/addressbook/gui/contact-editor/contact-editor.glade b/addressbook/gui/contact-editor/contact-editor.glade deleted file mode 100644 index c8c880fa0c..0000000000 --- a/addressbook/gui/contact-editor/contact-editor.glade +++ /dev/null @@ -1,2537 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>Contact-editor</name> - <program_name>contact-editor</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>True</use_widget_names> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> - <backup_source_files>False</backup_source_files> -</project> - -<widget> - <class>GnomeDialog</class> - <name>dialog2</name> - <border_width>2</border_width> - <visible>False</visible> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox2</name> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area2</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button28</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button29</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_APPLY</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button30</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkTable</class> - <name>table2</name> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>2</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkEntry</class> - <name>entry2</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>0</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox1</name> - <homogeneous>False</homogeneous> - <spacing>2</spacing> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>True</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button31</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <label>_Add</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>button32</name> - <border_width>2</border_width> - <can_focus>True</can_focus> - <label>_Delete</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow1</name> - <height>200</height> - <hscrollbar_policy>GTK_POLICY_ALWAYS</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_ALWAYS</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>True</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkCList</class> - <name>clist1</name> - <can_focus>True</can_focus> - <columns>1</columns> - <column_widths>80</column_widths> - <selection_mode>GTK_SELECTION_SINGLE</selection_mode> - <show_titles>True</show_titles> - <shadow_type>GTK_SHADOW_NONE</shadow_type> - - <widget> - <class>GtkLabel</class> - <child_name>CList:title</child_name> - <name>label20</name> - <label>Phone Types</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeDialog</class> - <name>dialog-add-phone</name> - <visible>False</visible> - <title>New phone type</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>vbox2</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button43</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <label>_Add</label> - <stock_pixmap>GNOME_STOCK_PIXMAP_ADD</stock_pixmap> - </widget> - - <widget> - <class>GtkButton</class> - <name>button44</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkFrame</class> - <name>frame-add-phone</name> - <border_width>4</border_width> - <label>New phone type</label> - <label_xalign>0</label_xalign> - <shadow_type>GTK_SHADOW_ETCHED_IN</shadow_type> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkAlignment</class> - <name>alignment9</name> - <border_width>9</border_width> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - - <widget> - <class>GtkEntry</class> - <name>entry-add-phone</name> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - </widget> - </widget> -</widget> - -<widget> - <class>GnomeApp</class> - <name>contact editor</name> - <visible>False</visible> - <title>Contact Editor</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - <enable_layout_config>True</enable_layout_config> - - <widget> - <class>GnomeDock</class> - <child_name>GnomeApp:dock</child_name> - <name>dock1</name> - <allow_floating>True</allow_floating> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkNotebook</class> - <child_name>GnomeDock:contents</child_name> - <name>notebook-contact-editor</name> - <can_focus>True</can_focus> - <show_tabs>True</show_tabs> - <show_border>True</show_border> - <tab_pos>GTK_POS_TOP</tab_pos> - <scrollable>False</scrollable> - <tab_hborder>2</tab_hborder> - <tab_vborder>2</tab_vborder> - <popup_enable>False</popup_enable> - - <widget> - <class>GtkTable</class> - <name>table-contact-editor-general</name> - <border_width>7</border_width> - <rows>14</rows> - <columns>8</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkEntry</class> - <name>entry-phone1</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-phone2</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-phone3</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-phone4</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkText</class> - <name>text-address</name> - <width>1</width> - <height>1</height> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>5</top_attach> - <bottom_attach>9</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>button-fullname</name> - <can_focus>True</can_focus> - <label>Full _Name...</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment3</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>1</yscale> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-email1</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment5</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>6</left_attach> - <right_attach>7</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-phone4</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment7</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>6</left_attach> - <right_attach>7</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-phone2</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment8</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>6</left_attach> - <right_attach>7</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-phone1</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator4</name> - <child> - <left_attach>4</left_attach> - <right_attach>8</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>2</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment6</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>6</left_attach> - <right_attach>7</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-phone3</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-fullname</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-jobtitle</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-company</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-email1</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-web</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>8</top_attach> - <bottom_attach>9</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator5</name> - <child> - <left_attach>0</left_attach> - <right_attach>4</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>2</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkCombo</class> - <name>combo-file-as</name> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>True</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items></items> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry-file-as</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator6</name> - <child> - <left_attach>0</left_attach> - <right_attach>4</right_attach> - <top_attach>7</top_attach> - <bottom_attach>8</bottom_attach> - <xpad>0</xpad> - <ypad>2</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment-htmlmail</name> - <xalign>0.5</xalign> - <yalign>0</yalign> - <xscale>1</xscale> - <yscale>1</yscale> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>6</top_attach> - <bottom_attach>7</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>True</xshrink> - <yshrink>True</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton-htmlmail</name> - <can_focus>True</can_focus> - <label>Wants to receive _HTML mail</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment4</name> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>6</left_attach> - <right_attach>7</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-address</name> - <relief>GTK_RELIEF_NORMAL</relief> - - <widget> - <class>Placeholder</class> - </widget> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox1</name> - <child> - <left_attach>5</left_attach> - <right_attach>6</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-phone1</name> - <label>Business</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-phone1</focus_target> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox2</name> - <child> - <left_attach>5</left_attach> - <right_attach>6</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-phone2</name> - <label>Home</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-phone2</focus_target> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox3</name> - <child> - <left_attach>5</left_attach> - <right_attach>6</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-phone3</name> - <label>Business Fax</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-phone3</focus_target> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox4</name> - <child> - <left_attach>5</left_attach> - <right_attach>6</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-phone4</name> - <label>Mobile</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-phone4</focus_target> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox5</name> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-email1</name> - <label>Primary Email</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-email1</focus_target> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox-business</name> - <child> - <left_attach>5</left_attach> - <right_attach>6</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-address</name> - <label>Business</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>text-address</focus_target> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment2</name> - <xalign>0</xalign> - <yalign>0</yalign> - <xscale>0</xscale> - <yscale>0</yscale> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>9</top_attach> - <bottom_attach>10</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkCheckButton</class> - <name>checkbutton-mailingaddress</name> - <label>This is the _mailing address</label> - <active>False</active> - <draw_indicator>True</draw_indicator> - </widget> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator9</name> - <child> - <left_attach>0</left_attach> - <right_attach>4</right_attach> - <top_attach>11</top_attach> - <bottom_attach>12</bottom_attach> - <xpad>0</xpad> - <ypad>2</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator10</name> - <child> - <left_attach>4</left_attach> - <right_attach>8</right_attach> - <top_attach>11</top_attach> - <bottom_attach>12</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment-contacts</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>0</yscale> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>12</top_attach> - <bottom_attach>13</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-contacts</name> - <can_focus>True</can_focus> - <label>C_ontacts...</label> - <relief>GTK_RELIEF_NORMAL</relief> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment15</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>0</yscale> - <child> - <left_attach>7</left_attach> - <right_attach>8</right_attach> - <top_attach>12</top_attach> - <bottom_attach>13</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkEntry</class> - <name>entry-categories</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment16</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>0</yscale> - <child> - <left_attach>5</left_attach> - <right_attach>7</right_attach> - <top_attach>12</top_attach> - <bottom_attach>13</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkButton</class> - <name>button-categories</name> - <can_focus>True</can_focus> - <label>Ca_tegories...</label> - <relief>GTK_RELIEF_NORMAL</relief> - </widget> - </widget> - - <widget> - <class>GtkEventBox</class> - <name>eventbox7</name> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label-jobtitle</name> - <label>_Job title:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-jobtitle</focus_target> - </widget> - </widget> - - <widget> - <class>Custom</class> - <name>custom1</name> - <creation_function>e_create_image_widget</creation_function> - <string1>malehead.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:19:47 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom2</name> - <creation_function>e_create_image_widget</creation_function> - <string1>cellphone.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:02 GMT</last_modification_time> - <child> - <left_attach>4</left_attach> - <right_attach>5</right_attach> - <top_attach>0</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom3</name> - <creation_function>e_create_image_widget</creation_function> - <string1>envelope.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:19:51 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>5</top_attach> - <bottom_attach>7</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom4</name> - <creation_function>e_create_image_widget</creation_function> - <string1>house.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:06 GMT</last_modification_time> - <child> - <left_attach>4</left_attach> - <right_attach>5</right_attach> - <top_attach>5</top_attach> - <bottom_attach>10</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom5</name> - <creation_function>e_create_image_widget</creation_function> - <string1>evolution-contacts-plain.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:19:59 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>12</top_attach> - <bottom_attach>14</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom6</name> - <creation_function>e_create_image_widget</creation_function> - <string1>briefcase.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:09 GMT</last_modification_time> - <child> - <left_attach>4</left_attach> - <right_attach>5</right_attach> - <top_attach>12</top_attach> - <bottom_attach>14</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom10</name> - <creation_function>e_create_image_widget</creation_function> - <string1>globe.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:19:56 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>8</top_attach> - <bottom_attach>10</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-company</name> - <label>Organi_zation:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-company</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkButton</class> - <name>button-fulladdr</name> - <can_focus>True</can_focus> - <label>Add_ress...</label> - <relief>GTK_RELIEF_NORMAL</relief> - <child> - <left_attach>5</left_attach> - <right_attach>7</right_attach> - <top_attach>6</top_attach> - <bottom_attach>7</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment17</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>1</xscale> - <yscale>0</yscale> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>12</top_attach> - <bottom_attach>13</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkTable</class> - <name>table-contacts</name> - <rows>1</rows> - <columns>1</columns> - <homogeneous>False</homogeneous> - <row_spacing>0</row_spacing> - <column_spacing>0</column_spacing> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>accellabel-fileas</name> - <label>File A_s:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-file-as</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>accellabel-web</name> - <label>_Web page address:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-web</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>8</top_attach> - <bottom_attach>9</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label15</name> - <label>General</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkTable</class> - <name>table-contact-editor-details</name> - <border_width>7</border_width> - <rows>9</rows> - <columns>6</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label-department</name> - <label>D_epartment:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-department</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-office</name> - <label>_Office:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-office</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-profession</name> - <label>P_rofession:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-profession</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-nickname</name> - <label>_Nickname:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-nickname</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-spouse</name> - <label>S_pouse:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-spouse</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-birthday</name> - <label>Birthda_y:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>dateedit-birthday</focus_target> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-assistant</name> - <label>A_ssistant's name:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-assistant</focus_target> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-manager</name> - <label>_Manager's Name:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-manager</focus_target> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-anniversary</name> - <label>Anni_versary:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>dateedit-anniversary</focus_target> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-spouse</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-department</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-office</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-profession</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-nickname</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-assistant</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>4</left_attach> - <right_attach>6</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-manager</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>4</left_attach> - <right_attach>6</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator7</name> - <child> - <left_attach>0</left_attach> - <right_attach>6</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>2</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-comments</name> - <label>No_tes:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>text-comments</focus_target> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>7</top_attach> - <bottom_attach>8</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkHSeparator</class> - <name>hseparator8</name> - <child> - <left_attach>0</left_attach> - <right_attach>6</right_attach> - <top_attach>6</top_attach> - <bottom_attach>7</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom7</name> - <creation_function>e_create_image_widget</creation_function> - <string1>briefcase.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:13 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>custom8</name> - <creation_function>e_create_image_widget</creation_function> - <string1>malehead.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:16 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>4</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkScrolledWindow</class> - <name>scrolledwindow2</name> - <hscrollbar_policy>GTK_POLICY_AUTOMATIC</hscrollbar_policy> - <vscrollbar_policy>GTK_POLICY_AUTOMATIC</vscrollbar_policy> - <hupdate_policy>GTK_UPDATE_CONTINUOUS</hupdate_policy> - <vupdate_policy>GTK_UPDATE_CONTINUOUS</vupdate_policy> - <child> - <left_attach>1</left_attach> - <right_attach>6</right_attach> - <top_attach>8</top_attach> - <bottom_attach>9</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>True</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkText</class> - <name>text-comments</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text></text> - </widget> - </widget> - - <widget> - <class>Custom</class> - <name>custom9</name> - <creation_function>e_create_image_widget</creation_function> - <string1>globe.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:19 GMT</last_modification_time> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>7</top_attach> - <bottom_attach>9</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>dateedit-birthday</name> - <can_focus>True</can_focus> - <creation_function>e_contact_editor_create_date</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 05 Jun 2001 02:36:27 GMT</last_modification_time> - <child> - <left_attach>4</left_attach> - <right_attach>6</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>Custom</class> - <name>dateedit-anniversary</name> - <can_focus>True</can_focus> - <creation_function>e_contact_editor_create_date</creation_function> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Tue, 05 Jun 2001 02:36:32 GMT</last_modification_time> - <child> - <left_attach>4</left_attach> - <right_attach>6</right_attach> - <top_attach>5</top_attach> - <bottom_attach>6</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label16</name> - <label>Details</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - - <widget> - <class>GtkVBox</class> - <name>vbox3</name> - <homogeneous>False</homogeneous> - <spacing>0</spacing> - - <widget> - <class>GtkHBox</class> - <name>hbox1</name> - <border_width>7</border_width> - <homogeneous>False</homogeneous> - <spacing>4</spacing> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - </child> - - <widget> - <class>Custom</class> - <name>custom12</name> - <creation_function>e_create_image_widget</creation_function> - <string1>globe.png</string1> - <string2></string2> - <int1>0</int1> - <int2>0</int2> - <last_modification_time>Thu, 18 May 2000 12:20:13 GMT</last_modification_time> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label24</name> - <label>If this person publishes free/busy or other calendar information on the Internet, enter the address -of that information here.</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>7.45058e-09</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> - </widget> - - <widget> - <class>GtkAlignment</class> - <name>alignment18</name> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xscale>0.75</xscale> - <yscale>1</yscale> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkTable</class> - <name>table-contact-editor-collaboration</name> - <border_width>7</border_width> - <rows>2</rows> - <columns>2</columns> - <homogeneous>False</homogeneous> - <row_spacing>4</row_spacing> - <column_spacing>4</column_spacing> - - <widget> - <class>GtkLabel</class> - <name>label-caluri</name> - <label>_Public Calendar URL:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-caluri</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-fburl</name> - <label>F_ree/Busy URL:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-fburl</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-caluri</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-fburl</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - </widget> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <child_name>Notebook:tab</child_name> - <name>label21</name> - <label>Collaboration</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - </widget> - </widget> - </widget> - - <widget> - <class>GnomeAppBar</class> - <child_name>GnomeApp:appbar</child_name> - <name>appbar1</name> - <has_progress>True</has_progress> - <has_status>True</has_status> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - </widget> -</widget> - -</GTK-Interface> diff --git a/addressbook/gui/contact-editor/contact-editor.ui b/addressbook/gui/contact-editor/contact-editor.ui new file mode 100644 index 0000000000..e4714d1bf4 --- /dev/null +++ b/addressbook/gui/contact-editor/contact-editor.ui @@ -0,0 +1,2446 @@ +<?xml version="1.0"?> +<interface> + <requires lib="gtk+" version="2.16"/> + <!-- interface-requires evolution 0.0 --> + <!-- interface-naming-policy toplevel-contextual --> + <object class="GtkListStore" id="model1"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + </object> + <object class="GtkListStore" id="model2"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0">Work</col> + </row> + <row> + <col id="0">Personal</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model3"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0">Work</col> + </row> + <row> + <col id="0">Personal</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model4"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0">Work</col> + </row> + <row> + <col id="0">Personal</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model5"> + <columns> + <!-- column-name gchararray --> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0">Work</col> + </row> + <row> + <col id="0">Personal</col> + </row> + </data> + </object> + <object class="GtkDialog" id="contact editor"> + <property name="title" translatable="yes">Contact Editor</property> + <property name="window_position">center</property> + <property name="type_hint">dialog</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="dialog-vbox1"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkNotebook" id="notebook11"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="border_width">12</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="min-content-width">320</property> + <property name="min-content-height">240</property> + <child> + <object class="GtkViewport" id="viewport1"> + <property name="visible">True</property> + <property name="resize_mode">queue</property> + <property name="shadow-type">none</property> + <child> + <object class="GtkVBox" id="vbox33"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="orientation">vertical</property> + <property name="spacing">1</property> + <child> + <object class="GtkHBox" id="hbox55"> + <property name="visible">True</property> + <property name="spacing">6</property> + <child> + <object class="GtkButton" id="button-image"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <child internal-child="accessible"> + <object class="AtkObject" id="button-image-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Image</property> + </object> + </child> + <child> + <object class="EImageChooser" type-func="e_image_chooser_get_type" id="image-chooser"> + <property name="visible">True</property> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkTable" id="table83"> + <property name="visible">True</property> + <property name="n_rows">3</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="label-nickname"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">Nic_kname:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-nickname</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-fullname"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">fullname</property> + <accessibility> + <relation type="labelled-by" target="button-fullname"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="accellabel-fileas"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_File under:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">combo-file-as</property> + </object> + <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> + <object class="GtkLabel" id="where-label"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Where:</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="GtkButton" id="button-categories"> + <property name="label" translatable="yes">Ca_tegories...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-categories"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="button-categories"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-nickname"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">nickname</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="EClientComboBox" type-func="e_client_combo_box_get_type" id="client-combo-box"> + <property name="extension-name">Address Book</property> + <property name="show-colors">False</property> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</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> + <child> + <object class="GtkButton" id="button-fullname"> + <property name="label" translatable="yes">Full _Name...</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combo-file-as"> + <property name="visible">True</property> + <property name="has-entry">True</property> + <property name="entry-text-column">0</property> + <property name="model">model1</property> + <property name="name">file-as</property> + </object> + <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> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkHSeparator" id="hseparator10"> + <property name="visible">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="padding">6</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox34"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <property name="spacing">10</property> + <child> + <object class="GtkFrame" id="frame65"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkTable" id="email-table"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="n_rows">3</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-email-3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">email-3</property> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-email-1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">email-1</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-email-2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">email-2</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-email-4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="name">email-4</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="checkbutton-htmlmail"> + <property name="label" translatable="yes">_Wants to receive HTML mail</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-email-1"> + <property name="visible">True</property> + <property name="model">model2</property> + <child> + <object class="GtkCellRendererText" id="renderer2"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-email-3"> + <property name="visible">True</property> + <property name="model">model3</property> + <child> + <object class="GtkCellRendererText" id="renderer3"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <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> + <child> + <object class="GtkComboBox" id="combobox-email-2"> + <property name="visible">True</property> + <property name="model">model4</property> + <child> + <object class="GtkCellRendererText" id="renderer4"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-email-4"> + <property name="visible">True</property> + <property name="model">model5</property> + <child> + <object class="GtkCellRendererText" id="renderer5"/> + <attributes> + <attribute name="text">0</attribute> + </attributes> + </child> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</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> + </object> + </child> + <child type="label"> + <object class="GtkHBox" id="hbox561"> + <property name="visible">True</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel" id="label400"> + <property name="visible">True</property> + <property name="label" translatable="yes">Email</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-mail-expand"> + <property name="width_request">20</property> + <property name="height_request">20</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="relief">none</property> + <child internal-child="accessible"> + <object class="AtkObject" id="button-mail-expand-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Email</property> + </object> + </child> + <child> + <object class="GtkArrow" id="arrow-mail-expand"> + <property name="visible">True</property> + <property name="shadow_type">none</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkVBox" id="vbox38"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkFrame" id="frame64"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkVBox" id="vbox37"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkTable" id="table84"> + <property name="visible">True</property> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-phone-1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-1"> + <property name="visible">True</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-3"> + <property name="visible">True</property> + </object> + <packing> + <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> + <child> + <object class="GtkComboBox" id="combobox-phone-2"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-4"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</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> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkTable" id="table-phone-extended"> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-phone-5"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-7"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-6"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-phone-8"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-5"> + <property name="visible">True</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-7"> + <property name="visible">True</property> + </object> + <packing> + <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> + <child> + <object class="GtkComboBox" id="combobox-phone-6"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-phone-8"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</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> + </object> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkHBox" id="hbox56"> + <property name="visible">True</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel" id="label399"> + <property name="visible">True</property> + <property name="label" translatable="yes">Telephone</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-phone-expand"> + <property name="width_request">20</property> + <property name="height_request">20</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="relief">none</property> + <child internal-child="accessible"> + <object class="AtkObject" id="button-phone-expand-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Telephone</property> + </object> + </child> + <child> + <object class="GtkArrow" id="arrow-phone-expand"> + <property name="visible">True</property> + <property name="shadow_type">none</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame66"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkTable" id="table86"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-im-name-1"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <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> + <object class="GtkEntry" id="entry-im-name-3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-im-name-2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-im-name-4"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-im-service-1"> + <property name="visible">True</property> + </object> + <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">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-im-service-3"> + <property name="visible">True</property> + </object> + <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">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-im-service-2"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">0</property> + <property name="bottom_attach">1</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="combobox-im-service-4"> + <property name="visible">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</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> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label404"> + <property name="visible">True</property> + <property name="label" translatable="yes">Instant Messaging</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + </child> + <child type="tab"> + <object class="GtkLabel" id="label405"> + <property name="visible">True</property> + <property name="label" translatable="yes">Contact</property> + </object> + <packing> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow-size-leader"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="min-content-width">320</property> + <property name="min-content-height">240</property> + <child> + <object class="GtkViewport" id="viewport2"> + <property name="visible">True</property> + <property name="shadow-type">none</property> + <property name="resize_mode">queue</property> + <child> + <object class="GtkVBox" id="vbox-size-leader"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="orientation">vertical</property> + <property name="spacing">12</property> + <child> + <object class="GtkFrame" id="frame67"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkTable" id="table87"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="n_rows">5</property> + <property name="n_columns">2</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="accellabel-homepage"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Home Page:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-homepage</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-caluri"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Calendar:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-caluri</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-fburl"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Free/Busy:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-fburl</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-videourl"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Video Chat:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-videourl</property> + </object> + <packing> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-homepage"> + <property name="visible">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="entry-homepage-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Home Page:</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-caluri"> + <property name="visible">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="entry-caluri-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Calendar:</property> + </object> + </child> + </object> + <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="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-fburl"> + <property name="visible">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="entry-fburl-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Free/Busy:</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-videourl"> + <property name="visible">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="entry-videourl-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Video Chat:</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-weblog"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Blog:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-weblog</property> + </object> + <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> + <object class="EUrlEntry" type-func="e_url_entry_get_type" id="entry-weblog"> + <property name="visible">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="entry-weblog-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes" comments="Translators: an accessibility name">Blog:</property> + </object> + </child> + </object> + <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> + </object> + </child> + <child type="label"> + <object class="GtkHBox" id="hbox5617"> + <property name="visible">True</property> + <property name="spacing">4</property> + <child> + <object class="GtkLabel" id="label410"> + <property name="visible">True</property> + <property name="label" translatable="yes">Web Addresses</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-web-expand"> + <property name="width_request">20</property> + <property name="height_request">20</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="relief">none</property> + <child internal-child="accessible"> + <object class="AtkObject" id="button-web-expand-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Web addresses</property> + </object> + </child> + <child> + <object class="GtkArrow" id="arrow-web-expand"> + <property name="visible">True</property> + <property name="shadow_type">none</property> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame68"> + <property name="visible">True</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkTable" id="table88"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="n_rows">3</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="label-profession"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Profession:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-profession</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-profession"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-profession"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-jobtitle"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes" context="Job">_Title:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-jobtitle</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-jobtitle"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-jobtitle"/> + </accessibility> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-company"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Company:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-company</property> + </object> + <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> + <object class="GtkEntry" id="entry-company"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-company"/> + </accessibility> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-department"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Department:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-department</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="GtkEntry" id="entry-department"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-department"/> + </accessibility> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-manager"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Manager:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-manager</property> + </object> + <packing> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-manager"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-manager"/> + </accessibility> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-assistant"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Assistant:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-assistant</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-assistant"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-assistant"/> + </accessibility> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label417"> + <property name="visible">True</property> + <property name="label" translatable="yes">Job</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkExpander" id="expander-personal-misc"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <child> + <object class="GtkTable" id="table89"> + <property name="visible">True</property> + <property name="border_width">12</property> + <property name="n_rows">2</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkLabel" id="label-office"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Office:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-office</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-spouse"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Spouse:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-spouse</property> + </object> + <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> + <object class="GtkEntry" id="entry-office"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-office"/> + </accessibility> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-spouse"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <accessibility> + <relation type="labelled-by" target="label-spouse"/> + </accessibility> + </object> + <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="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-birthday"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="label" translatable="yes">_Birthday:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">dateedit-birthday</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-anniversary"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Anniversary:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">dateedit-anniversary</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="EDateEdit" type-func="e_date_edit_get_type" id="dateedit-anniversary"> + <property name="visible">True</property> + <property name="allow_no_date_set">True</property> + <property name="show_time">False</property> + <property name="twodigit_year_can_future">False</property> + <property name="set_none">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="dateedit-anniversary-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Anniversary</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</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> + <child> + <object class="EDateEdit" type-func="e_date_edit_get_type" id="dateedit-birthday"> + <property name="visible">True</property> + <property name="allow_no_date_set">True</property> + <property name="show_time">False</property> + <property name="twodigit_year_can_future">False</property> + <property name="set_none">True</property> + <child internal-child="accessible"> + <object class="AtkObject" id="dateedit-birthday-atkobject"> + <property name="AtkObject::accessible-name" translatable="yes">Birthday</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label421"> + <property name="visible">True</property> + <property name="label" translatable="yes">Miscellaneous</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="label422"> + <property name="visible">True</property> + <property name="label" translatable="yes">Personal Information</property> + </object> + <packing> + <property name="position">1</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow3"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="min-content-width">320</property> + <property name="min-content-height">240</property> + <child> + <object class="GtkViewport" id="viewport3"> + <property name="visible">True</property> + <property name="resize_mode">queue</property> + <property name="shadow-type">none</property> + <child> + <object class="GtkVBox" id="vbox39"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <object class="GtkFrame" id="frame72"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment1"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="yalign">0.15000000596046448</property> + <property name="yscale">0.69999998807907104</property> + <property name="left_padding">19</property> + <property name="right_padding">10</property> + <child> + <object class="GtkHBox" id="hbox59"> + <property name="visible">True</property> + <child> + <object class="GtkTable" id="table-home-address"> + <property name="visible">True</property> + <property name="n_rows">4</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow-home-address"> + <property name="width_request">193</property> + <property name="height_request">69</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="textview-home-address"> + <property name="height_request">25</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="accepts_tab">False</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-home-city"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-city"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_City:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-home-city</property> + <property name="single_line_mode">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-home-zip"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-zip"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Zip/Postal Code:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-home-zip</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="GtkEntry" id="entry-home-state"> + <property name="width_request">256</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-state"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_State/Province:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-home-state</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-home-country"> + <property name="width_request">163</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-country"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="ypad">4</property> + <property name="label" translatable="yes">_Country:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-home-country</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-home-pobox"> + <property name="width_request">100</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-pobox"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_PO Box:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-home-pobox</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-home-address"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Address:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">textview-home-address</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="frame73"> + <property name="visible">True</property> + <property name="xalign">0.41999998688697815</property> + <property name="label" translatable="yes">Home</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkFrame" id="frame77"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="alignment6"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="yalign">0.15000000596046448</property> + <property name="yscale">0.69999998807907104</property> + <property name="left_padding">19</property> + <property name="right_padding">10</property> + <child> + <object class="GtkHBox" id="hbox98"> + <property name="visible">True</property> + <child> + <object class="GtkTable" id="table-work-address"> + <property name="visible">True</property> + <property name="n_rows">4</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow-work-address"> + <property name="width_request">193</property> + <property name="height_request">69</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="textview-work-address"> + <property name="height_request">25</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="accepts_tab">False</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-work-city"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-city"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_City:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-work-city</property> + <property name="single_line_mode">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-address"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Address:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">textview-work-address</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-work-zip"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-zip"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Zip/Postal Code:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-work-zip</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="GtkEntry" id="entry-work-state"> + <property name="width_request">256</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-state"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_State/Province:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-work-state</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-work-country"> + <property name="width_request">163</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-country"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="ypad">4</property> + <property name="label" translatable="yes">_Country:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-work-country</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-work-pobox"> + <property name="width_request">100</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-work-pobox"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_PO Box:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-work-pobox</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label460"> + <property name="visible">True</property> + <property name="xalign">0.41999998688697815</property> + <property name="label" translatable="yes">Work</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkExpander" id="expander-address-other"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="border_width">6</property> + <child> + <object class="GtkAlignment" id="alignment7"> + <property name="visible">True</property> + <property name="border_width">6</property> + <property name="yalign">0.15000000596046448</property> + <property name="yscale">0.69999998807907104</property> + <property name="left_padding">19</property> + <property name="right_padding">10</property> + <child> + <object class="GtkHBox" id="hbox103"> + <property name="visible">True</property> + <child> + <object class="GtkTable" id="table-other-address"> + <property name="visible">True</property> + <property name="n_rows">4</property> + <property name="n_columns">4</property> + <property name="column_spacing">6</property> + <property name="row_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-other-city"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-city"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_City:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-other-city</property> + <property name="single_line_mode">True</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-address"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Address:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">textview-other-address</property> + </object> + <packing> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-other-zip"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-zip"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_Zip/Postal Code:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-other-zip</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <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> + <object class="GtkEntry" id="entry-other-state"> + <property name="width_request">256</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-state"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_State/Province:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-other-state</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-other-country"> + <property name="width_request">163</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">3</property> + <property name="right_attach">4</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-country"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="ypad">4</property> + <property name="label" translatable="yes">_Country:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-other-country</property> + </object> + <packing> + <property name="left_attach">2</property> + <property name="right_attach">3</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-other-pobox"> + <property name="width_request">100</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-other-pobox"> + <property name="visible">True</property> + <property name="xalign">1</property> + <property name="label" translatable="yes">_PO Box:</property> + <property name="use_underline">True</property> + <property name="mnemonic_widget">entry-other-pobox</property> + </object> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow-other-address"> + <property name="width_request">193</property> + <property name="height_request">69</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="textview-other-address"> + <property name="height_request">25</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="accepts_tab">False</property> + </object> + </child> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <placeholder/> + </child> + <child> + <placeholder/> + </child> + </object> + <packing> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="label467"> + <property name="visible">True</property> + <property name="xalign">0.41999998688697815</property> + <property name="label" translatable="yes">Other</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="position">2</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="label437"> + <property name="visible">True</property> + <property name="label" translatable="yes">Mailing Address</property> + </object> + <packing> + <property name="position">2</property> + <property name="tab_fill">False</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow41"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="border_width">12</property> + <property name="hscrollbar_policy">automatic</property> + <property name="vscrollbar_policy">automatic</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTextView" id="text-comments"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </object> + </child> + </object> + <packing> + <property name="position">3</property> + </packing> + </child> + <child type="tab"> + <object class="GtkLabel" id="label468"> + <property name="visible">True</property> + <property name="label" translatable="yes">Notes</property> + </object> + <packing> + <property name="position">3</property> + <property name="tab_fill">False</property> + </packing> + </child> + </object> + <packing> + <property name="expand">True</property> + <property name="position">1</property> + </packing> + </child> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="dialog-action_area1"> + <property name="visible">True</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button-help"> + <property name="label">gtk-help</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-cancel"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button-ok"> + <property name="label">gtk-save</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="can_default">True</property> + <property name="has_default">True</property> + <property name="receives_default">False</property> + <property name="use_stock">True</property> + <accelerator key="s" modifiers="GDK_CONTROL_MASK" signal="clicked"/> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="-11">button-help</action-widget> + <action-widget response="-6">button-cancel</action-widget> + <action-widget response="-5">button-ok</action-widget> + </action-widgets> + </object> +</interface> diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.c b/addressbook/gui/contact-editor/e-contact-editor-address.c deleted file mode 100644 index dd9405816f..0000000000 --- a/addressbook/gui/contact-editor/e-contact-editor-address.c +++ /dev/null @@ -1,575 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-contact-editor-address.c - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include <e-contact-editor-address.h> - -#include <glib.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnomeui/gnome-window-icon.h> -#include <libgnome/gnome-util.h> -#include <gal/widgets/e-unicode.h> -#include <gal/widgets/e-gui-utils.h> -#include <gtk/gtkcombo.h> -#include <string.h> -#include <stdlib.h> -#include <locale.h> - -static void e_contact_editor_address_init (EContactEditorAddress *card); -static void e_contact_editor_address_class_init (EContactEditorAddressClass *klass); -static void e_contact_editor_address_set_arg (GtkObject *o, GtkArg *arg, guint arg_id); -static void e_contact_editor_address_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void e_contact_editor_address_destroy (GtkObject *object); - -static void fill_in_info(EContactEditorAddress *editor); -static void extract_info(EContactEditorAddress *editor); - -static GnomeDialogClass *parent_class = NULL; - -/* The arguments we take */ -enum { - ARG_0, - ARG_ADDRESS, - ARG_IS_READ_ONLY -}; - -GtkType -e_contact_editor_address_get_type (void) -{ - static GtkType contact_editor_address_type = 0; - - if (!contact_editor_address_type) - { - static const GtkTypeInfo contact_editor_address_info = - { - "EContactEditorAddress", - sizeof (EContactEditorAddress), - sizeof (EContactEditorAddressClass), - (GtkClassInitFunc) e_contact_editor_address_class_init, - (GtkObjectInitFunc) e_contact_editor_address_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - contact_editor_address_type = gtk_type_unique (gnome_dialog_get_type (), &contact_editor_address_info); - } - - return contact_editor_address_type; -} - -static void -e_contact_editor_address_class_init (EContactEditorAddressClass *klass) -{ - GtkObjectClass *object_class; - GnomeDialogClass *dialog_class; - - object_class = (GtkObjectClass*) klass; - dialog_class = (GnomeDialogClass *) klass; - - parent_class = gtk_type_class (gnome_dialog_get_type ()); - - gtk_object_add_arg_type ("EContactEditorAddress::address", GTK_TYPE_POINTER, - GTK_ARG_READWRITE, ARG_ADDRESS); - gtk_object_add_arg_type ("EContactEditorAddress::editable", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_IS_READ_ONLY); - - object_class->set_arg = e_contact_editor_address_set_arg; - object_class->get_arg = e_contact_editor_address_get_arg; - object_class->destroy = e_contact_editor_address_destroy; -} - -static GList * -add_to_tab_order(GList *list, GladeXML *gui, char *name) -{ - GtkWidget *widget = glade_xml_get_widget(gui, name); - return g_list_prepend(list, widget); -} - -static void -setup_tab_order(GladeXML *gui) -{ - GtkWidget *container; - GList *list = NULL; - - container = glade_xml_get_widget(gui, "table-checkaddress"); - - if (container) { - list = add_to_tab_order(list, gui, "entry-city"); - list = add_to_tab_order(list, gui, "entry-region"); - list = add_to_tab_order(list, gui, "entry-code"); - list = add_to_tab_order(list, gui, "combo-country"); - list = g_list_reverse(list); - e_container_change_tab_order(GTK_CONTAINER(container), list); - g_list_free(list); - } -} - -static char * countries [] = { - N_("United States"), - N_("Afghanistan"), - N_("Albania"), - N_("Algeria"), - N_("American Samoa"), - N_("Andorra"), - N_("Angola"), - N_("Anguilla"), - N_("Antarctica"), - N_("Antigua And Barbuda"), - N_("Argentina"), - N_("Armenia"), - N_("Aruba"), - N_("Australia"), - N_("Austria"), - N_("Azerbaijan"), - N_("Bahamas"), - N_("Bahrain"), - N_("Bangladesh"), - N_("Barbados"), - N_("Belarus"), - N_("Belgium"), - N_("Belize"), - N_("Benin"), - N_("Bermuda"), - N_("Bhutan"), - N_("Bolivia"), - N_("Bosnia And Herzegowina"), - N_("Botswana"), - N_("Bouvet Island"), - N_("Brazil"), - N_("British Indian Ocean Territory"), - N_("Brunei Darussalam"), - N_("Bulgaria"), - N_("Burkina Faso"), - N_("Burundi"), - N_("Cambodia"), - N_("Cameroon"), - N_("Canada"), - N_("Cape Verde"), - N_("Cayman Islands"), - N_("Central African Republic"), - N_("Chad"), - N_("Chile"), - N_("China"), - N_("Christmas Island"), - N_("Cocos (Keeling) Islands"), - N_("Colombia"), - N_("Comoros"), - N_("Congo"), - N_("Congo"), - N_("Cook Islands"), - N_("Costa Rica"), - N_("Cote d'Ivoire"), - N_("Croatia"), - N_("Cuba"), - N_("Cyprus"), - N_("Czech Republic"), - N_("Denmark"), - N_("Djibouti"), - N_("Dominica"), - N_("Dominican Republic"), - N_("East Timor"), - N_("Ecuador"), - N_("Egypt"), - N_("El Salvador"), - N_("Equatorial Guinea"), - N_("Eritrea"), - N_("Estonia"), - N_("Ethiopia"), - N_("Falkland Islands"), - N_("Faroe Islands"), - N_("Fiji"), - N_("Finland"), - N_("France"), - N_("French Guiana"), - N_("French Polynesia"), - N_("French Southern Territories"), - N_("Gabon"), - N_("Gambia"), - N_("Georgia"), - N_("Germany"), - N_("Ghana"), - N_("Gibraltar"), - N_("Greece"), - N_("Greenland"), - N_("Grenada"), - N_("Guadeloupe"), - N_("Guam"), - N_("Guatemala"), - N_("Guinea"), - N_("Guinea-bissau"), - N_("Guyana"), - N_("Haiti"), - N_("Heard And McDonald Islands"), - N_("Holy See"), - N_("Honduras"), - N_("Hong Kong"), - N_("Hungary"), - N_("Iceland"), - N_("India"), - N_("Indonesia"), - N_("Ireland"), - N_("Israel"), - N_("Italy"), - N_("Jamaica"), - N_("Japan"), - N_("Jordan"), - N_("Kazakhstan"), - N_("Kenya"), - N_("Kiribati"), - N_("Korea, Republic Of"), - N_("Kuwait"), - N_("Kyrgyzstan"), - N_("Laos"), - N_("Latvia"), - N_("Lebanon"), - N_("Lesotho"), - N_("Liberia"), - N_("Liechtenstein"), - N_("Lithuania"), - N_("Luxembourg"), - N_("Macau"), - N_("Macedonia"), - N_("Madagascar"), - N_("Malawi"), - N_("Malaysia"), - N_("Maldives"), - N_("Mali"), - N_("Malta"), - N_("Marshall Islands"), - N_("Martinique"), - N_("Mauritania"), - N_("Mauritius"), - N_("Mayotte"), - N_("Mexico"), - N_("Micronesia"), - N_("Moldova, Republic Of"), - N_("Monaco"), - N_("Mongolia"), - N_("Montserrat"), - N_("Morocco"), - N_("Mozambique"), - N_("Myanmar"), - N_("Namibia"), - N_("Nauru"), - N_("Nepal"), - N_("Netherlands"), - N_("Netherlands Antilles"), - N_("New Caledonia"), - N_("New Zealand"), - N_("Nicaragua"), - N_("Niger"), - N_("Nigeria"), - N_("Niue"), - N_("Norfolk Island"), - N_("Northern Mariana Islands"), - N_("Norway"), - N_("Oman"), - N_("Pakistan"), - N_("Palau"), - N_("Palestinian Territory"), - N_("Panama"), - N_("Papua New Guinea"), - N_("Paraguay"), - N_("Peru"), - N_("Philippines"), - N_("Pitcairn"), - N_("Poland"), - N_("Portugal"), - N_("Puerto Rico"), - N_("Qatar"), - N_("Reunion"), - N_("Romania"), - N_("Russian Federation"), - N_("Rwanda"), - N_("Saint Kitts And Nevis"), - N_("Saint Lucia"), - N_("Saint Vincent And The Grena-dines"), - N_("Samoa"), - N_("San Marino"), - N_("Sao Tome And Principe"), - N_("Saudi Arabia"), - N_("Senegal"), - N_("Seychelles"), - N_("Sierra Leone"), - N_("Singapore"), - N_("Slovakia"), - N_("Slovenia"), - N_("Solomon Islands"), - N_("Somalia"), - N_("South Africa"), - N_("South Georgia And The South Sandwich Islands"), - N_("Spain"), - N_("Sri Lanka"), - N_("St. Helena"), - N_("St. Pierre And Miquelon"), - N_("Sudan"), - N_("Suriname"), - N_("Svalbard And Jan Mayen Islands"), - N_("Swaziland"), - N_("Sweden"), - N_("Switzerland"), - N_("Taiwan"), - N_("Tajikistan"), - N_("Tanzania, United Republic Of"), - N_("Thailand"), - N_("Togo"), - N_("Tokelau"), - N_("Tonga"), - N_("Trinidad And Tobago"), - N_("Tunisia"), - N_("Turkey"), - N_("Turkmenistan"), - N_("Turks And Caicos Islands"), - N_("Tuvalu"), - N_("Uganda"), - N_("Ukraine"), - N_("United Arab Emirates"), - N_("United Kingdom"), - N_("United States Minor Outlying Islands"), - N_("Uruguay"), - N_("Uzbekistan"), - N_("Vanuatu"), - N_("Venezuela"), - N_("Viet Nam"), - N_("Virgin Islands, British"), - N_("Virgin Islands, U.S."), - N_("Wallis And Futuna Islands"), - N_("Western Sahara"), - N_("Yemen"), - N_("Yugoslavia"), - N_("Zambia"), - N_("Zimbabwe"), - NULL -}; - -static int -compare_func (const void *voida, const void *voidb) -{ - char * const *stringa = voida, * const *stringb = voidb; - - return strcoll (*stringa, *stringb); -} - -static void -fill_in_countries (GladeXML *gui) -{ - GtkCombo *combo; - combo = (GtkCombo *) glade_xml_get_widget(gui, "combo-country"); - if (combo && GTK_IS_COMBO (combo)) { - static gboolean sorted = FALSE; - static GList *country_list; - if (!sorted) { - int i; - char *locale; - - for (i = 0; countries[i]; i++) { - countries[i] = _(countries[i]); - } - - locale = setlocale (LC_COLLATE, NULL); - qsort (countries + 1, i - 1, sizeof (countries[0]), compare_func); - country_list = NULL; - for (i = 0; countries[i]; i++) { - country_list = g_list_prepend (country_list, countries[i]); - } - country_list = g_list_reverse (country_list); - sorted = TRUE; - } - gtk_combo_set_popdown_strings (combo, country_list); - } -} - -static void -e_contact_editor_address_init (EContactEditorAddress *e_contact_editor_address) -{ - GladeXML *gui; - GtkWidget *widget; - char *icon_path; - - gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_address), - GNOME_STOCK_BUTTON_OK); - - gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_address), - GNOME_STOCK_BUTTON_CANCEL); - - gtk_window_set_policy(GTK_WINDOW(e_contact_editor_address), FALSE, TRUE, FALSE); - - e_contact_editor_address->address = NULL; - - gui = glade_xml_new (EVOLUTION_GLADEDIR "/fulladdr.glade", NULL); - e_contact_editor_address->gui = gui; - - setup_tab_order (gui); - fill_in_countries (gui); - - widget = glade_xml_get_widget(gui, "dialog-checkaddress"); - gtk_window_set_title (GTK_WINDOW (e_contact_editor_address), - GTK_WINDOW (widget)->title); - - widget = glade_xml_get_widget(gui, "table-checkaddress"); - gtk_widget_ref(widget); - gtk_container_remove(GTK_CONTAINER(widget->parent), widget); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (e_contact_editor_address)->vbox), widget, TRUE, TRUE, 0); - gtk_widget_unref(widget); - - icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png"); - gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor_address), icon_path); - g_free (icon_path); -} - -void -e_contact_editor_address_destroy (GtkObject *object) -{ - EContactEditorAddress *e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS(object); - - if (e_contact_editor_address->gui) - gtk_object_unref(GTK_OBJECT(e_contact_editor_address->gui)); - e_card_delivery_address_unref(e_contact_editor_address->address); -} - -GtkWidget* -e_contact_editor_address_new (const ECardDeliveryAddress *address) -{ - GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_editor_address_get_type ())); - gtk_object_set (GTK_OBJECT(widget), - "address", address, - NULL); - return widget; -} - -static void -e_contact_editor_address_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - EContactEditorAddress *e_contact_editor_address; - - e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS (o); - - switch (arg_id){ - case ARG_ADDRESS: - e_card_delivery_address_unref(e_contact_editor_address->address); - e_contact_editor_address->address = e_card_delivery_address_copy(GTK_VALUE_POINTER (*arg)); - fill_in_info(e_contact_editor_address); - break; - case ARG_IS_READ_ONLY: { - int i; - char *entry_names[] = { - "entry-street", - "entry-city", - "entry-ext", - "entry-po", - "entry-region", - "combo-country", - "entry-code", - NULL - }; - e_contact_editor_address->editable = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - for (i = 0; entry_names[i] != NULL; i ++) { - GtkWidget *w = glade_xml_get_widget(e_contact_editor_address->gui, entry_names[i]); - if (GTK_IS_ENTRY (w)) { - gtk_entry_set_editable (GTK_ENTRY (w), - e_contact_editor_address->editable); - } - else if (GTK_IS_COMBO (w)) { - gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (w)->entry), - e_contact_editor_address->editable); - gtk_widget_set_sensitive (GTK_COMBO (w)->button, e_contact_editor_address->editable); - } - } - break; - } - } -} - -static void -e_contact_editor_address_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) -{ - EContactEditorAddress *e_contact_editor_address; - - e_contact_editor_address = E_CONTACT_EDITOR_ADDRESS (object); - - switch (arg_id) { - case ARG_ADDRESS: - extract_info(e_contact_editor_address); - GTK_VALUE_POINTER (*arg) = e_card_delivery_address_ref(e_contact_editor_address->address); - break; - case ARG_IS_READ_ONLY: - GTK_VALUE_BOOL (*arg) = e_contact_editor_address->editable ? TRUE : FALSE; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static void -fill_in_field(EContactEditorAddress *editor, char *field, char *string) -{ - GtkEditable *editable = GTK_EDITABLE(glade_xml_get_widget(editor->gui, field)); - if (editable) { - e_utf8_gtk_editable_set_text(editable, string); - } -} - -static void -fill_in_info(EContactEditorAddress *editor) -{ - ECardDeliveryAddress *address = editor->address; - if (address) { - fill_in_field(editor, "entry-street" , address->street ); - fill_in_field(editor, "entry-po" , address->po ); - fill_in_field(editor, "entry-ext" , address->ext ); - fill_in_field(editor, "entry-city" , address->city ); - fill_in_field(editor, "entry-region" , address->region ); - fill_in_field(editor, "entry-code" , address->code ); - fill_in_field(editor, "entry-country", address->country); - } -} - -static char * -extract_field(EContactEditorAddress *editor, char *field) -{ - GtkEditable *editable = GTK_EDITABLE(glade_xml_get_widget(editor->gui, field)); - if (editable) - return e_utf8_gtk_editable_get_text(editable); - else - return NULL; -} - -static void -extract_info(EContactEditorAddress *editor) -{ - ECardDeliveryAddress *address = editor->address; - if (!address) { - address = e_card_delivery_address_new(); - editor->address = address; - } - address->street = extract_field(editor, "entry-street" ); - address->po = extract_field(editor, "entry-po" ); - address->ext = extract_field(editor, "entry-ext" ); - address->city = extract_field(editor, "entry-city" ); - address->region = extract_field(editor, "entry-region" ); - address->code = extract_field(editor, "entry-code" ); - address->country = extract_field(editor, "entry-country"); -} diff --git a/addressbook/gui/contact-editor/e-contact-editor-address.h b/addressbook/gui/contact-editor/e-contact-editor-address.h deleted file mode 100644 index ff29c5b7ec..0000000000 --- a/addressbook/gui/contact-editor/e-contact-editor-address.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-contact-editor-address.h - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __E_CONTACT_EDITOR_ADDRESS_H__ -#define __E_CONTACT_EDITOR_ADDRESS_H__ - -#include <libgnomeui/gnome-dialog.h> -#include <glade/glade.h> -#include <ebook/e-card.h> - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -/* EContactEditorAddress - A dialog displaying information about a contact. - * - * The following arguments are available: - * - * name type read/write description - * -------------------------------------------------------------------------------- - * name ECardName * RW The card currently being edited. Returns a copy. - */ - -#define E_CONTACT_EDITOR_ADDRESS_TYPE (e_contact_editor_address_get_type ()) -#define E_CONTACT_EDITOR_ADDRESS(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE, EContactEditorAddress)) -#define E_CONTACT_EDITOR_ADDRESS_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_ADDRESS_TYPE, EContactEditorAddressClass)) -#define E_IS_CONTACT_EDITOR_ADDRESS(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE)) -#define E_IS_CONTACT_EDITOR_ADDRESS_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_ADDRESS_TYPE)) - - -typedef struct _EContactEditorAddress EContactEditorAddress; -typedef struct _EContactEditorAddressClass EContactEditorAddressClass; - -struct _EContactEditorAddress -{ - GnomeDialog parent; - - /* item specific fields */ - ECardDeliveryAddress *address; - - guint editable : 1; - - GladeXML *gui; -}; - -struct _EContactEditorAddressClass -{ - GnomeDialogClass parent_class; -}; - - -GtkWidget *e_contact_editor_address_new(const ECardDeliveryAddress *name); -GtkType e_contact_editor_address_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __E_CONTACT_EDITOR_ADDRESS_H__ */ diff --git a/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade b/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade deleted file mode 100644 index b91a040d46..0000000000 --- a/addressbook/gui/contact-editor/e-contact-editor-confirm-delete.glade +++ /dev/null @@ -1,83 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>e-contact-editor-confirm-delete</name> - <program_name>e-contact-editor-confirm-delete</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>True</use_widget_names> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> - <gnome_help_support>True</gnome_help_support> -</project> - -<widget> - <class>GnomeMessageBox</class> - <name>confirm-dialog</name> - <message_box_type>GNOME_MESSAGE_BOX_QUESTION</message_box_type> - <message>Are you sure you want -to delete this contact?</message> - <title>Delete Contact?</title> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>True</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button2</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.c b/addressbook/gui/contact-editor/e-contact-editor-fullname.c index 8d602657c0..4777091128 100644 --- a/addressbook/gui/contact-editor/e-contact-editor-fullname.c +++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.c @@ -1,260 +1,329 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-contact-editor-fullname.c - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Toshok <toshok@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H #include <config.h> -#include <libgnomeui/gnome-stock.h> -#include <gal/widgets/e-unicode.h> -#include "e-contact-editor-fullname.h" -#include <libgnomeui/gnome-window-icon.h> -#include <libgnome/gnome-util.h> -#include <gtk/gtkcombo.h> +#endif -static void e_contact_editor_fullname_init (EContactEditorFullname *card); -static void e_contact_editor_fullname_class_init (EContactEditorFullnameClass *klass); -static void e_contact_editor_fullname_set_arg (GtkObject *o, GtkArg *arg, guint arg_id); -static void e_contact_editor_fullname_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void e_contact_editor_fullname_destroy (GtkObject *object); +#include <glib/gi18n.h> -static void fill_in_info(EContactEditorFullname *editor); -static void extract_info(EContactEditorFullname *editor); +#include "e-util/e-util.h" +#include "e-util/e-util-private.h" -static GnomeDialogClass *parent_class = NULL; +#include "e-contact-editor-fullname.h" + +static void fill_in_info (EContactEditorFullname *editor); +static void extract_info (EContactEditorFullname *editor); -/* The arguments we take */ enum { - ARG_0, - ARG_NAME, - ARG_IS_READ_ONLY + PROP_0, + PROP_NAME, + PROP_EDITABLE }; -GtkType -e_contact_editor_fullname_get_type (void) -{ - static GtkType contact_editor_fullname_type = 0; - - if (!contact_editor_fullname_type) - { - static const GtkTypeInfo contact_editor_fullname_info = - { - "EContactEditorFullname", - sizeof (EContactEditorFullname), - sizeof (EContactEditorFullnameClass), - (GtkClassInitFunc) e_contact_editor_fullname_class_init, - (GtkObjectInitFunc) e_contact_editor_fullname_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - contact_editor_fullname_type = gtk_type_unique (gnome_dialog_get_type (), &contact_editor_fullname_info); - } - - return contact_editor_fullname_type; -} +G_DEFINE_TYPE ( + EContactEditorFullname, + e_contact_editor_fullname, + GTK_TYPE_DIALOG) static void -e_contact_editor_fullname_class_init (EContactEditorFullnameClass *klass) +e_contact_editor_fullname_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - GtkObjectClass *object_class; - GnomeDialogClass *dialog_class; - - object_class = (GtkObjectClass*) klass; - dialog_class = (GnomeDialogClass *) klass; + EContactEditorFullname *e_contact_editor_fullname; - parent_class = gtk_type_class (gnome_dialog_get_type ()); + e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object); - gtk_object_add_arg_type ("EContactEditorFullname::name", GTK_TYPE_POINTER, - GTK_ARG_READWRITE, ARG_NAME); + switch (property_id) { + case PROP_NAME: + e_contact_name_free (e_contact_editor_fullname->name); - gtk_object_add_arg_type ("EContactEditorFullname::editable", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_IS_READ_ONLY); - - object_class->set_arg = e_contact_editor_fullname_set_arg; - object_class->get_arg = e_contact_editor_fullname_get_arg; - object_class->destroy = e_contact_editor_fullname_destroy; -} + if (g_value_get_pointer (value) != NULL) { + e_contact_editor_fullname->name = + e_contact_name_copy ( + g_value_get_pointer (value)); + fill_in_info (e_contact_editor_fullname); + } + else { + e_contact_editor_fullname->name = NULL; + } + break; + case PROP_EDITABLE: { + gboolean editable; + gint i; -static void -e_contact_editor_fullname_init (EContactEditorFullname *e_contact_editor_fullname) -{ - GladeXML *gui; - GtkWidget *widget; - char *icon_path; + const gchar *widget_names[] = { + "comboentry-title", + "comboentry-suffix", + "entry-first", + "entry-middle", + "entry-last", + "label-title", + "label-suffix", + "label-first", + "label-middle", + "label-last", + NULL + }; - gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_fullname), - GNOME_STOCK_BUTTON_OK); - - gnome_dialog_append_button ( GNOME_DIALOG(e_contact_editor_fullname), - GNOME_STOCK_BUTTON_CANCEL); + editable = g_value_get_boolean (value); + e_contact_editor_fullname->editable = editable; - gtk_window_set_policy(GTK_WINDOW(e_contact_editor_fullname), TRUE, TRUE, FALSE); + for (i = 0; widget_names[i] != NULL; i++) { + GtkWidget *widget; - e_contact_editor_fullname->name = NULL; - gui = glade_xml_new (EVOLUTION_GLADEDIR "/fullname.glade", NULL); - e_contact_editor_fullname->gui = gui; - - widget = glade_xml_get_widget(gui, "dialog-checkfullname"); - gtk_window_set_title (GTK_WINDOW (e_contact_editor_fullname), - GTK_WINDOW (widget)->title); - - widget = glade_xml_get_widget(gui, "table-checkfullname"); - gtk_widget_ref(widget); - gtk_container_remove(GTK_CONTAINER(widget->parent), widget); - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (e_contact_editor_fullname)->vbox), widget, TRUE, TRUE, 0); - gtk_widget_unref(widget); - - icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png"); - gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor_fullname), icon_path); - g_free (icon_path); -} + widget = e_builder_get_widget ( + e_contact_editor_fullname->builder, + widget_names[i]); -void -e_contact_editor_fullname_destroy (GtkObject *object) -{ - EContactEditorFullname *e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME(object); + if (GTK_IS_ENTRY (widget)) { + gtk_editable_set_editable ( + GTK_EDITABLE (widget), editable); - if (e_contact_editor_fullname->gui) - gtk_object_unref(GTK_OBJECT(e_contact_editor_fullname->gui)); - e_card_name_unref(e_contact_editor_fullname->name); -} + } else if (GTK_IS_COMBO_BOX (widget)) { + GtkWidget *child; -GtkWidget* -e_contact_editor_fullname_new (const ECardName *name) -{ - GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_contact_editor_fullname_get_type ())); - gtk_object_set (GTK_OBJECT(widget), - "name", name, - NULL); - return widget; -} + child = gtk_bin_get_child (GTK_BIN (widget)); -static void -e_contact_editor_fullname_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) -{ - EContactEditorFullname *e_contact_editor_fullname; + gtk_editable_set_editable ( + GTK_EDITABLE (child), editable); + gtk_widget_set_sensitive (widget, editable); - e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (o); - - switch (arg_id){ - case ARG_NAME: - e_card_name_unref(e_contact_editor_fullname->name); - e_contact_editor_fullname->name = e_card_name_copy(GTK_VALUE_POINTER (*arg)); - fill_in_info(e_contact_editor_fullname); - break; - case ARG_IS_READ_ONLY: { - int i; - char *entry_names[] = { - "combo-title", - "combo-suffix", - "entry-first", - "entry-middle", - "entry-last", - NULL - }; - e_contact_editor_fullname->editable = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - for (i = 0; entry_names[i] != NULL; i ++) { - GtkWidget *w = glade_xml_get_widget(e_contact_editor_fullname->gui, entry_names[i]); - if (GTK_IS_ENTRY (w)) { - gtk_entry_set_editable (GTK_ENTRY (w), - e_contact_editor_fullname->editable); - } - else if (GTK_IS_COMBO (w)) { - gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (w)->entry), - e_contact_editor_fullname->editable); - gtk_widget_set_sensitive (GTK_COMBO (w)->button, e_contact_editor_fullname->editable); + } else if (GTK_IS_LABEL (widget)) { + gtk_widget_set_sensitive (widget, editable); } } break; } + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; } } static void -e_contact_editor_fullname_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +e_contact_editor_fullname_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) { EContactEditorFullname *e_contact_editor_fullname; e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object); - switch (arg_id) { - case ARG_NAME: - extract_info(e_contact_editor_fullname); - GTK_VALUE_POINTER (*arg) = e_card_name_ref(e_contact_editor_fullname->name); + switch (property_id) { + case PROP_NAME: + extract_info (e_contact_editor_fullname); + g_value_set_pointer ( + value, e_contact_name_copy ( + e_contact_editor_fullname->name)); break; - case ARG_IS_READ_ONLY: - GTK_VALUE_BOOL (*arg) = e_contact_editor_fullname->editable ? TRUE : FALSE; + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_contact_editor_fullname->editable); break; default: - arg->type = GTK_TYPE_INVALID; + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void -fill_in_field(EContactEditorFullname *editor, char *field, char *string) +e_contact_editor_fullname_dispose (GObject *object) +{ + EContactEditorFullname *e_contact_editor_fullname; + + e_contact_editor_fullname = E_CONTACT_EDITOR_FULLNAME (object); + + if (e_contact_editor_fullname->builder) { + g_object_unref (e_contact_editor_fullname->builder); + e_contact_editor_fullname->builder = NULL; + } + + if (e_contact_editor_fullname->name) { + e_contact_name_free (e_contact_editor_fullname->name); + e_contact_editor_fullname->name = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_contact_editor_fullname_parent_class)->dispose (object); +} + +static void +e_contact_editor_fullname_class_init (EContactEditorFullnameClass *class) +{ + GObjectClass *object_class; + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = e_contact_editor_fullname_set_property; + object_class->get_property = e_contact_editor_fullname_get_property; + object_class->dispose = e_contact_editor_fullname_dispose; + + g_object_class_install_property ( + object_class, + PROP_NAME, + g_param_spec_pointer ( + "name", + "Name", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_EDITABLE, + g_param_spec_boolean ( + "editable", + "Editable", + NULL, + FALSE, + G_PARAM_READWRITE)); +} + +static void +e_contact_editor_fullname_init (EContactEditorFullname *e_contact_editor_fullname) +{ + GtkBuilder *builder; + GtkDialog *dialog; + GtkWidget *parent; + GtkWidget *widget; + GtkWidget *action_area; + GtkWidget *content_area; + const gchar *title; + + dialog = GTK_DIALOG (e_contact_editor_fullname); + action_area = gtk_dialog_get_action_area (dialog); + content_area = gtk_dialog_get_content_area (dialog); + + gtk_widget_realize (GTK_WIDGET (e_contact_editor_fullname)); + gtk_container_set_border_width (GTK_CONTAINER (action_area), 12); + gtk_container_set_border_width (GTK_CONTAINER (content_area), 0); + + gtk_dialog_add_buttons ( + dialog, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, NULL); + + gtk_window_set_resizable (GTK_WINDOW (dialog), TRUE); + + e_contact_editor_fullname->name = NULL; + + builder = gtk_builder_new (); + e_load_ui_builder_definition (builder, "fullname.ui"); + + e_contact_editor_fullname->builder = builder; + + widget = e_builder_get_widget (builder, "dialog-checkfullname"); + title = gtk_window_get_title (GTK_WINDOW (widget)); + gtk_window_set_title (GTK_WINDOW (e_contact_editor_fullname), title); + + widget = e_builder_get_widget (builder, "table-checkfullname"); + parent = gtk_widget_get_parent (widget); + g_object_ref (widget); + gtk_container_remove (GTK_CONTAINER (parent), widget); + gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 0); + g_object_unref (widget); + + gtk_window_set_icon_name ( + GTK_WINDOW (e_contact_editor_fullname), "contact-new"); +} + +GtkWidget * +e_contact_editor_fullname_new (const EContactName *name) +{ + GtkWidget *widget = g_object_new (E_TYPE_CONTACT_EDITOR_FULLNAME, NULL); + + g_object_set ( + widget, + "name", name, + NULL); + return widget; +} + +static void +fill_in_field (EContactEditorFullname *editor, + const gchar *field, + const gchar *string) { - GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field)); + GtkWidget *widget = e_builder_get_widget (editor->builder, field); + GtkEntry *entry = NULL; + + if (GTK_IS_ENTRY (widget)) + entry = GTK_ENTRY (widget); + else if (GTK_IS_COMBO_BOX (widget)) + entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))); + if (entry) { if (string) - e_utf8_gtk_entry_set_text(entry, string); + gtk_entry_set_text (entry, string); else - gtk_entry_set_text(entry, ""); + gtk_entry_set_text (entry, ""); } } static void -fill_in_info(EContactEditorFullname *editor) +fill_in_info (EContactEditorFullname *editor) { - ECardName *name = editor->name; + EContactName *name = editor->name; if (name) { - fill_in_field(editor, "entry-title", name->prefix); - fill_in_field(editor, "entry-first", name->given); - fill_in_field(editor, "entry-middle", name->additional); - fill_in_field(editor, "entry-last", name->family); - fill_in_field(editor, "entry-suffix", name->suffix); + fill_in_field (editor, "comboentry-title", name->prefixes); + fill_in_field (editor, "entry-first", name->given); + fill_in_field (editor, "entry-middle", name->additional); + fill_in_field (editor, "entry-last", name->family); + fill_in_field (editor, "comboentry-suffix", name->suffixes); } } -static char * -extract_field(EContactEditorFullname *editor, char *field) +static gchar * +extract_field (EContactEditorFullname *editor, + const gchar *field) { - GtkEntry *entry = GTK_ENTRY(glade_xml_get_widget(editor->gui, field)); + GtkWidget *widget = e_builder_get_widget (editor->builder, field); + GtkEntry *entry = NULL; + + if (GTK_IS_ENTRY (widget)) + entry = GTK_ENTRY (widget); + else if (GTK_IS_COMBO_BOX (widget)) + entry = GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))); + if (entry) - return e_utf8_gtk_entry_get_text(entry); + return g_strdup (gtk_entry_get_text (entry)); else return NULL; } static void -extract_info(EContactEditorFullname *editor) +extract_info (EContactEditorFullname *editor) { - ECardName *name = editor->name; + EContactName *name = editor->name; if (!name) { - name = e_card_name_new(); + name = e_contact_name_new (); editor->name = name; } - name->prefix = extract_field(editor, "entry-title" ); - name->given = extract_field(editor, "entry-first" ); - name->additional = extract_field(editor, "entry-middle"); - name->family = extract_field(editor, "entry-last" ); - name->suffix = extract_field(editor, "entry-suffix"); + name->prefixes = extract_field (editor, "comboentry-title"); + name->given = extract_field (editor, "entry-first"); + name->additional = extract_field (editor, "entry-middle"); + name->family = extract_field (editor, "entry-last"); + name->suffixes = extract_field (editor, "comboentry-suffix"); } diff --git a/addressbook/gui/contact-editor/e-contact-editor-fullname.h b/addressbook/gui/contact-editor/e-contact-editor-fullname.h index 0d09b13700..51a9e28db9 100644 --- a/addressbook/gui/contact-editor/e-contact-editor-fullname.h +++ b/addressbook/gui/contact-editor/e-contact-editor-fullname.h @@ -1,33 +1,32 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-contact-editor-fullname.h - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. */ + #ifndef __E_CONTACT_EDITOR_FULLNAME_H__ #define __E_CONTACT_EDITOR_FULLNAME_H__ -#include <libgnomeui/gnome-dialog.h> -#include <glade/glade.h> -#include <ebook/e-card.h> +#include <gtk/gtk.h> +#include <libebook/libebook.h> -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS /* EContactEditorFullname - A dialog displaying information about a contact. * @@ -38,23 +37,22 @@ extern "C" { * name ECardName * RW The card currently being edited. Returns a copy. */ -#define E_CONTACT_EDITOR_FULLNAME_TYPE (e_contact_editor_fullname_get_type ()) -#define E_CONTACT_EDITOR_FULLNAME(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE, EContactEditorFullname)) -#define E_CONTACT_EDITOR_FULLNAME_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_FULLNAME_TYPE, EContactEditorFullnameClass)) -#define E_IS_CONTACT_EDITOR_FULLNAME(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE)) -#define E_IS_CONTACT_EDITOR_FULLNAME_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_FULLNAME_TYPE)) - +#define E_TYPE_CONTACT_EDITOR_FULLNAME (e_contact_editor_fullname_get_type ()) +#define E_CONTACT_EDITOR_FULLNAME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME, EContactEditorFullname)) +#define E_CONTACT_EDITOR_FULLNAME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_EDITOR_FULLNAME, EContactEditorFullnameClass)) +#define E_IS_CONTACT_EDITOR_FULLNAME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME)) +#define E_IS_CONTACT_EDITOR_FULLNAME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_EDITOR_FULLNAME)) typedef struct _EContactEditorFullname EContactEditorFullname; typedef struct _EContactEditorFullnameClass EContactEditorFullnameClass; struct _EContactEditorFullname { - GnomeDialog parent; - + GtkDialog parent; + /* item specific fields */ - ECardName *name; - GladeXML *gui; + EContactName *name; + GtkBuilder *builder; /* Whether the dialog will accept modifications */ guint editable : 1; @@ -62,16 +60,12 @@ struct _EContactEditorFullname struct _EContactEditorFullnameClass { - GnomeDialogClass parent_class; + GtkDialogClass parent_class; }; +GtkWidget *e_contact_editor_fullname_new (const EContactName *name); +GType e_contact_editor_fullname_get_type (void); -GtkWidget *e_contact_editor_fullname_new(const ECardName *name); -GtkType e_contact_editor_fullname_get_type (void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - +G_END_DECLS #endif /* __E_CONTACT_EDITOR_FULLNAME_H__ */ diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c index f22aaa5487..0d3f41e2d5 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.c +++ b/addressbook/gui/contact-editor/e-contact-editor.c @@ -1,110 +1,112 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* - * e-contact-editor.c - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H #include <config.h> +#endif +#include "eab-editor.h" #include "e-contact-editor.h" +#include <stdlib.h> +#include <string.h> #include <time.h> -#include <gtk/gtkcheckbutton.h> -#include <gtk/gtkcheckmenuitem.h> -#include <gtk/gtkcombo.h> -#include <gtk/gtktext.h> -#include <libgnomeui/gnome-popup-menu.h> -#include <libgnomeui/gnome-dialog-util.h> -#include <libgnomeui/gnome-window-icon.h> -#include <libgnomeui/gnome-stock.h> -#include <libgnome/gnome-i18n.h> - -#include <bonobo/bonobo-ui-container.h> -#include <bonobo/bonobo-ui-util.h> + +#include <gtk/gtk.h> +#include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> #include <gdk-pixbuf/gdk-pixbuf.h> -#include <gdk-pixbuf/gnome-canvas-pixbuf.h> -#include <gal/widgets/e-categories.h> -#include <gal/widgets/e-gui-utils.h> -#include <gal/widgets/e-unicode.h> -#include <gal/e-text/e-entry.h> -#include <e-util/e-categories-master-list-wombat.h> +#include "shell/e-shell.h" #include "addressbook/printing/e-contact-print.h" -#include "addressbook/printing/e-contact-print-envelope.h" -#include "addressbook/gui/widgets/e-addressbook-util.h" -#include "e-util/e-gui-utils.h" -#include "widgets/misc/e-dateedit.h" -#include "shell/evolution-shell-component-utils.h" +#include "addressbook/gui/widgets/eab-gui-util.h" -#include "e-card-merging.h" +#include "eab-contact-merging.h" -#include "e-contact-editor-address.h" #include "e-contact-editor-fullname.h" -#include "e-contact-save-as.h" -/* Signal IDs */ +#define EMAIL_SLOTS 4 +#define PHONE_SLOTS 8 +#define IM_SLOTS 4 +#define ADDRESS_SLOTS 3 + +#define EVOLUTION_UI_SLOT_PARAM "X-EVOLUTION-UI-SLOT" + +/* IM columns */ enum { - CARD_ADDED, - CARD_MODIFIED, - CARD_DELETED, - EDITOR_CLOSED, - LAST_SIGNAL + COLUMN_IM_ICON, + COLUMN_IM_SERVICE, + COLUMN_IM_SCREENNAME, + COLUMN_IM_LOCATION, + COLUMN_IM_LOCATION_TYPE, + COLUMN_IM_SERVICE_FIELD, + NUM_IM_COLUMNS }; -static void e_contact_editor_init (EContactEditor *card); -static void e_contact_editor_class_init (EContactEditorClass *klass); -static void e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id); -static void e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id); -static void e_contact_editor_destroy (GtkObject *object); +typedef struct { + EContactEditor *editor; + ESource *source; +} ConnectClosure; + +static void e_contact_editor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void e_contact_editor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); +static void e_contact_editor_dispose (GObject *object); +static void e_contact_editor_raise (EABEditor *editor); +static void e_contact_editor_show (EABEditor *editor); +static void e_contact_editor_save_contact (EABEditor *editor, + gboolean should_close); +static void e_contact_editor_close (EABEditor *editor); +static gboolean e_contact_editor_is_valid (EABEditor *editor); +static gboolean e_contact_editor_is_changed (EABEditor *editor); +static GtkWindow * + e_contact_editor_get_window (EABEditor *editor); +static void save_contact (EContactEditor *ce, + gboolean should_close); +static void entry_activated (EContactEditor *editor); + +static void set_entry_text (EContactEditor *editor, + GtkEntry *entry, + const gchar *string); +static void sensitize_ok (EContactEditor *ce); + +static EABEditorClass *parent_class = NULL; -#if 0 -static GtkWidget *e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info); -#endif -static void _email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor); -static void _phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor); -static void _address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor); -static void find_address_mailing (EContactEditor *editor); -static void enable_writable_fields(EContactEditor *editor); -static void set_editable(EContactEditor *editor); -static void fill_in_info(EContactEditor *editor); -static void extract_info(EContactEditor *editor); -static void set_fields(EContactEditor *editor); -static void set_address_field(EContactEditor *editor, int result); -static void add_field_callback(GtkWidget *widget, EContactEditor *editor); -static void command_state_changed (EContactEditor *ce); -static void widget_changed (GtkWidget *widget, EContactEditor *editor); -static void close_dialog (EContactEditor *ce); -static void enable_widget (GtkWidget *widget, gboolean enabled); - -static GtkObjectClass *parent_class = NULL; - -static guint contact_editor_signals[LAST_SIGNAL]; - -/* The arguments we take */ enum { - ARG_0, - ARG_BOOK, - ARG_CARD, - ARG_IS_NEW_CARD, - ARG_EDITABLE, - ARG_CHANGED, - ARG_WRITABLE_FIELDS + PROP_0, + PROP_SOURCE_CLIENT, + PROP_TARGET_CLIENT, + PROP_CONTACT, + PROP_IS_NEW_CONTACT, + PROP_EDITABLE, + PROP_CHANGED, + PROP_WRITABLE_FIELDS, + PROP_REQUIRED_FIELDS }; enum { @@ -113,299 +115,319 @@ enum { DYNAMIC_LIST_ADDRESS }; -static GSList *all_contact_editors = NULL; - -GtkType -e_contact_editor_get_type (void) -{ - static GtkType contact_editor_type = 0; - - if (!contact_editor_type) - { - static const GtkTypeInfo contact_editor_info = - { - "EContactEditor", - sizeof (EContactEditor), - sizeof (EContactEditorClass), - (GtkClassInitFunc) e_contact_editor_class_init, - (GtkObjectInitFunc) e_contact_editor_init, - /* reserved_1 */ NULL, - /* reserved_2 */ NULL, - (GtkClassInitFunc) NULL, - }; - - contact_editor_type = gtk_type_unique (GTK_TYPE_OBJECT, &contact_editor_info); - } - - return contact_editor_type; -} - -typedef void (*GtkSignal_NONE__INT_OBJECT) (GtkObject * object, - gint arg1, - GtkObject *arg2, - gpointer user_data); - -static void -e_marshal_NONE__INT_OBJECT (GtkObject * object, - GtkSignalFunc func, - gpointer func_data, GtkArg * args) -{ - GtkSignal_NONE__INT_OBJECT rfunc; - rfunc = (GtkSignal_NONE__INT_OBJECT) func; - (*rfunc) (object, - GTK_VALUE_INT (args[0]), - GTK_VALUE_OBJECT (args[1]), - func_data); +static struct { + EContactField field_id; + const gchar *type_1; + const gchar *type_2; } +phones[] = { + { E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT, NULL }, + { E_CONTACT_PHONE_BUSINESS, "WORK", "VOICE" }, + { E_CONTACT_PHONE_BUSINESS_FAX, "WORK", "FAX" }, + { E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK, NULL }, + { E_CONTACT_PHONE_CAR, "CAR", NULL }, + { E_CONTACT_PHONE_COMPANY, "X-EVOLUTION-COMPANY", NULL }, + { E_CONTACT_PHONE_HOME, "HOME", "VOICE" }, + { E_CONTACT_PHONE_HOME_FAX, "HOME", "FAX" }, + { E_CONTACT_PHONE_ISDN, "ISDN", NULL }, + { E_CONTACT_PHONE_MOBILE, "CELL", NULL }, + { E_CONTACT_PHONE_OTHER, "VOICE", NULL }, + { E_CONTACT_PHONE_OTHER_FAX, "FAX", NULL }, + { E_CONTACT_PHONE_PAGER, "PAGER", NULL }, + { E_CONTACT_PHONE_PRIMARY, "PREF", NULL }, + { E_CONTACT_PHONE_RADIO, EVC_X_RADIO, NULL }, + { E_CONTACT_PHONE_TELEX, EVC_X_TELEX, NULL }, + { E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD, NULL } +}; -static void -e_contact_editor_class_init (EContactEditorClass *klass) -{ - GtkObjectClass *object_class; +/* Defaults from the table above */ +static const gint phones_default[] = { 1, 6, 9, 2, 7, 12, 10, 10 }; - object_class = (GtkObjectClass*) klass; +static EContactField addresses[] = { + E_CONTACT_ADDRESS_WORK, + E_CONTACT_ADDRESS_HOME, + E_CONTACT_ADDRESS_OTHER +}; - parent_class = gtk_type_class (GTK_TYPE_OBJECT); +static EContactField address_labels[] = { + E_CONTACT_ADDRESS_LABEL_WORK, + E_CONTACT_ADDRESS_LABEL_HOME, + E_CONTACT_ADDRESS_LABEL_OTHER +}; - gtk_object_add_arg_type ("EContactEditor::book", GTK_TYPE_OBJECT, - GTK_ARG_READWRITE, ARG_BOOK); - gtk_object_add_arg_type ("EContactEditor::card", GTK_TYPE_OBJECT, - GTK_ARG_READWRITE, ARG_CARD); - gtk_object_add_arg_type ("EContactEditor::is_new_card", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_IS_NEW_CARD); - gtk_object_add_arg_type ("EContactEditor::writable_fields", GTK_TYPE_POINTER, - GTK_ARG_READWRITE, ARG_WRITABLE_FIELDS); - gtk_object_add_arg_type ("EContactEditor::editable", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_EDITABLE); - gtk_object_add_arg_type ("EContactEditor::changed", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_CHANGED); +static const gchar *address_name[] = { + "work", + "home", + "other" +}; - contact_editor_signals[CARD_ADDED] = - gtk_signal_new ("card_added", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EContactEditorClass, card_added), - e_marshal_NONE__INT_OBJECT, - GTK_TYPE_NONE, 2, - GTK_TYPE_INT, GTK_TYPE_OBJECT); +static struct { + EContactField field; + const gchar *pretty_name; +} +im_service[] = +{ + { E_CONTACT_IM_AIM, N_ ("AIM") }, + { E_CONTACT_IM_JABBER, N_ ("Jabber") }, + { E_CONTACT_IM_YAHOO, N_ ("Yahoo") }, + { E_CONTACT_IM_GADUGADU, N_ ("Gadu-Gadu") }, + { E_CONTACT_IM_MSN, N_ ("MSN") }, + { E_CONTACT_IM_ICQ, N_ ("ICQ") }, + { E_CONTACT_IM_GROUPWISE, N_ ("GroupWise") }, + { E_CONTACT_IM_SKYPE, N_ ("Skype") }, + { E_CONTACT_IM_TWITTER, N_ ("Twitter") } +}; - contact_editor_signals[CARD_MODIFIED] = - gtk_signal_new ("card_modified", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EContactEditorClass, card_modified), - e_marshal_NONE__INT_OBJECT, - GTK_TYPE_NONE, 2, - GTK_TYPE_INT, GTK_TYPE_OBJECT); +/* Defaults from the table above */ +static const gint im_service_default[] = { 0, 2, 4, 5 }; - contact_editor_signals[CARD_DELETED] = - gtk_signal_new ("card_deleted", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EContactEditorClass, card_deleted), - e_marshal_NONE__INT_OBJECT, - GTK_TYPE_NONE, 2, - GTK_TYPE_INT, GTK_TYPE_OBJECT); +static struct { + const gchar *name; + const gchar *pretty_name; +} +common_location[] = +{ + { "WORK", N_ ("Work") }, + { "HOME", N_ ("Home") }, + { "OTHER", N_ ("Other") } +}; - contact_editor_signals[EDITOR_CLOSED] = - gtk_signal_new ("editor_closed", - GTK_RUN_FIRST, - object_class->type, - GTK_SIGNAL_OFFSET (EContactEditorClass, editor_closed), - gtk_marshal_NONE__NONE, - GTK_TYPE_NONE, 0); +/* Default from the table above */ +static const gint email_default[] = { 0, 1, 2, 2 }; - gtk_object_class_add_signals (object_class, contact_editor_signals, LAST_SIGNAL); - - object_class->set_arg = e_contact_editor_set_arg; - object_class->get_arg = e_contact_editor_get_arg; - object_class->destroy = e_contact_editor_destroy; -} - -static void -_replace_button(EContactEditor *editor, gchar *button_xml, gchar *image, GtkSignalFunc func) -{ - GladeXML *gui = editor->gui; - GtkWidget *button = glade_xml_get_widget(gui, button_xml); - GtkWidget *pixmap; - gchar *image_temp; - if (button && GTK_IS_BUTTON(button)) { - image_temp = g_strdup_printf("%s/%s", EVOLUTIONDIR, image); - pixmap = e_create_image_widget(NULL, image_temp, NULL, 0, 0); - gtk_container_add(GTK_CONTAINER(button), - pixmap); - g_free(image_temp); - gtk_widget_show(pixmap); - gtk_signal_connect(GTK_OBJECT(button), "button_press_event", func, editor); - } -} +#define STRING_IS_EMPTY(x) (!(x) || !(*(x))) +#define STRING_MAKE_NON_NULL(x) ((x) ? (x) : "") -static void -_replace_buttons(EContactEditor *editor) +G_DEFINE_TYPE (EContactEditor, e_contact_editor, EAB_TYPE_EDITOR) + +static void +connect_closure_free (ConnectClosure *connect_closure) { - _replace_button(editor, "button-phone1", "arrow.png", _phone_arrow_pressed); - _replace_button(editor, "button-phone2", "arrow.png", _phone_arrow_pressed); - _replace_button(editor, "button-phone3", "arrow.png", _phone_arrow_pressed); - _replace_button(editor, "button-phone4", "arrow.png", _phone_arrow_pressed); - _replace_button(editor, "button-address", "arrow.png", _address_arrow_pressed); - _replace_button(editor, "button-email1", "arrow.png", _email_arrow_pressed); + if (connect_closure->editor != NULL) + g_object_unref (connect_closure->editor); + + if (connect_closure->source != NULL) + g_object_unref (connect_closure->source); + + g_slice_free (ConnectClosure, connect_closure); } - -static void -wants_html_changed (GtkWidget *widget, EContactEditor *editor) + +static void +e_contact_editor_contact_added (EABEditor *editor, + const GError *error, + EContact *contact) { - gboolean wants_html; - gtk_object_get(GTK_OBJECT(widget), - "active", &wants_html, - NULL); - gtk_object_set(GTK_OBJECT(editor->card), - "wants_html", wants_html, - NULL); - - widget_changed (widget, editor); -} - -static void -phone_entry_changed (GtkWidget *widget, EContactEditor *editor) -{ - int which; - GtkEntry *entry = GTK_ENTRY(widget); - ECardPhone *phone; - - if ( widget == glade_xml_get_widget(editor->gui, "entry-phone1") ) { - which = 1; - } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone2") ) { - which = 2; - } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone3") ) { - which = 3; - } else if ( widget == glade_xml_get_widget(editor->gui, "entry-phone4") ) { - which = 4; - } else + if (!error) + return; + + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; - phone = e_card_phone_new(); - phone->number = e_utf8_gtk_entry_get_text(entry); - e_card_simple_set_phone(editor->simple, editor->phone_choice[which - 1], phone); - e_card_phone_unref(phone); - set_fields(editor); - widget_changed (widget, editor); + eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error adding contact"), error); } static void -email_entry_changed (GtkWidget *widget, EContactEditor *editor) +e_contact_editor_contact_modified (EABEditor *editor, + const GError *error, + EContact *contact) { - gchar *string; - GtkEntry *entry = GTK_ENTRY(widget); - - string = e_utf8_gtk_entry_get_text(entry); - - e_card_simple_set_email(editor->simple, editor->email_choice, string); + if (!error) + return; - g_free (string); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - widget_changed (widget, editor); + eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error modifying contact"), error); } static void -address_text_changed (GtkWidget *widget, EContactEditor *editor) +e_contact_editor_contact_deleted (EABEditor *editor, + const GError *error, + EContact *contact) { - GtkEditable *editable = GTK_EDITABLE(widget); - ECardAddrLabel *address; - - if (editor->address_choice == -1) + if (!error) return; - address = e_card_address_label_new(); - - if (editor->address_mailing == editor->address_choice || editor->address_mailing == -1) { - GtkWidget *check; - - address->flags |= E_CARD_ADDR_DEFAULT; - - check = glade_xml_get_widget(editor->gui, "checkbutton-mailingaddress"); - if (check && GTK_IS_CHECK_BUTTON (check)) { - gtk_signal_handler_block_by_data (GTK_OBJECT (check), editor); - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), TRUE); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (check), editor); - } - } - - address->data = e_utf8_gtk_editable_get_chars(editable, 0, -1); + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + return; - e_card_simple_set_address(editor->simple, editor->address_choice, address); - e_card_address_label_unref(address); + eab_error_dialog (NULL, eab_editor_get_window (editor), _("Error removing contact"), error); +} - widget_changed (widget, editor); +static void +e_contact_editor_closed (EABEditor *editor) +{ + g_object_unref (editor); } +static void +e_contact_editor_class_init (EContactEditorClass *class) +{ + GObjectClass *object_class = G_OBJECT_CLASS (class); + EABEditorClass *editor_class = EAB_EDITOR_CLASS (class); + + parent_class = g_type_class_ref (EAB_TYPE_EDITOR); + + object_class->set_property = e_contact_editor_set_property; + object_class->get_property = e_contact_editor_get_property; + object_class->dispose = e_contact_editor_dispose; + + editor_class->raise = e_contact_editor_raise; + editor_class->show = e_contact_editor_show; + editor_class->close = e_contact_editor_close; + editor_class->is_valid = e_contact_editor_is_valid; + editor_class->save_contact = e_contact_editor_save_contact; + editor_class->is_changed = e_contact_editor_is_changed; + editor_class->get_window = e_contact_editor_get_window; + editor_class->contact_added = e_contact_editor_contact_added; + editor_class->contact_modified = e_contact_editor_contact_modified; + editor_class->contact_deleted = e_contact_editor_contact_deleted; + editor_class->editor_closed = e_contact_editor_closed; + + g_object_class_install_property ( + object_class, + PROP_SOURCE_CLIENT, + g_param_spec_object ( + "source_client", + "Source EBookClient", + NULL, + E_TYPE_BOOK_CLIENT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_TARGET_CLIENT, + g_param_spec_object ( + "target_client", + "Target EBookClient", + NULL, + E_TYPE_BOOK_CLIENT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CONTACT, + g_param_spec_object ( + "contact", + "Contact", + NULL, + E_TYPE_CONTACT, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_IS_NEW_CONTACT, + g_param_spec_boolean ( + "is_new_contact", + "Is New Contact", + NULL, + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_WRITABLE_FIELDS, + g_param_spec_pointer ( + "writable_fields", + "Writable Fields", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_REQUIRED_FIELDS, + g_param_spec_pointer ( + "required_fields", + "Required Fields", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_EDITABLE, + g_param_spec_boolean ( + "editable", + "Editable", + NULL, + FALSE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_CHANGED, + g_param_spec_boolean ( + "changed", + "Changed", + NULL, + FALSE, + G_PARAM_READWRITE)); +} static void -address_mailing_changed (GtkWidget *widget, EContactEditor *editor) +entry_activated (EContactEditor *editor) { - ECardAddrLabel *address; - GtkWidget *text; - gboolean mailing_address; + save_contact (editor, TRUE); +} - if (editor->address_choice == -1) - return; +/* FIXME: Linear time... */ +static gboolean +is_field_supported (EContactEditor *editor, + EContactField field_id) +{ + GSList *fields, *iter; + const gchar *field; - mailing_address = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); - - /* Mark the current address as the mailing address */ - text = glade_xml_get_widget(editor->gui, "text-address"); - if (text && GTK_IS_TEXT(text)) { + fields = editor->writable_fields; + if (!fields) + return FALSE; - address = e_card_address_label_new(); - - if (mailing_address) - address->flags |= E_CARD_ADDR_DEFAULT; - else - address->flags &= ~E_CARD_ADDR_DEFAULT; - address->data = e_utf8_gtk_editable_get_chars(GTK_EDITABLE (text), 0, -1); - - e_card_simple_set_address(editor->simple, editor->address_choice, address); - e_card_address_label_unref(address); - } + field = e_contact_field_name (field_id); + if (!field) + return FALSE; - /* Unset the previous mailing address flag */ - if (mailing_address && editor->address_mailing != -1) { - const ECardAddrLabel *curr; + for (iter = fields; iter; iter = iter->next) { + const gchar *this_field = iter->data; - curr = e_card_simple_get_address(editor->simple, - editor->address_mailing); - address = e_card_address_label_copy (curr); - address->flags &= ~E_CARD_ADDR_DEFAULT; - e_card_simple_set_address(editor->simple, - editor->address_mailing, - address); - } + if (!this_field) + continue; - /* Remember the new mailing address */ - if (mailing_address) - editor->address_mailing = editor->address_choice; - else - editor->address_mailing = -1; + if (!strcmp (field, this_field)) + return TRUE; + } - widget_changed (widget, editor); + return FALSE; } - /* This function tells you whether name_to_style will make sense. */ static gboolean -style_makes_sense(const ECardName *name, char *company, int style) +style_makes_sense (const EContactName *name, + const gchar *company, + gint style) { switch (style) { case 0: /* Fall Through */ case 1: return TRUE; case 2: + if (name) { + if (name->additional && *name->additional) + return TRUE; + else + return FALSE; + } + case 3: if (company && *company) return TRUE; else return FALSE; - case 3: /* Fall Through */ - case 4: - if (company && *company && name && ((name->given && *name->given) || (name->family && *name->family))) + case 4: /* Fall Through */ + case 5: + if (company && *company && name && + ((name->given && *name->given) || + (name->family && *name->family))) return TRUE; else return FALSE; @@ -414,12 +436,15 @@ style_makes_sense(const ECardName *name, char *company, int style) } } -static char * -name_to_style(const ECardName *name, char *company, int style) +static gchar * +name_to_style (const EContactName *name, + const gchar *company, + gint style) { - char *string; - char *strings[4], **stringptr; - char *substring; + gchar *string; + gchar *strings[4], **stringptr; + gchar *midstring[4], **midstrptr; + gchar *substring; switch (style) { case 0: stringptr = strings; @@ -430,7 +455,7 @@ name_to_style(const ECardName *name, char *company, int style) *(stringptr++) = name->given; } *stringptr = NULL; - string = g_strjoinv(", ", strings); + string = g_strjoinv (", ", strings); break; case 1: stringptr = strings; @@ -441,13 +466,31 @@ name_to_style(const ECardName *name, char *company, int style) *(stringptr++) = name->family; } *stringptr = NULL; - string = g_strjoinv(" ", strings); + string = g_strjoinv (" ", strings); break; case 2: - string = g_strdup(company); + midstrptr = midstring; + if (name) { + if (name->family && *name->family) + *(midstrptr++) = name->family; + if (name->given && *name->given) + *(midstrptr++) = name->given; + } + *midstrptr = NULL; + stringptr = strings; + *(stringptr++) = g_strjoinv(", ", midstring); + if (name) { + if (name->additional && *name->additional) + *(stringptr++) = name->additional; + } + *stringptr = NULL; + string = g_strjoinv (" ", strings); + break; + case 3: + string = g_strdup (company); break; - case 3: /* Fall Through */ - case 4: + case 4: /* Fall Through */ + case 5: stringptr = strings; if (name) { if (name->family && *name->family) @@ -456,2253 +499,4107 @@ name_to_style(const ECardName *name, char *company, int style) *(stringptr++) = name->given; } *stringptr = NULL; - substring = g_strjoinv(", ", strings); + substring = g_strjoinv (", ", strings); if (!(company && *company)) company = ""; - if (style == 3) - string = g_strdup_printf("%s (%s)", substring, company); + if (style == 4) + string = g_strdup_printf ("%s (%s)", substring, company); else - string = g_strdup_printf("%s (%s)", company, substring); - g_free(substring); + string = g_strdup_printf ("%s (%s)", company, substring); + g_free (substring); break; default: - string = g_strdup(""); + string = g_strdup (""); } return string; } -static int +static gint file_as_get_style (EContactEditor *editor) { - GtkEntry *file_as = GTK_ENTRY(glade_xml_get_widget(editor->gui, "entry-file-as")); - char *filestring; - char *trystring; - ECardName *name = editor->name; - int i; - int style; - - if (!(file_as && GTK_IS_ENTRY(file_as))) + GtkEntry *file_as = GTK_ENTRY ( + gtk_bin_get_child (GTK_BIN ( + e_builder_get_widget (editor->builder, "combo-file-as")))); + GtkEntry *company_w = GTK_ENTRY ( + e_builder_get_widget (editor->builder, "entry-company")); + gchar *filestring; + gchar *trystring; + EContactName *name = editor->name; + const gchar *company; + gint i; + + if (!(file_as && GTK_IS_ENTRY (file_as))) return -1; - filestring = e_utf8_gtk_entry_get_text(file_as); + company = gtk_entry_get_text (GTK_ENTRY (company_w)); + filestring = g_strdup (gtk_entry_get_text (file_as)); - style = -1; - for (i = 0; i < 5; i++) { - trystring = name_to_style(name, editor->company, i); - if (!strcmp(trystring, filestring)) { - g_free(trystring); - g_free(filestring); + for (i = 0; i < 6; i++) { + trystring = name_to_style (name, company, i); + if (!strcmp (trystring, filestring)) { + g_free (trystring); + g_free (filestring); return i; } - g_free(trystring); + g_free (trystring); } g_free (filestring); return -1; } static void -file_as_set_style(EContactEditor *editor, int style) +file_as_set_style (EContactEditor *editor, + gint style) { - char *string; - int i; + gchar *string; + gint i; GList *strings = NULL; - GtkEntry *file_as = GTK_ENTRY(glade_xml_get_widget(editor->gui, "entry-file-as")); - GtkWidget *widget; - + GtkComboBox *combo_file_as = GTK_COMBO_BOX ( + e_builder_get_widget (editor->builder, "combo-file-as")); + GtkEntry *company_w = GTK_ENTRY ( + e_builder_get_widget (editor->builder, "entry-company")); + const gchar *company; - if (!(file_as && GTK_IS_ENTRY(file_as))) + if (!(combo_file_as && GTK_IS_COMBO_BOX (combo_file_as))) return; + company = gtk_entry_get_text (GTK_ENTRY (company_w)); + if (style == -1) { - string = e_utf8_gtk_entry_get_text(file_as); - strings = g_list_append(strings, string); - } + GtkWidget *entry; - widget = glade_xml_get_widget(editor->gui, "combo-file-as"); + entry = gtk_bin_get_child (GTK_BIN (combo_file_as)); + if (entry) { + string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + strings = g_list_append (strings, string); + } + } - for (i = 0; i < 5; i++) { - if (style_makes_sense(editor->name, editor->company, i)) { - char *u; - u = name_to_style(editor->name, editor->company, i); - string = e_utf8_to_gtk_string (widget, u); - g_free (u); - if (string) strings = g_list_append(strings, string); + for (i = 0; i < 6; i++) { + if (style_makes_sense (editor->name, company, i)) { + gchar *u; + u = name_to_style (editor->name, company, i); + if (!STRING_IS_EMPTY (u)) + strings = g_list_append (strings, u); + else + g_free (u); } } - if (widget && GTK_IS_COMBO(widget)) { - GtkCombo *combo = GTK_COMBO(widget); - gtk_combo_set_popdown_strings(combo, strings); - g_list_foreach(strings, (GFunc) g_free, NULL); - g_list_free(strings); + if (combo_file_as) { + GList *l; + GtkListStore *list_store; + GtkTreeIter iter; + + list_store = GTK_LIST_STORE ( + gtk_combo_box_get_model (combo_file_as)); + + gtk_list_store_clear (list_store); + + for (l = strings; l; l = l->next) { + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, 0, l->data, -1); + } } + g_list_foreach (strings, (GFunc) g_free, NULL); + g_list_free (strings); + if (style != -1) { - string = name_to_style(editor->name, editor->company, style); - e_utf8_gtk_entry_set_text(file_as, string); - g_free(string); + string = name_to_style (editor->name, company, style); + set_entry_text ( + editor, GTK_ENTRY (gtk_bin_get_child ( + GTK_BIN (combo_file_as))), string); + g_free (string); } } static void -name_entry_changed (GtkWidget *widget, EContactEditor *editor) +name_entry_changed (GtkWidget *widget, + EContactEditor *editor) { - int style = 0; - char *string; + gint style = 0; + const gchar *string; - style = file_as_get_style(editor); - - e_card_name_unref(editor->name); + style = file_as_get_style (editor); + e_contact_name_free (editor->name); + string = gtk_entry_get_text (GTK_ENTRY (widget)); + editor->name = e_contact_name_from_string (string); + file_as_set_style (editor, style); - string = e_utf8_gtk_entry_get_text (GTK_ENTRY(widget)); - editor->name = e_card_name_from_string(string); - g_free (string); - - file_as_set_style(editor, style); + editor->check_merge = TRUE; - widget_changed (widget, editor); + sensitize_ok (editor); + if (string && !*string) + gtk_window_set_title ( + GTK_WINDOW (editor->app), _("Contact Editor")); } static void -company_entry_changed (GtkWidget *widget, EContactEditor *editor) +file_as_combo_changed (GtkWidget *widget, + EContactEditor *editor) { - int style = 0; + GtkWidget *entry; + gchar *string = NULL; + + entry = gtk_bin_get_child (GTK_BIN (widget)); + if (entry) + string = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + + if (string && *string) { + gchar *title; + title = g_strdup_printf (_("Contact Editor - %s"), string); + gtk_window_set_title (GTK_WINDOW (editor->app), title); + g_free (title); + } + else { + gtk_window_set_title ( + GTK_WINDOW (editor->app), _("Contact Editor")); + } + sensitize_ok (editor); - style = file_as_get_style(editor); - - g_free(editor->company); - - editor->company = e_utf8_gtk_entry_get_text(GTK_ENTRY(widget)); - - file_as_set_style(editor, style); + g_free (string); +} + +static void +company_entry_changed (GtkWidget *widget, + EContactEditor *editor) +{ + gint style = 0; - widget_changed (widget, editor); + style = file_as_get_style (editor); + file_as_set_style (editor, style); } static void -field_changed (GtkWidget *widget, EContactEditor *editor) +update_file_as_combo (EContactEditor *editor) { - if (!editor->changed) { - editor->changed = TRUE; - command_state_changed (editor); - } + file_as_set_style (editor, file_as_get_style (editor)); +} + +static void +fill_in_source_field (EContactEditor *editor) +{ + GtkWidget *source_menu; + + if (!editor->target_client) + return; + + source_menu = e_builder_get_widget ( + editor->builder, "client-combo-box"); + + e_source_combo_box_set_active ( + E_SOURCE_COMBO_BOX (source_menu), + e_client_get_source (E_CLIENT (editor->target_client))); } static void -set_entry_changed_signal_phone(EContactEditor *editor, char *id) +sensitize_ok (EContactEditor *ce) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, id); - if (widget && GTK_IS_ENTRY(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "changed", - phone_entry_changed, editor); + GtkWidget *widget; + gboolean allow_save; + GtkWidget *entry_fullname = + e_builder_get_widget (ce->builder, "entry-fullname"); + GtkWidget *entry_file_as = + gtk_bin_get_child (GTK_BIN ( + e_builder_get_widget (ce->builder, "combo-file-as"))); + GtkWidget *company_name = + e_builder_get_widget (ce->builder, "entry-company"); + const gchar *name_entry_string = + gtk_entry_get_text (GTK_ENTRY (entry_fullname)); + const gchar *file_as_entry_string = + gtk_entry_get_text (GTK_ENTRY (entry_file_as)); + const gchar *company_name_string = + gtk_entry_get_text (GTK_ENTRY (company_name)); + + allow_save = ce->target_editable && ce->changed; + + if (!strcmp (name_entry_string, "") || + !strcmp (file_as_entry_string, "")) { + if (strcmp (company_name_string , "")) { + allow_save = TRUE; + } + else + allow_save = FALSE; + } + widget = e_builder_get_widget (ce->builder, "button-ok"); + gtk_widget_set_sensitive (widget, allow_save); } static void -widget_changed (GtkWidget *widget, EContactEditor *editor) +object_changed (GObject *object, + EContactEditor *editor) { - if (!editor->editable) { + if (!editor->target_editable) { g_warning ("non-editable contact editor has an editable field in it."); return; } + if (!editor->check_merge && GTK_IS_WIDGET (object)) { + const gchar *widget_name; + + widget_name = gtk_widget_get_name (GTK_WIDGET (object)); + + if (widget_name && + ((g_str_equal (widget_name, "fullname")) || + (g_str_equal (widget_name, "nickname")) || + (g_str_equal (widget_name, "file-as")) || + (g_str_has_prefix (widget_name, "email-")))) + editor->check_merge = TRUE; + } + if (!editor->changed) { editor->changed = TRUE; - command_state_changed (editor); + sensitize_ok (editor); } } static void -set_entry_changed_signal_field(EContactEditor *editor, char *id) +image_chooser_changed (GtkWidget *widget, + EContactEditor *editor) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, id); - if (widget && GTK_IS_ENTRY(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "changed", - field_changed, editor); + editor->image_set = TRUE; + editor->image_changed = TRUE; } static void -set_entry_changed_signals(EContactEditor *editor) +set_entry_text (EContactEditor *editor, + GtkEntry *entry, + const gchar *string) { - GtkWidget *widget; - set_entry_changed_signal_phone(editor, "entry-phone1"); - set_entry_changed_signal_phone(editor, "entry-phone2"); - set_entry_changed_signal_phone(editor, "entry-phone3"); - set_entry_changed_signal_phone(editor, "entry-phone4"); - widget = glade_xml_get_widget(editor->gui, "entry-email1"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - email_entry_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "text-address"); - if (widget && GTK_IS_TEXT(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - address_text_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-fullname"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - name_entry_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-company"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - company_entry_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-web"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-categories"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-jobtitle"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-file-as"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-manager"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-assistant"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-office"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-department"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-profession"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-nickname"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-spouse"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "text-comments"); - if (widget && GTK_IS_TEXT(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "dateedit-birthday"); - if (widget && E_IS_DATE_EDIT(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary"); - if (widget && E_IS_DATE_EDIT(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - widget = glade_xml_get_widget(editor->gui, "entry-web"); - if (widget && GTK_IS_ENTRY(widget)) { - gtk_signal_connect(GTK_OBJECT(widget), "changed", - widget_changed, editor); - } - -} - -static void -full_name_clicked(GtkWidget *button, EContactEditor *editor) -{ - GnomeDialog *dialog = GNOME_DIALOG(e_contact_editor_fullname_new(editor->name)); - int result; + const gchar *oldstring = gtk_entry_get_text (entry); - gtk_object_set (GTK_OBJECT (dialog), - "editable", editor->editable, - NULL); - gtk_widget_show(GTK_WIDGET(dialog)); - result = gnome_dialog_run (dialog); + if (!string) + string = ""; - if (result == 0) { - ECardName *name; - GtkWidget *fname_widget; - int style = 0; + if (strcmp (string, oldstring)) { + g_signal_handlers_block_matched ( + entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); + gtk_entry_set_text (entry, string); + g_signal_handlers_unblock_matched ( + entry, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); + } +} - gtk_object_get(GTK_OBJECT(dialog), - "name", &name, - NULL); +static void +set_combo_box_active (EContactEditor *editor, + GtkComboBox *combo_box, + gint active) +{ + g_signal_handlers_block_matched ( + combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); + gtk_combo_box_set_active (combo_box, active); + g_signal_handlers_unblock_matched ( + combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); +} - style = file_as_get_style(editor); +static void +init_email_record_location (EContactEditor *editor, + gint record) +{ + GtkComboBox *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + gint i; + GtkTreeIter iter; + GtkListStore *store; + + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = GTK_COMBO_BOX ( + e_builder_get_widget (editor->builder, widget_name)); + g_free (widget_name); + + store = GTK_LIST_STORE (gtk_combo_box_get_model (location_combo_box)); + gtk_list_store_clear (store); + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, _(common_location[i].pretty_name), + -1); + } - fname_widget = glade_xml_get_widget(editor->gui, "entry-fullname"); - if (fname_widget && GTK_IS_ENTRY(fname_widget)) { - char *full_name = e_card_name_to_string(name); - e_utf8_gtk_entry_set_text(GTK_ENTRY(fname_widget), full_name); - g_free(full_name); - } + g_signal_connect_swapped ( + location_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), email_entry); + g_signal_connect ( + location_combo_box, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect ( + email_entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + email_entry, "activate", + G_CALLBACK (entry_activated), editor); +} - e_card_name_unref(editor->name); - editor->name = e_card_name_ref(name); +static void +fill_in_email_record (EContactEditor *editor, + gint record, + const gchar *address, + gint location) +{ + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + set_combo_box_active ( + editor, GTK_COMBO_BOX (location_combo_box), + location >= 0 ? location : email_default[2]); + set_entry_text (editor, GTK_ENTRY (email_entry), address ? address : ""); +} - file_as_set_style(editor, style); - } - gtk_object_unref(GTK_OBJECT(dialog)); +static void +extract_email_record (EContactEditor *editor, + gint record, + gchar **address, + gint *location) +{ + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + const gchar *text; + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + text = gtk_entry_get_text (GTK_ENTRY (email_entry)); + *address = g_strstrip (g_strdup (text)); + *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box)); +} + +static const gchar * +email_index_to_location (gint index) +{ + return common_location[index].name; +} + +static const gchar * +im_index_to_location (gint index) +{ + return common_location[index].name; } static void -full_addr_clicked(GtkWidget *button, EContactEditor *editor) +phone_index_to_type (gint index, + const gchar **type_1, + const gchar **type_2) { - GnomeDialog *dialog; - int result; - const ECardDeliveryAddress *address; + *type_1 = phones [index].type_1; + *type_2 = phones [index].type_2; +} - address = e_card_simple_get_delivery_address(editor->simple, editor->address_choice); +static gint +get_email_location (EVCardAttribute *attr) +{ + gint i; - dialog = GNOME_DIALOG(e_contact_editor_address_new(address)); - gtk_object_set (GTK_OBJECT (dialog), - "editable", editor->editable, - NULL); - gtk_widget_show(GTK_WIDGET(dialog)); - - result = gnome_dialog_run (dialog); - if (result == 0) { - ECardDeliveryAddress *new_address; - GtkWidget *address_widget; - - gtk_object_get(GTK_OBJECT(dialog), - "address", &new_address, - NULL); - - address_widget = glade_xml_get_widget(editor->gui, "text-address"); - if (address_widget && GTK_IS_EDITABLE(address_widget)) { - char *string = e_card_delivery_address_to_string(new_address); - e_utf8_gtk_editable_set_text(GTK_EDITABLE(address_widget), string); - g_free(string); - } else { - ECardAddrLabel *address = e_card_delivery_address_to_label(new_address); - e_card_simple_set_address(editor->simple, editor->address_choice, address); - e_card_address_label_unref(address); - } + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return i; + } - e_card_simple_set_delivery_address(editor->simple, editor->address_choice, new_address); + return -1; +} - e_card_delivery_address_unref(new_address); +static gint +get_im_location (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return i; } - gtk_object_unref(GTK_OBJECT(dialog)); + + return -1; } -static void -categories_clicked(GtkWidget *button, EContactEditor *editor) +static gint +get_phone_type (EVCardAttribute *attr) { - char *categories = NULL; - GnomeDialog *dialog; - int result; - GtkWidget *entry = glade_xml_get_widget(editor->gui, "entry-categories"); - ECategoriesMasterList *ecml; - if (entry && GTK_IS_ENTRY(entry)) - categories = e_utf8_gtk_entry_get_text(GTK_ENTRY(entry)); - else if (editor->card) - gtk_object_get(GTK_OBJECT(editor->card), - "categories", &categories, - NULL); - dialog = GNOME_DIALOG(e_categories_new(categories)); + gint i; - if (dialog == NULL) { - GtkWidget *uh_oh = gnome_error_dialog (_("Category editor not available.")); - gtk_widget_show (uh_oh); - return; + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + if (e_vcard_attribute_has_type (attr, phones[i].type_1) && + (phones[i].type_2 == NULL || + e_vcard_attribute_has_type (attr, phones[i].type_2))) + return i; } - ecml = e_categories_master_list_wombat_new (); - gtk_object_set(GTK_OBJECT(dialog), - "header", _("This contact belongs to these categories:"), - "ecml", ecml, - NULL); - gtk_object_unref (GTK_OBJECT (ecml)); - gtk_widget_show(GTK_WIDGET(dialog)); - result = gnome_dialog_run (dialog); - g_free (categories); - if (result == 0) { - gtk_object_get(GTK_OBJECT(dialog), - "categories", &categories, - NULL); - if (entry && GTK_IS_ENTRY(entry)) - e_utf8_gtk_entry_set_text(GTK_ENTRY(entry), categories); - else - gtk_object_set(GTK_OBJECT(editor->card), - "categories", categories, - NULL); - g_free(categories); + return -1; +} + +static EVCardAttributeParam * +get_ui_slot_param (EVCardAttribute *attr) +{ + EVCardAttributeParam *param = NULL; + GList *param_list; + GList *l; + + param_list = e_vcard_attribute_get_params (attr); + + for (l = param_list; l; l = g_list_next (l)) { + const gchar *str; + + param = l->data; + + str = e_vcard_attribute_param_get_name (param); + if (!g_ascii_strcasecmp (str, EVOLUTION_UI_SLOT_PARAM)) + break; + + param = NULL; + } + + return param; +} + +static gint +get_ui_slot (EVCardAttribute *attr) +{ + EVCardAttributeParam *param; + gint slot = -1; + + param = get_ui_slot_param (attr); + + if (param) { + GList *value_list; + + value_list = e_vcard_attribute_param_get_values (param); + slot = atoi (value_list->data); } - gtk_object_destroy(GTK_OBJECT(dialog)); + + return slot; } static void -ensure_select_names_contact (EContactEditor *editor) +set_ui_slot (EVCardAttribute *attr, + gint slot) { - if (editor->select_names_contacts == NULL) { - editor->select_names_contacts = e_select_names_manager_new (); - e_select_names_manager_add_section (editor->select_names_contacts, - "contacts", - "Related Contacts"); + EVCardAttributeParam *param; + gchar *slot_str; + + param = get_ui_slot_param (attr); + if (!param) { + param = e_vcard_attribute_param_new (EVOLUTION_UI_SLOT_PARAM); + e_vcard_attribute_add_param (attr, param); } - set_entry_changed_signal_field(editor, "entry-caluri"); - set_entry_changed_signal_field(editor, "entry-fburl"); + e_vcard_attribute_param_remove_values (param); + + slot_str = g_strdup_printf ("%d", slot); + e_vcard_attribute_param_add_value (param, slot_str); + g_free (slot_str); } -static void -contacts_clicked (GtkWidget *button, EContactEditor *editor) +static gint +alloc_ui_slot (EContactEditor *editor, + const gchar *widget_base, + gint preferred_slot, + gint num_slots) { - ensure_select_names_contact (editor); - e_select_names_manager_activate_dialog (editor->select_names_contacts, - "contacts"); + gchar *widget_name; + GtkWidget *widget; + const gchar *entry_contents; + gint i; + + /* See if we can get the preferred slot */ + + if (preferred_slot >= 1) { + widget_name = g_strdup_printf ("%s-%d", widget_base, preferred_slot); + widget = e_builder_get_widget (editor->builder, widget_name); + entry_contents = gtk_entry_get_text (GTK_ENTRY (widget)); + g_free (widget_name); + + if (STRING_IS_EMPTY (entry_contents)) + return preferred_slot; + } + + /* Find first empty slot */ + + for (i = 1; i <= num_slots; i++) { + widget_name = g_strdup_printf ("%s-%d", widget_base, i); + widget = e_builder_get_widget (editor->builder, widget_name); + entry_contents = gtk_entry_get_text (GTK_ENTRY (widget)); + g_free (widget_name); + + if (STRING_IS_EMPTY (entry_contents)) + return i; + } + + return -1; } static void -add_lists (EContactEditor *editor) +free_attr_list (GList *attr_list) { - GtkWidget *table = glade_xml_get_widget (editor->gui, "table-contacts"); - if (table && GTK_IS_TABLE (table)) { - GtkWidget *entry; + GList *l; - ensure_select_names_contact (editor); - entry = e_select_names_manager_create_entry (editor->select_names_contacts, - "contacts"); - gtk_signal_connect(GTK_OBJECT(entry), "changed", - widget_changed, editor); - gtk_table_attach_defaults (GTK_TABLE (table), entry, 0, 1, 0, 1); - gtk_widget_show (entry); + for (l = attr_list; l; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + e_vcard_attribute_free (attr); } + + g_list_free (attr_list); } +static void +fill_in_email (EContactEditor *editor) +{ + GList *email_attr_list; + GList *l; + gint record_n; -typedef struct { - EContactEditor *ce; - gboolean should_close; -} EditorCloseStruct; + /* Clear */ + + for (record_n = 1; record_n <= EMAIL_SLOTS; record_n++) { + fill_in_email_record ( + editor, record_n, NULL, email_default[record_n - 1]); + } + + /* Fill in */ + + email_attr_list = e_contact_get_attributes ( + editor->contact, E_CONTACT_EMAIL); + + for (record_n = 1, l = email_attr_list; + l && record_n <= EMAIL_SLOTS; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + gchar *email_address; + gint slot; + + email_address = e_vcard_attribute_get_value (attr); + slot = alloc_ui_slot ( + editor, "entry-email", + get_ui_slot (attr), EMAIL_SLOTS); + if (slot < 1) + break; + + fill_in_email_record ( + editor, slot, email_address, + get_email_location (attr)); + + record_n++; + + g_free (email_address); + } + + g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free); +} static void -card_added_cb (EBook *book, EBookStatus status, const char *id, EditorCloseStruct *ecs) +extract_email (EContactEditor *editor) { - EContactEditor *ce = ecs->ce; - gboolean should_close = ecs->should_close; + GList *attr_list = NULL; + GList *old_attr_list; + GList *l, *l_next; + gint i; - gtk_widget_set_sensitive (ce->app, TRUE); - ce->in_async_call = FALSE; + for (i = 1; i <= EMAIL_SLOTS; i++) { + gchar *address; + gint location; - e_card_set_id (ce->card, id); + extract_email_record (editor, i, &address, &location); - gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_ADDED], - status, ce->card); + if (!STRING_IS_EMPTY (address)) { + EVCardAttribute *attr; + attr = e_vcard_attribute_new ( + "", e_contact_vcard_attribute (E_CONTACT_EMAIL)); - if (status == E_BOOK_STATUS_SUCCESS) { - ce->is_new_card = FALSE; + if (location >= 0) + e_vcard_attribute_add_param_with_value ( + attr, + e_vcard_attribute_param_new (EVC_TYPE), + email_index_to_location (location)); - if (should_close) { - close_dialog (ce); - } - else { - ce->changed = FALSE; - command_state_changed (ce); + e_vcard_attribute_add_value (attr, address); + set_ui_slot (attr, i); + + attr_list = g_list_append (attr_list, attr); } + + g_free (address); } - gtk_object_unref (GTK_OBJECT (ce)); - g_free (ecs); + /* Splice in the old attributes, minus the EMAIL_SLOTS first */ + + old_attr_list = e_contact_get_attributes (editor->contact, E_CONTACT_EMAIL); + for (l = old_attr_list, i = 1; l && i <= EMAIL_SLOTS; l = l_next, i++) { + l_next = g_list_next (l); + + e_vcard_attribute_free (l->data); + l = g_list_delete_link (l, l); + } + + old_attr_list = l; + attr_list = g_list_concat (attr_list, old_attr_list); + + e_contact_set_attributes (editor->contact, E_CONTACT_EMAIL, attr_list); + + free_attr_list (attr_list); } static void -card_modified_cb (EBook *book, EBookStatus status, EditorCloseStruct *ecs) +sensitize_email_record (EContactEditor *editor, + gint record, + gboolean enabled) { - EContactEditor *ce = ecs->ce; - gboolean should_close = ecs->should_close; + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; - gtk_widget_set_sensitive (ce->app, TRUE); - ce->in_async_call = FALSE; + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_MODIFIED], - status, ce->card); + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - if (status == E_BOOK_STATUS_SUCCESS) { - if (should_close) { - close_dialog (ce); - } - else { - ce->changed = FALSE; - command_state_changed (ce); + gtk_widget_set_sensitive (location_combo_box, enabled); + gtk_editable_set_editable (GTK_EDITABLE (email_entry), enabled); +} + +static void +sensitize_email (EContactEditor *editor) +{ + gint i; + + for (i = 1; i <= EMAIL_SLOTS; i++) { + gboolean enabled = TRUE; + + if (!editor->target_editable) + enabled = FALSE; + + if (E_CONTACT_FIRST_EMAIL_ID + i - 1 <= E_CONTACT_LAST_EMAIL_ID && + !is_field_supported (editor, E_CONTACT_FIRST_EMAIL_ID + i - 1)) + enabled = FALSE; + + sensitize_email_record (editor, i, enabled); + } +} + +static void +init_item_sensitiveable_combo_box (GtkComboBox *combo) +{ + GtkCellRenderer *cell; + GtkListStore *store; + + g_return_if_fail (combo != NULL); + g_return_if_fail (GTK_IS_COMBO_BOX (combo)); + + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); + g_object_unref (store); + + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_attributes ( + GTK_CELL_LAYOUT (combo), cell, + "text", 0, "sensitive", 1, NULL); +} + +/* EContact can get attributes by field ID only, + * and there is none for TEL, so we need this */ +static GList * +get_attributes_named (EVCard *vcard, + const gchar *attr_name) +{ + GList *attr_list_in; + GList *attr_list_out = NULL; + GList *l; + + attr_list_in = e_vcard_get_attributes (vcard); + + for (l = attr_list_in; l; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + const gchar *name; + + name = e_vcard_attribute_get_name (attr); + + if (!g_ascii_strcasecmp (attr_name, name)) { + attr_list_out = g_list_append ( + attr_list_out, + e_vcard_attribute_copy (attr)); } } - gtk_object_unref (GTK_OBJECT (ce)); - g_free (ecs); + return attr_list_out; } -/* Emits the signal to request saving a card */ +/* EContact can set attributes by field ID only, + * and there is none for TEL, so we need this */ static void -save_card (EContactEditor *ce, gboolean should_close) +set_attributes_named (EVCard *vcard, + const gchar *attr_name, + GList *attr_list) { - extract_info (ce); - e_card_simple_sync_card (ce->simple); + GList *l; + + e_vcard_remove_attributes (vcard, NULL, attr_name); - if (ce->book) { - EditorCloseStruct *ecs = g_new(EditorCloseStruct, 1); - - ecs->ce = ce; - gtk_object_ref (GTK_OBJECT (ecs->ce)); + for (l = attr_list; l; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; - ecs->should_close = should_close; + e_vcard_add_attribute (vcard, e_vcard_attribute_copy (attr)); + } +} - gtk_widget_set_sensitive (ce->app, FALSE); - ce->in_async_call = TRUE; +static void +set_arrow_image (EContactEditor *editor, + const gchar *arrow_widget, + gboolean expanded) +{ + GtkWidget *arrow; - if (ce->is_new_card) - e_card_merging_book_add_card (ce->book, ce->card, GTK_SIGNAL_FUNC(card_added_cb), ecs); + arrow = e_builder_get_widget (editor->builder, arrow_widget); + if (expanded) + gtk_arrow_set ( + GTK_ARROW (arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE); + else + gtk_arrow_set ( + GTK_ARROW (arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE); +} + +static void +expand_widget_list (EContactEditor *editor, + const gchar **widget_names, + gboolean expanded) +{ + gint i; + for (i = 0; widget_names[i]; i++) + gtk_widget_set_visible ( + e_builder_get_widget (editor->builder, widget_names[i]), + expanded); +} + +static void +expand_web (EContactEditor *editor, + gboolean expanded) +{ + const gchar *names[] = { + "label-videourl", "label-fburl", + "entry-videourl", "entry-fburl", + NULL + }; + set_arrow_image (editor, "arrow-web-expand", expanded); + expand_widget_list (editor, names, expanded); +} + +static void +expand_phone (EContactEditor *editor, + gboolean expanded) +{ + const gchar *names[] = { + "entry-phone-3", "combobox-phone-3", + "entry-phone-4", "combobox-phone-4", + "table-phone-extended", NULL + }; + set_arrow_image (editor, "arrow-phone-expand", expanded); + expand_widget_list (editor, names, expanded); +} + +static void +expand_mail (EContactEditor *editor, + gboolean expanded) +{ + GtkTable *table; + GtkWidget *check; + const gchar *names[] = { + "entry-email-2", "combobox-email-2", + "entry-email-3", "combobox-email-3", + "entry-email-4", "combobox-email-4", + NULL + }; + set_arrow_image (editor, "arrow-mail-expand", expanded); + expand_widget_list (editor, names, expanded); + + /* move 'use html mail' into position */ + check = e_builder_get_widget (editor->builder, "checkbutton-htmlmail"); + table = GTK_TABLE (e_builder_get_widget (editor->builder, "email-table")); + if (check != NULL && table != NULL) { + GtkWidget *parent; + + g_object_ref (check); + parent = gtk_widget_get_parent (check); + gtk_container_remove (GTK_CONTAINER (parent), check); + if (expanded) + gtk_table_attach_defaults (table, check, 0, 4, 2, 3); else - e_card_merging_book_commit_card (ce->book, ce->card, GTK_SIGNAL_FUNC(card_modified_cb), ecs); + gtk_table_attach_defaults (table, check, 2, 4, 0, 1); + g_object_unref (check); } } -/* Closes the dialog box and emits the appropriate signals */ static void -close_dialog (EContactEditor *ce) +init_email (EContactEditor *editor) { - if (ce->app != NULL) { - gtk_widget_destroy (ce->app); - ce->app = NULL; - gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[EDITOR_CLOSED]); + gint i; + + for (i = 1; i <= EMAIL_SLOTS; i++) + init_email_record_location (editor, i); + + expand_mail (editor, !editor->compress_ui); +} + +static void +fill_in_phone_record (EContactEditor *editor, + gint record, + const gchar *phone, + gint phone_type) +{ + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + set_combo_box_active ( + editor, GTK_COMBO_BOX (phone_type_combo_box), + phone_type >= 0 ? phone_type : phones_default[record - 1]); + set_entry_text (editor, GTK_ENTRY (phone_entry), phone ? phone : ""); + + if (phone && *phone && record >= 3) + expand_phone (editor, TRUE); +} + +static void +extract_phone_record (EContactEditor *editor, + gint record, + gchar **phone, + gint *phone_type) +{ + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + *phone = g_strdup (gtk_entry_get_text (GTK_ENTRY (phone_entry))); + *phone_type = gtk_combo_box_get_active (GTK_COMBO_BOX (phone_type_combo_box)); +} + +static void +fill_in_phone (EContactEditor *editor) +{ + GList *phone_attr_list; + GList *l; + gint record_n; + + /* Clear */ + + for (record_n = 1; record_n <= PHONE_SLOTS; record_n++) { + fill_in_phone_record (editor, record_n, NULL, -1); + } + + /* Fill in */ + + phone_attr_list = get_attributes_named (E_VCARD (editor->contact), "TEL"); + + for (record_n = 1, l = phone_attr_list; + l && record_n <= PHONE_SLOTS; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + gchar *phone; + gint slot; + + phone = e_vcard_attribute_get_value (attr); + slot = alloc_ui_slot (editor, "entry-phone", get_ui_slot (attr), PHONE_SLOTS); + if (slot < 1) + break; + + fill_in_phone_record ( + editor, slot, phone, get_phone_type (attr)); + + record_n++; + + g_free (phone); } } -static gboolean -prompt_to_save_changes (EContactEditor *editor) +static void +extract_phone (EContactEditor *editor) { - if (!editor->changed) - return TRUE; + GList *attr_list = NULL; + GList *old_attr_list; + GList *l, *l_next; + gint i; - switch (e_addressbook_prompt_save_dialog (GTK_WINDOW(editor->app))) { - case 0: /* Save */ - save_card (editor, FALSE); - return TRUE; - case 1: /* Discard */ - return TRUE; - case 2: /* Cancel */ - default: - return FALSE; + for (i = 1; i <= PHONE_SLOTS; i++) { + gchar *phone; + gint phone_type; + + extract_phone_record (editor, i, &phone, &phone_type); + + if (!STRING_IS_EMPTY (phone)) { + EVCardAttribute *attr; + + attr = e_vcard_attribute_new ("", "TEL"); + + if (phone_type >= 0) { + const gchar *type_1; + const gchar *type_2; + + phone_index_to_type (phone_type, &type_1, &type_2); + + e_vcard_attribute_add_param_with_value ( + attr, e_vcard_attribute_param_new (EVC_TYPE), type_1); + + if (type_2) + e_vcard_attribute_add_param_with_value ( + attr, e_vcard_attribute_param_new (EVC_TYPE), type_2); + + } + + e_vcard_attribute_add_value (attr, phone); + set_ui_slot (attr, i); + + attr_list = g_list_append (attr_list, attr); + } + + g_free (phone); } + + /* Splice in the old attributes, minus the PHONE_SLOTS first */ + + old_attr_list = get_attributes_named (E_VCARD (editor->contact), "TEL"); + for (l = old_attr_list, i = 1; l && i <= PHONE_SLOTS; l = l_next, i++) { + l_next = g_list_next (l); + + e_vcard_attribute_free (l->data); + l = g_list_delete_link (l, l); + } + + old_attr_list = l; + attr_list = g_list_concat (attr_list, old_attr_list); + + set_attributes_named (E_VCARD (editor->contact), "TEL", attr_list); + + free_attr_list (attr_list); } -/* Menu callbacks */ +static void +init_phone_record_type (EContactEditor *editor, + gint record) +{ + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; + gint i; + GtkListStore *store; + + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (phone_type_combo_box)); + + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (phone_type_combo_box))); + + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + GtkTreeIter iter; + + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, e_contact_pretty_name (phones[i].field_id), + 1, TRUE, + -1); + } + + g_signal_connect_swapped ( + phone_type_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), phone_entry); + g_signal_connect ( + phone_type_combo_box, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect ( + phone_entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + phone_entry, "activate", + G_CALLBACK (entry_activated), editor); +} -/* File/Save callback */ static void -file_save_cb (GtkWidget *widget, gpointer data) +init_phone (EContactEditor *editor) { - EContactEditor *ce; + gint i; - ce = E_CONTACT_EDITOR (data); - save_card (ce, FALSE); + expand_phone (editor, FALSE); + + for (i = 1; i <= PHONE_SLOTS; i++) + init_phone_record_type (editor, i); } -/* File/Close callback */ static void -file_close_cb (GtkWidget *widget, gpointer data) +sensitize_phone_types (EContactEditor *editor, + GtkWidget *combo_box) { - EContactEditor *ce; + GtkTreeModel *model; + GtkTreeIter iter; + gint i; + gboolean valid; - ce = E_CONTACT_EDITOR (data); - if (!prompt_to_save_changes (ce)) - return; + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + valid = gtk_tree_model_get_iter_first (model, &iter); - close_dialog (ce); + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + if (!valid) { + g_warning (G_STRLOC ": Unexpected end of phone items in combo box"); + return; + } + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + 1, is_field_supported (editor, phones[i].field_id), + -1); + + valid = gtk_tree_model_iter_next (model, &iter); + } } static void -file_save_as_cb (GtkWidget *widget, gpointer data) +sensitize_phone_record (EContactEditor *editor, + gint record, + gboolean enabled) { - EContactEditor *ce; - ECard *card; + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; - ce = E_CONTACT_EDITOR (data); + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - extract_info (ce); - e_card_simple_sync_card (ce->simple); + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - card = ce->card; - e_contact_save_as(_("Save Contact as VCard"), card, GTK_WINDOW (ce->app)); + gtk_widget_set_sensitive (phone_type_combo_box, enabled); + gtk_editable_set_editable (GTK_EDITABLE (phone_entry), enabled); + + sensitize_phone_types (editor, phone_type_combo_box); } static void -file_send_as_cb (GtkWidget *widget, gpointer data) +sensitize_phone (EContactEditor *editor) { - EContactEditor *ce; - ECard *card; + gint i; - ce = E_CONTACT_EDITOR (data); + for (i = 1; i <= PHONE_SLOTS; i++) { + gboolean enabled = TRUE; - extract_info (ce); - e_card_simple_sync_card (ce->simple); + if (!editor->target_editable) + enabled = FALSE; - card = ce->card; - e_card_send(card, E_CARD_DISPOSITION_AS_ATTACHMENT); + sensitize_phone_record (editor, i, enabled); + } } static void -file_send_to_cb (GtkWidget *widget, gpointer data) +init_im_record_location (EContactEditor *editor, + gint record) { - EContactEditor *ce; - ECard *card; - ce = E_CONTACT_EDITOR (data); +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; + GtkListStore *store; + gint i; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (location_combo_box)); - extract_info (ce); - e_card_simple_sync_card (ce->simple); + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (location_combo_box))); - card = ce->card; - e_card_send(card, E_CARD_DISPOSITION_AS_TO); + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + GtkTreeIter iter; + + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, _(common_location[i].pretty_name), + 1, TRUE, + -1); + } + + g_signal_connect ( + location_combo_box, "changed", + G_CALLBACK (object_changed), editor); +#endif } -gboolean -e_contact_editor_confirm_delete(GtkWindow *parent) +static void +init_im_record_service (EContactEditor *editor, + gint record) { - GnomeDialog *dialog; - GladeXML *gui; - int result; + GtkWidget *service_combo_box; + GtkListStore *store; + GtkWidget *name_entry; + gchar *widget_name; + gint i; + + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + if (editor->compress_ui && record > 2) { + gtk_widget_hide (name_entry); + gtk_widget_hide (service_combo_box); + } - gui = glade_xml_new (EVOLUTION_GLADEDIR "/e-contact-editor-confirm-delete.glade", NULL); + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (service_combo_box)); - dialog = GNOME_DIALOG(glade_xml_get_widget(gui, "confirm-dialog")); + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (service_combo_box))); - gnome_dialog_set_parent(dialog, parent); - - result = gnome_dialog_run_and_close(dialog); + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { + GtkTreeIter iter; - gtk_object_unref(GTK_OBJECT(gui)); + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, im_service[i].pretty_name, + 1, TRUE, + -1); + } - return !result; + g_signal_connect_swapped ( + service_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), name_entry); + g_signal_connect ( + service_combo_box, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect ( + name_entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + name_entry, "activate", + G_CALLBACK (entry_activated), editor); } static void -card_deleted_cb (EBook *book, EBookStatus status, EContactEditor *ce) +init_im (EContactEditor *editor) { - gtk_widget_set_sensitive (ce->app, TRUE); - ce->in_async_call = FALSE; + gint i; + + for (i = 1; i <= IM_SLOTS; i++) { + init_im_record_service (editor, i); + init_im_record_location (editor, i); + } +} + +static void +fill_in_im_record (EContactEditor *editor, + gint record, + gint service, + const gchar *name, + gint location) +{ + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; +#endif + GtkWidget *name_entry; + gchar *widget_name; - gtk_signal_emit (GTK_OBJECT (ce), contact_editor_signals[CARD_DELETED], - status, ce->card); + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); +#endif - /* always close the dialog after we successfully delete a card */ - if (status == E_BOOK_STATUS_SUCCESS) - close_dialog (ce); + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + +#ifdef ENABLE_IM_LOCATION + set_combo_box_active ( + editor, GTK_COMBO_BOX (location_combo_box), + location >= 0 ? location : 0); +#endif + set_combo_box_active ( + editor, GTK_COMBO_BOX (service_combo_box), + service >= 0 ? service : im_service_default[record - 1]); + set_entry_text (editor, GTK_ENTRY (name_entry), name ? name : ""); } static void -delete_cb (GtkWidget *widget, gpointer data) +fill_in_im (EContactEditor *editor) { - EContactEditor *ce = E_CONTACT_EDITOR (data); - ECard *card = ce->card; - ECardSimple *simple = ce->simple; + GList *im_attr_list; + GList *l; + gint record_n; + gint i; + + /* Clear */ + + for (record_n = 1; record_n <= IM_SLOTS; record_n++) { + fill_in_im_record (editor, record_n, -1, NULL, -1); + } + + /* Fill in */ + + for (record_n = 1, i = 0; i < G_N_ELEMENTS (im_service); i++) { + im_attr_list = e_contact_get_attributes (editor->contact, im_service[i].field); - gtk_object_ref(GTK_OBJECT(card)); - gtk_object_ref(GTK_OBJECT(simple)); + for (l = im_attr_list; l && record_n <= IM_SLOTS; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + gchar *im_name; + gint slot; - if (e_contact_editor_confirm_delete(GTK_WINDOW(ce->app))) { + im_name = e_vcard_attribute_get_value (attr); + slot = alloc_ui_slot ( + editor, "entry-im-name", + get_ui_slot (attr), IM_SLOTS); + if (slot < 1) + break; - extract_info (ce); - e_card_simple_sync_card (simple); - - if (!ce->is_new_card && ce->book) { - gtk_widget_set_sensitive (ce->app, FALSE); - ce->in_async_call = TRUE; + fill_in_im_record ( + editor, slot, i, im_name, + get_im_location (attr)); - e_book_remove_card (ce->book, card, GTK_SIGNAL_FUNC(card_deleted_cb), ce); + record_n++; + + g_free (im_name); } - } - gtk_object_unref(GTK_OBJECT(card)); - gtk_object_unref(GTK_OBJECT(simple)); + g_list_free_full (im_attr_list, (GDestroyNotify) e_vcard_attribute_free); + } } -/* Emits the signal to request printing a card */ static void -print_cb (BonoboUIComponent *uih, void *data, const char *path) +extract_im_record (EContactEditor *editor, + gint record, + gint *service, + gchar **name, + gint *location) { - EContactEditor *ce; + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; +#endif + GtkWidget *name_entry; + gchar *widget_name; - ce = E_CONTACT_EDITOR (data); + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - extract_info (ce); - e_card_simple_sync_card (ce->simple); +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); +#endif + + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - gtk_widget_show(e_contact_print_card_dialog_new(ce->card)); + *name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name_entry))); + *service = gtk_combo_box_get_active (GTK_COMBO_BOX (service_combo_box)); +#ifdef ENABLE_IM_LOCATION + *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box)); +#else + *location = 1; /* set everything to HOME */ +#endif } -#if 0 /* Envelope printing is disabled for Evolution 1.0. */ -/* Emits the signal to request printing a card */ static void -print_envelope_cb (BonoboUIComponent *uih, void *data, const char *path) +extract_im (EContactEditor *editor) { - EContactEditor *ce; + GList **service_attr_list; + gint remaining_slots = IM_SLOTS; + gint i; - ce = E_CONTACT_EDITOR (data); + service_attr_list = g_new0 (GList *, G_N_ELEMENTS (im_service)); + + for (i = 1; i <= IM_SLOTS; i++) { + EVCardAttribute *attr; + gchar *name; + gint service; + gint location; + + extract_im_record (editor, i, &service, &name, &location); + + if (!STRING_IS_EMPTY (name)) { + attr = e_vcard_attribute_new ( + "", e_contact_vcard_attribute ( + im_service[service].field)); + + if (location >= 0) + e_vcard_attribute_add_param_with_value ( + attr, + e_vcard_attribute_param_new (EVC_TYPE), + im_index_to_location (location)); - extract_info (ce); - e_card_simple_sync_card (ce->simple); + e_vcard_attribute_add_value (attr, name); + set_ui_slot (attr, i); - gtk_widget_show(e_contact_print_envelope_dialog_new(ce->card)); + service_attr_list[service] = g_list_append ( + service_attr_list[service], attr); + } + + g_free (name); + } + + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { + GList *old_service_attr_list; + gint filled_in_slots; + GList *l, *l_next; + gint j; + + /* Splice in the old attributes, minus the filled_in_slots first */ + + old_service_attr_list = e_contact_get_attributes ( + editor->contact, im_service[i].field); + filled_in_slots = MIN ( + remaining_slots, + g_list_length (old_service_attr_list)); + remaining_slots -= filled_in_slots; + + for (l = old_service_attr_list, j = 0; + l && j < filled_in_slots; l = l_next, j++) { + l_next = g_list_next (l); + + e_vcard_attribute_free (l->data); + l = g_list_delete_link (l, l); + } + + old_service_attr_list = l; + service_attr_list[i] = g_list_concat ( + service_attr_list[i], old_service_attr_list); + + e_contact_set_attributes ( + editor->contact, + im_service[i].field, + service_attr_list[i]); + + free_attr_list (service_attr_list[i]); + } + + g_free (service_attr_list); } -#endif -/* Toolbar/Save and Close callback */ static void -tb_save_and_close_cb (BonoboUIComponent *uih, void *data, const char *path) +sensitize_im_types (EContactEditor *editor, + GtkWidget *combo_box) { - EContactEditor *ce; + GtkTreeModel *model; + GtkTreeIter iter; + gint i; + gboolean valid; - ce = E_CONTACT_EDITOR (data); - save_card (ce, TRUE); -} - -static -BonoboUIVerb verbs [] = { - BONOBO_UI_UNSAFE_VERB ("ContactEditorSave", file_save_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveAs", file_save_as_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorSaveClose", tb_save_and_close_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorSendAs", file_send_as_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorSendTo", file_send_to_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorDelete", delete_cb), - BONOBO_UI_UNSAFE_VERB ("ContactEditorPrint", print_cb), -#if 0 /* Envelope printing is disabled for Evolution 1.0. */ - BONOBO_UI_UNSAFE_VERB ("ContactEditorPrintEnvelope", print_envelope_cb), + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + valid = gtk_tree_model_get_iter_first (model, &iter); + + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { + if (!valid) { + g_warning (G_STRLOC ": Unexpected end of im items in combo box"); + return; + } + + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + 1, is_field_supported (editor, im_service[i].field), + -1); + + valid = gtk_tree_model_iter_next (model, &iter); + } +} + +static void +sensitize_im_record (EContactEditor *editor, + gint record, + gboolean enabled) +{ + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; #endif - /* BONOBO_UI_UNSAFE_VERB ("ContactEditorPageSetup", file_page_setup_menu), */ - BONOBO_UI_UNSAFE_VERB ("ContactEditorClose", file_close_cb), - - BONOBO_UI_VERB_END -}; + GtkWidget *name_entry; + gchar *widget_name; -EPixmap pixmaps[] = { - E_PIXMAP ("/commands/ContactEditorSave", "save-16.png"), - E_PIXMAP ("/commands/ContactEditorSaveClose", "save-16.png"), - E_PIXMAP ("/commands/ContactEditorSaveAs", "save-as-16.png"), - E_PIXMAP ("/commands/ContactEditorDelete", "evolution-trash-mini.png"), - E_PIXMAP ("/commands/ContactEditorPrint", "print.xpm"), -#if 0 /* Envelope printing is disabled for Evolution 1.0. */ - E_PIXMAP ("/commands/ContactEditorPrintEnvelope", "print.xpm"), + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); #endif - E_PIXMAP ("/Toolbar/ContactEditorSaveClose", "buttons/save-24.png"), - E_PIXMAP ("/Toolbar/ContactEditorDelete", "buttons/delete-message.png"), - E_PIXMAP ("/Toolbar/ContactEditorPrint", "buttons/print.png"), - E_PIXMAP_END -}; + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + gtk_widget_set_sensitive (service_combo_box, enabled); +#ifdef ENABLE_IM_LOCATION + gtk_widget_set_sensitive (location_combo_box, enabled); +#endif + gtk_editable_set_editable (GTK_EDITABLE (name_entry), enabled); + sensitize_im_types (editor, service_combo_box); +} static void -create_ui (EContactEditor *ce) +sensitize_im (EContactEditor *editor) { - bonobo_ui_component_add_verb_list_with_data (ce->uic, verbs, ce); + gint i; + gboolean enabled; + gboolean no_ims_supported; + + enabled = editor->target_editable; + no_ims_supported = TRUE; + + for (i = 0; i < G_N_ELEMENTS (im_service); i++) + if (is_field_supported (editor, im_service[i].field)) { + no_ims_supported = FALSE; + break; + } - bonobo_ui_util_set_ui (ce->uic, EVOLUTION_DATADIR, - "evolution-contact-editor.xml", - "evolution-contact-editor"); + if (no_ims_supported) + enabled = FALSE; - e_pixmaps_update (ce->uic, pixmaps); + for (i = 1; i <= IM_SLOTS; i++) { + sensitize_im_record (editor, i, enabled); + } } -/* Callback used when the dialog box is destroyed */ -static gint -app_delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data) +static void +init_personal (EContactEditor *editor) { - EContactEditor *ce; + gtk_expander_set_expanded ( + GTK_EXPANDER (e_builder_get_widget ( + editor->builder, "expander-personal-misc")), + !editor->compress_ui); - ce = E_CONTACT_EDITOR (data); + expand_web (editor, !editor->compress_ui); +} - /* if we're saving, don't allow the dialog to close */ - if (ce->in_async_call) - return TRUE; +static void +init_address_textview (EContactEditor *editor, + gint record) +{ + gchar *textview_name; + GtkWidget *textview; + GtkTextBuffer *text_buffer; - if (!prompt_to_save_changes (ce)) - return TRUE; + textview_name = g_strdup_printf ( + "textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->builder, textview_name); + g_free (textview_name); - close_dialog (ce); - return TRUE; + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); + + g_signal_connect ( + text_buffer, "changed", + G_CALLBACK (object_changed), editor); } -static GList * -add_to_tab_order(GList *list, GladeXML *gui, char *name) +static void +init_address_field (EContactEditor *editor, + gint record, + const gchar *widget_field_name) { - GtkWidget *widget = glade_xml_get_widget(gui, name); - return g_list_prepend(list, widget); + gchar *entry_name; + GtkWidget *entry; + + entry_name = g_strdup_printf ( + "entry-%s-%s", address_name[record], widget_field_name); + entry = e_builder_get_widget (editor->builder, entry_name); + g_free (entry_name); + + g_signal_connect ( + entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + entry, "activate", + G_CALLBACK (entry_activated), editor); } static void -setup_tab_order(GladeXML *gui) +init_address_record (EContactEditor *editor, + gint record) { - GtkWidget *container; - GList *list = NULL; + init_address_textview (editor, record); + init_address_field (editor, record, "city"); + init_address_field (editor, record, "state"); + init_address_field (editor, record, "zip"); + init_address_field (editor, record, "country"); + init_address_field (editor, record, "pobox"); +} - container = glade_xml_get_widget(gui, "table-contact-editor-general"); +static void +init_address (EContactEditor *editor) +{ + gint i; - if (container) { - list = add_to_tab_order(list, gui, "entry-fullname"); - list = add_to_tab_order(list, gui, "entry-jobtitle"); - list = add_to_tab_order(list, gui, "entry-company"); - list = add_to_tab_order(list, gui, "combo-file-as"); - list = add_to_tab_order(list, gui, "entry-phone1"); - list = add_to_tab_order(list, gui, "entry-phone2"); - list = add_to_tab_order(list, gui, "entry-phone3"); - list = add_to_tab_order(list, gui, "entry-phone4"); + for (i = 0; i < ADDRESS_SLOTS; i++) + init_address_record (editor, i); + + gtk_expander_set_expanded ( + GTK_EXPANDER (e_builder_get_widget ( + editor->builder, "expander-address-other")), + !editor->compress_ui); +} - list = add_to_tab_order(list, gui, "entry-email1"); - list = add_to_tab_order(list, gui, "alignment-htmlmail"); - list = add_to_tab_order(list, gui, "entry-web"); - list = add_to_tab_order(list, gui, "button-fulladdr"); - list = add_to_tab_order(list, gui, "text-address"); - list = add_to_tab_order(list, gui, "alignment-contacts"); - list = g_list_reverse(list); - e_container_change_tab_order(GTK_CONTAINER(container), list); - g_list_free(list); +static void +fill_in_address_textview (EContactEditor *editor, + gint record, + EContactAddress *address) +{ + gchar *textview_name; + GtkWidget *textview; + GtkTextBuffer *text_buffer; + GtkTextIter iter_end, iter_start; + + textview_name = g_strdup_printf ("textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->builder, textview_name); + g_free (textview_name); + + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); + gtk_text_buffer_set_text (text_buffer, address->street ? address->street : "", -1); + + gtk_text_buffer_get_end_iter (text_buffer, &iter_end); + if (address->ext && *address->ext) { + gtk_text_buffer_insert (text_buffer, &iter_end, "\n", -1); + gtk_text_buffer_insert (text_buffer, &iter_end, address->ext, -1); + } else { + gtk_text_buffer_insert (text_buffer, &iter_end, "", -1); } + gtk_text_buffer_get_iter_at_line (text_buffer, &iter_start, 0); + gtk_text_buffer_place_cursor (text_buffer, &iter_start); } static void -e_contact_editor_init (EContactEditor *e_contact_editor) +fill_in_address_label_textview (EContactEditor *editor, + gint record, + const gchar *label) { - GladeXML *gui; - GtkWidget *widget; - GtkWidget *bonobo_win; - GtkWidget *wants_html; - BonoboUIContainer *container; - char *icon_path; - - e_contact_editor->email_info = NULL; - e_contact_editor->phone_info = NULL; - e_contact_editor->address_info = NULL; - e_contact_editor->email_popup = NULL; - e_contact_editor->phone_popup = NULL; - e_contact_editor->address_popup = NULL; - e_contact_editor->email_list = NULL; - e_contact_editor->phone_list = NULL; - e_contact_editor->address_list = NULL; - e_contact_editor->name = e_card_name_new(); - e_contact_editor->company = g_strdup(""); - - e_contact_editor->email_choice = 0; - e_contact_editor->phone_choice[0] = E_CARD_SIMPLE_PHONE_ID_BUSINESS; - e_contact_editor->phone_choice[1] = E_CARD_SIMPLE_PHONE_ID_HOME; - e_contact_editor->phone_choice[2] = E_CARD_SIMPLE_PHONE_ID_BUSINESS_FAX; - e_contact_editor->phone_choice[3] = E_CARD_SIMPLE_PHONE_ID_MOBILE; - e_contact_editor->address_choice = 0; - e_contact_editor->address_mailing = -1; - - e_contact_editor->arbitrary_fields = NULL; - - e_contact_editor->simple = e_card_simple_new(NULL); - - e_contact_editor->card = NULL; - e_contact_editor->changed = FALSE; - e_contact_editor->in_async_call = FALSE; - e_contact_editor->editable = TRUE; + gchar *textview_name; + GtkWidget *textview; + GtkTextBuffer *text_buffer; - gui = glade_xml_new (EVOLUTION_GLADEDIR "/contact-editor.glade", NULL); - e_contact_editor->gui = gui; + textview_name = g_strdup_printf ( + "textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->builder, textview_name); + g_free (textview_name); - setup_tab_order(gui); + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); + gtk_text_buffer_set_text (text_buffer, label ? label : "", -1); +} - e_contact_editor->app = glade_xml_get_widget (gui, "contact editor"); +static void +fill_in_address_field (EContactEditor *editor, + gint record, + const gchar *widget_field_name, + const gchar *string) +{ + gchar *entry_name; + GtkWidget *entry; - e_container_foreach_leaf (GTK_CONTAINER (e_contact_editor->app), - (GtkCallback) add_field_callback, - e_contact_editor); + entry_name = g_strdup_printf ( + "entry-%s-%s", address_name[record], widget_field_name); + entry = e_builder_get_widget (editor->builder, entry_name); + g_free (entry_name); - _replace_buttons(e_contact_editor); - add_lists (e_contact_editor); - set_entry_changed_signals(e_contact_editor); + set_entry_text (editor, GTK_ENTRY (entry), string); +} - wants_html = glade_xml_get_widget(e_contact_editor->gui, "checkbutton-htmlmail"); - if (wants_html && GTK_IS_TOGGLE_BUTTON(wants_html)) - gtk_signal_connect(GTK_OBJECT(wants_html), "toggled", - wants_html_changed, e_contact_editor); +static void +fill_in_address_record (EContactEditor *editor, + gint record) +{ + EContactAddress *address; + gchar *address_label; + + address = e_contact_get (editor->contact, addresses[record]); + address_label = e_contact_get (editor->contact, address_labels[record]); + + if (address && + (!STRING_IS_EMPTY (address->street) || + !STRING_IS_EMPTY (address->ext) || + !STRING_IS_EMPTY (address->locality) || + !STRING_IS_EMPTY (address->region) || + !STRING_IS_EMPTY (address->code) || + !STRING_IS_EMPTY (address->po) || + !STRING_IS_EMPTY (address->country))) { + fill_in_address_textview (editor, record, address); + fill_in_address_field (editor, record, "city", address->locality); + fill_in_address_field (editor, record, "state", address->region); + fill_in_address_field (editor, record, "zip", address->code); + fill_in_address_field (editor, record, "country", address->country); + fill_in_address_field (editor, record, "pobox", address->po); + } else if (!STRING_IS_EMPTY (address_label)) { + fill_in_address_label_textview (editor, record, address_label); + } - widget = glade_xml_get_widget(e_contact_editor->gui, "checkbutton-mailingaddress"); - if (widget && GTK_IS_TOGGLE_BUTTON(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "toggled", - address_mailing_changed, e_contact_editor); - - widget = glade_xml_get_widget(e_contact_editor->gui, "button-fullname"); - if (widget && GTK_IS_BUTTON(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "clicked", - full_name_clicked, e_contact_editor); + g_free (address_label); + if (address) + g_boxed_free (e_contact_address_get_type (), address); +} - widget = glade_xml_get_widget(e_contact_editor->gui, "button-fulladdr"); - if (widget && GTK_IS_BUTTON(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "clicked", - full_addr_clicked, e_contact_editor); +static void +fill_in_address (EContactEditor *editor) +{ + gint i; - widget = glade_xml_get_widget(e_contact_editor->gui, "button-categories"); - if (widget && GTK_IS_BUTTON(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "clicked", - categories_clicked, e_contact_editor); + for (i = 0; i < ADDRESS_SLOTS; i++) + fill_in_address_record (editor, i); +} - widget = glade_xml_get_widget(e_contact_editor->gui, "button-contacts"); - if (widget && GTK_IS_BUTTON(widget)) - gtk_signal_connect(GTK_OBJECT(widget), "clicked", - contacts_clicked, e_contact_editor); +static void +extract_address_textview (EContactEditor *editor, + gint record, + EContactAddress *address) +{ + gchar *textview_name; + GtkWidget *textview; + GtkTextBuffer *text_buffer; + GtkTextIter iter_1, iter_2; + textview_name = g_strdup_printf ("textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->builder, textview_name); + g_free (textview_name); - /* Construct the app */ - bonobo_win = bonobo_window_new ("contact-editor-dialog", _("Contact Editor")); + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); + gtk_text_buffer_get_start_iter (text_buffer, &iter_1); - /* FIXME: The sucking bit */ - { - GtkWidget *contents; + /* Skip blank lines */ + while (gtk_text_iter_get_chars_in_line (&iter_1) < 1 && + !gtk_text_iter_is_end (&iter_1)) + gtk_text_iter_forward_line (&iter_1); - contents = gnome_dock_get_client_area ( - GNOME_DOCK (GNOME_APP (e_contact_editor->app)->dock)); - if (!contents) { - g_message ("contact_editor_construct(): Could not get contents"); - return; - } - gtk_widget_ref (contents); - gtk_container_remove (GTK_CONTAINER (contents->parent), contents); - bonobo_window_set_contents (BONOBO_WINDOW (bonobo_win), contents); - gtk_widget_destroy (e_contact_editor->app); - e_contact_editor->app = bonobo_win; - } + if (gtk_text_iter_is_end (&iter_1)) + return; + + iter_2 = iter_1; + gtk_text_iter_forward_to_line_end (&iter_2); - /* Build the menu and toolbar */ + /* Extract street (first line of text) */ + address->street = gtk_text_iter_get_text (&iter_1, &iter_2); - container = bonobo_ui_container_new (); - bonobo_ui_container_set_win (container, BONOBO_WINDOW (e_contact_editor->app)); + iter_1 = iter_2; + gtk_text_iter_forward_line (&iter_1); - e_contact_editor->uic = bonobo_ui_component_new_default (); - if (!e_contact_editor->uic) { - g_message ("e_contact_editor_init(): eeeeek, could not create the UI handler!"); + if (gtk_text_iter_is_end (&iter_1)) return; - } - bonobo_ui_component_set_container (e_contact_editor->uic, - bonobo_object_corba_objref ( - BONOBO_OBJECT (container))); - create_ui (e_contact_editor); + gtk_text_iter_forward_to_end (&iter_2); - widget = glade_xml_get_widget(e_contact_editor->gui, "entry-fullname"); - if (widget) - gtk_widget_grab_focus (widget); + /* Extract extended address (remaining lines of text) */ + address->ext = gtk_text_iter_get_text (&iter_1, &iter_2); +} - /* Connect to the deletion of the dialog */ +static gchar * +extract_address_field (EContactEditor *editor, + gint record, + const gchar *widget_field_name) +{ + gchar *entry_name; + GtkWidget *entry; - gtk_signal_connect (GTK_OBJECT (e_contact_editor->app), "delete_event", - GTK_SIGNAL_FUNC (app_delete_event_cb), e_contact_editor); + entry_name = g_strdup_printf ( + "entry-%s-%s", address_name[record], widget_field_name); + entry = e_builder_get_widget (editor->builder, entry_name); + g_free (entry_name); - /* set the icon */ - icon_path = g_concat_dir_and_file (EVOLUTION_ICONSDIR, "evolution-contacts-mini.png"); - gnome_window_icon_set_from_file (GTK_WINDOW (e_contact_editor->app), icon_path); - g_free (icon_path); + return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); } -void -e_contact_editor_destroy (GtkObject *object) { - EContactEditor *e_contact_editor = E_CONTACT_EDITOR(object); +static gchar * +append_to_address_label (gchar *address_label, + const gchar *part, + gboolean newline) +{ + gchar *new_address_label; - if (e_contact_editor->writable_fields) { - gtk_object_unref(GTK_OBJECT(e_contact_editor->writable_fields)); - } - if (e_contact_editor->email_list) { - g_list_foreach(e_contact_editor->email_list, (GFunc) g_free, NULL); - g_list_free(e_contact_editor->email_list); - } - if (e_contact_editor->email_info) { - g_free(e_contact_editor->email_info); - } - if (e_contact_editor->email_popup) { - gtk_widget_unref(e_contact_editor->email_popup); - } - - if (e_contact_editor->phone_list) { - g_list_foreach(e_contact_editor->phone_list, (GFunc) g_free, NULL); - g_list_free(e_contact_editor->phone_list); - } - if (e_contact_editor->phone_info) { - g_free(e_contact_editor->phone_info); + if (STRING_IS_EMPTY (part)) + return address_label; + + if (address_label) + new_address_label = g_strjoin ( + newline ? "\n" : ", ", + address_label, part, NULL); + else + new_address_label = g_strdup (part); + + g_free (address_label); + return new_address_label; +} + +static void +set_address_label (EContact *contact, + EContactField field, + EContactAddress *address) +{ + gchar *address_label = NULL; + gboolean format_address; + GSettings *settings; + + if (!address) { + e_contact_set (contact, field, NULL); + return; } - if (e_contact_editor->phone_popup) { - gtk_widget_unref(e_contact_editor->phone_popup); + + settings = g_settings_new ("org.gnome.evolution.addressbook"); + format_address = g_settings_get_boolean (settings, "address-formatting"); + g_object_unref (settings); + + if (format_address) { + address_label = eab_format_address ( + contact, + (field == E_CONTACT_ADDRESS_LABEL_WORK) ? + E_CONTACT_ADDRESS_WORK : + E_CONTACT_ADDRESS_HOME); } - - if (e_contact_editor->address_list) { - g_list_foreach(e_contact_editor->address_list, (GFunc) g_free, NULL); - g_list_free(e_contact_editor->address_list); + + if (!format_address || !address_label) { + address_label = append_to_address_label ( + address_label, address->street, TRUE); + address_label = append_to_address_label ( + address_label, address->ext, TRUE); + address_label = append_to_address_label ( + address_label, address->locality, TRUE); + address_label = append_to_address_label ( + address_label, address->region, FALSE); + address_label = append_to_address_label ( + address_label, address->code, TRUE); + address_label = append_to_address_label ( + address_label, address->po, TRUE); + address_label = append_to_address_label ( + address_label, address->country, TRUE); } - if (e_contact_editor->address_info) { - g_free(e_contact_editor->address_info); + + e_contact_set (contact, field, address_label); + g_free (address_label); +} + +static void +extract_address_record (EContactEditor *editor, + gint record) +{ + EContactAddress *address; + + address = g_new0 (EContactAddress, 1); + + extract_address_textview (editor, record, address); + address->locality = extract_address_field (editor, record, "city"); + address->region = extract_address_field (editor, record, "state"); + address->code = extract_address_field (editor, record, "zip"); + address->country = extract_address_field (editor, record, "country"); + address->po = extract_address_field (editor, record, "pobox"); + + if (!STRING_IS_EMPTY (address->street) || + !STRING_IS_EMPTY (address->ext) || + !STRING_IS_EMPTY (address->locality) || + !STRING_IS_EMPTY (address->region) || + !STRING_IS_EMPTY (address->code) || + !STRING_IS_EMPTY (address->po) || + !STRING_IS_EMPTY (address->country)) { + e_contact_set (editor->contact, addresses[record], address); + set_address_label (editor->contact, address_labels[record], address); } - if (e_contact_editor->address_popup) { - gtk_widget_unref(e_contact_editor->address_popup); + else { + e_contact_set (editor->contact, addresses[record], NULL); + set_address_label (editor->contact, address_labels[record], NULL); } - - if (e_contact_editor->simple) - gtk_object_unref(GTK_OBJECT(e_contact_editor->simple)); - if (e_contact_editor->book) - gtk_object_unref(GTK_OBJECT(e_contact_editor->book)); + g_boxed_free (e_contact_address_get_type (), address); +} - e_card_name_unref(e_contact_editor->name); - g_free (e_contact_editor->company); +static void +extract_address (EContactEditor *editor) +{ + gint i; - gtk_object_unref(GTK_OBJECT(e_contact_editor->gui)); + for (i = 0; i < ADDRESS_SLOTS; i++) + extract_address_record (editor, i); } static void -command_state_changed (EContactEditor *ce) +sensitize_address_textview (EContactEditor *editor, + gint record, + gboolean enabled) { - bonobo_ui_component_set_prop (ce->uic, - "/commands/ContactEditorSaveClose", - "sensitive", - ce->changed ? "1" : "0", NULL); - bonobo_ui_component_set_prop (ce->uic, - "/commands/ContactEditorSave", - "sensitive", - ce->changed ? "1" : "0", NULL); - bonobo_ui_component_set_prop (ce->uic, - "/commands/ContactEditorDelete", - "sensitive", - (ce->editable && !ce->is_new_card) ? "1" : "0", NULL); + gchar *widget_name; + GtkWidget *textview; + GtkWidget *label; + + widget_name = g_strdup_printf ("textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("label-%s-address", address_name[record]); + label = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); + + gtk_text_view_set_editable (GTK_TEXT_VIEW (textview), enabled); + gtk_widget_set_sensitive (label, enabled); } static void -supported_fields_cb (EBook *book, EBookStatus status, - EList *fields, EContactEditor *ce) +sensitize_address_field (EContactEditor *editor, + gint record, + const gchar *widget_field_name, + gboolean enabled) { - gtk_object_set (GTK_OBJECT (ce), - "writable_fields", fields, - NULL); + gchar *widget_name; + GtkWidget *entry; + GtkWidget *label; + + widget_name = g_strdup_printf ( + "entry-%s-%s", address_name[record], widget_field_name); + entry = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - e_contact_editor_show (ce); + widget_name = g_strdup_printf ( + "label-%s-%s", address_name[record], widget_field_name); + label = e_builder_get_widget (editor->builder, widget_name); + g_free (widget_name); - command_state_changed (ce); + gtk_editable_set_editable (GTK_EDITABLE (entry), enabled); + gtk_widget_set_sensitive (label, enabled); } static void -contact_editor_destroy_notify (void *data) +sensitize_address_record (EContactEditor *editor, + gint record, + gboolean enabled) { - EContactEditor *ce = E_CONTACT_EDITOR (data); - - all_contact_editors = g_slist_remove (all_contact_editors, ce); + sensitize_address_textview (editor, record, enabled); + sensitize_address_field (editor, record, "city", enabled); + sensitize_address_field (editor, record, "state", enabled); + sensitize_address_field (editor, record, "zip", enabled); + sensitize_address_field (editor, record, "country", enabled); + sensitize_address_field (editor, record, "pobox", enabled); } -EContactEditor * -e_contact_editor_new (EBook *book, - ECard *card, - gboolean is_new_card, - gboolean editable) +static void +sensitize_address (EContactEditor *editor) { - EContactEditor *ce; + gint i; - g_return_val_if_fail (E_IS_BOOK (book), NULL); - g_return_val_if_fail (E_IS_CARD (card), NULL); + for (i = 0; i < ADDRESS_SLOTS; i++) { + gboolean enabled = TRUE; - ce = E_CONTACT_EDITOR (gtk_type_new (E_CONTACT_EDITOR_TYPE)); + if (!editor->target_editable || + !(is_field_supported (editor, addresses[i]) || + is_field_supported (editor, address_labels[i]))) + enabled = FALSE; - all_contact_editors = g_slist_prepend (all_contact_editors, ce); - gtk_object_weakref (GTK_OBJECT (ce), contact_editor_destroy_notify, ce); + sensitize_address_record (editor, i, enabled); + } +} - gtk_object_set (GTK_OBJECT (ce), - "book", book, - "card", card, - "is_new_card", is_new_card, - "editable", editable, - NULL); +typedef struct { + const gchar *widget_name; + gint field_id; /* EContactField or -1 */ + gboolean process_data; /* If we should extract/fill in contents */ + gboolean desensitize_for_read_only; +} +FieldMapping; + +/* Table of widgets that interact with simple fields. This table is used to: + * + * - Fill in data. + * - Extract data. + * - Set sensitivity based on backend capabilities. + * - Set sensitivity based on book writeability. */ + +static FieldMapping simple_field_map[] = { + { "entry-homepage", E_CONTACT_HOMEPAGE_URL, TRUE, TRUE }, + { "accellabel-homepage", E_CONTACT_HOMEPAGE_URL, FALSE, TRUE }, + + { "entry-jobtitle", E_CONTACT_TITLE, TRUE, TRUE }, + { "label-jobtitle", E_CONTACT_TITLE, FALSE, TRUE }, + + { "entry-company", E_CONTACT_ORG, TRUE, TRUE }, + { "label-company", E_CONTACT_ORG, FALSE, TRUE }, + + { "entry-department", E_CONTACT_ORG_UNIT, TRUE, TRUE }, + { "label-department", E_CONTACT_ORG_UNIT, FALSE, TRUE }, + + { "entry-profession", E_CONTACT_ROLE, TRUE, TRUE }, + { "label-profession", E_CONTACT_ROLE, FALSE, TRUE }, + + { "entry-manager", E_CONTACT_MANAGER, TRUE, TRUE }, + { "label-manager", E_CONTACT_MANAGER, FALSE, TRUE }, + + { "entry-assistant", E_CONTACT_ASSISTANT, TRUE, TRUE }, + { "label-assistant", E_CONTACT_ASSISTANT, FALSE, TRUE }, - if (book) - e_book_get_supported_fields (book, (EBookFieldsCallback)supported_fields_cb, ce); + { "entry-nickname", E_CONTACT_NICKNAME, TRUE, TRUE }, + { "label-nickname", E_CONTACT_NICKNAME, FALSE, TRUE }, - return ce; + { "dateedit-birthday", E_CONTACT_BIRTH_DATE, TRUE, TRUE }, + { "label-birthday", E_CONTACT_BIRTH_DATE, FALSE, TRUE }, + + { "dateedit-anniversary", E_CONTACT_ANNIVERSARY, TRUE, TRUE }, + { "label-anniversary", E_CONTACT_ANNIVERSARY, FALSE, TRUE }, + + { "entry-spouse", E_CONTACT_SPOUSE, TRUE, TRUE }, + { "label-spouse", E_CONTACT_SPOUSE, FALSE, TRUE }, + + { "entry-office", E_CONTACT_OFFICE, TRUE, TRUE }, + { "label-office", E_CONTACT_OFFICE, FALSE, TRUE }, + + { "text-comments", E_CONTACT_NOTE, TRUE, TRUE }, + + { "entry-fullname", E_CONTACT_FULL_NAME, TRUE, TRUE }, + { "button-fullname", E_CONTACT_FULL_NAME, FALSE, TRUE }, + + { "entry-categories", E_CONTACT_CATEGORIES, TRUE, TRUE }, + { "button-categories", E_CONTACT_CATEGORIES, FALSE, TRUE }, + + { "entry-weblog", E_CONTACT_BLOG_URL, TRUE, TRUE }, + { "label-weblog", E_CONTACT_BLOG_URL, FALSE, TRUE }, + + { "entry-caluri", E_CONTACT_CALENDAR_URI, TRUE, TRUE }, + { "label-caluri", E_CONTACT_CALENDAR_URI, FALSE, TRUE }, + + { "entry-fburl", E_CONTACT_FREEBUSY_URL, TRUE, TRUE }, + { "label-fburl", E_CONTACT_FREEBUSY_URL, FALSE, TRUE }, + + { "entry-videourl", E_CONTACT_VIDEO_URL, TRUE, TRUE }, + { "label-videourl", E_CONTACT_VIDEO_URL, FALSE, TRUE }, + + { "checkbutton-htmlmail", E_CONTACT_WANTS_HTML, TRUE, TRUE }, + + { "image-chooser", E_CONTACT_PHOTO, TRUE, TRUE }, + { "button-image", E_CONTACT_PHOTO, FALSE, TRUE }, + + { "combo-file-as", E_CONTACT_FILE_AS, TRUE, TRUE }, + { "accellabel-fileas", E_CONTACT_FILE_AS, FALSE, TRUE }, +}; + +static void +init_simple_field (EContactEditor *editor, + GtkWidget *widget) +{ + GObject *changed_object = NULL; + + if (GTK_IS_ENTRY (widget)) { + changed_object = G_OBJECT (widget); + g_signal_connect_swapped ( + widget, "activate", + G_CALLBACK (entry_activated), editor); + + } else if (GTK_IS_COMBO_BOX (widget)) { + changed_object = G_OBJECT (widget); + g_signal_connect_swapped ( + gtk_bin_get_child (GTK_BIN (widget)), "activate", + G_CALLBACK (entry_activated), editor); + + } else if (GTK_IS_TEXT_VIEW (widget)) { + changed_object = G_OBJECT ( + gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget))); + + } else if (E_IS_URL_ENTRY (widget)) { + changed_object = G_OBJECT (widget); + g_signal_connect_swapped ( + changed_object, "activate", + G_CALLBACK (entry_activated), editor); + + } else if (E_IS_DATE_EDIT (widget)) { + changed_object = G_OBJECT (widget); + + } else if (E_IS_IMAGE_CHOOSER (widget)) { + changed_object = G_OBJECT (widget); + g_signal_connect ( + widget, "changed", + G_CALLBACK (image_chooser_changed), editor); + + } else if (GTK_IS_TOGGLE_BUTTON (widget)) { + g_signal_connect ( + widget, "toggled", + G_CALLBACK (object_changed), editor); + } + + if (changed_object) + g_signal_connect ( + changed_object, "changed", + G_CALLBACK (object_changed), editor); } static void -e_contact_editor_set_arg (GtkObject *o, GtkArg *arg, guint arg_id) +fill_in_simple_field (EContactEditor *editor, + GtkWidget *widget, + gint field_id) { - EContactEditor *editor; + EContact *contact; - editor = E_CONTACT_EDITOR (o); - - switch (arg_id){ - case ARG_BOOK: - if (editor->book) - gtk_object_unref(GTK_OBJECT(editor->book)); - editor->book = E_BOOK(GTK_VALUE_OBJECT (*arg)); - gtk_object_ref (GTK_OBJECT (editor->book)); - /* XXX more here about editable/etc. */ - break; - case ARG_CARD: - if (editor->card) - gtk_object_unref(GTK_OBJECT(editor->card)); - editor->card = e_card_duplicate(E_CARD(GTK_VALUE_OBJECT (*arg))); - gtk_object_set(GTK_OBJECT(editor->simple), - "card", editor->card, - NULL); - fill_in_info(editor); - editor->changed = FALSE; - break; + contact = editor->contact; - case ARG_IS_NEW_CARD: - editor->is_new_card = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - break; + g_signal_handlers_block_matched ( + widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); - case ARG_EDITABLE: { - gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - gboolean changed = (editor->editable != new_value); + if (GTK_IS_ENTRY (widget)) { + gchar *text = e_contact_get (contact, field_id); + gtk_entry_set_text (GTK_ENTRY (widget), STRING_MAKE_NON_NULL (text)); + g_free (text); + + } else if (GTK_IS_COMBO_BOX (widget)) { + gchar *text = e_contact_get (contact, field_id); + gtk_entry_set_text ( + GTK_ENTRY (gtk_bin_get_child (GTK_BIN (widget))), + STRING_MAKE_NON_NULL (text)); + g_free (text); + + } else if (GTK_IS_TEXT_VIEW (widget)) { + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); + gchar *text = e_contact_get (contact, field_id); + gtk_text_buffer_set_text (buffer, STRING_MAKE_NON_NULL (text), -1); + g_free (text); + + } else if (E_IS_URL_ENTRY (widget)) { + gchar *text = e_contact_get (contact, field_id); + gtk_entry_set_text ( + GTK_ENTRY (widget), STRING_MAKE_NON_NULL (text)); + g_free (text); + + } else if (E_IS_DATE_EDIT (widget)) { + EContactDate *date = e_contact_get (contact, field_id); + if (date) + e_date_edit_set_date ( + E_DATE_EDIT (widget), + date->year, date->month, date->day); + else + e_date_edit_set_time (E_DATE_EDIT (widget), -1); + + e_contact_date_free (date); + + } else if (E_IS_IMAGE_CHOOSER (widget)) { + EContactPhoto *photo = e_contact_get (contact, field_id); + editor->image_set = FALSE; + if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) { + e_image_chooser_set_image_data ( + E_IMAGE_CHOOSER (widget), + (gchar *) photo->data.inlined.data, + photo->data.inlined.length); + editor->image_set = TRUE; + } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI) { + gchar *file_name = g_filename_from_uri (photo->data.uri, NULL, NULL); + if (file_name) { + e_image_chooser_set_from_file ( + E_IMAGE_CHOOSER (widget), + file_name); + editor->image_set = TRUE; + g_free (file_name); + } + } - editor->editable = new_value; + if (!editor->image_set) { + gchar *file_name; - if (changed) { - set_editable (editor); - command_state_changed (editor); + file_name = e_icon_factory_get_icon_filename ( + "avatar-default", GTK_ICON_SIZE_DIALOG); + e_image_chooser_set_from_file ( + E_IMAGE_CHOOSER (widget), file_name); + editor->image_set = FALSE; + g_free (file_name); } - break; - } - case ARG_CHANGED: { - gboolean new_value = GTK_VALUE_BOOL (*arg) ? TRUE : FALSE; - gboolean changed = (editor->changed != new_value); + editor->image_changed = FALSE; + e_contact_photo_free (photo); - editor->changed = new_value; + } else if (GTK_IS_TOGGLE_BUTTON (widget)) { + gboolean val = e_contact_get (contact, field_id) != NULL; - if (changed) - command_state_changed (editor); - break; - } - case ARG_WRITABLE_FIELDS: - if (editor->writable_fields) - gtk_object_unref(GTK_OBJECT(editor->writable_fields)); - editor->writable_fields = GTK_VALUE_POINTER (*arg); - if (editor->writable_fields) - gtk_object_ref (GTK_OBJECT (editor->writable_fields)); - else - editor->writable_fields = e_list_new(NULL, NULL, NULL); - enable_writable_fields (editor); - break; + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), val); + + } else { + g_warning (G_STRLOC ": Unhandled widget class in mappings!"); } + + g_signal_handlers_unblock_matched ( + widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); } static void -e_contact_editor_get_arg (GtkObject *object, GtkArg *arg, guint arg_id) +extract_simple_field (EContactEditor *editor, + GtkWidget *widget, + gint field_id) { - EContactEditor *e_contact_editor; + EContact *contact; - e_contact_editor = E_CONTACT_EDITOR (object); + contact = editor->contact; - switch (arg_id) { - case ARG_BOOK: - GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_contact_editor->book); - break; + if (GTK_IS_ENTRY (widget)) { + const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget)); + e_contact_set (contact, field_id, (gchar *) text); - case ARG_CARD: - e_card_simple_sync_card(e_contact_editor->simple); - extract_info(e_contact_editor); - GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_contact_editor->card); - break; + } else if (GTK_IS_COMBO_BOX_TEXT (widget)) { + gchar *text = NULL; - case ARG_IS_NEW_CARD: - GTK_VALUE_BOOL (*arg) = e_contact_editor->is_new_card ? TRUE : FALSE; - break; + if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget))) { + GtkWidget *entry = gtk_bin_get_child (GTK_BIN (widget)); - case ARG_EDITABLE: - GTK_VALUE_BOOL (*arg) = e_contact_editor->editable ? TRUE : FALSE; - break; + text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + } - case ARG_CHANGED: - GTK_VALUE_BOOL (*arg) = e_contact_editor->changed ? TRUE : FALSE; - break; + if (!text) + text = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (widget)); + + e_contact_set (contact, field_id, text); + + g_free (text); + } else if (GTK_IS_COMBO_BOX (widget)) { + GtkTreeIter iter; + gchar *text = NULL; + + if (gtk_combo_box_get_has_entry (GTK_COMBO_BOX (widget))) { + GtkWidget *entry = gtk_bin_get_child (GTK_BIN (widget)); + + text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + } + + if (!text && gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) { + GtkListStore *store; - case ARG_WRITABLE_FIELDS: - if (e_contact_editor->writable_fields) - GTK_VALUE_POINTER (*arg) = e_list_duplicate (e_contact_editor->writable_fields); + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (widget))); + + gtk_tree_model_get ( + GTK_TREE_MODEL (store), &iter, + 0, &text, + -1); + } + + e_contact_set (contact, field_id, text); + + g_free (text); + + } else if (GTK_IS_TEXT_VIEW (widget)) { + GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)); + GtkTextIter start, end; + gchar *text; + + gtk_text_buffer_get_start_iter (buffer, &start); + gtk_text_buffer_get_end_iter (buffer, &end); + text = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); + e_contact_set (contact, field_id, text); + g_free (text); + + } else if (E_IS_URL_ENTRY (widget)) { + const gchar *text = gtk_entry_get_text (GTK_ENTRY (widget)); + e_contact_set (contact, field_id, (gchar *) text); + + } else if (E_IS_DATE_EDIT (widget)) { + EContactDate date; + if (e_date_edit_get_date ( + E_DATE_EDIT (widget), + (gint *) &date.year, + (gint *) &date.month, + (gint *) &date.day)) + e_contact_set (contact, field_id, &date); else - GTK_VALUE_POINTER (*arg) = NULL; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; + e_contact_set (contact, field_id, NULL); + + } else if (E_IS_IMAGE_CHOOSER (widget)) { + EContactPhoto photo; + photo.type = E_CONTACT_PHOTO_TYPE_INLINED; + photo.data.inlined.mime_type = NULL; + if (editor->image_changed) { + gchar *img_buff = NULL; + if (editor->image_set && + e_image_chooser_get_image_data ( + E_IMAGE_CHOOSER (widget), + &img_buff, &photo.data.inlined.length)) { + GdkPixbuf *pixbuf, *new; + GdkPixbufLoader *loader = gdk_pixbuf_loader_new (); + + photo.data.inlined.data = (guchar *) img_buff; + img_buff = NULL; + gdk_pixbuf_loader_write ( + loader, + photo.data.inlined.data, + photo.data.inlined.length, NULL); + gdk_pixbuf_loader_close (loader, NULL); + + pixbuf = gdk_pixbuf_loader_get_pixbuf (loader); + if (pixbuf) { + gint width, height, prompt_response; + + g_object_ref (pixbuf); + + height = gdk_pixbuf_get_height (pixbuf); + width = gdk_pixbuf_get_width (pixbuf); + if ((height > 96 || width > 96)) { + + prompt_response = + e_alert_run_dialog_for_args + (GTK_WINDOW (editor->app), + "addressbook:prompt-resize", + NULL); + + if (prompt_response == GTK_RESPONSE_YES) { + if (width > height) { + height = height * 96 / width; + width = 96; + } else { + width = width *96 / height; + height = 96; + } + + new = e_icon_factory_pixbuf_scale (pixbuf, width, height); + if (new) { + GdkPixbufFormat *format = + gdk_pixbuf_loader_get_format (loader); + gchar *format_name = + gdk_pixbuf_format_get_name (format); + g_free (photo.data.inlined.data); + gdk_pixbuf_save_to_buffer ( + new, &img_buff, + &photo.data.inlined.length, + format_name, NULL, NULL); + photo.data.inlined.data = (guchar *) img_buff; + img_buff = NULL; + g_free (format_name); + g_object_unref (new); + } + } else if (prompt_response == GTK_RESPONSE_CANCEL) { + g_object_unref (pixbuf); + g_object_unref (loader); + return; + } + } + g_object_unref (pixbuf); + } + editor->image_changed = FALSE; + g_object_unref (loader); + + e_contact_set (contact, field_id, &photo); + + g_free (photo.data.inlined.data); + + } else { + editor->image_changed = FALSE; + e_contact_set (contact, E_CONTACT_PHOTO, NULL); + } + } + + } else if (GTK_IS_TOGGLE_BUTTON (widget)) { + gboolean val; + + val = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget)); + e_contact_set (contact, field_id, val ? (gpointer) 1 : NULL); + + } else { + g_warning (G_STRLOC ": Unhandled widget class in mappings!"); } } static void -_popup_position(GtkMenu *menu, - gint *x, - gint *y, - gpointer data) +sensitize_simple_field (GtkWidget *widget, + gboolean enabled) +{ + if (GTK_IS_ENTRY (widget)) + gtk_editable_set_editable (GTK_EDITABLE (widget), enabled); + else if (GTK_IS_TEXT_VIEW (widget)) + gtk_text_view_set_editable (GTK_TEXT_VIEW (widget), enabled); + else if (E_IS_DATE_EDIT (widget)) + e_date_edit_set_editable (E_DATE_EDIT (widget), enabled); + else + gtk_widget_set_sensitive (widget, enabled); +} + +static void +init_simple (EContactEditor *editor) { - GtkWidget *button = GTK_WIDGET(data); - GtkRequisition request; - int mh, mw; - gdk_window_get_origin (button->window, x, y); - *x += button->allocation.width; - *y += button->allocation.height; + GtkWidget *widget; + gint i; + + for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) { + widget = e_builder_get_widget ( + editor->builder, simple_field_map[i].widget_name); + if (!widget) + continue; - gtk_widget_size_request(GTK_WIDGET(menu), &request); + init_simple_field (editor, widget); + } + + /* --- Special cases --- */ + + /* Update file_as */ - mh = request.height; - mw = request.width; + widget = e_builder_get_widget (editor->builder, "entry-fullname"); + g_signal_connect ( + widget, "changed", + G_CALLBACK (name_entry_changed), editor); - *x -= mw; - if (*x < 0) - *x = 0; - - if (*y < 0) - *y = 0; - - if ((*x + mw) > gdk_screen_width ()) - *x = gdk_screen_width () - mw; - - if ((*y + mh) > gdk_screen_height ()) - *y = gdk_screen_height () - mh; + widget = e_builder_get_widget (editor->builder, "combo-file-as"); + gtk_combo_box_set_entry_text_column (GTK_COMBO_BOX (widget), 0); + g_signal_connect ( + widget, "changed", + G_CALLBACK (file_as_combo_changed), editor); + + widget = e_builder_get_widget (editor->builder, "entry-company"); + g_signal_connect ( + widget, "changed", + G_CALLBACK (company_entry_changed), editor); } -static gint -_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor, GtkWidget *popup, GList **list, GnomeUIInfo **info, gchar *label, gchar *entry, gchar *dialog_title) -{ - gint menu_item; - gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "button_press_event"); - gtk_widget_realize(popup); - menu_item = gnome_popup_menu_do_popup_modal(popup, _popup_position, widget, button, editor); - if ( menu_item != -1 ) { -#if 0 - if (menu_item == g_list_length (*list)) { - e_contact_editor_build_dialog(editor, entry, label, dialog_title, list, info); - } else { -#endif - GtkWidget *label_widget = glade_xml_get_widget(editor->gui, label); - if (label_widget && GTK_IS_LABEL(label_widget)) { - gtk_object_set(GTK_OBJECT(label_widget), - "label", _(g_list_nth_data(*list, menu_item)), - NULL); - } -#if 0 - } -#endif +static void +fill_in_simple (EContactEditor *editor) +{ + EContactName *name; + gchar *filename; + gint i; + + for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) { + GtkWidget *widget; + + if (simple_field_map[i].field_id < 0 || + !simple_field_map[i].process_data) + continue; + + widget = e_builder_get_widget ( + editor->builder, simple_field_map[i].widget_name); + if (!widget) + continue; + + fill_in_simple_field ( + editor, widget, simple_field_map[i].field_id); } - return menu_item; + + /* --- Special cases --- */ + + /* Update broken-up name */ + + g_object_get (editor->contact, "name", &name, NULL); + + if (editor->name) + e_contact_name_free (editor->name); + + editor->name = name; + + /* Update the contact editor title */ + + filename = (gchar *) e_contact_get (editor->contact, E_CONTACT_FILE_AS); + + if (filename) { + gchar *title; + title = g_strdup_printf (_("Contact Editor - %s"), filename); + gtk_window_set_title (GTK_WINDOW (editor->app), title); + g_free (title); + g_free (filename); + } else + gtk_window_set_title ( + GTK_WINDOW (editor->app), _("Contact Editor")); + + /* Update file_as combo options */ + + update_file_as_combo (editor); } static void -e_contact_editor_build_ui_info(GList *list, GnomeUIInfo **infop) +extract_simple (EContactEditor *editor) { - GnomeUIInfo *info; - GnomeUIInfo singleton = { GNOME_APP_UI_TOGGLEITEM, NULL, NULL, NULL, NULL, NULL, GNOME_APP_PIXMAP_NONE, 0, 0, 0, NULL }; - GnomeUIInfo end = GNOMEUIINFO_END; - int length; - int i; + gint i; + + for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) { + GtkWidget *widget; - info = *infop; + if (simple_field_map[i].field_id < 0 || + !simple_field_map[i].process_data) + continue; + + widget = e_builder_get_widget ( + editor->builder, simple_field_map[i].widget_name); + if (!widget) + continue; - if ( info ) - g_free(info); - length = g_list_length( list ); - info = g_new(GnomeUIInfo, length + 2); - for (i = 0; i < length; i++) { - info[i] = singleton; - info[i].label = _(list->data); - list = list->next; + extract_simple_field ( + editor, widget, simple_field_map[i].field_id); } - info[i] = end; - *infop = info; + /* Special cases */ + + e_contact_set (editor->contact, E_CONTACT_NAME, editor->name); } static void -e_contact_editor_build_phone_ui (EContactEditor *editor) +sensitize_simple (EContactEditor *editor) { - int i; + gint i; - if (editor->phone_list == NULL) { - static char *info[] = { - N_("Assistant"), - N_("Business"), - N_("Business 2"), - N_("Business Fax"), - N_("Callback"), - N_("Car"), - N_("Company"), - N_("Home"), - N_("Home 2"), - N_("Home Fax"), - N_("ISDN"), - N_("Mobile"), - N_("Other"), - N_("Other Fax"), - N_("Pager"), - N_("Primary"), - N_("Radio"), - N_("Telex"), - N_("TTY/TDD") - }; - - for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) { - editor->phone_list = g_list_append(editor->phone_list, g_strdup(info[i])); - } - } - if (editor->phone_info == NULL) { - e_contact_editor_build_ui_info(editor->phone_list, &editor->phone_info); - - if ( editor->phone_popup ) - gtk_widget_unref(editor->phone_popup); - - editor->phone_popup = gnome_popup_menu_new(editor->phone_info); + for (i = 0; i < G_N_ELEMENTS (simple_field_map); i++) { + GtkWidget *widget; + gboolean enabled = TRUE; + + widget = e_builder_get_widget ( + editor->builder, simple_field_map[i].widget_name); + if (!widget) + continue; + + if (simple_field_map[i].field_id >= 0 && + !is_field_supported (editor, simple_field_map[i].field_id)) + enabled = FALSE; + + if (simple_field_map[i].desensitize_for_read_only && + !editor->target_editable) + enabled = FALSE; + + sensitize_simple_field (widget, enabled); } } static void -e_contact_editor_build_email_ui (EContactEditor *editor) +fill_in_all (EContactEditor *editor) { - int i; + fill_in_source_field (editor); + fill_in_simple (editor); + fill_in_email (editor); + fill_in_phone (editor); + fill_in_im (editor); + fill_in_address (editor); +} - if (editor->email_list == NULL) { - static char *info[] = { - N_("Primary Email"), - N_("Email 2"), - N_("Email 3") - }; - - for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) { - editor->email_list = g_list_append(editor->email_list, g_strdup(info[i])); - } +static void +extract_all (EContactEditor *editor) +{ + extract_simple (editor); + extract_email (editor); + extract_phone (editor); + extract_im (editor); + extract_address (editor); +} + +static void +sensitize_all (EContactEditor *editor) +{ + sensitize_ok (editor); + sensitize_simple (editor); + sensitize_email (editor); + sensitize_phone (editor); + sensitize_im (editor); + sensitize_address (editor); +} + +static void +init_all (EContactEditor *editor) +{ + const gchar *contents[] = { "viewport1", "viewport2", "viewport3", "text-comments" }; + gint ii; + GtkRequisition tab_req, requisition; + GtkWidget *widget; + + init_simple (editor); + init_email (editor); + init_phone (editor); + init_im (editor); + init_personal (editor); + init_address (editor); + + /* with so many scrolled windows, we need to + * do some manual sizing */ + requisition.width = -1; + requisition.height = -1; + + for (ii = 0; ii < G_N_ELEMENTS (contents); ii++) { + widget = e_builder_get_widget (editor->builder, contents[ii]); + + gtk_widget_get_preferred_size (widget, NULL, &tab_req); + + if (tab_req.width > requisition.width) + requisition.width = tab_req.width; + if (tab_req.height > requisition.height) + requisition.height = tab_req.height; } - if (editor->email_info == NULL) { - e_contact_editor_build_ui_info(editor->email_list, &editor->email_info); - if ( editor->email_popup ) - gtk_widget_unref(editor->email_popup); - - editor->email_popup = gnome_popup_menu_new(editor->email_info); + if (requisition.width > 0 && requisition.height > 0) { + GtkWindow *window; + GdkScreen *screen; + GdkRectangle monitor_area; + gint x = 0, y = 0, monitor, width, height; + + window = GTK_WINDOW (e_builder_get_widget (editor->builder, "contact editor")); + + gtk_widget_get_preferred_size (GTK_WIDGET (window), &tab_req, NULL); + width = tab_req.width - 320 + 24; + height = tab_req.height - 240 + 24; + + screen = gtk_window_get_screen (window); + gtk_window_get_position (window, &x, &y); + + monitor = gdk_screen_get_monitor_at_point (screen, x, y); + if (monitor < 0 || monitor >= gdk_screen_get_n_monitors (screen)) + monitor = 0; + + gdk_screen_get_monitor_workarea (screen, monitor, &monitor_area); + + if (requisition.width > monitor_area.width - width) + requisition.width = monitor_area.width - width; + + if (requisition.height > monitor_area.height - height) + requisition.height = monitor_area.height - height; + + if (requisition.width > 0 && requisition.height > 0) + gtk_window_set_default_size (window, width + requisition.width, height + requisition.height); } } static void -e_contact_editor_build_address_ui (EContactEditor *editor) +contact_editor_get_client_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - int i; + EClientComboBox *combo_box; + ConnectClosure *closure = user_data; + EClient *client; + GError *error = NULL; - if (editor->address_list == NULL) { - static char *info[] = { - N_("Business"), - N_("Home"), - N_("Other") - }; - - for (i = 0; i < sizeof(info) / sizeof(info[0]); i++) { - editor->address_list = g_list_append(editor->address_list, g_strdup(info[i])); - } + combo_box = E_CLIENT_COMBO_BOX (source_object); + + client = e_client_combo_box_get_client_finish ( + combo_box, result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_warn_if_fail (client == NULL); + g_error_free (error); + goto exit; + + } else if (error != NULL) { + GtkWindow *parent; + + parent = eab_editor_get_window (EAB_EDITOR (closure->editor)); + + eab_load_error_dialog ( + GTK_WIDGET (parent), NULL, + closure->source, error); + + e_source_combo_box_set_active ( + E_SOURCE_COMBO_BOX (combo_box), + closure->source); + + g_error_free (error); + goto exit; } - if (editor->address_info == NULL) { - e_contact_editor_build_ui_info(editor->address_list, &editor->address_info); - if ( editor->address_popup ) - gtk_widget_unref(editor->address_popup); - - editor->address_popup = gnome_popup_menu_new(editor->address_info); + /* FIXME Write a private contact_editor_set_target_client(). */ + g_object_set (closure->editor, "target_client", client, NULL); + + g_object_unref (client); + +exit: + connect_closure_free (closure); +} + +static void +source_changed (EClientComboBox *combo_box, + EContactEditor *editor) +{ + ConnectClosure *closure; + ESource *target_source; + ESource *source_source; + ESource *source; + + source = e_source_combo_box_ref_active ( + E_SOURCE_COMBO_BOX (combo_box)); + g_return_if_fail (source != NULL); + + if (editor->cancellable != NULL) { + g_cancellable_cancel (editor->cancellable); + g_object_unref (editor->cancellable); + editor->cancellable = NULL; } + + target_source = e_client_get_source (E_CLIENT (editor->target_client)); + source_source = e_client_get_source (E_CLIENT (editor->source_client)); + + if (e_source_equal (target_source, source)) + goto exit; + + if (e_source_equal (source_source, source)) { + g_object_set ( + editor, "target_client", + editor->source_client, NULL); + goto exit; + } + + editor->cancellable = g_cancellable_new (); + + closure = g_slice_new0 (ConnectClosure); + closure->editor = g_object_ref (editor); + closure->source = g_object_ref (source); + + e_client_combo_box_get_client ( + combo_box, source, + editor->cancellable, + contact_editor_get_client_cb, + closure); + +exit: + g_object_unref (source); } -#if 0 + static void -_dialog_clicked(GtkWidget *dialog, gint button, EContactEditor *editor) +full_name_response (GtkDialog *dialog, + gint response, + EContactEditor *editor) { - GtkWidget *label = gtk_object_get_data(GTK_OBJECT(dialog), - "e_contact_editor_label"); + EContactName *name; + GtkWidget *fname_widget; + gint style = 0; + gboolean editable = FALSE; - GtkWidget *dialog_entry = gtk_object_get_data(GTK_OBJECT(dialog), - "e_contact_editor_dialog_entry"); - - GList **list = gtk_object_get_data(GTK_OBJECT(dialog), - "e_contact_editor_list"); - GList **info = gtk_object_get_data(GTK_OBJECT(dialog), - "e_contact_editor_info"); - switch (button) { - case 0: - if (label && GTK_IS_LABEL(label)) { - gtk_object_set(GTK_OBJECT(label), - "label", gtk_entry_get_text(GTK_ENTRY(dialog_entry)), - NULL); - *list = g_list_append(*list, e_utf8_gtk_entry_get_text(GTK_ENTRY(dialog_entry))); - g_free(*info); - *info = NULL; + g_object_get (dialog, "editable", &editable, NULL); + + if (editable && response == GTK_RESPONSE_OK) { + g_object_get (dialog, "name", &name, NULL); + + style = file_as_get_style (editor); + + fname_widget = e_builder_get_widget ( + editor->builder, "entry-fullname"); + + if (GTK_IS_ENTRY (fname_widget)) { + GtkEntry *entry; + gchar *full_name = e_contact_name_to_string (name); + const gchar *old_full_name; + + entry = GTK_ENTRY (fname_widget); + old_full_name = gtk_entry_get_text (entry); + + if (strcmp (full_name, old_full_name)) + gtk_entry_set_text (entry, full_name); + g_free (full_name); } - break; + + e_contact_name_free (editor->name); + editor->name = name; + + file_as_set_style (editor, style); } - gnome_dialog_close(GNOME_DIALOG(dialog)); -} - -static void -_dialog_destroy(EContactEditor *editor, GtkWidget *dialog) -{ - gnome_dialog_close(GNOME_DIALOG(dialog)); -} - -static GtkWidget * -e_contact_editor_build_dialog(EContactEditor *editor, gchar *entry_id, gchar *label_id, gchar *title, GList **list, GnomeUIInfo **info) -{ - GtkWidget *dialog_entry = gtk_entry_new(); - GtkWidget *entry = glade_xml_get_widget(editor->gui, entry_id); - GtkWidget *label = glade_xml_get_widget(editor->gui, label_id); - - GtkWidget *dialog = gnome_dialog_new(title, - NULL); - - gtk_container_add(GTK_CONTAINER(GNOME_DIALOG(dialog)->vbox), - gtk_widget_new (gtk_frame_get_type(), - "border_width", 4, - "label", title, - "child", gtk_widget_new(gtk_alignment_get_type(), - "child", dialog_entry, - "xalign", .5, - "yalign", .5, - "xscale", 1.0, - "yscale", 1.0, - "border_width", 9, - NULL), - NULL)); - - gnome_dialog_append_button_with_pixmap(GNOME_DIALOG(dialog), - "Add", - GNOME_STOCK_PIXMAP_ADD); - gnome_dialog_append_button(GNOME_DIALOG(dialog), GNOME_STOCK_BUTTON_CANCEL); - gnome_dialog_set_default(GNOME_DIALOG(dialog), 0); - - gtk_signal_connect(GTK_OBJECT(dialog), "clicked", - _dialog_clicked, editor); - gtk_signal_connect_while_alive(GTK_OBJECT(editor), "destroy", - _dialog_destroy, GTK_OBJECT(dialog), GTK_OBJECT(dialog)); - - gtk_object_set_data(GTK_OBJECT(dialog), - "e_contact_editor_entry", entry); - gtk_object_set_data(GTK_OBJECT(dialog), - "e_contact_editor_label", label); - gtk_object_set_data(GTK_OBJECT(dialog), - "e_contact_editor_dialog_entry", dialog_entry); - gtk_object_set_data(GTK_OBJECT(dialog), - "e_contact_editor_list", list); - gtk_object_set_data(GTK_OBJECT(dialog), - "e_contact_editor_info", info); - - gtk_widget_show_all(dialog); - return dialog; + + gtk_widget_destroy (GTK_WIDGET (dialog)); + editor->fullname_dialog = NULL; +} + +static gint +full_name_editor_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + if (GTK_IS_WIDGET (widget)) + gtk_widget_destroy (widget); + + return TRUE; } -#endif static void -_phone_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor) -{ - int which; - int i; - gchar *label; - gchar *entry; - int result; - if ( widget == glade_xml_get_widget(editor->gui, "button-phone1") ) { - which = 1; - } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone2") ) { - which = 2; - } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone3") ) { - which = 3; - } else if ( widget == glade_xml_get_widget(editor->gui, "button-phone4") ) { - which = 4; - } else - return; - - label = g_strdup_printf("label-phone%d", which); - entry = g_strdup_printf("entry-phone%d", which); +full_name_clicked (GtkWidget *button, + EContactEditor *editor) +{ + GtkDialog *dialog; + gboolean fullname_supported; - e_contact_editor_build_phone_ui (editor); - - for(i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i++) { - const ECardPhone *phone = e_card_simple_get_phone(editor->simple, i); - gboolean checked; - checked = phone && phone->number && *phone->number; - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->phone_info[i].widget), - checked); - gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->phone_info[i].widget), - TRUE); - } - - result = _arrow_pressed (widget, button, editor, editor->phone_popup, &editor->phone_list, &editor->phone_info, label, entry, "Add new phone number type"); - - if (result != -1) { - editor->phone_choice[which - 1] = result; - set_fields(editor); - enable_widget (glade_xml_get_widget (editor->gui, label), TRUE); - enable_widget (glade_xml_get_widget (editor->gui, entry), editor->editable); + if (editor->fullname_dialog) { + gtk_window_present (GTK_WINDOW (editor->fullname_dialog)); + return; } - g_free(label); - g_free(entry); + dialog = GTK_DIALOG (e_contact_editor_fullname_new (editor->name)); + fullname_supported = is_field_supported (editor, E_CONTACT_FULL_NAME); + + g_object_set ( + dialog, "editable", + fullname_supported & editor->target_editable, NULL); + + g_signal_connect ( + dialog, "response", + G_CALLBACK (full_name_response), editor); + + /* Close the fullname dialog if the editor is closed */ + g_signal_connect_swapped ( + editor, "editor_closed", + G_CALLBACK (full_name_editor_delete_event_cb), dialog); + + gtk_widget_show (GTK_WIDGET (dialog)); + editor->fullname_dialog = GTK_WIDGET (dialog); } static void -_email_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor) +categories_response (GtkDialog *dialog, + gint response, + EContactEditor *editor) { - int i; - int result; + gchar *categories; + GtkWidget *entry; - e_contact_editor_build_email_ui (editor); + entry = e_builder_get_widget (editor->builder, "entry-categories"); - for(i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i++) { - const char *string = e_card_simple_get_email(editor->simple, i); - gboolean checked; - checked = string && *string; - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->email_info[i].widget), - checked); - gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->email_info[i].widget), - TRUE); + if (response == GTK_RESPONSE_OK) { + categories = e_categories_dialog_get_categories ( + E_CATEGORIES_DIALOG (dialog)); + if (GTK_IS_ENTRY (entry)) + gtk_entry_set_text ( + GTK_ENTRY (entry), categories); + else + e_contact_set ( + editor->contact, + E_CONTACT_CATEGORIES, + categories); + g_free (categories); } - - result = _arrow_pressed (widget, button, editor, editor->email_popup, &editor->email_list, &editor->email_info, "label-email1", "entry-email1", "Add new Email type"); - - if (result != -1) { - editor->email_choice = result; - set_fields(editor); - /* make sure the buttons/entry is/are sensitive */ - enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), TRUE); - enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), editor->editable); - enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), editor->editable); + gtk_widget_destroy (GTK_WIDGET (dialog)); + editor->categories_dialog = NULL; +} + +static gint +categories_editor_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + if (GTK_IS_WIDGET (widget)) + gtk_widget_destroy (widget); + + return TRUE; +} + +static void +categories_clicked (GtkWidget *button, + EContactEditor *editor) +{ + gchar *categories = NULL; + GtkDialog *dialog; + GtkWidget *entry = e_builder_get_widget (editor->builder, "entry-categories"); + + if (entry && GTK_IS_ENTRY (entry)) + categories = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + else if (editor->contact) + categories = e_contact_get (editor->contact, E_CONTACT_CATEGORIES); + + if (editor->categories_dialog != NULL) { + gtk_window_present (GTK_WINDOW (editor->categories_dialog)); + g_free (categories); + return; + }else if (!(dialog = GTK_DIALOG (e_categories_dialog_new (categories)))) { + e_alert_run_dialog_for_args ( + GTK_WINDOW (editor->app), + "addressbook:edit-categories", NULL); + g_free (categories); + return; } + + g_signal_connect ( + dialog, "response", + G_CALLBACK (categories_response), editor); + + /* Close the category dialog if the editor is closed*/ + g_signal_connect_swapped ( + editor, "editor_closed", + G_CALLBACK (categories_editor_delete_event_cb), dialog); + + gtk_widget_show (GTK_WIDGET (dialog)); + g_free (categories); + + editor->categories_dialog = GTK_WIDGET (dialog); } static void -_address_arrow_pressed (GtkWidget *widget, GdkEventButton *button, EContactEditor *editor) +image_selected (EContactEditor *editor) { - int i; - int result; + gchar *file_name; + GtkWidget *image_chooser; - e_contact_editor_build_address_ui (editor); + file_name = gtk_file_chooser_get_filename ( + GTK_FILE_CHOOSER (editor->file_selector)); - for(i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - const ECardAddrLabel *address = e_card_simple_get_address(editor->simple, i); - gboolean checked; - checked = address && address->data && *address->data; - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(editor->address_info[i].widget), - checked); - gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(editor->address_info[i].widget), - TRUE); - } + if (!file_name) + return; - result = _arrow_pressed (widget, button, editor, editor->address_popup, &editor->address_list, &editor->address_info, "label-address", "text-address", "Add new Address type"); + image_chooser = e_builder_get_widget (editor->builder, "image-chooser"); - if (result != -1) { - set_address_field(editor, result); + g_signal_handlers_block_by_func ( + image_chooser, image_chooser_changed, editor); + e_image_chooser_set_from_file ( + E_IMAGE_CHOOSER (image_chooser), file_name); + g_signal_handlers_unblock_by_func ( + image_chooser, image_chooser_changed, editor); - /* make sure the buttons/entry is/are sensitive */ - enable_widget (glade_xml_get_widget (editor->gui, "label-address"), TRUE); - enable_widget (glade_xml_get_widget (editor->gui, "text-address"), editor->editable); - } + editor->image_set = TRUE; + editor->image_changed = TRUE; + object_changed (G_OBJECT (image_chooser), editor); } static void -find_address_mailing (EContactEditor *editor) +image_cleared (EContactEditor *editor) { - const ECardAddrLabel *address; - int i; - - editor->address_mailing = -1; - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - address = e_card_simple_get_address(editor->simple, i); - if (address && (address->flags & E_CARD_ADDR_DEFAULT)) { - if (editor->address_mailing == -1) { - editor->address_mailing = i; - } else { - ECardAddrLabel *new; - - new = e_card_address_label_copy (address); - new->flags &= ~E_CARD_ADDR_DEFAULT; - e_card_simple_set_address(editor->simple, i, new); - e_card_address_label_unref (new); - } - } - } + GtkWidget *image_chooser; + gchar *file_name; + + image_chooser = e_builder_get_widget ( + editor->builder, "image-chooser"); + + file_name = e_icon_factory_get_icon_filename ( + "avatar-default", GTK_ICON_SIZE_DIALOG); + + g_signal_handlers_block_by_func ( + image_chooser, image_chooser_changed, editor); + e_image_chooser_set_from_file ( + E_IMAGE_CHOOSER (image_chooser), file_name); + g_signal_handlers_unblock_by_func ( + image_chooser, image_chooser_changed, editor); + + g_free (file_name); + + editor->image_set = FALSE; + editor->image_changed = TRUE; + object_changed (G_OBJECT (image_chooser), editor); } static void -set_field(GtkEntry *entry, const char *string) +file_chooser_response (GtkWidget *widget, + gint response, + EContactEditor *editor) { - char *oldstring = e_utf8_gtk_entry_get_text(entry); - if (!string) - string = ""; - if (strcmp(string, oldstring)) - e_utf8_gtk_entry_set_text(entry, string); - g_free (oldstring); + if (response == GTK_RESPONSE_ACCEPT) + image_selected (editor); + else if (response == GTK_RESPONSE_NO) + image_cleared (editor); + + gtk_widget_hide (editor->file_selector); +} + +static gboolean +file_selector_deleted (GtkWidget *widget) +{ + gtk_widget_hide (widget); + return TRUE; } static void -set_phone_field(GtkWidget *entry, const ECardPhone *phone) +update_preview_cb (GtkFileChooser *file_chooser, + gpointer data) { - set_field(GTK_ENTRY(entry), phone ? phone->number : ""); + GtkWidget *preview; + gchar *filename = NULL; + GdkPixbuf *pixbuf; + + gtk_file_chooser_set_preview_widget_active (file_chooser, TRUE); + preview = GTK_WIDGET (data); + filename = gtk_file_chooser_get_preview_filename (file_chooser); + if (filename == NULL) + return; + + pixbuf = gdk_pixbuf_new_from_file_at_size (filename, 128, 128, NULL); + if (!pixbuf) { + gchar *alternate_file; + alternate_file = e_icon_factory_get_icon_filename ( + "avatar-default", GTK_ICON_SIZE_DIALOG); + if (alternate_file) { + pixbuf = gdk_pixbuf_new_from_file_at_size ( + alternate_file, 128, 128, NULL); + g_free (alternate_file); + } + } + g_free (filename); + + gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf); + if (pixbuf) + g_object_unref (pixbuf); } static void -set_fields(EContactEditor *editor) +image_clicked (GtkWidget *button, + EContactEditor *editor) { - GtkWidget *entry; - GtkWidget *label_widget; - int i; + if (!editor->file_selector) { + const gchar *title = _("Please select an image for this contact"); + const gchar *no_image = _("_No image"); + GtkImage *preview; + GtkFileFilter *filter; + + editor->file_selector = gtk_file_chooser_dialog_new ( + title, GTK_WINDOW (editor->app), + GTK_FILE_CHOOSER_ACTION_OPEN, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, + no_image, GTK_RESPONSE_NO, + NULL); - entry = glade_xml_get_widget(editor->gui, "entry-phone1"); - if (entry && GTK_IS_ENTRY(entry)) - set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[0])); + filter = gtk_file_filter_new (); + gtk_file_filter_add_mime_type (filter, "image/*"); + gtk_file_chooser_set_filter ( + GTK_FILE_CHOOSER (editor->file_selector), + filter); + + preview = GTK_IMAGE (gtk_image_new ()); + gtk_file_chooser_set_preview_widget ( + GTK_FILE_CHOOSER (editor->file_selector), + GTK_WIDGET (preview)); + g_signal_connect ( + editor->file_selector, "update-preview", + G_CALLBACK (update_preview_cb), preview); + + gtk_dialog_set_default_response ( + GTK_DIALOG (editor->file_selector), + GTK_RESPONSE_ACCEPT); + + g_signal_connect ( + editor->file_selector, "response", + G_CALLBACK (file_chooser_response), editor); + + g_signal_connect_after ( + editor->file_selector, "delete-event", + G_CALLBACK (file_selector_deleted), + editor->file_selector); + } - entry = glade_xml_get_widget(editor->gui, "entry-phone2"); - if (entry && GTK_IS_ENTRY(entry)) - set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[1])); + /* Display the dialog */ - entry = glade_xml_get_widget(editor->gui, "entry-phone3"); - if (entry && GTK_IS_ENTRY(entry)) - set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[2])); + gtk_window_set_modal (GTK_WINDOW (editor->file_selector), TRUE); + gtk_window_present (GTK_WINDOW (editor->file_selector)); +} - entry = glade_xml_get_widget(editor->gui, "entry-phone4"); - if (entry && GTK_IS_ENTRY(entry)) - set_phone_field(entry, e_card_simple_get_phone(editor->simple, editor->phone_choice[3])); - - entry = glade_xml_get_widget(editor->gui, "entry-email1"); - if (entry && GTK_IS_ENTRY(entry)) - set_field(GTK_ENTRY(entry), e_card_simple_get_email(editor->simple, editor->email_choice)); +typedef struct { + EContactEditor *ce; + gboolean should_close; + gchar *new_id; +} EditorCloseStruct; +static void +contact_removed_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EBookClient *book_client = E_BOOK_CLIENT (source_object); + EditorCloseStruct *ecs = user_data; + EContactEditor *ce = ecs->ce; + gboolean should_close = ecs->should_close; + GError *error = NULL; + e_book_client_remove_contact_finish (book_client, result, &error); - e_contact_editor_build_address_ui (editor); + gtk_widget_set_sensitive (ce->app, TRUE); + ce->in_async_call = FALSE; - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i++) { - const ECardAddrLabel *address = e_card_simple_get_address(editor->simple, i); + e_contact_set (ce->contact, E_CONTACT_UID, ecs->new_id); - if (address && address->data && *address->data) - break; - } - if (i == E_CARD_SIMPLE_ADDRESS_ID_LAST) - i = 0; + eab_editor_contact_deleted (EAB_EDITOR (ce), error, ce->contact); + + ce->is_new_contact = FALSE; + + if (should_close) { + eab_editor_close (EAB_EDITOR (ce)); + } else { + ce->changed = FALSE; - label_widget = glade_xml_get_widget(editor->gui, "label-address"); - if (label_widget && GTK_IS_LABEL(label_widget)) { - gtk_object_set(GTK_OBJECT(label_widget), - "label", _(g_list_nth_data(editor->address_list, i)), - NULL); + g_object_ref (ce->target_client); + g_object_unref (ce->source_client); + ce->source_client = ce->target_client; + + sensitize_all (ce); } - set_address_field(editor, i); + if (error) + g_error_free (error); + + g_object_unref (ce); + g_free (ecs->new_id); + g_free (ecs); } static void -set_address_field(EContactEditor *editor, int result) +contact_added_cb (EBookClient *book_client, + const GError *error, + const gchar *id, + gpointer closure) { - GtkWidget *text, *check; - - text = glade_xml_get_widget(editor->gui, "text-address"); + EditorCloseStruct *ecs = closure; + EContactEditor *ce = ecs->ce; + gboolean should_close = ecs->should_close; - if (text && GTK_IS_TEXT(text)) { - int position; - GtkEditable *editable; - const ECardAddrLabel *address; + if (ce->source_client != ce->target_client && !e_client_is_readonly (E_CLIENT (ce->source_client)) && + !error && ce->is_new_contact == FALSE) { + ecs->new_id = g_strdup (id); + e_book_client_remove_contact ( + ce->source_client, ce->contact, NULL, contact_removed_cb, ecs); + return; + } - if (result == -1) - result = editor->address_choice; - editor->address_choice = -1; + gtk_widget_set_sensitive (ce->app, TRUE); + ce->in_async_call = FALSE; - position = 0; - editable = GTK_EDITABLE(text); + e_contact_set (ce->contact, E_CONTACT_UID, id); - gtk_editable_delete_text(editable, 0, -1); - address = e_card_simple_get_address(editor->simple, result); - if (address && address->data) { - gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, address->data); - gtk_editable_insert_text(editable, u, strlen(u), &position); - g_free (u); - } + eab_editor_contact_added (EAB_EDITOR (ce), error, ce->contact); - check = glade_xml_get_widget(editor->gui, "checkbutton-mailingaddress"); - if (check && GTK_IS_CHECK_BUTTON (check)) { - if (address && address->data) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), - address->flags & E_CARD_ADDR_DEFAULT); - else - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), FALSE); + if (!error) { + ce->is_new_contact = FALSE; + + if (should_close) { + eab_editor_close (EAB_EDITOR (ce)); + } else { + ce->changed = FALSE; + sensitize_all (ce); } - - editor->address_choice = result; - } -} - -static void -add_field_callback(GtkWidget *widget, EContactEditor *editor) -{ - const char *name; - int i; - static const char *builtins[] = { - "entry-fullname", - "entry-web", - "entry-company", - "entry-department", - "entry-office", - "entry-jobtitle", - "entry-profession", - "entry-manager", - "entry-assistant", - "entry-nickname", - "entry-spouse", - "text-comments", - "entry-categories", - "entry-contacts", - "entry-file-as", - "dateedit-anniversary", - "dateedit-birthday", - "entry-phone1", - "entry-phone2", - "entry-phone3", - "entry-phone4", - "entry-email1", - "text-address", - "checkbutton-mailingaddress", - "checkbutton-htmlmail", - "entry-caluri", - "entry-fburl", - NULL - }; - name = glade_get_widget_name(widget); - if (name) { - for (i = 0; builtins[i]; i++) { - if (!strcmp(name, builtins[i])) - return; + } + + g_object_unref (ce); + g_free (ecs); +} + +static void +contact_modified_cb (EBookClient *book_client, + const GError *error, + gpointer closure) +{ + EditorCloseStruct *ecs = closure; + EContactEditor *ce = ecs->ce; + gboolean should_close = ecs->should_close; + + gtk_widget_set_sensitive (ce->app, TRUE); + ce->in_async_call = FALSE; + + eab_editor_contact_modified (EAB_EDITOR (ce), error, ce->contact); + + if (!error) { + if (should_close) { + eab_editor_close (EAB_EDITOR (ce)); } - if (GTK_IS_ENTRY(widget) || GTK_IS_TEXT(widget)) { - editor->arbitrary_fields = g_list_prepend(editor->arbitrary_fields, g_strdup(name)); + else { + ce->changed = FALSE; + sensitize_all (ce); } } + + g_object_unref (ce); + g_free (ecs); } -static struct { - char *id; - char *key; -} field_mapping [] = { - { "entry-fullname", "full_name" }, - { "entry-web", "url" }, - { "entry-company", "org" }, - { "entry-department", "org_unit" }, - { "entry-office", "office" }, - { "entry-jobtitle", "title" }, - { "entry-profession", "role" }, - { "entry-manager", "manager" }, - { "entry-assistant", "assistant" }, - { "entry-nickname", "nickname" }, - { "entry-spouse", "spouse" }, - { "text-comments", "note" }, - { "entry-categories", "categories" }, - { "entry-caluri", "caluri" }, - { "entry-fburl", "fburl" }, -}; +static void +contact_modified_ready_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EBookClient *book_client = E_BOOK_CLIENT (source_object); + GError *error = NULL; + + e_book_client_modify_contact_finish (book_client, result, &error); + + contact_modified_cb (book_client, error, user_data); + + if (error) + g_error_free (error); +} + +/* Emits the signal to request saving a contact */ +static void +real_save_contact (EContactEditor *ce, + gboolean should_close) +{ + EShell *shell; + EditorCloseStruct *ecs; + ESourceRegistry *registry; + + shell = eab_editor_get_shell (EAB_EDITOR (ce)); + registry = e_shell_get_registry (shell); + + ecs = g_new0 (EditorCloseStruct, 1); + ecs->ce = ce; + g_object_ref (ecs->ce); + + ecs->should_close = should_close; + + gtk_widget_set_sensitive (ce->app, FALSE); + ce->in_async_call = TRUE; + + if (ce->source_client != ce->target_client) { + /* Two-step move; add to target, then remove from source */ + eab_merging_book_add_contact ( + registry, ce->target_client, + ce->contact, contact_added_cb, ecs); + } else { + if (ce->is_new_contact) + eab_merging_book_add_contact ( + registry, ce->target_client, + ce->contact, contact_added_cb, ecs); + else if (ce->check_merge) + eab_merging_book_modify_contact ( + registry, ce->target_client, + ce->contact, contact_modified_cb, ecs); + else + e_book_client_modify_contact ( + ce->target_client, ce->contact, NULL, + contact_modified_ready_cb, ecs); + } +} static void -fill_in_field(EContactEditor *editor, char *id, char *value) +save_contact (EContactEditor *ce, + gboolean should_close) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, id); - if (widget && GTK_IS_EDITABLE(widget)) { - int position = 0; - GtkEditable *editable = GTK_EDITABLE(widget); - gtk_editable_delete_text(editable, 0, -1); - if (value) { - gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, value); - gtk_editable_insert_text(editable, u, strlen(u), &position); - g_free (u); + gchar *uid; + const gchar *name_entry_string; + const gchar *file_as_entry_string; + const gchar *company_name_string; + GtkWidget *entry_fullname, *entry_file_as, *company_name; + + if (!ce->target_client) + return; + + if (ce->target_editable && e_client_is_readonly (E_CLIENT (ce->source_client))) { + if (e_alert_run_dialog_for_args ( + GTK_WINDOW (ce->app), + "addressbook:prompt-move", + NULL) == GTK_RESPONSE_NO) + return; + } + + entry_fullname = e_builder_get_widget (ce->builder, "entry-fullname"); + entry_file_as = gtk_bin_get_child ( + GTK_BIN (e_builder_get_widget (ce->builder, "combo-file-as"))); + company_name = e_builder_get_widget (ce->builder, "entry-company"); + name_entry_string = gtk_entry_get_text (GTK_ENTRY (entry_fullname)); + file_as_entry_string = gtk_entry_get_text (GTK_ENTRY (entry_file_as)); + company_name_string = gtk_entry_get_text (GTK_ENTRY (company_name)); + + if (strcmp (company_name_string , "")) { + if (!strcmp (name_entry_string, "")) + gtk_entry_set_text ( + GTK_ENTRY (entry_fullname), + company_name_string); + if (!strcmp (file_as_entry_string, "")) + gtk_entry_set_text ( + GTK_ENTRY (entry_file_as), + company_name_string); + } + + extract_all (ce); + + if (!e_contact_editor_is_valid (EAB_EDITOR (ce))) { + uid = e_contact_get (ce->contact, E_CONTACT_UID); + g_object_unref (ce->contact); + ce->contact = e_contact_new (); + if (uid) { + e_contact_set (ce->contact, E_CONTACT_UID, uid); + g_free (uid); } + return; } + + real_save_contact (ce, should_close); } static void -fill_in_card_field(EContactEditor *editor, ECard *card, char *id, char *key) +e_contact_editor_save_contact (EABEditor *editor, + gboolean should_close) { - char *string; - gtk_object_get(GTK_OBJECT(card), - key, &string, - NULL); - fill_in_field(editor, id, string); + save_contact (E_CONTACT_EDITOR (editor), should_close); } +/* Closes the dialog box and emits the appropriate signals */ static void -fill_in_single_field(EContactEditor *editor, char *name) +e_contact_editor_close (EABEditor *editor) { - ECardSimple *simple = editor->simple; - GtkWidget *widget = glade_xml_get_widget(editor->gui, name); - if (widget && GTK_IS_EDITABLE(widget)) { - int position = 0; - GtkEditable *editable = GTK_EDITABLE(widget); - const ECardArbitrary *arbitrary; + EContactEditor *ce = E_CONTACT_EDITOR (editor); - gtk_editable_delete_text(editable, 0, -1); - arbitrary = e_card_simple_get_arbitrary(simple, - name); - if (arbitrary && arbitrary->value) { - gchar *u = e_utf8_to_gtk_string ((GtkWidget *) editable, arbitrary->value); - gtk_editable_insert_text(editable, u, strlen(u), &position); - g_free (u); - } + if (ce->app != NULL) { + gtk_widget_destroy (ce->app); + ce->app = NULL; + eab_editor_closed (editor); } } -static void -disable_widget_foreach (char *key, GtkWidget *widget, gpointer closure) +static const EContactField non_string_fields[] = { + E_CONTACT_FULL_NAME, + E_CONTACT_ADDRESS, + E_CONTACT_ADDRESS_HOME, + E_CONTACT_ADDRESS_WORK, + E_CONTACT_ADDRESS_OTHER, + E_CONTACT_EMAIL, + E_CONTACT_IM_AIM, + E_CONTACT_IM_GROUPWISE, + E_CONTACT_IM_JABBER, + E_CONTACT_IM_YAHOO, + E_CONTACT_IM_GADUGADU, + E_CONTACT_IM_MSN, + E_CONTACT_IM_ICQ, + E_CONTACT_IM_SKYPE, + E_CONTACT_IM_TWITTER, + E_CONTACT_PHOTO, + E_CONTACT_LOGO, + E_CONTACT_X509_CERT, + E_CONTACT_CATEGORY_LIST, + E_CONTACT_BIRTH_DATE, + E_CONTACT_ANNIVERSARY + +}; + +static gboolean +is_non_string_field (EContactField id) { - enable_widget (widget, FALSE); + gint count = sizeof (non_string_fields) / sizeof (EContactField); + gint i; + for (i = 0; i < count; i++) + if (id == non_string_fields[i]) + return TRUE; + return FALSE; + } -static struct { - char *widget_name; - ECardSimpleField field_id; - gboolean desensitize_for_read_only; -} widget_field_mappings[] = { - { "entry-web", E_CARD_SIMPLE_FIELD_URL, TRUE }, - { "accellabel-web", E_CARD_SIMPLE_FIELD_URL }, +/* insert checks here (date format, for instance, etc.) */ +static gboolean +e_contact_editor_is_valid (EABEditor *editor) +{ + EContactEditor *ce = E_CONTACT_EDITOR (editor); + GtkWidget *widget; + gboolean validation_error = FALSE; + GSList *iter; + GString *errmsg = g_string_new (_("The contact data is invalid:\n\n")); + time_t bday, now = time (NULL); + + widget = e_builder_get_widget (ce->builder, "dateedit-birthday"); + if (!(e_date_edit_date_is_valid (E_DATE_EDIT (widget)))) { + g_string_append_printf ( + errmsg, _("'%s' has an invalid format"), + e_contact_pretty_name (E_CONTACT_BIRTH_DATE)); + validation_error = TRUE; + } + /* If valid, see if the birthday is a future date */ + bday = e_date_edit_get_time (E_DATE_EDIT (widget)); + if (bday > now) { + g_string_append_printf ( + errmsg, _("'%s' cannot be a future date"), + e_contact_pretty_name (E_CONTACT_BIRTH_DATE)); + validation_error = TRUE; + } - { "entry-jobtitle", E_CARD_SIMPLE_FIELD_TITLE, TRUE }, - { "label-jobtitle", E_CARD_SIMPLE_FIELD_TITLE }, + widget = e_builder_get_widget (ce->builder, "dateedit-anniversary"); + if (!(e_date_edit_date_is_valid (E_DATE_EDIT (widget)))) { + g_string_append_printf ( + errmsg, _("%s'%s' has an invalid format"), + validation_error ? ",\n" : "", + e_contact_pretty_name (E_CONTACT_ANNIVERSARY)); + validation_error = TRUE; + } - { "entry-company", E_CARD_SIMPLE_FIELD_ORG, TRUE }, - { "label-company", E_CARD_SIMPLE_FIELD_ORG }, + for (iter = ce->required_fields; iter; iter = iter->next) { + const gchar *field_name = iter->data; + EContactField field_id = e_contact_field_id (field_name); + + if (is_non_string_field (field_id)) { + if (e_contact_get_const (ce->contact, field_id) == NULL) { + g_string_append_printf ( + errmsg, _("%s'%s' is empty"), + validation_error ? ",\n" : "", + e_contact_pretty_name (field_id)); + validation_error = TRUE; + break; + } - { "combo-file-as", E_CARD_SIMPLE_FIELD_FILE_AS, TRUE }, - { "entry-file-as", E_CARD_SIMPLE_FIELD_FILE_AS, TRUE }, - { "accellabel-fileas", E_CARD_SIMPLE_FIELD_FILE_AS }, + } else { + const gchar *text; - { "label-department", E_CARD_SIMPLE_FIELD_ORG_UNIT }, - { "entry-department", E_CARD_SIMPLE_FIELD_ORG_UNIT, TRUE }, + text = e_contact_get_const (ce->contact, field_id); - { "label-office", E_CARD_SIMPLE_FIELD_OFFICE }, - { "entry-office", E_CARD_SIMPLE_FIELD_OFFICE, TRUE }, + if (STRING_IS_EMPTY (text)) { + g_string_append_printf ( + errmsg, _("%s'%s' is empty"), + validation_error ? ",\n" : "", + e_contact_pretty_name (field_id)); + validation_error = TRUE; + break; + } - { "label-profession", E_CARD_SIMPLE_FIELD_ROLE }, - { "entry-profession", E_CARD_SIMPLE_FIELD_ROLE, TRUE }, + } + } - { "label-manager", E_CARD_SIMPLE_FIELD_MANAGER }, - { "entry-manager", E_CARD_SIMPLE_FIELD_MANAGER, TRUE }, + if (validation_error) { + g_string_append (errmsg, "."); + e_alert_run_dialog_for_args ( + GTK_WINDOW (ce->app), + "addressbook:generic-error", + _("Invalid contact."), errmsg->str, NULL); + g_string_free (errmsg, TRUE); + return FALSE; + } + else { + g_string_free (errmsg, TRUE); + return TRUE; + } +} - { "label-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT }, - { "entry-assistant", E_CARD_SIMPLE_FIELD_ASSISTANT, TRUE }, +static gboolean +e_contact_editor_is_changed (EABEditor *editor) +{ + return E_CONTACT_EDITOR (editor)->changed; +} - { "label-nickname", E_CARD_SIMPLE_FIELD_NICKNAME }, - { "entry-nickname", E_CARD_SIMPLE_FIELD_NICKNAME, TRUE }, +static GtkWindow * +e_contact_editor_get_window (EABEditor *editor) +{ + return GTK_WINDOW (E_CONTACT_EDITOR (editor)->app); +} - { "label-spouse", E_CARD_SIMPLE_FIELD_SPOUSE }, - { "entry-spouse", E_CARD_SIMPLE_FIELD_SPOUSE, TRUE }, +static void +file_save_and_close_cb (GtkWidget *widget, + EContactEditor *ce) +{ + save_contact (ce, TRUE); +} - { "label-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE }, - { "dateedit-birthday", E_CARD_SIMPLE_FIELD_BIRTH_DATE, TRUE }, +static void +file_cancel_cb (GtkWidget *widget, + EContactEditor *ce) +{ + eab_editor_close (EAB_EDITOR (ce)); +} - { "label-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY }, - { "dateedit-anniversary", E_CARD_SIMPLE_FIELD_ANNIVERSARY, TRUE }, +/* Callback used when the dialog box is destroyed */ +static gint +app_delete_event_cb (GtkWidget *widget, + GdkEvent *event, + gpointer data) +{ + EContactEditor *ce; - { "label-comments", E_CARD_SIMPLE_FIELD_NOTE }, - { "text-comments", E_CARD_SIMPLE_FIELD_NOTE, TRUE }, + ce = E_CONTACT_EDITOR (data); - { "entry-fullname", E_CARD_SIMPLE_FIELD_FULL_NAME, TRUE }, + /* if we're saving, don't allow the dialog to close */ + if (ce->in_async_call) + return TRUE; - { "button-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE }, - { "entry-categories", E_CARD_SIMPLE_FIELD_CATEGORIES, TRUE }, + if (ce->changed) { + switch (eab_prompt_save_dialog (GTK_WINDOW (ce->app))) { + case GTK_RESPONSE_YES: + eab_editor_save_contact (EAB_EDITOR (ce), TRUE); + return TRUE; - { "label-caluri", E_CARD_SIMPLE_FIELD_CALURI }, - { "entry-caluri", E_CARD_SIMPLE_FIELD_CALURI, TRUE }, + case GTK_RESPONSE_NO: + break; - { "label-fburl", E_CARD_SIMPLE_FIELD_FBURL }, - { "entry-fburl", E_CARD_SIMPLE_FIELD_FBURL, TRUE } -}; -static int num_widget_field_mappings = sizeof(widget_field_mappings) / sizeof (widget_field_mappings[0]); + case GTK_RESPONSE_CANCEL: + default: + return TRUE; + + } + } + + eab_editor_close (EAB_EDITOR (ce)); + return TRUE; +} static void -enable_writable_fields(EContactEditor *editor) +show_help_cb (GtkWidget *widget, + gpointer data) { - EList *fields = editor->writable_fields; - EIterator *iter; - GHashTable *dropdown_hash, *supported_hash; - int i; - ECardSimple *simple; - ECard *card; - char *widget_name; + /* FIXME Pass a proper parent window. */ + e_display_help (NULL, "contacts-usage-add-contact"); +} - if (!fields) - return; +static GList * +add_to_tab_order (GList *list, + GtkBuilder *builder, + const gchar *name) +{ + GtkWidget *widget = e_builder_get_widget (builder, name); + return g_list_prepend (list, widget); +} - card = e_card_new (""); - simple = e_card_simple_new (card); - - dropdown_hash = g_hash_table_new (g_str_hash, g_str_equal); - supported_hash = g_hash_table_new (g_str_hash, g_str_equal); - - /* build our hashtable of the drop down menu items */ - e_contact_editor_build_phone_ui (editor); - for (i = 0; i < E_CARD_SIMPLE_PHONE_ID_LAST; i ++) - g_hash_table_insert (dropdown_hash, - (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_phone_to_field (i)), - editor->phone_info[i].widget); - e_contact_editor_build_email_ui (editor); - for (i = 0; i < E_CARD_SIMPLE_EMAIL_ID_LAST; i ++) - g_hash_table_insert (dropdown_hash, - (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_email_to_field (i)), - editor->email_info[i].widget); - e_contact_editor_build_address_ui (editor); - for (i = 0; i < E_CARD_SIMPLE_ADDRESS_ID_LAST; i ++) - g_hash_table_insert (dropdown_hash, - (char*)e_card_simple_get_ecard_field(simple, e_card_simple_map_address_to_field (i)), - editor->address_info[i].widget); - - /* then disable them all */ - g_hash_table_foreach (dropdown_hash, (GHFunc)disable_widget_foreach, NULL); - - /* disable the label widgets for the dropdowns (4 phone, 1 - email and the toggle button, and 1 address and one for - the full address button */ - for (i = 0; i < 4; i ++) { - widget_name = g_strdup_printf ("label-phone%d", i+1); - enable_widget (glade_xml_get_widget (editor->gui, widget_name), FALSE); - g_free (widget_name); - widget_name = g_strdup_printf ("entry-phone%d", i+1); - enable_widget (glade_xml_get_widget (editor->gui, widget_name), FALSE); - g_free (widget_name); +static void +setup_tab_order (GtkBuilder *builder) +{ + GtkWidget *container; + GList *list = NULL; +/* + container = e_builder_get_widget (builder, "table-contact-editor-general"); + * + if (container) { + list = add_to_tab_order (list, builder, "entry-fullname"); + list = add_to_tab_order (list, builder, "entry-jobtitle"); + list = add_to_tab_order (list, builder, "entry-company"); + list = add_to_tab_order (list, builder, "combo-file-as"); + list = add_to_tab_order (list, builder, "entry-phone-1"); + list = add_to_tab_order (list, builder, "entry-phone-2"); + list = add_to_tab_order (list, builder, "entry-phone-3"); + list = add_to_tab_order (list, builder, "entry-phone-4"); + * + list = add_to_tab_order (list, builder, "entry-email1"); + list = add_to_tab_order (list, builder, "alignment-htmlmail"); + list = add_to_tab_order (list, builder, "entry-web"); + list = add_to_tab_order (list, builder, "entry-homepage"); + list = add_to_tab_order (list, builder, "button-fulladdr"); + list = add_to_tab_order (list, builder, "text-address"); + list = g_list_reverse (list); + e_container_change_tab_order (GTK_CONTAINER (container), list); + g_list_free (list); } - enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), FALSE); - enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), FALSE); - enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), FALSE); - enable_widget (glade_xml_get_widget (editor->gui, "label-address"), FALSE); - enable_widget (glade_xml_get_widget (editor->gui, "text-address"), FALSE); +*/ + + container = e_builder_get_widget (builder, "table-home-address"); + gtk_container_get_focus_chain (GTK_CONTAINER (container), &list); + + list = add_to_tab_order (list, builder, "scrolledwindow-home-address"); + list = add_to_tab_order (list, builder, "entry-home-city"); + list = add_to_tab_order (list, builder, "entry-home-zip"); + list = add_to_tab_order (list, builder, "entry-home-state"); + list = add_to_tab_order (list, builder, "entry-home-pobox"); + list = add_to_tab_order (list, builder, "entry-home-country"); + list = g_list_reverse (list); + + gtk_container_set_focus_chain (GTK_CONTAINER (container), list); + g_list_free (list); + + container = e_builder_get_widget (builder, "table-work-address"); + gtk_container_get_focus_chain (GTK_CONTAINER (container), &list); + + list = add_to_tab_order (list, builder, "scrolledwindow-work-address"); + list = add_to_tab_order (list, builder, "entry-work-city"); + list = add_to_tab_order (list, builder, "entry-work-zip"); + list = add_to_tab_order (list, builder, "entry-work-state"); + list = add_to_tab_order (list, builder, "entry-work-pobox"); + list = add_to_tab_order (list, builder, "entry-work-country"); + list = g_list_reverse (list); + + gtk_container_set_focus_chain (GTK_CONTAINER (container), list); + g_list_free (list); + + container = e_builder_get_widget (builder, "table-other-address"); + gtk_container_get_focus_chain (GTK_CONTAINER (container), &list); + + list = add_to_tab_order (list, builder, "scrolledwindow-other-address"); + list = add_to_tab_order (list, builder, "entry-other-city"); + list = add_to_tab_order (list, builder, "entry-other-zip"); + list = add_to_tab_order (list, builder, "entry-other-state"); + list = add_to_tab_order (list, builder, "entry-other-pobox"); + list = add_to_tab_order (list, builder, "entry-other-country"); + list = g_list_reverse (list); + + gtk_container_set_focus_chain (GTK_CONTAINER (container), list); + g_list_free (list); +} - /* enable widgets that map directly from a field to a widget (the drop down items) */ - iter = e_list_get_iterator (fields); - for (; e_iterator_is_valid (iter); e_iterator_next (iter)) { - char *field = (char*)e_iterator_get (iter); - GtkWidget *widget = g_hash_table_lookup (dropdown_hash, field); +static void +expand_web_toggle (EContactEditor *ce) +{ + GtkWidget *widget; - if (widget) { - enable_widget (widget, TRUE); - } - else { - /* if it's not a field that's handled by the - dropdown items, add it to the has to be - used in the second step */ - g_hash_table_insert (supported_hash, field, field); - } + widget = e_builder_get_widget (ce->builder, "label-videourl"); + expand_web (ce, !gtk_widget_get_visible (widget)); +} - /* ugh - this is needed to make sure we don't have a - disabled label next to a drop down when the item in - the menu (the one reflected in the label) is - enabled. */ - if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_email_to_field(editor->email_choice)))) { - enable_widget (glade_xml_get_widget (editor->gui, "label-email1"), TRUE); - enable_widget (glade_xml_get_widget (editor->gui, "entry-email1"), editor->editable); - enable_widget (glade_xml_get_widget (editor->gui, "checkbutton-htmlmail"), editor->editable); - } - else if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_address_to_field(editor->address_choice)))) { - enable_widget (glade_xml_get_widget (editor->gui, "label-address"), TRUE); - enable_widget (glade_xml_get_widget (editor->gui, "text-address"), editor->editable); - } - else for (i = 0; i < 4; i ++) { - if (!strcmp (field, e_card_simple_get_ecard_field (simple, e_card_simple_map_phone_to_field(editor->phone_choice[i])))) { - widget_name = g_strdup_printf ("label-phone%d", i+1); - enable_widget (glade_xml_get_widget (editor->gui, widget_name), TRUE); - g_free (widget_name); - widget_name = g_strdup_printf ("entry-phone%d", i+1); - enable_widget (glade_xml_get_widget (editor->gui, widget_name), editor->editable); - g_free (widget_name); - } - } - } +static void +expand_phone_toggle (EContactEditor *ce) +{ + GtkWidget *phone_ext_table; - /* handle the label next to the dropdown widgets */ + phone_ext_table = e_builder_get_widget ( + ce->builder, "table-phone-extended"); + expand_phone (ce, !gtk_widget_get_visible (phone_ext_table)); +} - for (i = 0; i < num_widget_field_mappings; i ++) { - gboolean enabled; - GtkWidget *w; - const char *field; +static void +expand_mail_toggle (EContactEditor *ce) +{ + GtkWidget *mail; - w = glade_xml_get_widget(editor->gui, widget_field_mappings[i].widget_name); - if (!w) { - g_warning (_("Could not find widget for a field: `%s'"), - widget_field_mappings[i].widget_name); - continue; - } - field = e_card_simple_get_ecard_field (simple, - widget_field_mappings[i].field_id); + mail = e_builder_get_widget (ce->builder, "entry-email-4"); + expand_mail (ce, !gtk_widget_get_visible (mail)); +} - enabled = (g_hash_table_lookup (supported_hash, field) != NULL); +static void +e_contact_editor_init (EContactEditor *e_contact_editor) +{ + GtkBuilder *builder; + EShell *shell; + EClientCache *client_cache; + GtkWidget *container; + GtkWidget *widget, *label; + GtkEntryCompletion *completion; - if (widget_field_mappings[i].desensitize_for_read_only && !editor->editable) { - enabled = FALSE; - } + /* FIXME The shell should be obtained + * through a constructor property. */ + shell = e_shell_get_default (); + client_cache = e_shell_get_client_cache (shell); - enable_widget (w, enabled); - } + e_contact_editor->name = e_contact_name_new (); + + e_contact_editor->contact = NULL; + e_contact_editor->changed = FALSE; + e_contact_editor->check_merge = FALSE; + e_contact_editor->image_set = FALSE; + e_contact_editor->image_changed = FALSE; + e_contact_editor->in_async_call = FALSE; + e_contact_editor->target_editable = TRUE; + e_contact_editor->fullname_dialog = NULL; + e_contact_editor->categories_dialog = NULL; + e_contact_editor->compress_ui = e_shell_get_express_mode (shell); + + builder = gtk_builder_new (); + e_load_ui_builder_definition (builder, "contact-editor.ui"); + + e_contact_editor->builder = builder; + + setup_tab_order (builder); + + e_contact_editor->app = + e_builder_get_widget (builder, "contact editor"); + widget = e_contact_editor->app; + + gtk_widget_ensure_style (widget); + gtk_window_set_type_hint ( + GTK_WINDOW (widget), GDK_WINDOW_TYPE_HINT_NORMAL); + container = gtk_dialog_get_action_area (GTK_DIALOG (widget)); + gtk_container_set_border_width (GTK_CONTAINER (container), 12); + container = gtk_dialog_get_content_area (GTK_DIALOG (widget)); + gtk_container_set_border_width (GTK_CONTAINER (container), 0); + + init_all (e_contact_editor); + + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-image"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (image_clicked), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-fullname"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (full_name_clicked), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-categories"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (categories_clicked), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "client-combo-box"); + e_client_combo_box_set_client_cache ( + E_CLIENT_COMBO_BOX (widget), client_cache); + g_signal_connect ( + widget, "changed", + G_CALLBACK (source_changed), e_contact_editor); + label = e_builder_get_widget ( + e_contact_editor->builder, "where-label"); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-ok"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (file_save_and_close_cb), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-cancel"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (file_cancel_cb), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-help"); + g_signal_connect ( + widget, "clicked", + G_CALLBACK (show_help_cb), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-web-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_web_toggle), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-phone-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_phone_toggle), e_contact_editor); + widget = e_builder_get_widget ( + e_contact_editor->builder, "button-mail-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_mail_toggle), e_contact_editor); + + widget = e_builder_get_widget ( + e_contact_editor->builder, "entry-fullname"); + if (widget) + gtk_widget_grab_focus (widget); + + widget = e_builder_get_widget ( + e_contact_editor->builder, "entry-categories"); + completion = e_category_completion_new (); + gtk_entry_set_completion (GTK_ENTRY (widget), completion); + g_object_unref (completion); + + /* Connect to the deletion of the dialog */ + + g_signal_connect ( + e_contact_editor->app, "delete_event", + G_CALLBACK (app_delete_event_cb), e_contact_editor); + + /* set the icon */ + gtk_window_set_icon_name ( + GTK_WINDOW (e_contact_editor->app), "contact-editor"); + + /* show window */ + gtk_widget_show (e_contact_editor->app); - g_hash_table_destroy (dropdown_hash); - g_hash_table_destroy (supported_hash); - gtk_object_unref (GTK_OBJECT(simple)); - gtk_object_unref (GTK_OBJECT(card)); + gtk_application_add_window ( + GTK_APPLICATION (shell), + GTK_WINDOW (e_contact_editor->app)); } static void -set_editable (EContactEditor *editor) +e_contact_editor_dispose (GObject *object) { - int i; - char *entry; - /* set the sensitivity of all the non-dropdown entry/texts/dateedits */ - for (i = 0; i < num_widget_field_mappings; i ++) { - if (widget_field_mappings[i].desensitize_for_read_only) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, widget_field_mappings[i].widget_name); - enable_widget (widget, editor->editable); - } + EContactEditor *e_contact_editor = E_CONTACT_EDITOR (object); + + if (e_contact_editor->file_selector != NULL) { + gtk_widget_destroy (e_contact_editor->file_selector); + e_contact_editor->file_selector = NULL; + } + + g_slist_free_full ( + e_contact_editor->writable_fields, + (GDestroyNotify) g_free); + e_contact_editor->writable_fields = NULL; + + g_slist_free_full ( + e_contact_editor->required_fields, + (GDestroyNotify) g_free); + e_contact_editor->required_fields = NULL; + + if (e_contact_editor->contact) { + g_object_unref (e_contact_editor->contact); + e_contact_editor->contact = NULL; + } + + if (e_contact_editor->source_client) { + g_object_unref (e_contact_editor->source_client); + e_contact_editor->source_client = NULL; } - /* handle the phone dropdown entries */ - for (i = 0; i < 4; i ++) { - entry = g_strdup_printf ("entry-phone%d", i+1); + if (e_contact_editor->target_client) { + g_signal_handler_disconnect ( + e_contact_editor->target_client, + e_contact_editor->target_editable_id); + g_object_unref (e_contact_editor->target_client); + e_contact_editor->target_client = NULL; + } - enable_widget (glade_xml_get_widget(editor->gui, entry), - editor->editable); + if (e_contact_editor->name) { + e_contact_name_free (e_contact_editor->name); + e_contact_editor->name = NULL; + } - g_free (entry); + if (e_contact_editor->builder) { + g_object_unref (e_contact_editor->builder); + e_contact_editor->builder = NULL; } - /* handle the email dropdown entry */ - entry = "entry-email1"; - enable_widget (glade_xml_get_widget(editor->gui, entry), - editor->editable); - enable_widget (glade_xml_get_widget(editor->gui, "checkbutton-htmlmail"), - editor->editable); + if (e_contact_editor->cancellable != NULL) { + g_object_unref (e_contact_editor->cancellable); + e_contact_editor->cancellable = NULL; + } - /* handle the address dropdown entry */ - entry = "text-address"; - enable_widget (glade_xml_get_widget(editor->gui, entry), - editor->editable); + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); } static void -fill_in_info(EContactEditor *editor) +supported_fields_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - ECard *card = editor->card; - if (card) { - char *file_as; - char *related_contacts; - ECardName *name; - const ECardDate *anniversary; - const ECardDate *bday; - int i; - GtkWidget *widget; - GList *list; - gboolean wants_html, wants_html_set; - - gtk_object_get(GTK_OBJECT(card), - "file_as", &file_as, - "related_contacts", &related_contacts, - "name", &name, - "anniversary", &anniversary, - "birth_date", &bday, - "wants_html_set", &wants_html_set, - "wants_html", &wants_html, - NULL); - - for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) { - fill_in_card_field(editor, card, field_mapping[i].id, field_mapping[i].key); - } + EBookClient *book_client = E_BOOK_CLIENT (source_object); + EContactEditor *ce = user_data; + gchar *prop_value = NULL; + GSList *fields; + gboolean success; + GError *error = NULL; + + success = e_client_get_backend_property_finish ( + E_CLIENT (book_client), result, &prop_value, &error); + + if (!success) + prop_value = NULL; + + if (error != NULL) { + g_warning ( + "%s: Failed to get supported fields: %s", + G_STRFUNC, error->message); + g_error_free (error); + } - for (list = editor->arbitrary_fields; list; list = list->next) { - fill_in_single_field(editor, list->data); - } + if (!g_slist_find (eab_editor_get_all_editors (), ce)) { + g_warning ( + "supported_fields_cb called for book that's still " + "around, but contact editor that's been destroyed."); + g_free (prop_value); + return; + } - find_address_mailing (editor); - - if (wants_html_set) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, "checkbutton-htmlmail"); - if (widget && GTK_IS_CHECK_BUTTON(widget)) { - gtk_object_set(GTK_OBJECT(widget), - "active", wants_html, - NULL); - } - } + fields = e_client_util_parse_comma_strings (prop_value); - /* File as has to come after company and name or else it'll get messed up when setting them. */ - fill_in_field(editor, "entry-file-as", file_as); - - e_card_name_unref(editor->name); - editor->name = e_card_name_ref(name); - - widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary"); - if (widget && E_IS_DATE_EDIT(widget)) { - EDateEdit *dateedit; - dateedit = E_DATE_EDIT(widget); - if (anniversary) - e_date_edit_set_date (dateedit, - anniversary->year, - anniversary->month, - anniversary->day); - else - e_date_edit_set_time (dateedit, -1); - } + g_object_set (ce, "writable_fields", fields, NULL); - widget = glade_xml_get_widget(editor->gui, "dateedit-birthday"); - if (widget && E_IS_DATE_EDIT(widget)) { - EDateEdit *dateedit; - dateedit = E_DATE_EDIT(widget); - if (bday) - e_date_edit_set_date (dateedit, - bday->year, - bday->month, - bday->day); - else - e_date_edit_set_time (dateedit, -1); - } + g_slist_free_full (fields, (GDestroyNotify) g_free); + g_free (prop_value); - if (editor->select_names_contacts && related_contacts && *related_contacts) { - ESelectNamesModel *model = e_select_names_manager_get_source (editor->select_names_contacts, - "contacts"); - e_select_names_model_import_destinationv (model, related_contacts); - } + eab_editor_show (EAB_EDITOR (ce)); - set_fields(editor); - } + sensitize_all (ce); } static void -extract_field(EContactEditor *editor, ECard *card, char *editable_id, char *key) +required_fields_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, editable_id); - if (widget && GTK_IS_EDITABLE(widget)) { - GtkEditable *editable = GTK_EDITABLE(widget); - char *string = e_utf8_gtk_editable_get_chars(editable, 0, -1); - - if (string && *string) - gtk_object_set(GTK_OBJECT(card), - key, string, - NULL); - else - gtk_object_set(GTK_OBJECT(card), - key, NULL, - NULL); + EBookClient *book_client = E_BOOK_CLIENT (source_object); + EContactEditor *ce = user_data; + gchar *prop_value = NULL; + GSList *fields; + gboolean success; + GError *error = NULL; + + success = e_client_get_backend_property_finish ( + E_CLIENT (book_client), result, &prop_value, &error); + + if (!success) + prop_value = NULL; + + if (error != NULL) { + g_warning ( + "%s: Failed to get supported fields: %s", + G_STRFUNC, error->message); + g_error_free (error); + } - if (string) g_free(string); + if (!g_slist_find (eab_editor_get_all_editors (), ce)) { + g_warning ( + "supported_fields_cb called for book that's still " + "around, but contact editor that's been destroyed."); + g_free (prop_value); + return; } + + fields = e_client_util_parse_comma_strings (prop_value); + + g_object_set (ce, "required_fields", fields, NULL); + + g_slist_free_full (fields, (GDestroyNotify) g_free); + g_free (prop_value); +} + +EABEditor * +e_contact_editor_new (EShell *shell, + EBookClient *book_client, + EContact *contact, + gboolean is_new_contact, + gboolean editable) +{ + EABEditor *editor; + + g_return_val_if_fail (E_IS_SHELL (shell), NULL); + g_return_val_if_fail (E_IS_BOOK_CLIENT (book_client), NULL); + g_return_val_if_fail (E_IS_CONTACT (contact), NULL); + + editor = g_object_new (E_TYPE_CONTACT_EDITOR, "shell", shell, NULL); + + g_object_set ( + editor, + "source_client", book_client, + "contact", contact, + "is_new_contact", is_new_contact, + "editable", editable, + NULL); + + return editor; } static void -extract_single_field(EContactEditor *editor, char *name) +notify_readonly_cb (EBookClient *book_client, + GParamSpec *pspec, + EContactEditor *ce) { - GtkWidget *widget = glade_xml_get_widget(editor->gui, name); - ECardSimple *simple = editor->simple; - if (widget && GTK_IS_EDITABLE(widget)) { - GtkEditable *editable = GTK_EDITABLE(widget); - char *string = e_utf8_gtk_editable_get_chars(editable, 0, -1); + EClient *client; + gint new_target_editable; + gboolean changed = FALSE; - if (string && *string) - e_card_simple_set_arbitrary(simple, - name, - NULL, - string); - else - e_card_simple_set_arbitrary(simple, - name, - NULL, - NULL); - if (string) g_free(string); - } + client = E_CLIENT (ce->target_client); + new_target_editable = !e_client_is_readonly (client); + + if (ce->target_editable != new_target_editable) + changed = TRUE; + + ce->target_editable = new_target_editable; + + if (changed) + sensitize_all (ce); } static void -extract_info(EContactEditor *editor) +e_contact_editor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) { - ECard *card = editor->card; - if (card) { - ECardDate anniversary; - ECardDate bday; - int i; - GtkWidget *widget; - GList *list; + EContactEditor *editor; - widget = glade_xml_get_widget(editor->gui, "entry-file-as"); - if (widget && GTK_IS_EDITABLE(widget)) { - GtkEditable *editable = GTK_EDITABLE(widget); - char *string = e_utf8_gtk_editable_get_chars(editable, 0, -1); + editor = E_CONTACT_EDITOR (object); - if (string && *string) - gtk_object_set(GTK_OBJECT(card), - "file_as", string, - NULL); + switch (property_id) { + case PROP_SOURCE_CLIENT: { + gboolean writable; + gboolean changed = FALSE; + EBookClient *source_client; - if (string) g_free(string); - } + source_client = E_BOOK_CLIENT (g_value_get_object (value)); - for (i = 0; i < sizeof(field_mapping) / sizeof(field_mapping[0]); i++) { - extract_field(editor, card, field_mapping[i].id, field_mapping[i].key); - } + if (source_client == editor->source_client) + break; + + if (editor->source_client) + g_object_unref (editor->source_client); + + editor->source_client = source_client; + g_object_ref (editor->source_client); + + if (!editor->target_client) { + editor->target_client = editor->source_client; + g_object_ref (editor->target_client); + + editor->target_editable_id = g_signal_connect ( + editor->target_client, "notify::readonly", + G_CALLBACK (notify_readonly_cb), editor); + + e_client_get_backend_property ( + E_CLIENT (editor->target_client), + BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS, + NULL, supported_fields_cb, editor); - for (list = editor->arbitrary_fields; list; list = list->next) { - extract_single_field(editor, list->data); + e_client_get_backend_property ( + E_CLIENT (editor->target_client), + BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS, + NULL, required_fields_cb, editor); } - if (editor->select_names_contacts) { - ESelectNamesModel *model = e_select_names_manager_get_source (editor->select_names_contacts, - "contacts"); - char *string = e_select_names_model_export_destinationv (model); - if (string && *string) - gtk_object_set (GTK_OBJECT (card), - "related_contacts", string, - NULL); - else - gtk_object_set (GTK_OBJECT (card), - "related_contacts", NULL, - NULL); - g_free (string); + writable = !e_client_is_readonly (E_CLIENT (editor->target_client)); + if (writable != editor->target_editable) { + editor->target_editable = writable; + changed = TRUE; } - if (editor->name) - gtk_object_set(GTK_OBJECT(card), - "name", editor->name, - NULL); - - widget = glade_xml_get_widget(editor->gui, "dateedit-anniversary"); - if (widget && E_IS_DATE_EDIT(widget)) { - if (e_date_edit_get_date (E_DATE_EDIT (widget), - &anniversary.year, - &anniversary.month, - &anniversary.day)) { - /* g_print ("%d %d %d\n", anniversary.year, anniversary.month, anniversary.day); */ - gtk_object_set(GTK_OBJECT(card), - "anniversary", &anniversary, - NULL); - } else - gtk_object_set(GTK_OBJECT(card), - "anniversary", NULL, - NULL); + if (changed) + sensitize_all (editor); + + break; + } + + case PROP_TARGET_CLIENT: { + gboolean writable; + gboolean changed = FALSE; + EBookClient *target_client; + + target_client = E_BOOK_CLIENT (g_value_get_object (value)); + + if (target_client == editor->target_client) + break; + + if (editor->target_client) { + g_signal_handler_disconnect ( + editor->target_client, + editor->target_editable_id); + g_object_unref (editor->target_client); } - widget = glade_xml_get_widget(editor->gui, "dateedit-birthday"); - if (widget && E_IS_DATE_EDIT(widget)) { - if (e_date_edit_get_date (E_DATE_EDIT (widget), - &bday.year, - &bday.month, - &bday.day)) { - /* g_print ("%d %d %d\n", bday.year, bday.month, bday.day); */ - gtk_object_set(GTK_OBJECT(card), - "birth_date", &bday, - NULL); - } else - gtk_object_set(GTK_OBJECT(card), - "birth_date", NULL, - NULL); + editor->target_client = target_client; + g_object_ref (editor->target_client); + + editor->target_editable_id = g_signal_connect ( + editor->target_client, "notify::readonly", + G_CALLBACK (notify_readonly_cb), editor); + + e_client_get_backend_property ( + E_CLIENT (editor->target_client), + BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS, + NULL, supported_fields_cb, editor); + + e_client_get_backend_property ( + E_CLIENT (editor->target_client), + BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS, + NULL, required_fields_cb, editor); + + if (!editor->is_new_contact) + editor->changed = TRUE; + + writable = !e_client_is_readonly (E_CLIENT (editor->target_client)); + + if (writable != editor->target_editable) { + editor->target_editable = writable; + changed = TRUE; } + + if (changed) + sensitize_all (editor); + + 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_all (editor); + editor->changed = FALSE; + break; + + case PROP_IS_NEW_CONTACT: + editor->is_new_contact = g_value_get_boolean (value); + break; + + case PROP_EDITABLE: { + gboolean new_value = g_value_get_boolean (value); + gboolean changed = (editor->target_editable != new_value); + + editor->target_editable = new_value; + + if (changed) + sensitize_all (editor); + break; + } + + case PROP_CHANGED: { + gboolean new_value = g_value_get_boolean (value); + gboolean changed = (editor->changed != new_value); + + editor->changed = new_value; + + if (changed) + sensitize_ok (editor); + break; + } + case PROP_WRITABLE_FIELDS: + g_slist_free_full ( + editor->writable_fields, + (GDestroyNotify) g_free); + editor->writable_fields = g_slist_copy_deep ( + g_value_get_pointer (value), + (GCopyFunc) g_strdup, NULL); + + sensitize_all (editor); + break; + case PROP_REQUIRED_FIELDS: + g_slist_free_full ( + editor->required_fields, + (GDestroyNotify) g_free); + editor->required_fields = g_slist_copy_deep ( + g_value_get_pointer (value), + (GCopyFunc) g_strdup, NULL); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +e_contact_editor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + EContactEditor *e_contact_editor; + + e_contact_editor = E_CONTACT_EDITOR (object); + + switch (property_id) { + case PROP_SOURCE_CLIENT: + g_value_set_object (value, e_contact_editor->source_client); + break; + + case PROP_TARGET_CLIENT: + g_value_set_object (value, e_contact_editor->target_client); + break; + + case PROP_CONTACT: + extract_all (e_contact_editor); + g_value_set_object (value, e_contact_editor->contact); + break; + + case PROP_IS_NEW_CONTACT: + g_value_set_boolean ( + value, e_contact_editor->is_new_contact); + break; + + case PROP_EDITABLE: + g_value_set_boolean ( + value, e_contact_editor->target_editable); + break; + + case PROP_CHANGED: + g_value_set_boolean ( + value, e_contact_editor->changed); + break; + + case PROP_WRITABLE_FIELDS: + g_value_set_pointer (value, e_contact_editor->writable_fields); + break; + case PROP_REQUIRED_FIELDS: + g_value_set_pointer (value, e_contact_editor->required_fields); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; } } @@ -2712,12 +4609,16 @@ extract_info(EContactEditor *editor) * * Raises the dialog associated with this %EContactEditor object. */ -void -e_contact_editor_raise (EContactEditor *editor) +static void +e_contact_editor_raise (EABEditor *editor) { - /* FIXME: perhaps we should raise at realize time */ - if (GTK_WIDGET (editor->app)->window) - gdk_window_raise (GTK_WIDGET (editor->app)->window); + EContactEditor *ce = E_CONTACT_EDITOR (editor); + GdkWindow *window; + + window = gtk_widget_get_window (ce->app); + + if (window != NULL) + gdk_window_raise (window); } /** @@ -2726,71 +4627,9 @@ e_contact_editor_raise (EContactEditor *editor) * * Shows the dialog associated with this %EContactEditor object. */ -void -e_contact_editor_show (EContactEditor *ce) -{ - gtk_widget_show (ce->app); -} - -GtkWidget * -e_contact_editor_create_date(gchar *name, - gchar *string1, gchar *string2, - gint int1, gint int2); - -GtkWidget * -e_contact_editor_create_date(gchar *name, - gchar *string1, gchar *string2, - gint int1, gint int2) -{ - GtkWidget *widget = e_date_edit_new (); - e_date_edit_set_allow_no_date_set (E_DATE_EDIT (widget), - TRUE); - e_date_edit_set_show_time (E_DATE_EDIT (widget), FALSE); - e_date_edit_set_time (E_DATE_EDIT (widget), -1); - return widget; -} - static void -enable_widget (GtkWidget *widget, gboolean enabled) -{ - if (GTK_IS_ENTRY (widget)) { - gtk_entry_set_editable (GTK_ENTRY (widget), enabled); - } - else if (GTK_IS_TEXT (widget)) { - gtk_text_set_editable (GTK_TEXT (widget), enabled); - } - else if (GTK_IS_COMBO (widget)) { - gtk_entry_set_editable (GTK_ENTRY (GTK_COMBO (widget)->entry), - enabled); - gtk_widget_set_sensitive (GTK_COMBO (widget)->button, enabled); - } - else if (E_IS_DATE_EDIT (widget)) { - e_date_edit_set_editable (E_DATE_EDIT (widget), enabled); - } - else - gtk_widget_set_sensitive (widget, enabled); -} - - -gboolean -e_contact_editor_request_close_all (void) +e_contact_editor_show (EABEditor *editor) { - GSList *p; - GSList *pnext; - gboolean retval; - - retval = TRUE; - for (p = all_contact_editors; p != NULL; p = pnext) { - pnext = p->next; - - e_contact_editor_raise (E_CONTACT_EDITOR (p->data)); - if (! prompt_to_save_changes (E_CONTACT_EDITOR (p->data))) { - retval = FALSE; - break; - } - - close_dialog (E_CONTACT_EDITOR (p->data)); - } - - return retval; + EContactEditor *ce = E_CONTACT_EDITOR (editor); + gtk_widget_show (ce->app); } diff --git a/addressbook/gui/contact-editor/e-contact-editor.h b/addressbook/gui/contact-editor/e-contact-editor.h index 0010182b99..49446f7350 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.h +++ b/addressbook/gui/contact-editor/e-contact-editor.h @@ -1,39 +1,33 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-contact-editor.h - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. */ + #ifndef __E_CONTACT_EDITOR_H__ #define __E_CONTACT_EDITOR_H__ -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-app-helper.h> -#include <bonobo/bonobo-ui-component.h> -#include <glade/glade.h> +#include "addressbook/gui/contact-editor/eab-editor.h" -#include "addressbook/gui/component/select-names/e-select-names-manager.h" -#include "addressbook/backend/ebook/e-book.h" -#include "addressbook/backend/ebook/e-card.h" -#include "addressbook/backend/ebook/e-card-simple.h" +#include <gtk/gtk.h> -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ +G_BEGIN_DECLS /* EContactEditor - A dialog displaying information about a contact. * @@ -44,96 +38,80 @@ extern "C" { * card ECard * RW The card currently being edited */ -#define E_CONTACT_EDITOR_TYPE (e_contact_editor_get_type ()) -#define E_CONTACT_EDITOR(obj) (GTK_CHECK_CAST ((obj), E_CONTACT_EDITOR_TYPE, EContactEditor)) -#define E_CONTACT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_CONTACT_EDITOR_TYPE, EContactEditorClass)) -#define E_IS_CONTACT_EDITOR(obj) (GTK_CHECK_TYPE ((obj), E_CONTACT_EDITOR_TYPE)) -#define E_IS_CONTACT_EDITOR_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_CONTACT_EDITOR_TYPE)) - +#define E_TYPE_CONTACT_EDITOR (e_contact_editor_get_type ()) +#define E_CONTACT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_EDITOR, EContactEditor)) +#define E_CONTACT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_EDITOR, EContactEditorClass)) +#define E_IS_CONTACT_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_EDITOR)) +#define E_IS_CONTACT_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_CONTACT_EDITOR)) typedef struct _EContactEditor EContactEditor; typedef struct _EContactEditorClass EContactEditorClass; struct _EContactEditor { - GtkObject object; - + EABEditor object; + /* item specific fields */ - EBook *book; - ECard *card; - ECardSimple *simple; - - /* UI handler */ - BonoboUIComponent *uic; - - GladeXML *gui; + EBookClient *source_client; + EBookClient *target_client; + EContact *contact; + + GtkBuilder *builder; GtkWidget *app; - GnomeUIInfo *email_info; - GnomeUIInfo *phone_info; - GnomeUIInfo *address_info; - GtkWidget *email_popup; - GtkWidget *phone_popup; - GtkWidget *address_popup; - GList *email_list; - GList *phone_list; - GList *address_list; - - ESelectNamesManager *select_names_contacts; - - ECardName *name; - char *company; - - ECardSimpleEmailId email_choice; - ECardSimplePhoneId phone_choice[4]; - ECardSimpleAddressId address_choice; - ECardSimpleAddressId address_mailing; - - GList *arbitrary_fields; - - /* Whether we are editing a new card or an existing one */ - guint is_new_card : 1; - - /* Whether the card has been changed since bringing up the contact editor */ + + GtkWidget *file_selector; + + EContactName *name; + + /* Whether we are editing a new contact or an existing one */ + guint is_new_contact : 1; + + /* Whether an image is associated with a contact. */ + 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; + /* Wheter should check for contact to merge. Only when name or email are changed */ + guint check_merge : 1; + + /* Whether the contact editor will accept modifications, save */ + guint target_editable : 1; /* Whether an async wombat call is in progress */ guint in_async_call : 1; - EList *writable_fields; -}; + /* Whether an image is changed */ + guint image_changed : 1; -struct _EContactEditorClass -{ - GtkObjectClass parent_class; + /* Whether to try to reduce space used */ + guint compress_ui : 1; - /* Notification signals */ + GSList *writable_fields; - void (* card_added) (EContactEditor *ce, EBookStatus status, ECard *card); - void (* card_modified) (EContactEditor *ce, EBookStatus status, ECard *card); - void (* card_deleted) (EContactEditor *ce, EBookStatus status, ECard *card); - void (* editor_closed) (EContactEditor *ce); -}; + GSList *required_fields; -EContactEditor *e_contact_editor_new (EBook *book, - ECard *card, - gboolean is_new_card, - gboolean editable); -GtkType e_contact_editor_get_type (void); + GCancellable *cancellable; -void e_contact_editor_show (EContactEditor *editor); -void e_contact_editor_close (EContactEditor *editor); -void e_contact_editor_raise (EContactEditor *editor); + /* signal ids for "writable_status" */ + gint target_editable_id; -gboolean e_contact_editor_confirm_delete (GtkWindow *parent); + GtkWidget *fullname_dialog; + GtkWidget *categories_dialog; +}; -gboolean e_contact_editor_request_close_all (void); +struct _EContactEditorClass +{ + EABEditorClass parent_class; +}; -#ifdef __cplusplus -} -#endif /* __cplusplus */ +GType e_contact_editor_get_type (void); +EABEditor *e_contact_editor_new (EShell *shell, + EBookClient *book_client, + EContact *contact, + gboolean is_new_contact, + gboolean editable); +G_END_DECLS #endif /* __E_CONTACT_EDITOR_H__ */ diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c index e8d623afb0..5814205c4d 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.c +++ b/addressbook/gui/contact-editor/e-contact-quick-add.c @@ -1,286 +1,395 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-contact-quick-add.c - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - /* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Jon Trowbridge <trow@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ +#ifdef HAVE_CONFIG_H #include <config.h> +#endif + #include <ctype.h> -#include <glib.h> -#include <gtk/gtkentry.h> -#include <gtk/gtklabel.h> -#include <gtk/gtktable.h> -#include <libgnome/gnome-defs.h> -#include <libgnome/gnome-i18n.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-dialog.h> -#include <libgnomeui/gnome-stock.h> -#include <gal/widgets/e-unicode.h> -#include <addressbook/gui/component/addressbook.h> -#include <addressbook/backend/ebook/e-book.h> -#include <addressbook/backend/ebook/e-book-util.h> -#include <addressbook/backend/ebook/e-card.h> +#include <string.h> +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include <addressbook/util/eab-book-util.h> #include "e-contact-editor.h" #include "e-contact-quick-add.h" -#include "e-card-merging.h" +#include "eab-contact-merging.h" typedef struct _QuickAdd QuickAdd; struct _QuickAdd { gchar *name; gchar *email; - ECard *card; + gchar *vcard; + EContact *contact; + GCancellable *cancellable; + EClientCache *client_cache; + ESource *source; EContactQuickAddCallback cb; gpointer closure; + GtkWidget *dialog; GtkWidget *name_entry; GtkWidget *email_entry; + GtkWidget *combo_box; gint refs; }; static QuickAdd * -quick_add_new (void) +quick_add_new (EClientCache *client_cache) { QuickAdd *qa = g_new0 (QuickAdd, 1); - qa->card = e_card_new (""); + qa->contact = e_contact_new (); + qa->client_cache = g_object_ref (client_cache); qa->refs = 1; return qa; } static void -quick_add_ref (QuickAdd *qa) -{ - if (qa) { - ++qa->refs; - } -} - -static void quick_add_unref (QuickAdd *qa) { if (qa) { --qa->refs; if (qa->refs == 0) { + if (qa->cancellable != NULL) { + g_cancellable_cancel (qa->cancellable); + g_object_unref (qa->cancellable); + } g_free (qa->name); g_free (qa->email); - gtk_object_unref (GTK_OBJECT (qa->card)); + g_free (qa->vcard); + g_object_unref (qa->contact); + g_object_unref (qa->client_cache); g_free (qa); } } } static void -quick_add_set_name (QuickAdd *qa, const gchar *name) +quick_add_set_name (QuickAdd *qa, + const gchar *name) { - ECardName *card_name; - if (name == qa->name) return; g_free (qa->name); - - card_name = e_card_name_from_string (name); - qa->name = e_card_name_to_string (card_name); - - gtk_object_set (GTK_OBJECT (qa->card), - "full_name", qa->name, - NULL); - - e_card_name_unref (card_name); + qa->name = g_strdup (name); } static void -quick_add_set_email (QuickAdd *qa, const gchar *email) +quick_add_set_email (QuickAdd *qa, + const gchar *email) { - ECardSimple *simple; - if (email == qa->email) return; g_free (qa->email); qa->email = g_strdup (email); +} + +static void +quick_add_set_vcard (QuickAdd *qa, + const gchar *vcard) +{ + if (vcard == qa->vcard) + return; - simple = e_card_simple_new (qa->card); - e_card_simple_set (simple, E_CARD_SIMPLE_FIELD_EMAIL, email); - e_card_simple_sync_card (simple); - gtk_object_unref (GTK_OBJECT (simple)); + g_free (qa->vcard); + qa->vcard = g_strdup (vcard); } static void -merge_cb (EBook *book, EBookStatus status, gpointer closure) +merge_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - QuickAdd *qa = (QuickAdd *) closure; + QuickAdd *qa = user_data; + EClient *client; + GError *error = NULL; + + client = e_client_cache_get_client_finish ( + E_CLIENT_CACHE (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + /* Ignore cancellations. */ + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_warn_if_fail (client == NULL); + g_error_free (error); + return; + } - if (book != NULL) { - e_card_merging_book_add_card (book, qa->card, NULL, NULL); - if (qa->cb) - qa->cb (qa->card, qa->closure); - gtk_object_unref (GTK_OBJECT (book)); - } else { - /* Something went wrong. */ + if (error != NULL) { if (qa->cb) qa->cb (NULL, qa->closure); + g_error_free (error); + quick_add_unref (qa); + return; + } + + if (!e_client_is_readonly (client)) { + ESourceRegistry *registry; + + registry = e_client_cache_ref_registry (qa->client_cache); + + eab_merging_book_add_contact ( + registry, E_BOOK_CLIENT (client), + qa->contact, NULL, NULL); + + g_object_unref (registry); + } else { + ESource *source = e_client_get_source (client); + + e_alert_run_dialog_for_args ( + e_shell_get_active_window (NULL), + "addressbook:error-read-only", + e_source_get_display_name (source), + NULL); } - + + if (qa->cb) + qa->cb (qa->contact, qa->closure); + + g_object_unref (client); + quick_add_unref (qa); } static void -quick_add_merge_card (QuickAdd *qa) +quick_add_merge_contact (QuickAdd *qa) { - EBook *book; + if (qa->cancellable != NULL) { + g_cancellable_cancel (qa->cancellable); + g_object_unref (qa->cancellable); + } - quick_add_ref (qa); + qa->cancellable = g_cancellable_new (); - book = e_book_new (); - if (!addressbook_load_default_book (book, merge_cb, qa)) { - gtk_object_unref (GTK_OBJECT (book)); - merge_cb (book, E_BOOK_STATUS_OTHER_ERROR, qa); - } + e_client_cache_get_client ( + qa->client_cache, qa->source, + E_SOURCE_EXTENSION_ADDRESS_BOOK, + qa->cancellable, merge_cb, qa); } - -/* - * Raise a contact editor with all fields editable, and hook up all signals accordingly. - */ +/* Raise a contact editor with all fields editable, + * and hook up all signals accordingly. */ static void -card_added_cb (EContactEditor *ce, EBookStatus status, ECard *card, gpointer closure) +contact_added_cb (EContactEditor *ce, + const GError *error, + EContact *contact, + gpointer closure) { - QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (ce), "quick_add"); + QuickAdd *qa; - if (qa) { + qa = g_object_get_data (G_OBJECT (ce), "quick_add"); + if (qa) { if (qa->cb) - qa->cb (qa->card, qa->closure); - + qa->cb (qa->contact, qa->closure); + /* We don't need to unref qa because we set_data_full below */ - gtk_object_set_data (GTK_OBJECT (ce), "quick_add", NULL); + g_object_set_data (G_OBJECT (ce), "quick_add", NULL); } } static void -editor_closed_cb (GtkWidget *w, gpointer closure) +editor_closed_cb (GtkWidget *w, + gpointer closure) { - QuickAdd *qa = (QuickAdd *) gtk_object_get_data (GTK_OBJECT (w), "quick_add"); + QuickAdd *qa; + + qa = g_object_get_data (G_OBJECT (w), "quick_add"); if (qa) /* We don't need to unref qa because we set_data_full below */ - gtk_object_set_data (GTK_OBJECT (w), "quick_add", NULL); - - gtk_object_unref (GTK_OBJECT (w)); + g_object_set_data (G_OBJECT (w), "quick_add", NULL); } static void -ce_have_book (EBook *book, EBookStatus status, gpointer closure) +ce_have_contact (EBookClient *book_client, + const GError *error, + EContact *contact, + gpointer closure) { QuickAdd *qa = (QuickAdd *) closure; - if (book == NULL) { - g_warning ("Couldn't open local address book."); + if (error) { + if (book_client) + g_object_unref (book_client); + g_warning ( + "Failed to find contact, status %d (%s).", + error->code, error->message); quick_add_unref (qa); } else { - EContactEditor *contact_editor = e_contact_editor_new (book, qa->card, TRUE, TRUE /* XXX */); - - /* mark it as changed so the Save buttons are enabled when we bring up the dialog. */ - gtk_object_set (GTK_OBJECT(contact_editor), - "changed", TRUE, - NULL); - - /* We pass this via object data, so that we don't get a dangling pointer referenced if both - the "card_added" and "editor_closed" get emitted. (Which, based on a backtrace in bugzilla, - I think can happen and cause a crash. */ - gtk_object_set_data_full (GTK_OBJECT (contact_editor), "quick_add", qa, - (GtkDestroyNotify) quick_add_unref); - - gtk_signal_connect (GTK_OBJECT (contact_editor), - "card_added", - GTK_SIGNAL_FUNC (card_added_cb), - NULL); - gtk_signal_connect (GTK_OBJECT (contact_editor), - "editor_closed", - GTK_SIGNAL_FUNC (editor_closed_cb), - NULL); - - gtk_object_unref (GTK_OBJECT (book)); + EShell *shell; + EABEditor *contact_editor; + + if (contact) { + /* use found contact */ + if (qa->contact) + g_object_unref (qa->contact); + qa->contact = g_object_ref (contact); + } + + shell = e_shell_get_default (); + contact_editor = e_contact_editor_new ( + shell, book_client, qa->contact, TRUE, TRUE /* XXX */); + + /* Mark it as changed so the Save buttons are + * enabled when we bring up the dialog. */ + g_object_set ( + contact_editor, "changed", contact != NULL, NULL); + + /* We pass this via object data, so that we don't get a + * dangling pointer referenced if both the "contact_added" + * and "editor_closed" get emitted. (Which, based on a + * backtrace in bugzilla, I think can happen and cause a + * crash. */ + g_object_set_data_full ( + G_OBJECT (contact_editor), "quick_add", qa, + (GDestroyNotify) quick_add_unref); + + g_signal_connect ( + contact_editor, "contact_added", + G_CALLBACK (contact_added_cb), NULL); + g_signal_connect ( + contact_editor, "editor_closed", + G_CALLBACK (editor_closed_cb), NULL); + + g_object_unref (book_client); + } +} + +static void +ce_have_book (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + QuickAdd *qa = user_data; + EClient *client; + ESourceRegistry *registry; + GError *error = NULL; + + client = e_client_cache_get_client_finish ( + E_CLIENT_CACHE (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + /* Ignore cancellations. */ + if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) || + g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_warn_if_fail (client == NULL); + g_error_free (error); + return; } + + if (error != NULL) { + g_warning ("%s", error->message); + quick_add_unref (qa); + g_error_free (error); + return; + } + + registry = e_client_cache_ref_registry (qa->client_cache); + + eab_merging_book_find_contact ( + registry, E_BOOK_CLIENT (client), + qa->contact, ce_have_contact, qa); + + g_object_unref (registry); } static void -edit_card (QuickAdd *qa) +edit_contact (QuickAdd *qa) { - EBook *book; - book = e_book_new (); - if (!addressbook_load_default_book (book, ce_have_book, qa)) { - gtk_object_unref (GTK_OBJECT (book)); - ce_have_book (book, E_BOOK_STATUS_OTHER_ERROR, qa); + if (qa->cancellable != NULL) { + g_cancellable_cancel (qa->cancellable); + g_object_unref (qa->cancellable); } + + qa->cancellable = g_cancellable_new (); + + e_client_cache_get_client ( + qa->client_cache, qa->source, + E_SOURCE_EXTENSION_ADDRESS_BOOK, + qa->cancellable, ce_have_book, qa); } +#define QUICK_ADD_RESPONSE_EDIT_FULL 2 + static void -clicked_cb (GtkWidget *w, gint button, gpointer closure) +clicked_cb (GtkWidget *w, + gint button, + gpointer closure) { QuickAdd *qa = (QuickAdd *) closure; /* Get data out of entries. */ - if (button == 0 || button == 1) { + if (!qa->vcard && (button == GTK_RESPONSE_OK || + button == QUICK_ADD_RESPONSE_EDIT_FULL)) { gchar *name = NULL; gchar *email = NULL; - if (qa->name_entry) { - gchar *tmp; - tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->name_entry), 0, -1); - name = e_utf8_from_gtk_string (qa->name_entry, tmp); - g_free (tmp); - } + if (qa->name_entry) + name = gtk_editable_get_chars ( + GTK_EDITABLE (qa->name_entry), 0, -1); - if (qa->email_entry) { - gchar *tmp; - tmp = gtk_editable_get_chars (GTK_EDITABLE (qa->email_entry), 0, -1); - email = e_utf8_from_gtk_string (qa->email_entry, tmp); - g_free (tmp); - } + if (qa->email_entry) + email = gtk_editable_get_chars ( + GTK_EDITABLE (qa->email_entry), 0, -1); + + e_contact_set ( + qa->contact, E_CONTACT_FULL_NAME, + (name != NULL) ? name : ""); + + e_contact_set ( + qa->contact, E_CONTACT_EMAIL_1, + (email != NULL) ? email : ""); - quick_add_set_name (qa, name); - quick_add_set_email (qa, email); - g_free (name); g_free (email); } gtk_widget_destroy (w); - if (button == 0) { + if (button == GTK_RESPONSE_OK) { /* OK */ - quick_add_merge_card (qa); + quick_add_merge_contact (qa); + + } else if (button == QUICK_ADD_RESPONSE_EDIT_FULL) { - } else if (button == 1) { - /* EDIT FULL */ - edit_card (qa); + edit_contact (qa); } else { /* CANCEL */ @@ -289,74 +398,177 @@ clicked_cb (GtkWidget *w, gint button, gpointer closure) } +static void +sanitize_widgets (QuickAdd *qa) +{ + GtkComboBox *combo_box; + const gchar *active_id; + gboolean enabled = TRUE; + + g_return_if_fail (qa != NULL); + g_return_if_fail (qa->dialog != NULL); + + combo_box = GTK_COMBO_BOX (qa->combo_box); + active_id = gtk_combo_box_get_active_id (combo_box); + enabled = (active_id != NULL); + + gtk_dialog_set_response_sensitive ( + GTK_DIALOG (qa->dialog), + QUICK_ADD_RESPONSE_EDIT_FULL, enabled); + gtk_dialog_set_response_sensitive ( + GTK_DIALOG (qa->dialog), GTK_RESPONSE_OK, enabled); +} + +static void +source_changed (ESourceComboBox *source_combo_box, + QuickAdd *qa) +{ + ESource *source; + + source = e_source_combo_box_ref_active (source_combo_box); + + if (source != NULL) { + if (qa->source != NULL) + g_object_unref (qa->source); + qa->source = source; /* takes reference */ + } + + sanitize_widgets (qa); +} + static GtkWidget * build_quick_add_dialog (QuickAdd *qa) { + GtkWidget *container; GtkWidget *dialog; + GtkWidget *label; GtkTable *table; - const gint xpad=1, ypad=1; + ESource *source; + ESourceRegistry *registry; + const gchar *extension_name; + const gint xpad = 0, ypad = 0; g_return_val_if_fail (qa != NULL, NULL); - dialog = gnome_dialog_new (_("Contact Quick-Add"), - GNOME_STOCK_BUTTON_OK, - _("Edit Full"), - GNOME_STOCK_BUTTON_CANCEL, - NULL); + dialog = gtk_dialog_new_with_buttons ( + _("Contact Quick-Add"), + e_shell_get_active_window (NULL), + 0, + _("_Edit Full"), QUICK_ADD_RESPONSE_EDIT_FULL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); - gtk_signal_connect (GTK_OBJECT (dialog), - "clicked", - clicked_cb, - qa); + gtk_widget_ensure_style (dialog); - qa->name_entry = gtk_entry_new (); - if (qa->name) { - gchar *str = e_utf8_to_gtk_string (qa->name_entry, qa->name); - gtk_entry_set_text (GTK_ENTRY (qa->name_entry), str); - g_free (str); - } + container = gtk_dialog_get_action_area (GTK_DIALOG (dialog)); + gtk_container_set_border_width (GTK_CONTAINER (container), 12); + container = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + gtk_container_set_border_width (GTK_CONTAINER (container), 0); + + g_signal_connect ( + dialog, "response", + G_CALLBACK (clicked_cb), qa); + qa->dialog = dialog; + + qa->name_entry = gtk_entry_new (); + if (qa->name) + gtk_entry_set_text (GTK_ENTRY (qa->name_entry), qa->name); qa->email_entry = gtk_entry_new (); - if (qa->email) { - gchar *str = e_utf8_to_gtk_string (qa->email_entry, qa->email); - gtk_entry_set_text (GTK_ENTRY (qa->email_entry), str); - g_free (str); + if (qa->email) + gtk_entry_set_text (GTK_ENTRY (qa->email_entry), qa->email); + + if (qa->vcard) { + /* when adding vCard, then do not allow change name or email */ + gtk_widget_set_sensitive (qa->name_entry, FALSE); + gtk_widget_set_sensitive (qa->email_entry, FALSE); } - table = GTK_TABLE (gtk_table_new (2, 2, FALSE)); - - gtk_table_attach (table, gtk_label_new (_("Full Name")), - 0, 1, 0, 1, - 0, 0, xpad, ypad); - gtk_table_attach (table, qa->name_entry, - 1, 2, 0, 1, - GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad); - gtk_table_attach (table, gtk_label_new (_("E-mail")), - 0, 1, 1, 2, - 0, 0, xpad, ypad); - gtk_table_attach (table, qa->email_entry, - 1, 2, 1, 2, - GTK_EXPAND | GTK_FILL, GTK_EXPAND, xpad, ypad); - - gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), - GTK_WIDGET (table), - TRUE, TRUE, 0); + extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK; + registry = e_client_cache_ref_registry (qa->client_cache); + source = e_source_registry_ref_default_address_book (registry); + g_object_unref (registry); + + qa->combo_box = e_client_combo_box_new ( + qa->client_cache, extension_name); + e_source_combo_box_set_active ( + E_SOURCE_COMBO_BOX (qa->combo_box), source); + + g_object_unref (source); + + source_changed (E_SOURCE_COMBO_BOX (qa->combo_box), qa); + g_signal_connect ( + qa->combo_box, "changed", + G_CALLBACK (source_changed), qa); + + table = GTK_TABLE (gtk_table_new (3, 2, FALSE)); + gtk_table_set_row_spacings (table, 6); + gtk_table_set_col_spacings (table, 12); + + label = gtk_label_new_with_mnemonic (_("_Full name")); + gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->name_entry); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + + gtk_table_attach ( + table, label, + 0, 1, 0, 1, + GTK_FILL, 0, xpad, ypad); + gtk_table_attach ( + table, qa->name_entry, + 1, 2, 0, 1, + GTK_EXPAND | GTK_FILL, 0, xpad, ypad); + + label = gtk_label_new_with_mnemonic (_("E_mail")); + gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->email_entry); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + + gtk_table_attach ( + table, label, + 0, 1, 1, 2, + GTK_FILL, 0, xpad, ypad); + gtk_table_attach ( + table, qa->email_entry, + 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, 0, xpad, ypad); + + label = gtk_label_new_with_mnemonic (_("_Select Address Book")); + gtk_label_set_mnemonic_widget ((GtkLabel *) label, qa->combo_box); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + + gtk_table_attach ( + table, label, + 0, 1, 2, 3, + GTK_FILL, 0, xpad, ypad); + gtk_table_attach ( + table, qa->combo_box, + 1, 2, 2, 3, + GTK_EXPAND | GTK_FILL, 0, xpad, ypad); + + gtk_container_set_border_width (GTK_CONTAINER (table), 12); + container = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + gtk_box_pack_start ( + GTK_BOX (container), GTK_WIDGET (table), FALSE, FALSE, 0); gtk_widget_show_all (GTK_WIDGET (table)); - - + return dialog; } void -e_contact_quick_add (const gchar *in_name, const gchar *email, - EContactQuickAddCallback cb, gpointer closure) +e_contact_quick_add (EClientCache *client_cache, + const gchar *in_name, + const gchar *email, + EContactQuickAddCallback cb, + gpointer closure) { QuickAdd *qa; GtkWidget *dialog; gchar *name = NULL; gint len; + g_return_if_fail (E_IS_CLIENT_CACHE (client_cache)); + /* We need to have *something* to work with. */ if (in_name == NULL && email == NULL) { if (cb) @@ -370,14 +582,15 @@ e_contact_quick_add (const gchar *in_name, const gchar *email, /* Remove extra whitespace and the quotes some mailers put around names. */ g_strstrip (name); len = strlen (name); - if ((name[0] == '\'' && name[len-1] == '\'') || (name[0] == '"' && name[len-1] == '"')) { + if ((name[0] == '\'' && name[len - 1] == '\'') || + (name[0] == '"' && name[len - 1] == '"')) { name[0] = ' '; - name[len-1] = ' '; + name[len - 1] = ' '; } g_strstrip (name); } - qa = quick_add_new (); + qa = quick_add_new (client_cache); qa->cb = cb; qa->closure = closure; if (name) @@ -392,14 +605,19 @@ e_contact_quick_add (const gchar *in_name, const gchar *email, } void -e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure) +e_contact_quick_add_free_form (EClientCache *client_cache, + const gchar *text, + EContactQuickAddCallback cb, + gpointer closure) { - gchar *name=NULL, *email=NULL; + gchar *name = NULL, *email = NULL; const gchar *last_at, *s; gboolean in_quote; + g_return_if_fail (E_IS_CLIENT_CACHE (client_cache)); + if (text == NULL) { - e_contact_quick_add (NULL, NULL, cb, closure); + e_contact_quick_add (client_cache, NULL, NULL, cb, closure); return; } @@ -413,16 +631,17 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g in_quote = !in_quote; } - if (last_at == NULL) { /* No at sign, so we treat it all as the name */ name = g_strdup (text); } else { gboolean bad_char = FALSE; - + /* walk backwards to whitespace or a < or a quote... */ while (last_at >= text && !bad_char - && !(isspace ((gint) *last_at) || *last_at == '<' || *last_at == '"')) { + && !(isspace ((gint) *last_at) || + *last_at == '<' || + *last_at == '"')) { /* Check for some stuff that can't appear in a legal e-mail address. */ if (*last_at == '[' || *last_at == ']' @@ -437,16 +656,14 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g /* ...and then split the text there */ if (!bad_char) { if (text < last_at) - name = g_strndup (text, last_at-text); + name = g_strndup (text, last_at - text); email = g_strdup (last_at); } } /* If all else has failed, make it the name. */ - if (name == NULL && email == NULL) + if (name == NULL && email == NULL) name = g_strdup (text); - - /* Clean up email, remove bracketing <>s */ if (email && *email) { @@ -456,16 +673,106 @@ e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, g *email = ' '; changed = TRUE; } - if (email[strlen (email)-1] == '>') { - email[strlen (email)-1] = ' '; + if (email[strlen (email) - 1] == '>') { + email[strlen (email) - 1] = ' '; changed = TRUE; } if (changed) g_strstrip (email); } - - e_contact_quick_add (name, email, cb, closure); + e_contact_quick_add (client_cache, name, email, cb, closure); + g_free (name); g_free (email); } + +void +e_contact_quick_add_email (EClientCache *client_cache, + const gchar *email, + EContactQuickAddCallback cb, + gpointer closure) +{ + gchar *name = NULL; + gchar *addr = NULL; + gchar *lt, *gt; + + /* Handle something of the form "Foo <foo@bar.com>". This is more + * more forgiving than the free-form parser, allowing for unquoted + * whitespace since we know the whole string is an email address. */ + + lt = (email != NULL) ? strchr (email, '<') : NULL; + gt = (lt != NULL) ? strchr (email, '>') : NULL; + + if (lt != NULL && gt != NULL && (gt - lt) > 0) { + name = g_strndup (email, lt - email); + addr = g_strndup (lt + 1, gt - lt - 1); + } else { + addr = g_strdup (email); + } + + e_contact_quick_add (client_cache, name, addr, cb, closure); + + g_free (name); + g_free (addr); +} + +void +e_contact_quick_add_vcard (EClientCache *client_cache, + const gchar *vcard, + EContactQuickAddCallback cb, + gpointer closure) +{ + QuickAdd *qa; + GtkWidget *dialog; + EContact *contact; + + g_return_if_fail (E_IS_CLIENT_CACHE (client_cache)); + + /* We need to have *something* to work with. */ + if (vcard == NULL) { + if (cb) + cb (NULL, closure); + return; + } + + qa = quick_add_new (client_cache); + qa->cb = cb; + qa->closure = closure; + quick_add_set_vcard (qa, vcard); + + contact = e_contact_new_from_vcard (qa->vcard); + + if (contact) { + GList *emails; + gchar *name; + EContactName *contact_name; + + g_object_unref (qa->contact); + qa->contact = contact; + + contact_name = e_contact_get (qa->contact, E_CONTACT_NAME); + name = e_contact_name_to_string (contact_name); + quick_add_set_name (qa, name); + g_free (name); + e_contact_name_free (contact_name); + + emails = e_contact_get (qa->contact, E_CONTACT_EMAIL); + if (emails) { + quick_add_set_email (qa, emails->data); + + g_list_foreach (emails, (GFunc) g_free, NULL); + g_list_free (emails); + } + } else { + if (cb) + cb (NULL, closure); + + quick_add_unref (qa); + g_warning ("Contact's vCard parsing failed!"); + return; + } + + dialog = build_quick_add_dialog (qa); + gtk_widget_show_all (dialog); +} diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.h b/addressbook/gui/contact-editor/e-contact-quick-add.h index 1bf69ee114..abc94fddb7 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.h +++ b/addressbook/gui/contact-editor/e-contact-quick-add.h @@ -1,40 +1,52 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ - -/* - * e-contact-quick-add.h - * - * Copyright (C) 2001 Ximian, Inc. - * - * Developed by Jon Trowbridge <trow@ximian.com> - */ - /* * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - * USA. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Jon Trowbridge <trow@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * */ #ifndef __E_CONTACT_QUICK_ADD_H__ #define __E_CONTACT_QUICK_ADD_H__ -#include <addressbook/backend/ebook/e-card.h> - -typedef void (*EContactQuickAddCallback) (ECard *new_card, gpointer closure); - -void e_contact_quick_add (const gchar *name, const gchar *email, - EContactQuickAddCallback cb, gpointer closure); - -void e_contact_quick_add_free_form (const gchar *text, EContactQuickAddCallback cb, gpointer closure); +#include <libebook/libebook.h> + +#include <e-util/e-util.h> + +typedef void (*EContactQuickAddCallback) (EContact *new_contact, + gpointer closure); + +void e_contact_quick_add (EClientCache *client_cache, + const gchar *name, + const gchar *email, + EContactQuickAddCallback cb, + gpointer closure); +void e_contact_quick_add_free_form (EClientCache *client_cache, + const gchar *text, + EContactQuickAddCallback cb, + gpointer closure); +void e_contact_quick_add_email (EClientCache *client_cache, + const gchar *email, + EContactQuickAddCallback cb, + gpointer closure); +void e_contact_quick_add_vcard (EClientCache *client_cache, + const gchar *vcard, + EContactQuickAddCallback cb, + gpointer closure); #endif /* __E_CONTACT_QUICK_ADD_H__ */ diff --git a/addressbook/gui/contact-editor/e-contact-save-as.c b/addressbook/gui/contact-editor/e-contact-save-as.c deleted file mode 100644 index f2251ee233..0000000000 --- a/addressbook/gui/contact-editor/e-contact-save-as.c +++ /dev/null @@ -1,228 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-contact-editor.h - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include <config.h> - -#include "e-contact-save-as.h" - -#include <unistd.h> -#include <fcntl.h> -#include <gtk/gtkfilesel.h> -#include <gtk/gtksignal.h> -#include <gtk/gtk.h> -#include <libgnomeui/gnome-dialog.h> -#include <gal/util/e-util.h> -#include <libgnome/gnome-i18n.h> -#include <errno.h> -#include <string.h> -#include <libgnomeui/gnome-messagebox.h> -#include <libgnomeui/gnome-stock.h> - -static int file_exists(GtkFileSelection *filesel, const char *filename); - -typedef struct { - GtkFileSelection *filesel; - char *vcard; -} SaveAsInfo; - -static void -save_it(GtkWidget *widget, SaveAsInfo *info) -{ - gint error = 0; - gint response = 0; - - const char *filename = gtk_file_selection_get_filename (info->filesel); - - error = e_write_file (filename, info->vcard, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC); - - if (error == EEXIST) { - response = file_exists(info->filesel, filename); - switch (response) { - case 0 : /* Overwrite */ - e_write_file(filename, info->vcard, O_WRONLY | O_CREAT | O_TRUNC); - break; - case 1 : /* cancel */ - return; - } - } else if (error != 0) { - GtkWidget *dialog; - char *str; - - str = g_strdup_printf ("Error saving %s: %s", filename, strerror(errno)); - dialog = gnome_message_box_new (str, GNOME_MESSAGE_BOX_ERROR, GNOME_STOCK_BUTTON_OK, NULL); - g_free (str); - - gnome_dialog_set_parent (GNOME_DIALOG (dialog), GTK_WINDOW (info->filesel)); - - gtk_widget_show (dialog); - - return; - } - - g_free (info->vcard); - gtk_widget_destroy(GTK_WIDGET(info->filesel)); - g_free(info); -} - -static void -close_it(GtkWidget *widget, SaveAsInfo *info) -{ - g_free (info->vcard); - gtk_widget_destroy (GTK_WIDGET (info->filesel)); - g_free (info); -} - -static void -delete_it(GtkWidget *widget, SaveAsInfo *info) -{ - g_free (info->vcard); - g_free (info); -} - -static char * -make_safe_filename (const char *prefix, char *name) -{ - char *safe, *p; - - if (!name) { - /* This is a filename. Translators take note. */ - name = _("card.vcf"); - } - - p = strrchr (name, '/'); - if (p) - safe = g_strdup_printf ("%s%s%s", prefix, p, ".vcf"); - else - safe = g_strdup_printf ("%s/%s%s", prefix, name, ".vcf"); - - p = strrchr (safe, '/') + 1; - if (p) - e_filename_make_safe (p); - - return safe; -} - -void -e_contact_save_as(char *title, ECard *card, GtkWindow *parent_window) -{ - GtkFileSelection *filesel; - char *file; - char *name; - SaveAsInfo *info = g_new(SaveAsInfo, 1); - - filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title)); - - gtk_object_get (GTK_OBJECT (card), - "file_as", &name, - NULL); - file = make_safe_filename (g_get_home_dir(), name); - gtk_file_selection_set_filename (filesel, file); - g_free (file); - - info->filesel = filesel; - info->vcard = e_card_get_vcard(card); - - gtk_signal_connect(GTK_OBJECT(filesel->ok_button), "clicked", - save_it, info); - gtk_signal_connect(GTK_OBJECT(filesel->cancel_button), "clicked", - close_it, info); - gtk_signal_connect(GTK_OBJECT(filesel), "delete_event", - delete_it, info); - - if (parent_window) { - gtk_window_set_transient_for (GTK_WINDOW (filesel), - parent_window); - gtk_window_set_modal (GTK_WINDOW (filesel), TRUE); - } - - gtk_widget_show(GTK_WIDGET(filesel)); -} - -void -e_contact_list_save_as(char *title, GList *list, GtkWindow *parent_window) -{ - GtkFileSelection *filesel; - SaveAsInfo *info = g_new(SaveAsInfo, 1); - - filesel = GTK_FILE_SELECTION(gtk_file_selection_new(title)); - - /* This is a filename. Translators take note. */ - if (list && list->data && list->next == NULL) { - char *name, *file; - gtk_object_get (GTK_OBJECT (list->data), - "file_as", &name, - NULL); - file = make_safe_filename (g_get_home_dir(), name); - gtk_file_selection_set_filename (filesel, file); - g_free (file); - } else { - char *file; - file = make_safe_filename (g_get_home_dir(), _("list")); - gtk_file_selection_set_filename (filesel, file); - g_free (file); - } - - info->filesel = filesel; - info->vcard = e_card_list_get_vcard (list); - - gtk_signal_connect(GTK_OBJECT(filesel->ok_button), "clicked", - save_it, info); - gtk_signal_connect(GTK_OBJECT(filesel->cancel_button), "clicked", - close_it, info); - gtk_signal_connect(GTK_OBJECT(filesel), "delete_event", - delete_it, info); - - if (parent_window) { - gtk_window_set_transient_for (GTK_WINDOW (filesel), - parent_window); - gtk_window_set_modal (GTK_WINDOW (filesel), TRUE); - } - - gtk_widget_show(GTK_WIDGET(filesel)); -} - -static int -file_exists(GtkFileSelection *filesel, const char *filename) -{ - GnomeDialog *dialog = NULL; - GtkWidget *label; - GladeXML *gui = NULL; - int result = 0; - char *string; - - gui = glade_xml_new (EVOLUTION_GLADEDIR "/file-exists.glade", NULL); - dialog = GNOME_DIALOG(glade_xml_get_widget(gui, "dialog-exists")); - - label = glade_xml_get_widget (gui, "label-exists"); - if (GTK_IS_LABEL (label)) { - string = g_strdup_printf (_("%s already exists\nDo you want to overwrite it?"), filename); - gtk_label_set_text (GTK_LABEL (label), string); - g_free (string); - } - - gnome_dialog_set_parent(dialog, GTK_WINDOW(filesel)); - - gtk_widget_show (GTK_WIDGET (dialog)); - result = gnome_dialog_run_and_close(dialog); - - g_free(gui); - - return result; -} diff --git a/addressbook/gui/contact-editor/e-contact-save-as.h b/addressbook/gui/contact-editor/e-contact-save-as.h deleted file mode 100644 index 66d1e8bad9..0000000000 --- a/addressbook/gui/contact-editor/e-contact-save-as.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* e-contact-save-as.h - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ -#ifndef __E_CONTACT_SAVE_AS_H__ -#define __E_CONTACT_SAVE_AS_H__ - -#include <glade/glade.h> -#include "addressbook/backend/ebook/e-card.h" -#include "addressbook/backend/ebook/e-card-simple.h" - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -void e_contact_save_as (gchar *title, ECard *card, GtkWindow *parent_window); -void e_contact_list_save_as (gchar *title, GList *list, GtkWindow *parent_window); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __E_CONTACT_EDITOR_H__ */ diff --git a/addressbook/gui/contact-editor/eab-editor.c b/addressbook/gui/contact-editor/eab-editor.c new file mode 100644 index 0000000000..fcbdfb1049 --- /dev/null +++ b/addressbook/gui/contact-editor/eab-editor.c @@ -0,0 +1,403 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Toshok <toshok@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gtk/gtk.h> +#include <glib/gi18n.h> + +#include "eab-editor.h" +#include "e-util/e-util.h" +#include "addressbook/gui/widgets/eab-gui-util.h" + +#define EAB_EDITOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), EAB_TYPE_EDITOR, EABEditorPrivate)) + +struct _EABEditorPrivate { + EShell *shell; +}; + +enum { + PROP_0, + PROP_SHELL +}; + +enum { + CONTACT_ADDED, + CONTACT_MODIFIED, + CONTACT_DELETED, + EDITOR_CLOSED, + LAST_SIGNAL +}; + +static GSList *all_editors; +static guint signals[LAST_SIGNAL]; + +G_DEFINE_ABSTRACT_TYPE (EABEditor, eab_editor, G_TYPE_OBJECT) + +static void +eab_editor_quit_requested_cb (EShell *shell, + EShellQuitReason reason, + EABEditor *editor) +{ + GtkWindow *window; + + /* Quit immediately if another Evolution process asked us to. */ + if (reason == E_SHELL_QUIT_REMOTE_REQUEST) + return; + + window = eab_editor_get_window (editor); + + eab_editor_raise (editor); + if (!eab_editor_prompt_to_save_changes (editor, window)) + e_shell_cancel_quit (shell); +} + +static void +eab_editor_set_shell (EABEditor *editor, + EShell *shell) +{ + g_return_if_fail (editor->priv->shell == NULL); + g_return_if_fail (E_IS_SHELL (shell)); + + editor->priv->shell = g_object_ref (shell); + + g_signal_connect ( + shell, "quit-requested", + G_CALLBACK (eab_editor_quit_requested_cb), editor); +} + +static void +eab_editor_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL: + eab_editor_set_shell ( + EAB_EDITOR (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +eab_editor_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL: + g_value_set_object ( + value, eab_editor_get_shell ( + EAB_EDITOR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +eab_editor_dispose (GObject *object) +{ + EABEditorPrivate *priv; + + priv = EAB_EDITOR_GET_PRIVATE (object); + + if (priv->shell != NULL) { + g_signal_handlers_disconnect_matched ( + priv->shell, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + g_object_unref (priv->shell); + priv->shell = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (eab_editor_parent_class)->dispose (object); +} + +static void +eab_editor_finalize (GObject *object) +{ + all_editors = g_slist_remove (all_editors, object); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (eab_editor_parent_class)->finalize (object); +} + +static void +eab_editor_class_init (EABEditorClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EABEditorPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = eab_editor_set_property; + object_class->get_property = eab_editor_get_property; + object_class->dispose = eab_editor_dispose; + object_class->finalize = eab_editor_finalize; + + g_object_class_install_property ( + object_class, + PROP_SHELL, + g_param_spec_object ( + "shell", + "Shell", + "The EShell singleton", + E_TYPE_SHELL, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + signals[CONTACT_ADDED] = g_signal_new ( + "contact_added", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EABEditorClass, contact_added), + NULL, NULL, + e_marshal_NONE__POINTER_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_POINTER, + G_TYPE_OBJECT); + + signals[CONTACT_MODIFIED] = g_signal_new ( + "contact_modified", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EABEditorClass, contact_modified), + NULL, NULL, + e_marshal_NONE__POINTER_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_POINTER, + G_TYPE_OBJECT); + + signals[CONTACT_DELETED] = g_signal_new ( + "contact_deleted", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EABEditorClass, contact_deleted), + NULL, NULL, + e_marshal_NONE__POINTER_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_POINTER, + G_TYPE_OBJECT); + + signals[EDITOR_CLOSED] = g_signal_new ( + "editor_closed", + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (EABEditorClass, editor_closed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +static void +eab_editor_init (EABEditor *editor) +{ + editor->priv = EAB_EDITOR_GET_PRIVATE (editor); + + all_editors = g_slist_prepend (all_editors, editor); +} + +EShell * +eab_editor_get_shell (EABEditor *editor) +{ + g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL); + + return E_SHELL (editor->priv->shell); +} + +GSList * +eab_editor_get_all_editors (void) +{ + return all_editors; +} + +void +eab_editor_show (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_if_fail (EAB_IS_EDITOR (editor)); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_if_fail (class->show != NULL); + + class->show (editor); +} + +void +eab_editor_close (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_if_fail (EAB_IS_EDITOR (editor)); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_if_fail (class->close != NULL); + + class->close (editor); +} + +void +eab_editor_raise (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_if_fail (EAB_IS_EDITOR (editor)); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_if_fail (class->raise != NULL); + + class->raise (editor); +} + +void +eab_editor_save_contact (EABEditor *editor, + gboolean should_close) +{ + EABEditorClass *class; + + g_return_if_fail (EAB_IS_EDITOR (editor)); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_if_fail (class->save_contact != NULL); + + class->save_contact (editor, should_close); +} + +gboolean +eab_editor_is_changed (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_val_if_fail (class->is_changed != NULL, FALSE); + + return class->is_changed (editor); +} + +gboolean +eab_editor_is_valid (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_val_if_fail (EAB_IS_EDITOR (editor), FALSE); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_val_if_fail (class->is_valid != NULL, FALSE); + + return class->is_valid (editor); +} + +GtkWindow * +eab_editor_get_window (EABEditor *editor) +{ + EABEditorClass *class; + + g_return_val_if_fail (EAB_IS_EDITOR (editor), NULL); + + class = EAB_EDITOR_GET_CLASS (editor); + g_return_val_if_fail (class->get_window != NULL, NULL); + + return class->get_window (editor); +} + +/* This function prompts for saving if editor conents are in changed state and + * save or discards or cancels (just returns with out doing anything) according + * to user input. Editor gets destroyed in case of save and discard case. */ + +gboolean +eab_editor_prompt_to_save_changes (EABEditor *editor, + GtkWindow *window) +{ + if (!eab_editor_is_changed (editor)) { + eab_editor_close (EAB_EDITOR (editor)); + return TRUE; + } + + switch (eab_prompt_save_dialog (window)) { + case GTK_RESPONSE_YES: + if (!eab_editor_is_valid (editor)) { + return FALSE; + } + eab_editor_save_contact (editor, TRUE); + return TRUE; + case GTK_RESPONSE_NO: + eab_editor_close (EAB_EDITOR (editor)); + return TRUE; + case GTK_RESPONSE_CANCEL: + default: + return FALSE; + } +} + +void +eab_editor_contact_added (EABEditor *editor, + const GError *error, + EContact *contact) +{ + g_return_if_fail (EAB_IS_EDITOR (editor)); + g_return_if_fail (E_IS_CONTACT (contact)); + + g_signal_emit (editor, signals[CONTACT_ADDED], 0, error, contact); +} + +void +eab_editor_contact_modified (EABEditor *editor, + const GError *error, + EContact *contact) +{ + g_return_if_fail (EAB_IS_EDITOR (editor)); + g_return_if_fail (E_IS_CONTACT (contact)); + + g_signal_emit (editor, signals[CONTACT_MODIFIED], 0, error, contact); +} + +void +eab_editor_contact_deleted (EABEditor *editor, + const GError *error, + EContact *contact) +{ + g_return_if_fail (EAB_IS_EDITOR (editor)); + g_return_if_fail (E_IS_CONTACT (contact)); + + g_signal_emit (editor, signals[CONTACT_DELETED], 0, error, contact); +} + +void +eab_editor_closed (EABEditor *editor) +{ + g_return_if_fail (EAB_IS_EDITOR (editor)); + + g_signal_emit (editor, signals[EDITOR_CLOSED], 0); +} diff --git a/addressbook/gui/contact-editor/eab-editor.h b/addressbook/gui/contact-editor/eab-editor.h new file mode 100644 index 0000000000..88ede1522f --- /dev/null +++ b/addressbook/gui/contact-editor/eab-editor.h @@ -0,0 +1,112 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Toshok <toshok@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EAB_EDITOR_H__ +#define __EAB_EDITOR_H__ + +#include <gtk/gtk.h> +#include <libebook/libebook.h> +#include <shell/e-shell.h> + +/* Standard GObject macros */ +#define EAB_TYPE_EDITOR \ + (eab_editor_get_type ()) +#define EAB_EDITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), EAB_TYPE_EDITOR, EABEditor)) +#define EAB_EDITOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), EAB_TYPE_EDITOR, EABEditorClass)) +#define EAB_IS_EDITOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), EAB_TYPE_EDITOR)) +#define EAB_IS_EDITOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), EAB_TYPE_EDITOR)) +#define EAB_EDITOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), EAB_EDITOR_TYPE, EABEditorClass)) + +G_BEGIN_DECLS + +typedef struct _EABEditor EABEditor; +typedef struct _EABEditorClass EABEditorClass; +typedef struct _EABEditorPrivate EABEditorPrivate; + +struct _EABEditor { + GObject parent; + EABEditorPrivate *priv; +}; + +struct _EABEditorClass { + GObjectClass parent_class; + + /* virtual functions */ + void (* show) (EABEditor *editor); + void (* close) (EABEditor *editor); + void (* raise) (EABEditor *editor); + void (* save_contact) (EABEditor *editor, gboolean should_close); + gboolean (* is_valid) (EABEditor *editor); + gboolean (* is_changed) (EABEditor *editor); + GtkWindow * (* get_window) (EABEditor *editor); + + /* signals */ + void (* contact_added) (EABEditor *editor, const GError *error, EContact *contact); + void (* contact_modified) (EABEditor *editor, const GError *error, EContact *contact); + void (* contact_deleted) (EABEditor *editor, const GError *error, EContact *contact); + void (* editor_closed) (EABEditor *editor); +}; + +GType eab_editor_get_type (void); +EShell * eab_editor_get_shell (EABEditor *editor); +GSList * eab_editor_get_all_editors (void); + +/* virtual functions */ +void eab_editor_show (EABEditor *editor); +void eab_editor_close (EABEditor *editor); +void eab_editor_raise (EABEditor *editor); +void eab_editor_save_contact (EABEditor *editor, + gboolean should_close); +gboolean eab_editor_is_valid (EABEditor *editor); +gboolean eab_editor_is_changed (EABEditor *editor); +GtkWindow * eab_editor_get_window (EABEditor *editor); + +gboolean eab_editor_prompt_to_save_changes + (EABEditor *editor, + GtkWindow *window); + +/* these four generate EABEditor signals */ +void eab_editor_contact_added (EABEditor *editor, + const GError *error, + EContact *contact); +void eab_editor_contact_modified (EABEditor *editor, + const GError *error, + EContact *contact); +void eab_editor_contact_deleted (EABEditor *editor, + const GError *error, + EContact *contact); +void eab_editor_closed (EABEditor *editor); + +G_END_DECLS + +#endif /* __E_CONTACT_EDITOR_H__ */ diff --git a/addressbook/gui/contact-editor/file-exists.glade b/addressbook/gui/contact-editor/file-exists.glade deleted file mode 100644 index 7c457cb892..0000000000 --- a/addressbook/gui/contact-editor/file-exists.glade +++ /dev/null @@ -1,95 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>File_exists.glade</name> - <program_name>file_exists.glade</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> -</project> - -<widget> - <class>GnomeDialog</class> - <name>dialog-exists</name> - <visible>False</visible> - <title>Confirm Overwrite</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>False</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>False</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>dialog-vbox1</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>dialog-action_area1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <label>Overwrite</label> - </widget> - - <widget> - <class>GtkButton</class> - <name>button3</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label-exists</name> - <label>Don't bother translating this string. It's not used.</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0.5</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>False</fill> - </child> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/addressbook/gui/contact-editor/fulladdr.glade b/addressbook/gui/contact-editor/fulladdr.glade deleted file mode 100644 index d66b9163e8..0000000000 --- a/addressbook/gui/contact-editor/fulladdr.glade +++ /dev/null @@ -1,473 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>fulladdr</name> - <program_name>fulladdr</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>True</use_widget_names> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> -</project> - -<widget> - <class>GnomeDialog</class> - <name>dialog-checkaddress</name> - <visible>False</visible> - <title>Check Address</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>True</modal> - <allow_shrink>False</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>vbox-container</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <has_default>True</has_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button2</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkTable</class> - <name>table-checkaddress</name> - <border_width>8</border_width> - <rows>4</rows> - <columns>4</columns> - <homogeneous>False</homogeneous> - <row_spacing>6</row_spacing> - <column_spacing>6</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkLabel</class> - <name>label2</name> - <label>_Address:</label> - <justify>GTK_JUSTIFY_LEFT</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-street</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <label>_City:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-city</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-city</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-ext</name> - <width>100</width> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label8</name> - <label>_PO Box:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-po</focus_target> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>Address _2:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-ext</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-po</name> - <width>100</width> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-street</name> - <can_focus>True</can_focus> - <has_focus>True</has_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>4</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label5</name> - <label>_State/Province:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-region</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-region</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkCombo</class> - <name>combo-country</name> - <width>100</width> - <can_focus>True</can_focus> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items></items> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry-country</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-code</name> - <width>100</width> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>3</left_attach> - <right_attach>4</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label6</name> - <label>_ZIP Code:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-code</focus_target> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label7</name> - <label>Countr_y:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>1</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-country</focus_target> - <child> - <left_attach>2</left_attach> - <right_attach>3</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/addressbook/gui/contact-editor/fullname.glade b/addressbook/gui/contact-editor/fullname.glade deleted file mode 100644 index 17be70647c..0000000000 --- a/addressbook/gui/contact-editor/fullname.glade +++ /dev/null @@ -1,389 +0,0 @@ -<?xml version="1.0"?> -<GTK-Interface> - -<project> - <name>fullname</name> - <program_name>fullname</program_name> - <directory></directory> - <source_directory>src</source_directory> - <pixmaps_directory>pixmaps</pixmaps_directory> - <language>C</language> - <gnome_support>True</gnome_support> - <gettext_support>True</gettext_support> - <use_widget_names>True</use_widget_names> - <output_main_file>False</output_main_file> - <output_support_files>False</output_support_files> - <output_build_files>False</output_build_files> -</project> - -<widget> - <class>GnomeDialog</class> - <name>dialog-checkfullname</name> - <visible>False</visible> - <title>Check Full Name</title> - <type>GTK_WINDOW_TOPLEVEL</type> - <position>GTK_WIN_POS_NONE</position> - <modal>True</modal> - <allow_shrink>True</allow_shrink> - <allow_grow>True</allow_grow> - <auto_shrink>False</auto_shrink> - <auto_close>False</auto_close> - <hide_on_close>False</hide_on_close> - - <widget> - <class>GtkVBox</class> - <child_name>GnomeDialog:vbox</child_name> - <name>vbox-container</name> - <homogeneous>False</homogeneous> - <spacing>8</spacing> - <child> - <padding>4</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkHButtonBox</class> - <child_name>GnomeDialog:action_area</child_name> - <name>hbuttonbox1</name> - <layout_style>GTK_BUTTONBOX_END</layout_style> - <spacing>8</spacing> - <child_min_width>85</child_min_width> - <child_min_height>27</child_min_height> - <child_ipad_x>7</child_ipad_x> - <child_ipad_y>0</child_ipad_y> - <child> - <padding>0</padding> - <expand>False</expand> - <fill>True</fill> - <pack>GTK_PACK_END</pack> - </child> - - <widget> - <class>GtkButton</class> - <name>button1</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_OK</stock_button> - </widget> - - <widget> - <class>GtkButton</class> - <name>button2</name> - <can_default>True</can_default> - <can_focus>True</can_focus> - <stock_button>GNOME_STOCK_BUTTON_CANCEL</stock_button> - </widget> - </widget> - - <widget> - <class>GtkTable</class> - <name>table-checkfullname</name> - <border_width>8</border_width> - <rows>5</rows> - <columns>3</columns> - <homogeneous>False</homogeneous> - <row_spacing>6</row_spacing> - <column_spacing>21</column_spacing> - <child> - <padding>0</padding> - <expand>True</expand> - <fill>True</fill> - </child> - - <widget> - <class>GtkCombo</class> - <name>combo-title</name> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items> -Mr. -Mrs. -Ms. -Miss -Dr. -</items> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry-title</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkCombo</class> - <name>combo-suffix</name> - <value_in_list>False</value_in_list> - <ok_if_empty>True</ok_if_empty> - <case_sensitive>False</case_sensitive> - <use_arrows>True</use_arrows> - <use_arrows_always>False</use_arrows_always> - <items> -Sr. -Jr. -I -II -III -Esq. -</items> - <child> - <left_attach>1</left_attach> - <right_attach>2</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - - <widget> - <class>GtkEntry</class> - <child_name>GtkCombo:entry</child_name> - <name>entry-suffix</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - </widget> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-first</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-middle</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkEntry</class> - <name>entry-last</name> - <can_focus>True</can_focus> - <editable>True</editable> - <text_visible>True</text_visible> - <text_max_length>0</text_max_length> - <text></text> - <child> - <left_attach>1</left_attach> - <right_attach>3</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>True</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>False</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label2</name> - <label>_First:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-first</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>1</top_attach> - <bottom_attach>2</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label1</name> - <label>_Title:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-title</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>0</top_attach> - <bottom_attach>1</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label3</name> - <label>_Middle:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-middle</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>2</top_attach> - <bottom_attach>3</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label5</name> - <label>_Last:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-last</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>3</top_attach> - <bottom_attach>4</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - - <widget> - <class>GtkLabel</class> - <name>label4</name> - <label>_Suffix:</label> - <justify>GTK_JUSTIFY_CENTER</justify> - <wrap>False</wrap> - <xalign>0</xalign> - <yalign>0.5</yalign> - <xpad>0</xpad> - <ypad>0</ypad> - <focus_target>entry-suffix</focus_target> - <child> - <left_attach>0</left_attach> - <right_attach>1</right_attach> - <top_attach>4</top_attach> - <bottom_attach>5</bottom_attach> - <xpad>0</xpad> - <ypad>0</ypad> - <xexpand>False</xexpand> - <yexpand>False</yexpand> - <xshrink>False</xshrink> - <yshrink>False</yshrink> - <xfill>True</xfill> - <yfill>True</yfill> - </child> - </widget> - </widget> - </widget> -</widget> - -</GTK-Interface> diff --git a/addressbook/gui/contact-editor/fullname.ui b/addressbook/gui/contact-editor/fullname.ui new file mode 100644 index 0000000000..90a1f04a9b --- /dev/null +++ b/addressbook/gui/contact-editor/fullname.ui @@ -0,0 +1,363 @@ +<?xml version="1.0"?> +<!--*- mode: xml -*--> +<interface> + <object class="GtkListStore" id="model1"> + <columns> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes"></col> + </row> + <row> + <col id="0" translatable="yes">Mr.</col> + </row> + <row> + <col id="0" translatable="yes">Mrs.</col> + </row> + <row> + <col id="0" translatable="yes">Ms.</col> + </row> + <row> + <col id="0" translatable="yes">Miss</col> + </row> + <row> + <col id="0" translatable="yes">Dr.</col> + </row> + </data> + </object> + <object class="GtkListStore" id="model2"> + <columns> + <column type="gchararray"/> + </columns> + <data> + <row> + <col id="0" translatable="yes"></col> + </row> + <row> + <col id="0" translatable="yes">Sr.</col> + </row> + <row> + <col id="0" translatable="yes">Jr.</col> + </row> + <row> + <col id="0" translatable="yes">I</col> + </row> + <row> + <col id="0" translatable="yes">II</col> + </row> + <row> + <col id="0" translatable="yes">III</col> + </row> + <row> + <col id="0" translatable="yes">Esq.</col> + </row> + </data> + </object> + <object class="GtkDialog" id="dialog-checkfullname"> + <property name="title" translatable="yes">Full Name</property> + <property name="type">GTK_WINDOW_TOPLEVEL</property> + <property name="window_position">GTK_WIN_POS_NONE</property> + <property name="modal">True</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="focus_on_map">True</property> + <property name="urgency_hint">False</property> + <child internal-child="vbox"> + <object class="GtkVBox" id="vbox-container"> + <property name="visible">True</property> + <property name="homogeneous">False</property> + <property name="spacing">8</property> + <child internal-child="action_area"> + <object class="GtkHButtonBox" id="hbuttonbox1"> + <property name="visible">True</property> + <property name="layout_style">GTK_BUTTONBOX_END</property> + <child> + <object class="GtkButton" id="button1"> + <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> + </object> + </child> + <child> + <object class="GtkButton" id="button2"> + <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> + </object> + </child> + </object> + <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> + <object class="GtkTable" id="table-checkfullname"> + <property name="border_width">12</property> + <property name="visible">True</property> + <property name="n_rows">5</property> + <property name="n_columns">3</property> + <property name="homogeneous">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkEntry" id="entry-first"> + <property name="visible">True</property> + <property name="can_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 name="has_frame">True</property> + <property name="activates_default">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> + <property name="y_options"/> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-middle"> + <property name="visible">True</property> + <property name="can_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 name="has_frame">True</property> + <property name="activates_default">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options"/> + </packing> + </child> + <child> + <object class="GtkEntry" id="entry-last"> + <property name="visible">True</property> + <property name="can_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 name="has_frame">True</property> + <property name="activates_default">False</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">3</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="y_options"/> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-first"> + <property name="visible">True</property> + <property name="label" translatable="yes">_First:</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">1</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">entry-first</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </object> + <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">fill</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-title"> + <property name="visible">True</property> + <property name="label" translatable="yes" context="FullName">_Title:</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">1</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + <property name="mnemonic_widget">comboentry-title</property> + </object> + <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">fill</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-middle"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Middle:</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">1</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">entry-middle</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-last"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Last:</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">1</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="mnemonic_widget">entry-last</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="label-suffix"> + <property name="visible">True</property> + <property name="label" translatable="yes">_Suffix:</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">1</property> + <property name="yalign">0.5</property> + <property name="xpad">0</property> + <property name="ypad">0</property> + <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> + <property name="single_line_mode">False</property> + <property name="angle">0</property> + <property name="mnemonic_widget">comboentry-suffix</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="right_attach">1</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="comboentry-title"> + <property name="visible">True</property> + <property name="has-entry">True</property> + <property name="entry-text-column">0</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + <property name="model">model1</property> + </object> + <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="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + <child> + <object class="GtkComboBox" id="comboentry-suffix"> + <property name="visible">True</property> + <property name="has-entry">True</property> + <property name="entry-text-column">0</property> + <property name="add_tearoffs">False</property> + <property name="has_frame">True</property> + <property name="focus_on_click">True</property> + <property name="model">model2</property> + </object> + <packing> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">4</property> + <property name="bottom_attach">5</property> + <property name="x_options">fill</property> + <property name="y_options">fill</property> + </packing> + </child> + </object> + <packing> + <property name="padding">0</property> + <property name="expand">True</property> + <property name="fill">True</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="0">button1</action-widget> + <action-widget response="0">button2</action-widget> + </action-widgets> + </object> +</interface> diff --git a/addressbook/gui/contact-editor/test-editor.c b/addressbook/gui/contact-editor/test-editor.c index e6b46adb83..1d9c24aed7 100644 --- a/addressbook/gui/contact-editor/test-editor.c +++ b/addressbook/gui/contact-editor/test-editor.c @@ -1,65 +1,53 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* - * test-editor.c - * Copyright (C) 2000 Ximian, Inc. - * Author: Chris Lahey <clahey@ximian.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Chris Lahey <clahey@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. */ -#include "config.h" +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif #include <stdlib.h> -#include <gtk/gtkmain.h> -#include <libgnomeui/gnome-app.h> -#include <libgnomeui/gnome-init.h> -#include <glade/glade.h> +#include <gtk/gtk.h> #include "e-contact-editor.h" - -#define TEST_VCARD \ -"BEGIN:VCARD -" \ -"FN:Nat -" \ -"N:Friedman;Nat;D;Mr. -" \ -"BDAY:1977-08-06 -" \ -"TEL;WORK:617 679 1984 -" \ -"TEL;CELL:123 456 7890 -" \ -"EMAIL;INTERNET:nat@nat.org -" \ -"EMAIL;INTERNET:nat@ximian.com -" \ -"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234; -" \ -"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA -" \ -"END:VCARD -" \ -" -" - -static char * -read_file (char *name) +#include "ebook/e-card.h" + +#define TEST_VCARD \ +"BEGIN:VCARD\n" \ +"FN:Nat\n" \ +"N:Friedman;Nat;D;Mr.\n" \ +"BDAY:1977-08-06\n" \ +"TEL;WORK:617 679 1984\n" \ +"TEL;CELL:123 456 7890\n" \ +"EMAIL;INTERNET:nat@nat.org\n" \ +"EMAIL;INTERNET:nat@ximian.com\n" \ +"ADR;WORK;POSTAL:P.O. Box 101;;;Any Town;CA;91921-1234;\n" \ +"ADR;HOME;POSTAL;INTL:P.O. Box 202;;;Any Town 2;MI;12344-4321;USA\n" \ +"END:VCARD\n" + +static gchar * +read_file (gchar *name) { - int len; - char buff[65536]; - char line[1024]; + gint len; + gchar buff[65536]; + gchar line[1024]; FILE *f; f = fopen (name, "r"); @@ -79,65 +67,49 @@ read_file (char *name) /* Callback used when a contact editor is closed */ static void -editor_closed_cb (EContactEditor *ce, gpointer data) +editor_closed_cb (EContactEditor *ce, + gpointer data) { - static int count = 2; + static gint count = 2; count--; - gtk_object_unref (GTK_OBJECT (ce)); + g_object_unref (ce); if (count == 0) exit (0); } -#if 0 -static void about_callback( GtkWidget *widget, gpointer data ) -{ - - const gchar *authors[] = - { - "Christopher James Lahey <clahey@umich.edu>", - NULL - }; - - GtkWidget *about = - gnome_about_new ( _( "Contact Editor Test" ), VERSION, - _( "Copyright (C) 2000, Ximian, Inc." ), - authors, - _( "This should test the contact editor canvas item" ), - NULL); - gtk_widget_show (about); -} -#endif - -int main( int argc, char *argv[] ) +gint +main (gint argc, + gchar *argv[]) { - char *cardstr; + gchar *cardstr; EContactEditor *ce; - /* bindtextdomain (PACKAGE, GNOMELOCALEDIR); - textdomain (PACKAGE);*/ - - gnome_init( "Contact Editor Test", VERSION, argc, argv); - - glade_gnome_init (); + gtk_init (&argc, &argv); cardstr = NULL; if (argc == 2) - cardstr = read_file (argv [1]); + cardstr = read_file (argv[1]); if (cardstr == NULL) cardstr = TEST_VCARD; - ce = e_contact_editor_new (e_card_new_with_default_charset (cardstr, "ISO-8859-1"), TRUE, NULL, FALSE); - gtk_signal_connect (GTK_OBJECT (ce), "editor_closed", - GTK_SIGNAL_FUNC (editor_closed_cb), NULL); - - ce = e_contact_editor_new (e_card_new_with_default_charset (cardstr, "ISO-8859-1"), TRUE, NULL, FALSE); - gtk_signal_connect (GTK_OBJECT (ce), "editor_closed", - GTK_SIGNAL_FUNC (editor_closed_cb), NULL); - - gtk_main(); + ce = e_contact_editor_new ( + NULL, e_card_new_with_default_charset ( + cardstr, "ISO-8859-1"), TRUE, FALSE); + g_signal_connect ( + ce, "editor_closed", + G_CALLBACK (editor_closed_cb), NULL); + + ce = e_contact_editor_new ( + NULL, e_card_new_with_default_charset ( + cardstr, "ISO-8859-1"), TRUE, FALSE); + g_signal_connect ( + ce, "editor_closed", + G_CALLBACK (editor_closed_cb), NULL); + + gtk_main (); /* Not reached. */ return 0; |