aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/gui/widgets')
-rw-r--r--addressbook/gui/widgets/.cvsignore12
-rw-r--r--addressbook/gui/widgets/Makefile.am189
-rw-r--r--addressbook/gui/widgets/address_formats.dat214
-rw-r--r--addressbook/gui/widgets/addresstypes.xml104
-rw-r--r--addressbook/gui/widgets/countrytransl.map11370
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.c1306
-rw-r--r--addressbook/gui/widgets/e-addressbook-model.h175
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.c728
-rw-r--r--addressbook/gui/widgets/e-addressbook-reflow-adapter.h53
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.c443
-rw-r--r--addressbook/gui/widgets/e-addressbook-selector.h71
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.c562
-rw-r--r--addressbook/gui/widgets/e-addressbook-table-adapter.h88
-rw-r--r--addressbook/gui/widgets/e-addressbook-util.c385
-rw-r--r--addressbook/gui/widgets/e-addressbook-util.h55
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.c2848
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.etspec100
-rw-r--r--addressbook/gui/widgets/e-addressbook-view.h244
-rw-r--r--addressbook/gui/widgets/e-contact-map-window.c500
-rw-r--r--addressbook/gui/widgets/e-contact-map-window.h81
-rw-r--r--addressbook/gui/widgets/e-contact-map.c408
-rw-r--r--addressbook/gui/widgets/e-contact-map.h106
-rw-r--r--addressbook/gui/widgets/e-contact-marker.c624
-rw-r--r--addressbook/gui/widgets/e-contact-marker.h84
-rw-r--r--addressbook/gui/widgets/e-minicard-control.c373
-rw-r--r--addressbook/gui/widgets/e-minicard-control.h8
-rw-r--r--addressbook/gui/widgets/e-minicard-label.c754
-rw-r--r--addressbook/gui/widgets/e-minicard-label.h68
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.c617
-rw-r--r--addressbook/gui/widgets/e-minicard-view-widget.h68
-rw-r--r--addressbook/gui/widgets/e-minicard-view.c695
-rw-r--r--addressbook/gui/widgets/e-minicard-view.h70
-rw-r--r--addressbook/gui/widgets/e-minicard-widget-test.c119
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.c249
-rw-r--r--addressbook/gui/widgets/e-minicard-widget.h76
-rw-r--r--addressbook/gui/widgets/e-minicard.c1503
-rw-r--r--addressbook/gui/widgets/e-minicard.h129
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.c123
-rw-r--r--addressbook/gui/widgets/ea-addressbook-view.h55
-rw-r--r--addressbook/gui/widgets/ea-addressbook.c90
-rw-r--r--addressbook/gui/widgets/ea-addressbook.h33
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.c446
-rw-r--r--addressbook/gui/widgets/ea-minicard-view.h56
-rw-r--r--addressbook/gui/widgets/ea-minicard.c303
-rw-r--r--addressbook/gui/widgets/ea-minicard.h56
-rw-r--r--addressbook/gui/widgets/eab-config.c160
-rw-r--r--addressbook/gui/widgets/eab-config.h82
-rw-r--r--addressbook/gui/widgets/eab-contact-display.c626
-rw-r--r--addressbook/gui/widgets/eab-contact-display.h103
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.c1207
-rw-r--r--addressbook/gui/widgets/eab-contact-formatter.h84
-rw-r--r--addressbook/gui/widgets/eab-gui-util.c1119
-rw-r--r--addressbook/gui/widgets/eab-gui-util.h63
-rw-r--r--addressbook/gui/widgets/gal-view-factory-minicard.c120
-rw-r--r--addressbook/gui/widgets/gal-view-factory-minicard.h35
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.c261
-rw-r--r--addressbook/gui/widgets/gal-view-minicard.h91
-rw-r--r--addressbook/gui/widgets/test-minicard-label.c131
-rw-r--r--addressbook/gui/widgets/test-minicard-view.c208
-rw-r--r--addressbook/gui/widgets/test-minicard.c122
-rw-r--r--addressbook/gui/widgets/test-reflow.c201
61 files changed, 24287 insertions, 6967 deletions
diff --git a/addressbook/gui/widgets/.cvsignore b/addressbook/gui/widgets/.cvsignore
deleted file mode 100644
index 472fd2593f..0000000000
--- a/addressbook/gui/widgets/.cvsignore
+++ /dev/null
@@ -1,12 +0,0 @@
-.deps
-.libs
-.pure
-Makefile
-Makefile.in
-*.lo
-*.la
-minicard-label-test
-minicard-test
-minicard-view-test
-minicard-widget-test
-reflow-test
diff --git a/addressbook/gui/widgets/Makefile.am b/addressbook/gui/widgets/Makefile.am
index e262e18f5c..f9fea781a8 100644
--- a/addressbook/gui/widgets/Makefile.am
+++ b/addressbook/gui/widgets/Makefile.am
@@ -1,139 +1,92 @@
-INCLUDES = \
- -DG_LOG_DOMAIN=\"e-minicard\" \
- -DEVOLUTION_GLADEDIR=\""$(gladedir)"\" \
+ruledir = $(privdatadir)
+rule_DATA = addresstypes.xml address_formats.dat countrytransl.map
+
+noinst_LTLIBRARIES = libeabwidgets.la
+
+libeabwidgets_la_CPPFLAGS = \
+ $(AM_CPPFLAGS) \
+ -DG_LOG_DOMAIN=\"eab-widgets\" \
-DEVOLUTION_ETSPECDIR=\""$(etspecdir)"\" \
- -DEVOLUTION_DATADIR=\""$(datadir)"\" \
- -DEVOLUTION_IMAGESDIR=\""$(datadir)"/images/evolution\" \
+ -DEVOLUTION_GALVIEWSDIR=\""$(viewsdir)"\" \
+ -DEVOLUTION_RULEDIR=\"$(ruledir)\" \
+ -DEVOLUTION_IMAGESDIR=\"${imagesdir}\" \
+ -DEVOLUTION_PRIVDATADIR=\"${privdatadir}\" \
-I$(top_srcdir) \
- -I$(top_srcdir)/addressbook/backend \
- -I$(top_builddir)/addressbook/backend \
- -I$(top_srcdir)/addressbook/gui/contact-editor \
+ -I$(top_srcdir)/addressbook \
-I$(top_srcdir)/addressbook/gui/merging \
- -I$(top_srcdir)/addressbook/gui/component \
- -I$(top_srcdir)/widgets/misc \
+ -I$(top_srcdir)/addressbook/util \
-I$(top_builddir)/shell \
- $(EVOLUTION_ADDRESSBOOK_CFLAGS)
+ $(EVOLUTION_DATA_SERVER_CFLAGS) \
+ $(GNOME_PLATFORM_CFLAGS) \
+ $(GTKHTML_CFLAGS) \
+ $(CHAMPLAIN_CFLAGS) \
+ $(GEO_CFLAGS)
+
+eabincludedir = $(privincludedir)/addressbook/gui/widgets
-noinst_LIBRARIES = \
- libeminicard.a
+eabinclude_HEADERS = \
+ eab-config.h
-libeminicard_a_SOURCES = \
+libeabwidgets_la_SOURCES = \
+ eab-config.c \
+ eab-contact-display.c \
+ eab-contact-display.h \
+ eab-contact-formatter.c \
+ eab-contact-formatter.h \
+ eab-gui-util.c \
+ eab-gui-util.h \
+ e-contact-map.c \
+ e-contact-map.h \
+ e-contact-map-window.c \
+ e-contact-map-window.h \
+ e-contact-marker.c \
+ e-contact-marker.h \
+ e-minicard.c \
+ e-minicard.h \
+ e-minicard-label.c \
+ e-minicard-label.h \
+ e-minicard-view.c \
+ e-minicard-view.h \
+ e-minicard-view-widget.c \
+ e-minicard-view-widget.h \
e-addressbook-reflow-adapter.c \
e-addressbook-reflow-adapter.h \
e-addressbook-table-adapter.c \
e-addressbook-table-adapter.h \
e-addressbook-model.c \
e-addressbook-model.h \
- e-addressbook-util.c \
- e-addressbook-util.h \
+ e-addressbook-selector.c \
+ e-addressbook-selector.h \
e-addressbook-view.c \
e-addressbook-view.h \
- e-minicard-control.c \
- e-minicard-control.h \
- e-minicard-label.c \
- e-minicard-label.h \
- e-minicard-view-widget.c \
- e-minicard-view-widget.h \
- e-minicard-view.c \
- e-minicard-view.h \
- e-minicard-widget.c \
- e-minicard-widget.h \
- e-minicard.c \
- e-minicard.h \
- gal-view-factory-minicard.c \
- gal-view-factory-minicard.h \
gal-view-minicard.c \
- gal-view-minicard.h
-
-#noinst_PROGRAMS = \
-# minicard-widget-test \
-# minicard-label-test \
-# minicard-test
-## reflow-test
-## minicard-view-test
-#
-#minicard_label_test_SOURCES = \
-# test-minicard-label.c
-#
-#minicard_label_test_LDADD = \
-# libeminicard.a \
-# $(EVOLUTION_ADDRESSBOOK_LIBS) \
-# $(top_builddir)/e-util/libeutil.la
-#
-#minicard_test_SOURCES = \
-# test-minicard.c
-#
-#minicard_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.la \
-# $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(EVOLUTION_ADDRESSBOOK_LIBS) \
-# libeminicard.a
-#
-#reflow_test_SOURCES = \
-# test-reflow.c
-#
-#reflow_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/e-util/libeutil.la \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
+ gal-view-minicard.h \
+ ea-minicard.c \
+ ea-minicard.h \
+ ea-minicard-view.c \
+ ea-minicard-view.h \
+ ea-addressbook-view.c \
+ ea-addressbook-view.h \
+ ea-addressbook.c \
+ ea-addressbook.h
-#minicard_view_test_SOURCES = \
-# test-minicard-view.c
+libeabwidgets_la_LIBADD = \
+ $(top_builddir)/shell/libevolution-shell.la \
+ $(top_builddir)/e-util/libevolution-util.la \
+ $(top_builddir)/addressbook/util/libeabutil.la \
+ $(EVOLUTION_DATA_SERVER_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(GTKHTML_LIBS) \
+ $(CHAMPLAIN_LIBS) \
+ $(GEO_LIBS)
-#minicard_view_test_LDADD = \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/addressbook/ename/libename.la \
-# $(top_builddir)/addressbook/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/e-util/libeutil.la
-#
-#minicard_widget_test_SOURCES = \
-# e-minicard-widget-test.c
-#
-#minicard_widget_test_LDADD = \
-# libeminicard.a \
-# $(top_builddir)/addressbook/backend/ebook/libebook.la \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/libversit/libversit.la \
-# $(top_builddir)/e-util/ename/libename.la \
-# $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.a \
-# $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.a \
-# $(top_builddir)/addressbook/gui/component/select-names/libeselectnames.la \
-# $(top_builddir)/addressbook/printing/libecontactprint.a \
-# $(top_builddir)/widgets/misc/libemiscwidgets.a \
-# $(top_builddir)/e-util/libeutil.la \
-# $(top_builddir)/addressbook/gui/merging/libecardmerging.a \
-# $(EVOLUTION_ADDRESSBOOK_LIBS)
+dist-hook:
+ cd $(distdir); rm -f $(BUILT_SOURCES)
-gladedir = $(datadir)/evolution/glade
-glade_DATA =
-
-etspecdir = $(datadir)/evolution/etspec
etspec_DATA= e-addressbook-view.etspec
EXTRA_DIST = \
- $(glade_DATA) \
- $(etspec_DATA)
- \ No newline at end of file
+ $(etspec_DATA) \
+ $(rule_DATA)
+
+-include $(top_srcdir)/git.mk
diff --git a/addressbook/gui/widgets/address_formats.dat b/addressbook/gui/widgets/address_formats.dat
new file mode 100644
index 0000000000..307831a94c
--- /dev/null
+++ b/addressbook/gui/widgets/address_formats.dat
@@ -0,0 +1,214 @@
+[at]
+AddressFormat=%0(%n\n)%0(%m\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+BusinessAddressFormat=%0(%m\n)%0(z.Hd. %n\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+CountryPosition=below
+
+[au]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%L%w%w%R%w%w)%z
+CountryPosition=BELOW
+
+[ax]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[ca]
+AddressFormat=%0(%N\n)%0(%M\n)%0(%S\n)%0(PO BOX %p\n)%0(%L%w%R)%,%z
+CountryPosition=BELOW
+
+[ch]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[ch_de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[ch_fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Case postale %p\n)%0(%s\n)%z%w%l
+
+[ch_it]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Casella postale %p\n)%0(%s\n)%z%w%l
+
+[cz]
+AddressFormat=%0(%m\n)%0(%n\n)%0(p. p. %p\n)%0(%s\n)%z%w%w%l
+CountryPosition=below
+
+[de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[de_nds]
+AddressFormat=%0(%n\n)%0(- %m -\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[dk]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[fi]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(BP %p\n)%z%w%L
+CountryPosition=BELOW
+
+[gl]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[hu]
+AddressFormat=%0(%n\n)%0(\n%l)%0(\n%s)%0(\nPF. %p)%0(\n%z)%0(\n%r)
+BusinessAddressFormat=%0(%n\n)%m\n%z%w%l%0(\n%s)%0(\nPF. %p)%0(\n%r)
+CountryPosition=below
+
+[il]
+AddressFormat=%0(%n\n)%0(%m\n)%0(ת.ד. %p\n)%0(%s\n)%0(%l%w%z)
+CountryPosition=BELOW
+
+[jp]
+AddressFormat=%0(%z%w%r)%w%l%0(\n%s)%0(\n%m)%0(\n%n)
+CountryPosition=ABOVE
+
+[kh]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(P.O. Box %p\n)%z%w%L%0(\n%r)
+CountryPosition=BELOW
+
+[me]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+CountryPosition=BELOW
+
+[me_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштански фах %p\n)%z%w%l
+
+[na]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%l
+
+[nl]
+AddressFormat=%n\n%0(%m\n)%0(Postbus %p\n)%0(%s\n)%z%w%l
+CountryPosition=below
+
+[no]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postboks %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=BELOW
+
+[rs]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштански фах %p\n)%z%w%l
+CountryPosition=BELOW
+
+[rs_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+
+[se]
+AddressFormat=%n\n%0(%m\n)%0(Box %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=below
+
+[us]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%,%w%r)%w%z
+CountryPosition=BELOW
+
+[at]
+AddressFormat=%0(%n\n)%0(%m\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+BusinessAddressFormat=%0(%m\n)%0(z.Hd. %n\n)%0(Postfach %p\n)%0(%s\n)%0(%z)%w%l
+CountryPosition=below
+
+[au]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%L%w%w%R%w%w)%z
+CountryPosition=BELOW
+
+[ax]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[ca]
+AddressFormat=%0(%N\n)%0(%M\n)%0(%S\n)%0(PO BOX %p\n)%0(%L%w%R)%,%z
+CountryPosition=BELOW
+
+[ch]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[ch_de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[ch_fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Case postale %p\n)%0(%s\n)%z%w%l
+
+[ch_it]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Casella postale %p\n)%0(%s\n)%z%w%l
+
+[cz]
+AddressFormat=%0(%m\n)%0(%n\n)%0(p. p. %p\n)%0(%s\n)%z%w%w%l
+CountryPosition=below
+
+[de]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+CountryPosition=BELOW
+
+[de_nds]
+AddressFormat=%0(%n\n)%0(- %m -\n)%0(Postfach %p\n)%0(%s\n)%z%w%l
+
+[dk]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[fi]
+AddressFormat=%0(%m\n)%0(%n\n)%0(PB %p\n)%0(%s\n)%z%w%L
+CountryPosition=BELOW
+
+[fr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(BP %p\n)%z%w%L
+CountryPosition=BELOW
+
+[gl]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(Postboks %p\n)%z%w%l
+CountryPosition=below
+
+[hu]
+AddressFormat=%0(%n\n)%0(\n%l)%0(\n%s)%0(\nPF. %p)%0(\n%z)%0(\n%r)
+BusinessAddressFormat=%0(%n\n)%m\n%z%w%l%0(\n%s)%0(\nPF. %p)%0(\n%r)
+CountryPosition=below
+
+[il]
+AddressFormat=%0(%n\n)%0(%m\n)%0(ת.ד. %p\n)%0(%s\n)%0(%l%w%z)
+CountryPosition=BELOW
+
+[jp]
+AddressFormat=%0(%z%w%r)%w%l%0(\n%s)%0(\n%m)%0(\n%n)
+CountryPosition=ABOVE
+
+[kh]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(P.O. Box %p\n)%z%w%L%0(\n%r)
+CountryPosition=BELOW
+
+[me]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+CountryPosition=BELOW
+
+[me_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштански фах %p\n)%z%w%l
+
+[na]
+AddressFormat=%0(%m\n)%0(%n\n)%0(P.O. Box %p\n)%l
+
+[nl]
+AddressFormat=%n\n%0(%m\n)%0(Postbus %p\n)%0(%s\n)%z%w%l
+CountryPosition=below
+
+[no]
+AddressFormat=%0(%m\n)%0(%n\n)%0(Postboks %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=BELOW
+
+[rs]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(поштански фах %p\n)%z%w%l
+CountryPosition=BELOW
+
+[rs_sr]
+AddressFormat=%0(%m\n)%0(%n\n)%0(%s\n)%0(poštanski fah %p\n)%z%w%l
+
+[se]
+AddressFormat=%n\n%0(%m\n)%0(Box %p\n)%0(%s\n)%z%w%w%L
+CountryPosition=below
+
+[us]
+AddressFormat=%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%,%w%r)%w%z
+CountryPosition=BELOW
+
diff --git a/addressbook/gui/widgets/addresstypes.xml b/addressbook/gui/widgets/addresstypes.xml
new file mode 100644
index 0000000000..cef8000cc4
--- /dev/null
+++ b/addressbook/gui/widgets/addresstypes.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0"?>
+<filterdescription>
+<partset>
+ <part name="name">
+ <title>Name</title>
+ <input type="optionlist" name="name-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "full_name" ${name})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "full_name" ${name}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "full_name" ${name})))</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "full_name" ${name}))</code>
+ </option>
+ <option value="begin">
+ <title>begins with</title>
+ <code>(beginswith "full_name" ${name})</code>
+ </option>
+ <option value="end">
+ <title>ends in</title>
+ <code>(endswith "full_name" ${name})</code>
+ </option>
+ </input>
+ <input type="string" name="name"/>
+ </part>
+ <part name="email">
+ <title>Email</title>
+ <input type="optionlist" name="email-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "email" ${email})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "email" ${email}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "email" ${email})</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "email" ${email}))</code>
+ </option>
+ </input>
+ <input type="address" name="email"/>
+ </part>
+ <part name="category">
+ <title>Category</title>
+ <input type="optionlist" name="category-type">
+ <option value="contains">
+ <title>contains</title>
+ <code>(contains "category_list" ${category})</code>
+ </option>
+ <option value="not contains">
+ <title>does not contain</title>
+ <code>(not (contains "category_list" ${category}))</code>
+ </option>
+ <option value="is">
+ <title>is</title>
+ <code>(is "category_list" ${category})</code>
+ </option>
+ <option value="is not">
+ <title>is not</title>
+ <code>(not (is "category_list" ${category}))</code>
+ </option>
+ </input>
+ <input type="optionlist" name="category">
+ <dynamic func="e_util_get_category_filter_options"/>
+ </input>
+ </part>
+ <part name="sexp">
+ <title>Expression</title>
+ <input type="rawcode" name="rawcode"/>
+ </part>
+</partset>
+
+ <ruleset>
+
+ <rule grouping="any" source="demand">
+ <_title>Name contains</_title>
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Email begins with</_title>
+ <sources/>
+ </rule>
+
+ <rule grouping="any" source="demand">
+ <_title>Any field contains</_title>
+ <sources/>
+ </rule>
+
+ </ruleset>
+</filterdescription>
diff --git a/addressbook/gui/widgets/countrytransl.map b/addressbook/gui/widgets/countrytransl.map
new file mode 100644
index 0000000000..1f6757f72f
--- /dev/null
+++ b/addressbook/gui/widgets/countrytransl.map
@@ -0,0 +1,11370 @@
+Andorra ad
+Андора ad
+Андора ad
+Andora ad
+ອີນເດີຍ ad
+Andora ad
+Андорра ad
+安道尔 ad
+United Arab Emirates ae
+Vereenigde Arabiese Emirate ae
+الإمارات العربية المتحدة ae
+Злучаныя Арабскія Эміраты ae
+Обединени Арабски Емирства ae
+Ujedinjeni arapski emirati ae
+Emirats Àrabs Units ae
+Spojené arabské emiráty ae
+Forenende Arabiske Emirater ae
+Vereinigte Arabische Emirate ae
+Ενωμένα Αραβικά Εμιράτα ae
+Emiratos árabes unidos ae
+Araabia Ühendemiraadid ae
+Arabiar Emirato Batuak ae
+امارات متحده عربی ae
+Yhdistyneet Arabiemiraatit ae
+Émirats Arabes Unis ae
+איחוד האמירויות הערביות ae
+Ujedinjeni arapski emirati ae
+Egyesült Arab Emirátusok ae
+Emirati arabi uniti ae
+アラブ首長国連邦 ae
+아랍 에미레이트 연합 ae
+ສະຫະລັດ ae
+Jungtiniai Arabų Emiratai ae
+Emirati Għarab Magħquda ae
+De forente arabiske emirater ae
+Verenigde Arabische Emiraten ae
+Dei sameinte arabiske emirata ae
+Di-Emirate tseo di Kopanego tsa Arab ae
+Zjednoczone Emiraty Arabskie ae
+Emiratos Árabes Unidos ae
+Emirados Árabes ae
+Emiratele Arabe Unite ae
+Объединенные Арабские Эмираты ae
+Spojené arabské emiráty ae
+Združeni arabski Emirati ae
+Förenade arabemiraten ae
+³ì¸¢Â «ÃÒ ¿¡Î¸û ae
+Birleşik Arap Emirlikleri ae
+Об'єднані Арабські Емірати ae
+Mashango o tangananaho a Emirates ae
+阿拉伯联合酋长国 ae
+阿拉伯聯合大公國 ae
+Izindawo zezinduna zase-United Arab ae
+Afghanistan af
+Афганістан af
+Афганистан af
+Afganistan af
+Afghanistán af
+Afganisztán af
+ລີທົ່ວເນີຍ af
+Afeganistão af
+Afganistan af
+Afganistan af
+Afganistan af
+Афганістан af
+阿富汗 af
+Antigua and Barbuda ag
+Antigue en Barbuda ag
+أنتيغوا و باربودا ag
+Antigua və Barbuda ag
+Антыгуа і Барбуда ag
+Антигуа и Барбадос ag
+Antigua ha Barbuda ag
+Antigua i Barbuda ag
+Antigua i Barbuda ag
+Antigua a Barbuda ag
+Antigua og Barbuda ag
+Antigua und Barbuda ag
+Antigua και Barbuda ag
+Antigvo kaj Barbudo ag
+Antigua y Barbuda ag
+Antigua ja Barbuda ag
+Antigua eta Barbuda ag
+آنتیگوا و باربودا ag
+Antigua ja Barbados ag
+Antigua og Barbuda ag
+Antigua et Barbuda ag
+Antiga e Barbuda ag
+אנטיגואה וברבודה ag
+Antigua i Barbuda ag
+Antigua és Barbuda ag
+Antigua dan Barbuda ag
+Antigúa og Barbúda ag
+Antigua e Barbuda ag
+アンティグアバーブーダ ag
+앤티가 바부다 ag
+Antikva ir Barbuda ag
+Antigva un Barbudas ag
+Antigwa u Barbuda ag
+Antigua og Barbuda ag
+Antigua en Barbuda ag
+Antigua og Barbuda ag
+Antigua le Barbuda ag
+Antigua e Barbuda ag
+Antigua i Barbuda ag
+Antigua e Barbuda ag
+Antigua e Barbuda ag
+Antigua şi Barbuda ag
+Антигуа и Барбадос ag
+Antigua a Barbuda ag
+Antigva in Barbuda ag
+Antigua i Barbuda ag
+I-Antigua kanye ne Barbuda ag
+Antigua och Barbuda ag
+¬ýÊÌÅ¡ & À¡÷Ò¼¡ ag
+Antigua ve Barbuda ag
+Трінідад та Тобаго ag
+Antigua và Barbuda ag
+Antigua eyet Barbuda ag
+Antigua ne Barbuda ag
+安地瓜岛和巴布达岛 ag
+安地瓜島和巴布達島 ag
+Antigua kanye ne-Barbuda ag
+Anguilla ai
+Ангуила ai
+ແພນວິນ ai
+Angvila ai
+Ангілья ai
+安圭拉 ai
+Albania al
+Альбанія al
+Албания al
+Albanija al
+Albanien al
+Albánia al
+ແອດແລນຕິກ al
+Albânia al
+Albánsko al
+Albanija al
+Albanien al
+Албанія al
+阿尔巴尼亚 al
+Armenia am
+Армэнія am
+Армения am
+Armenija am
+Armenien am
+Örményország am
+ອາເຈນຕິນາ am
+Armênia am
+Arménsko am
+Armenija am
+Armenien am
+Арменія am
+亚美尼亚 am
+Netherlands Antilles an
+Холандски Антили an
+Nizozemski Antili an
+Nederlandske antiller an
+Antillas holandesas an
+Antilla Holandarrak an
+Holland-Antillák an
+ເນເທີແລນ an
+Antilhas an
+Holandské Antily an
+Nizozemski Antili an
+Nederländska Antillerna an
+Голландські Антилли an
+荷属安的列斯群岛 an
+Angola ao
+Ангола ao
+Ангола ao
+ບັນແກເລີຍ ao
+Ангола ao
+安哥拉 ao
+Argentina ar
+Argentinië ar
+الأرجنتين ar
+Аргентына ar
+Аржентина ar
+Arc'hantina ar
+Argentinien ar
+Αργεντινή ar
+Argentino ar
+Argentiina ar
+آرژانتین ar
+Agentiina ar
+Argentine ar
+Arxentina ar
+ארגנטינה ar
+Argentína ar
+Argentína ar
+アルゼンチン ar
+아르헨티나 ar
+ອາເຈນຕິນາ ar
+Argentīna ar
+Arġentina ar
+Argentinië ar
+Argentyna ar
+Аргентина ar
+Argentína ar
+I-Argentina ar
+¬÷¦ºƒýÊÉ¡ ar
+อาร์เจนตินา ar
+Arjantin ar
+Аргентина ar
+Agenthina ar
+Årdjintene ar
+阿根廷 ar
+阿根廷 ar
+American Samoa as
+Амэрыканскае Самоа as
+Американска Самоа as
+Američka Samoa as
+Samoa (USA) as
+Samoa americana as
+Amerikako Samoa as
+Amerikai Szamoa as
+ອາເມລິກາເຫນືອ as
+Samoa Americana as
+Americká Samoa as
+Ameriška Samoa as
+Amerikanska Samoa as
+Американське Самоа as
+美属萨摩亚群岛 as
+Austria at
+Oostenryk at
+النمسا at
+Avstriya at
+Аўстрыя at
+Австрия at
+Aostria at
+Austrija at
+Àustria at
+Rakousko at
+Østrig at
+Österreich at
+Αυστρία at
+Aŭstrio at
+اتریش at
+Itävalta at
+Eysturríki at
+Autriche at
+אוסטריה at
+Austrija at
+Ausztria at
+Austurríki at
+オーストリア at
+오스트리아 at
+ອອດສະເຕເລີຍ at
+Austrija at
+Austrija at
+Awtrija at
+Østerrike at
+Oostenrijk at
+Austerrike at
+Áustria at
+Áustria at
+Австрия at
+Rakúsko at
+Avstrija at
+Austrija at
+I-Austria at
+Österrike at
+¬Íò¾¢Ã¢Â¡ at
+ออสเตรีย at
+Avusturya at
+Австрія at
+Ositiria at
+A'o at
+Ôtriche at
+奥地利 at
+奧地利 at
+Australia au
+Australië au
+أستراليا au
+Avustralya au
+Аўстралія au
+Австралия au
+Aostralia au
+Australija au
+Austràlia au
+Austrálie au
+Australien au
+Australien au
+Αυστραλία au
+Aŭstralio au
+Austraalia au
+استرالیا au
+Australie au
+אוסטרליה au
+Australija au
+Ausztrália au
+Ástralía au
+オーストラリア au
+오스트레일리아 au
+ອອດສະເຕເລີຍ au
+Australija au
+Austrālija au
+Awstralja au
+Australië au
+Austrália au
+Austrália au
+Австралия au
+Austrália au
+Avstralija au
+Australija au
+I-Australia au
+Australien au
+¬ŠÍò¾¢§ÃĢ¡ au
+ออสเตรเลีย au
+Avusturalya au
+Австралія au
+Ositiralia au
+U'c au
+Ôstraleye au
+澳大利亚 au
+澳大利亞 au
+Aruba aw
+Аруба aw
+ເກມໄັພ່ aw
+Аруба aw
+阿鲁巴岛 aw
+Azerbaijan az
+أذربيجان az
+Azərbaycan az
+Азэрбайджан az
+Азарбайджан az
+Azerbejdžan az
+Azerbaitjan az
+Ázerbajdžánský az
+Azerbajdjan az
+Aserbaidschan az
+Αζερμπαϊτζάν az
+Azerbajĝana az
+Azerbaiján az
+Aserbaidžaan az
+آذربایجان az
+Azerbaidzan az
+Aserbadsjan az
+אזרביג'ן az
+Azerbejdžan az
+Azerbajdzsán az
+Azerbaigian az
+アゼルバイジャン az
+아제르바이잔 az
+ອາເຊີໄບຈັນ az
+Azerbaidžanas az
+Azerbaidžāņu az
+Ażerbajġan az
+Aserbajdsjan az
+Azerbeidjan az
+Aserbajdsjan az
+Azerbejdżan az
+Azerbaijão az
+Turco az
+Azerbadjan az
+Азербайджан az
+Ázerbajdžánsky az
+Azerbajdžan az
+Azerbejdžan az
+I-Azerbaijan az
+«º÷¨Àº¡ý az
+อาร์เซอร์ไบจัน az
+Azerice az
+Азербайджан az
+Azerbaydjan az
+阿塞拜疆 az
+亞塞拜然 az
+Bosnia and Herzegovina ba
+Bosnië en Herzegovina ba
+البوسنا و الهرسك ba
+Босьнія і Герцагавіна ba
+Боснена и Херцеговина ba
+Bosna i Hercegovina ba
+Bòsnia i Hercegovina ba
+Bosna a Herzegovina ba
+Bosnien-Herzegovina ba
+Bosnien und Herzegowina ba
+Βοσνία και Ερζεγοβίνη ba
+Bosnio kaj Hercegovino ba
+Bosnia y Herzegovina ba
+Bosnia ja Hertsegovina ba
+Bosnia eta Herzegovina ba
+بوسنی و هرزگوین ba
+Bosnia ja Herzegovina ba
+Bosnia-Herzegovina ba
+Bosnie herzégovine ba
+בוסניה הרצגובינה ba
+Bosna i Hercegovina ba
+Bosznia-Hercegovina ba
+Bosnia e Erzegovina ba
+ボスニアヘルツェゴビナ ba
+보스니아어와 헤르체고비나 ba
+ບອສເນີຍ ແລະ ເຫີເຊີໂກວິນາ ba
+Bosnija ir Hercegovina ba
+Bosnija un Hercogovina ba
+Bożnia u Ħerżegovina ba
+Bosnia-Hercegovina ba
+Bosnië en Herzegovina ba
+Bosnia-Hercegovina ba
+Bosnia le Herzegovina ba
+Bośnia i Hercegowina ba
+Bósnia e Herzegovina ba
+Bósnia Herzegóvina ba
+Bosnia şi Herţegovina ba
+Босния и Герцеговина ba
+Bosna a Hercegovina ba
+Bosna in Hercegovina ba
+I-Bosnia kanye ne Herzegovina ba
+Bosnien och Herzegovina ba
+¦À¡Íɢ¡ ba
+บอสเนีย และ เฮอร์เซโกวินา ba
+Bosna Hersek ba
+Боснія та Герцеговина ba
+Mubosinia na Muhezegovina ba
+Bosneye ba
+Bosnia ne Herzegovina ba
+波斯尼亚和黑塞哥维那 ba
+波士尼亞與赫塞哥維納 ba
+Bosnia kanye ne-Herzegovina ba
+Barbados bb
+بربادوس bb
+Барбадос bb
+Барбадос bb
+Μπαρμπάντος bb
+Babadoso bb
+باربادوس bb
+Barbade bb
+ברבדוס bb
+バルバドス bb
+바르바도스 bb
+ບາລບາດອດສ bb
+Barbadosas bb
+Barbadosa bb
+Барбадос bb
+I-Barbados bb
+À¡÷§À¼¡Í bb
+บาร์บาดอส bb
+Барбадос bb
+Barbades bb
+巴巴多斯 bb
+巴貝多 bb
+Bangladesh bd
+بنغلاديش bd
+Banqladeş bd
+Банглядэш bd
+Бангладеш bd
+Bangladeš bd
+Bangladéš bd
+Bangladesch bd
+Μπαγκλαντές bd
+Bangladeŝo bd
+بنگلادش bd
+בנגלדש bd
+Bangladeš bd
+Banglades bd
+バングラデシュ bd
+방글라데시 bd
+ບັງຄະລາເທດ bd
+Bangladešas bd
+Bangladeša bd
+Bangladexx bd
+Bangladesz bd
+Banglade bd
+Бангладеш bd
+Bangladéš bd
+Bangladeš bd
+I-Bangladesh bd
+Àí¸Ç¡§¾Í bd
+บังคลาเทศ bd
+Bangladeş bd
+Бангладеш bd
+孟加拉 bd
+孟加拉 bd
+Belgium be
+België be
+بلجيكا be
+Belçika be
+Бэльгія be
+Белгия be
+Belgia be
+Belgija be
+Bèlgica be
+Belgie be
+Belgien be
+Belgien be
+Βέλγιο be
+Belgio be
+Bélgica be
+Belgia be
+Belgika be
+بلژیک be
+Belgia be
+Belgia be
+Belgique be
+Bélxica be
+בלגיה be
+Belgija be
+Belgia be
+Belgía be
+Belgio be
+ベルギー be
+벨기에 be
+ເບລຢ່ງມ be
+Belgija be
+Beļģija be
+Belġju be
+Belgia be
+België be
+Belgia be
+Bèlgica be
+Belgia be
+Bélgica be
+Bélgica be
+Belgia be
+Бельгия be
+Belgicko be
+Belgija be
+Belgija be
+I-Belgium be
+Belgien be
+¦Àøº¢Âõ be
+เบลเยียม be
+Belçika be
+Бельгія be
+Beljike be
+比利时 be
+比利時 be
+Burkina Faso bf
+Буркіна Фасо bf
+Буркина Фаско bf
+ຕຸລະກີ bf
+Буркіна Фасо bf
+布基纳法索 bf
+Bulgaria bg
+Bulgarye bg
+بلغاريا bg
+Bolgarıstan bg
+Баўгарыя bg
+България bg
+Bugarska bg
+Bulgària bg
+Bulharsko bg
+Bulgarien bg
+Bulgarien bg
+Βουλγαρία bg
+Bulgario bg
+Bulgaaria bg
+بلغارستان bg
+Bulgarie bg
+בולגריה bg
+Bugarska bg
+Bulgária bg
+Búlgaría bg
+ブルガリア bg
+불가리아 bg
+ບັນແກເລີຍ bg
+Bulgarija bg
+Bulgārija bg
+Bulgarija bg
+Bulgarije bg
+Bułgaria bg
+Bulgária bg
+Bulgária bg
+Болгария bg
+Bulharsko bg
+Bolgarija bg
+Bugarska bg
+I-Bulgaria bg
+Bulgarien bg
+Àø§¸Ã¢Â¡ bg
+บัลแกเรีย bg
+Bulgaristan bg
+Болгарія bg
+Baligaria bg
+Bulgåreye bg
+保加利亚 bg
+保加利亞 bg
+Bahrain bh
+البحرين bh
+Бахрэйн bh
+Бахрейн bh
+Bahrein bh
+Bahrajn bh
+Μπαχρέιν bh
+Bahrein bh
+Bahrein bh
+بحرین bh
+בחריין bh
+バーレーン bh
+바레인 bh
+ຖັກກ່ງວ bh
+Bahreinas bh
+Baħrain bh
+Baghrein bh
+Bahrajn bh
+Bahamas bh
+Bahrein bh
+Бахрейн bh
+Bahrajn bh
+Bahrajn bh
+I-Bahrain bh
+Bahrein bh
+À‹¨Ãý bh
+Bahreyn bh
+Бахрейн bh
+巴林 bh
+巴林 bh
+Burundi bi
+Бурундзі bi
+Бурунди bi
+ເຄອຣດ bi
+Бурунді bi
+布隆迪 bi
+Benin bj
+Бэнін bj
+Бенин bj
+ບອສເນີຍ bj
+Бенін bj
+贝宁 bj
+Bermuda bm
+Бэрмуды bm
+Бермуда bm
+ເຍລລະມັນ bm
+Bermudy bm
+Bermudi bm
+Бермуди bm
+百慕大 bm
+Brunei Darussalam bn
+Брунэй bn
+Бруней bn
+Brunei bn
+Brunei Szultánság bn
+ເບລາລັສເຊີຍ bn
+Brunei bn
+Brunei Darusalam bn
+Бруней Даруссалам bn
+Bolivia bo
+Bolivië bo
+بوليفيا bo
+Boliviya bo
+Балівія bo
+Боливия bo
+Bolivija bo
+Bolívia bo
+Bolívie bo
+Bolivien bo
+Βολιβία bo
+Bolivio bo
+Boliivia bo
+بولیوی bo
+Bolivie bo
+בוליביה bo
+Bolivija bo
+Bolívia bo
+Bólivía bo
+ボリビア bo
+볼리비아 bo
+ໂບລີເວີຍ bo
+Bolivija bo
+Bolīvija bo
+Bolivja bo
+Boliwia bo
+Bolívia bo
+Bolívia bo
+Боливия bo
+Bolívia bo
+Bolivija bo
+Bolivija bo
+I-Bolivia bo
+¦À¡Ä¢Å¢Â¡ bo
+โบลิเวีย bo
+Bolivya bo
+Болівія bo
+Boliveye bo
+波利维亚 bo
+玻利維亞 bo
+Brazil br
+Brazilië br
+البرازيل br
+Braziliya br
+Бразылія br
+Бразилия br
+Brasil br
+Brazílie br
+Brasilien br
+Brasilien br
+Βραζιλία br
+Brazilo br
+Brasil br
+Brasiilia br
+Brasil br
+برزیل br
+Brasilia br
+Brésil br
+Brasil br
+ברזיל br
+Brazília br
+Brasilía br
+Brasile br
+ブラジル br
+브라질 br
+ບາຊີລ br
+Brazilija br
+Brazīlija br
+Brażil br
+Brasil br
+Brazilië br
+Brasil br
+Brasil br
+Brazylia br
+Brasil br
+Brasil br
+Brazilia br
+Бразилия br
+Brazília br
+Brazilija br
+I-Brazil br
+Brasilien br
+À¢§Ãº¢ø br
+บราซิล br
+Brezilya br
+Бразилія br
+Burazili br
+Braezi br
+巴西 br
+巴西 br
+Bahamas bs
+Багамы bs
+Бахами bs
+Bahami bs
+Bahamák bs
+ປານາມາ bs
+Bahamy bs
+Bahami bs
+Багами bs
+巴哈马 bs
+Bhutan bt
+Бутан bt
+Бутан bt
+Butan bt
+Bhután bt
+Bhután bt
+ຖັກກ່ງວ bt
+Butan bt
+Бутан bt
+不丹 bt
+Botswana bw
+Батсвана bw
+Боцвана bw
+Bocvana bw
+ບອດສເນີຍ bw
+Botsvana bw
+Ботсвана bw
+博茨瓦纳 bw
+Belarus by
+روسيا البيضاء by
+Беларусь by
+Беларус by
+Bjelorusija by
+Bělorusko by
+Hviderusland by
+Weißrussland by
+Bjelorusio by
+Valgevene by
+بلاروس by
+Valkovenäjä by
+Hvítarusland by
+Bélarus by
+בלרוס by
+Bjelorusija by
+Fehéroroszország by
+Hvíta-Rússland by
+Bielorussia by
+ベラルーシ by
+벨라루스 by
+ເບລາລັສ by
+Baltarusija by
+Baltkrievu by
+Hviterussland by
+Wit-Rusland by
+Kviterussland by
+Białoruś by
+Bielorússia by
+Bielorusso by
+Беларусь by
+Bielorusko by
+Belorusija by
+I-Belarus by
+Vitryssland by
+¦ÀÄ¡åÍ by
+เบลารัส by
+Білорусія by
+Belaruss by
+白俄罗斯 by
+白俄羅斯 by
+Belize bz
+Бэлізе bz
+Белиз bz
+ເບລຍ່ງມ bz
+Беліз bz
+伯利兹 bz
+Default C
+Verstek C
+افتراضي C
+Əsas C
+Па ўмаўчаньні C
+По подразбиране C
+Dre ziouer C
+Omissió C
+Výchozí C
+Standard C
+Standard C
+Προκαθορισμένο C
+Apriora C
+Predeterminado C
+Vaikimisi C
+Aurremugatua C
+پیش‌فرض C
+Oletus C
+Forsettur C
+Par défaut C
+Por Omisión C
+ברירת מחדל C
+Uobičajeno C
+Alapértelmezett C
+Standar C
+Sjálfgefið C
+Predefinito C
+標準 C
+기본 C
+ຄ່າປະລິຍາຍ C
+Nutylima C
+Noklusētais C
+Normali C
+Standard C
+Standaard C
+Standard C
+Thuso ya Tshoganetso C
+Omission C
+Domyślnie C
+Por Omissão C
+Padrão C
+Implicit C
+По умолчанию C
+Štandardný C
+Privzeto C
+Predefinisano C
+Förval C
+¦¸¡¼¡¿¢¨Ä C
+ค่าปริยาย C
+Öntanımlı C
+Типовий C
+Mặc định C
+Prémetou C
+Okwendalo C
+默认 C
+預設 C
+Okwendalo C
+Canada ca
+Kanada ca
+كندا ca
+Kanada ca
+Канада ca
+Канада ca
+Kanada ca
+Kanada ca
+Canadà ca
+Kanada ca
+Kanada ca
+Καναδάς ca
+Kanado ca
+Canadá ca
+Kanada ca
+Kanada ca
+کانادا ca
+Kanada ca
+Kanada ca
+Canadá ca
+קנדה ca
+Kanada ca
+Kanada ca
+Kanada ca
+Kanada ca
+カナダ ca
+캐나다 ca
+ແຄນາດາ ca
+Kanada ca
+Kanāda ca
+Kanada ca
+Kanada ca
+Canadá ca
+Canadá ca
+Канада ca
+Kanada ca
+Kanada ca
+Kanada ca
+I-Canada ca
+Kanada ca
+¸É¼¡ ca
+แคนาดา ca
+Kanada ca
+Канада ca
+加拿大 ca
+加拿大 ca
+Cocos (Keeling) Islands cc
+Кокосови Острови cc
+Kokosovo (Keeling) ostrvo cc
+Islas Cocos (Keeling) cc
+Koko Irlak cc
+Kókusz-szigetek (Keeling) cc
+Ilhas Cocos cc
+Kokosove Ostrovy cc
+Kokosovi (Keelingovi) otoki cc
+Kokosöarna cc
+Кокосові острови cc
+Congo, the democratic republic of the cd
+Дэмакратычная Рэспубліка Конга cd
+Конго cd
+Kongo, demokratska republika cd
+Congo, den demokratiske republik cd
+Congo, república democrática del cd
+Kongo, errepublika demokratikoa cd
+Kongói Demokratikus Köztársaság cd
+República Democrática do Congo cd
+Demokratická Republika Kongo cd
+Kongo, demokratična republika cd
+Demokratiska republiken Kongo cd
+刚果民主共和国 cd
+Central African Republic cf
+ЦАР cf
+Centralnoafrička Republika cf
+Central-afrikanske Republik cf
+República Centroafricana cf
+Afrika Erdiko Errepublika cf
+Közép-Afrikai Köztársaság cf
+ໂດມິນິກັນ cf
+República da África Central cf
+Stredoafrická Republika cf
+Centralnoafriška republika cf
+Centralafrikanska Republiken cf
+Центральноафриканська республіка cf
+中非共和国 cf
+Congo cg
+Конга cg
+Конго cg
+Kongo cg
+Kongo cg
+Kongó cg
+ຄອນໂໍຊລ cg
+Kongo cg
+Kongo cg
+Kongo cg
+Конго cg
+刚果 cg
+Switzerland ch
+Switserland ch
+سويسرا ch
+İsveçrə ch
+Швэйцарыя ch
+Швейцария ch
+Suis ch
+Švicarska ch
+Suïssa ch
+Švýcarsko ch
+Schweiz ch
+Schweiz ch
+Ελβετία ch
+Svislando ch
+Suiza ch
+Šveits ch
+Suitza ch
+سوییس ch
+Sveitsi ch
+Suisse ch
+Suíza ch
+שוייץ ch
+Švicarska ch
+Svájc ch
+Swiss ch
+Sviss ch
+Svizzera ch
+スイス ch
+스위스 ch
+ສະວິສເຊີແລນ ch
+Šveicarija ch
+Šveice ch
+Svizzera ch
+Sveits ch
+Zwitserland ch
+Sveits ch
+Suissa ch
+Szwajcaria ch
+Suíça ch
+Suíça ch
+Elveţia ch
+Швейцария ch
+Švajčiarsko ch
+Švica ch
+Švajcarska ch
+I-Switzerland ch
+Schweiz ch
+ÍÅ¢ðº÷Ä¡óÐ ch
+สวิสเซอร์แลนด์ ch
+İsviçre ch
+Швейцарія ch
+Thuỵ Sĩ ch
+Swisse ch
+瑞士 ch
+瑞士 ch
+Cote d'ivoire ci
+Бераг Слановай Косьці ci
+Кот'Дивоар ci
+Obala Slonovače ci
+Elfenbenskysten ci
+Costa de Marfil ci
+Elefántcsontpart ci
+ປ່ອຍຫມາກກະລອກ ci
+Slonokoščena obala ci
+Elfenbenskusten ci
+Кот д'Івуар ci
+Cook islands ck
+Kukova ostrva ck
+Cook-øerne ck
+Islas Cook ck
+Cook Irlak ck
+Cook-szigetek ck
+ຄຸກກີ້ ck
+Ilhas Cook ck
+Cookove ostrovy ck
+Cookovi otoki ck
+Cooköarna ck
+Острови Кука ck
+库克群岛 ck
+Chile cl
+Chilië cl
+تشيلي cl
+Şili cl
+Чылі cl
+Чили cl
+Čile cl
+Xile cl
+Χιλή cl
+Ĉilio cl
+Tšiili cl
+Txile cl
+شیلی cl
+Chili cl
+צ'ילה cl
+Čile cl
+Chili cl
+Cile cl
+チリ cl
+칠레 cl
+ຊີລີ cl
+Čilė cl
+Čīle cl
+Ċile cl
+Chili cl
+Cile cl
+Чили cl
+Čile cl
+Čile cl
+Čile cl
+I-Chile cl
+º¢Ä¢ cl
+ชิลี cl
+Şili cl
+Чилі cl
+Chi lê cl
+Tchili cl
+智利 cl
+智利 cl
+Cameroon cm
+Камэрун cm
+Камерун cm
+Kamerun cm
+Cameroun cm
+Camerún cm
+Kamerun cm
+Kamerun cm
+ຕາລາງງານ - K cm
+Camarões cm
+Komerun cm
+Kamerun cm
+Kamerun cm
+Камерун cm
+喀麦隆 cm
+China cn
+Sjina cn
+الصين cn
+Çin cn
+Кітай cn
+Китай cn
+Sina cn
+Kina cn
+Xina cn
+Čína cn
+Kina cn
+Κίνα cn
+Ĉinujo cn
+Hiina cn
+Txina cn
+چین cn
+Kiina cn
+Kina cn
+Chine cn
+סין cn
+Kina cn
+Kína cn
+Cina cn
+Kína cn
+Cina cn
+中国 cn
+중국 cn
+ຈີນ cn
+Kinija cn
+Ķīna cn
+Ċina cn
+Kina cn
+Kina cn
+Xina cn
+Chiny cn
+Китай cn
+Čína cn
+Kitajska cn
+Kina cn
+I-China cn
+Kina cn
+º£É¡ cn
+จีน cn
+Çin cn
+Китай cn
+Trung Quốc cn
+Chine cn
+中国 cn
+中國 cn
+Colombia co
+Colombië co
+كولمبيا co
+Калюмбія co
+Колумбия co
+Kolumbija co
+Colòmbia co
+Kolumbie co
+Kolumbien co
+Κολομβία co
+Kolumbio co
+Kolumbia co
+Kolonbia co
+کلمبیا co
+Kolumbia co
+Colombie co
+קולומביה co
+Kolumbija co
+Kolumbia co
+コロンビア co
+콜롬비아 co
+ໂຄລຳເບີຍ co
+Kolumbija co
+Kolumbija co
+Kolumbja co
+Columbia co
+Kolumbia co
+Colômbia co
+Colômbia co
+Columbia co
+Колумбия co
+Kolumbia co
+Kolumbija co
+I-Colombia co
+¦¸¡ÄõÀ¢Â¡ co
+โคลัมเบีย co
+Kolombiya co
+Колумбія co
+Colombeye co
+Columbia co
+哥伦比亚 co
+哥倫比亞 co
+Costa Rica cr
+كوستاريكا cr
+Коста Рыка cr
+Коста Рика cr
+Kostarika cr
+Kostarika cr
+Κόστα Ρίκα cr
+کاستاریکا cr
+Kosta Rika cr
+קוסטה ריקה cr
+Costa rica cr
+コスタリカ cr
+코스타 리카 cr
+ໂຄເອເທີຍ cr
+Kosta Rika cr
+Kostaryka cr
+Коста-Рика cr
+Kostarika cr
+Kostarika cr
+I-Costa Rica cr
+§¸¡Š¼¡ ⸡ cr
+Kosta Rika cr
+Коста-Ріка cr
+哥斯达黎加 cr
+哥斯大黎加 cr
+Cuba cu
+Kuba cu
+كوبا cu
+Куба cu
+Куба cu
+Kuba cu
+Kuba cu
+Kuba cu
+Κούβα cu
+Kuuba cu
+Kuba cu
+کوبا cu
+Kuuba cu
+Kuba cu
+קובה cu
+Kuba cu
+キューバ cu
+쿠바 cu
+ເກມໄພ່ cu
+Kuba cu
+Kuba cu
+Kuba cu
+Куба cu
+Kuba cu
+Kuba cu
+I-Cuba cu
+Kuba cu
+¸¢ÔÀ¡ cu
+Küba cu
+Куба cu
+古巴 cu
+古巴 cu
+Cape Verde cv
+Капе Верде cv
+Zelenortska ostrva cv
+Kapverdiske øer cv
+Cabo Verde cv
+Cabo Verde cv
+Zöldfoki-szigetek cv
+ເກມໄພ່ cv
+Cabo Verde cv
+Kap Verde cv
+佛得角 cv
+Christmas Island cx
+Božično ostrvo cx
+Juleøen cx
+Islas Christmas cx
+Eguberri Irla cx
+Karácsony-szigetek cx
+ຄິດສະຕອລ cx
+Ilhas do Natal cx
+Vianočné Ostrovy cx
+Božični otok cx
+Julön cx
+Острів Різдва cx
+圣诞岛 cx
+Cyprus cy
+Кіпр cy
+Кипър cy
+Kipar cy
+Cypern cy
+Chipre cy
+Txipre cy
+Ciprus cy
+ບີບອັດ cy
+Chipre cy
+Ciper cy
+Cypern cy
+Кипр cy
+塞浦路斯 cy
+Czechia cz
+Czechië cz
+التشيك cz
+Çex Respublikası cz
+Чэхія cz
+Чехия cz
+Tchekia cz
+Češka cz
+Txèquia cz
+Česko cz
+Tjekkiet cz
+Tschechien cz
+Τσεχία cz
+Ĉeĥio cz
+República Checa cz
+Tšehhi cz
+Txekia cz
+چک cz
+Tsekki cz
+République tchèque cz
+Chequia cz
+צ'כיה cz
+Češka cz
+Csehország cz
+Tékkland cz
+Repubblica Ceca cz
+チェコ cz
+체코 cz
+Čekija cz
+Čehija cz
+Cżekia cz
+Tsjekkia cz
+Tsjechië cz
+Tsjekkia cz
+Chèquia cz
+Czechy cz
+República Checa cz
+República Tcheca cz
+Cehia cz
+Чехия cz
+Česko cz
+Češka cz
+Češka cz
+I-Czechia cz
+Tjeckien cz
+¦ºì¡ cz
+Çek Cumhuriyeti cz
+Чехія cz
+Séc cz
+Tchekeye cz
+捷克 cz
+捷克 cz
+Germany de
+Duitsland de
+ألمانيا de
+Almaniya de
+Нямеччына de
+Германия de
+Alamagn de
+Njemačka de
+Alemanya de
+Německo de
+Tyskland de
+Deutschland de
+Γερμανία de
+Germanio de
+Alemania de
+Saksamaa de
+Alemania de
+ آلمان de
+Saksa de
+Týskland de
+Allemagne de
+Alemaña de
+גרמניה de
+Njemačka de
+Németország de
+Jerman de
+Þýskaland de
+Germania de
+ドイツ de
+독일 de
+ເຍລລະມັນນີ de
+Vokietija de
+Vācija de
+Ġermanja de
+Tyskland de
+Duitsland de
+Tyskland de
+Alemanya de
+Niemcy de
+Alemanha de
+Alemanha de
+Germania de
+Германия de
+Nemecko de
+Nemčija de
+Nemačka de
+I-Germany de
+Tyskland de
+§º÷ÁÉ¢ de
+เยอรมันนี de
+Almanya de
+Німеччина de
+Đức de
+Almagne de
+德国 de
+德國 de
+IJalimani de
+Djibouti dj
+جيبوتي dj
+Джыбуці dj
+Джибути dj
+Đibuti dj
+Džibuti dj
+Dschibuti dj
+Τζιμπουτί dj
+جیبوتی dj
+ג'יבוטי dj
+Džibuti dj
+Dzsibuti dj
+ジブティ dj
+지부티 dj
+ພັດພາ dj
+Džibuti dj
+Dġibuti dj
+Dżibuti dj
+Djibuti dj
+Djibuti dj
+Джибути dj
+Džibuty dj
+Džibuti dj
+I-Djibouti dj
+Ê¢ƒ¢¦À¡Ê dj
+Cibuti dj
+Джібуті dj
+吉布提 dj
+吉布地 dj
+Denmark dk
+Denemarke dk
+الدنمارك dk
+Danimarka dk
+Данія dk
+Дания dk
+Danmark dk
+Danska dk
+Dinamarca dk
+Dánsko dk
+Danmark dk
+Dänemark dk
+Δανία dk
+Danlando dk
+Dinamarca dk
+Taani dk
+Danimarka dk
+دانمارک dk
+Tanska dk
+Danmark dk
+Danemark dk
+Dinamarca dk
+דנמרק dk
+Danska dk
+Dánia dk
+Danmörk dk
+Danimarca dk
+デンマーク dk
+덴마크 dk
+ເດນມາກ dk
+Danija dk
+Dānija dk
+Danimarka dk
+Danmark dk
+Denemarken dk
+Danmark dk
+Dinamarca dk
+Dania dk
+Dinamarca dk
+Dinamarca dk
+Danemarca dk
+Дания dk
+Dánsko dk
+Danska dk
+Danska dk
+I-Denmark dk
+Danmark dk
+¦¼ýÁ¡÷ì dk
+เดนมาร์ก dk
+Danimarka dk
+Данія dk
+Đan Mạch dk
+Daenmåtche dk
+丹麦 dk
+丹麥 dk
+Dominica dm
+Дамініка dm
+Доминика dm
+Dominika dm
+Dominika dm
+ໂລມາເນີຍ dm
+Dominicana dm
+Dominikánsko dm
+Dominikanska republika dm
+Домініка dm
+多米尼加 dm
+Dominican Republic do
+Dominikiese Republiek do
+جمهورية الدومينيكان do
+Dominik Respublikası do
+Дамініканская Рэспубліка do
+Доминиканска република do
+Republik Dominikan do
+Dominikanska Republika do
+República Dominicana do
+Dominikánská republika do
+Dominikanske Republik do
+Dominikanische Republik do
+Δομινικανή Δημοκρατία do
+Dominika Respubliko do
+República Dominicana do
+Dominikaani Vabariik do
+Dominikar Errepublika do
+جمهوری دامینیکن do
+Dominikaaninen tasavalta do
+République dominicaine do
+República Dominicana do
+הרפובליקה הדומיניקנית do
+Dominikanska Republika do
+Dominikai Köztársaság do
+Republik Dominika do
+Dóminíska Lýðveldið do
+Repubblica Dominicana do
+ドミニカ共和国 do
+도미니카 공화국 do
+ໂດມິນີກັນ do
+Dominikos Respublika do
+Dominikas Republika do
+Repubblika Dominikana do
+Den dominikanske republikk do
+Dominicaanse Republiek do
+Den dominikanske republikken do
+Republica Dominicana do
+Dominikana do
+República Dominicana do
+República Dominicana do
+Republica Dominicană do
+Доминиканская республика do
+Dominikánska republika do
+Dominikanska republika do
+Dominikanska republika do
+I-Dominican Republic do
+Dominikanska republiken do
+¦¼¡Á¢É¢ì¸ý ÌÊÂÃÍ do
+โดมินิกัน do
+Dominik Cumhuriyeti do
+Домініканська республіка do
+Muvhuso wa Dominican do
+Cộng hoà Dominican do
+Republike Dominikinne do
+IRepublic yeDominican do
+多米尼加共和国 do
+多明尼加共和國 do
+Algeria dz
+Algerië dz
+الجزائر dz
+Альжыр dz
+Алжир dz
+Alžir dz
+Algèria dz
+Alžírsko dz
+Algeriet dz
+Algerien dz
+Αλγερία dz
+Algerio dz
+Argelia dz
+Alžeeria dz
+ الجزیره dz
+Algérie dz
+אלג'יריה dz
+Alžir dz
+Algéria dz
+アルジェリア dz
+알제리 dz
+ບັນກາເລີຍ dz
+Alžyras dz
+Alġerija dz
+Algerie dz
+Algerije dz
+Algerie dz
+Algieria dz
+Argélia dz
+Argélia dz
+Алжир dz
+Alžírsko dz
+Alžirija dz
+I-Algeria dz
+Algeriet dz
+«øƒ¢Ã¢Â¡ dz
+Алжир dz
+Aldjereye dz
+阿尔及利亚 dz
+阿爾及利亞 dz
+Equador ec
+Ewenaar ec
+الإكوادور ec
+Ekvator ec
+Эквадор ec
+Еквадор ec
+Ecuador ec
+Ekvador ec
+Ekvádor ec
+Ecuador ec
+Ισημερινός ec
+Ekvadoro ec
+Ecuador ec
+Ekvador ec
+Ekuador ec
+اکوادور ec
+Équateur ec
+Ecuador ec
+אקוודור ec
+Ekvador ec
+Ecuador ec
+Ekvador ec
+Ecuador ec
+エクアドル ec
+에콰도르 ec
+ເອກໍດໍ ec
+Ekvadoras ec
+Ekvadora ec
+Ekwador ec
+Ecuador ec
+Ecuador ec
+Ekwador ec
+Ecuador ec
+Эквадор ec
+Ekvádor ec
+Ekvador ec
+Ekvador ec
+I-Equador ec
+®ì¦Å§¼¡÷ ec
+เอกวาดอร์ ec
+Ekvator ec
+Еквадор ec
+Ecwåteur ec
+厄瓜多尔 ec
+厄瓜多 ec
+Estonia ee
+Estlandies ee
+استونيا ee
+Estoniya ee
+Эстонія ee
+Естония ee
+Estonija ee
+Estònia ee
+Estonsko ee
+Estland ee
+Estland ee
+Εσθονία ee
+Estlando ee
+Eesti ee
+استونی ee
+Eesti ee
+Estonie ee
+אסטוניה ee
+Estonija ee
+Észtország ee
+Eistland ee
+エストニア ee
+에스토니아 ee
+ເອໂທເນີຍ ee
+Estija ee
+Igaunija ee
+Estonja ee
+Estland ee
+Estland ee
+Estland ee
+Estònia ee
+Estónia ee
+Estônia ee
+Эстония ee
+Estónsko ee
+Estonija ee
+Estonija ee
+I-Estonia ee
+Estland ee
+±Í§¼¡É¢Â¡ ee
+เอสโธเนีย ee
+Estonya ee
+Естонія ee
+Estoneye ee
+爱沙尼亚 ee
+愛沙尼亞 ee
+Egypt eg
+Egipte eg
+مصر eg
+Misir eg
+Эгіпэт eg
+Египет eg
+Egipat eg
+Egipte eg
+Egypten eg
+Ägypten eg
+Αίγυπτος eg
+Egiptujo eg
+Egipto eg
+Egiptus eg
+Egypto eg
+مصر eg
+Egypti eg
+Egyptaland eg
+Égypte eg
+מצרים eg
+Egipat eg
+Egyiptom eg
+Egyptaland eg
+Egitto eg
+エジプト eg
+이집트 eg
+ອີຢີບ eg
+Egiptas eg
+Ēģipte eg
+Eġittu eg
+Egypte eg
+Egepeta eg
+Egipt eg
+Egipto eg
+Egito eg
+Egipt eg
+Египет eg
+Egipt eg
+I-Egypt eg
+Egypten eg
+±¸¢ôÐ eg
+อียิปต์ eg
+Mısır eg
+Єгипет eg
+Edjipe eg
+埃及 eg
+埃及 eg
+Igibhithe eg
+Western Sahara eh
+Западна Сахара eh
+Zapadna Sahara eh
+Vestsahara eh
+Sahara occidental eh
+Mendebaldeko Sahara eh
+Nyugat-Szahara eh
+ພື້ນທີ່ທຳງານ eh
+Sahara eh
+Západna Sahara eh
+Zahodna Sahara eh
+Västsahara eh
+Західна Сахара eh
+西撒哈拉 eh
+Eritrea er
+Эрытрэя er
+Еритрея er
+Eritreja er
+ແກ້ໄຂແຟ້ມທຳງານ er
+Eritreja er
+Еритрея er
+厄立特里亚 er
+Spain es
+Spanje es
+أسبانيا es
+İspaniya es
+Гішпанія es
+Испания es
+Spagn es
+Španija es
+Espanya es
+Španělsko es
+Spanien es
+Spanien es
+Ισπανία es
+Hispanio es
+España es
+Hispaania es
+Espainia es
+اسپانیا es
+Espanja es
+Spania es
+Espagne es
+España es
+ספרד es
+Španjolska es
+Spanyolország es
+Spanyol es
+Spánn es
+Spagna es
+スペイン es
+스페인 es
+ສະເປັນ es
+Ispanija es
+Spānija es
+Spanja es
+Spania es
+Spanje es
+Spania es
+Espanha es
+Hiszpania es
+Espanha es
+Espanha es
+Spania es
+Испания es
+Španielsko es
+Španija es
+Španija es
+I-Spain es
+Spanien es
+ͦÀ¢ý es
+สเปน es
+İspanya es
+Іспанія es
+Tây Ban Nha es
+Sipagne es
+西班牙 es
+西班牙 es
+Ethiopia et
+Этыёпія et
+Етиопия et
+Etiopija et
+Ethiopien et
+Etiopía et
+Etiopia et
+Etiópia et
+ເອໂທເນີຍ et
+Etiópia et
+Etiópia et
+Etiopija et
+Etiopien et
+Ефіопія et
+埃塞俄比亚 et
+Finland fi
+فنلندا fi
+Finlandiya fi
+Фінляндыя fi
+Финландия fi
+Finska fi
+Finlàndia fi
+Finsko fi
+Finnland fi
+Φινλανδία fi
+Finlando fi
+Finlandia fi
+Soome fi
+Finlandia fi
+فنلاند fi
+Suomi fi
+Finnland fi
+Finlande fi
+Finlandia fi
+פינלנד fi
+Finska fi
+Finnország fi
+Finlandia fi
+Finnland fi
+Finlandia fi
+フィンランド fi
+핀란드 fi
+ຟີນແລນ fi
+Suomija fi
+Somija fi
+Finlandja fi
+Finlandia fi
+Finlandia fi
+Finlândia fi
+Finlândia fi
+Finlanda fi
+Финляндия fi
+Fínsko fi
+Finska fi
+Finska fi
+I-Finland fi
+À¢ýÄ¡óÐ fi
+ฟินแลนด์ fi
+Finlandiya fi
+Фінляндія fi
+Phần Lan fi
+Finlande fi
+芬兰 fi
+芬蘭 fi
+Fiji fj
+Фіджы fj
+Фиджи fj
+Fidži fj
+Fidzsi fj
+ມີດີ fj
+Ilhas Fiji fj
+Fidži fj
+Fidži fj
+Фіджі fj
+斐济 fj
+Falkland Islands (Malvinas) fk
+Фолклендски Острови fk
+Foklandska ostrva (Malvini) fk
+Falkland-øerne fk
+Islas Falkland (Malvinas) fk
+Falkland Irlak (Malvinak) fk
+Falkland-szigetek fk
+Ilhas Malvinas fk
+Falklandské Ostrovy (Malviny) fk
+Falklandski otoki (Malvini) fk
+Falklandsöarna fk
+福克兰岛 (马尔维纳斯) fk
+Micronesia, Federated states of fm
+Федэрацыя Мiкранэзіі fm
+Микронезия fm
+Mikronezija, Federalne države fm
+Mikronesien, de forenede stater af fm
+Micronesia, Estados federados de fm
+Mikronesia, Estatu Federatuak fm
+Mikronézia fm
+Estados Federados da Micronésia fm
+Spjoené štáty Mikronézie fm
+Mikronezija, Združene države fm
+Mikronesiska federationen fm
+密克罗尼西亚联邦 fm
+Faroe Islands fo
+Фареорски Острови fo
+Farska ostrva fo
+Færøerne fo
+islas Faroe fo
+Faroe Irlak fo
+Faroe-szigetek fo
+ໄອແລນ fo
+Ilhas Faroe fo
+Ostrovy Faroe fo
+Otoki Faroe fo
+Färöarna fo
+Фарерські острови fo
+France fr
+Frankryk fr
+فرنسا fr
+Fransa fr
+Францыя fr
+Франция fr
+Frañs fr
+Francuska fr
+França fr
+Francie fr
+Frankrig fr
+Frankreich fr
+Γαλλία fr
+Francio fr
+Francia fr
+Prantsusmaa fr
+Frantzia fr
+فرانسه fr
+Ranska fr
+Frakland fr
+Francia fr
+צרפת fr
+Francuska fr
+Franciaország fr
+Prancis fr
+Frakkland fr
+Francia fr
+フランス fr
+프랑스 fr
+ຝຣັ່ງ fr
+Prancūzija fr
+Francija fr
+Franza fr
+Frankrike fr
+Frankrijk fr
+Frankrike fr
+Fora fr
+França fr
+Francja fr
+França fr
+França fr
+Franţa fr
+Франция fr
+Francúzsko fr
+Francija fr
+Francuska fr
+I-France fr
+Frankrike fr
+À¢Ã¡ýÍ fr
+ฝรั่งเศส fr
+Fransa fr
+Франція fr
+Fura fr
+Pháp fr
+Fransi fr
+法国 fr
+法國 fr
+Gabon ga
+Габон ga
+Габон ga
+Gabón ga
+ແກລ່ງນ ga
+Gabão ga
+Габон ga
+加蓬 ga
+United Kingdom gb
+Vereenigde Koninkryk gb
+المملكة المتحدة gb
+Birləşmiş Krallıq gb
+Злучанае Каралеўства gb
+Великобритания gb
+Rouantelezh Unanet gb
+Velika Britanija gb
+Regne Unit gb
+Spojené království gb
+Storbritannien gb
+Großbritannien gb
+Ηνωμένο Βασίλειο gb
+Britio gb
+Reino Unido gb
+Ühendatud Kuningriigid gb
+Erreinu Batua gb
+بریتانیا gb
+Iso-Britannia gb
+Stórabretland gb
+Royaume Uni gb
+Reino Unido gb
+בריטניה gb
+Ujedinjeno Kraljevstvo gb
+Egyesült Királyság gb
+Inggris gb
+Stóra Bretland gb
+Regno Unito gb
+イギリス gb
+영국 gb
+ສະຫະລາດສະອານາຈັກ gb
+Jungtinė Karalystė gb
+Apvienotā Karaliste gb
+Renju Unit gb
+Storbritannia gb
+Verenigd Koninkrijk gb
+Storbritannia gb
+Regne Unit gb
+Wielka Brytania gb
+Reino Unido gb
+Reino Unido gb
+Anglia gb
+Великобритания gb
+Anglicko gb
+Združeno kraljestvo gb
+Velika Britanija gb
+I-United Kingdom gb
+Storbritannien gb
+³ì¸¢Â ­Ã¡îº¢Âõ gb
+สหราชอาณาจักร gb
+Birleşik Krallık gb
+Великобританія gb
+Anh gb
+United Kingdom gb
+联合王国 gb
+聯合王國 gb
+United Kingdom gb
+Grenada gd
+غرينادا gd
+Qrenada gd
+Грэнада gd
+Гренада gd
+Granada gd
+Γρενάδα gd
+Grenado gd
+Granada gd
+گرانادا gd
+Grenade gd
+Granada gd
+גרנדה gd
+Grænhöfðaeyjar gd
+Granada gd
+グラナダ gd
+그러네이다 gd
+ເກນາດາ gd
+Grenāda gd
+Granada gd
+Granada gd
+Granada gd
+Гренада gd
+I-Grenada gd
+¸¢¦Ãɼ¡ gd
+เกรนาดา gd
+Гренада gd
+格林纳达 gd
+格瑞那達 gd
+Georgia ge
+Грузія ge
+Грузия ge
+Gruzija ge
+Georgien ge
+Grúzia ge
+ເຊີເບີຍ ge
+Geórgia ge
+Gruzija ge
+Georgien ge
+Грузія ge
+格鲁吉亚 ge
+Ghana gh
+غانا gh
+Гана gh
+Гана gh
+Gana gh
+Γκάνα gh
+غنا gh
+גאנה gh
+ガーナ gh
+ຈີນ gh
+Gana gh
+Gana gh
+Gana gh
+Гана gh
+Gana gh
+I-Ghana gh
+¸¡É¡ gh
+Гана gh
+加纳 gh
+迦納 gh
+Gibraltar gi
+Гибралтар gi
+Gibraltár gi
+ມອລຕາ gi
+Гібралтар gi
+直布罗陀 gi
+Gambia gm
+Гамбія gm
+Гамбия gm
+Gambija gm
+ແກມມາ gm
+Gâmbia gm
+Gambija gm
+Гамбія gm
+冈比亚 gm
+Guinea gn
+Гвінэя gn
+Гвинея gn
+Gvineja gn
+ເຖາວັນ gn
+Guiné gn
+Gvineja gn
+Гвінея gn
+几内亚 gn
+Guadeloupe gp
+Гвадалупа gp
+Gvadalupe gp
+Guadalupe gp
+ເດີລຸກ gp
+Guadalupe gp
+Гваделупа gp
+瓜德罗普岛 gp
+Equatorial Guinea gq
+Экватарыяльная Гвінэя gq
+Екваториялна Гвинея gq
+Ekvatorijalna Gvineja gq
+Ækvatorial Guinea gq
+Guinea equatorial gq
+Ginea Ekuatoriala gq
+Egyenlítői Guinea gq
+ການສອນ gq
+Guiné Equatorial gq
+Rovníkova Guinea gq
+Ekvatorialna Gvineja gq
+Ekvatorialguinea gq
+Екваторіальна Гвінея gq
+赤道几内亚 gq
+Greece gr
+Griekeland gr
+اليونان gr
+Yunanıstan gr
+Грэцыя gr
+Гърция gr
+Gres gr
+Grčka gr
+Grècia gr
+Řecko gr
+Grækenland gr
+Griechenland gr
+Ελλάδα gr
+Grekujo gr
+Grecia gr
+Kreeka gr
+Grezia gr
+یونان gr
+Kreikka gr
+Grikkaland gr
+Grèce gr
+Grecia gr
+יוון gr
+Grčka gr
+Görögország gr
+Grikkland gr
+Grecia gr
+ギリシャ gr
+그리스 gr
+ກີຊ gr
+Graikija gr
+Grieķija gr
+Greċja gr
+Hellas gr
+Griekenland gr
+Hellas gr
+Grèça gr
+Grecja gr
+Grécia gr
+Grécia gr
+Grecia gr
+Греция gr
+Grécko gr
+Grčija gr
+Grčka gr
+I-Greece gr
+Grekland gr
+¸¢Ã£Í gr
+กรีซ gr
+Yunanistan gr
+Греція gr
+Hy Lạp gr
+Grece gr
+希腊 gr
+希臘 gr
+Guatemala gt
+Gautemala gt
+غواتيمالا gt
+Quatemala gt
+Гватэмала gt
+Гватемала gt
+Gvatemala gt
+Γουατεμάλα gt
+Gvatemalo gt
+Guatemaala gt
+گواتمالا gt
+גואטמלה gt
+Gvatemala gt
+カタロニア gt
+과테말라 gt
+ກັວເຕມາລາ gt
+Gvatemala gt
+Gvatemala gt
+Gwatemala gt
+Gwatemala gt
+Гватемала gt
+Gvatemala gt
+Gvatemala gt
+I-Guatemala gt
+ÌÅ¡ò¾Á¡Ä¡ gt
+กัวเตมาลา gt
+Гватемала gt
+Gwatemala gt
+瓜地马拉 gt
+瓜地馬拉 gt
+Guam gu
+Гуам gu
+ແກມມາ gu
+Гуам gu
+关岛 gu
+Guinea-Bissau gw
+Гвінэя-Бісаў gw
+Гвинея-Бисау gw
+Gvineja-Bisau gw
+Ginea-Bissau gw
+Bissau-Guinea gw
+ລັດເຊີຍ gw
+Guiné-Bissau gw
+Гвінея-Біссау gw
+几内亚比绍 gw
+Guyana gy
+Гвіяна gy
+Гуана gy
+Gvajana gy
+ຈີນ gy
+Guiana gy
+Gvajana gy
+Гаяна gy
+圭亚那 gy
+Hong Kong hk
+Ганконг hk
+Хонг Конг hk
+Hongkong hk
+ບໍ່ຮູ້ຈັກ hk
+Гонконг hk
+香港 hk
+Honduras hn
+هندوراس hn
+Гандурас hn
+Хондурас hn
+Hondures hn
+Ονδούρα hn
+Honduraso hn
+Honduuras hn
+هندوراس hn
+הונדורס hn
+ホンデュラス hn
+온두라스 hn
+ຫອນດູລັດ hn
+Hondūras hn
+Hondurasa hn
+Ħonduras hn
+Hondures hn
+Гондурас hn
+I-Honduras hn
+¬ñÎáŠÍ hn
+ฮอนดูรัส hn
+Гондурас hn
+洪都拉斯 hn
+宏都拉斯 hn
+Croatia hr
+Kroatië hr
+كرواتيا hr
+Xırvatıstan hr
+Харватыя hr
+Хърватска hr
+Kroatia hr
+Hrvatska hr
+Croàcia hr
+Chorvatsko hr
+Kroatien hr
+Kroatien hr
+Κροατία hr
+Kroatio hr
+Croacia hr
+Horvaatia hr
+Kroazia hr
+کرواسی hr
+Kroatia hr
+Kroatia hr
+Croatie hr
+Croacia hr
+קרואטיה hr
+Hrvatska hr
+Horvátország hr
+Kroasia hr
+Króatía hr
+Croazia hr
+クロアチア hr
+크로아티아 hr
+ໂຄເອເທີຍ hr
+Kroatija hr
+Horvātija hr
+Kroazja hr
+Kroatia hr
+Kroatië hr
+Kroatia hr
+Croacia hr
+Chorwacja hr
+Croácia hr
+Croácia hr
+Croaţia hr
+Хорватия hr
+Chorvátsko hr
+Hrvaška hr
+Hrvatska hr
+I-Croatia hr
+Kroatien hr
+̦á§Åº¢Â¡ hr
+โครเอเธีย hr
+Hırvatistan hr
+Хорватія hr
+Crowåceye hr
+克罗地亚 hr
+克羅埃西亞 hr
+Haiti ht
+Гаіці ht
+Хаити ht
+Haití ht
+ວາດຮູບ - K ht
+Гаїті ht
+海地岛 ht
+Hungary hu
+Hongarye hu
+هنغاريا hu
+Macarıstan hu
+Вугоршчына hu
+Унгария hu
+Hungaria hu
+Mađarska hu
+Hongria hu
+Maďarsko hu
+Ungarn hu
+Ungarn hu
+Ουγγαρία hu
+Hungario hu
+Hungría hu
+Ungari hu
+Hungaria hu
+مجارستان hu
+Unkari hu
+Ungarn hu
+Hongrie hu
+Hungría hu
+הונגריה hu
+Mađjarska hu
+Magyarország hu
+Hungaria hu
+Ungverjaland hu
+Ungheria hu
+ハンガリー hu
+헝가리 hu
+ຫັງກາລີ hu
+Vengrija hu
+Ungārija hu
+Ungerija hu
+Ungarn hu
+Hongarije hu
+Ungarn hu
+Hongria hu
+Węgry hu
+Hungria hu
+Hungria hu
+Ungaria hu
+Венгрия hu
+Maďarsko hu
+Madžarska hu
+Mađarska hu
+I-Hungary hu
+Ungern hu
+¬í§¸Ã¢ hu
+ฮังการี hu
+Macaristan hu
+Угорщина hu
+Hongreye hu
+匈牙利 hu
+匈牙利 hu
+Indonesia id
+Indonesië id
+إندونيسيا id
+İndoneziya id
+Інданэзія id
+Индонезия id
+Indonezija id
+Indonèsia id
+Indonésie id
+Indonesien id
+Indonesien id
+Ινδονησία id
+Indonezio id
+Indoneesia id
+اندونزی id
+Indonésie id
+אינדונזיה id
+Indonezija id
+Indonézia id
+Indónesía id
+インドネシア id
+인도네시아 id
+ອີຍໂດນີເຊີຍ id
+Indonezija id
+Indonēzija id
+Indoneżja id
+Indonesië id
+Indonezja id
+Indonésia id
+Indonésia id
+Indonezia id
+Индонезия id
+Indonézia id
+Indonezija id
+I-Indonesia id
+Indonesien id
+­ó§¾¡É£º¢Â¡ id
+อินโดนีเซีย id
+İndonezya id
+Індонезія id
+Indoneseye id
+印度尼西亚 id
+印尼 id
+Ireland ie
+Ierland ie
+أيرلندا ie
+İrlandiya ie
+Ірляндыя ie
+Ирландия ie
+Iwerzhon ie
+Irska ie
+Irlanda ie
+Irsko ie
+Irland ie
+Irland ie
+Ιρλανδία ie
+Islando ie
+Irlanda ie
+Island ie
+Irlanda ie
+ایرلند ie
+Irlanti ie
+Írland ie
+Irlande ie
+Irlanda ie
+אירלנד ie
+Irska ie
+Írország ie
+Irlandia ie
+Írland ie
+Irlanda ie
+アイスランド ie
+아일랜드 ie
+ໄອແລນ ie
+Airija ie
+Īrija ie
+Irlanda ie
+Irland ie
+Ierland ie
+Irland ie
+Irlanda ie
+Irlandia ie
+Irlanda ie
+Irlanda ie
+Irlanda ie
+Ирландия ie
+Írsko ie
+Irska ie
+Irska ie
+I-Ireland ie
+Irland ie
+«Â÷Ä¡óÐ ie
+ไอร์แลนด์ ie
+İrlanda ie
+Ірландія ie
+Irlande ie
+爱尔兰 ie
+愛爾蘭 ie
+Israel il
+اسرائيل il
+İzrail il
+Ізраіль il
+Израел il
+Izrael il
+Izrael il
+Ισραήλ il
+Israelo il
+Iisrael il
+اسراییل il
+Ísrael il
+Israël il
+ישראל il
+Izrael il
+Izrael il
+Ísrael il
+Israele il
+イスラエル il
+이스라엘 il
+ອິດສະລະເອລ il
+Izraelis il
+Izraēla il
+Iżrael il
+Izrael il
+Израиль il
+Izrael il
+Izrael il
+Izrael il
+I-Israel il
+­Í§Ãø il
+อิสราเอล il
+İsrail il
+Ізраїль il
+Israyel il
+USirayeli il
+以色列 il
+以色列 il
+India in
+Indië in
+الهند in
+Hindistan in
+Індыя in
+Индия in
+Indija in
+Índia in
+Indie in
+Indien in
+Indien in
+Ινδία in
+Hindujo in
+هندوستان in
+Intia in
+Inde in
+הודו in
+Indija in
+Indland in
+インド in
+인도 in
+ອິນເດີຍ in
+Indija in
+Indija in
+Indja in
+Indie in
+Índia in
+Índia in
+Индия in
+Indija in
+I-India in
+Indien in
+­ó¾¢Â¡ in
+อินเดีย in
+Hindistan in
+Індія in
+Inde in
+印度 in
+印度 in
+Endiya in
+Iraq iq
+Irak iq
+العراق iq
+İraq iq
+Ірак iq
+Ирак iq
+Irak iq
+Irák iq
+Irak iq
+Irak iq
+Ιράκ iq
+Irako iq
+Irak iq
+Iraak iq
+عراق iq
+Irak iq
+Irak iq
+Irak iq
+עירק iq
+Irak iq
+Irak iq
+Írak iq
+Irak iq
+イラク iq
+이라크 iq
+ອີລັກ iq
+Irakas iq
+Irāka iq
+Irak iq
+Irak iq
+Irak iq
+Irak iq
+Iraque iq
+Iraque iq
+Irak iq
+Ирак iq
+Irák iq
+Irak iq
+I-Iraq iq
+Irak iq
+®Ã¡ì iq
+อิรัค iq
+Irak iq
+Ірак iq
+Irak iq
+伊拉克 iq
+伊拉克 iq
+Iran ir
+أيران ir
+Іран ir
+Иран ir
+Írán ir
+Ιράν ir
+Iraan ir
+ایران ir
+אירן ir
+Irán ir
+イラン ir
+이란 ir
+ອີລັກ ir
+Iranas ir
+Irão ir
+Irã ir
+Иран ir
+Irán ir
+I-Iran ir
+®Ã¡ý ir
+İran ir
+Іран ir
+伊朗 ir
+伊朗 ir
+Iceland is
+Ysland is
+أيسلندا is
+İslandiya is
+Ісьляндыя is
+Исландия is
+Island is
+Island is
+Islàndia is
+Island is
+Island is
+Island is
+Ισλανδία is
+Islando is
+Islandia is
+Island is
+Islandia is
+ایسلند is
+Islanti is
+Ísland is
+Islande is
+Islandia is
+איסלנד is
+Island is
+Izland is
+Islandia is
+Ísland is
+Islanda is
+アイスランド is
+아이슬란드 is
+ໄອຊແລນ is
+Islandija is
+Islande is
+Islandja is
+Island is
+IJsland is
+Island is
+Islandia is
+Islandia is
+Islândia is
+Islândia is
+Islanda is
+Исландия is
+Island is
+Islandija is
+Island is
+I-Iceland is
+Island is
+³ÍÄ¡óÐ is
+ไอซ์แลนด์ is
+İzlanda is
+Ісландія is
+Izlande is
+冰岛 is
+冰島 is
+Icelandi is
+Italy it
+Italië it
+ايطاليا it
+İtalyia it
+Італія it
+Италия it
+Italia it
+Italija it
+Itàlia it
+Itálie it
+Italien it
+Italien it
+Ιταλία it
+Italio it
+Italia it
+Itaalia it
+Italia it
+ایتالیا it
+Italia it
+Italia it
+Italie it
+Italia it
+איטליה it
+Italija it
+Olaszország it
+Italia it
+Ítalía it
+Italia it
+イタリア it
+이탈리아 it
+ອີຕາລີ it
+Italija it
+Itālija it
+Italja it
+Italia it
+Italië it
+Italia it
+Italia it
+Włochy it
+Itália it
+Itália it
+Italia it
+Италия it
+Taliansko it
+Italija it
+Italija it
+I-Italy it
+Italien it
+­ò¾¡Ä¢ it
+อิตาลี it
+İtalya it
+Італія it
+Itåleye it
+Ithali it
+意大利 it
+義大利 it
+Jamaica jm
+Jamaika jm
+جامايكا jm
+Yamayka jm
+Ямайка jm
+Ямайка jm
+Jamaika jm
+Jamajka jm
+Jamajka jm
+Jamaika jm
+Τζαμάικα jm
+Ĵamaiko jm
+Jamaika jm
+Jamaika jm
+جاماییکا jm
+Jamaika jm
+Jamaïque jm
+Xamaica jm
+ג'מייקה jm
+Jamajka jm
+Jamaika jm
+Jamaika jm
+Giamaica jm
+ジャマイカ jm
+자메이카 jm
+ຈາໄມກາ jm
+Jamaika jm
+Jamaika jm
+Ġamajka jm
+Jamajka jm
+Ямайка jm
+Jamajka jm
+Jamajka jm
+Jamajka jm
+I-Jamaica jm
+ƒº¦Áö측 jm
+จาไมกา jm
+Jamaika jm
+Ямайка jm
+Djamayike jm
+牙买加 jm
+牙買加 jm
+Jordan jo
+Jordaan jo
+الأردن jo
+İordaniya jo
+Ярданія jo
+Йордания jo
+Jordania jo
+Jordán jo
+Jordanien jo
+Ιορδανία jo
+Jordanio jo
+Jordania jo
+اردن jo
+Jordania jo
+Jordanie jo
+ירדן jo
+Jordánia jo
+Jórdanía jo
+Giordania jo
+ヨルダン jo
+요르단 jo
+ຈໍແດນ jo
+Jordanija jo
+Jordāna jo
+Ġordan jo
+Jordanië jo
+Jordania jo
+Jordânia jo
+Jordânia jo
+Iordania jo
+Иордания jo
+Jordánsko jo
+Jordanija jo
+I-Jordan jo
+Jordanien jo
+§Â¡÷¾¡ý jo
+จอร์แดน jo
+Ürdün jo
+Йорданія jo
+Djordaneye jo
+约旦 jo
+約旦 jo
+Ijolidani jo
+Japan jp
+اليابان jp
+Yaponiya jp
+Японія jp
+Япония jp
+Japó jp
+Japonsko jp
+Ιαπωνία jp
+Japanio jp
+Japón jp
+Jaapan jp
+Japonia jp
+ژاپن jp
+Japani jp
+Japon jp
+Xapón jp
+יפן jp
+Japán jp
+Jepang jp
+Giappone jp
+日本 jp
+일본 jp
+ຍີ່ປຸ່ນ jp
+Japonija jp
+Japāna jp
+Ġappun jp
+Japon jp
+Japonia jp
+Japão jp
+Japão jp
+Japonia jp
+Япония jp
+Japonsko jp
+Japonska jp
+I-Japan jp
+ºôÀ¡ý jp
+ญี่ปุ่น jp
+Japonya jp
+Японія jp
+Nhật bản jp
+Djapon jp
+日本 jp
+日本 jp
+Kenya ke
+Кенія ke
+Кения ke
+Kenija ke
+Kenia ke
+ເວນດາ ke
+Quênia ke
+Keňa ke
+Kenija ke
+Кенія ke
+肯尼亚 ke
+Kyrgyzstan kg
+Кыргызстан kg
+Киргистан kg
+Kirgistan kg
+Kirgizistan kg
+Kyrgyzstán kg
+Kirgizisztán kg
+ຄສິຕັລ kg
+Kirgizstan kg
+Kirgizistan kg
+Киргизстан kg
+吉尔吉斯坦 kg
+Cambodia kh
+Камбоджа kh
+Камбоджа kh
+Kambođa kh
+Kambodzsa kh
+ໂຄລຳເບີຍ kh
+Cambodja kh
+Kambodža kh
+Kambodža kh
+Kambodja kh
+Камбоджа kh
+柬埔寨 kh
+Kiribati ki
+Кiрыбацi ki
+Кирибати ki
+ແຟຄທັລ - K ki
+Кірібаті ki
+基里巴斯 ki
+Comoros km
+Каморы km
+Коморски km
+Komori km
+Comorerne km
+ສີ km
+Komori km
+Komorerna km
+Комори km
+科摩罗群岛 km
+St. Kitts and Nevis kn
+St. Kitts en Nevis kn
+سانت كيتس و نيفيس kn
+St. Kitts və Nevis kn
+Св. Кристоф и Невис kn
+S. Kitts ha Nevis kn
+St. Kitts i Nevis kn
+Sv. Kitts a Nevis kn
+St. Kitts-Nevis kn
+St. Kitts und Nevis kn
+St. Kitts και Nevis kn
+St. Kitts kaj Nevis kn
+St. Kitts y Nevis kn
+St. Kitts ja Nevis kn
+St. Kitts eta Nevis kn
+سن کیتس و نویس kn
+St. Kitts ja Nevis kn
+St Kitts et Nevis kn
+Saint Kitts e Nevis kn
+סנט קיטס ונביס kn
+St. Kitts és Nevis kn
+St. Kitts dan Nevis kn
+Ss. Kitts e Nevis kn
+セントキッツネヴィス kn
+세인트 키츠 네비스 kn
+Šv. Kitts ir Nevis kn
+St. Kitts un Nevis kn
+St. Kitts u Nevis kn
+St. Kitts og Nevis kn
+St. Kitts en Nevis kn
+St. Kitts og Nevis kn
+St. Kitts le Nevis kn
+St. Kitts e Nevis kn
+St. Kitts e Nevis kn
+St Kitts e Nevis kn
+Sf. Kitts şi Nevis kn
+о. Св. Кристофа и Невиса kn
+St. Kitts a Nevis kn
+St. Kitts in Nevis kn
+St. Kitts i Nevis kn
+I-St. Kitts and Nevis kn
+St. Kitts och Nevis kn
+¦ºÂ¢ý𠸢ðÍ & ¦¿Å¢Í kn
+St. Kitts ve Nevis kn
+Федерація Сент-Кітс і Невіс kn
+St. Kitts na Nevis kn
+St. Kitts neNevis kn
+圣基特和里维斯 kn
+聖克理斯多福及尼維斯 kn
+St. Kitts kanye no-Nevis kn
+North Korea kp
+Noord Korea kp
+كوريا الشمالية kp
+Şimali Koreya kp
+Паўночная Карэя kp
+Северна Корея kp
+Norzh-Korea kp
+Sjeverna Koreja kp
+Corea del Nord kp
+Severní Korea kp
+Nordkorea kp
+Nord-Korea kp
+Βόρεια Κορέα kp
+Nordkoreo kp
+Corea del Norte kp
+Põhja-Korea kp
+Ipar Korea kp
+کره شمالی kp
+Pohjois-Korea kp
+Norðurkorea kp
+Corée du nord kp
+Corea do Norte kp
+צפון קוריאה kp
+Sjeverna Koreja kp
+Észak-Korea kp
+Korea Utara kp
+Kórea - Norðurkórea kp
+Corea del Nord kp
+北朝鮮 kp
+조선민주주의 인민공화국 kp
+ເກົາລີເຫນືອ kp
+Šiaurės Korėja kp
+ZiemeļKoreja kp
+Korea ta' Fuq kp
+Nord-Korea kp
+Noord-Korea kp
+Nord-Korea kp
+Lebowa la Korea kp
+Corea dèu Nord kp
+Korea Północna kp
+Coreia do Norte kp
+Coréia do Norte kp
+Coreea de Nord kp
+Северная Корея kp
+severná Kórea kp
+Severna Koreja kp
+Severna Koreja kp
+I-North Korea kp
+Nordkorea kp
+ż ¦¸¡Ã¢Â¡ kp
+เกาหลีเหนือ kp
+Kuzey Kore kp
+Північна Корея kp
+Devhula ha Korea kp
+Bắc Triều Tiên kp
+Bijhe Coreye kp
+Umntla Korea kp
+朝鲜 kp
+北韓 kp
+Enyakatho ne-Korea kp
+South Korea kr
+Suid Korea kr
+كوريا الجنوبية kr
+Cənubi Koreya kr
+Паўднёвая Карэя kr
+Южна Корея kr
+Su-Korea kr
+Južna Koreja kr
+Corea del Sud kr
+Jižní Korea kr
+Sydkorea kr
+Süd-Korea kr
+Νότια Κορέα kr
+Sudkoreo kr
+Corea del Sur kr
+Lõuna-Korea kr
+Hego Korea kr
+کره جنوبی kr
+Etelä-Korea kr
+Suðurkorea kr
+Corée du sud kr
+Corea do Sur kr
+דרום קוריאה kr
+Južna Koreja kr
+Dél-Korea kr
+Korea Selatan kr
+Kórea - Suðurkórea kr
+Corea del Sud kr
+韓国 kr
+대한민국 kr
+ເກົາລີໃຕ້ kr
+Pietų Korėja kr
+DievidKoreja kr
+Korea t'Isfel kr
+Sør-Korea kr
+Zuid-Korea kr
+Sør-Korea kr
+Borwa bja Korea kr
+Corea dèu Sud kr
+Korea Południowa kr
+Coreia do Sul kr
+Coréia do Sul kr
+Coreea de Sud kr
+Южная Корея kr
+Južná Kórea kr
+Južna Koreja kr
+Južna Koreja kr
+I-South Korea kr
+Sydkorea kr
+¦¾ý ¦¸¡Ã¢Â¡ kr
+เกาหลีใต้ kr
+Güney Kore kr
+Південна Корея kr
+Korea tshipembe kr
+Hàn Quốc kr
+Nonne Coreye kr
+Umzantsi Korea kr
+韩国 kr
+南韓 kr
+Emzansi Korea kr
+Kuwait kw
+Kuwaït kw
+الكويت kw
+Кувэйт kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+Κουβέιτ kw
+Kuveit kw
+کویت kw
+Kuvait kw
+Kowait kw
+כווית kw
+Kuvajt kw
+Kuvait kw
+クェート kw
+쿠웨이트 kw
+ແຕ້ມຮູບ- K kw
+Kuveitas kw
+Koeweit kw
+Koweit kw
+Kuveit kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+I-Kuwait kw
+̨Åò kw
+KКувейт kw
+科威特 kw
+科威特 kw
+Cayman Islands ky
+Кайманови Острови ky
+Kajmanska ostrva ky
+Cayman-øerne ky
+Islas Caimán ky
+Kaiman Irlak ky
+Kajmán-szigetek ky
+ຄາຕາລັນ ky
+Ilhas Cayman ky
+Kajmanske Ostrovy ky
+Kajmanski otoki ky
+Caymanöarna ky
+Кайманські острови ky
+开曼群岛 ky
+Kazakhstan kz
+Казахстан kz
+Казахстан kz
+Kazahstan kz
+Kazakhstán kz
+Kazahsztán kz
+ແກແລກຕິກ - K kz
+Kazaquistão kz
+Kazachstan kz
+Kazahstan kz
+Kazakstan kz
+Казахстан kz
+哈萨克斯坦 kz
+Laos la
+Лаос la
+Лаос la
+Laosz la
+ລາວ la
+老挝 la
+Lebanon lb
+Libanon lb
+لبنان lb
+Ліван lb
+Ливан lb
+Liban lb
+Libanon lb
+Libanon lb
+Libanon lb
+Λίβανος lb
+Lebanono lb
+Líbano lb
+Liibanon lb
+لبنان lb
+Libanon lb
+Libanon lb
+Liban lb
+לבנון lb
+Libanon lb
+Libanon lb
+Libano lb
+レバノン lb
+레바논 lb
+ເດນ່ງນ lb
+Libanas lb
+Libanu lb
+Libanon lb
+Libanon lb
+Libanon lb
+Liban lb
+Líbano lb
+Líbano lb
+Liban lb
+Ливан lb
+Libanon lb
+Libanon lb
+I-Lebanon lb
+Libanon lb
+¦ÄÀÉ¡ý lb
+Ліван lb
+Liban lb
+黎巴嫩 lb
+黎巴嫩 lb
+St. Lucia lc
+سانت لوسيا lc
+Св. Люсиа lc
+S. Lucia lc
+Svatá Lucie lc
+Σάντα Λουτσία lc
+St. Lucio lc
+Santa Lucía lc
+سن لوسیا lc
+Sankta Lusia lc
+Sainte Lucie lc
+Santa Lucía lc
+סנטה לוסיה lc
+Santa Lucia lc
+セントルキア lc
+세인트 루시아 lc
+ເຊັນລູເຊີຍ lc
+Šv Liucija lc
+Sv. Lūcija lc
+St. Luċija lc
+Santa Lúcia lc
+Santa Lúcia lc
+Sf. Lucia lc
+о. Св. Люсии lc
+Sv. Júlia lc
+Sv. Lucija lc
+I-St. Lucia lc
+¦ºýð æº¢Â¡ lc
+เซนต์ลูเซีย lc
+Санта Лучія lc
+圣路西亚 lc
+聖露西亞 lc
+Liechtenstein li
+Ліхтэнштэйн li
+Лихтенщайн li
+Lihtenštajn li
+Liechtestein li
+ຟ້າແມບ li
+列支敦士登 li
+Sri Lanka lk
+Шры-Ланка lk
+Шри Ланка lk
+Šri Lanka lk
+ເຊີເບີຍ lk
+Šri Lanka lk
+斯里兰卡 lk
+Liberia lr
+Лібэрыя lr
+Либеря lr
+Liberija lr
+Libéria lr
+ລິຊາ lr
+Libéria lr
+Lýbia lr
+Liberija lr
+利比里亚 lr
+Lesotho ls
+Лесота ls
+Лесото ls
+Lesoto ls
+Lesoto ls
+ທົດສອບ ls
+Lesoto ls
+莱索托 ls
+Lithuania lt
+Lithuanië lt
+ليتوانيا lt
+Litvaniya lt
+Літва lt
+Литва lt
+Litvanija lt
+Lituània lt
+Litva lt
+Litauen lt
+Litauen lt
+Λιθουανία lt
+Litovio lt
+Lituania lt
+Leedu lt
+Lituania lt
+لیتوانی lt
+Liettua lt
+Lituanie lt
+ליטא lt
+Litva lt
+Litvánia lt
+Litháenska lt
+Lituania lt
+リトアニア lt
+리 투아니아 lt
+ລິທົ່ວເນີຍ lt
+Lietuva lt
+Lietuva lt
+Litwanja lt
+Litauen lt
+Litouwen lt
+Litauen lt
+Litwa lt
+Lituânia lt
+Lituânia lt
+Lituania lt
+Литва lt
+Litva lt
+Litva lt
+Litvanija lt
+I-Lithuania lt
+Litauen lt
+Ä¢òЧÅɢ¡ lt
+ลิธัวเนีย lt
+Litvanya lt
+Литва lt
+立陶宛 lt
+立陶宛 lt
+Luxembourg lu
+Luxenburg lu
+لوكسمبورغ lu
+Lüksemburq lu
+Люксэмбург lu
+Люксембург lu
+Luksemburg lu
+Luxemburg lu
+Lucembursko lu
+Luxemburg lu
+Λουξεμβούργο lu
+Luksemburgo lu
+Luxemburgo lu
+Luksemburg lu
+Luxemburg lu
+لوگزامبورگ lu
+Luxemburg lu
+Luksemborg lu
+לוקסמבורג lu
+Luksemburg lu
+Luxemburg lu
+Lúxemborg lu
+Lussemburgo lu
+ルクセンブルグ lu
+룩셈부르크 lu
+ລັກແຊມເບີກ lu
+Liuksemburgas lu
+Luksemburga lu
+Lussemburgu lu
+Luxemburg lu
+Luksemburg lu
+Luxemburgo lu
+Luxemburgo lu
+Luxemburg lu
+Люксембург lu
+Luxemburg lu
+Luksemburg lu
+Luksemburg lu
+I-Luxembourg lu
+Luxemburg lu
+Äìºõ§À¡÷ì lu
+ลักเซมเบอร์ก lu
+Lüksemburg lu
+Люксембург lu
+Lucsimbork lu
+卢森堡 lu
+盧森堡 lu
+Latvia lv
+لاتفيا lv
+Latviya lv
+Латвія lv
+Латвия lv
+Latvija lv
+Lotyšsko lv
+Letland lv
+Lettland lv
+Λιθουανία lv
+Latvio lv
+Letonia lv
+Läti lv
+لاتویا lv
+Lettonie lv
+לטביה lv
+Latvija lv
+Lettország lv
+Léttland lv
+Lettonia lv
+ラトビア lv
+라트비아 lv
+ລັດເວີຍ lv
+Latvija lv
+Latvija lv
+Latvja lv
+Letland lv
+Łotwa lv
+Letónia lv
+Латвия lv
+Lotyšsko lv
+Latvija lv
+Latvija lv
+I-Latvia lv
+Lettland lv
+ÄðŢ¡ lv
+ลัธเวีย lv
+Litvanya lv
+Латвія lv
+Lativia lv
+拉脱维亚 lv
+拉脫維亞 lv
+Libya ly
+Libië ly
+ليبيا ly
+Лівія ly
+Либия ly
+Libija ly
+Líbia ly
+Lýbie ly
+Libyen ly
+Libyen ly
+Λιβύη ly
+Libia ly
+Liibüa ly
+Libia ly
+لیبی ly
+Lybie ly
+לוב ly
+Líbia ly
+Libia ly
+リビア ly
+ລິຊາ ly
+Libija ly
+Libië ly
+Libia ly
+Líbia ly
+Líbia ly
+Ливия ly
+Lýbia ly
+Libija ly
+I-Libya ly
+Libyen ly
+Ä¢À¢Â¡ ly
+Лівія ly
+利比亚 ly
+利比亞 ly
+Morocco ma
+Morokko ma
+المغرب ma
+Марока ma
+Мароко ma
+Maroko ma
+Marroc ma
+Maroko ma
+Marokko ma
+Marokko ma
+Μαρόκο ma
+Moroko ma
+Marruecos ma
+Maroko ma
+Maroko ma
+مراکش ma
+Marokko ma
+Marokko ma
+Maroc ma
+מרוקו ma
+Maroko ma
+Marokkó ma
+Marocco ma
+モロッコ ma
+모로코 ma
+ເມົາລິ ma
+Marokas ma
+Marokk ma
+Marokko ma
+Marokko ma
+Marokko ma
+Maroko ma
+Marrocos ma
+Marrocos ma
+Maroc ma
+Марокко ma
+Maroko ma
+Maroko ma
+I-Morocco ma
+Marocko ma
+§Á¡Ã¡§¸¡ ma
+Марокко ma
+Marok ma
+摩洛哥 ma
+摩洛哥 ma
+Monaco mc
+Манака mc
+Монако mc
+Monako mc
+Mónaco mc
+ເມົາລິ mc
+Mônaco mc
+Monako mc
+Monako mc
+摩纳哥 mc
+Moldova md
+Малдова md
+Молдова md
+Moldavia md
+Moldavia md
+ສະໂລວັກ md
+Moldávsko md
+Moldavien md
+摩尔多瓦 md
+Madagascar mg
+Мадагаскар mg
+Мадагаскар mg
+Madagaskar mg
+Madagaszkár mg
+ຄາສະບາລ - K mg
+Madagaskar mg
+Madagaskar mg
+Madagaskar mg
+马达加斯加 mg
+Marshall Islands mh
+Маршаллавы астравы mh
+Маршалови Острови mh
+Maršalova ostrva mh
+Marshall-øerne mh
+Islas Marshall mh
+Marshall Irlak mh
+Marshall-szigetek mh
+ລາດສະອານາຈັກໄທຍ mh
+Ilhas Marshall mh
+Maršálove ostrovy mh
+Marshallovi otoki mh
+Marshallöarna mh
+马绍尔群岛 mh
+Macedonia mk
+Makedoniese mk
+مقدونيا mk
+Makedonya mk
+Македонія mk
+Македония mk
+Makedonia mk
+Makedonija mk
+Macedònia mk
+Makedonie mk
+Makedonien mk
+Makedonien mk
+Μακεδονία mk
+Macedonio mk
+Makedoonia mk
+Mazedonia mk
+مقدونیه mk
+Makedonia mk
+Macédoine mk
+מקדוניה mk
+Makedonija mk
+Macedónia mk
+Masedonia mk
+Makedónía mk
+マケドニア語 mk
+마케도니아 mk
+ມາເຊໂດເນີຍ mk
+Makedonija mk
+Maķedonija mk
+Maċedonja mk
+Makedonia mk
+Macedonië mk
+Makedonia mk
+Macedònian mk
+Macedónia mk
+Macedônia mk
+Македония mk
+Macedónsky mk
+Makedonija mk
+Makedonija mk
+I-Macedonia mk
+Makedonien mk
+Á¡º¢§¼¡É¢Â¡ mk
+มาเซโดเนีย mk
+Makedonya mk
+Македонія mk
+Masedonia mk
+马其顿 mk
+馬其頓 mk
+Mali ml
+Малі ml
+Мали ml
+ຈົດຫມາຍ ml
+马里 ml
+Myanmar mm
+М'янма mm
+Майнмар mm
+Mjanmar mm
+Burma mm
+Birmania mm
+ຕົວຮງກພີື້ນທີ່ທຳງານ - K mm
+Mjanmar mm
+缅甸 mm
+Mongolia mn
+Манголія mn
+Монголия mn
+Mongolija mn
+Mongoliet mn
+Mongólia mn
+ລອກອິນ mn
+Mongólia mn
+Mongolsko mn
+Mongolija mn
+Mongoliet mn
+蒙古 mn
+Macau mo
+Макао mo
+Makau mo
+Macao mo
+Makaó mo
+ມອລຕາ mo
+Makao mo
+Macao mo
+澳门 mo
+Martinique mq
+Мартиника mq
+Martinik mq
+Martinica mq
+ເມົາລິ mq
+Martinik mq
+马提尼克岛 mq
+Mauritania mr
+Маўрытанія mr
+Мавритания mr
+Mauritanija mr
+Mauretanien mr
+Mauritánia mr
+ລິທົວເນີຍ mr
+Mauritânia mr
+Mavretanija mr
+Mauretanien mr
+毛里塔尼亚 mr
+Montserrat ms
+Монсерат ms
+Monsera ms
+ຈໍພາບ ms
+蒙特塞拉特岛 ms
+Malta mt
+مالطة mt
+Мальта mt
+Малта mt
+Μάλτα mt
+Malto mt
+مالت mt
+Malte mt
+מלטה mt
+Málta mt
+マルタ mt
+왈타 mt
+ມອລຕາ mt
+Мальта mt
+I-Malta mt
+Á¡ø¼¡ mt
+มอลตา mt
+Мальта mt
+Male mt
+马耳他 mt
+馬爾他 mt
+Mauritius mu
+Маўрыцы mu
+Маурици mu
+Mauricijus mu
+Mauricio mu
+ພາທິຊັ້ນ mu
+Maurícius mu
+Mavricij mu
+毛里求斯 mu
+Maldives mv
+Мальдывы mv
+Малдиви mv
+Maldivi mv
+Maldiverne mv
+Maldivas mv
+Maldív-szigetek mv
+ມັລດິສ mv
+Maldivas mv
+Maldiv mv
+Maldiverna mv
+马尔代夫 mv
+Malawi mw
+Малаві mw
+Малави mw
+Malavi mw
+ມອລຕາ mw
+马拉维 mw
+Mexico mx
+Meksiko mx
+المكسيك mx
+Meksika mx
+Мэксыка mx
+Мексико mx
+Mec'hiko mx
+Meksiko mx
+Mèxic mx
+Mexiko mx
+Mexiko mx
+Μεξικό mx
+Meksikujo mx
+México mx
+Mehhiko mx
+Mexiko mx
+مکزیک mx
+Meksiko mx
+Meksiko mx
+Mexique mx
+México mx
+מקסיקו mx
+Meksiko mx
+Mexikó mx
+Meksiko mx
+Mexíkó mx
+Messico mx
+メキシコ mx
+멕시코 mx
+ເມັກຊີໂກ mx
+Meksika mx
+Meksika mx
+Messiku mx
+Mèxic mx
+Meksyk mx
+México mx
+México mx
+Mexic mx
+Мексика mx
+Mexiko mx
+Mehika mx
+Meksiko mx
+I-Mexico mx
+¦Á캢§¸¡ mx
+เม็กซิโก mx
+Meksika mx
+Мексика mx
+Mê hi cô mx
+Mecsike mx
+墨西哥 mx
+墨西哥 mx
+Malaysia my
+Малайзыя my
+Малайзия my
+Malezija my
+Malasia my
+Malasia my
+Malajzia my
+ມອລຕາ my
+Malásia my
+Malajzia my
+Malezija my
+马来西亚 my
+Mozambique mz
+Мазамбік mz
+Мозамбик mz
+Mozambik mz
+Mozambik mz
+ຫນ່ວຍຄວາມຈຳ mz
+Moçambique mz
+Mozambik mz
+Mozambik mz
+Moçambique mz
+莫桑比克 mz
+Namibia na
+Намібія na
+Намибия na
+Namibija na
+Namíbia na
+ຈາໄມກາ na
+Namíbia na
+Namíbia na
+Namibija na
+纳米比亚 na
+New Caledonia nc
+Нова Каледония nc
+Nova Kaledonija nc
+Ny Caledonien nc
+Nueva Caledonia nc
+Kaledonia Berria nc
+Új-Kaledónia nc
+ມາເຊໂດເນີຍ nc
+Nova Caledônia nc
+Nová Kaledónia nc
+Nova Kaledonija nc
+Nya Caledonien nc
+新喀里多尼亚 nc
+Niger ne
+Нігер ne
+Нигер ne
+ຕົວຮງກພື້ນທີ່ທຳງານ ne
+Nigéria ne
+Nigéria ne
+尼日尔 ne
+Norfolk Island nf
+Остров Норфолк nf
+Norfolk ostrvo nf
+Norfolk-øerne (Australien) nf
+Isla Norfolk nf
+Norfok Irla nf
+Norfolk-szigetek nf
+ໂປແລນ nf
+Ilhas Norfolk nf
+Ostrov Norfolk nf
+Otok Norfolk nf
+Norfolkön nf
+诺福克岛 nf
+Nigeria ng
+Нігерыя ng
+Нигерия ng
+Nigerija ng
+Nigéria ng
+ບັນແກເລີຍ ng
+Nigéria ng
+Nigéria ng
+Nigerija ng
+尼日利亚 ng
+Nicaragua ni
+Nikaragua ni
+نيكاراغوا ni
+Нікарагуа ni
+Никарагуа ni
+Nikaragva ni
+Nikaragua ni
+Νικαράγουα ni
+Nikaraagua ni
+نیکاراگویه ni
+Nikaragua ni
+Nikaragua ni
+ניקרגווה ni
+ニカラグア ni
+니카라과 ni
+ປາລາກກວຍ ni
+Nikaragua ni
+Nikaragwa ni
+Nikaragua ni
+Nicarágua ni
+Nicarágua ni
+Никарагуа ni
+Nikaragua ni
+Nikaragva ni
+I-Nicaragua ni
+¿¢¸Ã¡Ì§Å ni
+Nikaragua ni
+Нікарагуа ni
+尼加拉瓜 ni
+尼加拉瓜 ni
+Netherlands nl
+Nederland nl
+هولندا nl
+Hollandiya nl
+Галяндыя nl
+Холандия nl
+Izelvroioù nl
+Nizozemska nl
+Holanda nl
+Nizozemí nl
+Holland nl
+Niederlande nl
+Κάτω Χώρες nl
+Nederlando nl
+Países Bajos nl
+Holland nl
+Holanda nl
+هلند nl
+Alankomaat nl
+Háland nl
+Pays bas nl
+Países Baixos nl
+הולנד nl
+Nizozemska nl
+Hollandia nl
+Belanda nl
+Holland nl
+Paesi Bassi nl
+オランダ nl
+네덜란드 nl
+ເນເທີແລນ์ nl
+Olandija nl
+Nīderlande nl
+Nederland nl
+Nederland nl
+Nederland nl
+Holanda nl
+Holandia nl
+Países Baixos nl
+Holanda nl
+Olanda nl
+Нидерланды nl
+Holandsko nl
+Nizozemska nl
+Holandija nl
+I-Netherlands nl
+Nederländerna nl
+¦¿¾÷Ä¡óÐ nl
+เนเธอร์แลนด์ nl
+Hollanda nl
+Голландія nl
+Hà Lan nl
+荷兰 nl
+荷蘭 nl
+Norway no
+Noorweë no
+النرويج no
+Norveç no
+Нарвэгія no
+Норвегия no
+Norvegia no
+Norveška no
+Noruega no
+Norsko no
+Norge no
+Norwegen no
+Νορβηγία no
+Norvegio no
+Noruega no
+Norra no
+Norvegia no
+نروژ no
+Norja no
+Norra no
+Norvège no
+Noruega no
+נורבגיה no
+Norveška no
+Norvégia no
+Norwegia no
+Noregur no
+Norvegia no
+ノルウェー no
+노르웨이 no
+ນໍເວ no
+Norvegija no
+Norvēģija no
+Norveġja no
+Norge no
+Noorwegen no
+Noreg no
+Noruega no
+Norwegia no
+Noruega no
+Noruega no
+Norvegia no
+Норвегия no
+Nórsko no
+Norveška no
+Norveška no
+I-Norway no
+Norge no
+¿¡÷§Å no
+นอร์เวย์ no
+Norveç no
+Норвегія no
+Na uy no
+挪威 no
+挪威 no
+Nepal np
+Нэпал np
+Непал np
+Nepál np
+ເວນດາ np
+尼泊尔 np
+Nauru nr
+Науру nr
+Науру nr
+Naurú nr
+ປາລາກກວຍ nr
+瑙鲁 nr
+Niue nu
+Ниуе nu
+ເນ໊ຕ nu
+纽埃岛 nu
+New Zealand nz
+Nuwe Seeland nz
+نيوزيلاندا nz
+Yeni Zellandiya nz
+Новая Зэляндыя nz
+Нова Зеландия nz
+Zeland nevez nz
+Novi Zeland nz
+Nova Zelanda nz
+Nový Zéland nz
+Neuseeland nz
+Νέα Ζηλανδία nz
+Novzelando nz
+Nueva Zelanda nz
+Uus-Meremaa nz
+Zelanda Berria nz
+زلاندنو nz
+Uusi-Seelanti nz
+Nýsæland nz
+Nouvelle Zélande nz
+Nova Celandia nz
+ניו זילנד nz
+Novi Zeland nz
+Új-Zéland nz
+Selandia Baru nz
+Nýja Sjáland nz
+Nuova Zelanda nz
+ニュージーランド nz
+뉴질랜드 nz
+ນີວຊີແລນ nz
+Naujoji Zelandija nz
+JaunZēlande nz
+Nieuw Zeeland nz
+Navera Zelanda nz
+Nowa Zelandia nz
+Nova Zelândia nz
+Nova Zelândia nz
+Noua Zeelandă nz
+Новая Зеландия nz
+Nový Zéland nz
+Nova Zelandija nz
+Novi Zeland nz
+I-New Zealand nz
+Nya Zeeland nz
+¿¢äº¢Ä¡óÐ nz
+นิวซีแลนด์ nz
+Yeni Zelanda nz
+Нова Зеландія nz
+Nouve Zelande nz
+新西兰 nz
+紐西蘭 nz
+Oman om
+عُمان om
+Аман om
+Оман om
+Omán om
+Ομάν om
+Omano om
+Omán om
+Omaan om
+عمان om
+עומן om
+Omán om
+オマーン om
+오만 om
+ເຍີຍລະມັນ om
+Omanas om
+Omã om
+Оман om
+Omán om
+I-Oman om
+µÁý om
+Umman om
+Оман om
+ Oman om
+阿曼 om
+阿曼 om
+Panama pa
+بنما pa
+Панама pa
+Панама pa
+Panamà pa
+Παναμάς pa
+Panamo pa
+Panamá pa
+پاناما pa
+Panamá pa
+פנמה pa
+パナマ pa
+파나마 pa
+ປານາມາ pa
+Panamá pa
+Panamá pa
+Панама pa
+I-Panama pa
+ÀÉ¡Á¡ pa
+ปานามา pa
+Панама pa
+巴拿马 pa
+巴拿馬 pa
+Peru pe
+البيرو pe
+Пэру pe
+Перу pe
+Perou pe
+Perú pe
+Περού pe
+Peruo pe
+Perú pe
+Peruu pe
+پرو pe
+Pérou pe
+Perú pe
+פרו pe
+Perú pe
+Perù pe
+ペルー pe
+페루 pe
+ເປລູ pe
+Perū pe
+Pero pe
+Perú pe
+Перу pe
+I-Peru pe
+¦ÀÕ pe
+เปรู pe
+Перу pe
+Perou pe
+秘鲁 pe
+秘魯 pe
+French Polynesia pf
+Француская Палінэзія pf
+Френска Полинезия pf
+Francuska Polinezija pf
+Fransk Polynesien pf
+Polinesia francesa pf
+Polinesia Frantziarra pf
+Francia-Polinézia pf
+ຝຣັ່ງເສດ pf
+Polinésia Francesa pf
+Francúzska Polynézia pf
+Francoska Polinezija pf
+Franska Polynesien pf
+法属波利尼西亚 pf
+Papua New Guinea pg
+Папуа–Новая Гвінэя pg
+Папуа и Нова Гвинея pg
+Papua Nova Gvineja pg
+Papua Nueva Guinea pg
+Papua Ginea Berria pg
+Pápua Új-Guinea pg
+ເທົາອ່ອນ pg
+Nova Guiné Papua pg
+Papua Nová Guinea pg
+Papua Nova Gvineja pg
+Papua Nya Guinea pg
+巴布亚新几内亚 pg
+Philippines ph
+Філіпіны ph
+Филипини ph
+Filipini ph
+Filippinerne ph
+Filipinas ph
+Filipinak ph
+Fülöp-szigetek ph
+ອາລະປະໂຫຍດ ph
+Filipinas ph
+Filipíny ph
+Filipini ph
+Filippinerna ph
+菲律宾 ph
+Pakistan pk
+Пакістан pk
+Пакистан pk
+Pakisztán pk
+ລງບ pk
+Paquistão pk
+巴基斯坦 pk
+Poland pl
+Poolland pl
+بولندا pl
+Polşa pl
+Польшча pl
+Полша pl
+Polonia pl
+Poljska pl
+Polònia pl
+Polsko pl
+Polen pl
+Polen pl
+Πολωνία pl
+Pollando pl
+Polonia pl
+Poola pl
+Polonia pl
+لهستان pl
+Puola pl
+Pólland pl
+Pologne pl
+Polonia pl
+פולין pl
+Poljska pl
+Lengyelország pl
+Polandia pl
+Pólland pl
+Polonia pl
+ポーランド pl
+폴란드 pl
+ໂປແລນ pl
+Lenkija pl
+Polija pl
+Polonja pl
+Polen pl
+Polen pl
+Polen pl
+Polònia pl
+Polska pl
+Polónia pl
+Polônia pl
+Polonia pl
+Польша pl
+Poľsko pl
+Poljska pl
+Poljska pl
+I-Poland pl
+Polen pl
+§À¡Ä¡óÐ pl
+โปแลนด์ pl
+Polonya pl
+Польща pl
+Pholandi pl
+Ba Lan pl
+Pologne pl
+波兰 pl
+波蘭 pl
+Saint Pierre and Miquelon pm
+Sveti Pjer i Migelon pm
+Saint Pierre og Miquelon pm
+Saint Pierre y Miquelon pm
+Saint Pierre eta Miquelon pm
+Saint Pierre és Miquelon pm
+Saint Pierre e Miquelon pm
+Saint Pierre a Miquelon pm
+Sveti Pierre in Miquelon pm
+Saint Pierre och Miquelon pm
+圣皮埃尔和密克隆岛 pm
+Pitcairn pn
+Pitkern pn
+ລງບ pn
+Puerto Rico pr
+Пуерто Рико pr
+Portoriko pr
+ໂປຣໂຕຄອນ pr
+Porto Rico pr
+Portoriko pr
+波多尼各 pr
+Palestinian Territory ps
+Palesteinse Gebied ps
+السلطة الفلسطينية ps
+Палестынская тэрыторыя ps
+Палестина ps
+Palestinska teritorija ps
+Territori Palestí ps
+Palestinské území ps
+Palæstinensiske selvstyreområder ps
+Palästinensisches Gebiet ps
+Παλαιστίνη ps
+Palestinaj teritorioj ps
+Territorio palestino ps
+Palestiina territoorium ps
+Palestina ps
+فلسطین ps
+Palestiinalaisalue ps
+Palestinensiska økið ps
+Territoire palestinien ps
+השטחים הפלסטיניים ps
+Palestinski teritorij ps
+Palesztin területek ps
+Territori palestinesi ps
+パレスチナ自治区 ps
+팔레스타인 자치구 ps
+ການພິມຜິດພາດ ps
+Palestinos teritorija ps
+Palestina ps
+Palestinske territorier ps
+Palestijns territorium ps
+Palestinske territorium ps
+Bohwa bja Palestina ps
+Palestyna ps
+Território Palestiniano ps
+Território Palestino ps
+Teritoriul Palestinian ps
+Палестинские территории ps
+Palestínske územia ps
+Palestinski teritorij ps
+I-Palestinian Territory ps
+Palestina ps
+À¡Äо£É ¬¨½Âõ ps
+Filistin Bölgesi ps
+Палестинська територія ps
+Mukano wa maphalesitina ps
+Palestene ps
+Umhlaba wePalestina ps
+巴勒斯坦地区 ps
+巴勒斯坦領地 ps
+Indawo yama-Phalesitina ps
+Portugal pt
+البرتغال pt
+Portuqaliya pt
+Партугалія pt
+Португалия pt
+Portugalsko pt
+Πορτογαλία pt
+Portugalo pt
+پرتغال pt
+Portugali pt
+פורטוגל pt
+Portugália pt
+Portúgal pt
+Portogallo pt
+ポルトガル pt
+포르투갈 pt
+ໂປຣຕຸເກສ pt
+Portugalija pt
+Portugāle pt
+Portugall pt
+Portugalia pt
+Portugalia pt
+Португалия pt
+Portugalsko pt
+Portugalska pt
+I-Portugal pt
+§À¡÷òиø pt
+โปรตุเกส pt
+Portekiz pt
+Португалія pt
+BềEĐào Nha pt
+葡萄牙 pt
+葡萄牙 pt
+Palau pw
+Палау pw
+Палау pw
+ມອລຕາ pw
+帕劳群岛 pw
+Paraguay py
+Paraguaai py
+باراغواي py
+Paraqvay py
+Парагвай py
+Парагвай py
+Paragvaj py
+Paraguai py
+Παραγουάη py
+Paragvajo py
+Paraguai py
+پاراگویه py
+Paraguai py
+פרגואי py
+Paragvaj py
+パラグアイ py
+파라과이 py
+ປາລາກກວຍ py
+Paragvajus py
+Paragvaja py
+Paragwaj py
+Paraguai py
+Paragwaj py
+Paraguai py
+Paraguai py
+Paraguai py
+Парагвай py
+Portugalsko py
+Paragvaj py
+Paragvaj py
+I-Paraguay py
+Àá̧Špy
+ปารากวัย py
+Парагвай py
+Paragway py
+巴拉圭 py
+巴拉圭 py
+Qatar qa
+قطر qa
+Катар qa
+Катар qa
+Katar qa
+Katar qa
+Katar qa
+Κατάρ qa
+Kataro qa
+Katar qa
+قطر qa
+Katar qa
+קטר qa
+Katar qa
+Katar qa
+カタール qa
+카타르 qa
+ມອລຕາ qa
+Katar qa
+Катар qa
+Katar qa
+Katar qa
+I-Qatar qa
+¸¾¡÷ qa
+Katar qa
+Катар qa
+卡塔尔 qa
+卡達 qa
+Romania ro
+Romenië ro
+رومانيا ro
+Rumıniya ro
+Румынія ro
+Румъния ro
+Roumania ro
+Rumunija ro
+Rumunsko ro
+Rumænien ro
+Rumänien ro
+Ρουμανία ro
+Rumanio ro
+Rumanía ro
+Rumeenia ro
+Errumania ro
+رومانی ro
+Rumenia ro
+Roumanie ro
+Romanía ro
+רומניה ro
+Rumunjska ro
+Románia ro
+Rumania ro
+Rúmenía ro
+ルーマニア ro
+루마니아 ro
+ໂລມາເນີຍ ro
+Rumunija ro
+Rumānija ro
+Rumanija ro
+Roemenië ro
+Rumunia ro
+Roménia ro
+Romênia ro
+Румыния ro
+Rumunsko ro
+Romunija ro
+Rumunija ro
+I-Romania ro
+Rumänien ro
+Õ§Áɢ¡ ro
+โรมาเนีย ro
+Romanya ro
+Румунія ro
+Ru ma ni ro
+Roumaneye ro
+罗马尼亚 ro
+羅馬尼亞 ro
+Russia ru
+Rusland ru
+روسيا ru
+Rusiya ru
+Расея ru
+Русия ru
+Rusia ru
+Rusija ru
+Rússia ru
+Rusko ru
+Rusland ru
+Russland ru
+Ρωσία ru
+Ruslando ru
+Rusia ru
+Venemaa ru
+Errusia ru
+روسیه ru
+Venäjä ru
+Russland ru
+Russie ru
+Rusia ru
+רוסיה ru
+Rusija ru
+Oroszország ru
+Rusia ru
+Rússland ru
+ロシア ru
+러시아 ru
+ລັດເຊີຍ ru
+Rusija ru
+Krievija ru
+Russja ru
+Russland ru
+Rusland ru
+Russland ru
+Rosja ru
+Rússia ru
+Rússia ru
+Rusia ru
+Россия ru
+Rusko ru
+Rusija ru
+Rusija ru
+I-Russia ru
+Ryssland ru
+ú¢Â¡ ru
+รัสเซีย ru
+Rusya ru
+Росія ru
+Rashia ru
+Nga ru
+Russeye ru
+Rashiya ru
+俄罗斯 ru
+俄羅斯 ru
+Rwanda rw
+Руанда rw
+Руанда rw
+Ruanda rw
+Ruanda rw
+Ruanda rw
+ແພນດ້າ rw
+Ruanda rw
+Ruanda rw
+卢旺达 rw
+Saudi Arabia sa
+Saudi Arabië sa
+السعودية sa
+Саудаўская Арабія sa
+Саудитска Арабия sa
+Saudijska Arabija sa
+Aràbia Saudí sa
+Saúdská Arábie sa
+Saudi Arabien sa
+Saudi-Arabien sa
+Σαουδική Αραβία sa
+Saŭdi-Arabio sa
+Arabia Saudí sa
+Saudi Araabia sa
+عربستان سعودی sa
+Saudi-Arabia sa
+Arabie Saoudite sa
+ערב הסעודית sa
+Saudijska Arabija sa
+Szaúd-Arábia sa
+Arabia saudita sa
+サウジアラビア sa
+사우디 아라비아 sa
+ອາລະບິກ sa
+Saudi Arabija sa
+Għarabja Sawdita sa
+Saudi-Arabia sa
+Saudi-Arabië sa
+Saudi-Arabia sa
+Arabia Saudyjska sa
+Arábia Saudita sa
+Arábia Saudita sa
+Arabia Saudită sa
+Саудовская Аравия sa
+Saudská arábia sa
+Saudova Arabija sa
+I-Saudi Arabia sa
+Saudiarabien sa
+º×¾¢ «§ÃÀ¢Â¡ sa
+Suudi Arabistan sa
+Саудівська Аравія sa
+沙特阿拉伯 sa
+沙烏地阿拉伯 sa
+Solomon Islands sb
+Саламонавы астравы sb
+Соломонови Острови sb
+Solomonska ostrva sb
+Salomon-øerne sb
+Islas Salomón sb
+Solomon Irlak sb
+Salamon-szigetek sb
+ສະໂລວະເນີຍ sb
+Ilhas Salomão sb
+Šalamúnove ostrovy sb
+Solomonovi otoki sb
+Salomonöarna sb
+所罗门群岛 sb
+Seychelles sc
+Сэйшэлы sc
+Сейшелски острови sc
+Sejšeli sc
+Seychellerne sc
+ເຊລ sc
+Sejšeli sc
+Seychellerna sc
+塞舌尔 sc
+Sudan sd
+السودان sd
+Судан sd
+Судан sd
+Sudán sd
+Σουδάν sd
+Sudano sd
+Sudán sd
+Sudaan sd
+سودان sd
+Sudania sd
+Soudan sd
+סודן sd
+Szudán sd
+Súdan sd
+スーダン sd
+수단 sd
+ຊູດານ sd
+Sudanas sd
+Sudāna sd
+Sudão sd
+Sudão sd
+Судан sd
+Sudán sd
+I-Sudan sd
+ݼ¡ý sd
+ซูดาน sd
+Судан sd
+Sudani sd
+Soudan sd
+苏丹 sd
+蘇丹 sd
+Sweden se
+Swede se
+السويد se
+İsveç se
+Швэцыя se
+Швеция se
+Sveden se
+Švedska se
+Suècia se
+Švédsko se
+Sverige se
+Schweden se
+Σουηδία se
+Svedio se
+Suecia se
+Rootsi se
+Suedia se
+سوید se
+Ruotsi se
+Svøriki se
+Suède se
+Suecia se
+שבדיה se
+Švedska se
+Svédország se
+Swedia se
+Svíþjóð se
+Svezia se
+スウェーデン se
+스웨덴 se
+ສະວີເດນ se
+Švedija se
+Zviedrija se
+Svezja se
+Sverige se
+Zweden se
+Sverige se
+Suècia se
+Szwecja se
+Suécia se
+Suécia se
+Suedia se
+Швеция se
+Švédsko se
+Švedska se
+Švedska se
+I-Sweden se
+Sverige se
+ÍÅ£¼ý se
+สวีเดน se
+İsveç se
+Швеція se
+Swidene se
+Thuỵ Điển se
+瑞典 se
+瑞典 se
+Singapore sg
+Сынгапур sg
+Сингапур sg
+Singapur sg
+Singapur sg
+Szingapúr sg
+ໂຊນາ sg
+Singapura sg
+Singapur sg
+Singapur sg
+新加坡 sg
+Saint Helena sh
+Свети Елена sh
+Sveta Helena sh
+St. Helena sh
+Santa Helena sh
+Szent Heléna sh
+ຫົວເລື່ອງ sh
+Santa Helena sh
+Svätá Helena sh
+Sveta Helena sh
+圣赫勒拿岛 sh
+Slovenia si
+Slovenië si
+سلوفينيا si
+Sloveniya si
+Славенія si
+Словения si
+Slovenija si
+Eslovenia si
+Slovinsko si
+Slovenien si
+Slowenien si
+Σλοβενία si
+Slovenio si
+Eslovenia si
+Sloveenia si
+Eslovenia si
+اسلوانی si
+Slovénie si
+Eslovenia si
+סלובניה si
+Slovenija si
+Szlovénia si
+Slóvenía si
+スロベニア si
+슬로베니아 si
+ສະໂລວະເນີຍ si
+Slovėnija si
+Slovēnija si
+Slovenja si
+Slovenië si
+Eslovenia si
+Słowenia si
+Eslovénia si
+Eslovênia si
+Словения si
+Slovinsko si
+Slovenija si
+Slovenija si
+I-Slovenia si
+Slovenien si
+ͧġŢɢ¡ si
+สโลเวเนีย si
+Slovenya si
+Словенія si
+斯洛文尼亚 si
+斯洛維尼亞 si
+Slovakia sk
+Slovakië sk
+سلوفاكيا sk
+Slovakiya sk
+Славакія sk
+Словакия sk
+Slovačka sk
+Eslovaquia sk
+Slovensko sk
+Slovakiet sk
+Slowakien sk
+Σλοβακία sk
+Slovakujo sk
+Eslovaquia sk
+Slovakkia sk
+Eslovakia sk
+اسلواکی sk
+Slovaquie sk
+סלובקיה sk
+Slovačka sk
+Szlovákia sk
+Slóvakía sk
+Slovacchia sk
+スロバキア sk
+슬로바키아 sk
+ສະໂລວັກ sk
+Slovakija sk
+Slovākija sk
+Slovakja sk
+Slovakije sk
+Słowacja sk
+Eslováquia sk
+Eslováquia sk
+Slovacia sk
+Словакия sk
+Slovensko sk
+Slovaška sk
+I-Slovakia sk
+Slovakien sk
+ͧġš츢 sk
+สโลวัค sk
+Slovakya sk
+Словакія sk
+斯洛伐克 sk
+斯洛伐克 sk
+San Marino sm
+Сан-Марына sm
+Сан Марино sm
+ໂຊນາ sm
+圣马力诺 sm
+Senegal sn
+Сэнэгал sn
+Сенегал sn
+Szenegál sn
+ທົ່ວໄປ sn
+塞内加尔 sn
+Somalia so
+Somalië so
+صومال so
+Самалі so
+Сомалия so
+Somalija so
+Somàlia so
+Somálsko so
+Σομαλία so
+Somalio so
+Somaalia so
+سومالی so
+Somalie so
+סומליה so
+Somalija so
+Szomália so
+ソマリア so
+소말리아 so
+ໂລມາເນີຍ so
+Somalis so
+Somalija so
+Somalie so
+Somália so
+Somália so
+Сомали so
+Somálsko so
+Somalija so
+I-Somalia so
+§º¡Á¡Ä¢Â¡ so
+Somali so
+Сомалі so
+Somaleye so
+索马里 so
+索馬利亞 so
+Suriname sr
+Сурынам sr
+Суринам sr
+Surinam sr
+ເຊີເບີຍ sr
+Surinam sr
+Surinam sr
+Surinam sr
+Sao Tome and Principe st
+Сан Томе и Приницпе st
+Sao Tome i Principe st
+Sao Tomé og Principe st
+Sao Tome y Príncipe st
+Sao Tome eta Principe st
+Sao Tome és Principe st
+ບໍລິການ st
+São Tome e Príncipe st
+Sao Tome a Principe st
+Sao Tome in Principe st
+São Tomé och Príncipe st
+El Salvador sv
+السلفادور sv
+Сальвадор sv
+Ел Салвадор sv
+Salvador sv
+Salvador sv
+Ελ Σαλβαντόρ sv
+Elsalvadoro sv
+Salvador sv
+السالوادور sv
+Salvador sv
+O Salvador sv
+אל סלבדור sv
+Salvador sv
+エルサルバドル sv
+엘살바도르 sv
+ເອລຊັນວາດດໍ sv
+Salvadoras sv
+Salvadora sv
+Salwador sv
+Salvador sv
+Сальвадор sv
+Salvádor sv
+Salvador sv
+I-El Salvador sv
+±ø º¡øÅ§¼¡÷ sv
+เอลซัลวาดอร์ sv
+Ель-Сальвадор sv
+萨尔瓦多 sv
+薩爾瓦多 sv
+Syria sy
+Sirië sy
+سوريا sy
+Сырыя sy
+Сирия sy
+Sirija sy
+Síria sy
+Sýrie sy
+Syrien sy
+Syrien sy
+Συρία sy
+Sirio sy
+Siria sy
+Süüria sy
+Siria sy
+سوریه sy
+Syyria sy
+Syrie sy
+סוריה sy
+Sirija sy
+Szíria sy
+Siria sy
+シリア sy
+시리아 sy
+ເຊີເບີຍ sy
+Sirija sy
+Siria sy
+Syrië sy
+Síria sy
+Síria sy
+Siria sy
+Сирия sy
+Sýria sy
+Sirija sy
+I-Syria sy
+Syrien sy
+º¢Ã¢Â¡ sy
+Suriye sy
+Сирія sy
+叙利亚 sy
+敘利亞 sy
+Swaziland sz
+Свазылэнд sz
+Свазиленд sz
+Svazilend sz
+Swazilandia sz
+Swazilandia sz
+Szváziföld sz
+ລາດສະນາຈັກໄທຍ sz
+Suécia sz
+Swazijsko sz
+Svazi sz
+斯威士兰 sz
+Turks and Caicos Islands tc
+Turks i Kaikos ostrva tc
+Turks- og Caicosøerne tc
+Islas Turcos y Caicos tc
+Turks eta Caicos Irlak tc
+Turks- és Caicos-szigetek tc
+Ilhas Caicos e Turca tc
+Turks a Caicos ostrovy tc
+Otoka Turks in Caicos tc
+Turks- och Caicosöarna tc
+特克斯和凯科斯群岛 tc
+Chad td
+Чад td
+Чад td
+Čad td
+Tchad td
+Txad td
+Csád td
+ເກມໄພ່ td
+Čad td
+Čad td
+Tchad td
+乍得 td
+Togo tg
+Тога tg
+Того tg
+ຂອງເລ່ນສະນຸກ tg
+多哥 tg
+Thailand th
+تايلاند th
+Tayland th
+Тайлянд th
+Тайланд th
+Tajland th
+Tailàndia th
+Thajsko th
+Ταϊλάνδη th
+Tajlando th
+Tailandia th
+Tai th
+Thailandia th
+تایلند th
+Thaimaa th
+Tailand th
+Thaïlande th
+Tailandia th
+תאילנד th
+Tajland th
+Thaiföld th
+Tæland th
+Tailandia th
+タイ th
+태국 (타이) th
+ລາດສະນາຈັກໄທຍ th
+Tailandas th
+Taivāna th
+Tajlandja th
+Tailandia th
+Tajlandia th
+Tailândia th
+Tailândia th
+Tailanda th
+Таиланд th
+Thajsko th
+Tajska th
+Tajland th
+I-Thailand th
+¾¡öÄ¡óÐ th
+ราชอาณาจักรไทย th
+Tayland th
+Таїланд th
+Thái Lan th
+Taylande th
+泰国 th
+泰國 th
+Tajikistan tj
+Таджыкістан tj
+Таджикистан tj
+Tadžikistan tj
+Tajikistán tj
+Tadzsikisztán tj
+ໃຕ້ຫວັນ tj
+Tajiquistão tj
+Tadžikistan tj
+Tadžikistan tj
+Tadzjikistan tj
+塔吉克斯坦 tj
+Tokelau tk
+Токелао tk
+ເບລາລັສ tk
+Turkmenistan tm
+Туркмэністан tm
+Туркменистан tm
+Turkmenistán tm
+Türkmenisztán tm
+ຕຸລະກີ tm
+Turquia tm
+土库曼斯坦 tm
+Tunisia tn
+Tunisië tn
+تونس tn
+Туніс tn
+Тунис tn
+Tunis tn
+Tuníssia tn
+Tunisko tn
+Tunesien tn
+Tunesien tn
+Τυνησία tn
+Tunisio tn
+Túnez tn
+Tuneesia tn
+تونس tn
+Tunesia tn
+Tunisie tn
+תוניסיה tn
+Tunis tn
+Tunézia tn
+チュニジア tn
+튀니지 tn
+ລັດເຊີຍ tn
+Tunisas tn
+Tuneżija tn
+Tunisie tn
+Tunezja tn
+Tunísia tn
+Tunísia tn
+Тунис tn
+Tunisko tn
+Tunizija tn
+I-Tunisia tn
+Tunisien tn
+ÐÉ¢º¢Â¡ tn
+Tunus tn
+Туніс tn
+突尼斯 tn
+突尼西亞 tn
+Tonga to
+Тонга to
+Тонга to
+ໂຊນາ to
+汤加 to
+East Timor tp
+Источен Тимур tp
+Istočni Timor tp
+Østtimor tp
+Timor oriental tp
+Ekialdeko Timor tp
+Kelet-Timor tp
+ວັນແລະເວລາ tp
+Timor Leste tp
+Východný Timor tp
+Vzhodni Timor tp
+Östtimor tp
+东帝汶 tp
+Turkey tr
+Turkeye tr
+تركيا tr
+Türkiyə tr
+Турцыя tr
+Турция tr
+Turkia tr
+Turska tr
+Turquia tr
+Turecko tr
+Tyrkiet tr
+Türkei tr
+Τουρκία tr
+Turkujo tr
+Turquía tr
+Türgi tr
+Turkia tr
+ترکیه tr
+Turkki tr
+Turkaland tr
+Turquie tr
+Turquía tr
+טורקיה tr
+Turska tr
+Törökország tr
+Turki tr
+Tyrkland tr
+Turchia tr
+トルコ tr
+터키 tr
+ຕຸລະກີ tr
+Turkija tr
+Turcija tr
+Turkija tr
+Tyrkia tr
+Turkije tr
+Tyrkia tr
+Turquia tr
+Turcja tr
+Turquia tr
+Turquia tr
+Turcia tr
+Турция tr
+Turecko tr
+Turčija tr
+Turska tr
+I-Turkey tr
+Turkiet tr
+ÐÕ츢 tr
+ตุรกี tr
+Türkiye tr
+Туреччина tr
+ThềENhĩ Kì tr
+土耳其 tr
+土耳其 tr
+Trinidad and Tobago tt
+Trinidad en Tobago tt
+ترينيداد و توباغو tt
+Trinidad və Tabaqo tt
+Трынідад і Табага tt
+Тринидад и Тобаго tt
+Trinidad ha Tobago tt
+Trinidad i Tobago tt
+Trinidad i Tobago tt
+Trinidad a Tobago tt
+Trinidad og Tobago tt
+Trinidad und Tobago tt
+Τρίνινταντ και Τομπάγκο tt
+Trinidado kaj Tobago tt
+Trinidad y Tobago tt
+Trinidad ja Tobago tt
+Trinidad eta Tobago tt
+ترینیداد و تُباگو tt
+Trinidad ja Tobago tt
+Trinidad og Tobago tt
+Trinidad et Tobago tt
+Trindade e Tobago tt
+טרינידד וטובגו tt
+Trinidad i Tobago tt
+Trinidad és Tobago tt
+Trinidad dan Tobago tt
+Trinidad og Tobago tt
+Trinidad e Tobago tt
+トリニダードトバコ tt
+트리니다드토바고 tt
+ຕີນິແດດແລະໂທບາໂກ tt
+Trinidadas ir Tobagas tt
+Trinidada un Tobago tt
+Trinidad u Tobago tt
+Trinidad og Tobago tt
+Trinidad en Tobago tt
+Trinidad og Tobago tt
+Trinidad le Tobago tt
+Trinidad e Tobago tt
+Trinidad i Tobago tt
+Trinidade e Tobago tt
+Trinidad e Tobago tt
+Trinidad şi Tobago tt
+Тринидад и Тобаго tt
+Trinidad a Tobago tt
+Trinidad in Tabago tt
+Trinidad i Tobago tt
+I-Trinidad kanye neTobago tt
+Trinidad och Tobago tt
+ðâɢ¼¡ð & ¦¼¡À¡§¸¡ tt
+ตรีนิแดดและโทบาโก tt
+Trinidad veTabago tt
+Республіка Трінідад та Тобаго tt
+Trinidad na Tobago tt
+Trinidad và Tobago tt
+Trinidad ne Tobago tt
+特里尼达和多巴哥 tt
+千里達及托貝哥 tt
+Trinidad knaye ne-Tobago tt
+Tuvalu tv
+Тувалу tv
+Тували tv
+ຊູລູ tv
+图瓦卢 tv
+Taiwan tw
+تايوان tw
+Tayvan tw
+Тайвань tw
+Тайван tw
+Tajvan tw
+Ταϊβάν tw
+Tajvano tw
+Taiwán tw
+Taivan tw
+تایوان tw
+Taivan tw
+Taïwan tw
+Taiwán tw
+טיוואן tw
+Tajvan tw
+Tajvan tw
+台湾 tw
+대만 tw
+ໃຕ້ຫວັນ tw
+Taivanis tw
+Taivāna tw
+Tajwan tw
+Tajwan tw
+Formosa tw
+Тайвань tw
+Tajvan tw
+Tajvan tw
+I-Taiwan tw
+¾¡öÅ¡ý tw
+ได้หวัน tw
+Tayvan tw
+Тайвань tw
+Đài Loan tw
+中国台湾 tw
+台灣 tw
+Tanzania, United Republic of tz
+Злучаная Рэспубліка Танзанія tz
+Танзания tz
+Tanzanija, Ujedinjena Republika tz
+Tanzania tz
+Tanzania, Republica de tz
+Tanazia, Errepublika Batua tz
+Tanzánia tz
+ໂດມິນິກັນ tz
+República da Tanzânia tz
+Tanzánia, Spojená republika tz
+Tanzanija, Združena republika tz
+Förenade republiken Tanzania tz
+坦桑尼亚 tz
+Ukraine ua
+Ukraïne ua
+أوكرانيا ua
+Ukrayna ua
+Украіна ua
+Украйна ua
+Ukraina ua
+Ukrajina ua
+Ucraïna ua
+Ukrajina ua
+Ουκρανία ua
+Ukrainio ua
+Ucrania ua
+Ukraina ua
+Ukrania ua
+اکراین ua
+Ukraina ua
+Ukraina ua
+Ucraína ua
+אוקראינה ua
+Ukrajina ua
+Ukrajna ua
+Ukraina ua
+Úkraína ua
+Ucraina ua
+ウクライナ ua
+우크라이나 ua
+ຍູເຄຣນ ua
+Ukraina ua
+Ukraina ua
+Ukranja ua
+Ukraina ua
+Oekraïne ua
+Ukraina ua
+Ucraina ua
+Ukraina ua
+Ucrânia ua
+Ucrânia ua
+Ucraina ua
+Украина ua
+Ukrajina ua
+Ukrajina ua
+Ukrajna ua
+I-Ukraine ua
+Ukraina ua
+¯ì¦Ãöý ua
+ยูเครน ua
+Ukrayna ua
+Україна ua
+Ukraina ua
+Ucrinne ua
+乌克兰 ua
+烏克蘭 ua
+Uganda ug
+Уганда ug
+Уганда ug
+ແພນດ້າ ug
+乌干达 ug
+United States of America us
+Vereenigde State van Amerika us
+الولايات المتحدة الأمريكية us
+Amerika Birləşmiş Ştatları us
+Злучаныя Штаты Амэрыкі us
+САЩ us
+Stadoù-Unanet Amerika us
+Sjedinjene Američke Države us
+Estats Units d'Amèrica us
+Spojené státy americké us
+USA us
+USA us
+Ην. Πολιτείες της Αμερικής us
+Usono us
+Estados Unidos de América us
+Ameerika Ühendriigid us
+Amerikako Estatu Batuak us
+ایالات متحده‌ی آمریکا us
+Yhdysvallat us
+Sambandsríki Amerika (USA) us
+États Unis d'Amérique us
+Estados Unidos de América us
+ארצות הברית us
+Sjedinjene Američke Države us
+Amerikai Egyesült Államok us
+Amerika Serikat us
+Bandaríki Norður Ameríku us
+Stati Uniti d'America us
+アメリカ us
+미 합중국 us
+ສະຫະລັດອາເມລິກາ us
+Jungtinės Amerikos Valstijos us
+Amerikas Savienotās Valstis us
+Stati Uniti us
+USA us
+Verenigde Staten van Amerika us
+USA us
+Estats Units d'Amèrica us
+Stany Zjednoczone Ameryki us
+Estados Unidos da América us
+Estados Unidos us
+Statele Unite ale Americii us
+Соединенные Штаты Америки us
+USA us
+Združene države Amerike us
+Sjedinjene američke države us
+I-United States of America us
+Amerikas förenta stater us
+³ì¸¢Â «¦ÁÃ¢ì¸ ¿¡Î¸û us
+สหรัฐอเมริกา us
+Amerika Birleşik Devletleri us
+США us
+mashango o tangananaho a America us
+Mĩ us
+United States ye Melika us
+美利坚合众国 us
+美利堅合眾國 us
+Uruguay uy
+الأوروغواي uy
+Uruqvay uy
+Уругвай uy
+Уругвай uy
+Urugvaj uy
+Uruguai uy
+Ουρουγουάη uy
+Urugvajo uy
+Uruguai uy
+اروگویه uy
+Uruguai uy
+אורוגואי uy
+Urugvaj uy
+ウルグアイ uy
+우루과이 uy
+ອຸລຸກກວຍ uy
+Urugvajus uy
+Urugvaja uy
+Urugwaj uy
+Uruguai uy
+Urugwaj uy
+Uruguai uy
+Uruguai uy
+Uruguai uy
+Уругвай uy
+Uruguaj uy
+Urugvaj uy
+Urugvaj uy
+I-Uruguay uy
+¯Õ̧Šuy
+อุรุกวัย uy
+Уругвай uy
+Ourougway uy
+乌拉圭 uy
+烏拉圭 uy
+Uzbekistan uz
+Узбэкістан uz
+Узбекистан uz
+Uzbekistán uz
+Üzbegisztán uz
+ເດນ່ງນ uz
+Uzbequistão uz
+乌兹别克斯坦 uz
+Vatican City va
+Ватыкан va
+Ватикана va
+Vatikan va
+Vatikanstaten va
+Vaticano va
+Batikano Hiria va
+Vatikán va
+ລັດເວີຍ va
+Cidade do Vaticano va
+Vatikán va
+Vatikan va
+Vatikanstaten va
+梵蒂冈 va
+St. Vincent and the Grenadines vc
+St. Vincent en die Grenadene vc
+سانت فينسنت و الغرينادين vc
+St. Vincent və Grenadines vc
+Сент-Винсент и Гренадине vc
+S. Visant hag ar Grenadinez vc
+Sveti Vincent i Grenadini vc
+St. Vincent i les Granadines vc
+St. Vincent a Grenadiny vc
+St. Vincent og Grenadinerne vc
+St. Vincent und Grenadinen vc
+St. Vincent kaj la Grenadinoj vc
+San Vicente y las Granadinas vc
+St. Vincent ja Grenadines vc
+St. Vincent eta Grenadines vc
+سن وینسن و گرادینس vc
+St. Vincent ja Grenadiinit vc
+Sankta Vinsent og Grenadinoyggjar vc
+St Vincent et les Grenadines vc
+San Vicente e as Granadinas vc
+סנט וינסנט והגרנדינים vc
+St. Vincent és Grenadines vc
+St. Vincent dan the Grenadines vc
+St. Vincent og Grenadines vc
+S. Vincent e the Grenadines vc
+セントヴィンセントグレナディン vc
+세인트 빈센트 그레나딘 vc
+ເຊີນວິນແຊນ ແລະເກນາດີນ vc
+Šv. Vincentas ir Grenadinai vc
+Sv. Vincents un Grenadīnes vc
+St. Vinċenz u l-Grenadini vc
+St. Vincent og Grenadinene vc
+St. Vincent en de Grenadines vc
+St. Vincent og Grenadinane vc
+St. Vincent le Grenadines vc
+St. Vincent e les Granadines vc
+St. Vincent i Grenadyny vc
+São Vicente e Grenadinas vc
+São Vicente e Grenadines vc
+Sf. Vincent şi Grenadines vc
+Сент-Винсент и Гренадины vc
+St. Vincent a Grenadines vc
+Sv. Vincent in Grenadini vc
+St. Vincent i Grenadine vc
+I-St. Vincent and the Grenadines vc
+St. Vincent och Grenadinerna vc
+¦ºÂ¢ýð Å¢ý¦ºýð & ¸¢¦ÃÉËý¸û vc
+เซนต์วินเซนต์ และ เกรนาดีน vc
+St. Vincent ve Grenadines vc
+Сент-Вінсент і Гренадіни vc
+St. Vincent na Grenadines vc
+St. Vincent và Grenadines vc
+St. Vincent ne Grenadines vc
+圣文森特和格林那达 vc
+聖文森及格納那丁 vc
+I-St. Vincent kanye ne-Grenadines vc
+Venezuela ve
+فنزويلا ve
+Вэнэсуэла ve
+Венецуела ve
+Venecuela ve
+Βενεζουέλα ve
+Venezuelo ve
+Venetsueela ve
+ونزویلا ve
+Venesuela ve
+Vénézuela ve
+ונצואלה ve
+Venecuela ve
+ベネズェラ ve
+베네수엘라 ve
+ເວເນຊຸເອລາ ve
+Venesuela ve
+Venecuēla ve
+Veneżwela ve
+Wenezuela ve
+Венесуэла ve
+Venecuela ve
+I-Venezuela ve
+¦ÅÉ¢ÍÅÄ¡ ve
+เวเนซูเอลา ve
+Венесуела ve
+委内瑞拉 ve
+委內瑞拉 ve
+Virgin Islands, British vg
+Вирджински Острови, Британски vg
+Djevičanska ostrva, Britanska vg
+Britiske jomfruøer vg
+Islas Vírgenes Británicas vg
+Irla Birjinak, Britaniar vg
+Virgin-szigetek (brit) vg
+Ilhas Virgens, Inglaterra vg
+Panenské Ostrovy, Britské vg
+Deviški otoki, Britanski vg
+Brittiska Jungfruöarna vg
+维尔京群岛,英国 vg
+Virgin Islands, U.S. vi
+Вирджински Острови, Американски vi
+Djevičanska ostrva, Američka vi
+Jomfruøerne vi
+Islas Vírgenes Americanas vi
+Irla Birjinak, EE.BB. vi
+Virgin-szigetek (USA) vi
+Ilhas Virgens, EUA vi
+Panenské Ostrovy, Americké vi
+Deviški otoki, ZDA vi
+Amerikanska Jungfruöarna vi
+维尔京群岛,美国 vi
+Vietnam vn
+Viëtnam vn
+فييتنام vn
+Vyetnam vn
+Віетнам vn
+Виетнам vn
+Vijetnam vn
+Βιετνάμ vn
+Vjetnamo vn
+ویتنام vn
+וייטנאם vn
+Vijetnam vn
+Víetnam vn
+ベトナム vn
+베트남 vn
+ຫວງດນາມ vn
+Vietnamas vn
+Vjetnama vn
+Vjetnam vn
+Viëtnam vn
+Wietnam vn
+Vietname vn
+Vietnã vn
+Вьетнам vn
+I-Vietnam vn
+เวียตนาม vn
+В'єтнам vn
+越南 vn
+越南 vn
+Vanuatu vu
+Вануату vu
+Ванути vu
+ຈີນ vu
+瓦努阿图 vu
+Wallis and Futuna wf
+Valis i Futuna wf
+Wallis- og Futuna-øerne wf
+Wallis y Futuna wf
+Wallis eta Futuna wf
+Wallis és Futuna wf
+ປັກອິນພາບ wf
+Wallis e Futuna wf
+Wallis a Futuna wf
+Wallis in Futuna wf
+Wallis och Futuna wf
+Samoa ws
+Самоа ws
+Самоя ws
+Szamoa ws
+ໂຊນາ ws
+萨摩亚群岛 ws
+Yemen ye
+اليمن ye
+Емен ye
+Йемен ye
+Jemen ye
+Iemen ye
+Jemen ye
+Jemen ye
+Υεμένη ye
+Jemeno ye
+Jeemen ye
+یمن ye
+Jemen ye
+Jemen ye
+תימן ye
+Jemen ye
+Jemen ye
+イエメン ye
+예멘 ye
+ເດມອນ ye
+Jemenas ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Iémen ye
+Йемен ye
+Jemen ye
+Jemen ye
+I-Yemen ye
+Jemen ye
+§ÂÁý ye
+Ємен ye
+也门 ye
+葉門 ye
+Yugoslavia yu
+Югаславія yu
+Югославия yu
+Jugoslavija yu
+Jugoslavien (Serbien/Montenegro) yu
+Jugoszlávia yu
+ໂບລິເວີຍ yu
+Iugoslávia yu
+Juhoslávia yu
+Jugoslavija yu
+Jugoslavien yu
+南斯拉夫 yu
+South Africa za
+Suid Afrika za
+جنوب أفريقيا za
+Cənubi Afrika za
+Паўднёвая Афрыка za
+Южна Африка za
+Suafrika za
+Južna Afrika za
+Sudàfrica za
+Jižní Afrika za
+Sydafrikanske republik za
+Südafrika za
+Νότια Αφρική za
+Sudafriko za
+Sudáfrica za
+Lõuna Aafrika za
+Hego Afrika za
+آفریقای جنوبی za
+Etelä-Afrikka za
+Suðurafrika za
+Afrique du sud za
+África do Sur za
+דרום אפריקה za
+Južna Afrika za
+Dél-Afrika za
+Afrika Selatan za
+Suður Afríka za
+Sud Africa za
+南アフリカ za
+남 아프리카 공화국 za
+ແອບພິກາໃຕ້ za
+Pietų Afrika za
+Dienvid Āfrika za
+Afrika t'Isfel za
+Sør-Afrika za
+Zuid-Afrika za
+Sør-Afrika za
+Afrika Borwa za
+Sudafrica za
+Afryka Południowa za
+Africa do Sul za
+África do Sul za
+Africa de Sud za
+Южная Африка za
+Južná Afrika za
+Južna Afrika za
+Južna Afrika za
+I-South Africa za
+Sydafrika za
+¦¾ý ¬ôâ측 za
+แอฟริกาใต้ za
+Güney Afrika za
+Південна Африка za
+Afurika tshipembe za
+Nam Phi za
+Mzantsi Afrika za
+南非 za
+南非 za
+Emzantsi Afrika za
+Zambia zm
+Замбія zm
+Замбия zm
+ຈາໄມກາ້ zm
+Zâmbia zm
+Zambija zm
+赞比亚 zm
+Zimbabwe zw
+Зымбабвэ zw
+Зимбабве zw
+Zimbabve zw
+ລິຊາ zw
+Zimbabve zw
+津巴布韦 zw
+Andorra ad
+Андора ad
+Андора ad
+Andora ad
+ອີນເດີຍ ad
+Andora ad
+Андорра ad
+安道尔 ad
+United Arab Emirates ae
+Vereenigde Arabiese Emirate ae
+الإمارات العربية المتحدة ae
+Злучаныя Арабскія Эміраты ae
+Обединени Арабски Емирства ae
+Ujedinjeni arapski emirati ae
+Emirats Àrabs Units ae
+Spojené arabské emiráty ae
+Forenende Arabiske Emirater ae
+Vereinigte Arabische Emirate ae
+Ενωμένα Αραβικά Εμιράτα ae
+Emiratos árabes unidos ae
+Araabia Ühendemiraadid ae
+Arabiar Emirato Batuak ae
+امارات متحده عربی ae
+Yhdistyneet Arabiemiraatit ae
+Émirats Arabes Unis ae
+איחוד האמירויות הערביות ae
+Ujedinjeni arapski emirati ae
+Egyesült Arab Emirátusok ae
+Emirati arabi uniti ae
+アラブ首長国連邦 ae
+아랍 에미레이트 연합 ae
+ສະຫະລັດ ae
+Jungtiniai Arabų Emiratai ae
+Emirati Għarab Magħquda ae
+De forente arabiske emirater ae
+Verenigde Arabische Emiraten ae
+Dei sameinte arabiske emirata ae
+Di-Emirate tseo di Kopanego tsa Arab ae
+Zjednoczone Emiraty Arabskie ae
+Emiratos Árabes Unidos ae
+Emirados Árabes ae
+Emiratele Arabe Unite ae
+Объединенные Арабские Эмираты ae
+Spojené arabské emiráty ae
+Združeni arabski Emirati ae
+Förenade arabemiraten ae
+³ì¸¢Â «ÃÒ ¿¡Î¸û ae
+Birleşik Arap Emirlikleri ae
+Об'єднані Арабські Емірати ae
+Mashango o tangananaho a Emirates ae
+阿拉伯联合酋长国 ae
+阿拉伯聯合大公國 ae
+Izindawo zezinduna zase-United Arab ae
+Afghanistan af
+Афганістан af
+Афганистан af
+Afganistan af
+Afghanistán af
+Afganisztán af
+ລີທົ່ວເນີຍ af
+Afeganistão af
+Afganistan af
+Afganistan af
+Afganistan af
+Афганістан af
+阿富汗 af
+Antigua and Barbuda ag
+Antigue en Barbuda ag
+أنتيغوا و باربودا ag
+Antigua və Barbuda ag
+Антыгуа і Барбуда ag
+Антигуа и Барбадос ag
+Antigua ha Barbuda ag
+Antigua i Barbuda ag
+Antigua i Barbuda ag
+Antigua a Barbuda ag
+Antigua og Barbuda ag
+Antigua und Barbuda ag
+Antigua και Barbuda ag
+Antigvo kaj Barbudo ag
+Antigua y Barbuda ag
+Antigua ja Barbuda ag
+Antigua eta Barbuda ag
+آنتیگوا و باربودا ag
+Antigua ja Barbados ag
+Antigua og Barbuda ag
+Antigua et Barbuda ag
+Antiga e Barbuda ag
+אנטיגואה וברבודה ag
+Antigua i Barbuda ag
+Antigua és Barbuda ag
+Antigua dan Barbuda ag
+Antigúa og Barbúda ag
+Antigua e Barbuda ag
+アンティグアバーブーダ ag
+앤티가 바부다 ag
+Antikva ir Barbuda ag
+Antigva un Barbudas ag
+Antigwa u Barbuda ag
+Antigua og Barbuda ag
+Antigua en Barbuda ag
+Antigua og Barbuda ag
+Antigua le Barbuda ag
+Antigua e Barbuda ag
+Antigua i Barbuda ag
+Antigua e Barbuda ag
+Antigua e Barbuda ag
+Antigua şi Barbuda ag
+Антигуа и Барбадос ag
+Antigua a Barbuda ag
+Antigva in Barbuda ag
+Antigua i Barbuda ag
+I-Antigua kanye ne Barbuda ag
+Antigua och Barbuda ag
+¬ýÊÌÅ¡ & À¡÷Ò¼¡ ag
+Antigua ve Barbuda ag
+Трінідад та Тобаго ag
+Antigua và Barbuda ag
+Antigua eyet Barbuda ag
+Antigua ne Barbuda ag
+安地瓜岛和巴布达岛 ag
+安地瓜島和巴布達島 ag
+Antigua kanye ne-Barbuda ag
+Anguilla ai
+Ангуила ai
+ແພນວິນ ai
+Angvila ai
+Ангілья ai
+安圭拉 ai
+Albania al
+Альбанія al
+Албания al
+Albanija al
+Albanien al
+Albánia al
+ແອດແລນຕິກ al
+Albânia al
+Albánsko al
+Albanija al
+Albanien al
+Албанія al
+阿尔巴尼亚 al
+Armenia am
+Армэнія am
+Армения am
+Armenija am
+Armenien am
+Örményország am
+ອາເຈນຕິນາ am
+Armênia am
+Arménsko am
+Armenija am
+Armenien am
+Арменія am
+亚美尼亚 am
+Netherlands Antilles an
+Холандски Антили an
+Nizozemski Antili an
+Nederlandske antiller an
+Antillas holandesas an
+Antilla Holandarrak an
+Holland-Antillák an
+ເນເທີແລນ an
+Antilhas an
+Holandské Antily an
+Nizozemski Antili an
+Nederländska Antillerna an
+Голландські Антилли an
+荷属安的列斯群岛 an
+Angola ao
+Ангола ao
+Ангола ao
+ບັນແກເລີຍ ao
+Ангола ao
+安哥拉 ao
+Argentina ar
+Argentinië ar
+الأرجنتين ar
+Аргентына ar
+Аржентина ar
+Arc'hantina ar
+Argentinien ar
+Αργεντινή ar
+Argentino ar
+Argentiina ar
+آرژانتین ar
+Agentiina ar
+Argentine ar
+Arxentina ar
+ארגנטינה ar
+Argentína ar
+Argentína ar
+アルゼンチン ar
+아르헨티나 ar
+ອາເຈນຕິນາ ar
+Argentīna ar
+Arġentina ar
+Argentinië ar
+Argentyna ar
+Аргентина ar
+Argentína ar
+I-Argentina ar
+¬÷¦ºƒýÊÉ¡ ar
+อาร์เจนตินา ar
+Arjantin ar
+Аргентина ar
+Agenthina ar
+Årdjintene ar
+阿根廷 ar
+阿根廷 ar
+American Samoa as
+Амэрыканскае Самоа as
+Американска Самоа as
+Američka Samoa as
+Samoa (USA) as
+Samoa americana as
+Amerikako Samoa as
+Amerikai Szamoa as
+ອາເມລິກາເຫນືອ as
+Samoa Americana as
+Americká Samoa as
+Ameriška Samoa as
+Amerikanska Samoa as
+Американське Самоа as
+美属萨摩亚群岛 as
+Austria at
+Oostenryk at
+النمسا at
+Avstriya at
+Аўстрыя at
+Австрия at
+Aostria at
+Austrija at
+Àustria at
+Rakousko at
+Østrig at
+Österreich at
+Αυστρία at
+Aŭstrio at
+اتریش at
+Itävalta at
+Eysturríki at
+Autriche at
+אוסטריה at
+Austrija at
+Ausztria at
+Austurríki at
+オーストリア at
+오스트리아 at
+ອອດສະເຕເລີຍ at
+Austrija at
+Austrija at
+Awtrija at
+Østerrike at
+Oostenrijk at
+Austerrike at
+Áustria at
+Áustria at
+Австрия at
+Rakúsko at
+Avstrija at
+Austrija at
+I-Austria at
+Österrike at
+¬Íò¾¢Ã¢Â¡ at
+ออสเตรีย at
+Avusturya at
+Австрія at
+Ositiria at
+A'o at
+Ôtriche at
+奥地利 at
+奧地利 at
+Australia au
+Australië au
+أستراليا au
+Avustralya au
+Аўстралія au
+Австралия au
+Aostralia au
+Australija au
+Austràlia au
+Austrálie au
+Australien au
+Australien au
+Αυστραλία au
+Aŭstralio au
+Austraalia au
+استرالیا au
+Australie au
+אוסטרליה au
+Australija au
+Ausztrália au
+Ástralía au
+オーストラリア au
+오스트레일리아 au
+ອອດສະເຕເລີຍ au
+Australija au
+Austrālija au
+Awstralja au
+Australië au
+Austrália au
+Austrália au
+Австралия au
+Austrália au
+Avstralija au
+Australija au
+I-Australia au
+Australien au
+¬ŠÍò¾¢§ÃĢ¡ au
+ออสเตรเลีย au
+Avusturalya au
+Австралія au
+Ositiralia au
+U'c au
+Ôstraleye au
+澳大利亚 au
+澳大利亞 au
+Aruba aw
+Аруба aw
+ເກມໄັພ່ aw
+Аруба aw
+阿鲁巴岛 aw
+Azerbaijan az
+أذربيجان az
+Azərbaycan az
+Азэрбайджан az
+Азарбайджан az
+Azerbejdžan az
+Azerbaitjan az
+Ázerbajdžánský az
+Azerbajdjan az
+Aserbaidschan az
+Αζερμπαϊτζάν az
+Azerbajĝana az
+Azerbaiján az
+Aserbaidžaan az
+آذربایجان az
+Azerbaidzan az
+Aserbadsjan az
+אזרביג'ן az
+Azerbejdžan az
+Azerbajdzsán az
+Azerbaigian az
+アゼルバイジャン az
+아제르바이잔 az
+ອາເຊີໄບຈັນ az
+Azerbaidžanas az
+Azerbaidžāņu az
+Ażerbajġan az
+Aserbajdsjan az
+Azerbeidjan az
+Aserbajdsjan az
+Azerbejdżan az
+Azerbaijão az
+Turco az
+Azerbadjan az
+Азербайджан az
+Ázerbajdžánsky az
+Azerbajdžan az
+Azerbejdžan az
+I-Azerbaijan az
+«º÷¨Àº¡ý az
+อาร์เซอร์ไบจัน az
+Azerice az
+Азербайджан az
+Azerbaydjan az
+阿塞拜疆 az
+亞塞拜然 az
+Bosnia and Herzegovina ba
+Bosnië en Herzegovina ba
+البوسنا و الهرسك ba
+Босьнія і Герцагавіна ba
+Боснена и Херцеговина ba
+Bosna i Hercegovina ba
+Bòsnia i Hercegovina ba
+Bosna a Herzegovina ba
+Bosnien-Herzegovina ba
+Bosnien und Herzegowina ba
+Βοσνία και Ερζεγοβίνη ba
+Bosnio kaj Hercegovino ba
+Bosnia y Herzegovina ba
+Bosnia ja Hertsegovina ba
+Bosnia eta Herzegovina ba
+بوسنی و هرزگوین ba
+Bosnia ja Herzegovina ba
+Bosnia-Herzegovina ba
+Bosnie herzégovine ba
+בוסניה הרצגובינה ba
+Bosna i Hercegovina ba
+Bosznia-Hercegovina ba
+Bosnia e Erzegovina ba
+ボスニアヘルツェゴビナ ba
+보스니아어와 헤르체고비나 ba
+ບອສເນີຍ ແລະ ເຫີເຊີໂກວິນາ ba
+Bosnija ir Hercegovina ba
+Bosnija un Hercogovina ba
+Bożnia u Ħerżegovina ba
+Bosnia-Hercegovina ba
+Bosnië en Herzegovina ba
+Bosnia-Hercegovina ba
+Bosnia le Herzegovina ba
+Bośnia i Hercegowina ba
+Bósnia e Herzegovina ba
+Bósnia Herzegóvina ba
+Bosnia şi Herţegovina ba
+Босния и Герцеговина ba
+Bosna a Hercegovina ba
+Bosna in Hercegovina ba
+I-Bosnia kanye ne Herzegovina ba
+Bosnien och Herzegovina ba
+¦À¡Íɢ¡ ba
+บอสเนีย และ เฮอร์เซโกวินา ba
+Bosna Hersek ba
+Боснія та Герцеговина ba
+Mubosinia na Muhezegovina ba
+Bosneye ba
+Bosnia ne Herzegovina ba
+波斯尼亚和黑塞哥维那 ba
+波士尼亞與赫塞哥維納 ba
+Bosnia kanye ne-Herzegovina ba
+Barbados bb
+بربادوس bb
+Барбадос bb
+Барбадос bb
+Μπαρμπάντος bb
+Babadoso bb
+باربادوس bb
+Barbade bb
+ברבדוס bb
+バルバドス bb
+바르바도스 bb
+ບາລບາດອດສ bb
+Barbadosas bb
+Barbadosa bb
+Барбадос bb
+I-Barbados bb
+À¡÷§À¼¡Í bb
+บาร์บาดอส bb
+Барбадос bb
+Barbades bb
+巴巴多斯 bb
+巴貝多 bb
+Bangladesh bd
+بنغلاديش bd
+Banqladeş bd
+Банглядэш bd
+Бангладеш bd
+Bangladeš bd
+Bangladéš bd
+Bangladesch bd
+Μπαγκλαντές bd
+Bangladeŝo bd
+بنگلادش bd
+בנגלדש bd
+Bangladeš bd
+Banglades bd
+バングラデシュ bd
+방글라데시 bd
+ບັງຄະລາເທດ bd
+Bangladešas bd
+Bangladeša bd
+Bangladexx bd
+Bangladesz bd
+Banglade bd
+Бангладеш bd
+Bangladéš bd
+Bangladeš bd
+I-Bangladesh bd
+Àí¸Ç¡§¾Í bd
+บังคลาเทศ bd
+Bangladeş bd
+Бангладеш bd
+孟加拉 bd
+孟加拉 bd
+Belgium be
+België be
+بلجيكا be
+Belçika be
+Бэльгія be
+Белгия be
+Belgia be
+Belgija be
+Bèlgica be
+Belgie be
+Belgien be
+Belgien be
+Βέλγιο be
+Belgio be
+Bélgica be
+Belgia be
+Belgika be
+بلژیک be
+Belgia be
+Belgia be
+Belgique be
+Bélxica be
+בלגיה be
+Belgija be
+Belgia be
+Belgía be
+Belgio be
+ベルギー be
+벨기에 be
+ເບລຢ່ງມ be
+Belgija be
+Beļģija be
+Belġju be
+Belgia be
+België be
+Belgia be
+Bèlgica be
+Belgia be
+Bélgica be
+Bélgica be
+Belgia be
+Бельгия be
+Belgicko be
+Belgija be
+Belgija be
+I-Belgium be
+Belgien be
+¦Àøº¢Âõ be
+เบลเยียม be
+Belçika be
+Бельгія be
+Beljike be
+比利时 be
+比利時 be
+Burkina Faso bf
+Буркіна Фасо bf
+Буркина Фаско bf
+ຕຸລະກີ bf
+Буркіна Фасо bf
+布基纳法索 bf
+Bulgaria bg
+Bulgarye bg
+بلغاريا bg
+Bolgarıstan bg
+Баўгарыя bg
+България bg
+Bugarska bg
+Bulgària bg
+Bulharsko bg
+Bulgarien bg
+Bulgarien bg
+Βουλγαρία bg
+Bulgario bg
+Bulgaaria bg
+بلغارستان bg
+Bulgarie bg
+בולגריה bg
+Bugarska bg
+Bulgária bg
+Búlgaría bg
+ブルガリア bg
+불가리아 bg
+ບັນແກເລີຍ bg
+Bulgarija bg
+Bulgārija bg
+Bulgarija bg
+Bulgarije bg
+Bułgaria bg
+Bulgária bg
+Bulgária bg
+Болгария bg
+Bulharsko bg
+Bolgarija bg
+Bugarska bg
+I-Bulgaria bg
+Bulgarien bg
+Àø§¸Ã¢Â¡ bg
+บัลแกเรีย bg
+Bulgaristan bg
+Болгарія bg
+Baligaria bg
+Bulgåreye bg
+保加利亚 bg
+保加利亞 bg
+Bahrain bh
+البحرين bh
+Бахрэйн bh
+Бахрейн bh
+Bahrein bh
+Bahrajn bh
+Μπαχρέιν bh
+Bahrein bh
+Bahrein bh
+بحرین bh
+בחריין bh
+バーレーン bh
+바레인 bh
+ຖັກກ່ງວ bh
+Bahreinas bh
+Baħrain bh
+Baghrein bh
+Bahrajn bh
+Bahamas bh
+Bahrein bh
+Бахрейн bh
+Bahrajn bh
+Bahrajn bh
+I-Bahrain bh
+Bahrein bh
+À‹¨Ãý bh
+Bahreyn bh
+Бахрейн bh
+巴林 bh
+巴林 bh
+Burundi bi
+Бурундзі bi
+Бурунди bi
+ເຄອຣດ bi
+Бурунді bi
+布隆迪 bi
+Benin bj
+Бэнін bj
+Бенин bj
+ບອສເນີຍ bj
+Бенін bj
+贝宁 bj
+Bermuda bm
+Бэрмуды bm
+Бермуда bm
+ເຍລລະມັນ bm
+Bermudy bm
+Bermudi bm
+Бермуди bm
+百慕大 bm
+Brunei Darussalam bn
+Брунэй bn
+Бруней bn
+Brunei bn
+Brunei Szultánság bn
+ເບລາລັສເຊີຍ bn
+Brunei bn
+Brunei Darusalam bn
+Бруней Даруссалам bn
+Bolivia bo
+Bolivië bo
+بوليفيا bo
+Boliviya bo
+Балівія bo
+Боливия bo
+Bolivija bo
+Bolívia bo
+Bolívie bo
+Bolivien bo
+Βολιβία bo
+Bolivio bo
+Boliivia bo
+بولیوی bo
+Bolivie bo
+בוליביה bo
+Bolivija bo
+Bolívia bo
+Bólivía bo
+ボリビア bo
+볼리비아 bo
+ໂບລີເວີຍ bo
+Bolivija bo
+Bolīvija bo
+Bolivja bo
+Boliwia bo
+Bolívia bo
+Bolívia bo
+Боливия bo
+Bolívia bo
+Bolivija bo
+Bolivija bo
+I-Bolivia bo
+¦À¡Ä¢Å¢Â¡ bo
+โบลิเวีย bo
+Bolivya bo
+Болівія bo
+Boliveye bo
+波利维亚 bo
+玻利維亞 bo
+Brazil br
+Brazilië br
+البرازيل br
+Braziliya br
+Бразылія br
+Бразилия br
+Brasil br
+Brazílie br
+Brasilien br
+Brasilien br
+Βραζιλία br
+Brazilo br
+Brasil br
+Brasiilia br
+Brasil br
+برزیل br
+Brasilia br
+Brésil br
+Brasil br
+ברזיל br
+Brazília br
+Brasilía br
+Brasile br
+ブラジル br
+브라질 br
+ບາຊີລ br
+Brazilija br
+Brazīlija br
+Brażil br
+Brasil br
+Brazilië br
+Brasil br
+Brasil br
+Brazylia br
+Brasil br
+Brasil br
+Brazilia br
+Бразилия br
+Brazília br
+Brazilija br
+I-Brazil br
+Brasilien br
+À¢§Ãº¢ø br
+บราซิล br
+Brezilya br
+Бразилія br
+Burazili br
+Braezi br
+巴西 br
+巴西 br
+Bahamas bs
+Багамы bs
+Бахами bs
+Bahami bs
+Bahamák bs
+ປານາມາ bs
+Bahamy bs
+Bahami bs
+Багами bs
+巴哈马 bs
+Bhutan bt
+Бутан bt
+Бутан bt
+Butan bt
+Bhután bt
+Bhután bt
+ຖັກກ່ງວ bt
+Butan bt
+Бутан bt
+不丹 bt
+Botswana bw
+Батсвана bw
+Боцвана bw
+Bocvana bw
+ບອດສເນີຍ bw
+Botsvana bw
+Ботсвана bw
+博茨瓦纳 bw
+Belarus by
+روسيا البيضاء by
+Беларусь by
+Беларус by
+Bjelorusija by
+Bělorusko by
+Hviderusland by
+Weißrussland by
+Bjelorusio by
+Valgevene by
+بلاروس by
+Valkovenäjä by
+Hvítarusland by
+Bélarus by
+בלרוס by
+Bjelorusija by
+Fehéroroszország by
+Hvíta-Rússland by
+Bielorussia by
+ベラルーシ by
+벨라루스 by
+ເບລາລັສ by
+Baltarusija by
+Baltkrievu by
+Hviterussland by
+Wit-Rusland by
+Kviterussland by
+Białoruś by
+Bielorússia by
+Bielorusso by
+Беларусь by
+Bielorusko by
+Belorusija by
+I-Belarus by
+Vitryssland by
+¦ÀÄ¡åÍ by
+เบลารัส by
+Білорусія by
+Belaruss by
+白俄罗斯 by
+白俄羅斯 by
+Belize bz
+Бэлізе bz
+Белиз bz
+ເບລຍ່ງມ bz
+Беліз bz
+伯利兹 bz
+Default C
+Verstek C
+افتراضي C
+Əsas C
+Па ўмаўчаньні C
+По подразбиране C
+Dre ziouer C
+Omissió C
+Výchozí C
+Standard C
+Standard C
+Προκαθορισμένο C
+Apriora C
+Predeterminado C
+Vaikimisi C
+Aurremugatua C
+پیش‌فرض C
+Oletus C
+Forsettur C
+Par défaut C
+Por Omisión C
+ברירת מחדל C
+Uobičajeno C
+Alapértelmezett C
+Standar C
+Sjálfgefið C
+Predefinito C
+標準 C
+기본 C
+ຄ່າປະລິຍາຍ C
+Nutylima C
+Noklusētais C
+Normali C
+Standard C
+Standaard C
+Standard C
+Thuso ya Tshoganetso C
+Omission C
+Domyślnie C
+Por Omissão C
+Padrão C
+Implicit C
+По умолчанию C
+Štandardný C
+Privzeto C
+Predefinisano C
+Förval C
+¦¸¡¼¡¿¢¨Ä C
+ค่าปริยาย C
+Öntanımlı C
+Типовий C
+Mặc định C
+Prémetou C
+Okwendalo C
+默认 C
+預設 C
+Okwendalo C
+Canada ca
+Kanada ca
+كندا ca
+Kanada ca
+Канада ca
+Канада ca
+Kanada ca
+Kanada ca
+Canadà ca
+Kanada ca
+Kanada ca
+Καναδάς ca
+Kanado ca
+Canadá ca
+Kanada ca
+Kanada ca
+کانادا ca
+Kanada ca
+Kanada ca
+Canadá ca
+קנדה ca
+Kanada ca
+Kanada ca
+Kanada ca
+Kanada ca
+カナダ ca
+캐나다 ca
+ແຄນາດາ ca
+Kanada ca
+Kanāda ca
+Kanada ca
+Kanada ca
+Canadá ca
+Canadá ca
+Канада ca
+Kanada ca
+Kanada ca
+Kanada ca
+I-Canada ca
+Kanada ca
+¸É¼¡ ca
+แคนาดา ca
+Kanada ca
+Канада ca
+加拿大 ca
+加拿大 ca
+Cocos (Keeling) Islands cc
+Кокосови Острови cc
+Kokosovo (Keeling) ostrvo cc
+Islas Cocos (Keeling) cc
+Koko Irlak cc
+Kókusz-szigetek (Keeling) cc
+Ilhas Cocos cc
+Kokosove Ostrovy cc
+Kokosovi (Keelingovi) otoki cc
+Kokosöarna cc
+Кокосові острови cc
+Congo, the democratic republic of the cd
+Дэмакратычная Рэспубліка Конга cd
+Конго cd
+Kongo, demokratska republika cd
+Congo, den demokratiske republik cd
+Congo, república democrática del cd
+Kongo, errepublika demokratikoa cd
+Kongói Demokratikus Köztársaság cd
+República Democrática do Congo cd
+Demokratická Republika Kongo cd
+Kongo, demokratična republika cd
+Demokratiska republiken Kongo cd
+刚果民主共和国 cd
+Central African Republic cf
+ЦАР cf
+Centralnoafrička Republika cf
+Central-afrikanske Republik cf
+República Centroafricana cf
+Afrika Erdiko Errepublika cf
+Közép-Afrikai Köztársaság cf
+ໂດມິນິກັນ cf
+República da África Central cf
+Stredoafrická Republika cf
+Centralnoafriška republika cf
+Centralafrikanska Republiken cf
+Центральноафриканська республіка cf
+中非共和国 cf
+Congo cg
+Конга cg
+Конго cg
+Kongo cg
+Kongo cg
+Kongó cg
+ຄອນໂໍຊລ cg
+Kongo cg
+Kongo cg
+Kongo cg
+Конго cg
+刚果 cg
+Switzerland ch
+Switserland ch
+سويسرا ch
+İsveçrə ch
+Швэйцарыя ch
+Швейцария ch
+Suis ch
+Švicarska ch
+Suïssa ch
+Švýcarsko ch
+Schweiz ch
+Schweiz ch
+Ελβετία ch
+Svislando ch
+Suiza ch
+Šveits ch
+Suitza ch
+سوییس ch
+Sveitsi ch
+Suisse ch
+Suíza ch
+שוייץ ch
+Švicarska ch
+Svájc ch
+Swiss ch
+Sviss ch
+Svizzera ch
+スイス ch
+스위스 ch
+ສະວິສເຊີແລນ ch
+Šveicarija ch
+Šveice ch
+Svizzera ch
+Sveits ch
+Zwitserland ch
+Sveits ch
+Suissa ch
+Szwajcaria ch
+Suíça ch
+Suíça ch
+Elveţia ch
+Швейцария ch
+Švajčiarsko ch
+Švica ch
+Švajcarska ch
+I-Switzerland ch
+Schweiz ch
+ÍÅ¢ðº÷Ä¡óÐ ch
+สวิสเซอร์แลนด์ ch
+İsviçre ch
+Швейцарія ch
+Thuỵ Sĩ ch
+Swisse ch
+瑞士 ch
+瑞士 ch
+Cote d'ivoire ci
+Бераг Слановай Косьці ci
+Кот'Дивоар ci
+Obala Slonovače ci
+Elfenbenskysten ci
+Costa de Marfil ci
+Elefántcsontpart ci
+ປ່ອຍຫມາກກະລອກ ci
+Slonokoščena obala ci
+Elfenbenskusten ci
+Кот д'Івуар ci
+Cook islands ck
+Kukova ostrva ck
+Cook-øerne ck
+Islas Cook ck
+Cook Irlak ck
+Cook-szigetek ck
+ຄຸກກີ້ ck
+Ilhas Cook ck
+Cookove ostrovy ck
+Cookovi otoki ck
+Cooköarna ck
+Острови Кука ck
+库克群岛 ck
+Chile cl
+Chilië cl
+تشيلي cl
+Şili cl
+Чылі cl
+Чили cl
+Čile cl
+Xile cl
+Χιλή cl
+Ĉilio cl
+Tšiili cl
+Txile cl
+شیلی cl
+Chili cl
+צ'ילה cl
+Čile cl
+Chili cl
+Cile cl
+チリ cl
+칠레 cl
+ຊີລີ cl
+Čilė cl
+Čīle cl
+Ċile cl
+Chili cl
+Cile cl
+Чили cl
+Čile cl
+Čile cl
+Čile cl
+I-Chile cl
+º¢Ä¢ cl
+ชิลี cl
+Şili cl
+Чилі cl
+Chi lê cl
+Tchili cl
+智利 cl
+智利 cl
+Cameroon cm
+Камэрун cm
+Камерун cm
+Kamerun cm
+Cameroun cm
+Camerún cm
+Kamerun cm
+Kamerun cm
+ຕາລາງງານ - K cm
+Camarões cm
+Komerun cm
+Kamerun cm
+Kamerun cm
+Камерун cm
+喀麦隆 cm
+China cn
+Sjina cn
+الصين cn
+Çin cn
+Кітай cn
+Китай cn
+Sina cn
+Kina cn
+Xina cn
+Čína cn
+Kina cn
+Κίνα cn
+Ĉinujo cn
+Hiina cn
+Txina cn
+چین cn
+Kiina cn
+Kina cn
+Chine cn
+סין cn
+Kina cn
+Kína cn
+Cina cn
+Kína cn
+Cina cn
+中国 cn
+중국 cn
+ຈີນ cn
+Kinija cn
+Ķīna cn
+Ċina cn
+Kina cn
+Kina cn
+Xina cn
+Chiny cn
+Китай cn
+Čína cn
+Kitajska cn
+Kina cn
+I-China cn
+Kina cn
+º£É¡ cn
+จีน cn
+Çin cn
+Китай cn
+Trung Quốc cn
+Chine cn
+中国 cn
+中國 cn
+Colombia co
+Colombië co
+كولمبيا co
+Калюмбія co
+Колумбия co
+Kolumbija co
+Colòmbia co
+Kolumbie co
+Kolumbien co
+Κολομβία co
+Kolumbio co
+Kolumbia co
+Kolonbia co
+کلمبیا co
+Kolumbia co
+Colombie co
+קולומביה co
+Kolumbija co
+Kolumbia co
+コロンビア co
+콜롬비아 co
+ໂຄລຳເບີຍ co
+Kolumbija co
+Kolumbija co
+Kolumbja co
+Columbia co
+Kolumbia co
+Colômbia co
+Colômbia co
+Columbia co
+Колумбия co
+Kolumbia co
+Kolumbija co
+I-Colombia co
+¦¸¡ÄõÀ¢Â¡ co
+โคลัมเบีย co
+Kolombiya co
+Колумбія co
+Colombeye co
+Columbia co
+哥伦比亚 co
+哥倫比亞 co
+Costa Rica cr
+كوستاريكا cr
+Коста Рыка cr
+Коста Рика cr
+Kostarika cr
+Kostarika cr
+Κόστα Ρίκα cr
+کاستاریکا cr
+Kosta Rika cr
+קוסטה ריקה cr
+Costa rica cr
+コスタリカ cr
+코스타 리카 cr
+ໂຄເອເທີຍ cr
+Kosta Rika cr
+Kostaryka cr
+Коста-Рика cr
+Kostarika cr
+Kostarika cr
+I-Costa Rica cr
+§¸¡Š¼¡ ⸡ cr
+Kosta Rika cr
+Коста-Ріка cr
+哥斯达黎加 cr
+哥斯大黎加 cr
+Cuba cu
+Kuba cu
+كوبا cu
+Куба cu
+Куба cu
+Kuba cu
+Kuba cu
+Kuba cu
+Κούβα cu
+Kuuba cu
+Kuba cu
+کوبا cu
+Kuuba cu
+Kuba cu
+קובה cu
+Kuba cu
+キューバ cu
+쿠바 cu
+ເກມໄພ່ cu
+Kuba cu
+Kuba cu
+Kuba cu
+Куба cu
+Kuba cu
+Kuba cu
+I-Cuba cu
+Kuba cu
+¸¢ÔÀ¡ cu
+Küba cu
+Куба cu
+古巴 cu
+古巴 cu
+Cape Verde cv
+Капе Верде cv
+Zelenortska ostrva cv
+Kapverdiske øer cv
+Cabo Verde cv
+Cabo Verde cv
+Zöldfoki-szigetek cv
+ເກມໄພ່ cv
+Cabo Verde cv
+Kap Verde cv
+佛得角 cv
+Christmas Island cx
+Božično ostrvo cx
+Juleøen cx
+Islas Christmas cx
+Eguberri Irla cx
+Karácsony-szigetek cx
+ຄິດສະຕອລ cx
+Ilhas do Natal cx
+Vianočné Ostrovy cx
+Božični otok cx
+Julön cx
+Острів Різдва cx
+圣诞岛 cx
+Cyprus cy
+Кіпр cy
+Кипър cy
+Kipar cy
+Cypern cy
+Chipre cy
+Txipre cy
+Ciprus cy
+ບີບອັດ cy
+Chipre cy
+Ciper cy
+Cypern cy
+Кипр cy
+塞浦路斯 cy
+Czechia cz
+Czechië cz
+التشيك cz
+Çex Respublikası cz
+Чэхія cz
+Чехия cz
+Tchekia cz
+Češka cz
+Txèquia cz
+Česko cz
+Tjekkiet cz
+Tschechien cz
+Τσεχία cz
+Ĉeĥio cz
+República Checa cz
+Tšehhi cz
+Txekia cz
+چک cz
+Tsekki cz
+République tchèque cz
+Chequia cz
+צ'כיה cz
+Češka cz
+Csehország cz
+Tékkland cz
+Repubblica Ceca cz
+チェコ cz
+체코 cz
+Čekija cz
+Čehija cz
+Cżekia cz
+Tsjekkia cz
+Tsjechië cz
+Tsjekkia cz
+Chèquia cz
+Czechy cz
+República Checa cz
+República Tcheca cz
+Cehia cz
+Чехия cz
+Česko cz
+Češka cz
+Češka cz
+I-Czechia cz
+Tjeckien cz
+¦ºì¡ cz
+Çek Cumhuriyeti cz
+Чехія cz
+Séc cz
+Tchekeye cz
+捷克 cz
+捷克 cz
+Germany de
+Duitsland de
+ألمانيا de
+Almaniya de
+Нямеччына de
+Германия de
+Alamagn de
+Njemačka de
+Alemanya de
+Německo de
+Tyskland de
+Deutschland de
+Γερμανία de
+Germanio de
+Alemania de
+Saksamaa de
+Alemania de
+ آلمان de
+Saksa de
+Týskland de
+Allemagne de
+Alemaña de
+גרמניה de
+Njemačka de
+Németország de
+Jerman de
+Þýskaland de
+Germania de
+ドイツ de
+독일 de
+ເຍລລະມັນນີ de
+Vokietija de
+Vācija de
+Ġermanja de
+Tyskland de
+Duitsland de
+Tyskland de
+Alemanya de
+Niemcy de
+Alemanha de
+Alemanha de
+Germania de
+Германия de
+Nemecko de
+Nemčija de
+Nemačka de
+I-Germany de
+Tyskland de
+§º÷ÁÉ¢ de
+เยอรมันนี de
+Almanya de
+Німеччина de
+Đức de
+Almagne de
+德国 de
+德國 de
+IJalimani de
+Djibouti dj
+جيبوتي dj
+Джыбуці dj
+Джибути dj
+Đibuti dj
+Džibuti dj
+Dschibuti dj
+Τζιμπουτί dj
+جیبوتی dj
+ג'יבוטי dj
+Džibuti dj
+Dzsibuti dj
+ジブティ dj
+지부티 dj
+ພັດພາ dj
+Džibuti dj
+Dġibuti dj
+Dżibuti dj
+Djibuti dj
+Djibuti dj
+Джибути dj
+Džibuty dj
+Džibuti dj
+I-Djibouti dj
+Ê¢ƒ¢¦À¡Ê dj
+Cibuti dj
+Джібуті dj
+吉布提 dj
+吉布地 dj
+Denmark dk
+Denemarke dk
+الدنمارك dk
+Danimarka dk
+Данія dk
+Дания dk
+Danmark dk
+Danska dk
+Dinamarca dk
+Dánsko dk
+Danmark dk
+Dänemark dk
+Δανία dk
+Danlando dk
+Dinamarca dk
+Taani dk
+Danimarka dk
+دانمارک dk
+Tanska dk
+Danmark dk
+Danemark dk
+Dinamarca dk
+דנמרק dk
+Danska dk
+Dánia dk
+Danmörk dk
+Danimarca dk
+デンマーク dk
+덴마크 dk
+ເດນມາກ dk
+Danija dk
+Dānija dk
+Danimarka dk
+Danmark dk
+Denemarken dk
+Danmark dk
+Dinamarca dk
+Dania dk
+Dinamarca dk
+Dinamarca dk
+Danemarca dk
+Дания dk
+Dánsko dk
+Danska dk
+Danska dk
+I-Denmark dk
+Danmark dk
+¦¼ýÁ¡÷ì dk
+เดนมาร์ก dk
+Danimarka dk
+Данія dk
+Đan Mạch dk
+Daenmåtche dk
+丹麦 dk
+丹麥 dk
+Dominica dm
+Дамініка dm
+Доминика dm
+Dominika dm
+Dominika dm
+ໂລມາເນີຍ dm
+Dominicana dm
+Dominikánsko dm
+Dominikanska republika dm
+Домініка dm
+多米尼加 dm
+Dominican Republic do
+Dominikiese Republiek do
+جمهورية الدومينيكان do
+Dominik Respublikası do
+Дамініканская Рэспубліка do
+Доминиканска република do
+Republik Dominikan do
+Dominikanska Republika do
+República Dominicana do
+Dominikánská republika do
+Dominikanske Republik do
+Dominikanische Republik do
+Δομινικανή Δημοκρατία do
+Dominika Respubliko do
+República Dominicana do
+Dominikaani Vabariik do
+Dominikar Errepublika do
+جمهوری دامینیکن do
+Dominikaaninen tasavalta do
+République dominicaine do
+República Dominicana do
+הרפובליקה הדומיניקנית do
+Dominikanska Republika do
+Dominikai Köztársaság do
+Republik Dominika do
+Dóminíska Lýðveldið do
+Repubblica Dominicana do
+ドミニカ共和国 do
+도미니카 공화국 do
+ໂດມິນີກັນ do
+Dominikos Respublika do
+Dominikas Republika do
+Repubblika Dominikana do
+Den dominikanske republikk do
+Dominicaanse Republiek do
+Den dominikanske republikken do
+Republica Dominicana do
+Dominikana do
+República Dominicana do
+República Dominicana do
+Republica Dominicană do
+Доминиканская республика do
+Dominikánska republika do
+Dominikanska republika do
+Dominikanska republika do
+I-Dominican Republic do
+Dominikanska republiken do
+¦¼¡Á¢É¢ì¸ý ÌÊÂÃÍ do
+โดมินิกัน do
+Dominik Cumhuriyeti do
+Домініканська республіка do
+Muvhuso wa Dominican do
+Cộng hoà Dominican do
+Republike Dominikinne do
+IRepublic yeDominican do
+多米尼加共和国 do
+多明尼加共和國 do
+Algeria dz
+Algerië dz
+الجزائر dz
+Альжыр dz
+Алжир dz
+Alžir dz
+Algèria dz
+Alžírsko dz
+Algeriet dz
+Algerien dz
+Αλγερία dz
+Algerio dz
+Argelia dz
+Alžeeria dz
+ الجزیره dz
+Algérie dz
+אלג'יריה dz
+Alžir dz
+Algéria dz
+アルジェリア dz
+알제리 dz
+ບັນກາເລີຍ dz
+Alžyras dz
+Alġerija dz
+Algerie dz
+Algerije dz
+Algerie dz
+Algieria dz
+Argélia dz
+Argélia dz
+Алжир dz
+Alžírsko dz
+Alžirija dz
+I-Algeria dz
+Algeriet dz
+«øƒ¢Ã¢Â¡ dz
+Алжир dz
+Aldjereye dz
+阿尔及利亚 dz
+阿爾及利亞 dz
+Equador ec
+Ewenaar ec
+الإكوادور ec
+Ekvator ec
+Эквадор ec
+Еквадор ec
+Ecuador ec
+Ekvador ec
+Ekvádor ec
+Ecuador ec
+Ισημερινός ec
+Ekvadoro ec
+Ecuador ec
+Ekvador ec
+Ekuador ec
+اکوادور ec
+Équateur ec
+Ecuador ec
+אקוודור ec
+Ekvador ec
+Ecuador ec
+Ekvador ec
+Ecuador ec
+エクアドル ec
+에콰도르 ec
+ເອກໍດໍ ec
+Ekvadoras ec
+Ekvadora ec
+Ekwador ec
+Ecuador ec
+Ecuador ec
+Ekwador ec
+Ecuador ec
+Эквадор ec
+Ekvádor ec
+Ekvador ec
+Ekvador ec
+I-Equador ec
+®ì¦Å§¼¡÷ ec
+เอกวาดอร์ ec
+Ekvator ec
+Еквадор ec
+Ecwåteur ec
+厄瓜多尔 ec
+厄瓜多 ec
+Estonia ee
+Estlandies ee
+استونيا ee
+Estoniya ee
+Эстонія ee
+Естония ee
+Estonija ee
+Estònia ee
+Estonsko ee
+Estland ee
+Estland ee
+Εσθονία ee
+Estlando ee
+Eesti ee
+استونی ee
+Eesti ee
+Estonie ee
+אסטוניה ee
+Estonija ee
+Észtország ee
+Eistland ee
+エストニア ee
+에스토니아 ee
+ເອໂທເນີຍ ee
+Estija ee
+Igaunija ee
+Estonja ee
+Estland ee
+Estland ee
+Estland ee
+Estònia ee
+Estónia ee
+Estônia ee
+Эстония ee
+Estónsko ee
+Estonija ee
+Estonija ee
+I-Estonia ee
+Estland ee
+±Í§¼¡É¢Â¡ ee
+เอสโธเนีย ee
+Estonya ee
+Естонія ee
+Estoneye ee
+爱沙尼亚 ee
+愛沙尼亞 ee
+Egypt eg
+Egipte eg
+مصر eg
+Misir eg
+Эгіпэт eg
+Египет eg
+Egipat eg
+Egipte eg
+Egypten eg
+Ägypten eg
+Αίγυπτος eg
+Egiptujo eg
+Egipto eg
+Egiptus eg
+Egypto eg
+مصر eg
+Egypti eg
+Egyptaland eg
+Égypte eg
+מצרים eg
+Egipat eg
+Egyiptom eg
+Egyptaland eg
+Egitto eg
+エジプト eg
+이집트 eg
+ອີຢີບ eg
+Egiptas eg
+Ēģipte eg
+Eġittu eg
+Egypte eg
+Egepeta eg
+Egipt eg
+Egipto eg
+Egito eg
+Egipt eg
+Египет eg
+Egipt eg
+I-Egypt eg
+Egypten eg
+±¸¢ôÐ eg
+อียิปต์ eg
+Mısır eg
+Єгипет eg
+Edjipe eg
+埃及 eg
+埃及 eg
+Igibhithe eg
+Western Sahara eh
+Западна Сахара eh
+Zapadna Sahara eh
+Vestsahara eh
+Sahara occidental eh
+Mendebaldeko Sahara eh
+Nyugat-Szahara eh
+ພື້ນທີ່ທຳງານ eh
+Sahara eh
+Západna Sahara eh
+Zahodna Sahara eh
+Västsahara eh
+Західна Сахара eh
+西撒哈拉 eh
+Eritrea er
+Эрытрэя er
+Еритрея er
+Eritreja er
+ແກ້ໄຂແຟ້ມທຳງານ er
+Eritreja er
+Еритрея er
+厄立特里亚 er
+Spain es
+Spanje es
+أسبانيا es
+İspaniya es
+Гішпанія es
+Испания es
+Spagn es
+Španija es
+Espanya es
+Španělsko es
+Spanien es
+Spanien es
+Ισπανία es
+Hispanio es
+España es
+Hispaania es
+Espainia es
+اسپانیا es
+Espanja es
+Spania es
+Espagne es
+España es
+ספרד es
+Španjolska es
+Spanyolország es
+Spanyol es
+Spánn es
+Spagna es
+スペイン es
+스페인 es
+ສະເປັນ es
+Ispanija es
+Spānija es
+Spanja es
+Spania es
+Spanje es
+Spania es
+Espanha es
+Hiszpania es
+Espanha es
+Espanha es
+Spania es
+Испания es
+Španielsko es
+Španija es
+Španija es
+I-Spain es
+Spanien es
+ͦÀ¢ý es
+สเปน es
+İspanya es
+Іспанія es
+Tây Ban Nha es
+Sipagne es
+西班牙 es
+西班牙 es
+Ethiopia et
+Этыёпія et
+Етиопия et
+Etiopija et
+Ethiopien et
+Etiopía et
+Etiopia et
+Etiópia et
+ເອໂທເນີຍ et
+Etiópia et
+Etiópia et
+Etiopija et
+Etiopien et
+Ефіопія et
+埃塞俄比亚 et
+Finland fi
+فنلندا fi
+Finlandiya fi
+Фінляндыя fi
+Финландия fi
+Finska fi
+Finlàndia fi
+Finsko fi
+Finnland fi
+Φινλανδία fi
+Finlando fi
+Finlandia fi
+Soome fi
+Finlandia fi
+فنلاند fi
+Suomi fi
+Finnland fi
+Finlande fi
+Finlandia fi
+פינלנד fi
+Finska fi
+Finnország fi
+Finlandia fi
+Finnland fi
+Finlandia fi
+フィンランド fi
+핀란드 fi
+ຟີນແລນ fi
+Suomija fi
+Somija fi
+Finlandja fi
+Finlandia fi
+Finlandia fi
+Finlândia fi
+Finlândia fi
+Finlanda fi
+Финляндия fi
+Fínsko fi
+Finska fi
+Finska fi
+I-Finland fi
+À¢ýÄ¡óÐ fi
+ฟินแลนด์ fi
+Finlandiya fi
+Фінляндія fi
+Phần Lan fi
+Finlande fi
+芬兰 fi
+芬蘭 fi
+Fiji fj
+Фіджы fj
+Фиджи fj
+Fidži fj
+Fidzsi fj
+ມີດີ fj
+Ilhas Fiji fj
+Fidži fj
+Fidži fj
+Фіджі fj
+斐济 fj
+Falkland Islands (Malvinas) fk
+Фолклендски Острови fk
+Foklandska ostrva (Malvini) fk
+Falkland-øerne fk
+Islas Falkland (Malvinas) fk
+Falkland Irlak (Malvinak) fk
+Falkland-szigetek fk
+Ilhas Malvinas fk
+Falklandské Ostrovy (Malviny) fk
+Falklandski otoki (Malvini) fk
+Falklandsöarna fk
+福克兰岛 (马尔维纳斯) fk
+Micronesia, Federated states of fm
+Федэрацыя Мiкранэзіі fm
+Микронезия fm
+Mikronezija, Federalne države fm
+Mikronesien, de forenede stater af fm
+Micronesia, Estados federados de fm
+Mikronesia, Estatu Federatuak fm
+Mikronézia fm
+Estados Federados da Micronésia fm
+Spjoené štáty Mikronézie fm
+Mikronezija, Združene države fm
+Mikronesiska federationen fm
+密克罗尼西亚联邦 fm
+Faroe Islands fo
+Фареорски Острови fo
+Farska ostrva fo
+Færøerne fo
+islas Faroe fo
+Faroe Irlak fo
+Faroe-szigetek fo
+ໄອແລນ fo
+Ilhas Faroe fo
+Ostrovy Faroe fo
+Otoki Faroe fo
+Färöarna fo
+Фарерські острови fo
+France fr
+Frankryk fr
+فرنسا fr
+Fransa fr
+Францыя fr
+Франция fr
+Frañs fr
+Francuska fr
+França fr
+Francie fr
+Frankrig fr
+Frankreich fr
+Γαλλία fr
+Francio fr
+Francia fr
+Prantsusmaa fr
+Frantzia fr
+فرانسه fr
+Ranska fr
+Frakland fr
+Francia fr
+צרפת fr
+Francuska fr
+Franciaország fr
+Prancis fr
+Frakkland fr
+Francia fr
+フランス fr
+프랑스 fr
+ຝຣັ່ງ fr
+Prancūzija fr
+Francija fr
+Franza fr
+Frankrike fr
+Frankrijk fr
+Frankrike fr
+Fora fr
+França fr
+Francja fr
+França fr
+França fr
+Franţa fr
+Франция fr
+Francúzsko fr
+Francija fr
+Francuska fr
+I-France fr
+Frankrike fr
+À¢Ã¡ýÍ fr
+ฝรั่งเศส fr
+Fransa fr
+Франція fr
+Fura fr
+Pháp fr
+Fransi fr
+法国 fr
+法國 fr
+Gabon ga
+Габон ga
+Габон ga
+Gabón ga
+ແກລ່ງນ ga
+Gabão ga
+Габон ga
+加蓬 ga
+United Kingdom gb
+Vereenigde Koninkryk gb
+المملكة المتحدة gb
+Birləşmiş Krallıq gb
+Злучанае Каралеўства gb
+Великобритания gb
+Rouantelezh Unanet gb
+Velika Britanija gb
+Regne Unit gb
+Spojené království gb
+Storbritannien gb
+Großbritannien gb
+Ηνωμένο Βασίλειο gb
+Britio gb
+Reino Unido gb
+Ühendatud Kuningriigid gb
+Erreinu Batua gb
+بریتانیا gb
+Iso-Britannia gb
+Stórabretland gb
+Royaume Uni gb
+Reino Unido gb
+בריטניה gb
+Ujedinjeno Kraljevstvo gb
+Egyesült Királyság gb
+Inggris gb
+Stóra Bretland gb
+Regno Unito gb
+イギリス gb
+영국 gb
+ສະຫະລາດສະອານາຈັກ gb
+Jungtinė Karalystė gb
+Apvienotā Karaliste gb
+Renju Unit gb
+Storbritannia gb
+Verenigd Koninkrijk gb
+Storbritannia gb
+Regne Unit gb
+Wielka Brytania gb
+Reino Unido gb
+Reino Unido gb
+Anglia gb
+Великобритания gb
+Anglicko gb
+Združeno kraljestvo gb
+Velika Britanija gb
+I-United Kingdom gb
+Storbritannien gb
+³ì¸¢Â ­Ã¡îº¢Âõ gb
+สหราชอาณาจักร gb
+Birleşik Krallık gb
+Великобританія gb
+Anh gb
+United Kingdom gb
+联合王国 gb
+聯合王國 gb
+United Kingdom gb
+Grenada gd
+غرينادا gd
+Qrenada gd
+Грэнада gd
+Гренада gd
+Granada gd
+Γρενάδα gd
+Grenado gd
+Granada gd
+گرانادا gd
+Grenade gd
+Granada gd
+גרנדה gd
+Grænhöfðaeyjar gd
+Granada gd
+グラナダ gd
+그러네이다 gd
+ເກນາດາ gd
+Grenāda gd
+Granada gd
+Granada gd
+Granada gd
+Гренада gd
+I-Grenada gd
+¸¢¦Ãɼ¡ gd
+เกรนาดา gd
+Гренада gd
+格林纳达 gd
+格瑞那達 gd
+Georgia ge
+Грузія ge
+Грузия ge
+Gruzija ge
+Georgien ge
+Grúzia ge
+ເຊີເບີຍ ge
+Geórgia ge
+Gruzija ge
+Georgien ge
+Грузія ge
+格鲁吉亚 ge
+Ghana gh
+غانا gh
+Гана gh
+Гана gh
+Gana gh
+Γκάνα gh
+غنا gh
+גאנה gh
+ガーナ gh
+ຈີນ gh
+Gana gh
+Gana gh
+Gana gh
+Гана gh
+Gana gh
+I-Ghana gh
+¸¡É¡ gh
+Гана gh
+加纳 gh
+迦納 gh
+Gibraltar gi
+Гибралтар gi
+Gibraltár gi
+ມອລຕາ gi
+Гібралтар gi
+直布罗陀 gi
+Gambia gm
+Гамбія gm
+Гамбия gm
+Gambija gm
+ແກມມາ gm
+Gâmbia gm
+Gambija gm
+Гамбія gm
+冈比亚 gm
+Guinea gn
+Гвінэя gn
+Гвинея gn
+Gvineja gn
+ເຖາວັນ gn
+Guiné gn
+Gvineja gn
+Гвінея gn
+几内亚 gn
+Guadeloupe gp
+Гвадалупа gp
+Gvadalupe gp
+Guadalupe gp
+ເດີລຸກ gp
+Guadalupe gp
+Гваделупа gp
+瓜德罗普岛 gp
+Equatorial Guinea gq
+Экватарыяльная Гвінэя gq
+Екваториялна Гвинея gq
+Ekvatorijalna Gvineja gq
+Ækvatorial Guinea gq
+Guinea equatorial gq
+Ginea Ekuatoriala gq
+Egyenlítői Guinea gq
+ການສອນ gq
+Guiné Equatorial gq
+Rovníkova Guinea gq
+Ekvatorialna Gvineja gq
+Ekvatorialguinea gq
+Екваторіальна Гвінея gq
+赤道几内亚 gq
+Greece gr
+Griekeland gr
+اليونان gr
+Yunanıstan gr
+Грэцыя gr
+Гърция gr
+Gres gr
+Grčka gr
+Grècia gr
+Řecko gr
+Grækenland gr
+Griechenland gr
+Ελλάδα gr
+Grekujo gr
+Grecia gr
+Kreeka gr
+Grezia gr
+یونان gr
+Kreikka gr
+Grikkaland gr
+Grèce gr
+Grecia gr
+יוון gr
+Grčka gr
+Görögország gr
+Grikkland gr
+Grecia gr
+ギリシャ gr
+그리스 gr
+ກີຊ gr
+Graikija gr
+Grieķija gr
+Greċja gr
+Hellas gr
+Griekenland gr
+Hellas gr
+Grèça gr
+Grecja gr
+Grécia gr
+Grécia gr
+Grecia gr
+Греция gr
+Grécko gr
+Grčija gr
+Grčka gr
+I-Greece gr
+Grekland gr
+¸¢Ã£Í gr
+กรีซ gr
+Yunanistan gr
+Греція gr
+Hy Lạp gr
+Grece gr
+希腊 gr
+希臘 gr
+Guatemala gt
+Gautemala gt
+غواتيمالا gt
+Quatemala gt
+Гватэмала gt
+Гватемала gt
+Gvatemala gt
+Γουατεμάλα gt
+Gvatemalo gt
+Guatemaala gt
+گواتمالا gt
+גואטמלה gt
+Gvatemala gt
+カタロニア gt
+과테말라 gt
+ກັວເຕມາລາ gt
+Gvatemala gt
+Gvatemala gt
+Gwatemala gt
+Gwatemala gt
+Гватемала gt
+Gvatemala gt
+Gvatemala gt
+I-Guatemala gt
+ÌÅ¡ò¾Á¡Ä¡ gt
+กัวเตมาลา gt
+Гватемала gt
+Gwatemala gt
+瓜地马拉 gt
+瓜地馬拉 gt
+Guam gu
+Гуам gu
+ແກມມາ gu
+Гуам gu
+关岛 gu
+Guinea-Bissau gw
+Гвінэя-Бісаў gw
+Гвинея-Бисау gw
+Gvineja-Bisau gw
+Ginea-Bissau gw
+Bissau-Guinea gw
+ລັດເຊີຍ gw
+Guiné-Bissau gw
+Гвінея-Біссау gw
+几内亚比绍 gw
+Guyana gy
+Гвіяна gy
+Гуана gy
+Gvajana gy
+ຈີນ gy
+Guiana gy
+Gvajana gy
+Гаяна gy
+圭亚那 gy
+Hong Kong hk
+Ганконг hk
+Хонг Конг hk
+Hongkong hk
+ບໍ່ຮູ້ຈັກ hk
+Гонконг hk
+香港 hk
+Honduras hn
+هندوراس hn
+Гандурас hn
+Хондурас hn
+Hondures hn
+Ονδούρα hn
+Honduraso hn
+Honduuras hn
+هندوراس hn
+הונדורס hn
+ホンデュラス hn
+온두라스 hn
+ຫອນດູລັດ hn
+Hondūras hn
+Hondurasa hn
+Ħonduras hn
+Hondures hn
+Гондурас hn
+I-Honduras hn
+¬ñÎáŠÍ hn
+ฮอนดูรัส hn
+Гондурас hn
+洪都拉斯 hn
+宏都拉斯 hn
+Croatia hr
+Kroatië hr
+كرواتيا hr
+Xırvatıstan hr
+Харватыя hr
+Хърватска hr
+Kroatia hr
+Hrvatska hr
+Croàcia hr
+Chorvatsko hr
+Kroatien hr
+Kroatien hr
+Κροατία hr
+Kroatio hr
+Croacia hr
+Horvaatia hr
+Kroazia hr
+کرواسی hr
+Kroatia hr
+Kroatia hr
+Croatie hr
+Croacia hr
+קרואטיה hr
+Hrvatska hr
+Horvátország hr
+Kroasia hr
+Króatía hr
+Croazia hr
+クロアチア hr
+크로아티아 hr
+ໂຄເອເທີຍ hr
+Kroatija hr
+Horvātija hr
+Kroazja hr
+Kroatia hr
+Kroatië hr
+Kroatia hr
+Croacia hr
+Chorwacja hr
+Croácia hr
+Croácia hr
+Croaţia hr
+Хорватия hr
+Chorvátsko hr
+Hrvaška hr
+Hrvatska hr
+I-Croatia hr
+Kroatien hr
+̦á§Åº¢Â¡ hr
+โครเอเธีย hr
+Hırvatistan hr
+Хорватія hr
+Crowåceye hr
+克罗地亚 hr
+克羅埃西亞 hr
+Haiti ht
+Гаіці ht
+Хаити ht
+Haití ht
+ວາດຮູບ - K ht
+Гаїті ht
+海地岛 ht
+Hungary hu
+Hongarye hu
+هنغاريا hu
+Macarıstan hu
+Вугоршчына hu
+Унгария hu
+Hungaria hu
+Mađarska hu
+Hongria hu
+Maďarsko hu
+Ungarn hu
+Ungarn hu
+Ουγγαρία hu
+Hungario hu
+Hungría hu
+Ungari hu
+Hungaria hu
+مجارستان hu
+Unkari hu
+Ungarn hu
+Hongrie hu
+Hungría hu
+הונגריה hu
+Mađjarska hu
+Magyarország hu
+Hungaria hu
+Ungverjaland hu
+Ungheria hu
+ハンガリー hu
+헝가리 hu
+ຫັງກາລີ hu
+Vengrija hu
+Ungārija hu
+Ungerija hu
+Ungarn hu
+Hongarije hu
+Ungarn hu
+Hongria hu
+Węgry hu
+Hungria hu
+Hungria hu
+Ungaria hu
+Венгрия hu
+Maďarsko hu
+Madžarska hu
+Mađarska hu
+I-Hungary hu
+Ungern hu
+¬í§¸Ã¢ hu
+ฮังการี hu
+Macaristan hu
+Угорщина hu
+Hongreye hu
+匈牙利 hu
+匈牙利 hu
+Indonesia id
+Indonesië id
+إندونيسيا id
+İndoneziya id
+Інданэзія id
+Индонезия id
+Indonezija id
+Indonèsia id
+Indonésie id
+Indonesien id
+Indonesien id
+Ινδονησία id
+Indonezio id
+Indoneesia id
+اندونزی id
+Indonésie id
+אינדונזיה id
+Indonezija id
+Indonézia id
+Indónesía id
+インドネシア id
+인도네시아 id
+ອີຍໂດນີເຊີຍ id
+Indonezija id
+Indonēzija id
+Indoneżja id
+Indonesië id
+Indonezja id
+Indonésia id
+Indonésia id
+Indonezia id
+Индонезия id
+Indonézia id
+Indonezija id
+I-Indonesia id
+Indonesien id
+­ó§¾¡É£º¢Â¡ id
+อินโดนีเซีย id
+İndonezya id
+Індонезія id
+Indoneseye id
+印度尼西亚 id
+印尼 id
+Ireland ie
+Ierland ie
+أيرلندا ie
+İrlandiya ie
+Ірляндыя ie
+Ирландия ie
+Iwerzhon ie
+Irska ie
+Irlanda ie
+Irsko ie
+Irland ie
+Irland ie
+Ιρλανδία ie
+Islando ie
+Irlanda ie
+Island ie
+Irlanda ie
+ایرلند ie
+Irlanti ie
+Írland ie
+Irlande ie
+Irlanda ie
+אירלנד ie
+Irska ie
+Írország ie
+Irlandia ie
+Írland ie
+Irlanda ie
+アイスランド ie
+아일랜드 ie
+ໄອແລນ ie
+Airija ie
+Īrija ie
+Irlanda ie
+Irland ie
+Ierland ie
+Irland ie
+Irlanda ie
+Irlandia ie
+Irlanda ie
+Irlanda ie
+Irlanda ie
+Ирландия ie
+Írsko ie
+Irska ie
+Irska ie
+I-Ireland ie
+Irland ie
+«Â÷Ä¡óÐ ie
+ไอร์แลนด์ ie
+İrlanda ie
+Ірландія ie
+Irlande ie
+爱尔兰 ie
+愛爾蘭 ie
+Israel il
+اسرائيل il
+İzrail il
+Ізраіль il
+Израел il
+Izrael il
+Izrael il
+Ισραήλ il
+Israelo il
+Iisrael il
+اسراییل il
+Ísrael il
+Israël il
+ישראל il
+Izrael il
+Izrael il
+Ísrael il
+Israele il
+イスラエル il
+이스라엘 il
+ອິດສະລະເອລ il
+Izraelis il
+Izraēla il
+Iżrael il
+Izrael il
+Израиль il
+Izrael il
+Izrael il
+Izrael il
+I-Israel il
+­Í§Ãø il
+อิสราเอล il
+İsrail il
+Ізраїль il
+Israyel il
+USirayeli il
+以色列 il
+以色列 il
+India in
+Indië in
+الهند in
+Hindistan in
+Індыя in
+Индия in
+Indija in
+Índia in
+Indie in
+Indien in
+Indien in
+Ινδία in
+Hindujo in
+هندوستان in
+Intia in
+Inde in
+הודו in
+Indija in
+Indland in
+インド in
+인도 in
+ອິນເດີຍ in
+Indija in
+Indija in
+Indja in
+Indie in
+Índia in
+Índia in
+Индия in
+Indija in
+I-India in
+Indien in
+­ó¾¢Â¡ in
+อินเดีย in
+Hindistan in
+Індія in
+Inde in
+印度 in
+印度 in
+Endiya in
+Iraq iq
+Irak iq
+العراق iq
+İraq iq
+Ірак iq
+Ирак iq
+Irak iq
+Irák iq
+Irak iq
+Irak iq
+Ιράκ iq
+Irako iq
+Irak iq
+Iraak iq
+عراق iq
+Irak iq
+Irak iq
+Irak iq
+עירק iq
+Irak iq
+Irak iq
+Írak iq
+Irak iq
+イラク iq
+이라크 iq
+ອີລັກ iq
+Irakas iq
+Irāka iq
+Irak iq
+Irak iq
+Irak iq
+Irak iq
+Iraque iq
+Iraque iq
+Irak iq
+Ирак iq
+Irák iq
+Irak iq
+I-Iraq iq
+Irak iq
+®Ã¡ì iq
+อิรัค iq
+Irak iq
+Ірак iq
+Irak iq
+伊拉克 iq
+伊拉克 iq
+Iran ir
+أيران ir
+Іран ir
+Иран ir
+Írán ir
+Ιράν ir
+Iraan ir
+ایران ir
+אירן ir
+Irán ir
+イラン ir
+이란 ir
+ອີລັກ ir
+Iranas ir
+Irão ir
+Irã ir
+Иран ir
+Irán ir
+I-Iran ir
+®Ã¡ý ir
+İran ir
+Іран ir
+伊朗 ir
+伊朗 ir
+Iceland is
+Ysland is
+أيسلندا is
+İslandiya is
+Ісьляндыя is
+Исландия is
+Island is
+Island is
+Islàndia is
+Island is
+Island is
+Island is
+Ισλανδία is
+Islando is
+Islandia is
+Island is
+Islandia is
+ایسلند is
+Islanti is
+Ísland is
+Islande is
+Islandia is
+איסלנד is
+Island is
+Izland is
+Islandia is
+Ísland is
+Islanda is
+アイスランド is
+아이슬란드 is
+ໄອຊແລນ is
+Islandija is
+Islande is
+Islandja is
+Island is
+IJsland is
+Island is
+Islandia is
+Islandia is
+Islândia is
+Islândia is
+Islanda is
+Исландия is
+Island is
+Islandija is
+Island is
+I-Iceland is
+Island is
+³ÍÄ¡óÐ is
+ไอซ์แลนด์ is
+İzlanda is
+Ісландія is
+Izlande is
+冰岛 is
+冰島 is
+Icelandi is
+Italy it
+Italië it
+ايطاليا it
+İtalyia it
+Італія it
+Италия it
+Italia it
+Italija it
+Itàlia it
+Itálie it
+Italien it
+Italien it
+Ιταλία it
+Italio it
+Italia it
+Itaalia it
+Italia it
+ایتالیا it
+Italia it
+Italia it
+Italie it
+Italia it
+איטליה it
+Italija it
+Olaszország it
+Italia it
+Ítalía it
+Italia it
+イタリア it
+이탈리아 it
+ອີຕາລີ it
+Italija it
+Itālija it
+Italja it
+Italia it
+Italië it
+Italia it
+Italia it
+Włochy it
+Itália it
+Itália it
+Italia it
+Италия it
+Taliansko it
+Italija it
+Italija it
+I-Italy it
+Italien it
+­ò¾¡Ä¢ it
+อิตาลี it
+İtalya it
+Італія it
+Itåleye it
+Ithali it
+意大利 it
+義大利 it
+Jamaica jm
+Jamaika jm
+جامايكا jm
+Yamayka jm
+Ямайка jm
+Ямайка jm
+Jamaika jm
+Jamajka jm
+Jamajka jm
+Jamaika jm
+Τζαμάικα jm
+Ĵamaiko jm
+Jamaika jm
+Jamaika jm
+جاماییکا jm
+Jamaika jm
+Jamaïque jm
+Xamaica jm
+ג'מייקה jm
+Jamajka jm
+Jamaika jm
+Jamaika jm
+Giamaica jm
+ジャマイカ jm
+자메이카 jm
+ຈາໄມກາ jm
+Jamaika jm
+Jamaika jm
+Ġamajka jm
+Jamajka jm
+Ямайка jm
+Jamajka jm
+Jamajka jm
+Jamajka jm
+I-Jamaica jm
+ƒº¦Áö측 jm
+จาไมกา jm
+Jamaika jm
+Ямайка jm
+Djamayike jm
+牙买加 jm
+牙買加 jm
+Jordan jo
+Jordaan jo
+الأردن jo
+İordaniya jo
+Ярданія jo
+Йордания jo
+Jordania jo
+Jordán jo
+Jordanien jo
+Ιορδανία jo
+Jordanio jo
+Jordania jo
+اردن jo
+Jordania jo
+Jordanie jo
+ירדן jo
+Jordánia jo
+Jórdanía jo
+Giordania jo
+ヨルダン jo
+요르단 jo
+ຈໍແດນ jo
+Jordanija jo
+Jordāna jo
+Ġordan jo
+Jordanië jo
+Jordania jo
+Jordânia jo
+Jordânia jo
+Iordania jo
+Иордания jo
+Jordánsko jo
+Jordanija jo
+I-Jordan jo
+Jordanien jo
+§Â¡÷¾¡ý jo
+จอร์แดน jo
+Ürdün jo
+Йорданія jo
+Djordaneye jo
+约旦 jo
+約旦 jo
+Ijolidani jo
+Japan jp
+اليابان jp
+Yaponiya jp
+Японія jp
+Япония jp
+Japó jp
+Japonsko jp
+Ιαπωνία jp
+Japanio jp
+Japón jp
+Jaapan jp
+Japonia jp
+ژاپن jp
+Japani jp
+Japon jp
+Xapón jp
+יפן jp
+Japán jp
+Jepang jp
+Giappone jp
+日本 jp
+일본 jp
+ຍີ່ປຸ່ນ jp
+Japonija jp
+Japāna jp
+Ġappun jp
+Japon jp
+Japonia jp
+Japão jp
+Japão jp
+Japonia jp
+Япония jp
+Japonsko jp
+Japonska jp
+I-Japan jp
+ºôÀ¡ý jp
+ญี่ปุ่น jp
+Japonya jp
+Японія jp
+Nhật bản jp
+Djapon jp
+日本 jp
+日本 jp
+Kenya ke
+Кенія ke
+Кения ke
+Kenija ke
+Kenia ke
+ເວນດາ ke
+Quênia ke
+Keňa ke
+Kenija ke
+Кенія ke
+肯尼亚 ke
+Kyrgyzstan kg
+Кыргызстан kg
+Киргистан kg
+Kirgistan kg
+Kirgizistan kg
+Kyrgyzstán kg
+Kirgizisztán kg
+ຄສິຕັລ kg
+Kirgizstan kg
+Kirgizistan kg
+Киргизстан kg
+吉尔吉斯坦 kg
+Cambodia kh
+Камбоджа kh
+Камбоджа kh
+Kambođa kh
+Kambodzsa kh
+ໂຄລຳເບີຍ kh
+Cambodja kh
+Kambodža kh
+Kambodža kh
+Kambodja kh
+Камбоджа kh
+柬埔寨 kh
+Kiribati ki
+Кiрыбацi ki
+Кирибати ki
+ແຟຄທັລ - K ki
+Кірібаті ki
+基里巴斯 ki
+Comoros km
+Каморы km
+Коморски km
+Komori km
+Comorerne km
+ສີ km
+Komori km
+Komorerna km
+Комори km
+科摩罗群岛 km
+St. Kitts and Nevis kn
+St. Kitts en Nevis kn
+سانت كيتس و نيفيس kn
+St. Kitts və Nevis kn
+Св. Кристоф и Невис kn
+S. Kitts ha Nevis kn
+St. Kitts i Nevis kn
+Sv. Kitts a Nevis kn
+St. Kitts-Nevis kn
+St. Kitts und Nevis kn
+St. Kitts και Nevis kn
+St. Kitts kaj Nevis kn
+St. Kitts y Nevis kn
+St. Kitts ja Nevis kn
+St. Kitts eta Nevis kn
+سن کیتس و نویس kn
+St. Kitts ja Nevis kn
+St Kitts et Nevis kn
+Saint Kitts e Nevis kn
+סנט קיטס ונביס kn
+St. Kitts és Nevis kn
+St. Kitts dan Nevis kn
+Ss. Kitts e Nevis kn
+セントキッツネヴィス kn
+세인트 키츠 네비스 kn
+Šv. Kitts ir Nevis kn
+St. Kitts un Nevis kn
+St. Kitts u Nevis kn
+St. Kitts og Nevis kn
+St. Kitts en Nevis kn
+St. Kitts og Nevis kn
+St. Kitts le Nevis kn
+St. Kitts e Nevis kn
+St. Kitts e Nevis kn
+St Kitts e Nevis kn
+Sf. Kitts şi Nevis kn
+о. Св. Кристофа и Невиса kn
+St. Kitts a Nevis kn
+St. Kitts in Nevis kn
+St. Kitts i Nevis kn
+I-St. Kitts and Nevis kn
+St. Kitts och Nevis kn
+¦ºÂ¢ý𠸢ðÍ & ¦¿Å¢Í kn
+St. Kitts ve Nevis kn
+Федерація Сент-Кітс і Невіс kn
+St. Kitts na Nevis kn
+St. Kitts neNevis kn
+圣基特和里维斯 kn
+聖克理斯多福及尼維斯 kn
+St. Kitts kanye no-Nevis kn
+North Korea kp
+Noord Korea kp
+كوريا الشمالية kp
+Şimali Koreya kp
+Паўночная Карэя kp
+Северна Корея kp
+Norzh-Korea kp
+Sjeverna Koreja kp
+Corea del Nord kp
+Severní Korea kp
+Nordkorea kp
+Nord-Korea kp
+Βόρεια Κορέα kp
+Nordkoreo kp
+Corea del Norte kp
+Põhja-Korea kp
+Ipar Korea kp
+کره شمالی kp
+Pohjois-Korea kp
+Norðurkorea kp
+Corée du nord kp
+Corea do Norte kp
+צפון קוריאה kp
+Sjeverna Koreja kp
+Észak-Korea kp
+Korea Utara kp
+Kórea - Norðurkórea kp
+Corea del Nord kp
+北朝鮮 kp
+조선민주주의 인민공화국 kp
+ເກົາລີເຫນືອ kp
+Šiaurės Korėja kp
+ZiemeļKoreja kp
+Korea ta' Fuq kp
+Nord-Korea kp
+Noord-Korea kp
+Nord-Korea kp
+Lebowa la Korea kp
+Corea dèu Nord kp
+Korea Północna kp
+Coreia do Norte kp
+Coréia do Norte kp
+Coreea de Nord kp
+Северная Корея kp
+severná Kórea kp
+Severna Koreja kp
+Severna Koreja kp
+I-North Korea kp
+Nordkorea kp
+ż ¦¸¡Ã¢Â¡ kp
+เกาหลีเหนือ kp
+Kuzey Kore kp
+Північна Корея kp
+Devhula ha Korea kp
+Bắc Triều Tiên kp
+Bijhe Coreye kp
+Umntla Korea kp
+朝鲜 kp
+北韓 kp
+Enyakatho ne-Korea kp
+South Korea kr
+Suid Korea kr
+كوريا الجنوبية kr
+Cənubi Koreya kr
+Паўднёвая Карэя kr
+Южна Корея kr
+Su-Korea kr
+Južna Koreja kr
+Corea del Sud kr
+Jižní Korea kr
+Sydkorea kr
+Süd-Korea kr
+Νότια Κορέα kr
+Sudkoreo kr
+Corea del Sur kr
+Lõuna-Korea kr
+Hego Korea kr
+کره جنوبی kr
+Etelä-Korea kr
+Suðurkorea kr
+Corée du sud kr
+Corea do Sur kr
+דרום קוריאה kr
+Južna Koreja kr
+Dél-Korea kr
+Korea Selatan kr
+Kórea - Suðurkórea kr
+Corea del Sud kr
+韓国 kr
+대한민국 kr
+ເກົາລີໃຕ້ kr
+Pietų Korėja kr
+DievidKoreja kr
+Korea t'Isfel kr
+Sør-Korea kr
+Zuid-Korea kr
+Sør-Korea kr
+Borwa bja Korea kr
+Corea dèu Sud kr
+Korea Południowa kr
+Coreia do Sul kr
+Coréia do Sul kr
+Coreea de Sud kr
+Южная Корея kr
+Južná Kórea kr
+Južna Koreja kr
+Južna Koreja kr
+I-South Korea kr
+Sydkorea kr
+¦¾ý ¦¸¡Ã¢Â¡ kr
+เกาหลีใต้ kr
+Güney Kore kr
+Південна Корея kr
+Korea tshipembe kr
+Hàn Quốc kr
+Nonne Coreye kr
+Umzantsi Korea kr
+韩国 kr
+南韓 kr
+Emzansi Korea kr
+Kuwait kw
+Kuwaït kw
+الكويت kw
+Кувэйт kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+Κουβέιτ kw
+Kuveit kw
+کویت kw
+Kuvait kw
+Kowait kw
+כווית kw
+Kuvajt kw
+Kuvait kw
+クェート kw
+쿠웨이트 kw
+ແຕ້ມຮູບ- K kw
+Kuveitas kw
+Koeweit kw
+Koweit kw
+Kuveit kw
+Кувейт kw
+Kuvajt kw
+Kuvajt kw
+I-Kuwait kw
+̨Åò kw
+KКувейт kw
+科威特 kw
+科威特 kw
+Cayman Islands ky
+Кайманови Острови ky
+Kajmanska ostrva ky
+Cayman-øerne ky
+Islas Caimán ky
+Kaiman Irlak ky
+Kajmán-szigetek ky
+ຄາຕາລັນ ky
+Ilhas Cayman ky
+Kajmanske Ostrovy ky
+Kajmanski otoki ky
+Caymanöarna ky
+Кайманські острови ky
+开曼群岛 ky
+Kazakhstan kz
+Казахстан kz
+Казахстан kz
+Kazahstan kz
+Kazakhstán kz
+Kazahsztán kz
+ແກແລກຕິກ - K kz
+Kazaquistão kz
+Kazachstan kz
+Kazahstan kz
+Kazakstan kz
+Казахстан kz
+哈萨克斯坦 kz
+Laos la
+Лаос la
+Лаос la
+Laosz la
+ລາວ la
+老挝 la
+Lebanon lb
+Libanon lb
+لبنان lb
+Ліван lb
+Ливан lb
+Liban lb
+Libanon lb
+Libanon lb
+Libanon lb
+Λίβανος lb
+Lebanono lb
+Líbano lb
+Liibanon lb
+لبنان lb
+Libanon lb
+Libanon lb
+Liban lb
+לבנון lb
+Libanon lb
+Libanon lb
+Libano lb
+レバノン lb
+레바논 lb
+ເດນ່ງນ lb
+Libanas lb
+Libanu lb
+Libanon lb
+Libanon lb
+Libanon lb
+Liban lb
+Líbano lb
+Líbano lb
+Liban lb
+Ливан lb
+Libanon lb
+Libanon lb
+I-Lebanon lb
+Libanon lb
+¦ÄÀÉ¡ý lb
+Ліван lb
+Liban lb
+黎巴嫩 lb
+黎巴嫩 lb
+St. Lucia lc
+سانت لوسيا lc
+Св. Люсиа lc
+S. Lucia lc
+Svatá Lucie lc
+Σάντα Λουτσία lc
+St. Lucio lc
+Santa Lucía lc
+سن لوسیا lc
+Sankta Lusia lc
+Sainte Lucie lc
+Santa Lucía lc
+סנטה לוסיה lc
+Santa Lucia lc
+セントルキア lc
+세인트 루시아 lc
+ເຊັນລູເຊີຍ lc
+Šv Liucija lc
+Sv. Lūcija lc
+St. Luċija lc
+Santa Lúcia lc
+Santa Lúcia lc
+Sf. Lucia lc
+о. Св. Люсии lc
+Sv. Júlia lc
+Sv. Lucija lc
+I-St. Lucia lc
+¦ºýð æº¢Â¡ lc
+เซนต์ลูเซีย lc
+Санта Лучія lc
+圣路西亚 lc
+聖露西亞 lc
+Liechtenstein li
+Ліхтэнштэйн li
+Лихтенщайн li
+Lihtenštajn li
+Liechtestein li
+ຟ້າແມບ li
+列支敦士登 li
+Sri Lanka lk
+Шры-Ланка lk
+Шри Ланка lk
+Šri Lanka lk
+ເຊີເບີຍ lk
+Šri Lanka lk
+斯里兰卡 lk
+Liberia lr
+Лібэрыя lr
+Либеря lr
+Liberija lr
+Libéria lr
+ລິຊາ lr
+Libéria lr
+Lýbia lr
+Liberija lr
+利比里亚 lr
+Lesotho ls
+Лесота ls
+Лесото ls
+Lesoto ls
+Lesoto ls
+ທົດສອບ ls
+Lesoto ls
+莱索托 ls
+Lithuania lt
+Lithuanië lt
+ليتوانيا lt
+Litvaniya lt
+Літва lt
+Литва lt
+Litvanija lt
+Lituània lt
+Litva lt
+Litauen lt
+Litauen lt
+Λιθουανία lt
+Litovio lt
+Lituania lt
+Leedu lt
+Lituania lt
+لیتوانی lt
+Liettua lt
+Lituanie lt
+ליטא lt
+Litva lt
+Litvánia lt
+Litháenska lt
+Lituania lt
+リトアニア lt
+리 투아니아 lt
+ລິທົ່ວເນີຍ lt
+Lietuva lt
+Lietuva lt
+Litwanja lt
+Litauen lt
+Litouwen lt
+Litauen lt
+Litwa lt
+Lituânia lt
+Lituânia lt
+Lituania lt
+Литва lt
+Litva lt
+Litva lt
+Litvanija lt
+I-Lithuania lt
+Litauen lt
+Ä¢òЧÅɢ¡ lt
+ลิธัวเนีย lt
+Litvanya lt
+Литва lt
+立陶宛 lt
+立陶宛 lt
+Luxembourg lu
+Luxenburg lu
+لوكسمبورغ lu
+Lüksemburq lu
+Люксэмбург lu
+Люксембург lu
+Luksemburg lu
+Luxemburg lu
+Lucembursko lu
+Luxemburg lu
+Λουξεμβούργο lu
+Luksemburgo lu
+Luxemburgo lu
+Luksemburg lu
+Luxemburg lu
+لوگزامبورگ lu
+Luxemburg lu
+Luksemborg lu
+לוקסמבורג lu
+Luksemburg lu
+Luxemburg lu
+Lúxemborg lu
+Lussemburgo lu
+ルクセンブルグ lu
+룩셈부르크 lu
+ລັກແຊມເບີກ lu
+Liuksemburgas lu
+Luksemburga lu
+Lussemburgu lu
+Luxemburg lu
+Luksemburg lu
+Luxemburgo lu
+Luxemburgo lu
+Luxemburg lu
+Люксембург lu
+Luxemburg lu
+Luksemburg lu
+Luksemburg lu
+I-Luxembourg lu
+Luxemburg lu
+Äìºõ§À¡÷ì lu
+ลักเซมเบอร์ก lu
+Lüksemburg lu
+Люксембург lu
+Lucsimbork lu
+卢森堡 lu
+盧森堡 lu
+Latvia lv
+لاتفيا lv
+Latviya lv
+Латвія lv
+Латвия lv
+Latvija lv
+Lotyšsko lv
+Letland lv
+Lettland lv
+Λιθουανία lv
+Latvio lv
+Letonia lv
+Läti lv
+لاتویا lv
+Lettonie lv
+לטביה lv
+Latvija lv
+Lettország lv
+Léttland lv
+Lettonia lv
+ラトビア lv
+라트비아 lv
+ລັດເວີຍ lv
+Latvija lv
+Latvija lv
+Latvja lv
+Letland lv
+Łotwa lv
+Letónia lv
+Латвия lv
+Lotyšsko lv
+Latvija lv
+Latvija lv
+I-Latvia lv
+Lettland lv
+ÄðŢ¡ lv
+ลัธเวีย lv
+Litvanya lv
+Латвія lv
+Lativia lv
+拉脱维亚 lv
+拉脫維亞 lv
+Libya ly
+Libië ly
+ليبيا ly
+Лівія ly
+Либия ly
+Libija ly
+Líbia ly
+Lýbie ly
+Libyen ly
+Libyen ly
+Λιβύη ly
+Libia ly
+Liibüa ly
+Libia ly
+لیبی ly
+Lybie ly
+לוב ly
+Líbia ly
+Libia ly
+リビア ly
+ລິຊາ ly
+Libija ly
+Libië ly
+Libia ly
+Líbia ly
+Líbia ly
+Ливия ly
+Lýbia ly
+Libija ly
+I-Libya ly
+Libyen ly
+Ä¢À¢Â¡ ly
+Лівія ly
+利比亚 ly
+利比亞 ly
+Morocco ma
+Morokko ma
+المغرب ma
+Марока ma
+Мароко ma
+Maroko ma
+Marroc ma
+Maroko ma
+Marokko ma
+Marokko ma
+Μαρόκο ma
+Moroko ma
+Marruecos ma
+Maroko ma
+Maroko ma
+مراکش ma
+Marokko ma
+Marokko ma
+Maroc ma
+מרוקו ma
+Maroko ma
+Marokkó ma
+Marocco ma
+モロッコ ma
+모로코 ma
+ເມົາລິ ma
+Marokas ma
+Marokk ma
+Marokko ma
+Marokko ma
+Marokko ma
+Maroko ma
+Marrocos ma
+Marrocos ma
+Maroc ma
+Марокко ma
+Maroko ma
+Maroko ma
+I-Morocco ma
+Marocko ma
+§Á¡Ã¡§¸¡ ma
+Марокко ma
+Marok ma
+摩洛哥 ma
+摩洛哥 ma
+Monaco mc
+Манака mc
+Монако mc
+Monako mc
+Mónaco mc
+ເມົາລິ mc
+Mônaco mc
+Monako mc
+Monako mc
+摩纳哥 mc
+Moldova md
+Малдова md
+Молдова md
+Moldavia md
+Moldavia md
+ສະໂລວັກ md
+Moldávsko md
+Moldavien md
+摩尔多瓦 md
+Madagascar mg
+Мадагаскар mg
+Мадагаскар mg
+Madagaskar mg
+Madagaszkár mg
+ຄາສະບາລ - K mg
+Madagaskar mg
+Madagaskar mg
+Madagaskar mg
+马达加斯加 mg
+Marshall Islands mh
+Маршаллавы астравы mh
+Маршалови Острови mh
+Maršalova ostrva mh
+Marshall-øerne mh
+Islas Marshall mh
+Marshall Irlak mh
+Marshall-szigetek mh
+ລາດສະອານາຈັກໄທຍ mh
+Ilhas Marshall mh
+Maršálove ostrovy mh
+Marshallovi otoki mh
+Marshallöarna mh
+马绍尔群岛 mh
+Macedonia mk
+Makedoniese mk
+مقدونيا mk
+Makedonya mk
+Македонія mk
+Македония mk
+Makedonia mk
+Makedonija mk
+Macedònia mk
+Makedonie mk
+Makedonien mk
+Makedonien mk
+Μακεδονία mk
+Macedonio mk
+Makedoonia mk
+Mazedonia mk
+مقدونیه mk
+Makedonia mk
+Macédoine mk
+מקדוניה mk
+Makedonija mk
+Macedónia mk
+Masedonia mk
+Makedónía mk
+マケドニア語 mk
+마케도니아 mk
+ມາເຊໂດເນີຍ mk
+Makedonija mk
+Maķedonija mk
+Maċedonja mk
+Makedonia mk
+Macedonië mk
+Makedonia mk
+Macedònian mk
+Macedónia mk
+Macedônia mk
+Македония mk
+Macedónsky mk
+Makedonija mk
+Makedonija mk
+I-Macedonia mk
+Makedonien mk
+Á¡º¢§¼¡É¢Â¡ mk
+มาเซโดเนีย mk
+Makedonya mk
+Македонія mk
+Masedonia mk
+马其顿 mk
+馬其頓 mk
+Mali ml
+Малі ml
+Мали ml
+ຈົດຫມາຍ ml
+马里 ml
+Myanmar mm
+М'янма mm
+Майнмар mm
+Mjanmar mm
+Burma mm
+Birmania mm
+ຕົວຮງກພີື້ນທີ່ທຳງານ - K mm
+Mjanmar mm
+缅甸 mm
+Mongolia mn
+Манголія mn
+Монголия mn
+Mongolija mn
+Mongoliet mn
+Mongólia mn
+ລອກອິນ mn
+Mongólia mn
+Mongolsko mn
+Mongolija mn
+Mongoliet mn
+蒙古 mn
+Macau mo
+Макао mo
+Makau mo
+Macao mo
+Makaó mo
+ມອລຕາ mo
+Makao mo
+Macao mo
+澳门 mo
+Martinique mq
+Мартиника mq
+Martinik mq
+Martinica mq
+ເມົາລິ mq
+Martinik mq
+马提尼克岛 mq
+Mauritania mr
+Маўрытанія mr
+Мавритания mr
+Mauritanija mr
+Mauretanien mr
+Mauritánia mr
+ລິທົວເນີຍ mr
+Mauritânia mr
+Mavretanija mr
+Mauretanien mr
+毛里塔尼亚 mr
+Montserrat ms
+Монсерат ms
+Monsera ms
+ຈໍພາບ ms
+蒙特塞拉特岛 ms
+Malta mt
+مالطة mt
+Мальта mt
+Малта mt
+Μάλτα mt
+Malto mt
+مالت mt
+Malte mt
+מלטה mt
+Málta mt
+マルタ mt
+왈타 mt
+ມອລຕາ mt
+Мальта mt
+I-Malta mt
+Á¡ø¼¡ mt
+มอลตา mt
+Мальта mt
+Male mt
+马耳他 mt
+馬爾他 mt
+Mauritius mu
+Маўрыцы mu
+Маурици mu
+Mauricijus mu
+Mauricio mu
+ພາທິຊັ້ນ mu
+Maurícius mu
+Mavricij mu
+毛里求斯 mu
+Maldives mv
+Мальдывы mv
+Малдиви mv
+Maldivi mv
+Maldiverne mv
+Maldivas mv
+Maldív-szigetek mv
+ມັລດິສ mv
+Maldivas mv
+Maldiv mv
+Maldiverna mv
+马尔代夫 mv
+Malawi mw
+Малаві mw
+Малави mw
+Malavi mw
+ມອລຕາ mw
+马拉维 mw
+Mexico mx
+Meksiko mx
+المكسيك mx
+Meksika mx
+Мэксыка mx
+Мексико mx
+Mec'hiko mx
+Meksiko mx
+Mèxic mx
+Mexiko mx
+Mexiko mx
+Μεξικό mx
+Meksikujo mx
+México mx
+Mehhiko mx
+Mexiko mx
+مکزیک mx
+Meksiko mx
+Meksiko mx
+Mexique mx
+México mx
+מקסיקו mx
+Meksiko mx
+Mexikó mx
+Meksiko mx
+Mexíkó mx
+Messico mx
+メキシコ mx
+멕시코 mx
+ເມັກຊີໂກ mx
+Meksika mx
+Meksika mx
+Messiku mx
+Mèxic mx
+Meksyk mx
+México mx
+México mx
+Mexic mx
+Мексика mx
+Mexiko mx
+Mehika mx
+Meksiko mx
+I-Mexico mx
+¦Á캢§¸¡ mx
+เม็กซิโก mx
+Meksika mx
+Мексика mx
+Mê hi cô mx
+Mecsike mx
+墨西哥 mx
+墨西哥 mx
+Malaysia my
+Малайзыя my
+Малайзия my
+Malezija my
+Malasia my
+Malasia my
+Malajzia my
+ມອລຕາ my
+Malásia my
+Malajzia my
+Malezija my
+马来西亚 my
+Mozambique mz
+Мазамбік mz
+Мозамбик mz
+Mozambik mz
+Mozambik mz
+ຫນ່ວຍຄວາມຈຳ mz
+Moçambique mz
+Mozambik mz
+Mozambik mz
+Moçambique mz
+莫桑比克 mz
+Namibia na
+Намібія na
+Намибия na
+Namibija na
+Namíbia na
+ຈາໄມກາ na
+Namíbia na
+Namíbia na
+Namibija na
+纳米比亚 na
+New Caledonia nc
+Нова Каледония nc
+Nova Kaledonija nc
+Ny Caledonien nc
+Nueva Caledonia nc
+Kaledonia Berria nc
+Új-Kaledónia nc
+ມາເຊໂດເນີຍ nc
+Nova Caledônia nc
+Nová Kaledónia nc
+Nova Kaledonija nc
+Nya Caledonien nc
+新喀里多尼亚 nc
+Niger ne
+Нігер ne
+Нигер ne
+ຕົວຮງກພື້ນທີ່ທຳງານ ne
+Nigéria ne
+Nigéria ne
+尼日尔 ne
+Norfolk Island nf
+Остров Норфолк nf
+Norfolk ostrvo nf
+Norfolk-øerne (Australien) nf
+Isla Norfolk nf
+Norfok Irla nf
+Norfolk-szigetek nf
+ໂປແລນ nf
+Ilhas Norfolk nf
+Ostrov Norfolk nf
+Otok Norfolk nf
+Norfolkön nf
+诺福克岛 nf
+Nigeria ng
+Нігерыя ng
+Нигерия ng
+Nigerija ng
+Nigéria ng
+ບັນແກເລີຍ ng
+Nigéria ng
+Nigéria ng
+Nigerija ng
+尼日利亚 ng
+Nicaragua ni
+Nikaragua ni
+نيكاراغوا ni
+Нікарагуа ni
+Никарагуа ni
+Nikaragva ni
+Nikaragua ni
+Νικαράγουα ni
+Nikaraagua ni
+نیکاراگویه ni
+Nikaragua ni
+Nikaragua ni
+ניקרגווה ni
+ニカラグア ni
+니카라과 ni
+ປາລາກກວຍ ni
+Nikaragua ni
+Nikaragwa ni
+Nikaragua ni
+Nicarágua ni
+Nicarágua ni
+Никарагуа ni
+Nikaragua ni
+Nikaragva ni
+I-Nicaragua ni
+¿¢¸Ã¡Ì§Å ni
+Nikaragua ni
+Нікарагуа ni
+尼加拉瓜 ni
+尼加拉瓜 ni
+Netherlands nl
+Nederland nl
+هولندا nl
+Hollandiya nl
+Галяндыя nl
+Холандия nl
+Izelvroioù nl
+Nizozemska nl
+Holanda nl
+Nizozemí nl
+Holland nl
+Niederlande nl
+Κάτω Χώρες nl
+Nederlando nl
+Países Bajos nl
+Holland nl
+Holanda nl
+هلند nl
+Alankomaat nl
+Háland nl
+Pays bas nl
+Países Baixos nl
+הולנד nl
+Nizozemska nl
+Hollandia nl
+Belanda nl
+Holland nl
+Paesi Bassi nl
+オランダ nl
+네덜란드 nl
+ເນເທີແລນ์ nl
+Olandija nl
+Nīderlande nl
+Nederland nl
+Nederland nl
+Nederland nl
+Holanda nl
+Holandia nl
+Países Baixos nl
+Holanda nl
+Olanda nl
+Нидерланды nl
+Holandsko nl
+Nizozemska nl
+Holandija nl
+I-Netherlands nl
+Nederländerna nl
+¦¿¾÷Ä¡óÐ nl
+เนเธอร์แลนด์ nl
+Hollanda nl
+Голландія nl
+Hà Lan nl
+荷兰 nl
+荷蘭 nl
+Norway no
+Noorweë no
+النرويج no
+Norveç no
+Нарвэгія no
+Норвегия no
+Norvegia no
+Norveška no
+Noruega no
+Norsko no
+Norge no
+Norwegen no
+Νορβηγία no
+Norvegio no
+Noruega no
+Norra no
+Norvegia no
+نروژ no
+Norja no
+Norra no
+Norvège no
+Noruega no
+נורבגיה no
+Norveška no
+Norvégia no
+Norwegia no
+Noregur no
+Norvegia no
+ノルウェー no
+노르웨이 no
+ນໍເວ no
+Norvegija no
+Norvēģija no
+Norveġja no
+Norge no
+Noorwegen no
+Noreg no
+Noruega no
+Norwegia no
+Noruega no
+Noruega no
+Norvegia no
+Норвегия no
+Nórsko no
+Norveška no
+Norveška no
+I-Norway no
+Norge no
+¿¡÷§Å no
+นอร์เวย์ no
+Norveç no
+Норвегія no
+Na uy no
+挪威 no
+挪威 no
+Nepal np
+Нэпал np
+Непал np
+Nepál np
+ເວນດາ np
+尼泊尔 np
+Nauru nr
+Науру nr
+Науру nr
+Naurú nr
+ປາລາກກວຍ nr
+瑙鲁 nr
+Niue nu
+Ниуе nu
+ເນ໊ຕ nu
+纽埃岛 nu
+New Zealand nz
+Nuwe Seeland nz
+نيوزيلاندا nz
+Yeni Zellandiya nz
+Новая Зэляндыя nz
+Нова Зеландия nz
+Zeland nevez nz
+Novi Zeland nz
+Nova Zelanda nz
+Nový Zéland nz
+Neuseeland nz
+Νέα Ζηλανδία nz
+Novzelando nz
+Nueva Zelanda nz
+Uus-Meremaa nz
+Zelanda Berria nz
+زلاندنو nz
+Uusi-Seelanti nz
+Nýsæland nz
+Nouvelle Zélande nz
+Nova Celandia nz
+ניו זילנד nz
+Novi Zeland nz
+Új-Zéland nz
+Selandia Baru nz
+Nýja Sjáland nz
+Nuova Zelanda nz
+ニュージーランド nz
+뉴질랜드 nz
+ນີວຊີແລນ nz
+Naujoji Zelandija nz
+JaunZēlande nz
+Nieuw Zeeland nz
+Navera Zelanda nz
+Nowa Zelandia nz
+Nova Zelândia nz
+Nova Zelândia nz
+Noua Zeelandă nz
+Новая Зеландия nz
+Nový Zéland nz
+Nova Zelandija nz
+Novi Zeland nz
+I-New Zealand nz
+Nya Zeeland nz
+¿¢äº¢Ä¡óÐ nz
+นิวซีแลนด์ nz
+Yeni Zelanda nz
+Нова Зеландія nz
+Nouve Zelande nz
+新西兰 nz
+紐西蘭 nz
+Oman om
+عُمان om
+Аман om
+Оман om
+Omán om
+Ομάν om
+Omano om
+Omán om
+Omaan om
+عمان om
+עומן om
+Omán om
+オマーン om
+오만 om
+ເຍີຍລະມັນ om
+Omanas om
+Omã om
+Оман om
+Omán om
+I-Oman om
+µÁý om
+Umman om
+Оман om
+ Oman om
+阿曼 om
+阿曼 om
+Panama pa
+بنما pa
+Панама pa
+Панама pa
+Panamà pa
+Παναμάς pa
+Panamo pa
+Panamá pa
+پاناما pa
+Panamá pa
+פנמה pa
+パナマ pa
+파나마 pa
+ປານາມາ pa
+Panamá pa
+Panamá pa
+Панама pa
+I-Panama pa
+ÀÉ¡Á¡ pa
+ปานามา pa
+Панама pa
+巴拿马 pa
+巴拿馬 pa
+Peru pe
+البيرو pe
+Пэру pe
+Перу pe
+Perou pe
+Perú pe
+Περού pe
+Peruo pe
+Perú pe
+Peruu pe
+پرو pe
+Pérou pe
+Perú pe
+פרו pe
+Perú pe
+Perù pe
+ペルー pe
+페루 pe
+ເປລູ pe
+Perū pe
+Pero pe
+Perú pe
+Перу pe
+I-Peru pe
+¦ÀÕ pe
+เปรู pe
+Перу pe
+Perou pe
+秘鲁 pe
+秘魯 pe
+French Polynesia pf
+Француская Палінэзія pf
+Френска Полинезия pf
+Francuska Polinezija pf
+Fransk Polynesien pf
+Polinesia francesa pf
+Polinesia Frantziarra pf
+Francia-Polinézia pf
+ຝຣັ່ງເສດ pf
+Polinésia Francesa pf
+Francúzska Polynézia pf
+Francoska Polinezija pf
+Franska Polynesien pf
+法属波利尼西亚 pf
+Papua New Guinea pg
+Папуа–Новая Гвінэя pg
+Папуа и Нова Гвинея pg
+Papua Nova Gvineja pg
+Papua Nueva Guinea pg
+Papua Ginea Berria pg
+Pápua Új-Guinea pg
+ເທົາອ່ອນ pg
+Nova Guiné Papua pg
+Papua Nová Guinea pg
+Papua Nova Gvineja pg
+Papua Nya Guinea pg
+巴布亚新几内亚 pg
+Philippines ph
+Філіпіны ph
+Филипини ph
+Filipini ph
+Filippinerne ph
+Filipinas ph
+Filipinak ph
+Fülöp-szigetek ph
+ອາລະປະໂຫຍດ ph
+Filipinas ph
+Filipíny ph
+Filipini ph
+Filippinerna ph
+菲律宾 ph
+Pakistan pk
+Пакістан pk
+Пакистан pk
+Pakisztán pk
+ລງບ pk
+Paquistão pk
+巴基斯坦 pk
+Poland pl
+Poolland pl
+بولندا pl
+Polşa pl
+Польшча pl
+Полша pl
+Polonia pl
+Poljska pl
+Polònia pl
+Polsko pl
+Polen pl
+Polen pl
+Πολωνία pl
+Pollando pl
+Polonia pl
+Poola pl
+Polonia pl
+لهستان pl
+Puola pl
+Pólland pl
+Pologne pl
+Polonia pl
+פולין pl
+Poljska pl
+Lengyelország pl
+Polandia pl
+Pólland pl
+Polonia pl
+ポーランド pl
+폴란드 pl
+ໂປແລນ pl
+Lenkija pl
+Polija pl
+Polonja pl
+Polen pl
+Polen pl
+Polen pl
+Polònia pl
+Polska pl
+Polónia pl
+Polônia pl
+Polonia pl
+Польша pl
+Poľsko pl
+Poljska pl
+Poljska pl
+I-Poland pl
+Polen pl
+§À¡Ä¡óÐ pl
+โปแลนด์ pl
+Polonya pl
+Польща pl
+Pholandi pl
+Ba Lan pl
+Pologne pl
+波兰 pl
+波蘭 pl
+Saint Pierre and Miquelon pm
+Sveti Pjer i Migelon pm
+Saint Pierre og Miquelon pm
+Saint Pierre y Miquelon pm
+Saint Pierre eta Miquelon pm
+Saint Pierre és Miquelon pm
+Saint Pierre e Miquelon pm
+Saint Pierre a Miquelon pm
+Sveti Pierre in Miquelon pm
+Saint Pierre och Miquelon pm
+圣皮埃尔和密克隆岛 pm
+Pitcairn pn
+Pitkern pn
+ລງບ pn
+Puerto Rico pr
+Пуерто Рико pr
+Portoriko pr
+ໂປຣໂຕຄອນ pr
+Porto Rico pr
+Portoriko pr
+波多尼各 pr
+Palestinian Territory ps
+Palesteinse Gebied ps
+السلطة الفلسطينية ps
+Палестынская тэрыторыя ps
+Палестина ps
+Palestinska teritorija ps
+Territori Palestí ps
+Palestinské území ps
+Palæstinensiske selvstyreområder ps
+Palästinensisches Gebiet ps
+Παλαιστίνη ps
+Palestinaj teritorioj ps
+Territorio palestino ps
+Palestiina territoorium ps
+Palestina ps
+فلسطین ps
+Palestiinalaisalue ps
+Palestinensiska økið ps
+Territoire palestinien ps
+השטחים הפלסטיניים ps
+Palestinski teritorij ps
+Palesztin területek ps
+Territori palestinesi ps
+パレスチナ自治区 ps
+팔레스타인 자치구 ps
+ການພິມຜິດພາດ ps
+Palestinos teritorija ps
+Palestina ps
+Palestinske territorier ps
+Palestijns territorium ps
+Palestinske territorium ps
+Bohwa bja Palestina ps
+Palestyna ps
+Território Palestiniano ps
+Território Palestino ps
+Teritoriul Palestinian ps
+Палестинские территории ps
+Palestínske územia ps
+Palestinski teritorij ps
+I-Palestinian Territory ps
+Palestina ps
+À¡Äо£É ¬¨½Âõ ps
+Filistin Bölgesi ps
+Палестинська територія ps
+Mukano wa maphalesitina ps
+Palestene ps
+Umhlaba wePalestina ps
+巴勒斯坦地区 ps
+巴勒斯坦領地 ps
+Indawo yama-Phalesitina ps
+Portugal pt
+البرتغال pt
+Portuqaliya pt
+Партугалія pt
+Португалия pt
+Portugalsko pt
+Πορτογαλία pt
+Portugalo pt
+پرتغال pt
+Portugali pt
+פורטוגל pt
+Portugália pt
+Portúgal pt
+Portogallo pt
+ポルトガル pt
+포르투갈 pt
+ໂປຣຕຸເກສ pt
+Portugalija pt
+Portugāle pt
+Portugall pt
+Portugalia pt
+Portugalia pt
+Португалия pt
+Portugalsko pt
+Portugalska pt
+I-Portugal pt
+§À¡÷òиø pt
+โปรตุเกส pt
+Portekiz pt
+Португалія pt
+BềEĐào Nha pt
+葡萄牙 pt
+葡萄牙 pt
+Palau pw
+Палау pw
+Палау pw
+ມອລຕາ pw
+帕劳群岛 pw
+Paraguay py
+Paraguaai py
+باراغواي py
+Paraqvay py
+Парагвай py
+Парагвай py
+Paragvaj py
+Paraguai py
+Παραγουάη py
+Paragvajo py
+Paraguai py
+پاراگویه py
+Paraguai py
+פרגואי py
+Paragvaj py
+パラグアイ py
+파라과이 py
+ປາລາກກວຍ py
+Paragvajus py
+Paragvaja py
+Paragwaj py
+Paraguai py
+Paragwaj py
+Paraguai py
+Paraguai py
+Paraguai py
+Парагвай py
+Portugalsko py
+Paragvaj py
+Paragvaj py
+I-Paraguay py
+Àá̧Špy
+ปารากวัย py
+Парагвай py
+Paragway py
+巴拉圭 py
+巴拉圭 py
+Qatar qa
+قطر qa
+Катар qa
+Катар qa
+Katar qa
+Katar qa
+Katar qa
+Κατάρ qa
+Kataro qa
+Katar qa
+قطر qa
+Katar qa
+קטר qa
+Katar qa
+Katar qa
+カタール qa
+카타르 qa
+ມອລຕາ qa
+Katar qa
+Катар qa
+Katar qa
+Katar qa
+I-Qatar qa
+¸¾¡÷ qa
+Katar qa
+Катар qa
+卡塔尔 qa
+卡達 qa
+Romania ro
+Romenië ro
+رومانيا ro
+Rumıniya ro
+Румынія ro
+Румъния ro
+Roumania ro
+Rumunija ro
+Rumunsko ro
+Rumænien ro
+Rumänien ro
+Ρουμανία ro
+Rumanio ro
+Rumanía ro
+Rumeenia ro
+Errumania ro
+رومانی ro
+Rumenia ro
+Roumanie ro
+Romanía ro
+רומניה ro
+Rumunjska ro
+Románia ro
+Rumania ro
+Rúmenía ro
+ルーマニア ro
+루마니아 ro
+ໂລມາເນີຍ ro
+Rumunija ro
+Rumānija ro
+Rumanija ro
+Roemenië ro
+Rumunia ro
+Roménia ro
+Romênia ro
+Румыния ro
+Rumunsko ro
+Romunija ro
+Rumunija ro
+I-Romania ro
+Rumänien ro
+Õ§Áɢ¡ ro
+โรมาเนีย ro
+Romanya ro
+Румунія ro
+Ru ma ni ro
+Roumaneye ro
+罗马尼亚 ro
+羅馬尼亞 ro
+Russia ru
+Rusland ru
+روسيا ru
+Rusiya ru
+Расея ru
+Русия ru
+Rusia ru
+Rusija ru
+Rússia ru
+Rusko ru
+Rusland ru
+Russland ru
+Ρωσία ru
+Ruslando ru
+Rusia ru
+Venemaa ru
+Errusia ru
+روسیه ru
+Venäjä ru
+Russland ru
+Russie ru
+Rusia ru
+רוסיה ru
+Rusija ru
+Oroszország ru
+Rusia ru
+Rússland ru
+ロシア ru
+러시아 ru
+ລັດເຊີຍ ru
+Rusija ru
+Krievija ru
+Russja ru
+Russland ru
+Rusland ru
+Russland ru
+Rosja ru
+Rússia ru
+Rússia ru
+Rusia ru
+Россия ru
+Rusko ru
+Rusija ru
+Rusija ru
+I-Russia ru
+Ryssland ru
+ú¢Â¡ ru
+รัสเซีย ru
+Rusya ru
+Росія ru
+Rashia ru
+Nga ru
+Russeye ru
+Rashiya ru
+俄罗斯 ru
+俄羅斯 ru
+Rwanda rw
+Руанда rw
+Руанда rw
+Ruanda rw
+Ruanda rw
+Ruanda rw
+ແພນດ້າ rw
+Ruanda rw
+Ruanda rw
+卢旺达 rw
+Saudi Arabia sa
+Saudi Arabië sa
+السعودية sa
+Саудаўская Арабія sa
+Саудитска Арабия sa
+Saudijska Arabija sa
+Aràbia Saudí sa
+Saúdská Arábie sa
+Saudi Arabien sa
+Saudi-Arabien sa
+Σαουδική Αραβία sa
+Saŭdi-Arabio sa
+Arabia Saudí sa
+Saudi Araabia sa
+عربستان سعودی sa
+Saudi-Arabia sa
+Arabie Saoudite sa
+ערב הסעודית sa
+Saudijska Arabija sa
+Szaúd-Arábia sa
+Arabia saudita sa
+サウジアラビア sa
+사우디 아라비아 sa
+ອາລະບິກ sa
+Saudi Arabija sa
+Għarabja Sawdita sa
+Saudi-Arabia sa
+Saudi-Arabië sa
+Saudi-Arabia sa
+Arabia Saudyjska sa
+Arábia Saudita sa
+Arábia Saudita sa
+Arabia Saudită sa
+Саудовская Аравия sa
+Saudská arábia sa
+Saudova Arabija sa
+I-Saudi Arabia sa
+Saudiarabien sa
+º×¾¢ «§ÃÀ¢Â¡ sa
+Suudi Arabistan sa
+Саудівська Аравія sa
+沙特阿拉伯 sa
+沙烏地阿拉伯 sa
+Solomon Islands sb
+Саламонавы астравы sb
+Соломонови Острови sb
+Solomonska ostrva sb
+Salomon-øerne sb
+Islas Salomón sb
+Solomon Irlak sb
+Salamon-szigetek sb
+ສະໂລວະເນີຍ sb
+Ilhas Salomão sb
+Šalamúnove ostrovy sb
+Solomonovi otoki sb
+Salomonöarna sb
+所罗门群岛 sb
+Seychelles sc
+Сэйшэлы sc
+Сейшелски острови sc
+Sejšeli sc
+Seychellerne sc
+ເຊລ sc
+Sejšeli sc
+Seychellerna sc
+塞舌尔 sc
+Sudan sd
+السودان sd
+Судан sd
+Судан sd
+Sudán sd
+Σουδάν sd
+Sudano sd
+Sudán sd
+Sudaan sd
+سودان sd
+Sudania sd
+Soudan sd
+סודן sd
+Szudán sd
+Súdan sd
+スーダン sd
+수단 sd
+ຊູດານ sd
+Sudanas sd
+Sudāna sd
+Sudão sd
+Sudão sd
+Судан sd
+Sudán sd
+I-Sudan sd
+ݼ¡ý sd
+ซูดาน sd
+Судан sd
+Sudani sd
+Soudan sd
+苏丹 sd
+蘇丹 sd
+Sweden se
+Swede se
+السويد se
+İsveç se
+Швэцыя se
+Швеция se
+Sveden se
+Švedska se
+Suècia se
+Švédsko se
+Sverige se
+Schweden se
+Σουηδία se
+Svedio se
+Suecia se
+Rootsi se
+Suedia se
+سوید se
+Ruotsi se
+Svøriki se
+Suède se
+Suecia se
+שבדיה se
+Švedska se
+Svédország se
+Swedia se
+Svíþjóð se
+Svezia se
+スウェーデン se
+스웨덴 se
+ສະວີເດນ se
+Švedija se
+Zviedrija se
+Svezja se
+Sverige se
+Zweden se
+Sverige se
+Suècia se
+Szwecja se
+Suécia se
+Suécia se
+Suedia se
+Швеция se
+Švédsko se
+Švedska se
+Švedska se
+I-Sweden se
+Sverige se
+ÍÅ£¼ý se
+สวีเดน se
+İsveç se
+Швеція se
+Swidene se
+Thuỵ Điển se
+瑞典 se
+瑞典 se
+Singapore sg
+Сынгапур sg
+Сингапур sg
+Singapur sg
+Singapur sg
+Szingapúr sg
+ໂຊນາ sg
+Singapura sg
+Singapur sg
+Singapur sg
+新加坡 sg
+Saint Helena sh
+Свети Елена sh
+Sveta Helena sh
+St. Helena sh
+Santa Helena sh
+Szent Heléna sh
+ຫົວເລື່ອງ sh
+Santa Helena sh
+Svätá Helena sh
+Sveta Helena sh
+圣赫勒拿岛 sh
+Slovenia si
+Slovenië si
+سلوفينيا si
+Sloveniya si
+Славенія si
+Словения si
+Slovenija si
+Eslovenia si
+Slovinsko si
+Slovenien si
+Slowenien si
+Σλοβενία si
+Slovenio si
+Eslovenia si
+Sloveenia si
+Eslovenia si
+اسلوانی si
+Slovénie si
+Eslovenia si
+סלובניה si
+Slovenija si
+Szlovénia si
+Slóvenía si
+スロベニア si
+슬로베니아 si
+ສະໂລວະເນີຍ si
+Slovėnija si
+Slovēnija si
+Slovenja si
+Slovenië si
+Eslovenia si
+Słowenia si
+Eslovénia si
+Eslovênia si
+Словения si
+Slovinsko si
+Slovenija si
+Slovenija si
+I-Slovenia si
+Slovenien si
+ͧġŢɢ¡ si
+สโลเวเนีย si
+Slovenya si
+Словенія si
+斯洛文尼亚 si
+斯洛維尼亞 si
+Slovakia sk
+Slovakië sk
+سلوفاكيا sk
+Slovakiya sk
+Славакія sk
+Словакия sk
+Slovačka sk
+Eslovaquia sk
+Slovensko sk
+Slovakiet sk
+Slowakien sk
+Σλοβακία sk
+Slovakujo sk
+Eslovaquia sk
+Slovakkia sk
+Eslovakia sk
+اسلواکی sk
+Slovaquie sk
+סלובקיה sk
+Slovačka sk
+Szlovákia sk
+Slóvakía sk
+Slovacchia sk
+スロバキア sk
+슬로바키아 sk
+ສະໂລວັກ sk
+Slovakija sk
+Slovākija sk
+Slovakja sk
+Slovakije sk
+Słowacja sk
+Eslováquia sk
+Eslováquia sk
+Slovacia sk
+Словакия sk
+Slovensko sk
+Slovaška sk
+I-Slovakia sk
+Slovakien sk
+ͧġš츢 sk
+สโลวัค sk
+Slovakya sk
+Словакія sk
+斯洛伐克 sk
+斯洛伐克 sk
+San Marino sm
+Сан-Марына sm
+Сан Марино sm
+ໂຊນາ sm
+圣马力诺 sm
+Senegal sn
+Сэнэгал sn
+Сенегал sn
+Szenegál sn
+ທົ່ວໄປ sn
+塞内加尔 sn
+Somalia so
+Somalië so
+صومال so
+Самалі so
+Сомалия so
+Somalija so
+Somàlia so
+Somálsko so
+Σομαλία so
+Somalio so
+Somaalia so
+سومالی so
+Somalie so
+סומליה so
+Somalija so
+Szomália so
+ソマリア so
+소말리아 so
+ໂລມາເນີຍ so
+Somalis so
+Somalija so
+Somalie so
+Somália so
+Somália so
+Сомали so
+Somálsko so
+Somalija so
+I-Somalia so
+§º¡Á¡Ä¢Â¡ so
+Somali so
+Сомалі so
+Somaleye so
+索马里 so
+索馬利亞 so
+Suriname sr
+Сурынам sr
+Суринам sr
+Surinam sr
+ເຊີເບີຍ sr
+Surinam sr
+Surinam sr
+Surinam sr
+Sao Tome and Principe st
+Сан Томе и Приницпе st
+Sao Tome i Principe st
+Sao Tomé og Principe st
+Sao Tome y Príncipe st
+Sao Tome eta Principe st
+Sao Tome és Principe st
+ບໍລິການ st
+São Tome e Príncipe st
+Sao Tome a Principe st
+Sao Tome in Principe st
+São Tomé och Príncipe st
+El Salvador sv
+السلفادور sv
+Сальвадор sv
+Ел Салвадор sv
+Salvador sv
+Salvador sv
+Ελ Σαλβαντόρ sv
+Elsalvadoro sv
+Salvador sv
+السالوادور sv
+Salvador sv
+O Salvador sv
+אל סלבדור sv
+Salvador sv
+エルサルバドル sv
+엘살바도르 sv
+ເອລຊັນວາດດໍ sv
+Salvadoras sv
+Salvadora sv
+Salwador sv
+Salvador sv
+Сальвадор sv
+Salvádor sv
+Salvador sv
+I-El Salvador sv
+±ø º¡øÅ§¼¡÷ sv
+เอลซัลวาดอร์ sv
+Ель-Сальвадор sv
+萨尔瓦多 sv
+薩爾瓦多 sv
+Syria sy
+Sirië sy
+سوريا sy
+Сырыя sy
+Сирия sy
+Sirija sy
+Síria sy
+Sýrie sy
+Syrien sy
+Syrien sy
+Συρία sy
+Sirio sy
+Siria sy
+Süüria sy
+Siria sy
+سوریه sy
+Syyria sy
+Syrie sy
+סוריה sy
+Sirija sy
+Szíria sy
+Siria sy
+シリア sy
+시리아 sy
+ເຊີເບີຍ sy
+Sirija sy
+Siria sy
+Syrië sy
+Síria sy
+Síria sy
+Siria sy
+Сирия sy
+Sýria sy
+Sirija sy
+I-Syria sy
+Syrien sy
+º¢Ã¢Â¡ sy
+Suriye sy
+Сирія sy
+叙利亚 sy
+敘利亞 sy
+Swaziland sz
+Свазылэнд sz
+Свазиленд sz
+Svazilend sz
+Swazilandia sz
+Swazilandia sz
+Szváziföld sz
+ລາດສະນາຈັກໄທຍ sz
+Suécia sz
+Swazijsko sz
+Svazi sz
+斯威士兰 sz
+Turks and Caicos Islands tc
+Turks i Kaikos ostrva tc
+Turks- og Caicosøerne tc
+Islas Turcos y Caicos tc
+Turks eta Caicos Irlak tc
+Turks- és Caicos-szigetek tc
+Ilhas Caicos e Turca tc
+Turks a Caicos ostrovy tc
+Otoka Turks in Caicos tc
+Turks- och Caicosöarna tc
+特克斯和凯科斯群岛 tc
+Chad td
+Чад td
+Чад td
+Čad td
+Tchad td
+Txad td
+Csád td
+ເກມໄພ່ td
+Čad td
+Čad td
+Tchad td
+乍得 td
+Togo tg
+Тога tg
+Того tg
+ຂອງເລ່ນສະນຸກ tg
+多哥 tg
+Thailand th
+تايلاند th
+Tayland th
+Тайлянд th
+Тайланд th
+Tajland th
+Tailàndia th
+Thajsko th
+Ταϊλάνδη th
+Tajlando th
+Tailandia th
+Tai th
+Thailandia th
+تایلند th
+Thaimaa th
+Tailand th
+Thaïlande th
+Tailandia th
+תאילנד th
+Tajland th
+Thaiföld th
+Tæland th
+Tailandia th
+タイ th
+태국 (타이) th
+ລາດສະນາຈັກໄທຍ th
+Tailandas th
+Taivāna th
+Tajlandja th
+Tailandia th
+Tajlandia th
+Tailândia th
+Tailândia th
+Tailanda th
+Таиланд th
+Thajsko th
+Tajska th
+Tajland th
+I-Thailand th
+¾¡öÄ¡óÐ th
+ราชอาณาจักรไทย th
+Tayland th
+Таїланд th
+Thái Lan th
+Taylande th
+泰国 th
+泰國 th
+Tajikistan tj
+Таджыкістан tj
+Таджикистан tj
+Tadžikistan tj
+Tajikistán tj
+Tadzsikisztán tj
+ໃຕ້ຫວັນ tj
+Tajiquistão tj
+Tadžikistan tj
+Tadžikistan tj
+Tadzjikistan tj
+塔吉克斯坦 tj
+Tokelau tk
+Токелао tk
+ເບລາລັສ tk
+Turkmenistan tm
+Туркмэністан tm
+Туркменистан tm
+Turkmenistán tm
+Türkmenisztán tm
+ຕຸລະກີ tm
+Turquia tm
+土库曼斯坦 tm
+Tunisia tn
+Tunisië tn
+تونس tn
+Туніс tn
+Тунис tn
+Tunis tn
+Tuníssia tn
+Tunisko tn
+Tunesien tn
+Tunesien tn
+Τυνησία tn
+Tunisio tn
+Túnez tn
+Tuneesia tn
+تونس tn
+Tunesia tn
+Tunisie tn
+תוניסיה tn
+Tunis tn
+Tunézia tn
+チュニジア tn
+튀니지 tn
+ລັດເຊີຍ tn
+Tunisas tn
+Tuneżija tn
+Tunisie tn
+Tunezja tn
+Tunísia tn
+Tunísia tn
+Тунис tn
+Tunisko tn
+Tunizija tn
+I-Tunisia tn
+Tunisien tn
+ÐÉ¢º¢Â¡ tn
+Tunus tn
+Туніс tn
+突尼斯 tn
+突尼西亞 tn
+Tonga to
+Тонга to
+Тонга to
+ໂຊນາ to
+汤加 to
+East Timor tp
+Источен Тимур tp
+Istočni Timor tp
+Østtimor tp
+Timor oriental tp
+Ekialdeko Timor tp
+Kelet-Timor tp
+ວັນແລະເວລາ tp
+Timor Leste tp
+Východný Timor tp
+Vzhodni Timor tp
+Östtimor tp
+东帝汶 tp
+Turkey tr
+Turkeye tr
+تركيا tr
+Türkiyə tr
+Турцыя tr
+Турция tr
+Turkia tr
+Turska tr
+Turquia tr
+Turecko tr
+Tyrkiet tr
+Türkei tr
+Τουρκία tr
+Turkujo tr
+Turquía tr
+Türgi tr
+Turkia tr
+ترکیه tr
+Turkki tr
+Turkaland tr
+Turquie tr
+Turquía tr
+טורקיה tr
+Turska tr
+Törökország tr
+Turki tr
+Tyrkland tr
+Turchia tr
+トルコ tr
+터키 tr
+ຕຸລະກີ tr
+Turkija tr
+Turcija tr
+Turkija tr
+Tyrkia tr
+Turkije tr
+Tyrkia tr
+Turquia tr
+Turcja tr
+Turquia tr
+Turquia tr
+Turcia tr
+Турция tr
+Turecko tr
+Turčija tr
+Turska tr
+I-Turkey tr
+Turkiet tr
+ÐÕ츢 tr
+ตุรกี tr
+Türkiye tr
+Туреччина tr
+ThềENhĩ Kì tr
+土耳其 tr
+土耳其 tr
+Trinidad and Tobago tt
+Trinidad en Tobago tt
+ترينيداد و توباغو tt
+Trinidad və Tabaqo tt
+Трынідад і Табага tt
+Тринидад и Тобаго tt
+Trinidad ha Tobago tt
+Trinidad i Tobago tt
+Trinidad i Tobago tt
+Trinidad a Tobago tt
+Trinidad og Tobago tt
+Trinidad und Tobago tt
+Τρίνινταντ και Τομπάγκο tt
+Trinidado kaj Tobago tt
+Trinidad y Tobago tt
+Trinidad ja Tobago tt
+Trinidad eta Tobago tt
+ترینیداد و تُباگو tt
+Trinidad ja Tobago tt
+Trinidad og Tobago tt
+Trinidad et Tobago tt
+Trindade e Tobago tt
+טרינידד וטובגו tt
+Trinidad i Tobago tt
+Trinidad és Tobago tt
+Trinidad dan Tobago tt
+Trinidad og Tobago tt
+Trinidad e Tobago tt
+トリニダードトバコ tt
+트리니다드토바고 tt
+ຕີນິແດດແລະໂທບາໂກ tt
+Trinidadas ir Tobagas tt
+Trinidada un Tobago tt
+Trinidad u Tobago tt
+Trinidad og Tobago tt
+Trinidad en Tobago tt
+Trinidad og Tobago tt
+Trinidad le Tobago tt
+Trinidad e Tobago tt
+Trinidad i Tobago tt
+Trinidade e Tobago tt
+Trinidad e Tobago tt
+Trinidad şi Tobago tt
+Тринидад и Тобаго tt
+Trinidad a Tobago tt
+Trinidad in Tabago tt
+Trinidad i Tobago tt
+I-Trinidad kanye neTobago tt
+Trinidad och Tobago tt
+ðâɢ¼¡ð & ¦¼¡À¡§¸¡ tt
+ตรีนิแดดและโทบาโก tt
+Trinidad veTabago tt
+Республіка Трінідад та Тобаго tt
+Trinidad na Tobago tt
+Trinidad và Tobago tt
+Trinidad ne Tobago tt
+特里尼达和多巴哥 tt
+千里達及托貝哥 tt
+Trinidad knaye ne-Tobago tt
+Tuvalu tv
+Тувалу tv
+Тували tv
+ຊູລູ tv
+图瓦卢 tv
+Taiwan tw
+تايوان tw
+Tayvan tw
+Тайвань tw
+Тайван tw
+Tajvan tw
+Ταϊβάν tw
+Tajvano tw
+Taiwán tw
+Taivan tw
+تایوان tw
+Taivan tw
+Taïwan tw
+Taiwán tw
+טיוואן tw
+Tajvan tw
+Tajvan tw
+台湾 tw
+대만 tw
+ໃຕ້ຫວັນ tw
+Taivanis tw
+Taivāna tw
+Tajwan tw
+Tajwan tw
+Formosa tw
+Тайвань tw
+Tajvan tw
+Tajvan tw
+I-Taiwan tw
+¾¡öÅ¡ý tw
+ได้หวัน tw
+Tayvan tw
+Тайвань tw
+Đài Loan tw
+中国台湾 tw
+台灣 tw
+Tanzania, United Republic of tz
+Злучаная Рэспубліка Танзанія tz
+Танзания tz
+Tanzanija, Ujedinjena Republika tz
+Tanzania tz
+Tanzania, Republica de tz
+Tanazia, Errepublika Batua tz
+Tanzánia tz
+ໂດມິນິກັນ tz
+República da Tanzânia tz
+Tanzánia, Spojená republika tz
+Tanzanija, Združena republika tz
+Förenade republiken Tanzania tz
+坦桑尼亚 tz
+Ukraine ua
+Ukraïne ua
+أوكرانيا ua
+Ukrayna ua
+Украіна ua
+Украйна ua
+Ukraina ua
+Ukrajina ua
+Ucraïna ua
+Ukrajina ua
+Ουκρανία ua
+Ukrainio ua
+Ucrania ua
+Ukraina ua
+Ukrania ua
+اکراین ua
+Ukraina ua
+Ukraina ua
+Ucraína ua
+אוקראינה ua
+Ukrajina ua
+Ukrajna ua
+Ukraina ua
+Úkraína ua
+Ucraina ua
+ウクライナ ua
+우크라이나 ua
+ຍູເຄຣນ ua
+Ukraina ua
+Ukraina ua
+Ukranja ua
+Ukraina ua
+Oekraïne ua
+Ukraina ua
+Ucraina ua
+Ukraina ua
+Ucrânia ua
+Ucrânia ua
+Ucraina ua
+Украина ua
+Ukrajina ua
+Ukrajina ua
+Ukrajna ua
+I-Ukraine ua
+Ukraina ua
+¯ì¦Ãöý ua
+ยูเครน ua
+Ukrayna ua
+Україна ua
+Ukraina ua
+Ucrinne ua
+乌克兰 ua
+烏克蘭 ua
+Uganda ug
+Уганда ug
+Уганда ug
+ແພນດ້າ ug
+乌干达 ug
+United States of America us
+Vereenigde State van Amerika us
+الولايات المتحدة الأمريكية us
+Amerika Birləşmiş Ştatları us
+Злучаныя Штаты Амэрыкі us
+САЩ us
+Stadoù-Unanet Amerika us
+Sjedinjene Američke Države us
+Estats Units d'Amèrica us
+Spojené státy americké us
+USA us
+USA us
+Ην. Πολιτείες της Αμερικής us
+Usono us
+Estados Unidos de América us
+Ameerika Ühendriigid us
+Amerikako Estatu Batuak us
+ایالات متحده‌ی آمریکا us
+Yhdysvallat us
+Sambandsríki Amerika (USA) us
+États Unis d'Amérique us
+Estados Unidos de América us
+ארצות הברית us
+Sjedinjene Američke Države us
+Amerikai Egyesült Államok us
+Amerika Serikat us
+Bandaríki Norður Ameríku us
+Stati Uniti d'America us
+アメリカ us
+미 합중국 us
+ສະຫະລັດອາເມລິກາ us
+Jungtinės Amerikos Valstijos us
+Amerikas Savienotās Valstis us
+Stati Uniti us
+USA us
+Verenigde Staten van Amerika us
+USA us
+Estats Units d'Amèrica us
+Stany Zjednoczone Ameryki us
+Estados Unidos da América us
+Estados Unidos us
+Statele Unite ale Americii us
+Соединенные Штаты Америки us
+USA us
+Združene države Amerike us
+Sjedinjene američke države us
+I-United States of America us
+Amerikas förenta stater us
+³ì¸¢Â «¦ÁÃ¢ì¸ ¿¡Î¸û us
+สหรัฐอเมริกา us
+Amerika Birleşik Devletleri us
+США us
+mashango o tangananaho a America us
+Mĩ us
+United States ye Melika us
+美利坚合众国 us
+美利堅合眾國 us
+Uruguay uy
+الأوروغواي uy
+Uruqvay uy
+Уругвай uy
+Уругвай uy
+Urugvaj uy
+Uruguai uy
+Ουρουγουάη uy
+Urugvajo uy
+Uruguai uy
+اروگویه uy
+Uruguai uy
+אורוגואי uy
+Urugvaj uy
+ウルグアイ uy
+우루과이 uy
+ອຸລຸກກວຍ uy
+Urugvajus uy
+Urugvaja uy
+Urugwaj uy
+Uruguai uy
+Urugwaj uy
+Uruguai uy
+Uruguai uy
+Uruguai uy
+Уругвай uy
+Uruguaj uy
+Urugvaj uy
+Urugvaj uy
+I-Uruguay uy
+¯Õ̧Šuy
+อุรุกวัย uy
+Уругвай uy
+Ourougway uy
+乌拉圭 uy
+烏拉圭 uy
+Uzbekistan uz
+Узбэкістан uz
+Узбекистан uz
+Uzbekistán uz
+Üzbegisztán uz
+ເດນ່ງນ uz
+Uzbequistão uz
+乌兹别克斯坦 uz
+Vatican City va
+Ватыкан va
+Ватикана va
+Vatikan va
+Vatikanstaten va
+Vaticano va
+Batikano Hiria va
+Vatikán va
+ລັດເວີຍ va
+Cidade do Vaticano va
+Vatikán va
+Vatikan va
+Vatikanstaten va
+梵蒂冈 va
+St. Vincent and the Grenadines vc
+St. Vincent en die Grenadene vc
+سانت فينسنت و الغرينادين vc
+St. Vincent və Grenadines vc
+Сент-Винсент и Гренадине vc
+S. Visant hag ar Grenadinez vc
+Sveti Vincent i Grenadini vc
+St. Vincent i les Granadines vc
+St. Vincent a Grenadiny vc
+St. Vincent og Grenadinerne vc
+St. Vincent und Grenadinen vc
+St. Vincent kaj la Grenadinoj vc
+San Vicente y las Granadinas vc
+St. Vincent ja Grenadines vc
+St. Vincent eta Grenadines vc
+سن وینسن و گرادینس vc
+St. Vincent ja Grenadiinit vc
+Sankta Vinsent og Grenadinoyggjar vc
+St Vincent et les Grenadines vc
+San Vicente e as Granadinas vc
+סנט וינסנט והגרנדינים vc
+St. Vincent és Grenadines vc
+St. Vincent dan the Grenadines vc
+St. Vincent og Grenadines vc
+S. Vincent e the Grenadines vc
+セントヴィンセントグレナディン vc
+세인트 빈센트 그레나딘 vc
+ເຊີນວິນແຊນ ແລະເກນາດີນ vc
+Šv. Vincentas ir Grenadinai vc
+Sv. Vincents un Grenadīnes vc
+St. Vinċenz u l-Grenadini vc
+St. Vincent og Grenadinene vc
+St. Vincent en de Grenadines vc
+St. Vincent og Grenadinane vc
+St. Vincent le Grenadines vc
+St. Vincent e les Granadines vc
+St. Vincent i Grenadyny vc
+São Vicente e Grenadinas vc
+São Vicente e Grenadines vc
+Sf. Vincent şi Grenadines vc
+Сент-Винсент и Гренадины vc
+St. Vincent a Grenadines vc
+Sv. Vincent in Grenadini vc
+St. Vincent i Grenadine vc
+I-St. Vincent and the Grenadines vc
+St. Vincent och Grenadinerna vc
+¦ºÂ¢ýð Å¢ý¦ºýð & ¸¢¦ÃÉËý¸û vc
+เซนต์วินเซนต์ และ เกรนาดีน vc
+St. Vincent ve Grenadines vc
+Сент-Вінсент і Гренадіни vc
+St. Vincent na Grenadines vc
+St. Vincent và Grenadines vc
+St. Vincent ne Grenadines vc
+圣文森特和格林那达 vc
+聖文森及格納那丁 vc
+I-St. Vincent kanye ne-Grenadines vc
+Venezuela ve
+فنزويلا ve
+Вэнэсуэла ve
+Венецуела ve
+Venecuela ve
+Βενεζουέλα ve
+Venezuelo ve
+Venetsueela ve
+ونزویلا ve
+Venesuela ve
+Vénézuela ve
+ונצואלה ve
+Venecuela ve
+ベネズェラ ve
+베네수엘라 ve
+ເວເນຊຸເອລາ ve
+Venesuela ve
+Venecuēla ve
+Veneżwela ve
+Wenezuela ve
+Венесуэла ve
+Venecuela ve
+I-Venezuela ve
+¦ÅÉ¢ÍÅÄ¡ ve
+เวเนซูเอลา ve
+Венесуела ve
+委内瑞拉 ve
+委內瑞拉 ve
+Virgin Islands, British vg
+Вирджински Острови, Британски vg
+Djevičanska ostrva, Britanska vg
+Britiske jomfruøer vg
+Islas Vírgenes Británicas vg
+Irla Birjinak, Britaniar vg
+Virgin-szigetek (brit) vg
+Ilhas Virgens, Inglaterra vg
+Panenské Ostrovy, Britské vg
+Deviški otoki, Britanski vg
+Brittiska Jungfruöarna vg
+维尔京群岛,英国 vg
+Virgin Islands, U.S. vi
+Вирджински Острови, Американски vi
+Djevičanska ostrva, Američka vi
+Jomfruøerne vi
+Islas Vírgenes Americanas vi
+Irla Birjinak, EE.BB. vi
+Virgin-szigetek (USA) vi
+Ilhas Virgens, EUA vi
+Panenské Ostrovy, Americké vi
+Deviški otoki, ZDA vi
+Amerikanska Jungfruöarna vi
+维尔京群岛,美国 vi
+Vietnam vn
+Viëtnam vn
+فييتنام vn
+Vyetnam vn
+Віетнам vn
+Виетнам vn
+Vijetnam vn
+Βιετνάμ vn
+Vjetnamo vn
+ویتنام vn
+וייטנאם vn
+Vijetnam vn
+Víetnam vn
+ベトナム vn
+베트남 vn
+ຫວງດນາມ vn
+Vietnamas vn
+Vjetnama vn
+Vjetnam vn
+Viëtnam vn
+Wietnam vn
+Vietname vn
+Vietnã vn
+Вьетнам vn
+I-Vietnam vn
+เวียตนาม vn
+В'єтнам vn
+越南 vn
+越南 vn
+Vanuatu vu
+Вануату vu
+Ванути vu
+ຈີນ vu
+瓦努阿图 vu
+Wallis and Futuna wf
+Valis i Futuna wf
+Wallis- og Futuna-øerne wf
+Wallis y Futuna wf
+Wallis eta Futuna wf
+Wallis és Futuna wf
+ປັກອິນພາບ wf
+Wallis e Futuna wf
+Wallis a Futuna wf
+Wallis in Futuna wf
+Wallis och Futuna wf
+Samoa ws
+Самоа ws
+Самоя ws
+Szamoa ws
+ໂຊນາ ws
+萨摩亚群岛 ws
+Yemen ye
+اليمن ye
+Емен ye
+Йемен ye
+Jemen ye
+Iemen ye
+Jemen ye
+Jemen ye
+Υεμένη ye
+Jemeno ye
+Jeemen ye
+یمن ye
+Jemen ye
+Jemen ye
+תימן ye
+Jemen ye
+Jemen ye
+イエメン ye
+예멘 ye
+ເດມອນ ye
+Jemenas ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Jemen ye
+Iémen ye
+Йемен ye
+Jemen ye
+Jemen ye
+I-Yemen ye
+Jemen ye
+§ÂÁý ye
+Ємен ye
+也门 ye
+葉門 ye
+Yugoslavia yu
+Югаславія yu
+Югославия yu
+Jugoslavija yu
+Jugoslavien (Serbien/Montenegro) yu
+Jugoszlávia yu
+ໂບລິເວີຍ yu
+Iugoslávia yu
+Juhoslávia yu
+Jugoslavija yu
+Jugoslavien yu
+南斯拉夫 yu
+South Africa za
+Suid Afrika za
+جنوب أفريقيا za
+Cənubi Afrika za
+Паўднёвая Афрыка za
+Южна Африка za
+Suafrika za
+Južna Afrika za
+Sudàfrica za
+Jižní Afrika za
+Sydafrikanske republik za
+Südafrika za
+Νότια Αφρική za
+Sudafriko za
+Sudáfrica za
+Lõuna Aafrika za
+Hego Afrika za
+آفریقای جنوبی za
+Etelä-Afrikka za
+Suðurafrika za
+Afrique du sud za
+África do Sur za
+דרום אפריקה za
+Južna Afrika za
+Dél-Afrika za
+Afrika Selatan za
+Suður Afríka za
+Sud Africa za
+南アフリカ za
+남 아프리카 공화국 za
+ແອບພິກາໃຕ້ za
+Pietų Afrika za
+Dienvid Āfrika za
+Afrika t'Isfel za
+Sør-Afrika za
+Zuid-Afrika za
+Sør-Afrika za
+Afrika Borwa za
+Sudafrica za
+Afryka Południowa za
+Africa do Sul za
+África do Sul za
+Africa de Sud za
+Южная Африка za
+Južná Afrika za
+Južna Afrika za
+Južna Afrika za
+I-South Africa za
+Sydafrika za
+¦¾ý ¬ôâ측 za
+แอฟริกาใต้ za
+Güney Afrika za
+Південна Африка za
+Afurika tshipembe za
+Nam Phi za
+Mzantsi Afrika za
+南非 za
+南非 za
+Emzantsi Afrika za
+Zambia zm
+Замбія zm
+Замбия zm
+ຈາໄມກາ້ zm
+Zâmbia zm
+Zambija zm
+赞比亚 zm
+Zimbabwe zw
+Зымбабвэ zw
+Зимбабве zw
+Zimbabve zw
+ລິຊາ zw
+Zimbabve zw
+津巴布韦 zw
diff --git a/addressbook/gui/widgets/e-addressbook-model.c b/addressbook/gui/widgets/e-addressbook-model.c
index 9244df8a38..683eed3499 100644
--- a/addressbook/gui/widgets/e-addressbook-model.c
+++ b/addressbook/gui/widgets/e-addressbook-model.c
@@ -1,641 +1,993 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ * 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.
*
- * Author:
- * Christopher James Lahey <clahey@ximian.com>
+ * 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:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 1999 Ximian, Inc.
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "e-addressbook-model.h"
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <gnome.h>
-#include <gal/widgets/e-gui-utils.h>
-#include "e-addressbook-util.h"
-
-#define PARENT_TYPE gtk_object_get_type()
-GtkObjectClass *parent_class;
-
-/*
- * EAddressbookModel callbacks
- * These are the callbacks that define the behavior of our custom model.
- */
-static void e_addressbook_model_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_addressbook_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+#endif
+#include <string.h>
+#include <glib/gi18n.h>
+#include "e-addressbook-model.h"
+#include <e-util/e-marshal.h>
+#include <e-util/e-util.h>
+#include "eab-gui-util.h"
+
+#define E_ADDRESSBOOK_MODEL_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelPrivate))
+
+struct _EAddressbookModelPrivate {
+ EClientCache *client_cache;
+ gulong client_notify_readonly_handler_id;
+
+ EBookClient *book_client;
+ gchar *query_str;
+ EBookClientView *client_view;
+ guint client_view_idle_id;
+
+ /* Query Results */
+ GPtrArray *contacts;
+
+ /* Signal Handler IDs */
+ gulong create_contact_id;
+ gulong remove_contact_id;
+ gulong modify_contact_id;
+ gulong status_message_id;
+ gulong view_complete_id;
+ guint remove_status_id;
+
+ guint search_in_progress : 1;
+ guint editable : 1;
+ guint first_get_view : 1;
+};
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
+ PROP_0,
+ PROP_CLIENT,
+ PROP_CLIENT_CACHE,
+ PROP_EDITABLE,
+ PROP_QUERY
};
enum {
WRITABLE_STATUS,
STATUS_MESSAGE,
+ SEARCH_STARTED,
SEARCH_RESULT,
FOLDER_BAR_MESSAGE,
- CARD_ADDED,
- CARD_REMOVED,
- CARD_CHANGED,
+ CONTACT_ADDED,
+ CONTACTS_REMOVED,
+ CONTACT_CHANGED,
MODEL_CHANGED,
STOP_STATE_CHANGED,
- BACKEND_DIED,
LAST_SIGNAL
};
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
+static guint signals[LAST_SIGNAL];
-static guint e_addressbook_model_signals [LAST_SIGNAL] = {0, };
+G_DEFINE_TYPE (EAddressbookModel, e_addressbook_model, G_TYPE_OBJECT)
static void
free_data (EAddressbookModel *model)
{
- int i;
-
- for ( i = 0; i < model->data_count; i++ ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- }
+ GPtrArray *array;
- g_free(model->data);
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
+ array = model->priv->contacts;
+ g_ptr_array_foreach (array, (GFunc) g_object_unref, NULL);
+ g_ptr_array_set_size (array, 0);
}
static void
-remove_book_view(EAddressbookModel *model)
-{
- if (model->book_view && model->create_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->create_card_id);
- if (model->book_view && model->remove_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->remove_card_id);
- if (model->book_view && model->modify_card_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->modify_card_id);
- if (model->book_view && model->status_message_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->status_message_id);
- if (model->book_view && model->sequence_complete_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book_view),
- model->sequence_complete_id);
-
- model->create_card_id = 0;
- model->remove_card_id = 0;
- model->modify_card_id = 0;
- model->status_message_id = 0;
- model->sequence_complete_id = 0;
-
- model->search_in_progress = FALSE;
-
- if (model->book_view) {
- e_book_view_stop (model->book_view);
- gtk_object_unref(GTK_OBJECT(model->book_view));
- }
-
- model->book_view = NULL;
-}
-
-static void
-addressbook_destroy(GtkObject *object)
+remove_book_view (EAddressbookModel *model)
{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
-
- if (model->get_view_idle) {
- g_source_remove(model->get_view_idle);
- model->get_view_idle = 0;
- }
-
- remove_book_view(model);
- free_data (model);
-
- if (model->book) {
- if (model->writable_status_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->writable_status_id);
+ if (model->priv->client_view && model->priv->create_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->create_contact_id);
+ if (model->priv->client_view && model->priv->remove_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->remove_contact_id);
+ if (model->priv->client_view && model->priv->modify_contact_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->modify_contact_id);
+ if (model->priv->client_view && model->priv->status_message_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->status_message_id);
+ if (model->priv->client_view && model->priv->view_complete_id)
+ g_signal_handler_disconnect (
+ model->priv->client_view,
+ model->priv->view_complete_id);
+ if (model->priv->remove_status_id)
+ g_source_remove (model->priv->remove_status_id);
+
+ model->priv->create_contact_id = 0;
+ model->priv->remove_contact_id = 0;
+ model->priv->modify_contact_id = 0;
+ model->priv->status_message_id = 0;
+ model->priv->view_complete_id = 0;
+ model->priv->remove_status_id = 0;
+
+ model->priv->search_in_progress = FALSE;
+
+ if (model->priv->client_view) {
+ GError *error = NULL;
+
+ e_book_client_view_stop (model->priv->client_view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to stop client view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
- model->writable_status_id = 0;
+ g_object_unref (model->priv->client_view);
+ model->priv->client_view = NULL;
- gtk_object_unref(GTK_OBJECT(model->book));
- model->book = NULL;
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, NULL, -1);
}
-
- g_free (model->query);
}
static void
update_folder_bar_message (EAddressbookModel *model)
{
- int count;
- char *message;
+ guint count;
+ gchar *message;
- count = model->data_count;
+ count = model->priv->contacts->len;
switch (count) {
case 0:
- message = g_strdup (_("No cards"));
- break;
- case 1:
- message = g_strdup (_("1 card"));
+ message = g_strdup (_("No contacts"));
break;
default:
- message = g_strdup_printf (_("%d cards"), count);
+ message = g_strdup_printf (
+ ngettext ("%d contact", "%d contacts", count), count);
break;
}
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE],
- message);
+ g_signal_emit (model, signals[FOLDER_BAR_MESSAGE], 0, message);
g_free (message);
}
static void
-create_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
+view_create_contact_cb (EBookClientView *client_view,
+ const GSList *contact_list,
+ EAddressbookModel *model)
{
- int old_count = model->data_count;
- int length = g_list_length ((GList *)cards);
+ GPtrArray *array;
+ guint count;
+ guint index;
- if (model->data_count + length > model->allocated_count) {
- while (model->data_count + length > model->allocated_count)
- model->allocated_count = model->allocated_count * 2 + 1;
- model->data = g_renew(ECard *, model->data, model->allocated_count);
- }
+ array = model->priv->contacts;
+ index = array->len;
+ count = g_list_length ((GList *) contact_list);
- for ( ; cards; cards = cards->next) {
- model->data[model->data_count++] = cards->data;
- gtk_object_ref (cards->data);
- }
+ while (contact_list != NULL) {
+ EContact *contact = contact_list->data;
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_ADDED],
- old_count, model->data_count - old_count);
+ g_ptr_array_add (array, g_object_ref (contact));
+ contact_list = contact_list->next;
+ }
+ g_signal_emit (model, signals[CONTACT_ADDED], 0, index, count);
update_folder_bar_message (model);
}
-static void
-remove_card(EBookView *book_view,
- const char *id,
- EAddressbookModel *model)
-{
- int i;
-
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_get_id(model->data[i]), id) ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- memmove(model->data + i, model->data + i + 1, (model->data_count - i - 1) * sizeof (ECard *));
- model->data_count--;
-
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_REMOVED],
- i);
- update_folder_bar_message (model);
- break;
- }
- }
+static gint
+sort_descending (gconstpointer ca,
+ gconstpointer cb)
+{
+ gint a = *((gint *) ca);
+ gint b = *((gint *) cb);
+
+ return (a == b) ? 0 : (a < b) ? 1 : -1;
}
static void
-modify_card(EBookView *book_view,
- const GList *cards,
- EAddressbookModel *model)
-{
- for ( ; cards; cards = cards->next) {
- int i;
- for ( i = 0; i < model->data_count; i++) {
- if ( !strcmp(e_card_get_id(model->data[i]), e_card_get_id(E_CARD(cards->data))) ) {
- gtk_object_unref(GTK_OBJECT(model->data[i]));
- model->data[i] = e_card_duplicate(E_CARD(cards->data));
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [CARD_CHANGED],
- i);
+view_remove_contact_cb (EBookClientView *client_view,
+ const GSList *ids,
+ EAddressbookModel *model)
+{
+ /* XXX we should keep a hash around instead of this O(n*m) loop */
+ const GSList *iter;
+ GArray *indices;
+ GPtrArray *array;
+ gint ii;
+
+ array = model->priv->contacts;
+ indices = g_array_new (FALSE, FALSE, sizeof (gint));
+
+ for (iter = ids; iter != NULL; iter = iter->next) {
+ const gchar *target_uid = iter->data;
+
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *contact;
+ const gchar *uid;
+
+ contact = array->pdata[ii];
+ /* check if already removed */
+ if (!contact)
+ continue;
+
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ g_return_if_fail (uid != NULL);
+
+ if (strcmp (uid, target_uid) == 0) {
+ g_object_unref (contact);
+ g_array_append_val (indices, ii);
+ array->pdata[ii] = NULL;
break;
}
}
}
-}
-static void
-status_message (EBookView *book_view,
- char* status,
- EAddressbookModel *model)
-{
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STATUS_MESSAGE],
- status);
-}
+ /* Sort the 'indices' array in descending order, since
+ * g_ptr_array_remove_index() shifts subsequent elements
+ * down one position to fill the gap. */
+ g_array_sort (indices, sort_descending);
-static void
-sequence_complete (EBookView *book_view,
- EBookViewStatus status,
- EAddressbookModel *model)
-{
- model->search_in_progress = FALSE;
- status_message (book_view, NULL, model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [SEARCH_RESULT],
- status);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+ for (ii = 0; ii < indices->len; ii++) {
+ gint index;
+
+ index = g_array_index (indices, gint, ii);
+ g_ptr_array_remove_index (array, index);
+ }
+
+ g_signal_emit (model, signals[CONTACTS_REMOVED], 0, indices);
+ g_array_free (indices, FALSE);
+
+ update_folder_bar_message (model);
}
static void
-writable_status (EBook *book,
- gboolean writable,
- EAddressbookModel *model)
+view_modify_contact_cb (EBookClientView *client_view,
+ const GSList *contact_list,
+ EAddressbookModel *model)
{
- if (!model->editable_set) {
- model->editable = writable;
+ GPtrArray *array;
+
+ array = model->priv->contacts;
+
+ while (contact_list != NULL) {
+ EContact *new_contact = contact_list->data;
+ const gchar *target_uid;
+ gint ii;
+
+ target_uid = e_contact_get_const (new_contact, E_CONTACT_UID);
+ g_warn_if_fail (target_uid != NULL);
+
+ /* skip contacts without UID */
+ if (!target_uid) {
+ contact_list = contact_list->next;
+ continue;
+ }
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [WRITABLE_STATUS],
- writable);
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *old_contact;
+ const gchar *uid;
+
+ old_contact = array->pdata[ii];
+ g_return_if_fail (old_contact != NULL);
+
+ uid = e_contact_get_const (old_contact, E_CONTACT_UID);
+ g_return_if_fail (uid != NULL);
+
+ if (strcmp (uid, target_uid) != 0)
+ continue;
+
+ g_object_unref (old_contact);
+ array->pdata[ii] = e_contact_duplicate (new_contact);
+
+ g_signal_emit (
+ model, signals[CONTACT_CHANGED], 0, ii);
+ break;
+ }
+
+ contact_list = contact_list->next;
}
}
static void
-backend_died (EBook *book,
- EAddressbookModel *model)
+view_progress_cb (EBookClientView *client_view,
+ guint percent,
+ const gchar *message,
+ EAddressbookModel *model)
{
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [BACKEND_DIED]);
+ if (model->priv->remove_status_id)
+ g_source_remove (model->priv->remove_status_id);
+ model->priv->remove_status_id = 0;
+
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, message, percent);
}
static void
-e_addressbook_model_class_init (GtkObjectClass *object_class)
-{
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->destroy = addressbook_destroy;
- object_class->set_arg = e_addressbook_model_set_arg;
- object_class->get_arg = e_addressbook_model_get_arg;
-
- gtk_object_add_arg_type ("EAddressbookModel::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookModel::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookModel::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- e_addressbook_model_signals [WRITABLE_STATUS] =
- gtk_signal_new ("writable_status",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, writable_status),
- gtk_marshal_NONE__BOOL,
- GTK_TYPE_NONE, 1, GTK_TYPE_BOOL);
-
- e_addressbook_model_signals [STATUS_MESSAGE] =
- gtk_signal_new ("status_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, status_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_model_signals [SEARCH_RESULT] =
- gtk_signal_new ("search_result",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, search_result),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1, GTK_TYPE_ENUM);
-
- e_addressbook_model_signals [FOLDER_BAR_MESSAGE] =
- gtk_signal_new ("folder_bar_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, folder_bar_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_model_signals [CARD_ADDED] =
- gtk_signal_new ("card_added",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_added),
- gtk_marshal_NONE__INT_INT,
- GTK_TYPE_NONE, 2, GTK_TYPE_INT, GTK_TYPE_INT);
-
- e_addressbook_model_signals [CARD_REMOVED] =
- gtk_signal_new ("card_removed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_removed),
- gtk_marshal_NONE__INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
- e_addressbook_model_signals [CARD_CHANGED] =
- gtk_signal_new ("card_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, card_changed),
- gtk_marshal_NONE__INT,
- GTK_TYPE_NONE, 1, GTK_TYPE_INT);
-
- e_addressbook_model_signals [MODEL_CHANGED] =
- gtk_signal_new ("model_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, model_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_model_signals [STOP_STATE_CHANGED] =
- gtk_signal_new ("stop_state_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, stop_state_changed),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_model_signals [BACKEND_DIED] =
- gtk_signal_new ("backend_died",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookModelClass, backend_died),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, e_addressbook_model_signals, LAST_SIGNAL);
+view_complete_cb (EBookClientView *client_view,
+ const GError *error,
+ EAddressbookModel *model)
+{
+ model->priv->search_in_progress = FALSE;
+ view_progress_cb (client_view, -1, NULL, model);
+ g_signal_emit (model, signals[SEARCH_RESULT], 0, error);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
}
static void
-e_addressbook_model_init (GtkObject *object)
-{
- EAddressbookModel *model = E_ADDRESSBOOK_MODEL(object);
- model->book = NULL;
- model->query = g_strdup("(contains \"x-evolution-any-field\" \"\")");
- model->book_view = NULL;
- model->get_view_idle = 0;
- model->create_card_id = 0;
- model->remove_card_id = 0;
- model->modify_card_id = 0;
- model->status_message_id = 0;
- model->writable_status_id = 0;
- model->backend_died_id = 0;
- model->sequence_complete_id = 0;
- model->data = NULL;
- model->data_count = 0;
- model->allocated_count = 0;
- model->search_in_progress = FALSE;
- model->editable = FALSE;
- model->editable_set = FALSE;
- model->first_get_view = TRUE;
+addressbook_model_client_notify_readonly_cb (EClientCache *client_cache,
+ EClient *client,
+ GParamSpec *pspec,
+ EAddressbookModel *model)
+{
+ if (!E_IS_BOOK_CLIENT (client))
+ return;
+
+ if (E_BOOK_CLIENT (client) == model->priv->book_client) {
+ gboolean editable = !e_client_is_readonly (client);
+ e_addressbook_model_set_editable (model, editable);
+ }
}
static void
-book_view_loaded (EBook *book, EBookStatus status, EBookView *book_view, gpointer closure)
+client_view_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- EAddressbookModel *model = closure;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ EBookClientView *client_view = NULL;
+ EAddressbookModel *model = user_data;
+ GError *error = NULL;
- remove_book_view(model);
+ if (!e_book_client_get_view_finish (book_client, result, &client_view, &error))
+ client_view = NULL;
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error getting book view"), status);
+ if (error) {
+ eab_error_dialog (NULL, NULL, _("Error getting book view"), error);
+ g_error_free (error);
return;
}
- model->book_view = book_view;
- if (model->book_view)
- gtk_object_ref(GTK_OBJECT(model->book_view));
- model->create_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- model);
- model->remove_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- model);
- model->modify_card_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- model);
- model->status_message_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "status_message",
- GTK_SIGNAL_FUNC(status_message),
- model);
- model->sequence_complete_id = gtk_signal_connect(GTK_OBJECT(model->book_view),
- "sequence_complete",
- GTK_SIGNAL_FUNC(sequence_complete),
- model);
-
+ remove_book_view (model);
free_data (model);
- model->search_in_progress = TRUE;
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [MODEL_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+ model->priv->client_view = client_view;
+ if (model->priv->client_view) {
+ model->priv->create_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-added",
+ G_CALLBACK (view_create_contact_cb), model);
+ model->priv->remove_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-removed",
+ G_CALLBACK (view_remove_contact_cb), model);
+ model->priv->modify_contact_id = g_signal_connect (
+ model->priv->client_view, "objects-modified",
+ G_CALLBACK (view_modify_contact_cb), model);
+ model->priv->status_message_id = g_signal_connect (
+ model->priv->client_view, "progress",
+ G_CALLBACK (view_progress_cb), model);
+ model->priv->view_complete_id = g_signal_connect (
+ model->priv->client_view, "complete",
+ G_CALLBACK (view_complete_cb), model);
+
+ model->priv->search_in_progress = TRUE;
+ }
+
+ g_signal_emit (model, signals[MODEL_CHANGED], 0);
+ g_signal_emit (model, signals[SEARCH_STARTED], 0);
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+
+ if (model->priv->client_view) {
+ e_book_client_view_start (model->priv->client_view, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to start client view: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+ }
}
static gboolean
-get_view (EAddressbookModel *model)
-{
- if (model->book && model->query) {
- if (model->first_get_view) {
- char *capabilities;
- capabilities = e_book_get_static_capabilities (model->book);
- if (capabilities && strstr (capabilities, "do-initial-query")) {
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
+addressbook_model_idle_cb (EAddressbookModel *model)
+{
+ model->priv->client_view_idle_id = 0;
+
+ if (model->priv->book_client && model->priv->query_str) {
+ remove_book_view (model);
+
+ if (model->priv->first_get_view) {
+ model->priv->first_get_view = FALSE;
+
+ if (e_client_check_capability (E_CLIENT (model->priv->book_client), "do-initial-query")) {
+ e_book_client_get_view (
+ model->priv->book_client, model->priv->query_str,
+ NULL, client_view_ready_cb, model);
} else {
- remove_book_view(model);
free_data (model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [MODEL_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
+
+ g_signal_emit (
+ model, signals[MODEL_CHANGED], 0);
+ g_signal_emit (
+ model, signals[STOP_STATE_CHANGED], 0);
}
- model->first_get_view = FALSE;
- g_free (capabilities);
- }
- else
- e_book_get_book_view (model->book, model->query, book_view_loaded, model);
+ } else
+ e_book_client_get_view (
+ model->priv->book_client, model->priv->query_str,
+ NULL, client_view_ready_cb, model);
+
}
- model->get_view_idle = 0;
+ g_object_unref (model);
+
return FALSE;
}
-ECard *
-e_addressbook_model_get_card(EAddressbookModel *model,
- int row)
+static gboolean
+remove_status_cb (gpointer data)
{
- if (model->data && 0 <= row && row < model->data_count) {
- ECard *card;
- card = e_card_duplicate (model->data[row]);
- return card;
+ EAddressbookModel *model = data;
+
+ g_return_val_if_fail (model != NULL, FALSE);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, NULL, -1);
+ model->priv->remove_status_id = 0;
+
+ return FALSE;
+}
+
+static void
+addressbook_model_set_client_cache (EAddressbookModel *model,
+ EClientCache *client_cache)
+{
+ g_return_if_fail (E_IS_CLIENT_CACHE (client_cache));
+ g_return_if_fail (model->priv->client_cache == NULL);
+
+ model->priv->client_cache = g_object_ref (client_cache);
+}
+
+static void
+addressbook_model_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CLIENT:
+ e_addressbook_model_set_client (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_CLIENT_CACHE:
+ addressbook_model_set_client_cache (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_EDITABLE:
+ e_addressbook_model_set_editable (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_boolean (value));
+ return;
+
+ case PROP_QUERY:
+ e_addressbook_model_set_query (
+ E_ADDRESSBOOK_MODEL (object),
+ g_value_get_string (value));
+ return;
}
- return NULL;
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+
}
-const ECard *
-e_addressbook_model_peek_card(EAddressbookModel *model,
- int row)
+static void
+addressbook_model_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- if (model->data && 0 <= row && row < model->data_count) {
- return model->data[row];
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (
+ value, e_addressbook_model_get_client (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_CLIENT_CACHE:
+ g_value_set_object (
+ value, e_addressbook_model_get_client_cache (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_EDITABLE:
+ g_value_set_boolean (
+ value, e_addressbook_model_get_editable (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
+
+ case PROP_QUERY:
+ g_value_set_string (
+ value, e_addressbook_model_get_query (
+ E_ADDRESSBOOK_MODEL (object)));
+ return;
}
- return NULL;
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-e_addressbook_model_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_model_dispose (GObject *object)
{
- EAddressbookModel *model;
+ EAddressbookModel *model = E_ADDRESSBOOK_MODEL (object);
- model = E_ADDRESSBOOK_MODEL (o);
-
- switch (arg_id){
- case ARG_BOOK:
- if (model->book) {
- if (model->writable_status_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->writable_status_id);
- model->writable_status_id = 0;
-
- if (model->backend_died_id)
- gtk_signal_disconnect(GTK_OBJECT (model->book),
- model->backend_died_id);
- model->backend_died_id = 0;
-
- gtk_object_unref(GTK_OBJECT(model->book));
- }
- model->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- if (model->book) {
- model->first_get_view = TRUE;
- gtk_object_ref(GTK_OBJECT(model->book));
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
- gtk_signal_connect (GTK_OBJECT(model->book),
- "writable_status",
- writable_status, model);
- gtk_signal_connect (GTK_OBJECT(model->book),
- "backend_died",
- backend_died, model);
- }
- break;
- case ARG_QUERY:
- if (model->query)
- g_free(model->query);
- model->query = g_strdup(GTK_VALUE_STRING (*arg));
- if (model->get_view_idle == 0)
- model->get_view_idle = g_idle_add((GSourceFunc)get_view, model);
- break;
- case ARG_EDITABLE:
- model->editable = GTK_VALUE_BOOL (*arg);
- model->editable_set = TRUE;
- break;
+ remove_book_view (model);
+ free_data (model);
+
+ if (model->priv->client_notify_readonly_handler_id > 0) {
+ g_signal_handler_disconnect (
+ model->priv->client_cache,
+ model->priv->client_notify_readonly_handler_id);
+ model->priv->client_notify_readonly_handler_id = 0;
}
+
+ g_clear_object (&model->priv->client_cache);
+ g_clear_object (&model->priv->book_client);
+
+ if (model->priv->query_str) {
+ g_free (model->priv->query_str);
+ model->priv->query_str = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->dispose (object);
}
static void
-e_addressbook_model_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+addressbook_model_finalize (GObject *object)
{
- EAddressbookModel *e_addressbook_model;
+ EAddressbookModelPrivate *priv;
- e_addressbook_model = E_ADDRESSBOOK_MODEL (object);
+ priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (object);
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_addressbook_model->book);
- break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = g_strdup(e_addressbook_model->query);
- break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_addressbook_model->editable;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
+ g_ptr_array_free (priv->contacts, TRUE);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->finalize (object);
}
-GtkType
-e_addressbook_model_get_type (void)
+static void
+addressbook_model_constructed (GObject *object)
{
- static GtkType type = 0;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ gulong handler_id;
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookModel",
- sizeof (EAddressbookModel),
- sizeof (EAddressbookModelClass),
- (GtkClassInitFunc) e_addressbook_model_class_init,
- (GtkObjectInitFunc) e_addressbook_model_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
+ model = E_ADDRESSBOOK_MODEL (object);
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_model_parent_class)->constructed (object);
- return type;
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ handler_id = g_signal_connect (
+ client_cache, "client-notify::readonly",
+ G_CALLBACK (addressbook_model_client_notify_readonly_cb),
+ model);
+ model->priv->client_notify_readonly_handler_id = handler_id;
}
-EAddressbookModel*
-e_addressbook_model_new (void)
+static void
+e_addressbook_model_class_init (EAddressbookModelClass *class)
{
- EAddressbookModel *et;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookModelPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_model_set_property;
+ object_class->get_property = addressbook_model_get_property;
+ object_class->dispose = addressbook_model_dispose;
+ object_class->finalize = addressbook_model_finalize;
+ object_class->constructed = addressbook_model_constructed;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT_CACHE,
+ g_param_spec_object (
+ "client-cache",
+ "Client Cache",
+ "Shared EClient instances",
+ E_TYPE_CLIENT_CACHE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ signals[WRITABLE_STATUS] = g_signal_new (
+ "writable_status",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, writable_status),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOOLEAN,
+ G_TYPE_NONE, 1,
+ G_TYPE_BOOLEAN);
+
+ signals[STATUS_MESSAGE] = g_signal_new (
+ "status_message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, status_message),
+ NULL, NULL,
+ e_marshal_VOID__STRING_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_STRING,
+ G_TYPE_INT);
+
+ signals[SEARCH_STARTED] = g_signal_new (
+ "search_started",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SEARCH_RESULT] = g_signal_new (
+ "search_result",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, search_result),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ G_TYPE_ERROR);
+
+ signals[FOLDER_BAR_MESSAGE] = g_signal_new (
+ "folder_bar_message",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, folder_bar_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[CONTACT_ADDED] = g_signal_new (
+ "contact_added",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_added),
+ NULL, NULL,
+ e_marshal_NONE__INT_INT,
+ G_TYPE_NONE, 2,
+ G_TYPE_INT,
+ G_TYPE_INT);
+
+ signals[CONTACTS_REMOVED] = g_signal_new (
+ "contacts_removed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contacts_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1,
+ G_TYPE_POINTER);
+
+ signals[CONTACT_CHANGED] = g_signal_new (
+ "contact_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, contact_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1,
+ G_TYPE_INT);
+
+ signals[MODEL_CHANGED] = g_signal_new (
+ "model_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, model_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[STOP_STATE_CHANGED] = g_signal_new (
+ "stop_state_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookModelClass, stop_state_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
- et = gtk_type_new (e_addressbook_model_get_type ());
-
- return et;
+static void
+e_addressbook_model_init (EAddressbookModel *model)
+{
+ model->priv = E_ADDRESSBOOK_MODEL_GET_PRIVATE (model);
+ model->priv->contacts = g_ptr_array_new ();
+ model->priv->first_get_view = TRUE;
}
-void e_addressbook_model_stop (EAddressbookModel *model)
+EAddressbookModel *
+e_addressbook_model_new (EClientCache *client_cache)
{
- remove_book_view(model);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STOP_STATE_CHANGED]);
- gtk_signal_emit (GTK_OBJECT (model),
- e_addressbook_model_signals [STATUS_MESSAGE],
- "Search Interrupted.");
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+
+ return g_object_new (
+ E_TYPE_ADDRESSBOOK_MODEL,
+ "client-cache", client_cache, NULL);
+}
+
+EClientCache *
+e_addressbook_model_get_client_cache (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->client_cache;
+}
+
+EContact *
+e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row)
+{
+ GPtrArray *array;
+
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ array = model->priv->contacts;
+
+ if (0 <= row && row < array->len)
+ return e_contact_duplicate (array->pdata[row]);
+
+ return NULL;
+}
+
+void
+e_addressbook_model_stop (EAddressbookModel *model)
+{
+ const gchar *message;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ remove_book_view (model);
+
+ message = _("Search Interrupted");
+ g_signal_emit (model, signals[STOP_STATE_CHANGED], 0);
+ g_signal_emit (model, signals[STATUS_MESSAGE], 0, message, -1);
+
+ if (!model->priv->remove_status_id)
+ model->priv->remove_status_id =
+ g_timeout_add_seconds (3, remove_status_cb, model);
}
gboolean
e_addressbook_model_can_stop (EAddressbookModel *model)
{
- return model->search_in_progress;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->search_in_progress;
}
void
e_addressbook_model_force_folder_bar_message (EAddressbookModel *model)
{
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
update_folder_bar_message (model);
}
-int
-e_addressbook_model_card_count (EAddressbookModel *model)
+gint
+e_addressbook_model_contact_count (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), 0);
+
+ return model->priv->contacts->len;
+}
+
+EContact *
+e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->contacts->pdata[index];
+}
+
+gint
+e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact)
+{
+ GPtrArray *array;
+ gint ii;
+
+ /* XXX This searches for a particular EContact instance,
+ * as opposed to an equivalent but possibly different
+ * EContact instance. Might have to revise this in
+ * the future. */
+
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), -1);
+ g_return_val_if_fail (E_IS_CONTACT (contact), -1);
+
+ array = model->priv->contacts;
+ for (ii = 0; ii < array->len; ii++) {
+ EContact *candidate = array->pdata[ii];
+
+ if (contact == candidate)
+ return ii;
+ }
+
+ return -1;
+}
+
+EBookClient *
+e_addressbook_model_get_client (EAddressbookModel *model)
{
- return model->data_count;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->book_client;
}
-ECard *
-e_addressbook_model_card_at (EAddressbookModel *model, int index)
+void
+e_addressbook_model_set_client (EAddressbookModel *model,
+ EBookClient *book_client)
{
- return model->data[index];
+ gboolean editable;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+ g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
+
+ if (model->priv->book_client == book_client)
+ return;
+
+ if (model->priv->book_client != NULL)
+ g_object_unref (model->priv->book_client);
+
+ model->priv->book_client = g_object_ref (book_client);
+ model->priv->first_get_view = TRUE;
+
+ editable = !e_client_is_readonly (E_CLIENT (book_client));
+ e_addressbook_model_set_editable (model, editable);
+
+ if (model->priv->client_view_idle_id == 0)
+ model->priv->client_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "client");
}
gboolean
-e_addressbook_model_editable (EAddressbookModel *model)
+e_addressbook_model_get_editable (EAddressbookModel *model)
{
- return model->editable;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), FALSE);
+
+ return model->priv->editable;
}
-EBook *
-e_addressbook_model_get_ebook (EAddressbookModel *model)
+void
+e_addressbook_model_set_editable (EAddressbookModel *model,
+ gboolean editable)
{
- return model->book;
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ if (model->priv->editable != editable) {
+ model->priv->editable = editable;
+
+ g_signal_emit (
+ model, signals[WRITABLE_STATUS], 0,
+ model->priv->editable);
+
+ g_object_notify (G_OBJECT (model), "editable");
+ }
+}
+
+gchar *
+e_addressbook_model_get_query (EAddressbookModel *model)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_MODEL (model), NULL);
+
+ return model->priv->query_str;
+}
+
+void
+e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query)
+{
+ EBookQuery *book_query;
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_MODEL (model));
+
+ if (query == NULL)
+ book_query = e_book_query_any_field_contains ("");
+ else
+ book_query = e_book_query_from_string (query);
+
+ /* also checks whether the query is a valid query string */
+ if (!book_query)
+ return;
+
+ if (model->priv->query_str != NULL) {
+ gchar *new_query;
+
+ new_query = e_book_query_to_string (book_query);
+
+ if (new_query && g_str_equal (model->priv->query_str, new_query)) {
+ g_free (new_query);
+ e_book_query_unref (book_query);
+ return;
+ }
+
+ g_free (new_query);
+ }
+
+ g_free (model->priv->query_str);
+ model->priv->query_str = e_book_query_to_string (book_query);
+ e_book_query_unref (book_query);
+
+ if (model->priv->client_view_idle_id == 0)
+ model->priv->client_view_idle_id = g_idle_add (
+ (GSourceFunc) addressbook_model_idle_cb,
+ g_object_ref (model));
+
+ g_object_notify (G_OBJECT (model), "query");
}
diff --git a/addressbook/gui/widgets/e-addressbook-model.h b/addressbook/gui/widgets/e-addressbook-model.h
index eb1004499a..c08fdb4319 100644
--- a/addressbook/gui/widgets/e-addressbook-model.h
+++ b/addressbook/gui/widgets/e-addressbook-model.h
@@ -1,80 +1,119 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_ADDRESSBOOK_MODEL_H_
-#define _E_ADDRESSBOOK_MODEL_H_
-
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#define E_ADDRESSBOOK_MODEL_TYPE (e_addressbook_model_get_type ())
-#define E_ADDRESSBOOK_MODEL(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModel))
-#define E_ADDRESSBOOK_MODEL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_MODEL_TYPE, EAddressbookModelClass))
-#define E_IS_ADDRESSBOOK_MODEL(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_MODEL_TYPE))
-#define E_IS_ADDRESSBOOK_MODEL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_MODEL_TYPE))
+/*
+ *
+ * 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/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef E_ADDRESSBOOK_MODEL_H
+#define E_ADDRESSBOOK_MODEL_H
+
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_MODEL \
+ (e_addressbook_model_get_type ())
+#define E_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModel))
+#define E_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL, EAddressbookModelClass))
+#define E_IS_ADDRESSBOOK_MODEL(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_IS_ADDRESSBOOK_MODEL_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_MODEL))
+#define E_ADDRESSBOOK_MODEL_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_MODEL))
+
+G_BEGIN_DECLS
typedef struct _EAddressbookModel EAddressbookModel;
typedef struct _EAddressbookModelClass EAddressbookModelClass;
+typedef struct _EAddressbookModelPrivate EAddressbookModelPrivate;
struct _EAddressbookModel {
- GtkObject parent;
-
- /* item specific fields */
- EBook *book;
- char *query;
- EBookView *book_view;
-
- int get_view_idle;
-
- ECard **data;
- int data_count;
- int allocated_count;
-
- int create_card_id, remove_card_id, modify_card_id, status_message_id, writable_status_id, sequence_complete_id, backend_died_id;
-
- guint search_in_progress : 1;
- guint editable : 1;
- guint editable_set : 1;
- guint first_get_view : 1;
+ GObject parent;
+ EAddressbookModelPrivate *priv;
};
-
struct _EAddressbookModelClass {
- GtkObjectClass parent_class;
-
- /*
- * Signals
- */
- void (*writable_status) (EAddressbookModel *model, gboolean writable);
- void (*search_result) (EAddressbookModel *model, EBookViewStatus status);
- void (*status_message) (EAddressbookModel *model, const gchar *message);
- void (*folder_bar_message) (EAddressbookModel *model, const gchar *message);
- void (*card_added) (EAddressbookModel *model, gint index, gint count);
- void (*card_removed) (EAddressbookModel *model, gint index);
- void (*card_changed) (EAddressbookModel *model, gint index);
- void (*model_changed) (EAddressbookModel *model);
- void (*stop_state_changed) (EAddressbookModel *model);
- void (*backend_died) (EAddressbookModel *model);
+ GObjectClass parent_class;
+
+ /* Signals */
+ void (*writable_status) (EAddressbookModel *model,
+ gboolean writable);
+ void (*search_started) (EAddressbookModel *model);
+ void (*search_result) (EAddressbookModel *model,
+ const GError *error);
+ void (*status_message) (EAddressbookModel *model,
+ const gchar *message,
+ gint percent);
+ void (*folder_bar_message) (EAddressbookModel *model,
+ const gchar *message);
+ void (*contact_added) (EAddressbookModel *model,
+ gint index,
+ gint count);
+ void (*contacts_removed) (EAddressbookModel *model,
+ gpointer id_list);
+ void (*contact_changed) (EAddressbookModel *model,
+ gint index);
+ void (*model_changed) (EAddressbookModel *model);
+ void (*stop_state_changed) (EAddressbookModel *model);
};
-
-GtkType e_addressbook_model_get_type (void);
-EAddressbookModel *e_addressbook_model_new (void);
+GType e_addressbook_model_get_type (void);
+EAddressbookModel *
+ e_addressbook_model_new (EClientCache *client_cache);
+EClientCache * e_addressbook_model_get_client_cache
+ (EAddressbookModel *model);
/* Returns object with ref count of 1. */
-ECard *e_addressbook_model_get_card (EAddressbookModel *model,
- int row);
-const ECard *e_addressbook_model_peek_card (EAddressbookModel *model,
- int row);
-EBook *e_addressbook_model_get_ebook (EAddressbookModel *model);
-
-void e_addressbook_model_stop (EAddressbookModel *model);
-gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
-
-void e_addressbook_model_force_folder_bar_message (EAddressbookModel *model);
-
-int e_addressbook_model_card_count (EAddressbookModel *model);
-ECard *e_addressbook_model_card_at (EAddressbookModel *model,
- int index);
-gboolean e_addressbook_model_editable (EAddressbookModel *model);
-
-#endif /* _E_ADDRESSBOOK_MODEL_H_ */
+EContact * e_addressbook_model_get_contact (EAddressbookModel *model,
+ gint row);
+
+void e_addressbook_model_stop (EAddressbookModel *model);
+gboolean e_addressbook_model_can_stop (EAddressbookModel *model);
+
+void e_addressbook_model_force_folder_bar_message
+ (EAddressbookModel *model);
+
+gint e_addressbook_model_contact_count
+ (EAddressbookModel *model);
+EContact * e_addressbook_model_contact_at (EAddressbookModel *model,
+ gint index);
+gint e_addressbook_model_find (EAddressbookModel *model,
+ EContact *contact);
+EBookClient * e_addressbook_model_get_client (EAddressbookModel *model);
+void e_addressbook_model_set_client (EAddressbookModel *model,
+ EBookClient *book_client);
+gboolean e_addressbook_model_get_editable
+ (EAddressbookModel *model);
+void e_addressbook_model_set_editable
+ (EAddressbookModel *model,
+ gboolean editable);
+gchar * e_addressbook_model_get_query (EAddressbookModel *model);
+void e_addressbook_model_set_query (EAddressbookModel *model,
+ const gchar *query);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_MODEL_H */
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
index 16e61a2d89..48ed73bb25 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.c
@@ -1,452 +1,613 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
-
+/*
+ * 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/>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ */
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+#include <string.h>
+
+#include <glib/gi18n.h>
#include "e-addressbook-reflow-adapter.h"
#include "e-addressbook-model.h"
-#include "e-addressbook-view.h"
-#include "e-addressbook-util.h"
-
-#include <gal/util/e-i18n.h>
+#include "eab-gui-util.h"
#include "e-minicard.h"
-#include <gal/widgets/e-unicode.h>
-#include <gal/widgets/e-font.h>
-#include <gal/widgets/e-popup-menu.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gal/unicode/gunicode.h>
-#include "e-contact-save-as.h"
+#include <e-util/e-util.h>
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/printing/e-contact-print-envelope.h"
+#define E_ADDRESSBOOK_REFLOW_ADAPTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapterPrivate))
struct _EAddressbookReflowAdapterPrivate {
EAddressbookModel *model;
-
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
-};
-#define PARENT_TYPE e_reflow_model_get_type()
-EReflowModel *parent_class;
+ gboolean loading;
+
+ gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
+ gint search_started_id, search_result_id;
+};
#define d(x)
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
- ARG_MODEL,
+ PROP_0,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE,
+ PROP_MODEL
};
enum {
DRAG_BEGIN,
+ OPEN_CONTACT,
LAST_SIGNAL
};
-static guint e_addressbook_reflow_adapter_signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (
+ EAddressbookReflowAdapter,
+ e_addressbook_reflow_adapter,
+ E_TYPE_REFLOW_MODEL)
static void
-unlink_model(EAddressbookReflowAdapter *adapter)
+unlink_model (EAddressbookReflowAdapter *adapter)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->create_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->remove_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->modify_card_id);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
+ if (priv->model && priv->create_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->create_contact_id);
+ if (priv->model && priv->remove_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->remove_contact_id);
+ if (priv->model && priv->modify_contact_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->modify_contact_id);
+ if (priv->model && priv->model_changed_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->model_changed_id);
+ if (priv->model && priv->search_started_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->search_started_id);
+ if (priv->model && priv->search_result_id)
+ g_signal_handler_disconnect (
+ priv->model,
+ priv->search_result_id);
+
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
+ priv->model_changed_id = 0;
+ priv->search_started_id = 0;
+ priv->search_result_id = 0;
- gtk_object_unref(GTK_OBJECT(priv->model));
+ if (priv->model)
+ g_object_unref (priv->model);
priv->model = NULL;
}
-
-static int
-count_lines (const gchar *text)
+static gint
+text_height (PangoLayout *layout,
+ const gchar *text)
{
- int num_lines = 1;
- gunichar unival;
+ gint height;
- for (text = e_unicode_get_utf8 (text, &unival); (unival && text); text = e_unicode_get_utf8 (text, &unival)) {
- if (unival == '\n') {
- num_lines ++;
- }
- }
+ pango_layout_set_text (layout, text, -1);
- return num_lines;
-}
-
-static int
-text_height (GnomeCanvas *canvas, const gchar *text)
-{
- EFont *font = e_font_from_gdk_font (((GtkWidget *) canvas)->style->font);
- gint height = e_font_height (font) * count_lines (text) / canvas->pixels_per_unit;
+ pango_layout_get_pixel_size (layout, NULL, &height);
- e_font_unref (font);
return height;
}
static void
-addressbook_finalize(GtkObject *object)
+addressbook_dispose (GObject *object)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
unlink_model (adapter);
}
static void
-addressbook_set_width (EReflowModel *erm, int width)
+addressbook_set_width (EReflowModel *erm,
+ gint width)
{
}
/* This function returns the number of items in our EReflowModel. */
-static int
+static gint
addressbook_count (EReflowModel *erm)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
}
-/* This function returns the number of items in our EReflowModel. */
-static int
-addressbook_height (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
+/* This function returns the height of the minicontact in question */
+static gint
+addressbook_height (EReflowModel *erm,
+ gint i,
+ GnomeCanvasGroup *parent)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- /* FIXME */
- ECardSimpleField field;
- int count = 0;
- int height;
- char *string;
- ECardSimple *simple = e_card_simple_new (e_addressbook_model_card_at (priv->model, i));
+ EContactField field;
+ gint count = 0;
+ gchar *string;
+ EContact *contact = (EContact *) e_addressbook_model_contact_at (priv->model, i);
+ PangoLayout *layout;
+ gint height;
- string = e_card_simple_get(simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, string ? string : "") + 10.0;
- g_free(string);
+ layout = gtk_widget_create_pango_layout (
+ GTK_WIDGET (GNOME_CANVAS_ITEM (parent)->canvas), "");
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING && count < 5; field++) {
+ string = e_contact_get (contact, E_CONTACT_FILE_AS);
+ height = text_height (layout, string ? string : "") + 10.0;
+ g_free (string);
- if (field == E_CARD_SIMPLE_FIELD_FAMILY_NAME)
+ for (field = E_CONTACT_FULL_NAME;
+ field != E_CONTACT_LAST_SIMPLE_STRING && count < 5; field++) {
+
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
continue;
- string = e_card_simple_get(simple, field);
+ string = e_contact_get (contact, field);
if (string && *string) {
- int this_height;
- int field_text_height;
+ gint this_height;
+ gint field_text_height;
- this_height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, e_card_simple_get_name(simple, field));
+ this_height = text_height (layout, e_contact_pretty_name (field));
- field_text_height = text_height (GNOME_CANVAS_ITEM (parent)->canvas, string);
+ field_text_height = text_height (layout, string);
if (this_height < field_text_height)
this_height = field_text_height;
this_height += 3;
height += this_height;
- count ++;
+ count++;
}
g_free (string);
}
height += 2;
- gtk_object_unref (GTK_OBJECT (simple));
+ g_object_unref (layout);
return height;
}
-static int
-addressbook_compare (EReflowModel *erm, int n1, int n2)
+static GHashTable *
+addressbook_create_cmp_cache (EReflowModel *erm)
+{
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+ GHashTable *cmp_cache;
+ gint ii, count;
+
+ count = e_reflow_model_count (erm);
+
+ if (priv->loading || count <= 0)
+ return NULL;
+
+ cmp_cache = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
+
+ for (ii = 0; ii < count; ii++) {
+ EContact *contact;
+
+ contact = (EContact *)
+ e_addressbook_model_contact_at (priv->model, ii);
+ if (contact != NULL) {
+ const gchar *file_as;
+
+ file_as = e_contact_get_const (
+ contact, E_CONTACT_FILE_AS);
+ if (file_as != NULL)
+ g_hash_table_insert (
+ cmp_cache, GINT_TO_POINTER (ii),
+ g_utf8_collate_key (file_as, -1));
+ }
+ }
+
+ return cmp_cache;
+}
+
+static gint
+addressbook_compare (EReflowModel *erm,
+ gint n1,
+ gint n2,
+ GHashTable *cmp_cache)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- ECard *card1, *card2;
-
- card1 = e_addressbook_model_card_at (priv->model, n1);
- card2 = e_addressbook_model_card_at (priv->model, n2);
-
- if (card1 && card2) {
- char *file_as1, *file_as2;
- file_as1 = card1->file_as;
- file_as2 = card2->file_as;
- if (file_as1 && file_as2)
- return g_utf8_collate(file_as1, file_as2);
- if (file_as1)
+ EContact *contact1, *contact2;
+
+ if (priv->loading) {
+ return n1 - n2;
+ }
+ else {
+ contact1 = (EContact *) e_addressbook_model_contact_at (priv->model, n1);
+ contact2 = (EContact *) e_addressbook_model_contact_at (priv->model, n2);
+
+ if (contact1 && contact2) {
+ const gchar *file_as1, *file_as2;
+ const gchar *uid1, *uid2;
+
+ if (cmp_cache) {
+ file_as1 = g_hash_table_lookup (cmp_cache, GINT_TO_POINTER (n1));
+ file_as2 = g_hash_table_lookup (cmp_cache, GINT_TO_POINTER (n2));
+ if (file_as1 && file_as2)
+ return strcmp (file_as1, file_as2);
+ } else {
+ file_as1 = e_contact_get_const (contact1, E_CONTACT_FILE_AS);
+ file_as2 = e_contact_get_const (contact2, E_CONTACT_FILE_AS);
+ if (file_as1 && file_as2)
+ return g_utf8_collate (file_as1, file_as2);
+ }
+ if (file_as1)
+ return -1;
+ if (file_as2)
+ return 1;
+ uid1 = e_contact_get_const (contact1, E_CONTACT_UID);
+ uid2 = e_contact_get_const (contact2, E_CONTACT_UID);
+ if (uid1 && uid2)
+ return strcmp (uid1, uid2);
+ if (uid1)
+ return -1;
+ if (uid2)
+ return 1;
+ }
+ if (contact1)
return -1;
- if (file_as2)
+ if (contact2)
return 1;
- return strcmp(e_card_get_id(card1), e_card_get_id(card2));
+ return 0;
}
- if (card1)
- return -1;
- if (card2)
- return 1;
- return 0;
}
-static int
-adapter_drag_begin (EMinicard *card, GdkEvent *event, EAddressbookReflowAdapter *adapter)
+static gint
+adapter_drag_begin (EMinicard *card,
+ GdkEvent *event,
+ EAddressbookReflowAdapter *adapter)
{
gint ret_val = 0;
- gtk_signal_emit (GTK_OBJECT(adapter),
- e_addressbook_reflow_adapter_signals[DRAG_BEGIN],
- event, &ret_val);
+ g_signal_emit (
+ adapter,
+ signals[DRAG_BEGIN], 0,
+ event, &ret_val);
return ret_val;
}
+static void
+adapter_open_contact (EMinicard *card,
+ EContact *contact,
+ EAddressbookReflowAdapter *adapter)
+{
+ g_signal_emit (adapter, signals[OPEN_CONTACT], 0, contact);
+}
+
static GnomeCanvasItem *
-addressbook_incarnate (EReflowModel *erm, int i, GnomeCanvasGroup *parent)
+addressbook_incarnate (EReflowModel *erm,
+ gint i,
+ GnomeCanvasGroup *parent)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
GnomeCanvasItem *item;
- item = gnome_canvas_item_new(parent,
- e_minicard_get_type(),
- "card", e_addressbook_model_card_at (priv->model, i),
- "editable", e_addressbook_model_editable (priv->model),
- NULL);
+ item = gnome_canvas_item_new (
+ parent, e_minicard_get_type (),
+ "contact", e_addressbook_model_contact_at (priv->model, i),
+ "editable", e_addressbook_model_get_editable (priv->model),
+ NULL);
-#if 0
- gtk_signal_connect (GTK_OBJECT (item), "selected",
- GTK_SIGNAL_FUNC(card_selected), emvm);
-#endif
+ g_signal_connect (
+ item, "drag_begin",
+ G_CALLBACK (adapter_drag_begin), adapter);
- gtk_signal_connect (GTK_OBJECT (item), "drag_begin",
- GTK_SIGNAL_FUNC(adapter_drag_begin), adapter);
+ g_signal_connect (
+ item, "open-contact",
+ G_CALLBACK (adapter_open_contact), adapter);
return item;
}
static void
-addressbook_reincarnate (EReflowModel *erm, int i, GnomeCanvasItem *item)
+addressbook_reincarnate (EReflowModel *erm,
+ gint i,
+ GnomeCanvasItem *item)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(erm);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (erm);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- gnome_canvas_item_set(item,
- "card", e_addressbook_model_card_at (priv->model, i),
- NULL);
+ gnome_canvas_item_set (
+ item,
+ "contact", e_addressbook_model_contact_at (priv->model, i),
+ NULL);
}
+static void
+create_contact (EAddressbookModel *model,
+ gint index,
+ gint count,
+ EAddressbookReflowAdapter *adapter)
+{
+ e_reflow_model_items_inserted (
+ E_REFLOW_MODEL (adapter),
+ index,
+ count);
+}
+
+static void
+remove_contacts (EAddressbookModel *model,
+ gpointer data,
+ EAddressbookReflowAdapter *adapter)
+{
+ GArray *indices = (GArray *) data;
+ gint count = indices->len;
+
+ if (count == 1)
+ e_reflow_model_item_removed (
+ E_REFLOW_MODEL (adapter),
+ g_array_index (indices, gint, 0));
+ else
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+}
static void
-create_card(EAddressbookModel *model,
- gint index, gint count,
- EAddressbookReflowAdapter *adapter)
+modify_contact (EAddressbookModel *model,
+ gint index,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_items_inserted (E_REFLOW_MODEL (adapter),
- index,
- count);
+ e_reflow_model_item_changed (E_REFLOW_MODEL (adapter), index);
}
static void
-remove_card(EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+model_changed (EAddressbookModel *model,
+ EAddressbookReflowAdapter *adapter)
{
e_reflow_model_changed (E_REFLOW_MODEL (adapter));
}
static void
-modify_card(EAddressbookModel *model,
- gint index,
- EAddressbookReflowAdapter *adapter)
+search_started (EAddressbookModel *model,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_item_changed (E_REFLOW_MODEL (adapter), index);
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+
+ priv->loading = TRUE;
}
static void
-model_changed(EAddressbookModel *model,
- EAddressbookReflowAdapter *adapter)
+search_result (EAddressbookModel *model,
+ const GError *error,
+ EAddressbookReflowAdapter *adapter)
{
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+ EAddressbookReflowAdapterPrivate *priv = adapter->priv;
+
+ priv->loading = FALSE;
+
+ e_reflow_model_comparison_changed (E_REFLOW_MODEL (adapter));
}
static void
-addressbook_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(o);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- switch (arg_id){
- case ARG_BOOK:
- gtk_object_set (GTK_OBJECT (priv->model),
- "book", GTK_VALUE_OBJECT (*arg),
- NULL);
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_object_set (
+ priv->model,
+ "client", g_value_get_object (value),
+ NULL);
break;
- case ARG_QUERY:
- gtk_object_set (GTK_OBJECT (priv->model),
- "query", GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_set (
+ priv->model,
+ "query", g_value_get_string (value),
+ NULL);
break;
- case ARG_EDITABLE:
- gtk_object_set (GTK_OBJECT (priv->model),
- "editable", GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_set (
+ priv->model,
+ "editable", g_value_get_boolean (value),
+ NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-addressbook_get_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+addressbook_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(o);
+ EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (object);
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- switch (arg_id) {
- case ARG_BOOK: {
- EBook *book;
- gtk_object_get (GTK_OBJECT (priv->model),
- "book", &book,
- NULL);
- if (book)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(book);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
+ switch (property_id) {
+ case PROP_CLIENT: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "client", value);
break;
}
- case ARG_QUERY: {
- char *query;
- gtk_object_get (GTK_OBJECT (priv->model),
- "query", &query,
- NULL);
- GTK_VALUE_STRING (*arg) = query;
+ case PROP_QUERY: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "query", value);
break;
}
- case ARG_EDITABLE: {
- gboolean editable;
- gtk_object_get (GTK_OBJECT (priv->model),
- "editable", &editable,
- NULL);
- GTK_VALUE_BOOL (*arg) = editable;
+ case PROP_EDITABLE: {
+ g_object_get_property (
+ G_OBJECT (priv->model),
+ "editable", value);
break;
}
- case ARG_MODEL:
- if (priv->model)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT (priv->model);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
+ case PROP_MODEL:
+ g_value_set_object (value, priv->model);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_addressbook_reflow_adapter_class_init (GtkObjectClass *object_class)
+e_addressbook_reflow_adapter_class_init (EAddressbookReflowAdapterClass *class)
{
- EReflowModelClass *model_class = (EReflowModelClass *) object_class;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->set_arg = addressbook_set_arg;
- object_class->get_arg = addressbook_get_arg;
- object_class->finalize = addressbook_finalize;
-
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EAddressbookReflowAdapter::model", E_ADDRESSBOOK_MODEL_TYPE,
- GTK_ARG_READABLE, ARG_MODEL);
-
- e_addressbook_reflow_adapter_signals [DRAG_BEGIN] =
- gtk_signal_new ("drag_begin",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookReflowAdapterClass, drag_begin),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
-
- gtk_object_class_add_signals (object_class, e_addressbook_reflow_adapter_signals, LAST_SIGNAL);
-
- model_class->set_width = addressbook_set_width;
- model_class->count = addressbook_count;
- model_class->height = addressbook_height;
- model_class->compare = addressbook_compare;
- model_class->incarnate = addressbook_incarnate;
- model_class->reincarnate = addressbook_reincarnate;
+ GObjectClass *object_class;
+ EReflowModelClass *reflow_model_class;
+
+ g_type_class_add_private (
+ class, sizeof (EAddressbookReflowAdapterPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_set_property;
+ object_class->get_property = addressbook_get_property;
+ object_class->dispose = addressbook_dispose;
+
+ reflow_model_class = E_REFLOW_MODEL_CLASS (class);
+ reflow_model_class->set_width = addressbook_set_width;
+ reflow_model_class->count = addressbook_count;
+ reflow_model_class->height = addressbook_height;
+ reflow_model_class->create_cmp_cache = addressbook_create_cmp_cache;
+ reflow_model_class->compare = addressbook_compare;
+ reflow_model_class->incarnate = addressbook_incarnate;
+ reflow_model_class->reincarnate = addressbook_reincarnate;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ 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_MODEL,
+ g_param_spec_object (
+ "model",
+ "Model",
+ NULL,
+ E_TYPE_ADDRESSBOOK_MODEL,
+ G_PARAM_READABLE));
+
+ signals[DRAG_BEGIN] = g_signal_new (
+ "drag_begin",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, drag_begin),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookReflowAdapterClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
}
static void
-e_addressbook_reflow_adapter_init (GtkObject *object)
-{
- EAddressbookReflowAdapter *adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(object);
- EAddressbookReflowAdapterPrivate *priv;
-
- priv = adapter->priv = g_new0 (EAddressbookReflowAdapterPrivate, 1);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
- priv->model_changed_id = 0;
-}
-
-GtkType
-e_addressbook_reflow_adapter_get_type (void)
+e_addressbook_reflow_adapter_init (EAddressbookReflowAdapter *adapter)
{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookReflowAdapter",
- sizeof (EAddressbookReflowAdapter),
- sizeof (EAddressbookReflowAdapterClass),
- (GtkClassInitFunc) e_addressbook_reflow_adapter_class_init,
- (GtkObjectInitFunc) e_addressbook_reflow_adapter_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
+ adapter->priv = E_ADDRESSBOOK_REFLOW_ADAPTER_GET_PRIVATE (adapter);
}
void
e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
- EAddressbookModel *model)
+ EAddressbookModel *model)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- priv->model = model;
- gtk_object_ref (GTK_OBJECT (priv->model));
-
- priv->create_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- adapter);
- priv->remove_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- adapter);
- priv->modify_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- adapter);
- priv->model_changed_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "model_changed",
- GTK_SIGNAL_FUNC(model_changed),
- adapter);
+ priv->model = g_object_ref (model);
+
+ priv->create_contact_id = g_signal_connect (
+ priv->model, "contact_added",
+ G_CALLBACK (create_contact), adapter);
+
+ priv->remove_contact_id = g_signal_connect (
+ priv->model, "contacts_removed",
+ G_CALLBACK (remove_contacts), adapter);
+
+ priv->modify_contact_id = g_signal_connect (
+ priv->model, "contact_changed",
+ G_CALLBACK (modify_contact), adapter);
+
+ priv->model_changed_id = g_signal_connect (
+ priv->model, "model_changed",
+ G_CALLBACK (model_changed), adapter);
+
+ priv->search_started_id = g_signal_connect (
+ priv->model, "search_started",
+ G_CALLBACK (search_started), adapter);
+
+ priv->search_result_id = g_signal_connect (
+ priv->model, "search_result",
+ G_CALLBACK (search_result), adapter);
}
EReflowModel *
@@ -454,19 +615,18 @@ e_addressbook_reflow_adapter_new (EAddressbookModel *model)
{
EAddressbookReflowAdapter *et;
- et = gtk_type_new (e_addressbook_reflow_adapter_get_type ());
+ et = g_object_new (E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, NULL);
e_addressbook_reflow_adapter_construct (et, model);
- return E_REFLOW_MODEL(et);
+ return E_REFLOW_MODEL (et);
}
-
-ECard *
-e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
- int index)
+EContact *
+e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
+ gint index)
{
EAddressbookReflowAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_get_card (priv->model, index);
+ return e_addressbook_model_get_contact (priv->model, index);
}
diff --git a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
index b3f6ab9c0d..fee217c2f1 100644
--- a/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-reflow-adapter.h
@@ -1,19 +1,37 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ *
+ * 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/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
#ifndef _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
#define _E_ADDRESSBOOK_REFLOW_ADAPTER_H_
-#include <gal/widgets/e-reflow-model.h>
-#include <gal/widgets/e-selection-model.h>
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
#include "e-addressbook-model.h"
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card.h"
-#define E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE (e_addressbook_reflow_adapter_get_type ())
-#define E_ADDRESSBOOK_REFLOW_ADAPTER(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE, EAddressbookReflowAdapter))
-#define E_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE, EAddressbookReflowAdapterClass))
-#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE))
-#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_REFLOW_ADAPTER_TYPE))
+#define E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER (e_addressbook_reflow_adapter_get_type ())
+#define E_ADDRESSBOOK_REFLOW_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapter))
+#define E_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER, EAddressbookReflowAdapterClass))
+#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER))
+#define E_IS_ADDRESSBOOK_REFLOW_ADAPTER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER))
typedef struct _EAddressbookReflowAdapter EAddressbookReflowAdapter;
typedef struct _EAddressbookReflowAdapterPrivate EAddressbookReflowAdapterPrivate;
@@ -25,23 +43,24 @@ struct _EAddressbookReflowAdapter {
EAddressbookReflowAdapterPrivate *priv;
};
-
struct _EAddressbookReflowAdapterClass {
EReflowModelClass parent_class;
/*
* Signals
*/
- gint (* drag_begin) (EAddressbookReflowAdapter *adapter, GdkEvent *event);
+ gint (*drag_begin) (EAddressbookReflowAdapter *adapter,
+ GdkEvent *event);
+ void (*open_contact) (EAddressbookReflowAdapter *adapter,
+ EContact *contact);
};
-
-GtkType e_addressbook_reflow_adapter_get_type (void);
+GType e_addressbook_reflow_adapter_get_type (void);
void e_addressbook_reflow_adapter_construct (EAddressbookReflowAdapter *adapter,
EAddressbookModel *model);
EReflowModel *e_addressbook_reflow_adapter_new (EAddressbookModel *model);
/* Returns object with ref count of 1. */
-ECard *e_addressbook_reflow_adapter_get_card (EAddressbookReflowAdapter *adapter,
- int index);
+EContact *e_addressbook_reflow_adapter_get_contact (EAddressbookReflowAdapter *adapter,
+ gint index);
#endif /* _E_ADDRESSBOOK_REFLOW_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-selector.c b/addressbook/gui/widgets/e-addressbook-selector.c
new file mode 100644
index 0000000000..7ef9ccd047
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.c
@@ -0,0 +1,443 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.c
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-addressbook-selector.h"
+
+#include <e-util/e-util.h>
+
+#include <eab-book-util.h>
+#include <eab-contact-merging.h>
+
+#define E_ADDRESSBOOK_SELECTOR_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorPrivate))
+
+typedef struct _MergeContext MergeContext;
+
+struct _EAddressbookSelectorPrivate {
+ EAddressbookView *current_view;
+};
+
+struct _MergeContext {
+ ESourceRegistry *registry;
+ EBookClient *source_client;
+ EBookClient *target_client;
+
+ EContact *current_contact;
+ GSList *remaining_contacts;
+ guint pending_removals;
+ gboolean pending_adds;
+
+ gint remove_from_source : 1;
+ gint copy_done : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_CURRENT_VIEW
+};
+
+static GtkTargetEntry drag_types[] = {
+ { (gchar *) "text/x-source-vcard", 0, 0 }
+};
+
+G_DEFINE_TYPE (
+ EAddressbookSelector,
+ e_addressbook_selector,
+ E_TYPE_CLIENT_SELECTOR)
+
+static void
+merge_context_next (MergeContext *merge_context)
+{
+ GSList *list;
+
+ merge_context->current_contact = NULL;
+ if (!merge_context->remaining_contacts)
+ return;
+
+ list = merge_context->remaining_contacts;
+ merge_context->current_contact = list->data;
+ list = g_slist_delete_link (list, list);
+ merge_context->remaining_contacts = list;
+}
+
+static MergeContext *
+merge_context_new (ESourceRegistry *registry,
+ EBookClient *source_client,
+ EBookClient *target_client,
+ GSList *contact_list)
+{
+ MergeContext *merge_context;
+
+ merge_context = g_slice_new0 (MergeContext);
+ merge_context->registry = g_object_ref (registry);
+ merge_context->source_client = source_client;
+ merge_context->target_client = target_client;
+ merge_context->remaining_contacts = contact_list;
+ merge_context_next (merge_context);
+
+ return merge_context;
+}
+
+static void
+merge_context_free (MergeContext *merge_context)
+{
+ if (merge_context->registry != NULL)
+ g_object_unref (merge_context->registry);
+
+ if (merge_context->source_client != NULL)
+ g_object_unref (merge_context->source_client);
+
+ if (merge_context->target_client != NULL)
+ g_object_unref (merge_context->target_client);
+
+ g_slice_free (MergeContext, merge_context);
+}
+
+static void
+addressbook_selector_removed_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ MergeContext *merge_context = user_data;
+ GError *error = NULL;
+
+ e_book_client_remove_contact_finish (book_client, result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to remove contact: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ merge_context->pending_removals--;
+
+ if (merge_context->pending_adds)
+ return;
+
+ if (merge_context->pending_removals > 0)
+ return;
+
+ merge_context_free (merge_context);
+}
+
+static void
+addressbook_selector_merge_next_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer closure)
+{
+ MergeContext *merge_context = closure;
+
+ if (merge_context->remove_from_source && !error) {
+ /* Remove previous contact from source. */
+ e_book_client_remove_contact (
+ merge_context->source_client,
+ merge_context->current_contact, NULL,
+ addressbook_selector_removed_cb, merge_context);
+ merge_context->pending_removals++;
+ }
+
+ g_object_unref (merge_context->current_contact);
+
+ if (merge_context->remaining_contacts != NULL) {
+ merge_context_next (merge_context);
+ eab_merging_book_add_contact (
+ merge_context->registry,
+ merge_context->target_client,
+ merge_context->current_contact,
+ addressbook_selector_merge_next_cb, merge_context);
+
+ } else if (merge_context->pending_removals == 0) {
+ merge_context_free (merge_context);
+ } else
+ merge_context->pending_adds = FALSE;
+}
+
+static void
+addressbook_selector_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ e_addressbook_selector_set_current_view (
+ E_ADDRESSBOOK_SELECTOR (object),
+ g_value_get_object (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CURRENT_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_selector_get_current_view (
+ E_ADDRESSBOOK_SELECTOR (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+addressbook_selector_dispose (GObject *object)
+{
+ EAddressbookSelectorPrivate *priv;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (object);
+
+ if (priv->current_view != NULL) {
+ g_object_unref (priv->current_view);
+ priv->current_view = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_selector_parent_class)->dispose (object);
+}
+
+static void
+addressbook_selector_constructed (GObject *object)
+{
+ ESourceSelector *selector;
+ ESourceRegistry *registry;
+ ESource *source;
+
+ selector = E_SOURCE_SELECTOR (object);
+ registry = e_source_selector_get_registry (selector);
+ source = e_source_registry_ref_default_address_book (registry);
+ e_source_selector_set_primary_selection (selector, source);
+ g_object_unref (source);
+
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_selector_parent_class)->
+ constructed (object);
+}
+
+static void
+target_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ MergeContext *merge_context = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ g_return_if_fail (merge_context != NULL);
+
+ client = e_client_selector_get_client_finish (
+ E_CLIENT_SELECTOR (source_object), result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ merge_context->target_client = client ? E_BOOK_CLIENT (client) : NULL;
+
+ if (!merge_context->target_client) {
+ g_slist_foreach (
+ merge_context->remaining_contacts,
+ (GFunc) g_object_unref, NULL);
+ g_slist_free (merge_context->remaining_contacts);
+
+ merge_context_free (merge_context);
+ return;
+ }
+
+ eab_merging_book_add_contact (
+ merge_context->registry,
+ merge_context->target_client,
+ merge_context->current_contact,
+ addressbook_selector_merge_next_cb, merge_context);
+}
+
+static gboolean
+addressbook_selector_data_dropped (ESourceSelector *selector,
+ GtkSelectionData *selection_data,
+ ESource *destination,
+ GdkDragAction action,
+ guint info)
+{
+ EAddressbookSelectorPrivate *priv;
+ MergeContext *merge_context;
+ EAddressbookModel *model;
+ EBookClient *source_client;
+ ESourceRegistry *registry;
+ GSList *list;
+ const gchar *string;
+ gboolean remove_from_source;
+
+ priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+ g_return_val_if_fail (priv->current_view != NULL, FALSE);
+
+ string = (const gchar *) gtk_selection_data_get_data (selection_data);
+ remove_from_source = (action == GDK_ACTION_MOVE);
+
+ registry = e_source_selector_get_registry (selector);
+
+ eab_source_and_contact_list_from_string (
+ registry, string, NULL, &list);
+
+ if (list == NULL)
+ return FALSE;
+
+ model = e_addressbook_view_get_model (priv->current_view);
+ source_client = e_addressbook_model_get_client (model);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (source_client), FALSE);
+
+ merge_context = merge_context_new (
+ registry, g_object_ref (source_client), NULL, list);
+ merge_context->remove_from_source = remove_from_source;
+ merge_context->pending_adds = TRUE;
+
+ e_client_selector_get_client (
+ E_CLIENT_SELECTOR (selector), destination, NULL,
+ target_client_connect_cb, merge_context);
+
+ return TRUE;
+}
+
+static void
+e_addressbook_selector_class_init (EAddressbookSelectorClass *class)
+{
+ GObjectClass *object_class;
+ ESourceSelectorClass *selector_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookSelectorPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_selector_set_property;
+ object_class->get_property = addressbook_selector_get_property;
+ object_class->dispose = addressbook_selector_dispose;
+ object_class->constructed = addressbook_selector_constructed;
+
+ selector_class = E_SOURCE_SELECTOR_CLASS (class);
+ selector_class->data_dropped = addressbook_selector_data_dropped;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CURRENT_VIEW,
+ g_param_spec_object (
+ "current-view",
+ NULL,
+ NULL,
+ E_TYPE_ADDRESSBOOK_VIEW,
+ G_PARAM_READWRITE));
+}
+
+static void
+e_addressbook_selector_init (EAddressbookSelector *selector)
+{
+ selector->priv = E_ADDRESSBOOK_SELECTOR_GET_PRIVATE (selector);
+
+ e_source_selector_set_show_colors (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ gtk_drag_dest_set (
+ GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ e_drag_dest_add_directory_targets (GTK_WIDGET (selector));
+}
+
+GtkWidget *
+e_addressbook_selector_new (EClientCache *client_cache)
+{
+ ESourceRegistry *registry;
+ GtkWidget *widget;
+
+ g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL);
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ widget = g_object_new (
+ E_TYPE_ADDRESSBOOK_SELECTOR,
+ "client-cache", client_cache,
+ "extension-name", E_SOURCE_EXTENSION_ADDRESS_BOOK,
+ "registry", registry, NULL);
+
+ g_object_unref (registry);
+
+ return widget;
+}
+
+EAddressbookView *
+e_addressbook_selector_get_current_view (EAddressbookSelector *selector)
+{
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector), NULL);
+
+ return selector->priv->current_view;
+}
+
+void
+e_addressbook_selector_set_current_view (EAddressbookSelector *selector,
+ EAddressbookView *current_view)
+{
+ /* XXX This is only needed for moving contacts via drag-and-drop.
+ * The selection data doesn't include the source of the data
+ * (the model for the currently selected address book view),
+ * so we have to rely on it being provided to us. I would
+ * be happy to see this function go away. */
+
+ g_return_if_fail (E_IS_ADDRESSBOOK_SELECTOR (selector));
+
+ if (current_view != NULL)
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (current_view));
+
+ if (selector->priv->current_view == current_view)
+ return;
+
+ if (selector->priv->current_view != NULL) {
+ g_object_unref (selector->priv->current_view);
+ selector->priv->current_view = NULL;
+ }
+
+ if (current_view != NULL)
+ g_object_ref (current_view);
+
+ selector->priv->current_view = current_view;
+
+ g_object_notify (G_OBJECT (selector), "current-view");
+}
diff --git a/addressbook/gui/widgets/e-addressbook-selector.h b/addressbook/gui/widgets/e-addressbook-selector.h
new file mode 100644
index 0000000000..3746bc3aeb
--- /dev/null
+++ b/addressbook/gui/widgets/e-addressbook-selector.h
@@ -0,0 +1,71 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-addressbook-selector.h
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.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.
+ *
+ * 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., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef E_ADDRESSBOOK_SELECTOR_H
+#define E_ADDRESSBOOK_SELECTOR_H
+
+#include "e-addressbook-view.h"
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_SELECTOR \
+ (e_addressbook_selector_get_type ())
+#define E_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelector))
+#define E_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+#define E_IS_ADDRESSBOOK_SELECTOR(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_IS_ADDRESSBOOK_SELECTOR_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_SELECTOR))
+#define E_ADDRESSBOOK_SELECTOR_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_SELECTOR, EAddressbookSelectorClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookSelector EAddressbookSelector;
+typedef struct _EAddressbookSelectorClass EAddressbookSelectorClass;
+typedef struct _EAddressbookSelectorPrivate EAddressbookSelectorPrivate;
+
+struct _EAddressbookSelector {
+ EClientSelector parent;
+ EAddressbookSelectorPrivate *priv;
+};
+
+struct _EAddressbookSelectorClass {
+ EClientSelectorClass parent_class;
+};
+
+GType e_addressbook_selector_get_type (void);
+GtkWidget * e_addressbook_selector_new (EClientCache *client_cache);
+EAddressbookView *
+ e_addressbook_selector_get_current_view
+ (EAddressbookSelector *selector);
+void e_addressbook_selector_set_current_view
+ (EAddressbookSelector *selector,
+ EAddressbookView *current_view);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_SELECTOR_H */
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.c b/addressbook/gui/widgets/e-addressbook-table-adapter.c
index abcaf6e6b0..a7f1f6bb5b 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.c
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.c
@@ -1,398 +1,434 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-
+/*
+ * 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:
+ *
+ * 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 <libebook/libebook.h>
+
#include "e-addressbook-model.h"
#include "e-addressbook-table-adapter.h"
-#include "e-card-merging.h"
-#include "e-addressbook-util.h"
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
-#include <gnome-xml/xmlmemory.h>
-#include <gnome.h>
+#include "eab-book-util.h"
+#include "eab-contact-merging.h"
+#include "eab-gui-util.h"
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+#include <libxml/xmlmemory.h>
+
+#define E_ADDRESSBOOK_TABLE_ADAPTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterPrivate))
struct _EAddressbookTableAdapterPrivate {
EAddressbookModel *model;
- ECardSimple **simples;
- int count;
+ gint create_contact_id, remove_contact_id, modify_contact_id, model_changed_id;
- int create_card_id, remove_card_id, modify_card_id, model_changed_id;
+ GHashTable *emails;
};
-#define PARENT_TYPE e_table_model_get_type()
-ETableModelClass *parent_class;
+/* Forward Declarations */
+static void e_addressbook_table_adapter_table_model_init
+ (ETableModelInterface *interface);
-#define COLS (E_CARD_SIMPLE_FIELD_LAST)
+G_DEFINE_TYPE_WITH_CODE (
+ EAddressbookTableAdapter,
+ e_addressbook_table_adapter,
+ G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_TABLE_MODEL,
+ e_addressbook_table_adapter_table_model_init))
static void
-unlink_model(EAddressbookTableAdapter *adapter)
+unlink_model (EAddressbookTableAdapter *adapter)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
-
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->create_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->remove_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->modify_card_id);
- gtk_signal_disconnect(GTK_OBJECT (priv->model),
- priv->model_changed_id);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
- priv->model_changed_id = 0;
- /* free up the existing mapping if there is one */
- if (priv->simples) {
- for (i = 0; i < priv->count; i ++)
- gtk_object_unref (GTK_OBJECT (priv->simples[i]));
- g_free (priv->simples);
- priv->simples = NULL;
- }
+ g_signal_handler_disconnect (priv->model, priv->create_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->remove_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->modify_contact_id);
+ g_signal_handler_disconnect (priv->model, priv->model_changed_id);
+
+ priv->create_contact_id = 0;
+ priv->remove_contact_id = 0;
+ priv->modify_contact_id = 0;
+ priv->model_changed_id = 0;
- gtk_object_unref(GTK_OBJECT(priv->model));
+ g_object_unref (priv->model);
priv->model = NULL;
}
static void
-build_simple_mapping(EAddressbookTableAdapter *adapter)
+addressbook_finalize (GObject *object)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
+ EAddressbookTableAdapter *adapter;
- /* free up the existing mapping if there is one */
- if (priv->simples) {
- for (i = 0; i < priv->count; i ++)
- gtk_object_unref (GTK_OBJECT (priv->simples[i]));
- g_free (priv->simples);
- }
+ adapter = E_ADDRESSBOOK_TABLE_ADAPTER (object);
- /* build up our mapping to ECardSimple*'s */
- priv->count = e_addressbook_model_card_count (priv->model);
- priv->simples = g_new (ECardSimple*, priv->count);
- for (i = 0; i < priv->count; i ++) {
- priv->simples[i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, i));
- gtk_object_ref (GTK_OBJECT (priv->simples[i]));
- }
-}
-
-static void
-addressbook_destroy(GtkObject *object)
-{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object);
+ unlink_model (adapter);
- unlink_model(adapter);
+ g_hash_table_destroy (adapter->priv->emails);
- g_free (adapter->priv);
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_addressbook_table_adapter_parent_class)->finalize (object);
}
/* This function returns the number of columns in our ETableModel. */
-static int
+static gint
addressbook_col_count (ETableModel *etc)
{
- return COLS;
+ return E_CONTACT_FIELD_LAST;
}
/* This function returns the number of rows in our ETableModel. */
-static int
+static gint
addressbook_row_count (ETableModel *etc)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- return e_addressbook_model_card_count (priv->model);
+ return e_addressbook_model_contact_count (priv->model);
+}
+
+static void
+addressbook_append_row (ETableModel *etm,
+ ETableModel *source,
+ gint row)
+{
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etm);
+ EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ EBookClient *book_client;
+ EContact *contact;
+ gint col;
+
+ contact = e_contact_new ();
+
+ for (col = 1; col < E_CONTACT_LAST_SIMPLE_STRING; col++) {
+ gconstpointer val = e_table_model_value_at (source, col, row);
+ e_contact_set (contact, col, (gpointer) val);
+ }
+
+ client_cache =
+ e_addressbook_model_get_client_cache (priv->model);
+ book_client = e_addressbook_model_get_client (priv->model);
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ eab_merging_book_add_contact (
+ registry, book_client, contact, NULL, NULL);
+
+ g_object_unref (registry);
+
+ g_object_unref (contact);
}
/* This function returns the value at a particular point in our ETableModel. */
-static void *
-addressbook_value_at (ETableModel *etc, int col, int row)
+static gpointer
+addressbook_value_at (ETableModel *etc,
+ gint col,
+ gint row)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- const char *value;
+ EContact *contact;
+ const gchar *value;
- if ( col >= COLS || row >= e_addressbook_model_card_count (priv->model) )
+ if (col >= E_CONTACT_FIELD_LAST)
return NULL;
- value = e_card_simple_get_const(priv->simples[row], col);
+ if (row >= e_addressbook_model_contact_count (priv->model))
+ return NULL;
+
+ contact = e_addressbook_model_contact_at (priv->model, row);
+ value = e_contact_get_const (contact, col);
+
+ if (value && *value && (col == E_CONTACT_EMAIL_1 ||
+ col == E_CONTACT_EMAIL_2 || col == E_CONTACT_EMAIL_3)) {
+ gchar *val = g_hash_table_lookup (priv->emails, value);
+
+ if (val) {
+ /* we have this already cached, so use value from the cache */
+ value = val;
+ } else {
+ gchar *name = NULL, *mail = NULL;
+
+ if (eab_parse_qp_email (value, &name, &mail))
+ val = g_strdup_printf ("%s <%s>", name, mail);
+ else
+ val = g_strdup (value);
- if (value && !strncmp (value, "<?xml", 5)) {
- EDestination *dest = e_destination_import (value);
- if (dest) {
- g_free ((gchar *) value);
- value = g_strdup (e_destination_get_address (dest));
- gtk_object_unref (GTK_OBJECT (dest));
+ g_free (name);
+ g_free (mail);
+
+ g_hash_table_insert (priv->emails, g_strdup (value), val);
+ value = val;
}
}
-
- return (void *)(value ? value : "");
+ return (gpointer)(value ? value : "");
}
/* This function sets the value at a particular point in our ETableModel. */
static void
-card_modified_cb (EBook* book, EBookStatus status,
- gpointer user_data)
+contact_modified_cb (EBookClient *book_client,
+ const GError *error,
+ gpointer user_data)
{
- /* g_print ("%s: %s(): a card was modified\n", __FILE__, __FUNCTION__); */
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
+ if (error)
+ eab_error_dialog (NULL, NULL, _("Error modifying card"), error);
}
+
static void
-addressbook_set_value_at (ETableModel *etc, int col, int row, const void *val)
+addressbook_set_value_at (ETableModel *etc,
+ gint col,
+ gint row,
+ gconstpointer val)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
+ EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER (etc);
EAddressbookTableAdapterPrivate *priv = adapter->priv;
- if (e_addressbook_model_editable (priv->model)) {
- ECard *card;
- if ( col >= COLS|| row >= e_addressbook_model_card_count (priv->model) )
+ if (e_addressbook_model_get_editable (priv->model)) {
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ EBookClient *book_client;
+ EContact *contact;
+
+ if (col >= E_CONTACT_FIELD_LAST)
return;
- e_table_model_pre_change(etc);
+ if (row >= e_addressbook_model_contact_count (priv->model))
+ return;
- e_card_simple_set(priv->simples[row],
- col,
- val);
- gtk_object_get(GTK_OBJECT(priv->simples[row]),
- "card", &card,
- NULL);
+ contact = e_addressbook_model_get_contact (priv->model, row);
+ if (!contact)
+ return;
- e_card_merging_book_commit_card(e_addressbook_model_get_ebook(priv->model),
- card, card_modified_cb, NULL);
+ e_table_model_pre_change (etc);
- /* XXX do we need this? shouldn't the commit_card generate a changed signal? */
- e_table_model_cell_changed(etc, col, row);
- }
-}
+ if (col == E_CONTACT_EMAIL_1 ||
+ col == E_CONTACT_EMAIL_2 ||
+ col == E_CONTACT_EMAIL_3) {
+ const gchar *old_value = e_contact_get_const (contact, col);
-/* This function returns whether a particular cell is editable. */
-static gboolean
-addressbook_is_cell_editable (ETableModel *etc, int col, int row)
-{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etc);
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- ECard *card;
+ /* remove old value from cache and use new one */
+ if (old_value && *old_value)
+ g_hash_table_remove (priv->emails, old_value);
+ }
- if (row >= 0 && row < e_addressbook_model_card_count (priv->model))
- card = e_addressbook_model_card_at (priv->model, row);
- else
- card = NULL;
-
- if (!e_addressbook_model_editable(priv->model))
- return FALSE;
- else if (card && e_card_evolution_list (card))
- /* we only allow editing of the name and file as for
- lists */
- return col == E_CARD_SIMPLE_FIELD_FULL_NAME || col == E_CARD_SIMPLE_FIELD_FILE_AS;
- else
- return col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING;
-}
+ client_cache =
+ e_addressbook_model_get_client_cache (priv->model);
+ book_client = e_addressbook_model_get_client (priv->model);
-static void
-addressbook_append_row (ETableModel *etm, ETableModel *source, gint row)
-{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(etm);
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- ECard *card;
- ECardSimple *simple;
- int col;
+ registry = e_client_cache_ref_registry (client_cache);
+
+ e_contact_set (contact, col, (gpointer) val);
+ eab_merging_book_modify_contact (
+ registry, book_client,
+ contact, contact_modified_cb, etc);
- card = e_card_new("");
- simple = e_card_simple_new(card);
+ g_object_unref (registry);
- for (col = 0; col < E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING; col++) {
- const void *val = e_table_model_value_at(source, col, row);
- e_card_simple_set(simple, col, val);
+ g_object_unref (contact);
+
+ /* XXX Do we need this? Shouldn't the commit_contact
+ * generate a changed signal? */
+ e_table_model_cell_changed (etc, col, row);
}
- e_card_simple_sync_card(simple);
- e_card_merging_book_add_card (e_addressbook_model_get_ebook (priv->model), card, NULL, NULL);
- gtk_object_unref(GTK_OBJECT(simple));
- gtk_object_unref(GTK_OBJECT(card));
+}
+
+/* This function returns whether a particular cell is editable. */
+static gboolean
+addressbook_is_cell_editable (ETableModel *etc,
+ gint col,
+ gint row)
+{
+ return FALSE;
}
/* This function duplicates the value passed to it. */
-static void *
-addressbook_duplicate_value (ETableModel *etc, int col, const void *value)
+static gpointer
+addressbook_duplicate_value (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return g_strdup(value);
+ return g_strdup (value);
}
/* This function frees the value passed to it. */
static void
-addressbook_free_value (ETableModel *etc, int col, void *value)
+addressbook_free_value (ETableModel *etc,
+ gint col,
+ gpointer value)
{
- g_free(value);
+ g_free (value);
}
-static void *
-addressbook_initialize_value (ETableModel *etc, int col)
+static gpointer
+addressbook_initialize_value (ETableModel *etc,
+ gint col)
{
- return g_strdup("");
+ return g_strdup ("");
}
static gboolean
-addressbook_value_is_empty (ETableModel *etc, int col, const void *value)
+addressbook_value_is_empty (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return !(value && *(char *)value);
+ return !(value && *(gchar *) value);
}
-static char *
-addressbook_value_to_string (ETableModel *etc, int col, const void *value)
+static gchar *
+addressbook_value_to_string (ETableModel *etc,
+ gint col,
+ gconstpointer value)
{
- return g_strdup(value);
+ return g_strdup (value);
}
static void
-e_addressbook_table_adapter_class_init (GtkObjectClass *object_class)
+e_addressbook_table_adapter_class_init (EAddressbookTableAdapterClass *class)
{
- ETableModelClass *model_class = (ETableModelClass *) object_class;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- object_class->destroy = addressbook_destroy;
-
- model_class->column_count = addressbook_col_count;
- model_class->row_count = addressbook_row_count;
- model_class->value_at = addressbook_value_at;
- model_class->set_value_at = addressbook_set_value_at;
- model_class->is_cell_editable = addressbook_is_cell_editable;
- model_class->append_row = addressbook_append_row;
- model_class->duplicate_value = addressbook_duplicate_value;
- model_class->free_value = addressbook_free_value;
- model_class->initialize_value = addressbook_initialize_value;
- model_class->value_is_empty = addressbook_value_is_empty;
- model_class->value_to_string = addressbook_value_to_string;
+ GObjectClass *object_class;
+
+ g_type_class_add_private (
+ class, sizeof (EAddressbookTableAdapterPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = addressbook_finalize;
}
static void
-e_addressbook_table_adapter_init (GtkObject *object)
+e_addressbook_table_adapter_table_model_init (ETableModelInterface *interface)
{
- EAddressbookTableAdapter *adapter = E_ADDRESSBOOK_TABLE_ADAPTER(object);
- EAddressbookTableAdapterPrivate *priv;
-
- priv = adapter->priv = g_new0 (EAddressbookTableAdapterPrivate, 1);
-
- priv->create_card_id = 0;
- priv->remove_card_id = 0;
- priv->modify_card_id = 0;
- priv->model_changed_id = 0;
- priv->simples = NULL;
- priv->count = 0;
+ interface->column_count = addressbook_col_count;
+ interface->row_count = addressbook_row_count;
+ interface->append_row = addressbook_append_row;
+
+ interface->value_at = addressbook_value_at;
+ interface->set_value_at = addressbook_set_value_at;
+ interface->is_cell_editable = addressbook_is_cell_editable;
+
+ interface->duplicate_value = addressbook_duplicate_value;
+ interface->free_value = addressbook_free_value;
+ interface->initialize_value = addressbook_initialize_value;
+ interface->value_is_empty = addressbook_value_is_empty;
+ interface->value_to_string = addressbook_value_to_string;
}
-
static void
-create_card (EAddressbookModel *model,
- gint index, gint count,
- EAddressbookTableAdapter *adapter)
+e_addressbook_table_adapter_init (EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
- int i;
-
- priv->count += count;
- priv->simples = g_renew(ECardSimple *, priv->simples, priv->count);
- memmove (priv->simples + index + count, priv->simples + index, (priv->count - index - count) * sizeof (ECardSimple *));
+ adapter->priv = E_ADDRESSBOOK_TABLE_ADAPTER_GET_PRIVATE (adapter);
+}
+static void
+create_contact (EAddressbookModel *model,
+ gint index,
+ gint count,
+ EAddressbookTableAdapter *adapter)
+{
e_table_model_pre_change (E_TABLE_MODEL (adapter));
- for (i = 0; i < count; i ++) {
- priv->simples[index + i] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index + i));
- }
e_table_model_rows_inserted (E_TABLE_MODEL (adapter), index, count);
}
static void
-remove_card (EAddressbookModel *model,
- gint index,
- EAddressbookTableAdapter *adapter)
+remove_contacts (EAddressbookModel *model,
+ gpointer data,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ GArray *indices = (GArray *) data;
+ gint count = indices->len;
- e_table_model_pre_change (E_TABLE_MODEL (adapter));
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
- gtk_object_unref (GTK_OBJECT (priv->simples[index]));
- memmove (priv->simples + index, priv->simples + index + 1, (priv->count - index - 1) * sizeof (ECardSimple *));
- priv->count --;
- e_table_model_rows_deleted (E_TABLE_MODEL (adapter), index, 1);
+ e_table_model_pre_change (E_TABLE_MODEL (adapter));
+ if (count == 1)
+ e_table_model_rows_deleted (
+ E_TABLE_MODEL (adapter),
+ g_array_index (indices, gint, 0), 1);
+ else
+ e_table_model_changed (E_TABLE_MODEL (adapter));
}
static void
-modify_card (EAddressbookModel *model,
- gint index,
- EAddressbookTableAdapter *adapter)
+modify_contact (EAddressbookModel *model,
+ gint index,
+ EAddressbookTableAdapter *adapter)
{
- EAddressbookTableAdapterPrivate *priv = adapter->priv;
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
e_table_model_pre_change (E_TABLE_MODEL (adapter));
-
- gtk_object_unref (GTK_OBJECT (priv->simples[index]));
- priv->simples[index] = e_card_simple_new (e_addressbook_model_card_at (priv->model, index));
- gtk_object_ref (GTK_OBJECT (priv->simples[index]));
e_table_model_row_changed (E_TABLE_MODEL (adapter), index);
}
static void
model_changed (EAddressbookModel *model,
- EAddressbookTableAdapter *adapter)
+ EAddressbookTableAdapter *adapter)
{
+ /* clear whole cache */
+ g_hash_table_remove_all (adapter->priv->emails);
+
e_table_model_pre_change (E_TABLE_MODEL (adapter));
- build_simple_mapping (adapter);
e_table_model_changed (E_TABLE_MODEL (adapter));
}
-GtkType
-e_addressbook_table_adapter_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type){
- GtkTypeInfo info = {
- "EAddressbookTableAdapter",
- sizeof (EAddressbookTableAdapter),
- sizeof (EAddressbookTableAdapterClass),
- (GtkClassInitFunc) e_addressbook_table_adapter_class_init,
- (GtkObjectInitFunc) e_addressbook_table_adapter_init,
- NULL, /* reserved 1 */
- NULL, /* reserved 2 */
- (GtkClassInitFunc) NULL
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
-
void
e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EAddressbookModel *model)
+ EAddressbookModel *model)
{
EAddressbookTableAdapterPrivate *priv = adapter->priv;
priv->model = model;
- gtk_object_ref (GTK_OBJECT (priv->model));
-
- priv->create_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_added",
- GTK_SIGNAL_FUNC(create_card),
- adapter);
- priv->remove_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_removed",
- GTK_SIGNAL_FUNC(remove_card),
- adapter);
- priv->modify_card_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "card_changed",
- GTK_SIGNAL_FUNC(modify_card),
- adapter);
- priv->model_changed_id = gtk_signal_connect(GTK_OBJECT(priv->model),
- "model_changed",
- GTK_SIGNAL_FUNC(model_changed),
- adapter);
-
- build_simple_mapping (adapter);
+ g_object_ref (priv->model);
+
+ priv->create_contact_id = g_signal_connect (
+ priv->model, "contact_added",
+ G_CALLBACK (create_contact), adapter);
+
+ priv->remove_contact_id = g_signal_connect (
+ priv->model, "contacts_removed",
+ G_CALLBACK (remove_contacts), adapter);
+
+ priv->modify_contact_id = g_signal_connect (
+ priv->model, "contact_changed",
+ G_CALLBACK (modify_contact), adapter);
+
+ priv->model_changed_id = g_signal_connect (
+ priv->model, "model_changed",
+ G_CALLBACK (model_changed), adapter);
+
+ priv->emails = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_free);
}
ETableModel *
@@ -400,9 +436,9 @@ e_addressbook_table_adapter_new (EAddressbookModel *model)
{
EAddressbookTableAdapter *et;
- et = gtk_type_new (e_addressbook_table_adapter_get_type ());
+ et = g_object_new (E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, NULL);
e_addressbook_table_adapter_construct (et, model);
- return E_TABLE_MODEL(et);
+ return E_TABLE_MODEL (et);
}
diff --git a/addressbook/gui/widgets/e-addressbook-table-adapter.h b/addressbook/gui/widgets/e-addressbook-table-adapter.h
index d76434e80a..93b7ae9553 100644
--- a/addressbook/gui/widgets/e-addressbook-table-adapter.h
+++ b/addressbook/gui/widgets/e-addressbook-table-adapter.h
@@ -1,44 +1,70 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-#ifndef _E_ADDRESSBOOK_TABLE_ADAPTER_H_
-#define _E_ADDRESSBOOK_TABLE_ADAPTER_H_
-
-#include <gal/e-table/e-table-model.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/backend/ebook/e-book-view.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#define E_ADDRESSBOOK_TABLE_ADAPTER_TYPE (e_addressbook_table_adapter_get_type ())
-#define E_ADDRESSBOOK_TABLE_ADAPTER(o) (GTK_CHECK_CAST ((o), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE, EAddressbookTableAdapter))
-#define E_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE, EAddressbookTableAdapterClass))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(o) (GTK_CHECK_TYPE ((o), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE))
-#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), E_ADDRESSBOOK_TABLE_ADAPTER_TYPE))
-
-/* Virtual Column list:
- 0 Email
- 1 Full Name
- 2 Street
- 3 Phone
-*/
+/*
+ *
+ * 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/>
+ *
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef _EAB_TABLE_ADAPTER_H_
+#define _EAB_TABLE_ADAPTER_H_
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_TABLE_ADAPTER \
+ (e_addressbook_table_adapter_get_type ())
+#define E_ADDRESSBOOK_TABLE_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapter))
+#define E_ADDRESSBOOK_TABLE_ADAPTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterClass))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
+#define E_IS_ADDRESSBOOK_TABLE_ADAPTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER))
+#define E_ADDRESSBOOK_TABLE_ADAPTER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_TABLE_ADAPTER, EAddressbookTableAdapterClass))
+
+G_BEGIN_DECLS
typedef struct _EAddressbookTableAdapter EAddressbookTableAdapter;
-typedef struct _EAddressbookTableAdapterPrivate EAddressbookTableAdapterPrivate;
typedef struct _EAddressbookTableAdapterClass EAddressbookTableAdapterClass;
+typedef struct _EAddressbookTableAdapterPrivate EAddressbookTableAdapterPrivate;
struct _EAddressbookTableAdapter {
- ETableModel parent;
-
+ GObject parent;
EAddressbookTableAdapterPrivate *priv;
};
-
struct _EAddressbookTableAdapterClass {
- ETableModelClass parent_class;
+ GObjectClass parent_class;
};
+GType e_addressbook_table_adapter_get_type
+ (void) G_GNUC_CONST;
+void e_addressbook_table_adapter_construct
+ (EAddressbookTableAdapter *adapter,
+ EAddressbookModel *model);
+ETableModel * e_addressbook_table_adapter_new
+ (EAddressbookModel *model);
-GtkType e_addressbook_table_adapter_get_type (void);
-void e_addressbook_table_adapter_construct (EAddressbookTableAdapter *adapter,
- EAddressbookModel *model);
-ETableModel *e_addressbook_table_adapter_new (EAddressbookModel *model);
+G_END_DECLS
-#endif /* _E_ADDRESSBOOK_TABLE_ADAPTER_H_ */
+#endif /* _EAB_TABLE_ADAPTER_H_ */
diff --git a/addressbook/gui/widgets/e-addressbook-util.c b/addressbook/gui/widgets/e-addressbook-util.c
deleted file mode 100644
index 04f4238fbd..0000000000
--- a/addressbook/gui/widgets/e-addressbook-util.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-table-field-chooser.c
- * Copyright (C) 2001 Ximian, Inc.
- * Author: Chris Toshok <toshok@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-addressbook-util.h"
-
-#include <gnome.h>
-
-#include "e-card-merging.h"
-#include <shell/evolution-shell-client.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-
-void
-e_addressbook_error_dialog (const gchar *msg, EBookStatus status)
-{
- static char *status_to_string[] = {
- N_("Success"),
- N_("Unknown error"),
- N_("Repository offline"),
- N_("Permission denied"),
- N_("Card not found"),
- N_("Card ID already exists"),
- N_("Protocol not supported"),
- N_("Cancelled"),
- N_("Authentication Failed"),
- N_("Authentication Required"),
- N_("TLS not Available"),
- N_("Addressbook does not exist"),
- N_("Other error")
- };
- char *error_msg;
-
- error_msg = g_strdup_printf ("%s: %s", msg, _(status_to_string [status]));
-
- gtk_widget_show (gnome_error_dialog (error_msg));
-
- g_free (error_msg);
-}
-
-gint
-e_addressbook_prompt_save_dialog (GtkWindow *parent)
-{
- GtkWidget *dialog;
-
- dialog = gnome_message_box_new (_("Do you want to save changes?"),
- GNOME_MESSAGE_BOX_QUESTION,
- GNOME_STOCK_BUTTON_YES,
- GNOME_STOCK_BUTTON_NO,
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
-
- gnome_dialog_set_default (GNOME_DIALOG (dialog), 0);
- gnome_dialog_grab_focus (GNOME_DIALOG (dialog), 0);
- gnome_dialog_set_parent (GNOME_DIALOG (dialog), parent);
-
- return gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
-}
-
-static void
-added_cb (EBook* book, EBookStatus status, const char *id,
- gboolean is_list)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error adding list") : _("Error adding card"), status);
- }
-}
-
-static void
-modified_cb (EBook* book, EBookStatus status,
- gboolean is_list)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error modifying list") : _("Error modifying card"),
- status);
- }
-}
-
-static void
-deleted_cb (EBook* book, EBookStatus status,
- gboolean is_list)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (is_list ? _("Error removing list") : _("Error removing card"),
- status);
- }
-}
-
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
-{
- gtk_object_unref (editor);
-}
-
-EContactEditor *
-e_addressbook_show_contact_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
-{
- EContactEditor *ce;
-
- ce = e_contact_editor_new (book, card, is_new_card, editable);
-
- gtk_signal_connect (GTK_OBJECT (ce), "card_added",
- GTK_SIGNAL_FUNC (added_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "card_modified",
- GTK_SIGNAL_FUNC (modified_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "card_deleted",
- GTK_SIGNAL_FUNC (deleted_cb), GINT_TO_POINTER (FALSE));
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), NULL);
-
- return ce;
-}
-
-EContactListEditor *
-e_addressbook_show_contact_list_editor (EBook *book, ECard *card,
- gboolean is_new_card,
- gboolean editable)
-{
- EContactListEditor *ce;
-
- ce = e_contact_list_editor_new (book, card, is_new_card, editable);
-
- gtk_signal_connect (GTK_OBJECT (ce), "list_added",
- GTK_SIGNAL_FUNC (added_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "list_modified",
- GTK_SIGNAL_FUNC (modified_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "list_deleted",
- GTK_SIGNAL_FUNC (deleted_cb), GINT_TO_POINTER (TRUE));
- gtk_signal_connect (GTK_OBJECT (ce), "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), GINT_TO_POINTER (TRUE));
-
- e_contact_list_editor_show (ce);
-
- return ce;
-}
-
-typedef struct {
- EBook *book;
- GList *list;
- gboolean editable;
-} BookAndList;
-
-static void
-view_cards (EBook *book, GList *list, gboolean editable)
-{
- for (; list; list = list->next) {
- ECard *card = list->data;
- if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, editable);
- else
- e_addressbook_show_contact_editor (book, card, FALSE, editable);
- }
-}
-
-static void
-view_question_clicked (GtkObject *object, int button, BookAndList *bnl)
-{
- GnomeDialog *dialog = GNOME_DIALOG (object);
- switch (button) {
- case 0:
- view_cards (bnl->book, bnl->list, bnl->editable);
- break;
- }
- gnome_dialog_close(dialog);
-}
-
-static void
-view_question_destroyed (GtkObject *object, GList *list)
-{
- gtk_main_quit();
-}
-
-void
-e_addressbook_show_multiple_cards (EBook *book,
- GList *list,
- gboolean editable)
-{
- if (list) {
- int length = g_list_length (list);
- if (length > 5) {
- char *string;
- GtkWidget *dialog;
- BookAndList bnl;
-
- bnl.book = book;
- bnl.list = list;
- bnl.editable = editable;
-
- dialog = gnome_dialog_new (_("Display Cards?"),
- _("Display Cards"),
- GNOME_STOCK_BUTTON_CANCEL,
- NULL);
-
- string = g_strdup_printf (_("Opening %d cards will open %d new windows as well.\n"
- "Do you really want to display all of these cards?"), length, length);
- gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox), gtk_label_new (string), FALSE, FALSE, 0);
- g_free (string);
-
- gtk_signal_connect (GTK_OBJECT (dialog), "destroy",
- GTK_SIGNAL_FUNC (view_question_destroyed), &bnl);
- gtk_signal_connect (GTK_OBJECT (dialog), "clicked",
- GTK_SIGNAL_FUNC (view_question_clicked), &bnl);
-
- gtk_widget_show_all (dialog);
-
- gtk_main();
- } else {
- view_cards (book, list, editable);
- }
- }
-}
-
-
-
-typedef struct CardCopyProcess_ CardCopyProcess;
-
-typedef void (*CardCopyDone) (CardCopyProcess *process);
-
-struct CardCopyProcess_ {
- int count;
- GList *cards;
- EBook *source;
- EBook *destination;
- CardCopyDone done_cb;
-};
-
-static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
- }
-}
-
-static void
-do_delete (gpointer data, gpointer user_data)
-{
- EBook *book = user_data;
- ECard *card = data;
-
- e_book_remove_card(book, card, card_deleted_cb, NULL);
-}
-
-static void
-delete_cards (CardCopyProcess *process)
-{
- g_list_foreach (process->cards,
- do_delete,
- process->source);
-}
-
-static void
-process_unref (CardCopyProcess *process)
-{
- process->count --;
- if (process->count == 0) {
- if (process->done_cb) {
- process->done_cb (process);
- }
- e_free_object_list(process->cards);
- gtk_object_unref (GTK_OBJECT (process->source));
- gtk_object_unref (GTK_OBJECT (process->destination));
- g_free (process);
- }
-}
-
-static void
-card_added_cb (EBook* book, EBookStatus status, const char *id, gpointer user_data)
-{
- CardCopyProcess *process = user_data;
-
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error adding card"), status);
- } else {
- process_unref (process);
- }
-}
-
-static void
-do_copy (gpointer data, gpointer user_data)
-{
- EBook *book;
- ECard *card;
- CardCopyProcess *process;
-
- process = user_data;
- card = data;
-
- book = process->destination;
-
- process->count ++;
- e_book_add_card(book, card, card_added_cb, process);
-}
-
-static void
-got_book_cb (EBook *book, gpointer closure)
-{
- CardCopyProcess *process;
- process = closure;
- if (book) {
- process->destination = book;
- gtk_object_ref (GTK_OBJECT (book));
- g_list_foreach (process->cards,
- do_copy,
- process);
- }
- process_unref (process);
-}
-
-extern EvolutionShellClient *global_shell_client;
-
-void
-e_addressbook_transfer_cards (EBook *source, GList *cards /* adopted */, gboolean delete_from_source, GtkWindow *parent_window)
-{
- const char *allowed_types[] = { "contacts/*", NULL };
- GNOME_Evolution_Folder *folder;
- static char *last_uri = NULL;
- CardCopyProcess *process;
- char *desc;
-
- if (cards == NULL)
- return;
-
- if (last_uri == NULL)
- last_uri = g_strdup ("");
-
- if (cards->next == NULL) {
- if (delete_from_source)
- desc = _("Move card to");
- else
- desc = _("Copy card to");
- } else {
- if (delete_from_source)
- desc = _("Move cards to");
- else
- desc = _("Copy cards to");
- }
-
- evolution_shell_client_user_select_folder (global_shell_client,
- parent_window,
- desc, last_uri, allowed_types,
- &folder);
- if (!folder)
- return;
-
- if (strcmp (last_uri, folder->evolutionUri) != 0) {
- g_free (last_uri);
- last_uri = g_strdup (folder->evolutionUri);
- }
-
- process = g_new (CardCopyProcess, 1);
- process->count = 1;
- process->source = source;
- gtk_object_ref (GTK_OBJECT (source));
- process->cards = cards;
- process->destination = NULL;
-
- if (delete_from_source)
- process->done_cb = delete_cards;
- else
- process->done_cb = NULL;
-
- e_book_use_address_book_by_uri (folder->physicalUri, got_book_cb, process);
-
- CORBA_free (folder);
-}
diff --git a/addressbook/gui/widgets/e-addressbook-util.h b/addressbook/gui/widgets/e-addressbook-util.h
deleted file mode 100644
index f0681cea4d..0000000000
--- a/addressbook/gui/widgets/e-addressbook-util.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-addressbook-util.h
- * Copyright (C) 2001 Ximian, Inc.
- * Author: Chris Toshok <toshok@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_ADDRESSBOOK_UTIL_H__
-#define __E_ADDRESSBOOK_UTIL_H__
-
-#include "addressbook/backend/ebook/e-book.h"
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/gui/contact-list-editor/e-contact-list-editor.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-void e_addressbook_error_dialog (const gchar *msg,
- EBookStatus status);
-gint e_addressbook_prompt_save_dialog (GtkWindow *parent);
-EContactEditor *e_addressbook_show_contact_editor (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable);
-EContactListEditor *e_addressbook_show_contact_list_editor (EBook *book,
- ECard *card,
- gboolean is_new_card,
- gboolean editable);
-void e_addressbook_show_multiple_cards (EBook *book,
- GList *list,
- gboolean editable);
-void e_addressbook_transfer_cards (EBook *source,
- GList *cards, /* adopted */
- gboolean delete_from_source,
- GtkWindow *parent_window);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* __E_ADDRESSBOOK_UTIL_H__ */
diff --git a/addressbook/gui/widgets/e-addressbook-view.c b/addressbook/gui/widgets/e-addressbook-view.c
index f9669a20ac..38d7196217 100644
--- a/addressbook/gui/widgets/e-addressbook-view.c
+++ b/addressbook/gui/widgets/e-addressbook-view.c
@@ -1,1977 +1,1695 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-table-field-chooser.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>
+ * 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>
+#endif
-#include <gtk/gtkinvisible.h>
-
-#include <libgnome/gnome-paper.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnome/gnome-util.h>
-#include <gal/e-table/e-table-scrolled.h>
-#include <gal/e-table/e-table-model.h>
-#include <gal/widgets/e-scroll-frame.h>
-#include <gal/widgets/e-popup-menu.h>
-#include <gal/widgets/e-gui-utils.h>
-#include <gal/widgets/e-unicode.h>
-#include <gal/menus/gal-view-factory-etable.h>
-#include <gal/menus/gal-view-etable.h>
-#include <gal/util/e-unicode-i18n.h>
-#include <gal/util/e-xml-utils.h>
-#include <gal/unicode/gunicode.h>
-#include <libgnomeui/gnome-dialog-util.h>
-#include <libgnomeui/gnome-stock.h>
-
-#include <libgnomeprint/gnome-print.h>
-#include <libgnomeprint/gnome-print-dialog.h>
-#include <libgnomeprint/gnome-print-master.h>
-#include <libgnomeprint/gnome-print-master-preview.h>
+#include <ctype.h>
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include "e-addressbook-view.h"
+
+#include "e-util/e-util.h"
+#include "shell/e-shell-sidebar.h"
#include "addressbook/printing/e-contact-print.h"
-#include "addressbook/printing/e-contact-print-envelope.h"
+#include "ea-addressbook.h"
-#include "gal-view-factory-minicard.h"
#include "gal-view-minicard.h"
-#include "e-addressbook-view.h"
#include "e-addressbook-model.h"
-#include "e-addressbook-util.h"
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
#include "e-addressbook-table-adapter.h"
-#include "e-addressbook-reflow-adapter.h"
-#include "e-minicard-view-widget.h"
-#include "e-contact-save-as.h"
-#include "e-card-merging.h"
+#include "eab-contact-merging.h"
-#include "e-contact-editor.h"
-#include <gdk/gdkkeysyms.h>
-#include <ctype.h>
+#define E_ADDRESSBOOK_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewPrivate))
-#include <gnome-xml/tree.h>
-#include <gnome-xml/parser.h>
+#define d(x)
-#define SHOW_ALL_SEARCH "(contains \"x-evolution-any-field\" \"\")"
+static void status_message (EAddressbookView *view,
+ const gchar *status, gint percent);
+static void search_result (EAddressbookView *view,
+ const GError *error);
+static void folder_bar_message (EAddressbookView *view,
+ const gchar *status);
+static void stop_state_changed (GObject *object,
+ EAddressbookView *view);
+static void command_state_change (EAddressbookView *view);
-#define d(x)
+struct _EAddressbookViewPrivate {
+ gpointer shell_view; /* weak pointer */
+
+ EAddressbookModel *model;
+ EActivity *activity;
+
+ ESource *source;
+
+ GObject *object;
+
+ GalViewInstance *view_instance;
+
+ /* stored search setup for this view */
+ gint filter_id;
+ gchar *search_text;
+ gint search_id;
+ EFilterRule *advanced_search;
+
+ GtkTargetList *copy_target_list;
+ GtkTargetList *paste_target_list;
+};
-static void e_addressbook_view_init (EAddressbookView *card);
-static void e_addressbook_view_class_init (EAddressbookViewClass *klass);
-static void e_addressbook_view_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_addressbook_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_addressbook_view_destroy (GtkObject *object);
-static void change_view_type (EAddressbookView *view, EAddressbookViewType view_type);
-
-static void status_message (GtkObject *object, const gchar *status, EAddressbookView *eav);
-static void search_result (GtkObject *object, EBookViewStatus status, EAddressbookView *eav);
-static void folder_bar_message (GtkObject *object, const gchar *status, EAddressbookView *eav);
-static void stop_state_changed (GtkObject *object, EAddressbookView *eav);
-static void writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav);
-static void backend_died (GtkObject *object, EAddressbookView *eav);
-static void command_state_change (EAddressbookView *eav);
-static void alphabet_state_change (EAddressbookView *eav, gunichar letter);
-
-static void selection_clear_event (GtkWidget *invisible, GdkEventSelection *event,
- EAddressbookView *view);
-static void selection_received (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint time, EAddressbookView *view);
-static void selection_get (GtkWidget *invisible, GtkSelectionData *selection_data,
- guint info, guint time_stamp, EAddressbookView *view);
-static void invisible_destroyed (GtkWidget *invisible, EAddressbookView *view);
-
-static GtkTableClass *parent_class = NULL;
-
-/* The arguments we take */
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_TYPE,
+ PROP_0,
+ PROP_COPY_TARGET_LIST,
+ PROP_MODEL,
+ PROP_PASTE_TARGET_LIST,
+ PROP_SHELL_VIEW,
+ PROP_SOURCE
};
enum {
- STATUS_MESSAGE,
- SEARCH_RESULT,
- FOLDER_BAR_MESSAGE,
+ OPEN_CONTACT,
+ POPUP_EVENT,
COMMAND_STATE_CHANGE,
- ALPHABET_STATE_CHANGE,
+ SELECTION_CHANGE,
LAST_SIGNAL
};
-enum DndTargetType {
- DND_TARGET_TYPE_VCARD,
+enum {
+ DND_TARGET_TYPE_SOURCE_VCARD,
+ DND_TARGET_TYPE_VCARD
};
-#define VCARD_TYPE "text/x-vcard"
+
static GtkTargetEntry drag_types[] = {
- { VCARD_TYPE, 0, DND_TARGET_TYPE_VCARD },
+ { (gchar *) "text/x-source-vcard", 0, DND_TARGET_TYPE_SOURCE_VCARD },
+ { (gchar *) "text/x-vcard", 0, DND_TARGET_TYPE_VCARD }
};
-static const int num_drag_types = sizeof (drag_types) / sizeof (drag_types[0]);
-static guint e_addressbook_view_signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL];
-static GdkAtom clipboard_atom = GDK_NONE;
+/* Forward Declarations */
+static void e_addressbook_view_selectable_init
+ (ESelectableInterface *interface);
-static GalViewCollection *collection = NULL;
+G_DEFINE_TYPE_WITH_CODE (
+ EAddressbookView,
+ e_addressbook_view,
+ GTK_TYPE_SCROLLED_WINDOW,
+ G_IMPLEMENT_INTERFACE (
+ E_TYPE_SELECTABLE,
+ e_addressbook_view_selectable_init))
-GtkType
-e_addressbook_view_get_type (void)
+static void
+addressbook_view_emit_open_contact (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact)
{
- static GtkType type = 0;
-
- if (!type) {
- static const GtkTypeInfo info =
- {
- "EAddressbookView",
- sizeof (EAddressbookView),
- sizeof (EAddressbookViewClass),
- (GtkClassInitFunc) e_addressbook_view_class_init,
- (GtkObjectInitFunc) e_addressbook_view_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (gtk_table_get_type (), &info);
- }
-
- return type;
+ g_signal_emit (view, signals[OPEN_CONTACT], 0, contact, is_new_contact);
}
static void
-e_addressbook_view_class_init (EAddressbookViewClass *klass)
+addressbook_view_emit_popup_event (EAddressbookView *view,
+ GdkEvent *event)
{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
-
- parent_class = gtk_type_class (gtk_table_get_type ());
-
- object_class->set_arg = e_addressbook_view_set_arg;
- object_class->get_arg = e_addressbook_view_get_arg;
- object_class->destroy = e_addressbook_view_destroy;
-
- gtk_object_add_arg_type ("EAddressbookView::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EAddressbookView::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EAddressbookView::type", GTK_TYPE_ENUM,
- GTK_ARG_READWRITE, ARG_TYPE);
-
- e_addressbook_view_signals [STATUS_MESSAGE] =
- gtk_signal_new ("status_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, status_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_view_signals [SEARCH_RESULT] =
- gtk_signal_new ("search_result",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, search_result),
- gtk_marshal_NONE__ENUM,
- GTK_TYPE_NONE, 1, GTK_TYPE_ENUM);
-
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE] =
- gtk_signal_new ("folder_bar_message",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, folder_bar_message),
- gtk_marshal_NONE__POINTER,
- GTK_TYPE_NONE, 1, GTK_TYPE_POINTER);
-
- e_addressbook_view_signals [COMMAND_STATE_CHANGE] =
- gtk_signal_new ("command_state_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, command_state_change),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- e_addressbook_view_signals [ALPHABET_STATE_CHANGE] =
- gtk_signal_new ("alphabet_state_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EAddressbookViewClass, alphabet_state_change),
- gtk_marshal_NONE__UINT,
- GTK_TYPE_NONE, 1, GTK_TYPE_UINT);
-
- gtk_object_class_add_signals (object_class, e_addressbook_view_signals, LAST_SIGNAL);
-
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
+ /* Grab focus so that EFocusTracker asks us to update the
+ * selection-related actions before showing the popup menu.
+ * Apparently ETable doesn't automatically grab focus on
+ * right-clicks (is that a bug?). */
+ gtk_widget_grab_focus (GTK_WIDGET (view));
+
+ g_signal_emit (view, signals[POPUP_EVENT], 0, event);
}
static void
-e_addressbook_view_init (EAddressbookView *eav)
+addressbook_view_emit_selection_change (EAddressbookView *view)
{
- eav->view_type = E_ADDRESSBOOK_VIEW_NONE;
-
- eav->model = e_addressbook_model_new ();
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "status_message",
- GTK_SIGNAL_FUNC (status_message),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "search_result",
- GTK_SIGNAL_FUNC (search_result),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "folder_bar_message",
- GTK_SIGNAL_FUNC (folder_bar_message),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "stop_state_changed",
- GTK_SIGNAL_FUNC (stop_state_changed),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "writable_status",
- GTK_SIGNAL_FUNC (writable_status),
- eav);
-
- gtk_signal_connect (GTK_OBJECT(eav->model),
- "backend_died",
- GTK_SIGNAL_FUNC (backend_died),
- eav);
-
- eav->editable = FALSE;
- eav->book = NULL;
- eav->query = g_strdup (SHOW_ALL_SEARCH);
-
- eav->object = NULL;
- eav->widget = NULL;
-
- eav->view_instance = NULL;
- eav->view_menus = NULL;
- eav->uic = NULL;
- eav->current_alphabet_widget = NULL;
-
- eav->invisible = gtk_invisible_new ();
-
- gtk_selection_add_target (eav->invisible,
- clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- 0);
-
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_get",
- GTK_SIGNAL_FUNC (selection_get),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_clear_event",
- GTK_SIGNAL_FUNC (selection_clear_event),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "selection_received",
- GTK_SIGNAL_FUNC (selection_received),
- eav);
- gtk_signal_connect (GTK_OBJECT(eav->invisible), "destroy",
- GTK_SIGNAL_FUNC (invisible_destroyed),
- eav);
+ g_signal_emit (view, signals[SELECTION_CHANGE], 0);
}
static void
-e_addressbook_view_destroy (GtkObject *object)
+addressbook_view_open_contact (EAddressbookView *view,
+ EContact *contact)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
-
- if (eav->model) {
- gtk_object_unref(GTK_OBJECT(eav->model));
- eav->model = NULL;
- }
+ addressbook_view_emit_open_contact (view, contact, FALSE);
+}
- if (eav->book) {
- gtk_object_unref(GTK_OBJECT(eav->book));
- eav->book = NULL;
- }
+static void
+addressbook_view_create_contact (EAddressbookView *view)
+{
+ EContact *contact;
- g_free(eav->query);
- eav->query = NULL;
+ contact = e_contact_new ();
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
+}
- eav->uic = NULL;
+static void
+addressbook_view_create_contact_list (EAddressbookView *view)
+{
+ EContact *contact;
- if (eav->view_instance) {
- gtk_object_unref (GTK_OBJECT (eav->view_instance));
- eav->view_instance = NULL;
- }
+ contact = e_contact_new ();
+ e_contact_set (contact, E_CONTACT_IS_LIST, GINT_TO_POINTER (TRUE));
+ addressbook_view_emit_open_contact (view, contact, TRUE);
+ g_object_unref (contact);
+}
- if (eav->view_menus) {
- gtk_object_unref (GTK_OBJECT (eav->view_menus));
- eav->view_menus = NULL;
- }
+static void
+table_double_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
+{
+ EAddressbookModel *model;
+ EContact *contact;
- if (eav->clipboard_cards) {
- g_list_foreach (eav->clipboard_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (eav->clipboard_cards);
- eav->clipboard_cards = NULL;
- }
-
- if (eav->invisible) {
- gtk_widget_destroy (eav->invisible);
- eav->invisible = NULL;
- }
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(object);
+ model = e_addressbook_view_get_model (view);
+ contact = e_addressbook_model_get_contact (model, row);
+ addressbook_view_emit_open_contact (view, contact, FALSE);
+ g_object_unref (contact);
}
-GtkWidget*
-e_addressbook_view_new (void)
+static gint
+table_right_click (ETable *table,
+ gint row,
+ gint col,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_addressbook_view_get_type ()));
- return widget;
+ addressbook_view_emit_popup_event (view, event);
+
+ return TRUE;
}
-static void
-writable_status (GtkObject *object, gboolean writable, EAddressbookView *eav)
+static gint
+table_white_space_event (ETable *table,
+ GdkEvent *event,
+ EAddressbookView *view)
{
- eav->editable = writable;
- command_state_change (eav);
+ guint event_button = 0;
+
+ gdk_event_get_button (event, &event_button);
+
+ if (event->type == GDK_BUTTON_PRESS && event_button == 3) {
+ addressbook_view_emit_popup_event (view, event);
+ return TRUE;
+ }
+
+ return FALSE;
}
static void
-init_collection (void)
+table_drag_data_get (ETable *table,
+ gint row,
+ gint col,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer user_data)
{
- GalViewFactory *factory;
- ETableSpecification *spec;
- char *galview;
+ EAddressbookView *view = user_data;
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ GSList *contact_list;
+ GdkAtom target;
+ gchar *value;
- if (collection == NULL) {
- collection = gal_view_collection_new();
+ if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER (view->priv->object))
+ return;
- gal_view_collection_set_title (collection, _("Addressbook"));
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
- galview = gnome_util_prepend_user_home("/evolution/views/addressbook/");
- gal_view_collection_set_storage_directories
- (collection,
- EVOLUTION_DATADIR "/evolution/views/addressbook/",
- galview);
- g_free(galview);
+ contact_list = e_addressbook_view_get_selected (view);
+ target = gtk_selection_data_get_target (selection_data);
- spec = e_table_specification_new();
- e_table_specification_load_from_file (spec, EVOLUTION_ETSPECDIR "/e-addressbook-view.etspec");
+ switch (info) {
+ case DND_TARGET_TYPE_VCARD:
+ value = eab_contact_list_to_string (contact_list);
- factory = gal_view_factory_etable_new (spec);
- gtk_object_unref (GTK_OBJECT (spec));
- gal_view_collection_add_factory (collection, factory);
- gtk_object_unref (GTK_OBJECT (factory));
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
- factory = gal_view_factory_minicard_new ();
- gal_view_collection_add_factory (collection, factory);
- gtk_object_unref (GTK_OBJECT (factory));
+ g_free (value);
+ break;
- gal_view_collection_load(collection);
- }
-}
+ case DND_TARGET_TYPE_SOURCE_VCARD:
+ value = eab_book_and_contact_list_to_string (
+ book_client, contact_list);
-static void
-display_view(GalViewInstance *instance,
- GalView *view,
- gpointer data)
-{
- EAddressbookView *address_view = data;
- if (GAL_IS_VIEW_ETABLE(view)) {
- change_view_type (address_view, E_ADDRESSBOOK_VIEW_TABLE);
- gal_view_etable_attach_table (GAL_VIEW_ETABLE(view), e_table_scrolled_get_table(E_TABLE_SCROLLED(address_view->widget)));
- } else if (GAL_IS_VIEW_MINICARD(view)) {
- change_view_type (address_view, E_ADDRESSBOOK_VIEW_MINICARD);
- gal_view_minicard_attach (GAL_VIEW_MINICARD(view), E_MINICARD_VIEW_WIDGET (address_view->object));
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+
+ g_free (value);
+ break;
}
- address_view->current_view = view;
+
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
static void
-setup_menus (EAddressbookView *view)
+addressbook_view_create_table_view (EAddressbookView *view,
+ GalViewEtable *gal_view)
{
- if (view->book && view->view_instance == NULL) {
- init_collection ();
- view->view_instance = gal_view_instance_new (collection, e_book_get_uri (view->book));
- }
+ ETableModel *adapter;
+ ETableExtras *extras;
+ ETableSpecification *specification;
+ ECell *cell;
+ GtkWidget *widget;
+ gchar *etspecfile;
+ GError *local_error = NULL;
- if (view->view_instance && view->uic) {
- view->view_menus = gal_view_menus_new(view->view_instance);
- gal_view_menus_apply(view->view_menus, view->uic, NULL);
+ adapter = e_addressbook_table_adapter_new (view->priv->model);
- display_view (view->view_instance, gal_view_instance_get_current_view (view->view_instance), view);
+ extras = e_table_extras_new ();
- gtk_signal_connect(GTK_OBJECT(view->view_instance), "display_view",
- display_view, view);
+ /* Set proper format component for a default 'date' cell renderer. */
+ cell = e_table_extras_get_cell (extras, "date");
+ e_cell_date_set_format_component (E_CELL_DATE (cell), "addressbook");
+
+ etspecfile = g_build_filename (
+ EVOLUTION_ETSPECDIR, "e-addressbook-view.etspec", NULL);
+ specification = e_table_specification_new (etspecfile, &local_error);
+
+ /* Failure here is fatal. */
+ if (local_error != NULL) {
+ g_error ("%s: %s", etspecfile, local_error->message);
+ g_assert_not_reached ();
}
-}
-static void
-e_addressbook_view_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ /* Here we create the table. We give it the three pieces of
+ * the table we've created, the header, the model, and the
+ * initial layout. It does the rest. */
+ widget = e_table_new (adapter, extras, specification);
+ gtk_container_add (GTK_CONTAINER (view), widget);
- switch (arg_id){
- case ARG_BOOK:
- if (eav->book) {
- gtk_object_unref(GTK_OBJECT(eav->book));
- }
- if (GTK_VALUE_OBJECT(*arg)) {
- eav->book = E_BOOK(GTK_VALUE_OBJECT(*arg));
- gtk_object_ref(GTK_OBJECT(eav->book));
- }
- else
- eav->book = NULL;
+ g_object_unref (specification);
+ g_free (etspecfile);
- if (eav->view_instance) {
- gtk_object_unref (GTK_OBJECT (eav->view_instance));
- eav->view_instance = NULL;
- }
+ view->priv->object = G_OBJECT (adapter);
- gtk_object_set(GTK_OBJECT(eav->model),
- "book", eav->book,
- NULL);
+ g_signal_connect (
+ widget, "double_click",
+ G_CALLBACK (table_double_click), view);
+ g_signal_connect (
+ widget, "right_click",
+ G_CALLBACK (table_right_click), view);
+ g_signal_connect (
+ widget, "white_space_event",
+ G_CALLBACK (table_white_space_event), view);
+ g_signal_connect_swapped (
+ widget, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
- setup_menus (eav);
+ e_table_drag_source_set (
+ E_TABLE (widget), GDK_BUTTON1_MASK,
+ drag_types, G_N_ELEMENTS (drag_types),
+ GDK_ACTION_MOVE | GDK_ACTION_COPY);
- break;
- case ARG_QUERY:
-#if 0 /* This code will mess up ldap a bit. We need to think about the ramifications of this more. */
- if ((GTK_VALUE_STRING (*arg) == NULL && !strcmp (eav->query, SHOW_ALL_SEARCH)) ||
- (GTK_VALUE_STRING (*arg) != NULL && !strcmp (eav->query, GTK_VALUE_STRING (*arg))))
- break;
-#endif
- g_free(eav->query);
- eav->query = g_strdup(GTK_VALUE_STRING(*arg));
- if (!eav->query)
- eav->query = g_strdup (SHOW_ALL_SEARCH);
- gtk_object_set(GTK_OBJECT(eav->model),
- "query", eav->query,
- NULL);
- if (eav->current_alphabet_widget != NULL) {
- GtkWidget *current = eav->current_alphabet_widget;
-
- eav->current_alphabet_widget = NULL;
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current), FALSE);
- }
- break;
- case ARG_TYPE:
- change_view_type(eav, GTK_VALUE_ENUM(*arg));
- break;
- default:
- break;
- }
+ g_signal_connect (
+ E_TABLE (widget), "table_drag_data_get",
+ G_CALLBACK (table_drag_data_get), view);
+
+ gtk_widget_show (widget);
+
+ gal_view_etable_attach_table (gal_view, E_TABLE (widget));
}
static void
-e_addressbook_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+addressbook_view_create_minicard_view (EAddressbookView *view,
+ GalViewMinicard *gal_view)
{
- EAddressbookView *eav = E_ADDRESSBOOK_VIEW(object);
+ GtkWidget *minicard_view;
+ EAddressbookReflowAdapter *adapter;
- switch (arg_id) {
- case ARG_BOOK:
- if (eav->book)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(eav->book);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
- break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = eav->query;
- break;
- case ARG_TYPE:
- GTK_VALUE_ENUM (*arg) = eav->view_type;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
+ adapter = E_ADDRESSBOOK_REFLOW_ADAPTER (
+ e_addressbook_reflow_adapter_new (view->priv->model));
+ minicard_view = e_minicard_view_widget_new (adapter);
-static ESelectionModel*
-get_selection_model (EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD)
- return e_minicard_view_widget_get_selection_model (E_MINICARD_VIEW_WIDGET(view->object));
- else
- return e_table_get_selection_model (e_table_scrolled_get_table (E_TABLE_SCROLLED(view->widget)));
-}
+ g_signal_connect_swapped (
+ adapter, "open-contact",
+ G_CALLBACK (addressbook_view_open_contact), view);
-/* Popup menu stuff */
-typedef struct {
- EAddressbookView *view;
- EPopupMenu *submenu;
- gpointer closure;
-} CardAndBook;
+ g_signal_connect_swapped (
+ minicard_view, "create-contact",
+ G_CALLBACK (addressbook_view_create_contact), view);
-static ESelectionModel*
-card_and_book_get_selection_model (CardAndBook *card_and_book)
-{
- return get_selection_model (card_and_book->view);
+ g_signal_connect_swapped (
+ minicard_view, "create-contact-list",
+ G_CALLBACK (addressbook_view_create_contact_list), view);
+
+ g_signal_connect_swapped (
+ minicard_view, "selection_change",
+ G_CALLBACK (addressbook_view_emit_selection_change), view);
+
+ g_signal_connect_swapped (
+ minicard_view, "right_click",
+ G_CALLBACK (addressbook_view_emit_popup_event), view);
+
+ view->priv->object = G_OBJECT (minicard_view);
+
+ gtk_container_add (GTK_CONTAINER (view), minicard_view);
+ gtk_widget_show (minicard_view);
+
+ e_reflow_model_changed (E_REFLOW_MODEL (adapter));
+
+ gal_view_minicard_attach (gal_view, view);
}
static void
-card_and_book_free (CardAndBook *card_and_book)
+addressbook_view_display_view_cb (GalViewInstance *view_instance,
+ GalView *gal_view,
+ EAddressbookView *view)
{
- EAddressbookView *view = card_and_book->view;
- ESelectionModel *selection;
+ EShellView *shell_view;
+ GtkWidget *child;
- if (card_and_book->submenu)
- gal_view_instance_free_popup_menu (view->view_instance,
- card_and_book->submenu);
+ child = gtk_bin_get_child (GTK_BIN (view));
+ if (child != NULL)
+ gtk_container_remove (GTK_CONTAINER (view), child);
+ view->priv->object = NULL;
- selection = card_and_book_get_selection_model (card_and_book);
- if (selection)
- e_selection_model_right_click_up(selection);
+ if (GAL_IS_VIEW_ETABLE (gal_view))
+ addressbook_view_create_table_view (
+ view, GAL_VIEW_ETABLE (gal_view));
+ else if (GAL_IS_VIEW_MINICARD (gal_view))
+ addressbook_view_create_minicard_view (
+ view, GAL_VIEW_MINICARD (gal_view));
- gtk_object_unref(GTK_OBJECT(view));
+ shell_view = e_addressbook_view_get_shell_view (view);
+ e_shell_view_set_view_instance (shell_view, view_instance);
+
+ command_state_change (view);
}
static void
-get_card_list_1(gint model_row,
- gpointer closure)
+addressbook_view_set_shell_view (EAddressbookView *view,
+ EShellView *shell_view)
{
- CardAndBook *card_and_book;
- GList **list;
- EAddressbookView *view;
- ECard *card;
+ g_return_if_fail (view->priv->shell_view == NULL);
- card_and_book = closure;
- list = card_and_book->closure;
- view = card_and_book->view;
+ view->priv->shell_view = shell_view;
- card = e_addressbook_model_get_card(view->model, model_row);
- *list = g_list_prepend(*list, card);
+ g_object_add_weak_pointer (
+ G_OBJECT (shell_view),
+ &view->priv->shell_view);
}
-static GList *
-get_card_list (CardAndBook *card_and_book)
+static void
+addressbook_view_set_source (EAddressbookView *view,
+ ESource *source)
{
- GList *list = NULL;
- ESelectionModel *selection;
+ g_return_if_fail (view->priv->source == NULL);
- selection = card_and_book_get_selection_model (card_and_book);
+ view->priv->source = g_object_ref (source);
+}
+
+static void
+addressbook_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_SHELL_VIEW:
+ addressbook_view_set_shell_view (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
- if (selection) {
- card_and_book->closure = &list;
- e_selection_model_foreach (selection, get_card_list_1, card_and_book);
+ case PROP_SOURCE:
+ addressbook_view_set_source (
+ E_ADDRESSBOOK_VIEW (object),
+ g_value_get_object (value));
+ return;
}
- return list;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
static void
-has_email_address_1(gint model_row,
- gpointer closure)
-{
- CardAndBook *card_and_book;
- gboolean *has_email;
- EAddressbookView *view;
- const ECard *card;
- EList *email;
+addressbook_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_COPY_TARGET_LIST:
+ g_value_set_boxed (
+ value,
+ e_addressbook_view_get_copy_target_list (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- card_and_book = closure;
- has_email = card_and_book->closure;
- view = card_and_book->view;
+ case PROP_MODEL:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_model (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- if (*has_email)
- return;
+ case PROP_PASTE_TARGET_LIST:
+ g_value_set_boxed (
+ value,
+ e_addressbook_view_get_paste_target_list (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- card = e_addressbook_model_peek_card(view->model, model_row);
+ case PROP_SHELL_VIEW:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_shell_view (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
- gtk_object_get (GTK_OBJECT (card),
- "email", &email,
- NULL);
+ case PROP_SOURCE:
+ g_value_set_object (
+ value,
+ e_addressbook_view_get_source (
+ E_ADDRESSBOOK_VIEW (object)));
+ return;
+ }
- if (e_list_length (email) > 0)
- *has_email = TRUE;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
}
-static gboolean
-get_has_email_address (CardAndBook *card_and_book)
+static void
+addressbook_view_dispose (GObject *object)
{
- ESelectionModel *selection;
- gboolean has_email = FALSE;
+ EAddressbookViewPrivate *priv;
- selection = card_and_book_get_selection_model (card_and_book);
+ priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (object);
- if (selection) {
- card_and_book->closure = &has_email;
- e_selection_model_foreach (selection, has_email_address_1, card_and_book);
+ if (priv->shell_view != NULL) {
+ g_object_remove_weak_pointer (
+ G_OBJECT (priv->shell_view),
+ &priv->shell_view);
+ priv->shell_view = NULL;
}
- return has_email;
-}
+ if (priv->model != NULL) {
+ g_signal_handlers_disconnect_matched (
+ priv->model, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, object);
+ g_object_unref (priv->model);
+ priv->model = NULL;
+ }
-static void
-save_as (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- e_contact_list_save_as(_("Save as VCard"), cards, NULL);
- e_free_object_list(cards);
+ if (priv->activity != NULL) {
+ /* XXX Activity is not cancellable. */
+ e_activity_set_state (priv->activity, E_ACTIVITY_COMPLETED);
+ g_object_unref (priv->activity);
+ priv->activity = NULL;
}
-}
-static void
-send_as (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- e_card_list_send(cards, E_CARD_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(cards);
+ if (priv->source != NULL) {
+ g_object_unref (priv->source);
+ priv->source = NULL;
}
-}
-static void
-send_to (GtkWidget *widget, CardAndBook *card_and_book)
+ if (priv->view_instance != NULL) {
+ g_object_unref (priv->view_instance);
+ priv->view_instance = NULL;
+ }
-{
- GList *cards = get_card_list (card_and_book);
+ priv->filter_id = 0;
+ priv->search_id = 0;
- if (cards) {
- e_card_list_send(cards, E_CARD_DISPOSITION_AS_TO);
- e_free_object_list(cards);
+ if (priv->search_text) {
+ g_free (priv->search_text);
+ priv->search_text = NULL;
}
-}
-static void
-print (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- if (cards->next)
- gtk_widget_show(e_contact_print_card_list_dialog_new(cards));
- else
- gtk_widget_show(e_contact_print_card_dialog_new(cards->data));
- e_free_object_list(cards);
+ if (priv->advanced_search) {
+ g_object_unref (priv->advanced_search);
+ priv->advanced_search = NULL;
}
-}
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
-static void
-print_envelope (GtkWidget *widget, CardAndBook *card_and_book)
-{
- GList *cards = get_card_list (card_and_book);
- if (cards) {
- gtk_widget_show(e_contact_list_print_envelope_dialog_new(card_and_book->card));
- e_free_object_list(cards);
+ if (priv->copy_target_list != NULL) {
+ gtk_target_list_unref (priv->copy_target_list);
+ priv->copy_target_list = NULL;
}
-}
-#endif
-static void
-copy (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_copy (card_and_book->view);
-}
+ if (priv->paste_target_list != NULL) {
+ gtk_target_list_unref (priv->paste_target_list);
+ priv->paste_target_list = NULL;
+ }
-static void
-paste (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_paste (card_and_book->view);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_addressbook_view_parent_class)->dispose (object);
}
static void
-cut (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_constructed (GObject *object)
{
- e_addressbook_view_cut (card_and_book->view);
-}
+ EAddressbookView *view = E_ADDRESSBOOK_VIEW (object);
+ GalViewInstance *view_instance;
+ EShell *shell;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+ EClientCache *client_cache;
+ ESource *source;
+ const gchar *uid;
-static void
-delete (GtkWidget *widget, CardAndBook *card_and_book)
-{
- if (e_contact_editor_confirm_delete(GTK_WINDOW(gtk_widget_get_toplevel(card_and_book->view->widget)))) {
- EBook *book;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+ shell = e_shell_backend_get_shell (shell_backend);
+ client_cache = e_shell_get_client_cache (shell);
- GList *list = get_card_list(card_and_book);
- GList *iterator;
+ source = e_addressbook_view_get_source (view);
+ uid = e_source_get_uid (source);
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
+ view->priv->model = e_addressbook_model_new (client_cache);
- for (iterator = list; iterator; iterator = iterator->next) {
- ECard *card = iterator->data;
- /* Remove the card. */
- e_book_remove_card (book,
- card,
- NULL,
- NULL);
- }
- e_free_object_list(list);
- }
-}
+ view_instance = e_shell_view_new_view_instance (shell_view, uid);
+ g_signal_connect (
+ view_instance, "display-view",
+ G_CALLBACK (addressbook_view_display_view_cb), view);
+ view->priv->view_instance = view_instance;
-static void
-copy_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_copy_to_folder (card_and_book->view);
-}
+ /* Do not call gal_view_instance_load() here. EBookShellContent
+ * must first obtain a reference to this EAddressbookView so that
+ * e_book_shell_content_get_current_view() returns the correct
+ * view in GalViewInstance::loaded signal handlers. */
-static void
-move_to_folder (GtkWidget *widget, CardAndBook *card_and_book)
-{
- e_addressbook_view_move_to_folder (card_and_book->view);
+ /* Chain up to parent's constructed() method. */
+ G_OBJECT_CLASS (e_addressbook_view_parent_class)->constructed (object);
}
static void
-free_popup_info (GtkWidget *w, CardAndBook *card_and_book)
+addressbook_view_update_actions (ESelectable *selectable,
+ EFocusTracker *focus_tracker,
+ GdkAtom *clipboard_targets,
+ gint n_clipboard_targets)
{
- card_and_book_free (card_and_book);
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ ESelectionModel *selection_model;
+ GtkAction *action;
+ GtkTargetList *target_list;
+ gboolean can_paste = FALSE;
+ gboolean source_is_editable;
+ gboolean sensitive;
+ const gchar *tooltip;
+ gint n_contacts;
+ gint n_selected;
+ gint ii;
+
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ model = e_addressbook_view_get_model (view);
+ selection_model = e_addressbook_view_get_selection_model (view);
+
+ source_is_editable = e_addressbook_model_get_editable (model);
+ n_contacts = (selection_model != NULL) ?
+ e_selection_model_row_count (selection_model) : 0;
+ n_selected = (selection_model != NULL) ?
+ e_selection_model_selected_count (selection_model) : 0;
+
+ target_list = e_selectable_get_paste_target_list (selectable);
+ for (ii = 0; ii < n_clipboard_targets && !can_paste; ii++)
+ can_paste = gtk_target_list_find (
+ target_list, clipboard_targets[ii], NULL);
+
+ action = e_focus_tracker_get_cut_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && (n_selected > 0);
+ tooltip = _("Cut selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_copy_clipboard_action (focus_tracker);
+ sensitive = (n_selected > 0);
+ tooltip = _("Copy selected contacts to the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_paste_clipboard_action (focus_tracker);
+ sensitive = source_is_editable && can_paste;
+ tooltip = _("Paste contacts from the clipboard");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_delete_selection_action (focus_tracker);
+ sensitive = source_is_editable && (n_selected > 0);
+ tooltip = _("Delete selected contacts");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
+
+ action = e_focus_tracker_get_select_all_action (focus_tracker);
+ sensitive = (n_contacts > 0);
+ tooltip = _("Select all visible contacts");
+ gtk_action_set_sensitive (action, sensitive);
+ gtk_action_set_tooltip (action, tooltip);
}
static void
-new_card (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_cut_clipboard (ESelectable *selectable)
{
- EBook *book;
-
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, TRUE);
-}
+ EAddressbookView *view;
-static void
-new_list (GtkWidget *widget, CardAndBook *card_and_book)
-{
- EBook *book;
+ view = E_ADDRESSBOOK_VIEW (selectable);
- gtk_object_get(GTK_OBJECT(card_and_book->view->model),
- "book", &book,
- NULL);
- e_addressbook_show_contact_list_editor (book, e_card_new(""), TRUE, TRUE);
+ e_selectable_copy_clipboard (selectable);
+ e_addressbook_view_delete_selection (view, FALSE);
}
-#if 0
static void
-sources (GtkWidget *widget, CardAndBook *card_and_book)
+addressbook_view_copy_clipboard (ESelectable *selectable)
{
- BonoboControl *control;
- GNOME_Evolution_ShellView shell_view;
- CORBA_Environment ev;
+ EAddressbookView *view;
+ GtkClipboard *clipboard;
+ GSList *contact_list;
+ gchar *string;
- control = gtk_object_get_data (GTK_OBJECT (gcal), "control");
- if (control == NULL)
- return;
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- shell_view = get_shell_view_interface (control);
- if (shell_view == CORBA_OBJECT_NIL)
- return;
+ contact_list = e_addressbook_view_get_selected (view);
- CORBA_exception_init (&ev);
-
- GNOME_Evolution_ShellView_showSettings (shell_view, &ev);
-
- if (BONOBO_EX (&ev))
- g_message ("control_util_show_settings(): Could not show settings");
+ string = eab_contact_list_to_string (contact_list);
+ e_clipboard_set_directory (clipboard, string, -1);
+ g_free (string);
- CORBA_exception_free (&ev);
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
-#endif
-
-#define POPUP_READONLY_MASK 0x1
-#define POPUP_NOSELECTION_MASK 0x2
-#define POPUP_NOEMAIL_MASK 0x4
static void
-do_popup_menu(EAddressbookView *view, GdkEvent *event)
+addressbook_view_paste_clipboard (ESelectable *selectable)
{
- CardAndBook *card_and_book;
- GtkMenu *popup;
- EPopupMenu *submenu = NULL;
- ESelectionModel *selection_model;
- gboolean selection = FALSE;
-
- EPopupMenu menu[] = {
- E_POPUP_ITEM (N_("New Contact..."), GTK_SIGNAL_FUNC(new_card), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("New Contact List..."), GTK_SIGNAL_FUNC(new_list), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
-#if 0
- E_POPUP_ITEM (N_("Go to Folder..."), GTK_SIGNAL_FUNC (goto_folder), 0),
- E_POPUP_ITEM (N_("Import..."), GTK_SIGNAL_FUNC (import), POPUP_READONLY_MASK),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Search for Contacts..."), GTK_SIGNAL_FUNC (search), 0),
- E_POPUP_ITEM (N_("Addressbook Sources..."), GTK_SIGNAL_FUNC (sources), 0),
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Pilot Settings..."), GTK_SIGNAL_FUNC (pilot_settings), 0),
-#endif
- E_POPUP_SEPARATOR,
- E_POPUP_ITEM (N_("Save as VCard"), GTK_SIGNAL_FUNC(save_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Forward Contact"), GTK_SIGNAL_FUNC(send_as), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Send Message to Contact"), GTK_SIGNAL_FUNC(send_to), POPUP_NOSELECTION_MASK | POPUP_NOEMAIL_MASK),
- E_POPUP_ITEM (N_("Print"), GTK_SIGNAL_FUNC(print), POPUP_NOSELECTION_MASK),
-#if 0 /* Envelope printing is disabled for Evolution 1.0. */
- E_POPUP_ITEM (N_("Print Envelope"), GTK_SIGNAL_FUNC(print_envelope), POPUP_NOSELECTION_MASK),
-#endif
- E_POPUP_SEPARATOR,
+ EBookClient *book_client;
+ EAddressbookView *view;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ ESourceRegistry *registry;
+ GtkClipboard *clipboard;
+ GSList *contact_list, *iter;
+ gchar *string;
- E_POPUP_ITEM (N_("Copy to folder..."), GTK_SIGNAL_FUNC(copy_to_folder), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Move to folder..."), GTK_SIGNAL_FUNC(move_to_folder), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
- E_POPUP_ITEM (N_("Cut"), GTK_SIGNAL_FUNC (cut), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Copy"), GTK_SIGNAL_FUNC (copy), POPUP_NOSELECTION_MASK),
- E_POPUP_ITEM (N_("Paste"), GTK_SIGNAL_FUNC (paste), POPUP_READONLY_MASK),
- E_POPUP_ITEM (N_("Delete"), GTK_SIGNAL_FUNC(delete), POPUP_READONLY_MASK | POPUP_NOSELECTION_MASK),
- E_POPUP_SEPARATOR,
+ if (!e_clipboard_wait_is_directory_available (clipboard))
+ return;
-#if 0
- E_POPUP_SUBMENU (N_("Current View"), submenu = gal_view_instance_get_popup_menu (view->view_instance), 0),
-#endif
- E_POPUP_TERMINATOR
- };
+ model = e_addressbook_view_get_model (view);
+ client_cache = e_addressbook_model_get_client_cache (model);
+ book_client = e_addressbook_model_get_client (model);
- card_and_book = g_new(CardAndBook, 1);
- card_and_book->view = view;
- card_and_book->submenu = submenu;
+ string = e_clipboard_wait_for_directory (clipboard);
+ contact_list = eab_contact_list_from_string (string);
+ g_free (string);
- gtk_object_ref(GTK_OBJECT(card_and_book->view));
+ registry = e_client_cache_ref_registry (client_cache);
- selection_model = card_and_book_get_selection_model (card_and_book);
- if (selection_model)
- selection = e_selection_model_selected_count (selection_model) > 0;
+ for (iter = contact_list; iter != NULL; iter = iter->next) {
+ EContact *contact = iter->data;
- popup = e_popup_menu_create (menu,
- 0,
- (e_addressbook_model_editable (view->model) ? 0 : POPUP_READONLY_MASK) +
- (selection ? 0 : POPUP_NOSELECTION_MASK) +
- (get_has_email_address (card_and_book) ? 0 : POPUP_NOEMAIL_MASK),
- card_and_book);
+ eab_merging_book_add_contact (
+ registry, book_client, contact, NULL, NULL);
+ }
- gtk_signal_connect (GTK_OBJECT (popup), "selection-done",
- GTK_SIGNAL_FUNC (free_popup_info), card_and_book);
- e_popup_menu (popup, event);
+ g_object_unref (registry);
+ g_slist_free_full (contact_list, (GDestroyNotify) g_object_unref);
}
+static void
+addressbook_view_delete_selection (ESelectable *selectable)
+{
+ EAddressbookView *view;
-/* Minicard view stuff */
-
-/* Translators: put here a list of labels you want to see on buttons in
- addressbook. You may use any character to separate labels but it must
- also be placed at the begining ot the string */
-const char *button_labels = N_(",123,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z");
-/* Translators: put here a list of characters that correspond to buttons
- in addressbook. You may use any character to separate labels but it
- must also be placed at the begining ot the string.
- Use lower case letters if possible. */
-const char *button_letters = N_(",0,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z");
+ view = E_ADDRESSBOOK_VIEW (selectable);
-typedef struct {
- EAddressbookView *view;
- GtkWidget *button;
- GtkWidget *vbox;
- gunichar letter;
-} LetterClosure;
+ e_addressbook_view_delete_selection (view, TRUE);
+}
-static char **
-e_utf8_split (const char *utf8_str, gunichar delim)
+static void
+addressbook_view_select_all (ESelectable *selectable)
{
- GSList *str_list = NULL, *sl;
- int n = 0;
- const char *str, *s;
- char **str_array;
-
- g_return_val_if_fail (utf8_str != NULL, NULL);
-
- str = utf8_str;
- while (*str != '\0') {
- int len;
- char *new_str;
-
- for (s = str; *s != '\0' && g_utf8_get_char (s) != delim; s = g_utf8_next_char (s))
- ;
- len = s - str;
- new_str = g_new (char, len + 1);
- if (len > 0) {
- memcpy (new_str, str, len);
- }
- new_str[len] = '\0';
- str_list = g_slist_prepend (str_list, new_str);
- n++;
- if (*s != '\0') {
- str = g_utf8_next_char (s);
- } else {
- str = s;
- }
- }
+ EAddressbookView *view;
+ ESelectionModel *selection_model;
- str_array = g_new (char *, n + 1);
- str_array[n--] = NULL;
- for (sl = str_list; sl != NULL; sl = sl->next) {
- str_array[n--] = sl->data;
- }
- g_slist_free (str_list);
+ view = E_ADDRESSBOOK_VIEW (selectable);
+ selection_model = e_addressbook_view_get_selection_model (view);
- return str_array;
+ if (selection_model != NULL)
+ e_selection_model_select_all (selection_model);
}
static void
-jump_to_letter(EAddressbookView *view, gunichar letter)
-{
- char *query;
-
- if (g_unichar_isdigit (letter)) {
- const char *letters = U_(button_letters);
- char **letter_v;
- GString *gstr;
- char **p;
-
- letter_v = e_utf8_split (g_utf8_next_char (letters),
- g_utf8_get_char (letters));
- g_assert (letter_v != NULL && letter_v[0] != NULL);
- gstr = g_string_new ("(not (or ");
- for (p = letter_v + 1; *p != NULL; p++) {
- g_string_sprintfa (gstr, "(beginswith \"file_as\" \"%s\")", *p);
- }
- g_string_append (gstr, "))");
- query = gstr->str;
- g_strfreev (letter_v);
- g_string_free (gstr, FALSE);
- } else {
- char s[6 + 1];
-
- s [g_unichar_to_utf8 (letter, s)] = '\0';
- query = g_strdup_printf ("(beginswith \"file_as\" \"%s\")", s);
- }
- gtk_object_set (GTK_OBJECT (view),
- "query", query,
- NULL);
- g_free (query);
+e_addressbook_view_class_init (EAddressbookViewClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EAddressbookViewPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = addressbook_view_set_property;
+ object_class->get_property = addressbook_view_get_property;
+ object_class->dispose = addressbook_view_dispose;
+ object_class->constructed = addressbook_view_constructed;
+
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_COPY_TARGET_LIST,
+ "copy-target-list");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MODEL,
+ g_param_spec_object (
+ "model",
+ "Model",
+ NULL,
+ E_TYPE_ADDRESSBOOK_MODEL,
+ G_PARAM_READABLE));
+
+ /* Inherited from ESelectableInterface */
+ g_object_class_override_property (
+ object_class,
+ PROP_PASTE_TARGET_LIST,
+ "paste-target-list");
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHELL_VIEW,
+ g_param_spec_object (
+ "shell-view",
+ "Shell View",
+ NULL,
+ E_TYPE_SHELL_VIEW,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SOURCE,
+ g_param_spec_object (
+ "source",
+ "Source",
+ NULL,
+ E_TYPE_SOURCE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, open_contact),
+ NULL, NULL,
+ e_marshal_VOID__OBJECT_BOOLEAN,
+ G_TYPE_NONE, 2,
+ E_TYPE_CONTACT,
+ G_TYPE_BOOLEAN);
+
+ signals[POPUP_EVENT] = g_signal_new (
+ "popup-event",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, popup_event),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__BOXED,
+ G_TYPE_NONE, 1,
+ GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+ signals[COMMAND_STATE_CHANGE] = g_signal_new (
+ "command-state-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, command_state_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTION_CHANGE] = g_signal_new (
+ "selection-change",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EAddressbookViewClass, selection_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ /* init the accessibility support for e_addressbook_view */
+ eab_view_a11y_init ();
}
static void
-button_toggled(GtkWidget *button, LetterClosure *closure)
+e_addressbook_view_init (EAddressbookView *view)
{
- EAddressbookView *view = closure->view;
+ GtkTargetList *target_list;
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button))) {
- GtkWidget *current = view->current_alphabet_widget;
+ view->priv = E_ADDRESSBOOK_VIEW_GET_PRIVATE (view);
- view->current_alphabet_widget = NULL;
- if (current && current != button)
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (current), FALSE);
- jump_to_letter (view, closure->letter);
- view->current_alphabet_widget = button;
- alphabet_state_change (view, closure->letter);
- } else {
- if (view->current_alphabet_widget != NULL &&
- view->current_alphabet_widget == button) {
- view->current_alphabet_widget = NULL;
- gtk_object_set (GTK_OBJECT (view),
- "query", NULL,
- NULL);
- alphabet_state_change (view, 0);
- }
- }
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_directory_targets (target_list, 0);
+ view->priv->copy_target_list = target_list;
+
+ target_list = gtk_target_list_new (NULL, 0);
+ e_target_list_add_directory_targets (target_list, 0);
+ view->priv->paste_target_list = target_list;
+
+ gtk_scrolled_window_set_policy (
+ GTK_SCROLLED_WINDOW (view),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (
+ GTK_SCROLLED_WINDOW (view), GTK_SHADOW_IN);
}
static void
-free_closure(GtkWidget *button, LetterClosure *closure)
+e_addressbook_view_selectable_init (ESelectableInterface *interface)
{
- if (button != NULL &&
- button == closure->view->current_alphabet_widget) {
- closure->view->current_alphabet_widget = NULL;
- }
- g_free(closure);
+ interface->update_actions = addressbook_view_update_actions;
+ interface->cut_clipboard = addressbook_view_cut_clipboard;
+ interface->copy_clipboard = addressbook_view_copy_clipboard;
+ interface->paste_clipboard = addressbook_view_paste_clipboard;
+ interface->delete_selection = addressbook_view_delete_selection;
+ interface->select_all = addressbook_view_select_all;
}
-static GtkWidget *
-create_alphabet (EAddressbookView *view)
+GtkWidget *
+e_addressbook_view_new (EShellView *shell_view,
+ ESource *source)
{
- GtkWidget *widget, *viewport, *vbox;
- const char *labels, *letters;
- char **label_v, **letter_v;
- char **pl, **pc;
- gunichar sep;
-
- widget = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (widget),
- GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
-
- viewport = gtk_viewport_new (NULL, NULL);
- gtk_container_add (GTK_CONTAINER (widget), viewport);
- gtk_container_set_border_width (GTK_CONTAINER (viewport), 4);
- gtk_viewport_set_shadow_type (GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
-
- vbox = gtk_vbox_new (FALSE, 4);
- gtk_container_add (GTK_CONTAINER (viewport), vbox);
- gtk_widget_set_usize (vbox, 27, 0);
-
- labels = U_(button_labels);
- sep = g_utf8_get_char (labels);
- label_v = e_utf8_split (g_utf8_next_char (labels), sep);
- letters = U_(button_letters);
- sep = g_utf8_get_char (letters);
- letter_v = e_utf8_split (g_utf8_next_char (letters), sep);
- g_assert (label_v != NULL && letter_v != NULL);
- for (pl = label_v, pc = letter_v; *pl != NULL && *pc != NULL; pl++, pc++) {
- GtkWidget *button;
- LetterClosure *closure;
- char *label;
-
- label = e_utf8_to_locale_string (*pl);
- button = gtk_toggle_button_new_with_label (label);
- g_free (label);
- gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
-
- closure = g_new (LetterClosure, 1);
- closure->view = view;
- closure->letter = g_utf8_get_char (*pc);
- closure->button = button;
- closure->vbox = vbox;
- gtk_signal_connect(GTK_OBJECT(button), "toggled",
- GTK_SIGNAL_FUNC (button_toggled), closure);
- gtk_signal_connect(GTK_OBJECT(button), "destroy",
- GTK_SIGNAL_FUNC (free_closure), closure);
-
- }
- g_strfreev (label_v);
- g_strfreev (letter_v);
+ GtkWidget *widget;
+ EAddressbookView *view;
- gtk_widget_show_all (widget);
+ g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
+
+ widget = g_object_new (
+ E_TYPE_ADDRESSBOOK_VIEW, "shell-view",
+ shell_view, "source", source, NULL);
+
+ view = E_ADDRESSBOOK_VIEW (widget);
+
+ g_signal_connect_swapped (
+ view->priv->model, "status_message",
+ G_CALLBACK (status_message), view);
+ g_signal_connect_swapped (
+ view->priv->model, "search_result",
+ G_CALLBACK (search_result), view);
+ g_signal_connect_swapped (
+ view->priv->model, "folder_bar_message",
+ G_CALLBACK (folder_bar_message), view);
+ g_signal_connect (
+ view->priv->model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), view);
+ g_signal_connect_swapped (
+ view->priv->model, "writable-status",
+ G_CALLBACK (command_state_change), view);
return widget;
}
-static void
-minicard_selection_change (EMinicardViewWidget *widget, EAddressbookView *view)
+EAddressbookModel *
+e_addressbook_view_get_model (EAddressbookView *view)
{
- command_state_change (view);
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static void
-minicard_button_press (GtkWidget *widget, GdkEventButton *event, EAddressbookView *view)
-{
- d(g_print ("Button %d pressed with event type %d\n", event->button, event->type));
+ return view->priv->model;
}
-static void
-minicard_right_click (EMinicardView *minicard_view_item, GdkEvent *event, EAddressbookView *view)
+GalViewInstance *
+e_addressbook_view_get_view_instance (EAddressbookView *view)
{
- do_popup_menu(view, event);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->view_instance;
}
-static void
-create_minicard_view (EAddressbookView *view)
+GObject *
+e_addressbook_view_get_view_object (EAddressbookView *view)
{
- GtkWidget *scrollframe;
- GtkWidget *alphabet;
- GtkWidget *minicard_view;
- GtkWidget *minicard_hbox;
- EAddressbookReflowAdapter *adapter;
+ /* XXX Find a more descriptive name for this. */
- gtk_widget_push_visual (gdk_rgb_get_visual ());
- gtk_widget_push_colormap (gdk_rgb_get_cmap ());
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- minicard_hbox = gtk_hbox_new(FALSE, 0);
+ return view->priv->object;
+}
- adapter = E_ADDRESSBOOK_REFLOW_ADAPTER(e_addressbook_reflow_adapter_new (view->model));
- minicard_view = e_minicard_view_widget_new(adapter);
+/* Helper for e_addressbook_view_get_selected() */
+static void
+add_to_list (gint model_row,
+ gpointer closure)
+{
+ GSList **list = closure;
+ *list = g_slist_prepend (*list, GINT_TO_POINTER (model_row));
+}
- /* A hack */
- gtk_object_set_data (GTK_OBJECT (adapter), "view", view);
+GSList *
+e_addressbook_view_get_selected (EAddressbookView *view)
+{
+ GSList *list, *iter;
+ ESelectionModel *selection;
- gtk_signal_connect(GTK_OBJECT(minicard_view), "selection_change",
- GTK_SIGNAL_FUNC(minicard_selection_change), view);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- gtk_signal_connect(GTK_OBJECT(minicard_view), "button_press_event",
- GTK_SIGNAL_FUNC(minicard_button_press), view);
+ list = NULL;
+ selection = e_addressbook_view_get_selection_model (view);
+ e_selection_model_foreach (selection, add_to_list, &list);
- gtk_signal_connect(GTK_OBJECT(minicard_view), "right_click",
- GTK_SIGNAL_FUNC(minicard_right_click), view);
+ for (iter = list; iter != NULL; iter = iter->next)
+ iter->data = e_addressbook_model_get_contact (
+ view->priv->model, GPOINTER_TO_INT (iter->data));
+ return g_slist_reverse (list);
+}
+ESelectionModel *
+e_addressbook_view_get_selection_model (EAddressbookView *view)
+{
+ GalView *gal_view;
+ GalViewInstance *view_instance;
+ ESelectionModel *model = NULL;
- view->object = GTK_OBJECT(minicard_view);
- view->widget = minicard_hbox;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- scrollframe = e_scroll_frame_new (NULL, NULL);
- e_scroll_frame_set_policy (E_SCROLL_FRAME (scrollframe),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
- gtk_container_add (GTK_CONTAINER (scrollframe), minicard_view);
+ if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ GtkWidget *child;
+ child = gtk_bin_get_child (GTK_BIN (view));
+ model = e_table_get_selection_model (E_TABLE (child));
- gtk_box_pack_start(GTK_BOX(minicard_hbox), scrollframe, TRUE, TRUE, 0);
+ } else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EMinicardViewWidget *widget;
- alphabet = create_alphabet(view);
- if (alphabet) {
- gtk_object_ref(GTK_OBJECT(alphabet));
- gtk_widget_unparent(alphabet);
- gtk_box_pack_start(GTK_BOX(minicard_hbox), alphabet, FALSE, FALSE, 0);
- gtk_object_unref(GTK_OBJECT(alphabet));
+ widget = E_MINICARD_VIEW_WIDGET (view->priv->object);
+ model = e_minicard_view_widget_get_selection_model (widget);
}
- gtk_table_attach(GTK_TABLE(view), minicard_hbox,
- 0, 1,
- 0, 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
-
- gtk_widget_show_all( GTK_WIDGET(minicard_hbox) );
-
- gtk_widget_pop_visual ();
- gtk_widget_pop_colormap ();
-
- e_reflow_model_changed (E_REFLOW_MODEL (adapter));
-
- gtk_object_unref (GTK_OBJECT (adapter));
+ return model;
}
-static void
-table_double_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
+EShellView *
+e_addressbook_view_get_shell_view (EAddressbookView *view)
{
- if (E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object)) {
- EAddressbookModel *model = view->model;
- ECard *card = e_addressbook_model_get_card(model, row);
- EBook *book;
-
- gtk_object_get(GTK_OBJECT(model),
- "book", &book,
- NULL);
-
- g_assert (E_IS_BOOK (book));
-
- if (e_card_evolution_list (card))
- e_addressbook_show_contact_list_editor (book, card, FALSE, view->editable);
- else
- e_addressbook_show_contact_editor (book, card, FALSE, view->editable);
- }
-}
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
-static gint
-table_right_click(ETableScrolled *table, gint row, gint col, GdkEvent *event, EAddressbookView *view)
-{
- do_popup_menu(view, event);
- return TRUE;
+ return view->priv->shell_view;
}
-static gint
-table_white_space_event(ETableScrolled *table, GdkEvent *event, EAddressbookView *view)
+ESource *
+e_addressbook_view_get_source (EAddressbookView *view)
{
- if (event->type == GDK_BUTTON_PRESS && ((GdkEventButton *)event)->button == 3) {
- do_popup_menu(view, event);
- return TRUE;
- } else {
- return FALSE;
- }
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->source;
}
-static void
-table_selection_change(ETableScrolled *table, EAddressbookView *view)
+GtkTargetList *
+e_addressbook_view_get_copy_target_list (EAddressbookView *view)
{
- command_state_change (view);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
+
+ return view->priv->copy_target_list;
}
-static void
-table_drag_data_get (ETable *table,
- int row,
- int col,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer user_data)
+GtkTargetList *
+e_addressbook_view_get_paste_target_list (EAddressbookView *view)
{
- EAddressbookView *view = user_data;
-
- if (!E_IS_ADDRESSBOOK_TABLE_ADAPTER(view->object))
- return;
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (view), NULL);
- switch (info) {
- case DND_TARGET_TYPE_VCARD: {
- char *value;
+ return view->priv->paste_target_list;
+}
- row = e_table_view_to_model_row (table, row);
- value = e_card_get_vcard(view->model->data[row]);
+static void
+status_message (EAddressbookView *view,
+ const gchar *status,
+ gint percent)
+{
+ EActivity *activity;
+ EShellView *shell_view;
+ EShellBackend *shell_backend;
+
+ activity = view->priv->activity;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_backend = e_shell_view_get_shell_backend (shell_view);
+
+ if (status == NULL || *status == '\0') {
+ if (activity != NULL) {
+ view->priv->activity = NULL;
+ e_activity_set_state (activity, E_ACTIVITY_COMPLETED);
+ g_object_unref (activity);
+ }
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- value, strlen (value));
- break;
- }
+ } else if (activity == NULL) {
+ activity = e_activity_new ();
+ view->priv->activity = activity;
+ e_activity_set_text (activity, status);
+ if (percent >= 0)
+ e_activity_set_percent (activity, percent);
+ e_shell_backend_add_activity (shell_backend, activity);
+ } else {
+ e_activity_set_text (activity, status);
+ if (percent >= 0)
+ e_activity_set_percent (activity, percent);
}
}
static void
-emit_status_message (EAddressbookView *eav, const gchar *status)
+search_result (EAddressbookView *view,
+ const GError *error)
{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [STATUS_MESSAGE],
- status);
-}
+ EShellView *shell_view;
+ EAlertSink *alert_sink;
-static void
-emit_search_result (EAddressbookView *eav, EBookViewStatus status)
-{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [SEARCH_RESULT],
- status);
-}
+ shell_view = e_addressbook_view_get_shell_view (view);
+ alert_sink = E_ALERT_SINK (e_shell_view_get_shell_content (shell_view));
-static void
-emit_folder_bar_message (EAddressbookView *eav, const gchar *message)
-{
- gtk_signal_emit (GTK_OBJECT (eav),
- e_addressbook_view_signals [FOLDER_BAR_MESSAGE],
- message);
+ eab_search_result_dialog (alert_sink, error);
}
static void
-status_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
+folder_bar_message (EAddressbookView *view,
+ const gchar *message)
{
- emit_status_message (eav, status);
-}
+ EShellView *shell_view;
+ EShellSidebar *shell_sidebar;
+ const gchar *display_name;
-static void
-search_result (GtkObject *object, EBookViewStatus status, EAddressbookView *eav)
-{
- emit_search_result (eav, status);
-}
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
-static void
-folder_bar_message (GtkObject *object, const gchar *status, EAddressbookView *eav)
-{
- emit_folder_bar_message (eav, status);
-}
+ if (view->priv->source == NULL)
+ return;
-static void
-stop_state_changed (GtkObject *object, EAddressbookView *eav)
-{
- command_state_change (eav);
+ display_name = e_source_get_display_name (view->priv->source);
+ e_shell_sidebar_set_primary_text (shell_sidebar, display_name);
+ e_shell_sidebar_set_secondary_text (shell_sidebar, message);
}
static void
-command_state_change (EAddressbookView *eav)
+stop_state_changed (GObject *object,
+ EAddressbookView *view)
{
- /* Reffing during emission is unnecessary. Gtk automatically refs during an emission. */
- gtk_signal_emit (GTK_OBJECT (eav), e_addressbook_view_signals [COMMAND_STATE_CHANGE]);
+ command_state_change (view);
}
static void
-alphabet_state_change (EAddressbookView *eav, gunichar letter)
+command_state_change (EAddressbookView *view)
{
- gtk_signal_emit (GTK_OBJECT (eav), e_addressbook_view_signals [ALPHABET_STATE_CHANGE], letter);
+ g_signal_emit (view, signals[COMMAND_STATE_CHANGE], 0);
}
static void
-backend_died (GtkObject *object, EAddressbookView *eav)
+contact_print_button_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ EPrintable *printable)
{
- char *message = g_strdup_printf (_("The addressbook backend for\n%s\nhas crashed. "
- "You will have to restart Evolution in order "
- "to use it again"),
- e_book_get_uri (eav->book));
- gnome_error_dialog_parented (message, GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (eav))));
- g_free (message);
-}
+ GtkPageSetup *setup;
+ gdouble top_margin, page_width;
+ cairo_t *cr;
-static void
-create_table_view (EAddressbookView *view)
-{
- ETableModel *adapter;
- ECardSimple *simple;
- GtkWidget *table;
-
- simple = e_card_simple_new(NULL);
+ setup = gtk_print_context_get_page_setup (context);
+ top_margin = gtk_page_setup_get_top_margin (setup, GTK_UNIT_POINTS);
+ page_width = gtk_page_setup_get_page_width (setup, GTK_UNIT_POINTS);
- adapter = e_addressbook_table_adapter_new(view->model);
+ cr = gtk_print_context_get_cairo_context (context);
- /* Here we create the table. We give it the three pieces of
- the table we've created, the header, the model, and the
- initial layout. It does the rest. */
- table = e_table_scrolled_new_from_spec_file (adapter, NULL, EVOLUTION_ETSPECDIR "/e-addressbook-view.etspec", NULL);
-
- view->object = GTK_OBJECT(adapter);
- view->widget = table;
-
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "double_click",
- GTK_SIGNAL_FUNC(table_double_click), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "right_click",
- GTK_SIGNAL_FUNC(table_right_click), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "white_space_event",
- GTK_SIGNAL_FUNC(table_white_space_event), view);
- gtk_signal_connect(GTK_OBJECT(e_table_scrolled_get_table(E_TABLE_SCROLLED(table))), "selection_change",
- GTK_SIGNAL_FUNC(table_selection_change), view);
-
- /* drag & drop signals */
- e_table_drag_source_set (E_TABLE(E_TABLE_SCROLLED(table)->table), GDK_BUTTON1_MASK,
- drag_types, num_drag_types, GDK_ACTION_MOVE);
-
- gtk_signal_connect (GTK_OBJECT (E_TABLE_SCROLLED(table)->table),
- "table_drag_data_get",
- GTK_SIGNAL_FUNC (table_drag_data_get),
- view);
-
- gtk_table_attach(GTK_TABLE(view), table,
- 0, 1,
- 0, 1,
- GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND,
- 0, 0);
-
- gtk_widget_show( GTK_WIDGET(table) );
-
- gtk_object_unref(GTK_OBJECT(simple));
-}
+ e_printable_reset (printable);
+ while (e_printable_data_left (printable)) {
+ cairo_save (cr);
+ contact_page_draw_footer (operation,context,page_nr++);
+ e_printable_print_page (
+ printable, context, page_width - 16, top_margin + 10, TRUE);
+ cairo_restore (cr);
+ }
+}
static void
-change_view_type (EAddressbookView *view, EAddressbookViewType view_type)
+e_contact_print_button (EPrintable *printable,
+ GtkPrintOperationAction action)
{
- if (view_type == view->view_type)
- return;
+ GtkPrintOperation *operation;
- if (view->widget) {
- gtk_widget_destroy (view->widget);
- view->widget = NULL;
- }
- view->object = NULL;
-
- switch (view_type) {
- case E_ADDRESSBOOK_VIEW_MINICARD:
- create_minicard_view (view);
- break;
- case E_ADDRESSBOOK_VIEW_TABLE:
- create_table_view (view);
- break;
- default:
- g_warning ("view_type must be either TABLE or MINICARD\n");
- return;
- }
+ operation = e_print_operation_new ();
+ gtk_print_operation_set_n_pages (operation, 1);
- view->view_type = view_type;
+ g_signal_connect (
+ operation, "draw_page",
+ G_CALLBACK (contact_print_button_draw_page), printable);
- command_state_change (view);
-}
+ gtk_print_operation_run (operation, action, NULL, NULL);
-static void
-e_contact_print_destroy(GnomeDialog *dialog, gpointer data)
-{
- ETableScrolled *table = gtk_object_get_data(GTK_OBJECT(dialog), "table");
- EPrintable *printable = gtk_object_get_data(GTK_OBJECT(dialog), "printable");
- gtk_object_unref(GTK_OBJECT(printable));
- gtk_object_unref(GTK_OBJECT(table));
-}
-
-static void
-e_contact_print_button(GnomeDialog *dialog, gint button, gpointer data)
-{
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- EPrintable *printable = gtk_object_get_data(GTK_OBJECT(dialog), "printable");
- GtkWidget *preview;
- switch( button ) {
- case GNOME_PRINT_PRINT:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 5 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- gnome_print_master_print(master);
- gtk_object_unref(GTK_OBJECT(master));
- gnome_dialog_close(dialog);
- break;
- case GNOME_PRINT_PREVIEW:
- master = gnome_print_master_new_from_dialog( GNOME_PRINT_DIALOG(dialog) );
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 9 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview"));
- gtk_widget_show_all(preview);
- gtk_object_unref(GTK_OBJECT(master));
- break;
- case GNOME_PRINT_CANCEL:
- gnome_dialog_close(dialog);
- break;
- }
+ g_object_unref (operation);
}
void
-e_addressbook_view_setup_menus (EAddressbookView *view,
- BonoboUIComponent *uic)
+e_addressbook_view_print (EAddressbookView *view,
+ gboolean selection_only,
+ GtkPrintOperationAction action)
{
+ GalView *gal_view;
+ GalViewInstance *view_instance;
- g_return_if_fail (view != NULL);
g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- g_return_if_fail (uic != NULL);
- g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
- init_collection ();
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
- view->uic = uic;
+ /* Print the selected contacts. */
+ if (GAL_IS_VIEW_MINICARD (gal_view) && selection_only) {
+ GSList *contact_list;
- setup_menus (view);
-}
+ contact_list = e_addressbook_view_get_selected (view);
+ e_contact_print (NULL, NULL, contact_list, action);
+ g_slist_free_full (
+ contact_list,
+ (GDestroyNotify) g_object_unref);
-/**
- * e_addressbook_view_discard_menus:
- * @view: An addressbook view.
- *
- * Makes an addressbook view discard its GAL view menus and its views instance
- * objects. This should be called when the corresponding Bonobo component is
- * deactivated.
- **/
-void
-e_addressbook_view_discard_menus (EAddressbookView *view)
-{
- g_return_if_fail (view != NULL);
- g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
- g_return_if_fail (view->view_instance);
+ /* Print the latest query results. */
+ } else if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ EBookQuery *query;
+ const gchar *query_string;
- if (view->view_menus) {
- gal_view_menus_unmerge (view->view_menus, NULL);
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+ query_string = e_addressbook_model_get_query (model);
- gtk_object_unref (GTK_OBJECT (view->view_menus));
- view->view_menus = NULL;
- }
+ if (query_string != NULL)
+ query = e_book_query_from_string (query_string);
+ else
+ query = NULL;
- if (view->view_instance) {
- gtk_object_unref (GTK_OBJECT (view->view_instance));
- view->view_instance = NULL;
- }
+ e_contact_print (book_client, query, NULL, action);
- view->uic = NULL;
-}
+ if (query != NULL)
+ e_book_query_unref (query);
-void
-e_addressbook_view_print(EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
- char *query;
- EBook *book;
- GtkWidget *print;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "query", &query,
- "book", &book,
- NULL);
- print = e_contact_print_dialog_new(book, query);
- g_free(query);
- gtk_widget_show_all(print);
- } else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
- GtkWidget *dialog;
+ /* XXX Does this print the entire table or just selected? */
+ } else if (GAL_IS_VIEW_ETABLE (gal_view)) {
EPrintable *printable;
- ETable *etable;
-
- dialog = gnome_print_dialog_new("Print cards", GNOME_PRINT_DIALOG_RANGE | GNOME_PRINT_DIALOG_COPIES);
- gnome_print_dialog_construct_range_any(GNOME_PRINT_DIALOG(dialog), GNOME_PRINT_RANGE_ALL | GNOME_PRINT_RANGE_SELECTION,
- NULL, NULL, NULL);
+ GtkWidget *widget;
- gtk_object_get(GTK_OBJECT(view->widget), "table", &etable, NULL);
- printable = e_table_get_printable(etable);
+ widget = gtk_bin_get_child (GTK_BIN (view));
+ printable = e_table_get_printable (E_TABLE (widget));
+ g_object_ref_sink (printable);
- gtk_object_ref(GTK_OBJECT(view->widget));
-
- gtk_object_set_data(GTK_OBJECT(dialog), "table", view->widget);
- gtk_object_set_data(GTK_OBJECT(dialog), "printable", printable);
-
- gtk_signal_connect(GTK_OBJECT(dialog),
- "clicked", GTK_SIGNAL_FUNC(e_contact_print_button), NULL);
- gtk_signal_connect(GTK_OBJECT(dialog),
- "destroy", GTK_SIGNAL_FUNC(e_contact_print_destroy), NULL);
- gtk_widget_show(dialog);
- }
-}
-
-void
-e_addressbook_view_print_preview(EAddressbookView *view)
-{
- if (view->view_type == E_ADDRESSBOOK_VIEW_MINICARD) {
- char *query;
- EBook *book;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "query", &query,
- "book", &book,
- NULL);
- e_contact_print_preview(book, query);
- g_free(query);
- } else if (view->view_type == E_ADDRESSBOOK_VIEW_TABLE) {
- EPrintable *printable;
- ETable *etable;
- GnomePrintMaster *master;
- GnomePrintContext *pc;
- GtkWidget *preview;
-
- gtk_object_get(GTK_OBJECT(view->widget), "table", &etable, NULL);
- printable = e_table_get_printable(etable);
-
- master = gnome_print_master_new();
- gnome_print_master_set_copies (master, 1, FALSE);
- pc = gnome_print_master_get_context( master );
- e_printable_reset(printable);
- while (e_printable_data_left(printable)) {
- if (gnome_print_gsave(pc) == -1)
- /* FIXME */;
- if (gnome_print_translate(pc, 72, 72) == -1)
- /* FIXME */;
- e_printable_print_page(printable,
- pc,
- 6.5 * 72,
- 9 * 72,
- TRUE);
- if (gnome_print_grestore(pc) == -1)
- /* FIXME */;
- if (gnome_print_showpage(pc) == -1)
- /* FIXME */;
- }
- gnome_print_master_close(master);
- preview = GTK_WIDGET(gnome_print_master_preview_new(master, "Print Preview"));
- gtk_widget_show_all(preview);
- gtk_object_unref(GTK_OBJECT(master));
- gtk_object_unref(GTK_OBJECT(printable));
- }
-}
+ e_contact_print_button (printable, action);
-static void
-card_deleted_cb (EBook* book, EBookStatus status, gpointer user_data)
-{
- if (status != E_BOOK_STATUS_SUCCESS) {
- e_addressbook_error_dialog (_("Error removing card"), status);
+ g_object_unref (printable);
}
}
static void
-do_remove (int i, gpointer user_data)
+report_and_free_error_if_any (GError *error)
{
- EBook *book;
- ECard *card;
- EAddressbookView *view = user_data;
-
- gtk_object_get (GTK_OBJECT(view->model),
- "book", &book,
- NULL);
+ if (!error)
+ return;
- card = e_addressbook_model_get_card (view->model, i);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ g_error_free (error);
+ return;
+ }
- e_book_remove_card(book, card, card_deleted_cb, view);
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_PERMISSION_DENIED)) {
+ e_alert_run_dialog_for_args (
+ e_shell_get_active_window (NULL),
+ "addressbook:contact-delete-error-perm", NULL);
+ } else {
+ eab_error_dialog (NULL, NULL, _("Failed to delete contact"), error);
+ }
- gtk_object_unref (GTK_OBJECT (card));
+ g_error_free (error);
}
-void
-e_addressbook_view_delete_selection(EAddressbookView *view)
+/* callback function to handle removal of contacts for
+ * which a user doesnt have write permission
+ */
+static void
+remove_contacts_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- ESelectionModel *model = get_selection_model (view);
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GError *error = NULL;
- g_return_if_fail (model);
+ e_book_client_remove_contacts_finish (book_client, result, &error);
- e_selection_model_foreach (model,
- do_remove,
- view);
-}
-
-static void
-invisible_destroyed (GtkWidget *invisible, EAddressbookView *view)
-{
- view->invisible = NULL;
+ report_and_free_error_if_any (error);
}
static void
-selection_get (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint info,
- guint time_stamp,
- EAddressbookView *view)
+remove_contact_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
{
- char *value;
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ GError *error = NULL;
- value = e_card_list_get_vcard(view->clipboard_cards);
+ e_book_client_remove_contact_finish (book_client, result, &error);
- gtk_selection_data_set (selection_data, GDK_SELECTION_TYPE_STRING,
- 8, value, strlen (value));
-
+ report_and_free_error_if_any (error);
}
-static void
-selection_clear_event (GtkWidget *invisible,
- GdkEventSelection *event,
- EAddressbookView *view)
-{
- if (view->clipboard_cards) {
- g_list_foreach (view->clipboard_cards, (GFunc)gtk_object_unref, NULL);
- g_list_free (view->clipboard_cards);
- view->clipboard_cards = NULL;
- }
-}
-
-static void
-selection_received (GtkWidget *invisible,
- GtkSelectionData *selection_data,
- guint time,
- EAddressbookView *view)
-{
- if (selection_data->length < 0 || selection_data->type != GDK_SELECTION_TYPE_STRING) {
- return;
+static gboolean
+addressbook_view_confirm_delete (GtkWindow *parent,
+ gboolean plural,
+ gboolean is_list,
+ const gchar *name)
+{
+ GtkWidget *dialog;
+ gchar *message;
+ gint response;
+
+ if (is_list) {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contact lists?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact list?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact list (%s)?"), name);
+ }
+ } else {
+ if (plural) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete these contacts?"));
+ } else if (name == NULL) {
+ message = g_strdup (
+ _("Are you sure you want to "
+ "delete this contact?"));
+ } else {
+ message = g_strdup_printf (
+ _("Are you sure you want to delete "
+ "this contact (%s)?"), name);
+ }
}
- else {
- /* XXX make sure selection_data->data = \0 terminated */
- GList *card_list = e_card_load_cards_from_string_with_default_charset (selection_data->data, "ISO-8859-1");
- GList *l;
-
- if (!card_list /* it wasn't a vcard list */)
- return;
- for (l = card_list; l; l = l->next) {
- ECard *card = l->data;
+ dialog = gtk_message_dialog_new (
+ parent, 0, GTK_MESSAGE_QUESTION,
+ GTK_BUTTONS_NONE, "%s", message);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_DELETE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
- e_card_merging_book_add_card (view->book, card, NULL /* XXX */, NULL);
- }
+ g_free (message);
- g_list_foreach (card_list, (GFunc)gtk_object_unref, NULL);
- g_list_free (card_list);
- }
+ return (response == GTK_RESPONSE_ACCEPT);
}
-static void
-add_to_list (int model_row, gpointer closure)
-{
- GList **list = closure;
- *list = g_list_prepend (*list, GINT_TO_POINTER (model_row));
-}
+void
+e_addressbook_view_delete_selection (EAddressbookView *view,
+ gboolean is_delete)
+{
+ GSList *list, *l;
+ gboolean plural = FALSE, is_list = FALSE;
+ EContact *contact;
+ ETable *etable = NULL;
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ ESelectionModel *selection_model = NULL;
+ GalViewInstance *view_instance;
+ GalView *gal_view;
+ GtkWidget *widget;
+ gchar *name = NULL;
+ gint row = 0, select;
+
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+
+ view_instance = e_addressbook_view_get_view_instance (view);
+ gal_view = gal_view_instance_get_current_view (view_instance);
+
+ list = e_addressbook_view_get_selected (view);
+ contact = list->data;
+
+ if (g_slist_next (list))
+ plural = TRUE;
+ else
+ name = e_contact_get (contact, E_CONTACT_FILE_AS);
-static GList *
-get_selected_cards (EAddressbookView *view)
-{
- GList *list;
- GList *iterator;
- ESelectionModel *selection = get_selection_model (view);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ is_list = TRUE;
- list = NULL;
- e_selection_model_foreach (selection, add_to_list, &list);
+ widget = gtk_bin_get_child (GTK_BIN (view));
- for (iterator = list; iterator; iterator = iterator->next) {
- iterator->data = e_addressbook_model_card_at (view->model, GPOINTER_TO_INT (iterator->data));
- if (iterator->data)
- gtk_object_ref (iterator->data);
+ if (GAL_IS_VIEW_MINICARD (gal_view)) {
+ selection_model = e_addressbook_view_get_selection_model (view);
+ row = e_selection_model_cursor_row (selection_model);
}
- list = g_list_reverse (list);
- return list;
-}
-#if 0
-void
-e_addressbook_view_save_state (EAddressbookView *view, const char *filename)
-{
- xmlDoc *doc;
- xmlNode *node;
-
- doc = xmlNewDoc ("1.0");
- node = xmlNewDocNode (doc, NULL, "addressbook-view", NULL);
- xmlDocSetRootElement (doc, node);
-
- switch (view->view_type) {
- case E_ADDRESSBOOK_VIEW_MINICARD: {
- int column_width;
- e_xml_set_string_prop_by_name (node, "style", "minicard");
- gtk_object_get (GTK_OBJECT (view->object),
- "column_width", &column_width,
- NULL);
- e_xml_set_integer_prop_by_name (node, "column-width", column_width);
- break;
- }
- case E_ADDRESSBOOK_VIEW_TABLE: {
- ETableState *state;
- state = e_table_get_state_object (E_TABLE (view->widget));
-
- e_xml_set_string_prop_by_name (node, "style", "table");
- e_table_state_save_to_node (state, node);
- gtk_object_unref (GTK_OBJECT (state));
- break;
+ else if (GAL_IS_VIEW_ETABLE (gal_view)) {
+ etable = E_TABLE (widget);
+ row = e_table_get_cursor_row (E_TABLE (etable));
}
- default:
- xmlFreeDoc(doc);
+
+ /* confirm delete */
+ if (is_delete && !addressbook_view_confirm_delete (
+ GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view))),
+ plural, is_list, name)) {
+ g_free (name);
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
return;
}
- xmlSaveFile (filename, doc);
- xmlFreeDoc(doc);
-}
-void
-e_addressbook_view_load_state (EAddressbookView *view, const char *filename)
-{
- xmlDoc *doc;
+ if (e_client_check_capability (E_CLIENT (book_client), "bulk-remove")) {
+ GSList *ids = NULL;
- doc = xmlParseFile (filename);
- if (doc) {
- xmlNode *node;
- char *type;
+ for (l = list; l; l = g_slist_next (l)) {
+ const gchar *uid;
- node = xmlDocGetRootElement (doc);
- type = e_xml_get_string_prop_by_name (node, "style");
+ contact = l->data;
- if (!strcmp (type, "minicard")) {
- int column_width;
-
- change_view_type (view, E_ADDRESSBOOK_VIEW_MINICARD);
+ uid = e_contact_get_const (contact, E_CONTACT_UID);
+ ids = g_slist_prepend (ids, (gpointer) uid);
+ }
- column_width = e_xml_get_integer_prop_by_name (node, "column-width");
- gtk_object_set (GTK_OBJECT (view->object),
- "column_width", column_width,
- NULL);
- } else if (!strcmp (type, "table")) {
- ETableState *state;
+ /* Remove the cards all at once. */
+ e_book_client_remove_contacts (
+ book_client, ids, NULL, remove_contacts_cb, NULL);
- change_view_type (view, E_ADDRESSBOOK_VIEW_TABLE);
+ g_slist_free (ids);
+ } else {
+ for (l = list; l; l = g_slist_next (l)) {
+ contact = l->data;
- state = e_table_state_new();
- e_table_state_load_from_node (state, node->xmlChildrenNode);
- e_table_set_state_object (E_TABLE (view->widget), state);
- gtk_object_unref (GTK_OBJECT (state));
+ /* Remove the card. */
+ e_book_client_remove_contact (
+ book_client, contact, NULL,
+ remove_contact_cb, NULL);
}
- xmlFreeDoc(doc);
}
-}
-#endif
-void
-e_addressbook_view_save_as (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_contact_list_save_as (_("Save as VCard"), list, NULL);
- e_free_object_list(list);
-}
+ /* Sets the cursor, at the row after the deleted row */
+ if (GAL_IS_VIEW_MINICARD (gal_view) && row != 0 && selection_model) {
+ select = e_sorter_model_to_sorted (selection_model->sorter, row);
-void
-e_addressbook_view_view (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- e_addressbook_show_multiple_cards (view->book, list, view->editable);
- e_free_object_list(list);
-}
+ /* Sets the cursor, before the deleted row if its the last row */
+ if (select == e_selection_model_row_count (selection_model) - 1)
+ select = select - 1;
+ else
+ select = select + 1;
-void
-e_addressbook_view_send (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_card_list_send (list, E_CARD_DISPOSITION_AS_ATTACHMENT);
- e_free_object_list(list);
-}
+ row = e_sorter_sorted_to_model (selection_model->sorter, select);
+ e_selection_model_cursor_changed (selection_model, row, 0);
+ }
-void
-e_addressbook_view_send_to (EAddressbookView *view)
-{
- GList *list = get_selected_cards (view);
- if (list)
- e_card_list_send (list, E_CARD_DISPOSITION_AS_TO);
- e_free_object_list(list);
-}
+ /* Sets the cursor, at the row after the deleted row */
+ else if (GAL_IS_VIEW_ETABLE (gal_view) && row != 0) {
+ select = e_table_model_to_view_row (E_TABLE (etable), row);
-void
-e_addressbook_view_cut (EAddressbookView *view)
-{
- e_addressbook_view_copy (view);
- e_addressbook_view_delete_selection (view);
+ /* Sets the cursor, before the deleted row if its the last row */
+ if (select == e_table_model_row_count (E_TABLE (etable)->model) - 1)
+ select = select - 1;
+ else
+ select = select + 1;
+
+ row = e_table_view_to_model_row (E_TABLE (etable), select);
+ e_table_set_cursor_row (E_TABLE (etable), row);
+ }
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
}
void
-e_addressbook_view_copy (EAddressbookView *view)
+e_addressbook_view_view (EAddressbookView *view)
{
- view->clipboard_cards = get_selected_cards (view);
+ GSList *list, *iter;
+ gint response;
+ guint length;
- gtk_selection_owner_set (view->invisible, clipboard_atom, GDK_CURRENT_TIME);
-}
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-void
-e_addressbook_view_paste (EAddressbookView *view)
-{
- gtk_selection_convert (view->invisible, clipboard_atom,
- GDK_SELECTION_TYPE_STRING,
- GDK_CURRENT_TIME);
-}
+ list = e_addressbook_view_get_selected (view);
+ length = g_slist_length (list);
+ response = GTK_RESPONSE_YES;
-void
-e_addressbook_view_select_all (EAddressbookView *view)
-{
- ESelectionModel *model = get_selection_model (view);
+ if (length > 5) {
+ GtkWidget *dialog;
+
+ /* XXX Use e_alert_new(). */
+ /* XXX Provide a parent window. */
+ dialog = gtk_message_dialog_new (
+ NULL, 0,
+ GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, ngettext (
+ /* Translators: This is shown for > 5 contacts. */
+ "Opening %d contacts will open %d new windows "
+ "as well.\nDo you really want to display all of "
+ "these contacts?",
+ "Opening %d contacts will open %d new windows "
+ "as well.\nDo you really want to display all of "
+ "these contacts?", length), length, length);
+ gtk_dialog_add_buttons (
+ GTK_DIALOG (dialog),
+ _("_Don't Display"), GTK_RESPONSE_NO,
+ _("Display _All Contacts"), GTK_RESPONSE_YES,
+ NULL);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+ }
- g_return_if_fail (model);
+ if (response == GTK_RESPONSE_YES)
+ for (iter = list; iter != NULL; iter = iter->next)
+ addressbook_view_emit_open_contact (
+ view, iter->data, FALSE);
- e_selection_model_select_all (model);
+ g_slist_free_full (list, (GDestroyNotify) g_object_unref);
}
void
-e_addressbook_view_show_all(EAddressbookView *view)
+e_addressbook_view_show_all (EAddressbookView *view)
{
- gtk_object_set(GTK_OBJECT(view),
- "query", NULL,
- NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_set_query (view->priv->model, "");
}
void
-e_addressbook_view_stop(EAddressbookView *view)
+e_addressbook_view_stop (EAddressbookView *view)
{
- if (view)
- e_addressbook_model_stop (view->model);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+
+ e_addressbook_model_stop (view->priv->model);
}
-static void
-view_transfer_cards (EAddressbookView *view, gboolean delete_from_source)
+struct TransferContactsData
{
- EBook *book;
- GList *cards;
- GtkWindow *parent_window;
-
- gtk_object_get(GTK_OBJECT(view->model),
- "book", &book,
- NULL);
- cards = get_selected_cards (view);
- parent_window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
+ gboolean delete_from_source;
+ EAddressbookView *view;
+};
- e_addressbook_transfer_cards (book, cards, delete_from_source, parent_window);
-}
+static void
+all_contacts_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ struct TransferContactsData *tcd = user_data;
+ EAddressbookModel *model;
+ EClientCache *client_cache;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EAlertSink *alert_sink;
+ GSList *contacts = NULL;
+ GError *error = NULL;
+
+ g_return_if_fail (book_client != NULL);
+ g_return_if_fail (tcd != NULL);
+
+ if (!e_book_client_get_contacts_finish (book_client, result, &contacts, &error))
+ contacts = NULL;
+
+ shell_view = e_addressbook_view_get_shell_view (tcd->view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ alert_sink = E_ALERT_SINK (shell_content);
+
+ model = e_addressbook_view_get_model (tcd->view);
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ if (error) {
+ e_alert_submit (
+ alert_sink, "addressbook:search-error",
+ error->message, NULL);
+ g_error_free (error);
+ } else if (contacts) {
+ ESourceRegistry *registry;
+
+ registry = e_client_cache_ref_registry (client_cache);
+
+ eab_transfer_contacts (
+ registry, book_client, contacts,
+ tcd->delete_from_source, alert_sink);
+
+ g_object_unref (registry);
+ }
-void
-e_addressbook_view_copy_to_folder (EAddressbookView *view)
-{
- view_transfer_cards (view, FALSE);
+ g_object_unref (tcd->view);
+ g_free (tcd);
}
-void
-e_addressbook_view_move_to_folder (EAddressbookView *view)
-{
- view_transfer_cards (view, TRUE);
-}
+static void
+view_transfer_contacts (EAddressbookView *view,
+ gboolean delete_from_source,
+ gboolean all)
+{
+ EAddressbookModel *model;
+ EBookClient *book_client;
+ EClientCache *client_cache;
+
+ model = e_addressbook_view_get_model (view);
+ book_client = e_addressbook_model_get_client (model);
+ client_cache = e_addressbook_model_get_client_cache (model);
+
+ if (all) {
+ EBookQuery *query;
+ gchar *query_str;
+ struct TransferContactsData *tcd;
+
+ query = e_book_query_any_field_contains ("");
+ query_str = e_book_query_to_string (query);
+ e_book_query_unref (query);
+
+ tcd = g_new0 (struct TransferContactsData, 1);
+ tcd->delete_from_source = delete_from_source;
+ tcd->view = g_object_ref (view);
+
+ e_book_client_get_contacts (
+ book_client, query_str, NULL,
+ all_contacts_ready_cb, tcd);
+ } else {
+ GSList *contacts = NULL;
+ EShellView *shell_view;
+ EShellContent *shell_content;
+ EAlertSink *alert_sink;
+ ESourceRegistry *registry;
+ shell_view = e_addressbook_view_get_shell_view (view);
+ shell_content = e_shell_view_get_shell_content (shell_view);
+ alert_sink = E_ALERT_SINK (shell_content);
-static gboolean
-e_addressbook_view_selection_nonempty (EAddressbookView *view)
-{
- ESelectionModel *selection_model;
+ contacts = e_addressbook_view_get_selected (view);
- selection_model = get_selection_model (view);
- if (selection_model == NULL)
- return FALSE;
+ registry = e_client_cache_ref_registry (client_cache);
- return e_selection_model_selected_count (selection_model) != 0;
-}
+ eab_transfer_contacts (
+ registry, book_client, contacts,
+ delete_from_source, alert_sink);
-gboolean
-e_addressbook_view_can_create (EAddressbookView *view)
-{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
+ g_object_unref (registry);
+ }
}
-gboolean
-e_addressbook_view_can_print (EAddressbookView *view)
+void
+e_addressbook_view_copy_to_folder (EAddressbookView *view,
+ gboolean all)
{
- return view && view->model ? e_addressbook_model_card_count (view->model) : FALSE;
+ view_transfer_contacts (view, FALSE, all);
}
-gboolean
-e_addressbook_view_can_save_as (EAddressbookView *view)
+void
+e_addressbook_view_move_to_folder (EAddressbookView *view,
+ gboolean all)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ view_transfer_contacts (view, TRUE, all);
}
-gboolean
-e_addressbook_view_can_view (EAddressbookView *view)
+void
+e_addressbook_view_set_search (EAddressbookView *view,
+ gint filter_id,
+ gint search_id,
+ const gchar *search_text,
+ EFilterRule *advanced_search)
{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ EAddressbookViewPrivate *priv;
-gboolean
-e_addressbook_view_can_send (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
-gboolean
-e_addressbook_view_can_send_to (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ priv = view->priv;
-gboolean
-e_addressbook_view_can_delete (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
-}
+ if (priv->search_text)
+ g_free (priv->search_text);
+ if (priv->advanced_search)
+ g_object_unref (priv->advanced_search);
-gboolean
-e_addressbook_view_can_cut (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
-}
+ priv->filter_id = filter_id;
+ priv->search_id = search_id;
+ priv->search_text = g_strdup (search_text);
-gboolean
-e_addressbook_view_can_copy (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
+ if (advanced_search != NULL)
+ priv->advanced_search = e_filter_rule_clone (advanced_search);
+ else
+ priv->advanced_search = NULL;
}
-gboolean
-e_addressbook_view_can_paste (EAddressbookView *view)
+/* Free returned values for search_text and advanced_search,
+ * if not NULL, as these are new copies. */
+void
+e_addressbook_view_get_search (EAddressbookView *view,
+ gint *filter_id,
+ gint *search_id,
+ gchar **search_text,
+ EFilterRule **advanced_search)
{
- return view ? e_addressbook_model_editable (view->model) : FALSE;
-}
+ EAddressbookViewPrivate *priv;
-gboolean
-e_addressbook_view_can_select_all (EAddressbookView *view)
-{
- return view ? e_addressbook_model_card_count (view->model) != 0 : FALSE;
-}
+ g_return_if_fail (view != NULL);
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (view));
+ g_return_if_fail (filter_id != NULL);
+ g_return_if_fail (search_id != NULL);
+ g_return_if_fail (search_text != NULL);
+ g_return_if_fail (advanced_search != NULL);
-gboolean
-e_addressbook_view_can_stop (EAddressbookView *view)
-{
- return view ? e_addressbook_model_can_stop (view->model) : FALSE;
-}
+ priv = view->priv;
-gboolean
-e_addressbook_view_can_copy_to_folder (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) : FALSE;
-}
+ *filter_id = priv->filter_id;
+ *search_id = priv->search_id;
+ *search_text = g_strdup (priv->search_text);
-gboolean
-e_addressbook_view_can_move_to_folder (EAddressbookView *view)
-{
- return view ? e_addressbook_view_selection_nonempty (view) && e_addressbook_model_editable (view->model) : FALSE;
+ if (priv->advanced_search != NULL)
+ *advanced_search = e_filter_rule_clone (priv->advanced_search);
+ else
+ *advanced_search = NULL;
}
diff --git a/addressbook/gui/widgets/e-addressbook-view.etspec b/addressbook/gui/widgets/e-addressbook-view.etspec
index a0a0015d75..45eaea1df3 100644
--- a/addressbook/gui/widgets/e-addressbook-view.etspec
+++ b/addressbook/gui/widgets/e-addressbook-view.etspec
@@ -1,51 +1,65 @@
-<ETableSpecification click-to-add="true" draw-grid="true" _click-to-add-message="* Click here to add a contact *">
- <ETableColumn model_col= "0" _title="File As" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "1" _title="Full Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "2" _title="Email" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "3" _title="Primary Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "4" _title="Assistant Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "5" _title="Business Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "6" _title="Callback Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "7" _title="Company Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "8" _title="Home Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col= "9" _title="Organization" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="10" _title="Business Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="11" _title="Home Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="12" _title="Mobile Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="13" _title="Car Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="14" _title="Business Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="15" _title="Home Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="16" _title="Business Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="17" _title="Home Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="18" _title="ISDN" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="19" _title="Other Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="20" _title="Other Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="21" _title="Pager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="22" _title="Radio" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="23" _title="Telex" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="24" _title="TTY" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="25" _title="Other Address" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="26" _title="Email 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="27" _title="Email 3" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="28" _title="Web Site" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="29" _title="Department" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="30" _title="Office" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="31" _title="Title" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="32" _title="Profession" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="33" _title="Manager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="34" _title="Assistant" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="35" _title="Nickname" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="36" _title="Spouse" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="37" _title="Note" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
- <ETableColumn model_col="38" _title="Free-busy URL" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="string"/>
+<ETableSpecification draw-grid="true" cursor-mode="line">
+ <ETableColumn model_col= "2" _title="File As" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "4" _title="Full Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "5" _title="Given Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "6" _title="Family Name" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "7" _title="Nickname" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col= "8" _title="Email" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "9" _title="Email 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "10" _title="Email 3" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col= "16" _title="Assistant Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "17" _title="Business Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col= "18" _title="Business Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="19" _title="Business Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="20" _title="Callback Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="21" _title="Car Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="22" _title="Company Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="23" _title="Home Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="24" _title="Home Phone 2" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="25" _title="Home Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="26" _title="ISDN Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="27" _title="Mobile Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="28" _title="Other Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="29" _title="Other Fax" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="30" _title="Pager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="31" _title="Primary Phone" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="32" _title="Radio" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="33" _title="Telex" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+<!-- Translators: This is a vcard standard and stands for the type of
+ phone used by the hearing impaired. TTY stands for "teletype"
+ (familiar from Unix device names), and TDD is "Telecommunications
+ Device for Deaf". However, you probably want to leave this
+ abbreviation unchanged unless you know that there is actually a
+ different and established translation for this in your language. -->
+ <ETableColumn model_col="34" _title="TTYTDD" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="35" _title="Company" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="stringcase"/>
+ <ETableColumn model_col="36" _title="Unit" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="37" _title="Office" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="38" _title="Title" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="39" _title="Role" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="40" _title="Manager" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="41" _title="Assistant" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="42" _title="Web Site" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="43" _title="Journal" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="44" _title="Categories" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
+ <ETableColumn model_col="49" _title="Spouse" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+ <ETableColumn model_col="50" _title="Note" expansion="1.0" minimum_width="75" resizable="true" cell="string" compare="collate"/>
+
<ETableState>
<column source="0"/>
<column source="1"/>
<column source="5"/>
- <column source="2"/>
- <column source="3"/>
+ <column source="23"/>
+ <column source="36"/>
<grouping>
- <leaf column="0" ascending="true"/>
+ <leaf column="2" ascending="true"/>
</grouping>
</ETableState>
</ETableSpecification>
diff --git a/addressbook/gui/widgets/e-addressbook-view.h b/addressbook/gui/widgets/e-addressbook-view.h
index 897c37d420..94668d6ace 100644
--- a/addressbook/gui/widgets/e-addressbook-view.h
+++ b/addressbook/gui/widgets/e-addressbook-view.h
@@ -1,147 +1,129 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-addressbook-view.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 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_ADDRESSBOOK_VIEW_H__
-#define __E_ADDRESSBOOK_VIEW_H__
-
-#include <gtk/gtktable.h>
-#include <bonobo/bonobo-ui-component.h>
-#include <gal/menus/gal-view-instance.h>
-#include "e-addressbook-model.h"
-#include "widgets/menus/gal-view-menus.h"
-#include "addressbook/backend/ebook/e-book.h"
-#include <gal/unicode/gunicode.h>
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EAddressbookView - A card displaying information about a contact.
+ * 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>
*
- * The following arguments are available:
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * name type read/write description
- * --------------------------------------------------------------------------------
*/
-#define E_ADDRESSBOOK_VIEW_TYPE (e_addressbook_view_get_type ())
-#define E_ADDRESSBOOK_VIEW(obj) (GTK_CHECK_CAST ((obj), E_ADDRESSBOOK_VIEW_TYPE, EAddressbookView))
-#define E_ADDRESSBOOK_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_ADDRESSBOOK_VIEW_TYPE, EAddressbookViewClass))
-#define E_IS_ADDRESSBOOK_VIEW(obj) (GTK_CHECK_TYPE ((obj), E_ADDRESSBOOK_VIEW_TYPE))
-#define E_IS_ADDRESSBOOK_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_ADDRESSBOOK_VIEW_TYPE))
+#ifndef E_ADDRESSBOOK_VIEW_H
+#define E_ADDRESSBOOK_VIEW_H
-typedef enum {
- E_ADDRESSBOOK_VIEW_NONE, /* initialized to this */
- E_ADDRESSBOOK_VIEW_TABLE,
- E_ADDRESSBOOK_VIEW_MINICARD
-} EAddressbookViewType;
+#include <libebook/libebook.h>
+#include <shell/e-shell-view.h>
-typedef struct _EAddressbookView EAddressbookView;
-typedef struct _EAddressbookViewClass EAddressbookViewClass;
-
-struct _EAddressbookView
-{
- GtkTable parent;
-
- /* item specific fields */
- EAddressbookViewType view_type;
-
- EAddressbookModel *model;
-
- GtkWidget *invisible;
- GList *clipboard_cards;
-
- EBook *book;
- char *query;
- guint editable : 1;
-
- GtkObject *object;
- GtkWidget *widget;
- GtkWidget *current_alphabet_widget;
-
- GtkWidget *vbox;
-
- /* Menus handler and the view instance */
- GalViewInstance *view_instance;
- GalViewMenus *view_menus;
- GalView *current_view;
- BonoboUIComponent *uic;
+#include "e-addressbook-model.h"
+#include "eab-contact-display.h"
+
+/* Standard GObject macros */
+#define E_TYPE_ADDRESSBOOK_VIEW \
+ (e_addressbook_view_get_type ())
+#define E_ADDRESSBOOK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookView))
+#define E_ADDRESSBOOK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
+#define E_IS_ADDRESSBOOK_VIEW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_IS_ADDRESSBOOK_VIEW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW))
+#define E_ADDRESSBOOK_VIEW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_ADDRESSBOOK_VIEW, EAddressbookViewClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EAddressbookView EAddressbookView;
+typedef struct _EAddressbookViewClass EAddressbookViewClass;
+typedef struct _EAddressbookViewPrivate EAddressbookViewPrivate;
+
+struct _EAddressbookView {
+ GtkScrolledWindow parent;
+ EAddressbookViewPrivate *priv;
};
-struct _EAddressbookViewClass
-{
- GtkTableClass parent_class;
-
- /*
- * Signals
- */
- void (*status_message) (EAddressbookView *view, const gchar *message);
- void (*search_result) (EAddressbookView *view, EBookViewStatus status);
- void (*folder_bar_message) (EAddressbookView *view, const gchar *message);
- void (*command_state_change) (EAddressbookView *view);
- void (*alphabet_state_change) (EAddressbookView *view, gunichar letter);
+struct _EAddressbookViewClass {
+ GtkScrolledWindowClass parent_class;
+
+ /* Signals */
+ void (*open_contact) (EAddressbookView *view,
+ EContact *contact,
+ gboolean is_new_contact);
+ void (*popup_event) (EAddressbookView *view,
+ GdkEvent *event);
+ void (*command_state_change) (EAddressbookView *view);
+ void (*selection_change) (EAddressbookView *view);
};
-GtkWidget *e_addressbook_view_new (void);
-GtkType e_addressbook_view_get_type (void);
-
-void e_addressbook_view_setup_menus (EAddressbookView *view,
- BonoboUIComponent *uic);
-
-void e_addressbook_view_discard_menus (EAddressbookView *view);
-
-void e_addressbook_view_save_as (EAddressbookView *view);
-void e_addressbook_view_view (EAddressbookView *view);
-void e_addressbook_view_send (EAddressbookView *view);
-void e_addressbook_view_send_to (EAddressbookView *view);
-void e_addressbook_view_print (EAddressbookView *view);
-void e_addressbook_view_print_preview (EAddressbookView *view);
-void e_addressbook_view_delete_selection (EAddressbookView *view);
-void e_addressbook_view_cut (EAddressbookView *view);
-void e_addressbook_view_copy (EAddressbookView *view);
-void e_addressbook_view_paste (EAddressbookView *view);
-void e_addressbook_view_select_all (EAddressbookView *view);
-void e_addressbook_view_show_all (EAddressbookView *view);
-void e_addressbook_view_stop (EAddressbookView *view);
-void e_addressbook_view_copy_to_folder (EAddressbookView *view);
-void e_addressbook_view_move_to_folder (EAddressbookView *view);
-
-gboolean e_addressbook_view_can_create (EAddressbookView *view);
-gboolean e_addressbook_view_can_print (EAddressbookView *view);
-gboolean e_addressbook_view_can_save_as (EAddressbookView *view);
-gboolean e_addressbook_view_can_view (EAddressbookView *view);
-gboolean e_addressbook_view_can_send (EAddressbookView *view);
-gboolean e_addressbook_view_can_send_to (EAddressbookView *view);
-gboolean e_addressbook_view_can_delete (EAddressbookView *view);
-gboolean e_addressbook_view_can_cut (EAddressbookView *view);
-gboolean e_addressbook_view_can_copy (EAddressbookView *view);
-gboolean e_addressbook_view_can_paste (EAddressbookView *view);
-gboolean e_addressbook_view_can_select_all (EAddressbookView *view);
-gboolean e_addressbook_view_can_stop (EAddressbookView *view);
-gboolean e_addressbook_view_can_copy_to_folder (EAddressbookView *view);
-gboolean e_addressbook_view_can_move_to_folder (EAddressbookView *view);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_ADDRESSBOOK_VIEW_H__ */
+GType e_addressbook_view_get_type (void);
+GtkWidget * e_addressbook_view_new (EShellView *shell_view,
+ ESource *source);
+EAddressbookModel *
+ e_addressbook_view_get_model (EAddressbookView *view);
+GalViewInstance *
+ e_addressbook_view_get_view_instance
+ (EAddressbookView *view);
+GObject * e_addressbook_view_get_view_object
+ (EAddressbookView *view);
+GSList * e_addressbook_view_get_selected (EAddressbookView *view);
+ESelectionModel *
+ e_addressbook_view_get_selection_model
+ (EAddressbookView *view);
+EShellView * e_addressbook_view_get_shell_view
+ (EAddressbookView *view);
+ESource * e_addressbook_view_get_source (EAddressbookView *view);
+GtkTargetList * e_addressbook_view_get_copy_target_list
+ (EAddressbookView *view);
+GtkTargetList * e_addressbook_view_get_paste_target_list
+ (EAddressbookView *view);
+void e_addressbook_view_view (EAddressbookView *view);
+void e_addressbook_view_print (EAddressbookView *view,
+ gboolean selection_only,
+ GtkPrintOperationAction action);
+void e_addressbook_view_delete_selection
+ (EAddressbookView *view,
+ gboolean is_delete);
+void e_addressbook_view_show_all (EAddressbookView *view);
+void e_addressbook_view_stop (EAddressbookView *view);
+void e_addressbook_view_copy_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+void e_addressbook_view_move_to_folder
+ (EAddressbookView *view,
+ gboolean all);
+
+gboolean e_addressbook_view_can_create (EAddressbookView *view);
+
+void e_addressbook_view_set_search (EAddressbookView *view,
+ gint filter_id,
+ gint search_id,
+ const gchar *search_text,
+ EFilterRule *advanced_search);
+
+void e_addressbook_view_get_search (EAddressbookView *view,
+ gint *filter_id,
+ gint *search_id,
+ gchar **search_text,
+ EFilterRule **advanced_search);
+
+G_END_DECLS
+
+#endif /* E_ADDRESSBOOK_VIEW_H */
diff --git a/addressbook/gui/widgets/e-contact-map-window.c b/addressbook/gui/widgets/e-contact-map-window.c
new file mode 100644
index 0000000000..1dbe694d50
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map-window.c
@@ -0,0 +1,500 @@
+/*
+ * e-contact-map-window.c
+ *
+ * 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/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-map.h"
+#include "e-contact-map-window.h"
+#include "e-contact-marker.h"
+
+#include <champlain/champlain.h>
+
+#include <string.h>
+
+#include <glib/gi18n.h>
+#include <glib-object.h>
+
+#define E_CONTACT_MAP_WINDOW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowPrivate))
+
+G_DEFINE_TYPE (EContactMapWindow, e_contact_map_window, GTK_TYPE_WINDOW)
+
+struct _EContactMapWindowPrivate {
+ EContactMap *map;
+
+ GtkWidget *zoom_in_btn;
+ GtkWidget *zoom_out_btn;
+
+ GtkWidget *search_entry;
+ GtkListStore *completion_model;
+
+ GHashTable *hash_table; /* Hash table contact-name -> marker */
+
+ GtkWidget *spinner;
+ gint tasks_cnt;
+};
+
+enum {
+ SHOW_CONTACT_EDITOR,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+static void
+marker_doubleclick_cb (ClutterActor *actor,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ EContactMarker *marker;
+ const gchar *contact_uid;
+
+ marker = E_CONTACT_MARKER (actor);
+ contact_uid = e_contact_marker_get_contact_uid (marker);
+
+ g_signal_emit (window, signals[SHOW_CONTACT_EDITOR], 0, contact_uid);
+}
+
+static void
+book_contacts_received_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ EBookClient *client = E_BOOK_CLIENT (source_object);
+ GSList *contacts = NULL, *p;
+ GError *error = NULL;
+
+ if (!e_book_client_get_contacts_finish (client, result, &contacts, &error))
+ contacts = NULL;
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Failed to get contacts: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ for (p = contacts; p; p = p->next)
+ e_contact_map_add_contact (
+ window->priv->map, (EContact *) p->data);
+
+ g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+ g_object_unref (client);
+}
+
+static void
+contact_map_window_zoom_in_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ ChamplainView *view;
+
+ view = e_contact_map_get_view (window->priv->map);
+
+ champlain_view_zoom_in (view);
+}
+
+static void
+contact_map_window_zoom_out_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ ChamplainView *view;
+
+ view = e_contact_map_get_view (window->priv->map);
+
+ champlain_view_zoom_out (view);
+}
+static void
+zoom_level_changed_cb (ChamplainView *view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ EContactMapWindow *window = user_data;
+ gint zoom_level = champlain_view_get_zoom_level (view);
+
+ gtk_widget_set_sensitive (
+ window->priv->zoom_in_btn,
+ (zoom_level < champlain_view_get_max_zoom_level (view)));
+
+ gtk_widget_set_sensitive (
+ window->priv->zoom_out_btn,
+ (zoom_level > champlain_view_get_min_zoom_level (view)));
+}
+
+/**
+ * Add contact to hash_table only when EContactMap tells us
+ * that the contact has really been added to map.
+ */
+static void
+map_contact_added_cb (EContactMap *map,
+ ClutterActor *marker,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ const gchar *name;
+ GtkTreeIter iter;
+
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+
+ g_hash_table_insert (
+ priv->hash_table,
+ g_strdup (name), marker);
+
+ gtk_list_store_append (priv->completion_model, &iter);
+ gtk_list_store_set (
+ priv->completion_model, &iter,
+ 0, name, -1);
+
+ g_signal_connect (
+ marker, "double-clicked",
+ G_CALLBACK (marker_doubleclick_cb), user_data);
+
+ priv->tasks_cnt--;
+ if (priv->tasks_cnt == 0) {
+ gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+ gtk_widget_hide (priv->spinner);
+ }
+}
+
+static void
+map_contact_removed_cb (EContactMap *map,
+ const gchar *name,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ GtkTreeIter iter;
+ GtkTreeModel *model = GTK_TREE_MODEL (priv->completion_model);
+
+ g_hash_table_remove (priv->hash_table, name);
+
+ if (gtk_tree_model_get_iter_first (model, &iter)) {
+ do {
+ gchar *name_str;
+ gtk_tree_model_get (model, &iter, 0, &name_str, -1);
+ if (g_ascii_strcasecmp (name_str, name) == 0) {
+ g_free (name_str);
+ gtk_list_store_remove (priv->completion_model, &iter);
+ break;
+ }
+ g_free (name_str);
+ } while (gtk_tree_model_iter_next (model, &iter));
+ }
+}
+
+static void
+map_contact_geocoding_started_cb (EContactMap *map,
+ ClutterActor *marker,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+
+ gtk_spinner_start (GTK_SPINNER (priv->spinner));
+ gtk_widget_show (priv->spinner);
+
+ priv->tasks_cnt++;
+}
+
+static void
+map_contact_geocoding_failed_cb (EContactMap *map,
+ const gchar *name,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+
+ priv->tasks_cnt--;
+
+ if (priv->tasks_cnt == 0) {
+ gtk_spinner_stop (GTK_SPINNER (priv->spinner));
+ gtk_widget_hide (priv->spinner);
+ }
+}
+
+static void
+contact_map_window_find_contact_cb (GtkButton *button,
+ gpointer user_data)
+{
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ ClutterActor *marker;
+
+ marker = g_hash_table_lookup (
+ priv->hash_table,
+ gtk_entry_get_text (GTK_ENTRY (priv->search_entry)));
+
+ if (marker)
+ e_contact_map_zoom_on_marker (priv->map, marker);
+}
+
+static gboolean
+contact_map_window_entry_key_pressed_cb (GtkWidget *entry,
+ GdkEventKey *event,
+ gpointer user_data)
+{
+ if (event->keyval == GDK_KEY_Return)
+ contact_map_window_find_contact_cb (NULL, user_data);
+
+ return FALSE;
+}
+
+static gboolean
+entry_completion_match_selected_cb (GtkEntryCompletion *widget,
+ GtkTreeModel *model,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ GValue name_val = {0};
+ EContactMapWindowPrivate *priv = E_CONTACT_MAP_WINDOW (user_data)->priv;
+ const gchar *name;
+
+ gtk_tree_model_get_value (model, iter, 0, &name_val);
+ g_return_val_if_fail (G_VALUE_HOLDS_STRING (&name_val), FALSE);
+
+ name = g_value_get_string (&name_val);
+ gtk_entry_set_text (GTK_ENTRY (priv->search_entry), name);
+
+ contact_map_window_find_contact_cb (NULL, user_data);
+
+ return TRUE;
+}
+
+static void
+contact_map_window_finalize (GObject *object)
+{
+ EContactMapWindowPrivate *priv;
+
+ priv = E_CONTACT_MAP_WINDOW (object)->priv;
+
+ if (priv->hash_table) {
+ g_hash_table_destroy (priv->hash_table);
+ priv->hash_table = NULL;
+ }
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_contact_map_window_parent_class)->finalize (object);
+}
+
+static void
+contact_map_window_dispose (GObject *object)
+{
+ EContactMapWindowPrivate *priv;
+
+ priv = E_CONTACT_MAP_WINDOW (object)->priv;
+
+ if (priv->map) {
+ gtk_widget_destroy (GTK_WIDGET (priv->map));
+ priv->map = NULL;
+ }
+
+ if (priv->completion_model) {
+ g_object_unref (priv->completion_model);
+ priv->completion_model = NULL;
+ }
+
+ G_OBJECT_CLASS (e_contact_map_window_parent_class)->dispose (object);
+}
+
+static void
+e_contact_map_window_class_init (EContactMapWindowClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EContactMapWindowPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = contact_map_window_finalize;
+ object_class->dispose = contact_map_window_dispose;
+
+ signals[SHOW_CONTACT_EDITOR] = g_signal_new (
+ "show-contact-editor",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapWindowClass, show_contact_editor),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+e_contact_map_window_init (EContactMapWindow *window)
+{
+ EContactMapWindowPrivate *priv;
+ GtkWidget *map;
+ GtkWidget *button, *entry;
+ GtkWidget *hbox, *vbox, *viewport;
+ GtkEntryCompletion *entry_completion;
+ GtkListStore *completion_model;
+ ChamplainView *view;
+ GHashTable *hash_table;
+
+ priv = E_CONTACT_MAP_WINDOW_GET_PRIVATE (window);
+ window->priv = priv;
+
+ priv->tasks_cnt = 0;
+
+ hash_table = g_hash_table_new_full (
+ (GHashFunc) g_str_hash,
+ (GEqualFunc) g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) NULL);
+ priv->hash_table = hash_table;
+
+ gtk_window_set_title (GTK_WINDOW (window), _("Contacts Map"));
+ gtk_container_set_border_width (GTK_CONTAINER (window), 12);
+ gtk_widget_set_size_request (GTK_WIDGET (window), 800, 600);
+
+ /* The map view itself */
+ map = e_contact_map_new ();
+ view = e_contact_map_get_view (E_CONTACT_MAP (map));
+ champlain_view_set_zoom_level (view, 2);
+ priv->map = E_CONTACT_MAP (map);
+ g_signal_connect (
+ view, "notify::zoom-level",
+ G_CALLBACK (zoom_level_changed_cb), window);
+ g_signal_connect (
+ map, "contact-added",
+ G_CALLBACK (map_contact_added_cb), window);
+ g_signal_connect (
+ map, "contact-removed",
+ G_CALLBACK (map_contact_removed_cb), window);
+ g_signal_connect (
+ map, "geocoding-started",
+ G_CALLBACK (map_contact_geocoding_started_cb), window);
+ g_signal_connect (
+ map, "geocoding-failed",
+ G_CALLBACK (map_contact_geocoding_failed_cb), window);
+
+ /* HBox container */
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 7);
+
+ /* Spinner */
+ button = gtk_spinner_new ();
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+ gtk_widget_hide (button);
+ priv->spinner = button;
+
+ /* Zoom-in button */
+ button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_IN);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_zoom_in_cb), window);
+ priv->zoom_in_btn = button;
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ /* Zoom-out button */
+ button = gtk_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_zoom_out_cb), window);
+ priv->zoom_out_btn = button;
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ /* Completion model */
+ completion_model = gtk_list_store_new (1, G_TYPE_STRING);
+ priv->completion_model = completion_model;
+
+ /* Entry completion */
+ entry_completion = gtk_entry_completion_new ();
+ gtk_entry_completion_set_model (
+ entry_completion, GTK_TREE_MODEL (completion_model));
+ gtk_entry_completion_set_text_column (entry_completion, 0);
+ g_signal_connect (
+ entry_completion, "match-selected",
+ G_CALLBACK (entry_completion_match_selected_cb), window);
+
+ /* Search entry */
+ entry = gtk_entry_new ();
+ gtk_entry_set_completion (GTK_ENTRY (entry), entry_completion);
+ g_signal_connect (
+ entry, "key-press-event",
+ G_CALLBACK (contact_map_window_entry_key_pressed_cb), window);
+ window->priv->search_entry = entry;
+ gtk_container_add (GTK_CONTAINER (hbox), entry);
+
+ /* Search button */
+ button = gtk_button_new_from_stock (GTK_STOCK_FIND);
+ g_signal_connect (
+ button, "clicked",
+ G_CALLBACK (contact_map_window_find_contact_cb), window);
+ gtk_container_add (GTK_CONTAINER (hbox), button);
+
+ viewport = gtk_frame_new (NULL);
+ gtk_container_add (GTK_CONTAINER (viewport), map);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_container_add (GTK_CONTAINER (vbox), viewport);
+ gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (window), vbox);
+
+ gtk_widget_show_all (vbox);
+ gtk_widget_hide (priv->spinner);
+}
+
+EContactMapWindow *
+e_contact_map_window_new (void)
+{
+ return g_object_new (
+ E_TYPE_CONTACT_MAP_WINDOW, NULL);
+}
+
+/**
+ * Gets all contacts from @book and puts them
+ * on the map view
+ */
+void
+e_contact_map_window_load_addressbook (EContactMapWindow *map,
+ EBookClient *book_client)
+{
+ EBookQuery *book_query;
+ gchar *query_string;
+
+ g_return_if_fail (E_IS_CONTACT_MAP_WINDOW (map));
+ g_return_if_fail (E_IS_BOOK_CLIENT (book_client));
+
+ /* Reference book, so that it does not get deleted before the callback is
+ * involved. The book is unrefed in the callback */
+ g_object_ref (book_client);
+
+ book_query = e_book_query_field_exists (E_CONTACT_ADDRESS);
+ query_string = e_book_query_to_string (book_query);
+ e_book_query_unref (book_query);
+
+ e_book_client_get_contacts (
+ book_client, query_string, NULL,
+ book_contacts_received_cb, map);
+
+ g_free (query_string);
+}
+
+EContactMap *
+e_contact_map_window_get_map (EContactMapWindow *window)
+{
+ g_return_val_if_fail (E_IS_CONTACT_MAP_WINDOW (window), NULL);
+
+ return window->priv->map;
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-map-window.h b/addressbook/gui/widgets/e-contact-map-window.h
new file mode 100644
index 0000000000..aa7bff4208
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map-window.h
@@ -0,0 +1,81 @@
+/*
+ * e-contact-map-window.h
+ *
+ * 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/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MAP_WINDOW_H
+#define E_CONTACT_MAP_WINDOW_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <gtk/gtk.h>
+
+#include <libebook/libebook.h>
+
+#include "e-contact-map.h"
+
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_MAP_WINDOW \
+ (e_contact_map_window_get_type ())
+#define E_CONTACT_MAP_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindow))
+#define E_CONTACT_MAP_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass))
+#define E_IS_CONTACT_MAP_WINDOW(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW))
+#define E_IS_CONTACT_MAP_WINDOW_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_MAP_WINDOW))
+#define E_CONTACT_MAP_WINDOW_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_MAP_WINDOW, EContactMapWindowClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EContactMapWindow EContactMapWindow;
+typedef struct _EContactMapWindowClass EContactMapWindowClass;
+typedef struct _EContactMapWindowPrivate EContactMapWindowPrivate;
+
+struct _EContactMapWindow {
+ GtkWindow parent;
+ EContactMapWindowPrivate *priv;
+};
+
+struct _EContactMapWindowClass {
+ GtkWindowClass parent_class;
+
+ void (*show_contact_editor) (EContactMapWindow *window,
+ const gchar *contact_uid);
+};
+
+GType e_contact_map_window_get_type (void) G_GNUC_CONST;
+EContactMapWindow * e_contact_map_window_new (void);
+
+void e_contact_map_window_load_addressbook (EContactMapWindow *window,
+ EBookClient *book);
+
+EContactMap * e_contact_map_window_get_map (EContactMapWindow *window);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif /* E_CONTACT_MAP_WINDOW_H */
diff --git a/addressbook/gui/widgets/e-contact-map.c b/addressbook/gui/widgets/e-contact-map.c
new file mode 100644
index 0000000000..57e7e55b97
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map.c
@@ -0,0 +1,408 @@
+/*
+ * e-contact-map.c
+ *
+ * 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/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-map.h"
+
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+#include <geoclue/geoclue-address.h>
+#include <geoclue/geoclue-position.h>
+#include <geocode-glib.h>
+
+#include <clutter/clutter.h>
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <math.h>
+
+#include "e-util/e-util.h"
+
+#include "e-contact-marker.h"
+
+#define E_CONTACT_MAP_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMapPrivate))
+
+typedef struct _AsyncContext AsyncContext;
+
+struct _EContactMapPrivate {
+ GHashTable *markers; /* Hash table contact-name -> marker */
+
+ ChamplainMarkerLayer *marker_layer;
+};
+
+struct _AsyncContext {
+ EContactMap *map;
+ EContactMarker *marker;
+};
+
+enum {
+ CONTACT_ADDED,
+ CONTACT_REMOVED,
+ GEOCODING_STARTED,
+ GEOCODING_FAILED,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+G_DEFINE_TYPE (EContactMap, e_contact_map, GTK_CHAMPLAIN_TYPE_EMBED)
+
+static void
+async_context_free (AsyncContext *async_context)
+{
+ if (async_context->map != NULL)
+ g_object_unref (async_context->map);
+
+ g_slice_free (AsyncContext, async_context);
+}
+
+static void
+contact_map_address_resolved_cb (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GHashTable *resolved = NULL;
+ gpointer marker_ptr;
+ const gchar *name;
+ gdouble latitude, longitude;
+ AsyncContext *async_context = user_data;
+ ChamplainMarkerLayer *marker_layer;
+ ChamplainMarker *marker;
+ GError *error = NULL;
+
+ g_return_if_fail (async_context != NULL);
+ g_return_if_fail (E_IS_CONTACT_MAP (async_context->map));
+ g_return_if_fail (E_IS_CONTACT_MARKER (async_context->marker));
+
+ marker = CHAMPLAIN_MARKER (async_context->marker);
+ marker_layer = async_context->map->priv->marker_layer;
+
+ /* If the marker_layer does not exist anymore, the map has
+ * probably been destroyed before this callback was launched.
+ * It's not a failure, just silently clean up what was left
+ * behind and pretend nothing happened. */
+
+ if (!CHAMPLAIN_IS_MARKER_LAYER (marker_layer))
+ goto exit;
+
+ resolved = geocode_object_resolve_finish (
+ GEOCODE_OBJECT (source), result, &error);
+
+ if (resolved == NULL ||
+ !geocode_object_get_coords (resolved, &longitude, &latitude)) {
+ const gchar *name;
+ if (error)
+ g_error_free (error);
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+ g_signal_emit (
+ async_context->map,
+ signals[GEOCODING_FAILED], 0, name);
+ goto exit;
+ }
+
+ /* Move the marker to resolved position */
+ champlain_location_set_location (
+ CHAMPLAIN_LOCATION (marker), latitude, longitude);
+ champlain_marker_layer_add_marker (marker_layer, marker);
+ champlain_marker_set_selected (marker, FALSE);
+
+ /* Store the marker in the hash table. Use it's label as key */
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+ marker_ptr = g_hash_table_lookup (
+ async_context->map->priv->markers, name);
+ if (marker_ptr != NULL) {
+ g_hash_table_remove (async_context->map->priv->markers, name);
+ champlain_marker_layer_remove_marker (marker_layer, marker_ptr);
+ }
+ g_hash_table_insert (
+ async_context->map->priv->markers,
+ g_strdup (name), marker);
+
+ g_signal_emit (
+ async_context->map,
+ signals[CONTACT_ADDED], 0, marker);
+
+exit:
+ async_context_free (async_context);
+
+ if (resolved != NULL)
+ g_hash_table_unref (resolved);
+}
+
+static void
+resolve_marker_position (EContactMap *map,
+ EContactMarker *marker,
+ EContactAddress *address)
+{
+ GeocodeObject *geocoder;
+ AsyncContext *async_context;
+ const gchar *key;
+
+ g_return_if_fail (E_IS_CONTACT_MAP (map));
+ g_return_if_fail (address != NULL);
+
+ geocoder = geocode_object_new ();
+
+ key = GEOCODE_OBJECT_FIELD_POSTAL;
+ geocode_object_add (geocoder, key, address->code);
+
+ key = GEOCODE_OBJECT_FIELD_COUNTRY;
+ geocode_object_add (geocoder, key, address->country);
+
+ key = GEOCODE_OBJECT_FIELD_STATE;
+ geocode_object_add (geocoder, key, address->region);
+
+ key = GEOCODE_OBJECT_FIELD_CITY;
+ geocode_object_add (geocoder, key, address->locality);
+
+ key = GEOCODE_OBJECT_FIELD_STREET;
+ geocode_object_add (geocoder, key, address->street);
+
+ async_context = g_slice_new0 (AsyncContext);
+ async_context->map = g_object_ref (map);
+ async_context->marker = marker;
+
+ geocode_object_resolve_async (
+ geocoder, NULL,
+ contact_map_address_resolved_cb,
+ async_context);
+
+ g_object_unref (geocoder);
+
+ g_signal_emit (map, signals[GEOCODING_STARTED], 0, marker);
+}
+
+static void
+contact_map_finalize (GObject *object)
+{
+ EContactMapPrivate *priv;
+
+ priv = E_CONTACT_MAP (object)->priv;
+
+ if (priv->markers) {
+ g_hash_table_destroy (priv->markers);
+ priv->markers = NULL;
+ }
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_contact_map_parent_class)->finalize (object);
+}
+
+static void
+e_contact_map_class_init (EContactMapClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EContactMapPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = contact_map_finalize;
+
+ signals[CONTACT_ADDED] = g_signal_new (
+ "contact-added",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, contact_added),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[CONTACT_REMOVED] = g_signal_new (
+ "contact-removed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, contact_removed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+
+ signals[GEOCODING_STARTED] = g_signal_new (
+ "geocoding-started",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, geocoding_started),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, G_TYPE_OBJECT);
+
+ signals[GEOCODING_FAILED] = g_signal_new (
+ "geocoding-failed",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMapClass, geocoding_failed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__STRING,
+ G_TYPE_NONE, 1, G_TYPE_STRING);
+}
+
+static void
+e_contact_map_init (EContactMap *map)
+{
+ GHashTable *hash_table;
+ ChamplainMarkerLayer *layer;
+ ChamplainView *view;
+
+ map->priv = E_CONTACT_MAP_GET_PRIVATE (map);
+
+ hash_table = g_hash_table_new_full (
+ g_str_hash, g_str_equal,
+ (GDestroyNotify) g_free, NULL);
+
+ map->priv->markers = hash_table;
+
+ view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+ /* This feature is somehow broken sometimes, so disable it for now */
+ champlain_view_set_zoom_on_double_click (view, FALSE);
+ layer = champlain_marker_layer_new_full (CHAMPLAIN_SELECTION_SINGLE);
+ champlain_view_add_layer (view, CHAMPLAIN_LAYER (layer));
+ map->priv->marker_layer = layer;
+}
+
+GtkWidget *
+e_contact_map_new (void)
+{
+ return g_object_new (
+ E_TYPE_CONTACT_MAP,NULL);
+}
+
+void
+e_contact_map_add_contact (EContactMap *map,
+ EContact *contact)
+{
+ EContactAddress *address;
+ EContactPhoto *photo;
+ const gchar *contact_uid;
+ gchar *name;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (contact && E_IS_CONTACT (contact));
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
+
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ if (address) {
+ name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Home"), ")", NULL);
+ e_contact_map_add_marker (map, name, contact_uid, address, photo);
+ g_free (name);
+ e_contact_address_free (address);
+ }
+
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ if (address) {
+ name = g_strconcat (e_contact_get_const (contact, E_CONTACT_FILE_AS), " (", _("Work"), ")", NULL);
+ e_contact_map_add_marker (map, name, contact_uid, address, photo);
+ g_free (name);
+ e_contact_address_free (address);
+ }
+
+ if (photo)
+ e_contact_photo_free (photo);
+}
+
+void
+e_contact_map_add_marker (EContactMap *map,
+ const gchar *name,
+ const gchar *contact_uid,
+ EContactAddress *address,
+ EContactPhoto *photo)
+{
+ EContactMarker *marker;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (name && *name);
+ g_return_if_fail (contact_uid && *contact_uid);
+ g_return_if_fail (address);
+
+ marker = E_CONTACT_MARKER (e_contact_marker_new (name, contact_uid, photo));
+
+ resolve_marker_position (map, marker, address);
+}
+
+/**
+ * The \name parameter must match the label of the
+ * marker (for example "John Smith (work)")
+ */
+void
+e_contact_map_remove_contact (EContactMap *map,
+ const gchar *name)
+{
+ ChamplainMarker *marker;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (name && *name);
+
+ marker = g_hash_table_lookup (map->priv->markers, name);
+
+ champlain_marker_layer_remove_marker (map->priv->marker_layer, marker);
+
+ g_hash_table_remove (map->priv->markers, name);
+
+ g_signal_emit (map, signals[CONTACT_REMOVED], 0, name);
+}
+
+void
+e_contact_map_remove_marker (EContactMap *map,
+ ClutterActor *marker)
+{
+ const gchar *name;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
+
+ name = champlain_label_get_text (CHAMPLAIN_LABEL (marker));
+
+ e_contact_map_remove_contact (map, name);
+}
+
+void
+e_contact_map_zoom_on_marker (EContactMap *map,
+ ClutterActor *marker)
+{
+ ChamplainView *view;
+ gdouble lat, lng;
+
+ g_return_if_fail (map && E_IS_CONTACT_MAP (map));
+ g_return_if_fail (marker && CLUTTER_IS_ACTOR (marker));
+
+ lat = champlain_location_get_latitude (CHAMPLAIN_LOCATION (marker));
+ lng = champlain_location_get_longitude (CHAMPLAIN_LOCATION (marker));
+
+ view = gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+
+ champlain_view_center_on (view, lat, lng);
+ champlain_view_set_zoom_level (view, 15);
+}
+
+ChamplainView *
+e_contact_map_get_view (EContactMap *map)
+{
+ g_return_val_if_fail (E_IS_CONTACT_MAP (map), NULL);
+
+ return gtk_champlain_embed_get_view (GTK_CHAMPLAIN_EMBED (map));
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-map.h b/addressbook/gui/widgets/e-contact-map.h
new file mode 100644
index 0000000000..d9503e2c9b
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-map.h
@@ -0,0 +1,106 @@
+/*
+ * e-contact-map.h
+ *
+ * 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/>
+ *
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MAP_H
+#define E_CONTACT_MAP_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <gtk/gtk.h>
+
+#include <champlain/champlain.h>
+#include <champlain-gtk/champlain-gtk.h>
+
+#include <libebook/libebook.h>
+
+/* Standard GObject macros */
+#define E_TYPE_CONTACT_MAP \
+ (e_contact_map_get_type ())
+#define E_CONTACT_MAP(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMap))
+#define E_CONTACT_MAP_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_CONTACT_MAP, EContactMapClass))
+#define E_IS_CONTACT_MAP(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_CONTACT_MAP))
+#define E_IS_CONTACT_MAP_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), E_TYPE_CONTACT_MAP))
+#define E_CONTACT_MAP_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_CONTACT_MAP, EContactMapClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EContactMap EContactMap;
+typedef struct _EContactMapClass EContactMapClass;
+typedef struct _EContactMapPrivate EContactMapPrivate;
+
+struct _EContactMap {
+ GtkChamplainEmbed parent;
+ EContactMapPrivate *priv;
+};
+
+struct _EContactMapClass {
+ GtkWindowClass parent_class;
+
+ void (*contact_added) (EContactMap *map,
+ ClutterActor *marker);
+
+ void (*contact_removed) (EContactMap *map,
+ const gchar *name);
+
+ void (*geocoding_started) (EContactMap *map,
+ ClutterActor *marker);
+
+ void (*geocoding_failed) (EContactMap *map,
+ const gchar *name);
+};
+
+GType e_contact_map_get_type (void) G_GNUC_CONST;
+GtkWidget * e_contact_map_new (void);
+
+void e_contact_map_add_contact (EContactMap *map,
+ EContact *contact);
+
+void e_contact_map_add_marker (EContactMap *map,
+ const gchar *name,
+ const gchar *contact_uid,
+ EContactAddress *address,
+ EContactPhoto *photo);
+
+void e_contact_map_remove_contact (EContactMap *map,
+ const gchar *name);
+
+void e_contact_map_remove_marker (EContactMap *map,
+ ClutterActor *marker);
+
+void e_contact_map_zoom_on_marker (EContactMap *map,
+ ClutterActor *marker);
+
+ChamplainView * e_contact_map_get_view (EContactMap *map);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif
diff --git a/addressbook/gui/widgets/e-contact-marker.c b/addressbook/gui/widgets/e-contact-marker.c
new file mode 100644
index 0000000000..9ac9417c9f
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-marker.c
@@ -0,0 +1,624 @@
+/*
+ * e-contact-marker.c
+ *
+ * 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/>
+ *
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ * Copyright (C) 2011 Jiri Techet <techet@gmail.com>
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef WITH_CONTACT_MAPS
+
+#include "e-contact-marker.h"
+
+#include <champlain/champlain.h>
+#include <gtk/gtk.h>
+#include <clutter/clutter.h>
+#include <glib.h>
+#include <glib/gi18n.h>
+#include <glib-object.h>
+#include <cairo.h>
+#include <math.h>
+#include <string.h>
+
+#define E_CONTACT_MARKER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerPrivate))
+
+G_DEFINE_TYPE (EContactMarker, e_contact_marker, CHAMPLAIN_TYPE_LABEL);
+
+struct _EContactMarkerPrivate
+{
+ gchar *contact_uid;
+
+ ClutterActor *image;
+ ClutterActor *text_actor;
+
+ ClutterActor *shadow;
+ ClutterActor *background;
+
+ guint total_width;
+ guint total_height;
+
+ ClutterGroup *content_group;
+
+ guint redraw_id;
+};
+
+enum {
+ DOUBLE_CLICKED,
+ LAST_SIGNAL
+};
+
+static gint signals[LAST_SIGNAL] = {0};
+
+#define DEFAULT_FONT_NAME "Serif 9"
+
+static ClutterColor DEFAULT_COLOR = { 0x33, 0x33, 0x33, 0xff };
+
+#define RADIUS 10
+#define PADDING (RADIUS / 2)
+
+static gboolean
+contact_marker_clicked_cb (ClutterActor *actor,
+ ClutterEvent *event,
+ gpointer user_data)
+{
+ gint click_count = clutter_event_get_click_count (event);
+
+ if (click_count == 2)
+ g_signal_emit (E_CONTACT_MARKER (actor), signals[DOUBLE_CLICKED], 0);
+
+ return TRUE;
+}
+
+static ClutterActor *
+texture_new_from_pixbuf (GdkPixbuf *pixbuf,
+ GError **error)
+{
+ ClutterActor *texture = NULL;
+ const guchar *data;
+ gboolean has_alpha, success;
+ gint width, height, rowstride;
+ ClutterTextureFlags flags = 0;
+
+ data = gdk_pixbuf_get_pixels (pixbuf);
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ texture = clutter_texture_new ();
+ success = clutter_texture_set_from_rgb_data (
+ CLUTTER_TEXTURE (texture),
+ data, has_alpha, width, height, rowstride,
+ (has_alpha ? 4: 3), flags, NULL);
+
+ if (!success) {
+ clutter_actor_destroy (CLUTTER_ACTOR (texture));
+ texture = NULL;
+ }
+
+ return texture;
+}
+
+static ClutterActor *
+contact_photo_to_texture (EContactPhoto *photo)
+{
+ GdkPixbuf *pixbuf;
+
+ if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ GError *error = NULL;
+
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ 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)
+ g_object_ref (pixbuf);
+ g_object_unref (loader);
+
+ if (error) {
+ g_error_free (error);
+ return NULL;
+ }
+ } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI) {
+ GError *error = NULL;
+
+ pixbuf = gdk_pixbuf_new_from_file (photo->data.uri, &error);
+
+ if (error) {
+ g_error_free (error);
+ return NULL;
+ }
+ } else
+ return NULL;
+
+ if (pixbuf) {
+ ClutterActor *texture;
+ GError *error = NULL;
+
+ texture = texture_new_from_pixbuf (pixbuf, &error);
+ if (error) {
+ g_error_free (error);
+ g_object_unref (pixbuf);
+ return NULL;
+ }
+
+ g_object_unref (pixbuf);
+ return texture;
+ }
+
+ return NULL;
+}
+
+static void
+draw_box (cairo_t *cr,
+ gint width,
+ gint height,
+ gint point)
+{
+ cairo_move_to (cr, RADIUS, 0);
+ cairo_line_to (cr, width - RADIUS, 0);
+ cairo_arc (cr, width - RADIUS, RADIUS, RADIUS - 1, 3 * M_PI / 2.0, 0);
+ cairo_line_to (cr, width, height - RADIUS);
+ cairo_arc (cr, width - RADIUS, height - RADIUS, RADIUS - 1, 0, M_PI / 2.0);
+ cairo_line_to (cr, point, height);
+ cairo_line_to (cr, 0, height + point);
+ cairo_arc (cr, RADIUS, RADIUS, RADIUS - 1, M_PI, 3 * M_PI / 2.0);
+ cairo_close_path (cr);
+}
+
+static void
+draw_shadow (EContactMarker *marker,
+ gint width,
+ gint height,
+ gint point)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ClutterActor *shadow = NULL;
+ cairo_t *cr;
+ gdouble slope;
+ gdouble scaling;
+ gint x;
+ cairo_matrix_t matrix;
+
+ slope = -0.3;
+ scaling = 0.65;
+ x = -40 * slope;
+
+ shadow = clutter_cairo_texture_new (width + x, (height + point));
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (shadow));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ cairo_matrix_init (&matrix, 1, 0, slope, scaling, x, 0);
+ cairo_set_matrix (cr, &matrix);
+
+ draw_box (cr, width, height, point);
+
+ cairo_set_source_rgba (cr, 0, 0, 0, 0.15);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
+
+ clutter_actor_set_position (shadow, 0, height / 2.0);
+
+ clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), shadow);
+
+ if (priv->shadow != NULL) {
+ clutter_container_remove_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->shadow);
+ }
+
+ priv->shadow = shadow;
+}
+
+static void
+draw_background (EContactMarker *marker,
+ gint width,
+ gint height,
+ gint point)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ClutterActor *bg = NULL;
+ const ClutterColor *color;
+ ClutterColor darker_color;
+ cairo_t *cr;
+
+ bg = clutter_cairo_texture_new (width, height + point);
+ cr = clutter_cairo_texture_create (CLUTTER_CAIRO_TEXTURE (bg));
+
+ cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (cr);
+ cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
+
+ /* If selected, add the selection color to the marker's color */
+ if (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)))
+ color = champlain_marker_get_selection_color ();
+ else
+ color = &DEFAULT_COLOR;
+
+ draw_box (cr, width, height, point);
+
+ clutter_color_darken (color, &darker_color);
+
+ cairo_set_source_rgba (
+ cr,
+ color->red / 255.0,
+ color->green / 255.0,
+ color->blue / 255.0,
+ color->alpha / 255.0);
+ cairo_fill_preserve (cr);
+
+ cairo_set_line_width (cr, 1.0);
+ cairo_set_source_rgba (
+ cr,
+ darker_color.red / 255.0,
+ darker_color.green / 255.0,
+ darker_color.blue / 255.0,
+ darker_color.alpha / 255.0);
+ cairo_stroke (cr);
+ cairo_destroy (cr);
+
+ clutter_container_add_actor (CLUTTER_CONTAINER (priv->content_group), bg);
+
+ if (priv->background != NULL) {
+ clutter_container_remove_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->background);
+ }
+
+ priv->background = bg;
+}
+
+static void
+draw_marker (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+ ChamplainLabel *label = CHAMPLAIN_LABEL (marker);
+ guint height = 0, point = 0;
+ guint total_width = 0, total_height = 0;
+ ClutterText *text;
+
+ if (priv->image) {
+ clutter_actor_set_position (priv->image, 2 *PADDING, 2 *PADDING);
+ if (clutter_actor_get_parent (priv->image) == NULL)
+ clutter_container_add_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->image);
+ }
+
+ if (priv->text_actor == NULL) {
+ priv->text_actor = clutter_text_new_with_text (
+ "Serif 8",
+ champlain_label_get_text (label));
+ champlain_label_set_font_name (label, "Serif 8");
+ }
+
+ text = CLUTTER_TEXT (priv->text_actor);
+ clutter_text_set_text (
+ text,
+ champlain_label_get_text (label));
+ clutter_text_set_font_name (
+ text,
+ champlain_label_get_font_name (label));
+ clutter_text_set_line_alignment (text, PANGO_ALIGN_CENTER);
+ clutter_text_set_line_wrap (text, TRUE);
+ clutter_text_set_line_wrap_mode (text, PANGO_WRAP_WORD);
+ clutter_text_set_ellipsize (
+ text,
+ champlain_label_get_ellipsize (label));
+ clutter_text_set_attributes (
+ text,
+ champlain_label_get_attributes (label));
+ clutter_text_set_use_markup (
+ text,
+ champlain_label_get_use_markup (label));
+
+ if (priv->image) {
+ clutter_actor_set_width (
+ priv->text_actor,
+ clutter_actor_get_width (priv->image));
+ total_height = clutter_actor_get_height (priv->image) + 2 *PADDING +
+ clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
+ total_width = clutter_actor_get_width (priv->image) + 4 *PADDING;
+ clutter_actor_set_position (
+ priv->text_actor, PADDING,
+ clutter_actor_get_height (priv->image) + 2 *PADDING + 3);
+ } else {
+ total_height = clutter_actor_get_height (priv->text_actor) + 2 *PADDING;
+ total_width = clutter_actor_get_width (priv->text_actor) + 4 *PADDING;
+ clutter_actor_set_position (priv->text_actor, 2 * PADDING, PADDING);
+ }
+
+ height += 2 * PADDING;
+ if (height > total_height)
+ total_height = height;
+
+ clutter_text_set_color (
+ CLUTTER_TEXT (priv->text_actor),
+ (champlain_marker_get_selected (CHAMPLAIN_MARKER (marker)) ?
+ champlain_marker_get_selection_text_color () :
+ champlain_label_get_text_color (CHAMPLAIN_LABEL (marker))));
+ if (clutter_actor_get_parent (priv->text_actor) == NULL)
+ clutter_container_add_actor (
+ CLUTTER_CONTAINER (priv->content_group),
+ priv->text_actor);
+
+ if (priv->text_actor == NULL && priv->image == NULL) {
+ total_width = 6 * PADDING;
+ total_height = 6 * PADDING;
+ }
+
+ point = (total_height + 2 * PADDING) / 4.0;
+ priv->total_width = total_width;
+ priv->total_height = total_height;
+
+ draw_shadow (marker, total_width, total_height, point);
+ draw_background (marker, total_width, total_height, point);
+
+ if (priv->text_actor != NULL && priv->background != NULL)
+ clutter_actor_raise (priv->text_actor, priv->background);
+ if (priv->image != NULL && priv->background != NULL)
+ clutter_actor_raise (priv->image, priv->background);
+
+ clutter_actor_set_anchor_point (CLUTTER_ACTOR (marker), 0, total_height + point);
+}
+
+static gboolean
+redraw_on_idle (gpointer gobject)
+{
+ EContactMarker *marker = E_CONTACT_MARKER (gobject);
+
+ draw_marker (marker);
+ marker->priv->redraw_id = 0;
+ return FALSE;
+}
+
+static void
+queue_redraw (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv = marker->priv;
+
+ if (!priv->redraw_id) {
+ priv->redraw_id = g_idle_add_full (
+ G_PRIORITY_DEFAULT,
+ (GSourceFunc) redraw_on_idle,
+ g_object_ref (marker),
+ (GDestroyNotify) g_object_unref);
+ }
+}
+
+static void
+allocate (ClutterActor *self,
+ const ClutterActorBox *box,
+ ClutterAllocationFlags flags)
+{
+ ClutterActorBox child_box;
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->allocate (self, box, flags);
+
+ child_box.x1 = 0;
+ child_box.x2 = box->x2 - box->x1;
+ child_box.y1 = 0;
+ child_box.y2 = box->y2 - box->y1;
+ clutter_actor_allocate (CLUTTER_ACTOR (priv->content_group), &child_box, flags);
+}
+
+static void
+paint (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ clutter_actor_paint (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+map (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->map (self);
+
+ clutter_actor_map (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+unmap (ClutterActor *self)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+
+ CLUTTER_ACTOR_CLASS (e_contact_marker_parent_class)->unmap (self);
+
+ clutter_actor_unmap (CLUTTER_ACTOR (priv->content_group));
+}
+
+static void
+pick (ClutterActor *self,
+ const ClutterColor *color)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (self)->priv;
+ gfloat width, height;
+
+ if (!clutter_actor_should_pick_paint (self))
+ return;
+
+ width = priv->total_width;
+ height = priv->total_height;
+
+ cogl_path_new ();
+
+ cogl_set_source_color4ub (
+ color->red,
+ color->green,
+ color->blue,
+ color->alpha);
+
+ cogl_path_move_to (RADIUS, 0);
+ cogl_path_line_to (width - RADIUS, 0);
+ cogl_path_arc (width - RADIUS, RADIUS, RADIUS, RADIUS, -90, 0);
+ cogl_path_line_to (width, height - RADIUS);
+ cogl_path_arc (width - RADIUS, height - RADIUS, RADIUS, RADIUS, 0, 90);
+ cogl_path_line_to (RADIUS, height);
+ cogl_path_arc (RADIUS, height - RADIUS, RADIUS, RADIUS, 90, 180);
+ cogl_path_line_to (0, RADIUS);
+ cogl_path_arc (RADIUS, RADIUS, RADIUS, RADIUS, 180, 270);
+ cogl_path_close ();
+ cogl_path_fill ();
+}
+
+static void
+notify_selected (GObject *gobject,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ G_GNUC_UNUSED gpointer user_data)
+{
+ queue_redraw (E_CONTACT_MARKER (gobject));
+}
+
+static void
+e_contact_marker_finalize (GObject *object)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
+
+ if (priv->contact_uid) {
+ g_free (priv->contact_uid);
+ priv->contact_uid = NULL;
+ }
+
+ if (priv->redraw_id) {
+ g_source_remove (priv->redraw_id);
+ priv->redraw_id = 0;
+ }
+
+ G_OBJECT_CLASS (e_contact_marker_parent_class)->finalize (object);
+}
+
+static void
+e_contact_marker_dispose (GObject *object)
+{
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (object)->priv;
+
+ priv->background = NULL;
+ priv->shadow = NULL;
+ priv->text_actor = NULL;
+
+ if (priv->content_group) {
+ clutter_actor_unparent (CLUTTER_ACTOR (priv->content_group));
+ priv->content_group = NULL;
+ }
+
+ G_OBJECT_CLASS (e_contact_marker_parent_class)->dispose (object);
+}
+
+static void
+e_contact_marker_class_init (EContactMarkerClass *class)
+{
+ ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (class);
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ g_type_class_add_private (class, sizeof (EContactMarkerPrivate));
+
+ object_class->dispose = e_contact_marker_dispose;
+ object_class->finalize = e_contact_marker_finalize;
+
+ actor_class->paint = paint;
+ actor_class->allocate = allocate;
+ actor_class->map = map;
+ actor_class->unmap = unmap;
+ actor_class->pick = pick;
+
+ signals[DOUBLE_CLICKED] = g_signal_new (
+ "double-clicked",
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EContactMarkerClass, double_clicked),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+}
+
+static void
+e_contact_marker_init (EContactMarker *marker)
+{
+ EContactMarkerPrivate *priv;
+
+ priv = E_CONTACT_MARKER_GET_PRIVATE (marker);
+
+ marker->priv = priv;
+ priv->contact_uid = NULL;
+ priv->image = NULL;
+ priv->background = NULL;
+ priv->shadow = NULL;
+ priv->text_actor = NULL;
+ priv->content_group = CLUTTER_GROUP (clutter_group_new ());
+ priv->redraw_id = 0;
+
+ clutter_actor_set_parent (
+ CLUTTER_ACTOR (priv->content_group), CLUTTER_ACTOR (marker));
+ clutter_actor_queue_relayout (CLUTTER_ACTOR (marker));
+
+ priv->total_width = 0;
+ priv->total_height = 0;
+
+ g_signal_connect (
+ marker, "notify::selected",
+ G_CALLBACK (notify_selected), NULL);
+ g_signal_connect (
+ marker, "button-release-event",
+ G_CALLBACK (contact_marker_clicked_cb), NULL);
+}
+
+ClutterActor *
+e_contact_marker_new (const gchar *name,
+ const gchar *contact_uid,
+ EContactPhoto *photo)
+{
+ ClutterActor *marker = CLUTTER_ACTOR (g_object_new (E_TYPE_CONTACT_MARKER, NULL));
+ EContactMarkerPrivate *priv = E_CONTACT_MARKER (marker)->priv;
+
+ g_return_val_if_fail (name && *name, NULL);
+ g_return_val_if_fail (contact_uid && *contact_uid, NULL);
+
+ champlain_label_set_text (CHAMPLAIN_LABEL (marker), name);
+ priv->contact_uid = g_strdup (contact_uid);
+ if (photo)
+ priv->image = contact_photo_to_texture (photo);
+
+ queue_redraw (E_CONTACT_MARKER (marker));
+
+ return marker;
+}
+
+const gchar *
+e_contact_marker_get_contact_uid (EContactMarker *marker)
+{
+ g_return_val_if_fail (marker && E_IS_CONTACT_MARKER (marker), NULL);
+
+ return marker->priv->contact_uid;
+}
+
+#endif /* WITH_CONTACT_MAPS */
diff --git a/addressbook/gui/widgets/e-contact-marker.h b/addressbook/gui/widgets/e-contact-marker.h
new file mode 100644
index 0000000000..791a9c46b5
--- /dev/null
+++ b/addressbook/gui/widgets/e-contact-marker.h
@@ -0,0 +1,84 @@
+/*
+ * e-contact-marker.h
+ *
+ * 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/>
+ *
+ * Copyright (C) 2008 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
+ * Copyright (C) 2011 Jiri Techet <techet@gmail.com>
+ * Copyright (C) 2011 Dan Vratil <dvratil@redhat.com>
+ *
+ */
+
+#ifndef E_CONTACT_MARKER_H
+#define E_CONTACT_MARKER_H
+
+#ifdef WITH_CONTACT_MAPS
+
+#include <libebook/libebook.h>
+
+#include <champlain/champlain.h>
+
+#include <glib-object.h>
+#include <clutter/clutter.h>
+
+G_BEGIN_DECLS
+
+#define E_TYPE_CONTACT_MARKER e_contact_marker_get_type ()
+
+#define E_CONTACT_MARKER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CONTACT_MARKER, EContactMarker))
+
+#define E_CONTACT_MARKER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
+
+#define E_IS_CONTACT_MARKER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CONTACT_MARKER))
+
+#define E_IS_CONTACT_MARKER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CONTACT_MARKER))
+
+#define E_CONTACT_MARKER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CONTACT_MARKER, EContactMarkerClass))
+
+typedef struct _EContactMarkerPrivate EContactMarkerPrivate;
+
+typedef struct _EContactMarker EContactMarker;
+typedef struct _EContactMarkerClass EContactMarkerClass;
+
+struct _EContactMarker
+{
+ ChamplainLabel parent;
+ EContactMarkerPrivate *priv;
+};
+
+struct _EContactMarkerClass
+{
+ ChamplainLabelClass parent_class;
+
+ void (*double_clicked) (ClutterActor *actor);
+};
+
+GType e_contact_marker_get_type (void);
+
+ClutterActor * e_contact_marker_new (const gchar *name,
+ const gchar *contact_uid,
+ EContactPhoto *photo);
+
+const gchar * e_contact_marker_get_contact_uid (EContactMarker *marker);
+
+G_END_DECLS
+
+#endif /* WITH_CONTACT_MAPS */
+
+#endif
diff --git a/addressbook/gui/widgets/e-minicard-control.c b/addressbook/gui/widgets/e-minicard-control.c
deleted file mode 100644
index 73417af78c..0000000000
--- a/addressbook/gui/widgets/e-minicard-control.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-control.c
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * Copyright 1999, 2000, Ximian, Inc.
- */
-
-#include <config.h>
-
-#include <bonobo/bonobo-generic-factory.h>
-#include <bonobo/bonobo-persist.h>
-#include <bonobo/bonobo-persist-stream.h>
-#include <bonobo/bonobo-stream-client.h>
-#include <addressbook/backend/ebook/e-book.h>
-#include <addressbook/backend/ebook/e-book-util.h>
-#include <addressbook/backend/ebook/e-card.h>
-#include <gal/util/e-util.h>
-
-#include <addressbook/gui/component/addressbook.h>
-
-#include "e-minicard-control.h"
-#include "e-minicard-widget.h"
-#include "e-card-merging.h"
-
-typedef struct {
- EMinicardWidget *minicard;
- GList *card_list;
- GtkWidget *label;
-} EMinicardControl;
-
-#if 0
-enum {
- PROP_RUNNING
-} MyArgs;
-
-#define RUNNING_KEY "Clock::Running"
-
-static void
-get_prop (BonoboPropertyBag *bag,
- BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GtkObject *clock = user_data;
-
- switch (arg_id) {
-
- case PROP_RUNNING:
- {
- gboolean b = GPOINTER_TO_UINT (gtk_object_get_data (clock, RUNNING_KEY));
- BONOBO_ARG_SET_BOOLEAN (arg, b);
- break;
- }
-
- default:
- g_warning ("Unhandled arg %d", arg_id);
- break;
- }
-}
-
-static void
-set_prop (BonoboPropertyBag *bag,
- const BonoboArg *arg,
- guint arg_id,
- CORBA_Environment *ev,
- gpointer user_data)
-{
- GtkClock *clock = user_data;
-
- switch (arg_id) {
-
- case PROP_RUNNING:
- {
- guint i;
-
- i = BONOBO_ARG_GET_BOOLEAN (arg);
-
- if (i)
- gtk_clock_start (clock);
- else
- gtk_clock_stop (clock);
-
- gtk_object_set_data (GTK_OBJECT (clock), RUNNING_KEY,
- GUINT_TO_POINTER (i));
- break;
- }
-
- default:
- g_warning ("Unhandled arg %d", arg_id);
- break;
- }
-}
-#endif
-
-/*
- * Bonobo::PersistStream
- *
- * These two functions implement the Bonobo::PersistStream load and
- * save methods which allow data to be loaded into and out of the
- * BonoboObject.
- */
-static char *
-stream_read (Bonobo_Stream stream)
-{
- Bonobo_Stream_iobuf *buffer;
- CORBA_Environment ev;
- char *data = NULL;
- gint length = 0;
-
- CORBA_exception_init (&ev);
- do {
-#define READ_CHUNK_SIZE 65536
- Bonobo_Stream_read (stream, READ_CHUNK_SIZE,
- &buffer, &ev);
-
- if (ev._major != CORBA_NO_EXCEPTION) {
- CORBA_exception_free (&ev);
- return NULL;
- }
-
- if (buffer->_length <= 0)
- break;
-
- data = g_realloc (data, length + buffer->_length + 1);
-
- memcpy (data + length, buffer->_buffer, buffer->_length);
-
- length += buffer->_length;
-
- CORBA_free (buffer);
- } while (1);
-
- CORBA_free (buffer);
- CORBA_exception_free (&ev);
-
- if (data)
- data[length] = '\0';
- else
- data = g_strdup("");
-
- return data;
-} /* stream_read */
-
-/*
- * This function implements the Bonobo::PersistStream:load method.
- */
-static void
-pstream_load (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- GList *list;
- char *vcard;
- EMinicardControl *minicard_control = data;
-
- if (type && g_strcasecmp (type, "text/vCard") != 0 &&
- g_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- if ((vcard = stream_read (stream)) == NULL) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_FileNotFound, NULL);
- return;
- }
-
- e_free_object_list (minicard_control->card_list);
- list = e_card_load_cards_from_string_with_default_charset(vcard, "ISO-8859-1");
- g_free(vcard);
- minicard_control->card_list = list;
- if (list)
- gtk_object_set(GTK_OBJECT(minicard_control->minicard),
- "card", list->data,
- NULL);
- if (list && list->next) {
- char *message;
- int length = g_list_length (list) - 1;
- if (length > 1) {
- message = g_strdup_printf (_("and %d other cards."), length);
- } else {
- message = g_strdup_printf (_("and one other card."));
- }
- gtk_label_set_text (GTK_LABEL (minicard_control->label), message);
- g_free (message);
- gtk_widget_show (minicard_control->label);
- } else {
- gtk_widget_hide (minicard_control->label);
- }
-} /* pstream_load */
-
-/*
- * This function implements the Bonobo::PersistStream:save method.
- */
-static void
-pstream_save (BonoboPersistStream *ps, const Bonobo_Stream stream,
- Bonobo_Persist_ContentType type, void *data,
- CORBA_Environment *ev)
-{
- EMinicardControl *minicard_control = data;
- char *vcard;
- int length;
-
- if (type && g_strcasecmp (type, "text/vCard") != 0 &&
- g_strcasecmp (type, "text/x-vCard") != 0) {
- CORBA_exception_set (ev, CORBA_USER_EXCEPTION,
- ex_Bonobo_Persist_WrongDataType, NULL);
- return;
- }
-
- vcard = e_card_list_get_vcard(minicard_control->card_list);
- length = strlen (vcard);
- bonobo_stream_client_write (stream, vcard, length, ev);
- g_free (vcard);
-} /* pstream_save */
-
-static CORBA_long
-pstream_get_max_size (BonoboPersistStream *ps, void *data,
- CORBA_Environment *ev)
-{
- EMinicardControl *minicard_control = data;
- char *vcard;
- gint length;
-
- vcard = e_card_list_get_vcard(minicard_control->card_list);
- length = strlen (vcard);
- g_free (vcard);
-
- return length;
-}
-
-static Bonobo_Persist_ContentTypeList *
-pstream_get_content_types (BonoboPersistStream *ps, void *closure,
- CORBA_Environment *ev)
-{
- return bonobo_persist_generate_content_types (2, "text/vCard", "text/x-vCard");
-}
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- GList *list = closure;
- if (book) {
- GList *p;
- for (p = list; p; p = p->next) {
- e_card_merging_book_add_card(book, p->data, NULL, NULL);
- }
- gtk_object_unref (GTK_OBJECT (book));
- }
- e_free_object_list (list);
-}
-
-static void
-save_in_addressbook(GtkWidget *button, gpointer data)
-{
- EMinicardControl *minicard_control = data;
- GList *list, *p;
- EBook *book;
-
- book = e_book_new ();
-
- list = g_list_copy (minicard_control->card_list);
-
- for (p = list; p; p = p->next)
- gtk_object_ref (GTK_OBJECT (p->data));
-
- if (!addressbook_load_default_book (book, book_open_cb, list)) {
- gtk_object_unref (GTK_OBJECT (book));
- book_open_cb (NULL, E_BOOK_STATUS_OTHER_ERROR, list);
- }
-}
-
-static void
-free_struct (GtkWidget *control, gpointer data)
-{
- EMinicardControl *minicard_control = data;
- e_free_object_list (minicard_control->card_list);
- g_free (minicard_control);
-}
-
-static BonoboObject *
-e_minicard_control_factory (BonoboGenericFactory *Factory, void *closure)
-{
-#if 0
- BonoboPropertyBag *pb;
-#endif
- BonoboControl *control;
- BonoboPersistStream *stream;
- GtkWidget *minicard;
- GtkWidget *button;
- GtkWidget *label;
- GtkWidget *vbox;
-
- EMinicardControl *minicard_control = g_new (EMinicardControl, 1);
-
-
- minicard_control->card_list = NULL;
- minicard_control->minicard = NULL;
- minicard_control->label = NULL;
-
- /* Create the control. */
-
- minicard = e_minicard_widget_new ();
- gtk_widget_show (minicard);
- minicard_control->minicard = E_MINICARD_WIDGET (minicard);
-
- /* This is intentionally not shown. */
- label = gtk_label_new ("");
- minicard_control->label = label;
-
- button = gtk_button_new_with_label(_("Save in addressbook"));
- gtk_signal_connect(GTK_OBJECT(button), "clicked",
- save_in_addressbook, minicard_control);
- gtk_widget_show (button);
-
- vbox = gtk_vbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), minicard, TRUE, TRUE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0);
- gtk_widget_show (vbox);
-
- control = bonobo_control_new (vbox);
-
- gtk_signal_connect (GTK_OBJECT (control), "destroy",
- free_struct, minicard_control);
-
- stream = bonobo_persist_stream_new (pstream_load, pstream_save,
- pstream_get_max_size,
- pstream_get_content_types,
- minicard_control);
-
-#if 0
- /* Create the properties. */
- pb = bonobo_property_bag_new (get_prop, set_prop, clock);
- bonobo_control_set_properties (control, pb);
-
- bonobo_property_bag_add (pb, "running", PROP_RUNNING,
- BONOBO_ARG_BOOLEAN, NULL,
- "Whether or not the clock is running", 0);
-#endif
-
- if (stream == NULL) {
- bonobo_object_unref (BONOBO_OBJECT (control));
- return NULL;
- }
-
- bonobo_object_add_interface (BONOBO_OBJECT (control),
- BONOBO_OBJECT (stream));
-
- return BONOBO_OBJECT (control);
-}
-
-void
-e_minicard_control_factory_init (void)
-{
- static BonoboGenericFactory *factory = NULL;
-
- if (factory != NULL)
- return;
-
- factory =
- bonobo_generic_factory_new (
- "OAFIID:GNOME_Evolution_Addressbook_MiniCard_ControlFactory",
- e_minicard_control_factory, NULL);
-
- if (factory == NULL)
- g_error ("I could not register a EMinicard control factory.");
-}
diff --git a/addressbook/gui/widgets/e-minicard-control.h b/addressbook/gui/widgets/e-minicard-control.h
deleted file mode 100644
index 4a0da88435..0000000000
--- a/addressbook/gui/widgets/e-minicard-control.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __E_MINICARD_CONTROL_H__
-#define __E_MINICARD_CONTROL_H__
-
-#include <bonobo/bonobo-control.h>
-
-void e_minicard_control_factory_init (void);
-
-#endif /* __E_MINICARD_CONTROL_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-label.c b/addressbook/gui/widgets/e-minicard-label.c
index b59ff46ae3..0e75917b80 100644
--- a/addressbook/gui/widgets/e-minicard-label.c
+++ b/addressbook/gui/widgets/e-minicard-label.c
@@ -1,216 +1,286 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-label.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 "e-minicard-label.h"
-#include <gtk/gtksignal.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <gal/util/e-util.h>
-#include <gal/e-text/e-text.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-canvas-utils.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
-static void e_minicard_label_init (EMinicardLabel *card);
-static void e_minicard_label_class_init (EMinicardLabelClass *klass);
-static void e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
+#include <libgnomecanvas/libgnomecanvas.h>
+
+#include "e-util/e-util.h"
+
+static void e_minicard_label_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void e_minicard_label_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
static gboolean e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_label_realize (GnomeCanvasItem *item);
-static void e_minicard_label_unrealize (GnomeCanvasItem *item);
-static void e_minicard_label_reflow(GnomeCanvasItem *item, int flags);
+static void e_minicard_label_reflow (GnomeCanvasItem *item, gint flags);
+static void e_minicard_label_style_set (EMinicardLabel *label, GtkStyle *previous_style);
-static void e_minicard_label_resize_children( EMinicardLabel *e_minicard_label );
+static void e_minicard_label_resize_children (EMinicardLabel *e_minicard_label);
-static GnomeCanvasGroupClass *parent_class = NULL;
+static void set_colors (EMinicardLabel *label);
-/* The arguments we take */
enum {
- ARG_0,
- ARG_WIDTH,
- ARG_HEIGHT,
- ARG_HAS_FOCUS,
- ARG_FIELD,
- ARG_FIELDNAME,
- ARG_TEXT_MODEL,
- ARG_MAX_FIELD_NAME_WIDTH,
- ARG_EDITABLE
+ PROP_0,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_HAS_FOCUS,
+ PROP_FIELD,
+ PROP_FIELDNAME,
+ PROP_TEXT_MODEL,
+ PROP_MAX_FIELD_NAME_WIDTH,
+ PROP_EDITABLE
};
-GtkType
-e_minicard_label_get_type (void)
-{
- static GtkType minicard_label_type = 0;
-
- if (!minicard_label_type)
- {
- static const GtkTypeInfo minicard_label_info =
- {
- "EMinicardLabel",
- sizeof (EMinicardLabel),
- sizeof (EMinicardLabelClass),
- (GtkClassInitFunc) e_minicard_label_class_init,
- (GtkObjectInitFunc) e_minicard_label_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- minicard_label_type = gtk_type_unique (gnome_canvas_group_get_type (), &minicard_label_info);
- }
-
- return minicard_label_type;
-}
+enum {
+ STYLE_SET,
+ LAST_SIGNAL
+};
+
+static guint e_minicard_label_signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (
+ EMinicardLabel,
+ e_minicard_label,
+ GNOME_TYPE_CANVAS_GROUP)
static void
-e_minicard_label_class_init (EMinicardLabelClass *klass)
+e_minicard_label_class_init (EMinicardLabelClass *class)
{
- GtkObjectClass *object_class;
- GnomeCanvasItemClass *item_class;
-
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
-
- parent_class = gtk_type_class (gnome_canvas_group_get_type ());
-
- gtk_object_add_arg_type ("EMinicardLabel::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_WIDTH);
- gtk_object_add_arg_type ("EMinicardLabel::height", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("EMinicardLabel::has_focus", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_FOCUS);
- gtk_object_add_arg_type ("EMinicardLabel::field", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_FIELD);
- gtk_object_add_arg_type ("EMinicardLabel::fieldname", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_FIELDNAME);
- gtk_object_add_arg_type ("EMinicardLabel::text_model", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_TEXT_MODEL);
- gtk_object_add_arg_type ("EMinicardLabel::max_field_name_length", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_MAX_FIELD_NAME_WIDTH);
- gtk_object_add_arg_type ("EMinicardLabel::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- object_class->set_arg = e_minicard_label_set_arg;
- object_class->get_arg = e_minicard_label_get_arg;
- /* object_class->destroy = e_minicard_label_destroy; */
-
- /* GnomeCanvasItem method overrides */
- item_class->realize = e_minicard_label_realize;
- item_class->unrealize = e_minicard_label_unrealize;
- item_class->event = e_minicard_label_event;
+ GObjectClass *object_class;
+ GnomeCanvasItemClass *item_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ item_class = (GnomeCanvasItemClass *) class;
+
+ class->style_set = e_minicard_label_style_set;
+
+ object_class->set_property = e_minicard_label_set_property;
+ object_class->get_property = e_minicard_label_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WIDTH,
+ g_param_spec_double (
+ "width",
+ "Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEIGHT,
+ g_param_spec_double (
+ "height",
+ "Height",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_FOCUS,
+ g_param_spec_boolean (
+ "has_focus",
+ "Has Focus",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FIELD,
+ g_param_spec_string (
+ "field",
+ "Field",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_FIELDNAME,
+ g_param_spec_string (
+ "fieldname",
+ "Field Name",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_TEXT_MODEL,
+ g_param_spec_object (
+ "text_model",
+ "Text Model",
+ NULL,
+ E_TYPE_TEXT_MODEL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MAX_FIELD_NAME_WIDTH,
+ g_param_spec_double (
+ "max_field_name_length",
+ "Max field name length",
+ NULL,
+ -1.0, G_MAXDOUBLE, -1.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ e_minicard_label_signals[STYLE_SET] = g_signal_new (
+ "style_set",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMinicardLabelClass, style_set),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_STYLE);
+
+ /* GnomeCanvasItem method overrides */
+ item_class->realize = e_minicard_label_realize;
+ item_class->event = e_minicard_label_event;
}
static void
e_minicard_label_init (EMinicardLabel *minicard_label)
{
- minicard_label->width = 10;
- minicard_label->height = 10;
- minicard_label->rect = NULL;
- minicard_label->fieldname = NULL;
- minicard_label->field = NULL;
+ minicard_label->width = 10;
+ minicard_label->height = 10;
+ minicard_label->rect = NULL;
+ minicard_label->fieldname = NULL;
+ minicard_label->field = NULL;
- minicard_label->max_field_name_length = -1;
+ minicard_label->max_field_name_length = -1;
- e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard_label), e_minicard_label_reflow);
+ e_canvas_item_set_reflow_callback (
+ GNOME_CANVAS_ITEM (minicard_label),
+ e_minicard_label_reflow);
}
static void
-e_minicard_label_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_label_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GnomeCanvasItem *item;
EMinicardLabel *e_minicard_label;
+ GnomeCanvasItem *item;
+
+ e_minicard_label = E_MINICARD_LABEL (object);
+ item = GNOME_CANVAS_ITEM (object);
- item = GNOME_CANVAS_ITEM (o);
- e_minicard_label = E_MINICARD_LABEL (o);
-
- switch (arg_id){
- case ARG_WIDTH:
- e_minicard_label->width = GTK_VALUE_DOUBLE (*arg);
- e_minicard_label_resize_children(e_minicard_label);
+ switch (property_id) {
+ case PROP_WIDTH:
+ e_minicard_label->width = g_value_get_double (value);
+ e_minicard_label_resize_children (e_minicard_label);
e_canvas_item_request_reflow (item);
break;
- case ARG_HAS_FOCUS:
- if (e_minicard_label->field && (GTK_VALUE_ENUM(*arg) != E_FOCUS_NONE))
- e_canvas_item_grab_focus(e_minicard_label->field, FALSE);
+ case PROP_HAS_FOCUS:
+ if (e_minicard_label->field && (g_value_get_boolean (value) != E_FOCUS_NONE))
+ e_canvas_item_grab_focus (e_minicard_label->field, FALSE);
break;
- case ARG_FIELD:
- gnome_canvas_item_set( e_minicard_label->field, "text", GTK_VALUE_STRING (*arg), NULL );
+ case PROP_FIELD:
+ gnome_canvas_item_set (e_minicard_label->field, "text", g_value_get_string (value), NULL);
break;
- case ARG_FIELDNAME:
- gnome_canvas_item_set( e_minicard_label->fieldname, "text", GTK_VALUE_STRING (*arg), NULL );
+ case PROP_FIELDNAME:
+ gnome_canvas_item_set (e_minicard_label->fieldname, "text", g_value_get_string (value), NULL);
break;
- case ARG_TEXT_MODEL:
- gnome_canvas_item_set( e_minicard_label->field, "model", GTK_VALUE_OBJECT (*arg), NULL);
+ case PROP_TEXT_MODEL:
+ gnome_canvas_item_set (e_minicard_label->field, "model", g_value_get_object (value), NULL);
break;
- case ARG_MAX_FIELD_NAME_WIDTH:
- e_minicard_label->max_field_name_length = GTK_VALUE_DOUBLE (*arg);
+ case PROP_MAX_FIELD_NAME_WIDTH:
+ e_minicard_label->max_field_name_length = g_value_get_double (value);
break;
- case ARG_EDITABLE:
- e_minicard_label->editable = GTK_VALUE_BOOL (*arg);
- gtk_object_set (GTK_OBJECT (e_minicard_label->field), "editable", e_minicard_label->editable, NULL);
+ case PROP_EDITABLE:
+ e_minicard_label->editable = g_value_get_boolean (value);
+ g_object_set (e_minicard_label->field, "editable", FALSE /* e_minicard_label->editable */, NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_label_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardLabel *e_minicard_label;
- char *temp;
- ETextModel *tempmodel;
e_minicard_label = E_MINICARD_LABEL (object);
- switch (arg_id) {
- case ARG_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->width;
+ switch (property_id) {
+ case PROP_WIDTH:
+ g_value_set_double (value, e_minicard_label->width);
break;
- case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->height;
+ case PROP_HEIGHT:
+ g_value_set_double (value, e_minicard_label->height);
break;
- case ARG_HAS_FOCUS:
- GTK_VALUE_ENUM (*arg) = e_minicard_label->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
+ case PROP_HAS_FOCUS:
+ g_value_set_boolean (value, e_minicard_label->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE);
break;
- case ARG_FIELD:
- gtk_object_get( GTK_OBJECT( e_minicard_label->field ), "text", &temp, NULL );
- GTK_VALUE_STRING (*arg) = temp;
+ case PROP_FIELD:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->field),
+ "text", value);
break;
- case ARG_FIELDNAME:
- gtk_object_get( GTK_OBJECT( e_minicard_label->fieldname ), "text", &temp, NULL );
- GTK_VALUE_STRING (*arg) = temp;
+ case PROP_FIELDNAME:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->fieldname),
+ "text", value);
break;
- case ARG_TEXT_MODEL:
- gtk_object_get( GTK_OBJECT( e_minicard_label->field ), "model", &tempmodel, NULL );
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(tempmodel);
+ case PROP_TEXT_MODEL:
+ g_object_get_property (
+ G_OBJECT (e_minicard_label->field),
+ "model", value);
break;
- case ARG_MAX_FIELD_NAME_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard_label->max_field_name_length;
+ case PROP_MAX_FIELD_NAME_WIDTH:
+ g_value_set_double (value, e_minicard_label->max_field_name_length);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_minicard_label->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, e_minicard_label->editable);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
@@ -218,253 +288,241 @@ e_minicard_label_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
static void
e_minicard_label_realize (GnomeCanvasItem *item)
{
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->realize)
- (* GNOME_CANVAS_ITEM_CLASS( parent_class )->realize) (item);
-
- e_canvas_item_request_reflow(item);
-
- if (!item->canvas->aa)
- {
- }
-}
-
-void
-e_minicard_label_construct (GnomeCanvasItem *item)
-{
EMinicardLabel *e_minicard_label;
GnomeCanvasGroup *group;
- GdkFont *font;
-
- font = ((GtkWidget *) item->canvas)->style->font;
e_minicard_label = E_MINICARD_LABEL (item);
- group = GNOME_CANVAS_GROUP( item );
-
- e_minicard_label->rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) e_minicard_label->width - 1,
- "y2", (double) e_minicard_label->height - 1,
- "outline_color", NULL,
- NULL );
- e_minicard_label->fieldname =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "clip_width", (double) ( e_minicard_label->width / 2 - 4 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
- "font_gdk", font,
- "fill_color", "black",
- "draw_background", FALSE,
- NULL );
- e_canvas_item_move_absolute(e_minicard_label->fieldname, 2, 1);
-
- e_minicard_label->field =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "clip_width", (double) ( ( e_minicard_label->width + 1 ) / 2 - 4 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
- "font_gdk", font,
- "fill_color", "black",
- "editable", e_minicard_label->editable,
- "draw_background", FALSE,
- NULL );
- e_canvas_item_move_absolute(e_minicard_label->field, ( e_minicard_label->width / 2 + 2), 1);
-
- e_canvas_item_request_reflow(item);
+ group = GNOME_CANVAS_GROUP (item);
+
+ GNOME_CANVAS_ITEM_CLASS (e_minicard_label_parent_class)->realize (item);
+
+ e_canvas_item_request_reflow (item);
+
+ e_minicard_label->rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 0,
+ "y1", (gdouble) 0,
+ "x2", (gdouble) e_minicard_label->width - 1,
+ "y2", (gdouble) e_minicard_label->height - 1,
+ "outline_color", NULL,
+ NULL);
+
+ e_minicard_label->fieldname = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "clip_width", (gdouble) (e_minicard_label->width / 2 - 4),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color", "black",
+ "im_context", E_CANVAS (item->canvas)->im_context,
+ NULL);
+
+ e_canvas_item_move_absolute (e_minicard_label->fieldname, 2, 1);
+
+ e_minicard_label->field = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "clip_width", (gdouble) ((e_minicard_label->width + 1) / 2 - 4),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color", "black",
+ "editable", FALSE, /* e_minicard_label->editable, */
+ "im_context", E_CANVAS (item->canvas)->im_context,
+ NULL);
+
+ e_canvas_item_move_absolute (
+ e_minicard_label->field,
+ (e_minicard_label->width / 2 + 2), 1);
+
+ set_colors (e_minicard_label);
+
+ e_canvas_item_request_reflow (item);
}
-static void
-e_minicard_label_unrealize (GnomeCanvasItem *item)
+static gboolean
+e_minicard_label_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
- EMinicardLabel *e_minicard_label;
+ EMinicardLabel *e_minicard_label;
+
+ e_minicard_label = E_MINICARD_LABEL (item);
- e_minicard_label = E_MINICARD_LABEL (item);
+ switch (event->type) {
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_KEY_Escape) {
+ GnomeCanvasItem *parent;
- if (!item->canvas->aa)
- {
- }
+ e_text_cancel_editing (E_TEXT (e_minicard_label->field));
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize)
- (* GNOME_CANVAS_ITEM_CLASS( parent_class )->unrealize) (item);
-}
+ parent = GNOME_CANVAS_ITEM (e_minicard_label)->parent;
+ if (parent)
+ e_canvas_item_grab_focus (parent, FALSE);
+ }
+ break;
+ case GDK_FOCUS_CHANGE: {
+ GdkEventFocus *focus_event = (GdkEventFocus *) event;
-static gboolean
-e_minicard_label_event (GnomeCanvasItem *item, GdkEvent *event)
-{
- EMinicardLabel *e_minicard_label;
-
- e_minicard_label = E_MINICARD_LABEL (item);
-
- switch( event->type )
- {
- case GDK_KEY_PRESS:
- if (event->key.keyval == GDK_Escape) {
- GnomeCanvasItem *parent;
-
- e_text_cancel_editing (E_TEXT (e_minicard_label->field));
-
- parent = GNOME_CANVAS_ITEM (e_minicard_label)->parent;
- if (parent)
- e_canvas_item_grab_focus(parent, FALSE);
- }
- break;
- case GDK_FOCUS_CHANGE:
- {
- GdkEventFocus *focus_event = (GdkEventFocus *) event;
- if ( focus_event->in )
- {
- gnome_canvas_item_set( e_minicard_label->rect,
- "outline_color", "grey50",
- "fill_color", "grey90",
- NULL );
- e_minicard_label->has_focus = TRUE;
- }
- else
- {
- gnome_canvas_item_set( e_minicard_label->rect,
- "outline_color", NULL,
- "fill_color", NULL,
- NULL );
- e_minicard_label->has_focus = FALSE;
- }
- }
- break;
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- case GDK_MOTION_NOTIFY:
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY: {
- gboolean return_val;
-#if 0
- GnomeCanvasItem *field;
- ArtPoint p;
- double inv[6], affine[6];
-
- field = e_minicard_label->field;
- art_affine_identity (affine);
-
- if (field->xform != NULL) {
- if (field->object.flags & GNOME_CANVAS_ITEM_AFFINE_FULL) {
- art_affine_multiply (affine, affine, field->xform);
- } else {
- affine[4] += field->xform[0];
- affine[5] += field->xform[1];
- }
- }
-
- art_affine_invert (inv, affine);
- switch(event->type) {
- case GDK_MOTION_NOTIFY:
- p.x = event->motion.x;
- p.y = event->motion.y;
- art_affine_point (&p, &p, inv);
- event->motion.x = p.x;
- event->motion.y = p.y;
- break;
- case GDK_BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- p.x = event->button.x;
- p.y = event->button.y;
- art_affine_point (&p, &p, inv);
- event->button.x = p.x;
- event->button.y = p.y;
- break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- p.x = event->crossing.x;
- p.y = event->crossing.y;
- art_affine_point (&p, &p, inv);
- event->crossing.x = p.x;
- event->crossing.y = p.y;
- break;
- default:
- break;
- }
-#endif
- gtk_signal_emit_by_name(GTK_OBJECT(e_minicard_label->field), "event", event, &return_val);
- return return_val;
- break;
- }
- default:
- break;
- }
-
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
- return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
- else
- return 0;
+ e_minicard_label->has_focus = focus_event->in;
+ set_colors (e_minicard_label);
+
+ g_object_set (
+ e_minicard_label->field,
+ "handle_popup", e_minicard_label->has_focus,
+ NULL);
+ break;
+ }
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ case GDK_MOTION_NOTIFY:
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY: {
+ gboolean return_val;
+ g_signal_emit_by_name (e_minicard_label->field, "event", event, &return_val);
+ return return_val;
+ }
+ default:
+ break;
+ }
+
+ return GNOME_CANVAS_ITEM_CLASS (e_minicard_label_parent_class)->
+ event (item, event);
}
static void
-e_minicard_label_resize_children(EMinicardLabel *e_minicard_label)
+e_minicard_label_resize_children (EMinicardLabel *e_minicard_label)
{
- double left_width;
+ gdouble left_width;
+ gdouble fieldnamewidth;
+ gdouble fieldwidth;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
if (e_minicard_label->max_field_name_length != -1 && ((e_minicard_label->width / 2) - 4 > e_minicard_label->max_field_name_length))
left_width = e_minicard_label->max_field_name_length;
else
left_width = e_minicard_label->width / 2 - 4;
- gnome_canvas_item_set( e_minicard_label->fieldname,
- "clip_width", (double) ( left_width ),
- NULL );
- gnome_canvas_item_set( e_minicard_label->field,
- "clip_width", (double) ( e_minicard_label->width - 8 - left_width ),
- NULL );
+ fieldnamewidth = (gdouble) MAX (left_width, 0);
+ fieldwidth = (gdouble) MAX (e_minicard_label->width - 8 - left_width, 0);
+ gnome_canvas_item_set (
+ e_minicard_label->fieldname,
+ "clip_width", is_rtl ? fieldwidth : fieldnamewidth,
+ NULL);
+ gnome_canvas_item_set (
+ e_minicard_label->field,
+ "clip_width", is_rtl ? fieldnamewidth : fieldwidth,
+ NULL);
}
static void
-e_minicard_label_reflow(GnomeCanvasItem *item, int flags)
+set_colors (EMinicardLabel *label)
{
- EMinicardLabel *e_minicard_label = E_MINICARD_LABEL(item);
-
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (label);
+
+ if ((item->flags & GNOME_CANVAS_ITEM_REALIZED)) {
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ canvas = GNOME_CANVAS_ITEM (label)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
+ if (label->has_focus) {
+ gnome_canvas_item_set (
+ label->rect,
+ "outline_color_gdk", &style->mid[GTK_STATE_SELECTED],
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->field,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->fieldname,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+ }
+ else {
+ gnome_canvas_item_set (
+ label->rect,
+ "outline_color_gdk", NULL,
+ "fill_color_gdk", NULL,
+ NULL);
+
+ gnome_canvas_item_set (
+ label->field,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+
+ gnome_canvas_item_set (
+ label->fieldname,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
+ }
+ }
+}
+
+static void
+e_minicard_label_style_set (EMinicardLabel *label,
+ GtkStyle *previous_style)
+{
+ set_colors (label);
+}
+
+static void
+e_minicard_label_reflow (GnomeCanvasItem *item,
+ gint flags)
+{
+ EMinicardLabel *e_minicard_label = E_MINICARD_LABEL (item);
+
gint old_height;
gdouble text_height;
gdouble left_width;
old_height = e_minicard_label->height;
- gtk_object_get(GTK_OBJECT(e_minicard_label->fieldname),
- "text_height", &text_height,
- NULL);
+ g_object_get (
+ e_minicard_label->fieldname,
+ "text_height", &text_height,
+ NULL);
e_minicard_label->height = text_height;
-
- gtk_object_get(GTK_OBJECT(e_minicard_label->field),
- "text_height", &text_height,
- NULL);
+ g_object_get (
+ e_minicard_label->field,
+ "text_height", &text_height,
+ NULL);
if (e_minicard_label->height < text_height)
e_minicard_label->height = text_height;
e_minicard_label->height += 3;
- gnome_canvas_item_set( e_minicard_label->rect,
- "x2", (double) e_minicard_label->width - 1,
- "y2", (double) e_minicard_label->height - 1,
- NULL );
+ gnome_canvas_item_set (
+ e_minicard_label->rect,
+ "x2", (gdouble) e_minicard_label->width - 1,
+ "y2", (gdouble) e_minicard_label->height - 1,
+ NULL);
+
+ gnome_canvas_item_set (
+ e_minicard_label->fieldname,
+ "clip_height", (gdouble) e_minicard_label->height - 3,
+ NULL);
if (e_minicard_label->max_field_name_length != -1 && ((e_minicard_label->width / 2) - 4 > e_minicard_label->max_field_name_length))
left_width = e_minicard_label->max_field_name_length;
else
left_width = e_minicard_label->width / 2 - 4;
- e_canvas_item_move_absolute(e_minicard_label->field, left_width + 6, 1);
+ e_canvas_item_move_absolute (e_minicard_label->field, left_width + 6, 1);
if (old_height != e_minicard_label->height)
- e_canvas_item_request_parent_reflow(item);
+ e_canvas_item_request_parent_reflow (item);
}
GnomeCanvasItem *
-e_minicard_label_new(GnomeCanvasGroup *parent)
+e_minicard_label_new (GnomeCanvasGroup *parent)
{
- GnomeCanvasItem *item = gnome_canvas_item_new(parent, e_minicard_label_get_type(), NULL);
- e_minicard_label_construct(item);
- return item;
+ return gnome_canvas_item_new (
+ parent, e_minicard_label_get_type (), NULL);
}
diff --git a/addressbook/gui/widgets/e-minicard-label.h b/addressbook/gui/widgets/e-minicard-label.h
index 32792991a7..0cd9183e5f 100644
--- a/addressbook/gui/widgets/e-minicard-label.h
+++ b/addressbook/gui/widgets/e-minicard-label.h
@@ -1,32 +1,31 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-label.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_MINICARD_LABEL_H__
#define __E_MINICARD_LABEL_H__
-#include <glib.h>
-#include <libgnomeui/gnome-canvas.h>
+#include <libgnomecanvas/libgnomecanvas.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EMinicardLabel - A label doing focus with non-marching ants.
*
@@ -40,12 +39,11 @@ extern "C" {
* fieldname string RW text in the fieldname label
*/
-#define E_MINICARD_LABEL_TYPE (e_minicard_label_get_type ())
-#define E_MINICARD_LABEL(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_LABEL_TYPE, EMinicardLabel))
-#define E_MINICARD_LABEL_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_LABEL_TYPE, EMiniCardLabelClass))
-#define E_IS_MINICARD_LABEL(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_LABEL_TYPE))
-#define E_IS_MINICARD_LABEL_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_LABEL_TYPE))
-
+#define E_TYPE_MINICARD_LABEL (e_minicard_label_get_type ())
+#define E_MINICARD_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_LABEL, EMinicardLabel))
+#define E_MINICARD_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_LABEL, EMiniCardLabelClass))
+#define E_IS_MINICARD_LABEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_LABEL))
+#define E_IS_MINICARD_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_LABEL))
typedef struct _EMinicardLabel EMinicardLabel;
typedef struct _EMinicardLabelClass EMinicardLabelClass;
@@ -53,11 +51,11 @@ typedef struct _EMinicardLabelClass EMinicardLabelClass;
struct _EMinicardLabel
{
GnomeCanvasGroup parent;
-
+
/* item specific fields */
- double width;
- double height;
- double max_field_name_length;
+ gdouble width;
+ gdouble height;
+ gdouble max_field_name_length;
guint editable : 1;
GnomeCanvasItem *fieldname;
GnomeCanvasItem *field;
@@ -69,16 +67,14 @@ struct _EMinicardLabel
struct _EMinicardLabelClass
{
GnomeCanvasGroupClass parent_class;
-};
+ void (* style_set) (EMinicardLabel *label, GtkStyle *previous_style);
+};
-GtkType e_minicard_label_get_type (void);
-GnomeCanvasItem *e_minicard_label_new(GnomeCanvasGroup *parent);
+GType e_minicard_label_get_type (void);
+GnomeCanvasItem *e_minicard_label_new (GnomeCanvasGroup *parent);
void e_minicard_label_construct (GnomeCanvasItem *item);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
+G_END_DECLS
#endif /* __E_MINICARD_LABEL_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.c b/addressbook/gui/widgets/e-minicard-view-widget.c
index 1f6e1bd26b..7ff63a1bd9 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.c
+++ b/addressbook/gui/widgets/e-minicard-view-widget.c
@@ -1,146 +1,194 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-view-widget.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 <gtk/gtksignal.h>
-#include <gal/widgets/e-canvas-background.h>
-#include <gal/widgets/e-canvas.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
-#include "e-minicard-view-widget.h"
+#include <e-util/e-util.h>
-static void e_minicard_view_widget_init (EMinicardViewWidget *widget);
-static void e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass);
-static void e_minicard_view_widget_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_view_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_view_widget_destroy (GtkObject *object);
-static void e_minicard_view_widget_reflow (ECanvas *canvas);
-static void e_minicard_view_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static void e_minicard_view_widget_realize (GtkWidget *widget);
+#include "e-minicard-view-widget.h"
-static ECanvasClass *parent_class = NULL;
+static void e_minicard_view_widget_set_property
+ (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void e_minicard_view_widget_get_property
+ (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void e_minicard_view_widget_dispose (GObject *object);
+static void e_minicard_view_widget_reflow (ECanvas *canvas);
+static void e_minicard_view_widget_size_allocate
+ (GtkWidget *widget,
+ GtkAllocation *allocation);
+static void e_minicard_view_widget_style_set
+ (GtkWidget *widget,
+ GtkStyle *previous_style);
+static void e_minicard_view_widget_realize (GtkWidget *widget);
+static gboolean e_minicard_view_widget_real_focus_in_event
+ (GtkWidget *widget,
+ GdkEventFocus *event);
-/* The arguments we take */
enum {
- ARG_0,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE,
- ARG_COLUMN_WIDTH
+ PROP_0,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE,
+ PROP_COLUMN_WIDTH
};
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
SELECTION_CHANGE,
COLUMN_WIDTH_CHANGED,
RIGHT_CLICK,
LAST_SIGNAL
};
-static guint signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
-GtkType
-e_minicard_view_widget_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type)
- {
- static const GtkTypeInfo info =
- {
- "EMinicardViewWidget",
- sizeof (EMinicardViewWidget),
- sizeof (EMinicardViewWidgetClass),
- (GtkClassInitFunc) e_minicard_view_widget_class_init,
- (GtkObjectInitFunc) e_minicard_view_widget_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (e_canvas_get_type (), &info);
- }
-
- return type;
-}
+G_DEFINE_TYPE (
+ EMinicardViewWidget,
+ e_minicard_view_widget,
+ E_TYPE_CANVAS)
static void
-e_minicard_view_widget_class_init (EMinicardViewWidgetClass *klass)
+e_minicard_view_widget_class_init (EMinicardViewWidgetClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GtkWidgetClass *widget_class;
ECanvasClass *canvas_class;
- object_class = (GtkObjectClass*) klass;
- widget_class = GTK_WIDGET_CLASS (klass);
- canvas_class = E_CANVAS_CLASS (klass);
-
- parent_class = gtk_type_class (e_canvas_get_type ());
-
- gtk_object_add_arg_type ("EMinicardViewWidget::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EMinicardViewWidget::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EMinicardViewWidget::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EMinicardViewWidget::column_width", GTK_TYPE_INT,
- GTK_ARG_READWRITE, ARG_COLUMN_WIDTH);
-
- signals [SELECTION_CHANGE] =
- gtk_signal_new ("selection_change",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, selection_change),
- gtk_marshal_NONE__NONE,
- GTK_TYPE_NONE, 0);
-
- signals [COLUMN_WIDTH_CHANGED] =
- gtk_signal_new ("column_width_changed",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, column_width_changed),
- e_marshal_NONE__DOUBLE,
- GTK_TYPE_NONE, 1, GTK_TYPE_DOUBLE);
-
- signals [RIGHT_CLICK] =
- gtk_signal_new ("right_click",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewWidgetClass, right_click),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_GDK_EVENT);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_view_widget_set_arg;
- object_class->get_arg = e_minicard_view_widget_get_arg;
- object_class->destroy = e_minicard_view_widget_destroy;
-
- widget_class->realize = e_minicard_view_widget_realize;
- widget_class->size_allocate = e_minicard_view_widget_size_allocate;
-
- canvas_class->reflow = e_minicard_view_widget_reflow;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_minicard_view_widget_set_property;
+ object_class->get_property = e_minicard_view_widget_get_property;
+ object_class->dispose = e_minicard_view_widget_dispose;
- klass->selection_change = NULL;
- klass->column_width_changed = NULL;
- klass->right_click = NULL;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->style_set = e_minicard_view_widget_style_set;
+ widget_class->realize = e_minicard_view_widget_realize;
+ widget_class->size_allocate = e_minicard_view_widget_size_allocate;
+ widget_class->focus_in_event = e_minicard_view_widget_real_focus_in_event;
+
+ canvas_class = E_CANVAS_CLASS (class);
+ canvas_class->reflow = e_minicard_view_widget_reflow;
+
+ class->selection_change = NULL;
+ class->column_width_changed = NULL;
+ class->right_click = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ 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_COLUMN_WIDTH,
+ g_param_spec_double (
+ "column_width",
+ "Column Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 225.0,
+ G_PARAM_READWRITE));
+
+ signals[CREATE_CONTACT] = g_signal_new (
+ "create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CREATE_CONTACT_LIST] = g_signal_new (
+ "create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, create_contact_list),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[SELECTION_CHANGE] = g_signal_new (
+ "selection_change",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, selection_change),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[COLUMN_WIDTH_CHANGED] = g_signal_new (
+ "column_width_changed",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, column_width_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__DOUBLE,
+ G_TYPE_NONE, 1,
+ G_TYPE_DOUBLE);
+
+ signals[RIGHT_CLICK] = g_signal_new (
+ "right_click",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewWidgetClass, right_click),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
}
static void
@@ -148,205 +196,287 @@ e_minicard_view_widget_init (EMinicardViewWidget *view)
{
view->emv = NULL;
- view->book = NULL;
+ view->book_client = NULL;
view->query = NULL;
view->editable = FALSE;
- view->column_width = 150;
+ view->column_width = 225;
}
GtkWidget *
e_minicard_view_widget_new (EAddressbookReflowAdapter *adapter)
{
- EMinicardViewWidget *widget = E_MINICARD_VIEW_WIDGET (gtk_type_new (e_minicard_view_widget_get_type ()));
+ EMinicardViewWidget *widget;
+
+ widget = g_object_new (E_TYPE_MINICARD_VIEW_WIDGET, NULL);
- widget->adapter = adapter;
- gtk_object_ref (GTK_OBJECT (widget->adapter));
+ widget->adapter = g_object_ref (adapter);
return GTK_WIDGET (widget);
}
static void
-e_minicard_view_widget_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_view_widget_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
EMinicardViewWidget *emvw;
- emvw = E_MINICARD_VIEW_WIDGET (o);
+ emvw = E_MINICARD_VIEW_WIDGET (object);
- switch (arg_id){
- case ARG_BOOK:
- if (emvw->book)
- gtk_object_unref(GTK_OBJECT(emvw->book));
- if (GTK_VALUE_OBJECT (*arg)) {
- emvw->book = E_BOOK(GTK_VALUE_OBJECT (*arg));
- if (emvw->book)
- gtk_object_ref(GTK_OBJECT(emvw->book));
+ switch (property_id) {
+ case PROP_CLIENT:
+ if (emvw->book_client)
+ g_object_unref (emvw->book_client);
+ if (g_value_get_object (value)) {
+ emvw->book_client = E_BOOK_CLIENT (g_value_get_object (value));
+ if (emvw->book_client)
+ g_object_ref (emvw->book_client);
} else
- emvw->book = NULL;
+ emvw->book_client = NULL;
if (emvw->emv)
- gtk_object_set(GTK_OBJECT(emvw->emv),
- "book", emvw->book,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "client", emvw->book_client,
+ NULL);
break;
- case ARG_QUERY:
- emvw->query = g_strdup(GTK_VALUE_STRING (*arg));
+ case PROP_QUERY:
+ emvw->query = g_strdup (g_value_get_string (value));
if (emvw->emv)
- gtk_object_set(GTK_OBJECT(emvw->emv),
- "query", emvw->query,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "query", emvw->query,
+ NULL);
break;
- case ARG_EDITABLE:
- emvw->editable = GTK_VALUE_BOOL(*arg);
+ case PROP_EDITABLE:
+ emvw->editable = g_value_get_boolean (value);
if (emvw->emv)
- gtk_object_set (GTK_OBJECT(emvw->emv),
- "editable", emvw->editable,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "editable", emvw->editable,
+ NULL);
break;
- case ARG_COLUMN_WIDTH:
- emvw->column_width = GTK_VALUE_INT (*arg);
+ case PROP_COLUMN_WIDTH:
+ emvw->column_width = g_value_get_double (value);
if (emvw->emv) {
- gtk_object_set (GTK_OBJECT(emvw->emv),
- "column_width", (int) emvw->column_width,
- NULL);
+ g_object_set (
+ emvw->emv,
+ "column_width", emvw->column_width,
+ NULL);
}
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_view_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_view_widget_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardViewWidget *emvw;
emvw = E_MINICARD_VIEW_WIDGET (object);
- switch (arg_id) {
- case ARG_BOOK:
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(emvw->book);
+ switch (property_id) {
+ case PROP_CLIENT:
+ g_value_set_object (value, emvw->book_client);
break;
- case ARG_QUERY:
- GTK_VALUE_STRING (*arg) = g_strdup(emvw->query);
+ case PROP_QUERY:
+ g_value_set_string (value, emvw->query);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = emvw->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, emvw->editable);
break;
- case ARG_COLUMN_WIDTH:
- GTK_VALUE_INT (*arg) = emvw->column_width;
+ case PROP_COLUMN_WIDTH:
+ g_value_set_double (value, emvw->column_width);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_view_widget_destroy (GtkObject *object)
+e_minicard_view_widget_dispose (GObject *object)
{
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(object);
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (object);
- if (view->book)
- gtk_object_unref(GTK_OBJECT(view->book));
- g_free(view->query);
+ if (view->book_client) {
+ g_object_unref (view->book_client);
+ view->book_client = NULL;
+ }
+ if (view->query) {
+ g_free (view->query);
+ view->query = NULL;
+ }
- gtk_object_unref (GTK_OBJECT (view->adapter));
+ if (view->adapter) {
+ g_object_unref (view->adapter);
+ view->adapter = NULL;
+ }
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_view_widget_parent_class)->dispose (object);
}
static void
-selection_change (ESelectionModel *esm, EMinicardViewWidget *widget)
+selection_change (ESelectionModel *esm,
+ EMinicardViewWidget *widget)
{
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [SELECTION_CHANGE]);
+ g_signal_emit (widget, signals[SELECTION_CHANGE], 0);
}
static void
-column_width_changed (ESelectionModel *esm, double width, EMinicardViewWidget *widget)
+selection_row_change (ESelectionModel *esm,
+ gint row,
+ EMinicardViewWidget *widget)
{
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [COLUMN_WIDTH_CHANGED], width);
+ selection_change (esm, widget);
+}
+
+static void
+column_width_changed (ESelectionModel *esm,
+ gdouble width,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[COLUMN_WIDTH_CHANGED], 0, width);
+}
+
+static void
+create_contact (EMinicardView *view,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT], 0);
+}
+
+static void
+create_contact_list (EMinicardView *view,
+ EMinicardViewWidget *widget)
+{
+ g_signal_emit (widget, signals[CREATE_CONTACT_LIST], 0);
}
static guint
-right_click (EMinicardView *view, GdkEvent *event, EMinicardViewWidget *widget)
+right_click (EMinicardView *view,
+ GdkEvent *event,
+ EMinicardViewWidget *widget)
{
guint ret_val;
- gtk_signal_emit (GTK_OBJECT(widget),
- signals [RIGHT_CLICK],
- event, &ret_val);
+
+ g_signal_emit (widget, signals[RIGHT_CLICK], 0, event, &ret_val);
+
return ret_val;
}
static void
+e_minicard_view_widget_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+ GtkStyle *style;
+
+ style = gtk_widget_get_style (widget);
+
+ if (view->background)
+ gnome_canvas_item_set (
+ view->background, "fill_color_gdk",
+ &style->base[GTK_STATE_NORMAL], NULL);
+
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ style_set (widget, previous_style);
+}
+
+static void
e_minicard_view_widget_realize (GtkWidget *widget)
{
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
-
- gnome_canvas_item_new(gnome_canvas_root( GNOME_CANVAS(view) ),
- e_canvas_background_get_type(),
- "fill_color", "white",
- NULL );
-
- view->emv = gnome_canvas_item_new(
- gnome_canvas_root( GNOME_CANVAS(view) ),
- e_minicard_view_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+ GtkStyle *style = gtk_widget_get_style (widget);
+
+ view->background = gnome_canvas_item_new (
+ gnome_canvas_root (GNOME_CANVAS (view)),
+ e_canvas_background_get_type (),
+ "fill_color_gdk", &style->base[GTK_STATE_NORMAL],
+ NULL);
+
+ view->emv = gnome_canvas_item_new (
+ gnome_canvas_root (GNOME_CANVAS (view)),
+ e_minicard_view_get_type (),
+ "height", (gdouble) 100,
+ "minimum_width", (gdouble) 100,
"adapter", view->adapter,
- "column_width", (int) view->column_width,
- NULL );
-
- gtk_signal_connect (GTK_OBJECT (E_REFLOW(view->emv)->selection),
- "selection_changed",
- selection_change, view);
- gtk_signal_connect (GTK_OBJECT (view->emv),
- "column_width_changed",
- column_width_changed, view);
- gtk_signal_connect (GTK_OBJECT (view->emv),
- "right_click",
- GTK_SIGNAL_FUNC (right_click), view);
-
- if (GTK_WIDGET_CLASS(parent_class)->realize)
- GTK_WIDGET_CLASS(parent_class)->realize (widget);
+ "column_width", view->column_width,
+ NULL);
+
+ g_signal_connect (
+ E_REFLOW (view->emv)->selection,
+ "selection_changed",
+ G_CALLBACK (selection_change), view);
+ g_signal_connect (
+ E_REFLOW (view->emv)->selection,
+ "selection_row_changed",
+ G_CALLBACK (selection_row_change), view);
+ g_signal_connect (
+ view->emv, "column_width_changed",
+ G_CALLBACK (column_width_changed), view);
+ g_signal_connect (
+ view->emv, "create-contact",
+ G_CALLBACK (create_contact), view);
+ g_signal_connect (
+ view->emv, "create-contact-list",
+ G_CALLBACK (create_contact_list), view);
+ g_signal_connect (
+ view->emv, "right_click",
+ G_CALLBACK (right_click), view);
+
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ realize (widget);
}
static void
-e_minicard_view_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
+e_minicard_view_widget_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
- if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
- GTK_WIDGET_CLASS(parent_class)->size_allocate (widget, allocation);
-
- if (GTK_WIDGET_REALIZED(widget)) {
- double width;
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(widget);
-
- gnome_canvas_item_set( view->emv,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( view->emv,
- "minimum_width", (double) allocation->width,
- NULL );
- gtk_object_get(GTK_OBJECT(view->emv),
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region (GNOME_CANVAS (view), 0, 0, width - 1, allocation->height - 1);
+ GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ size_allocate (widget, allocation);
+
+ if (gtk_widget_get_realized (widget)) {
+ gdouble width;
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (widget);
+
+ gnome_canvas_item_set (
+ view->emv, "height",
+ (gdouble) allocation->height, NULL);
+ gnome_canvas_item_set (
+ view->emv, "minimum_width",
+ (gdouble) allocation->width, NULL);
+ g_object_get (view->emv, "width", &width, NULL);
+ width = MAX (width, allocation->width);
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (view), 0, 0,
+ width - 1, allocation->height - 1);
}
}
static void
-e_minicard_view_widget_reflow(ECanvas *canvas)
+e_minicard_view_widget_reflow (ECanvas *canvas)
{
- double width;
- EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET(canvas);
+ gdouble width;
+ EMinicardViewWidget *view = E_MINICARD_VIEW_WIDGET (canvas);
+ GtkAllocation allocation;
+
+ E_CANVAS_CLASS (e_minicard_view_widget_parent_class)->reflow (canvas);
- if (E_CANVAS_CLASS(parent_class)->reflow)
- E_CANVAS_CLASS(parent_class)->reflow (canvas);
+ g_object_get (view->emv, "width", &width, NULL);
+ gtk_widget_get_allocation (GTK_WIDGET (canvas), &allocation);
- gtk_object_get(GTK_OBJECT(view->emv),
- "width", &width,
- NULL);
- width = MAX(width, GTK_WIDGET(canvas)->allocation.width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS(canvas), 0, 0, width - 1, GTK_WIDGET(canvas)->allocation.height - 1);
+ gnome_canvas_set_scroll_region (
+ GNOME_CANVAS (canvas), 0, 0,
+ MAX (width, allocation.width) - 1,
+ allocation.height - 1);
}
ESelectionModel *
@@ -359,10 +489,35 @@ e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view)
}
EMinicardView *
-e_minicard_view_widget_get_view (EMinicardViewWidget *view)
+e_minicard_view_widget_get_view (EMinicardViewWidget *view)
{
if (view->emv)
return E_MINICARD_VIEW (view->emv);
else
return NULL;
}
+
+static gboolean
+e_minicard_view_widget_real_focus_in_event (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ GnomeCanvas *canvas;
+ EMinicardViewWidget *view;
+
+ canvas = GNOME_CANVAS (widget);
+ view = E_MINICARD_VIEW_WIDGET (widget);
+
+ if (!canvas->focused_item) {
+ EReflow *reflow = E_REFLOW (view->emv);
+ if (reflow->count) {
+ gint unsorted = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), 0);
+
+ if (unsorted != -1)
+ canvas->focused_item = reflow->items[unsorted];
+ }
+ }
+
+ return GTK_WIDGET_CLASS (e_minicard_view_widget_parent_class)->
+ focus_in_event (widget, event);
+}
+
diff --git a/addressbook/gui/widgets/e-minicard-view-widget.h b/addressbook/gui/widgets/e-minicard-view-widget.h
index c55bb6e636..71fe00a497 100644
--- a/addressbook/gui/widgets/e-minicard-view-widget.h
+++ b/addressbook/gui/widgets/e-minicard-view-widget.h
@@ -1,41 +1,41 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-view-widget.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_MINICARD_VIEW_WIDGET_H__
#define __E_MINICARD_VIEW_WIDGET_H__
-#include <gal/widgets/e-canvas.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "e-minicard-view.h"
+#include <libebook/libebook.h>
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+#include <e-util/e-util.h>
-#define E_MINICARD_VIEW_WIDGET_TYPE (e_minicard_view_widget_get_type ())
-#define E_MINICARD_VIEW_WIDGET(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_VIEW_WIDGET_TYPE, EMinicardViewWidget))
-#define E_MINICARD_VIEW_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_VIEW_WIDGET_TYPE, EMinicardViewWidgetClass))
-#define E_IS_MINICARD_VIEW_WIDGET(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_VIEW_WIDGET_TYPE))
-#define E_IS_MINICARD_VIEW_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_VIEW_WIDGET_TYPE))
+#include "e-minicard-view.h"
+G_BEGIN_DECLS
+
+#define E_TYPE_MINICARD_VIEW_WIDGET (e_minicard_view_widget_get_type ())
+#define E_MINICARD_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_VIEW_WIDGET, EMinicardViewWidget))
+#define E_MINICARD_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_VIEW_WIDGET, EMinicardViewWidgetClass))
+#define E_IS_MINICARD_VIEW_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_VIEW_WIDGET))
+#define E_IS_MINICARD_VIEW_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_VIEW_WIDGET))
typedef struct _EMinicardViewWidget EMinicardViewWidget;
typedef struct _EMinicardViewWidgetClass EMinicardViewWidgetClass;
@@ -44,35 +44,35 @@ struct _EMinicardViewWidget
{
ECanvas parent;
+ GnomeCanvasItem *background;
GnomeCanvasItem *emv;
EAddressbookReflowAdapter *adapter;
- EBook *book;
- char *query;
+ EBookClient *book_client;
+ gchar *query;
guint editable : 1;
- double column_width;
+ gdouble column_width;
};
struct _EMinicardViewWidgetClass
{
ECanvasClass parent_class;
+ void (*create_contact) (EMinicardViewWidget *emvw);
+ void (*create_contact_list) (EMinicardViewWidget *emvw);
void (*selection_change) (EMinicardViewWidget *emvw);
void (*column_width_changed) (EMinicardViewWidget *emvw, double width);
guint (*right_click) (EMinicardViewWidget *emvw);
};
-
-GtkType e_minicard_view_widget_get_type (void);
+GType e_minicard_view_widget_get_type (void);
GtkWidget *e_minicard_view_widget_new (EAddressbookReflowAdapter *adapter);
/* Get parts of the view widget. */
ESelectionModel *e_minicard_view_widget_get_selection_model (EMinicardViewWidget *view);
EMinicardView *e_minicard_view_widget_get_view (EMinicardViewWidget *view);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+G_END_DECLS
#endif /* __E_MINICARD_VIEW_WIDGET_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-view.c b/addressbook/gui/widgets/e-minicard-view.c
index 6b596bb754..1a35f3aa09 100644
--- a/addressbook/gui/widgets/e-minicard-view.c
+++ b/addressbook/gui/widgets/e-minicard-view.c
@@ -1,123 +1,158 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard-view.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 "e-minicard-view.h"
-#include "e-addressbook-util.h"
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
-#include <gtk/gtkselection.h>
-#include <gtk/gtkdnd.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-unicode.h>
-#include <libgnome/gnome-i18n.h>
+#include "e-util/e-util.h"
-static void e_minicard_view_drag_data_get(GtkWidget *widget,
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
+
+#include "ea-addressbook.h"
+
+static void e_minicard_view_drag_data_get (GtkWidget *widget,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time,
EMinicardView *view);
-static EReflowClass *parent_class = NULL;
-#define PARENT_TYPE (E_REFLOW_TYPE)
-
-/* The arguments we take */
enum {
- ARG_0,
- ARG_ADAPTER,
- ARG_BOOK,
- ARG_QUERY,
- ARG_EDITABLE
+ PROP_0,
+ PROP_ADAPTER,
+ PROP_CLIENT,
+ PROP_QUERY,
+ PROP_EDITABLE
};
-
enum {
+ CREATE_CONTACT,
+ CREATE_CONTACT_LIST,
RIGHT_CLICK,
LAST_SIGNAL
};
-static guint signals [LAST_SIGNAL] = {0, };
+static guint signals[LAST_SIGNAL] = {0, };
enum DndTargetType {
DND_TARGET_TYPE_VCARD_LIST,
+ DND_TARGET_TYPE_SOURCE_VCARD_LIST
};
#define VCARD_LIST_TYPE "text/x-vcard"
+#define SOURCE_VCARD_LIST_TYPE "text/x-source-vcard"
static GtkTargetEntry drag_types[] = {
- { VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
+ { (gchar *) SOURCE_VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_SOURCE_VCARD_LIST },
+ { (gchar *) VCARD_LIST_TYPE, 0, DND_TARGET_TYPE_VCARD_LIST }
};
-static gint num_drag_types = sizeof(drag_types) / sizeof(drag_types[0]);
+
+G_DEFINE_TYPE (EMinicardView, e_minicard_view, E_TYPE_REFLOW)
static void
-e_minicard_view_drag_data_get(GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- EMinicardView *view)
+e_minicard_view_drag_data_get (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ EMinicardView *view)
{
- if (!E_IS_MINICARD_VIEW(view))
+ GdkAtom target;
+
+ if (!E_IS_MINICARD_VIEW (view))
return;
+ target = gtk_selection_data_get_target (selection_data);
+
switch (info) {
case DND_TARGET_TYPE_VCARD_LIST: {
- char *value;
-
- value = e_card_list_get_vcard(view->drag_list);
-
- gtk_selection_data_set (selection_data,
- selection_data->target,
- 8,
- value, strlen (value));
+ gchar *value;
+
+ value = eab_contact_list_to_string (view->drag_list);
+
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+ g_free (value);
+ break;
+ }
+ case DND_TARGET_TYPE_SOURCE_VCARD_LIST: {
+ EBookClient *book_client = NULL;
+ gchar *value;
+
+ g_object_get (view->adapter, "book_client", &book_client, NULL);
+ value = eab_book_and_contact_list_to_string (book_client, view->drag_list);
+
+ gtk_selection_data_set (
+ selection_data, target, 8,
+ (guchar *) value, strlen (value));
+
+ g_object_unref (book_client);
+ g_free (value);
break;
}
}
+}
- g_list_foreach (view->drag_list, (GFunc)gtk_object_unref, NULL);
- g_list_free (view->drag_list);
+static void
+clear_drag_data (EMinicardView *view)
+{
+ g_slist_free_full (view->drag_list, (GDestroyNotify) g_object_unref);
view->drag_list = NULL;
}
-static int
-e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter, GdkEvent *event, EMinicardView *view)
+static gint
+e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter,
+ GdkEvent *event,
+ EMinicardView *view)
{
GdkDragContext *context;
GtkTargetList *target_list;
GdkDragAction actions = GDK_ACTION_MOVE | GDK_ACTION_COPY;
-
+
+ clear_drag_data (view);
+
view->drag_list = e_minicard_view_get_card_list (view);
- g_print ("dragging %d card(s)\n", g_list_length (view->drag_list));
+ g_print ("dragging %d card(s)\n", g_slist_length (view->drag_list));
- target_list = gtk_target_list_new (drag_types, num_drag_types);
+ target_list = gtk_target_list_new (drag_types, G_N_ELEMENTS (drag_types));
- context = gtk_drag_begin (GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
- target_list, actions, 1/*XXX*/, event);
+ context = gtk_drag_begin (
+ GTK_WIDGET (GNOME_CANVAS_ITEM (view)->canvas),
+ target_list, actions, 1/*XXX */, event);
if (!view->canvas_drag_data_get_id)
- view->canvas_drag_data_get_id = gtk_signal_connect (GTK_OBJECT (GNOME_CANVAS_ITEM (view)->canvas),
- "drag_data_get",
- GTK_SIGNAL_FUNC (e_minicard_view_drag_data_get),
- view);
+ view->canvas_drag_data_get_id = g_signal_connect (
+ GNOME_CANVAS_ITEM (view)->canvas, "drag_data_get",
+ G_CALLBACK (e_minicard_view_drag_data_get), view);
gtk_drag_set_icon_default (context);
@@ -127,30 +162,64 @@ e_minicard_view_drag_begin (EAddressbookReflowAdapter *adapter, GdkEvent *event,
static void
set_empty_message (EMinicardView *view)
{
- char *empty_message;
- gboolean editable = FALSE;
+ gchar *empty_message;
+ gboolean editable = FALSE, perform_initial_query = FALSE, searching = FALSE;
if (view->adapter) {
- gtk_object_get (GTK_OBJECT (view->adapter),
- "editable", &editable,
- NULL);
+ EAddressbookModel *model = NULL;
+ EBookClient *book_client = NULL;
+
+ g_object_get (
+ view->adapter,
+ "editable", &editable,
+ "model", &model,
+ "client", &book_client,
+ NULL);
+
+ if (book_client && !e_client_check_capability (E_CLIENT (book_client), "do-initial-query"))
+ perform_initial_query = TRUE;
+
+ searching = model && e_addressbook_model_can_stop (model);
+
+ if (book_client)
+ g_object_unref (book_client);
+ if (model)
+ g_object_unref (model);
}
- if (editable)
- empty_message = e_utf8_from_locale_string(_("\n\nThere are no items to show in this view.\n\n"
- "Double-click here to create a new Contact."));
- else
- empty_message = e_utf8_from_locale_string(_("\n\nThere are no items to show in this view."));
+ if (searching) {
+ empty_message = _("\n\nSearching for the Contacts...");
+ } else if (editable) {
+ if (perform_initial_query)
+ empty_message = _("\n\nSearch for the Contact\n\n"
+ "or double-click here to create a new Contact.");
+ else
+ empty_message = _("\n\nThere are no items to show in this view.\n\n"
+ "Double-click here to create a new Contact.");
+ } else {
+ if (perform_initial_query)
+ empty_message = _("\n\nSearch for the Contact.");
+ else
+ empty_message = _("\n\nThere are no items to show in this view.");
+ }
- gtk_object_set (GTK_OBJECT(view),
- "empty_message", empty_message,
- NULL);
+ g_object_set (
+ view,
+ "empty_message", empty_message,
+ NULL);
+}
- g_free (empty_message);
+static void
+writable_status_change (EAddressbookModel *model,
+ gboolean writable,
+ EMinicardView *view)
+{
+ set_empty_message (view);
}
static void
-writable_status_change (EAddressbookModel *model, gboolean writable, EMinicardView *view)
+stop_state_changed (EAddressbookModel *model,
+ EMinicardView *view)
{
set_empty_message (view);
}
@@ -160,169 +229,206 @@ adapter_changed (EMinicardView *view)
{
set_empty_message (view);
- gtk_signal_connect (GTK_OBJECT (view->adapter), "drag_begin",
- GTK_SIGNAL_FUNC (e_minicard_view_drag_begin), view);
+ g_signal_connect (
+ view->adapter, "drag_begin",
+ G_CALLBACK (e_minicard_view_drag_begin), view);
}
static void
-e_minicard_view_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_view_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- GnomeCanvasItem *item;
EMinicardView *view;
- item = GNOME_CANVAS_ITEM (o);
- view = E_MINICARD_VIEW (o);
-
- switch (arg_id){
- case ARG_ADAPTER:
+ view = E_MINICARD_VIEW (object);
+
+ switch (property_id) {
+ case PROP_ADAPTER:
if (view->adapter) {
- if (view->writable_status_id) {
+ if (view->writable_status_id || view->stop_state_id) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- gtk_signal_disconnect (GTK_OBJECT (model), view->writable_status_id);
+ if (view->writable_status_id)
+ g_signal_handler_disconnect (model, view->writable_status_id);
+ if (view->stop_state_id)
+ g_signal_handler_disconnect (model, view->stop_state_id);
}
}
- gtk_object_unref (GTK_OBJECT(view->adapter));
+ g_object_unref (view->adapter);
}
view->writable_status_id = 0;
- view->adapter = GTK_VALUE_POINTER (*arg);
- gtk_object_ref (GTK_OBJECT (view->adapter));
+ view->stop_state_id = 0;
+ view->adapter = g_value_get_object (value);
+ g_object_ref (view->adapter);
adapter_changed (view);
- gtk_object_set (GTK_OBJECT (view),
- "model", view->adapter,
- NULL);
+ g_object_set (
+ view,
+ "model", view->adapter,
+ NULL);
if (view->adapter) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- view->writable_status_id =
- gtk_signal_connect (GTK_OBJECT (model), "writable_status",
- GTK_SIGNAL_FUNC (writable_status_change), view);
+ view->writable_status_id = g_signal_connect (
+ model, "writable_status",
+ G_CALLBACK (writable_status_change), view);
+ view->stop_state_id = g_signal_connect (
+ model, "stop_state_changed",
+ G_CALLBACK (stop_state_changed), view);
}
-
+
}
break;
- case ARG_BOOK:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "book", GTK_VALUE_OBJECT (*arg),
- NULL);
+ case PROP_CLIENT:
+ g_object_set (
+ view->adapter,
+ "client", g_value_get_object (value),
+ NULL);
set_empty_message (view);
break;
- case ARG_QUERY:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "query", GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_set (
+ view->adapter,
+ "query", g_value_get_string (value),
+ NULL);
break;
- case ARG_EDITABLE:
- gtk_object_set (GTK_OBJECT (view->adapter),
- "editable", GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_set (
+ view->adapter,
+ "editable", g_value_get_boolean (value),
+ NULL);
set_empty_message (view);
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_view_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_view_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicardView *view;
view = E_MINICARD_VIEW (object);
- switch (arg_id) {
- case ARG_ADAPTER:
- GTK_VALUE_POINTER (*arg) = view->adapter;
+ switch (property_id) {
+ case PROP_ADAPTER:
+ g_value_set_object (value, view->adapter);
break;
- case ARG_BOOK:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "book", &GTK_VALUE_OBJECT (*arg),
- NULL);
+ case PROP_CLIENT:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "client", value);
break;
- case ARG_QUERY:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "query", &GTK_VALUE_STRING (*arg),
- NULL);
+ case PROP_QUERY:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "query", value);
break;
- case ARG_EDITABLE:
- gtk_object_get (GTK_OBJECT (view->adapter),
- "editable", &GTK_VALUE_BOOL (*arg),
- NULL);
+ case PROP_EDITABLE:
+ g_object_get_property (
+ G_OBJECT (view->adapter),
+ "editable", value);
break;
default:
- arg->type = GTK_TYPE_INVALID;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
-e_minicard_view_destroy (GtkObject *object)
+e_minicard_view_dispose (GObject *object)
{
- EMinicardView *view = E_MINICARD_VIEW(object);
+ EMinicardView *view = E_MINICARD_VIEW (object);
+
+ clear_drag_data (view);
if (view->canvas_drag_data_get_id) {
- gtk_signal_disconnect (GTK_OBJECT (GNOME_CANVAS_ITEM (view)->canvas),
- view->canvas_drag_data_get_id);
+ g_signal_handler_disconnect (
+ GNOME_CANVAS_ITEM (view)->canvas,
+ view->canvas_drag_data_get_id);
+ view->canvas_drag_data_get_id = 0;
}
if (view->adapter) {
- if (view->writable_status_id) {
+ if (view->writable_status_id || view->stop_state_id) {
EAddressbookModel *model;
- gtk_object_get (GTK_OBJECT (view->adapter),
- "model", &model,
- NULL);
+ g_object_get (
+ view->adapter,
+ "model", &model,
+ NULL);
if (model) {
- gtk_signal_disconnect (GTK_OBJECT (model), view->writable_status_id);
+ if (view->writable_status_id)
+ g_signal_handler_disconnect (model, view->writable_status_id);
+ if (view->stop_state_id)
+ g_signal_handler_disconnect (model, view->stop_state_id);
}
}
- gtk_object_unref (GTK_OBJECT(view->adapter));
+ g_object_unref (view->adapter);
}
view->writable_status_id = 0;
+ view->stop_state_id = 0;
view->adapter = NULL;
- GTK_OBJECT_CLASS(parent_class)->destroy (object);
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_view_parent_class)->dispose (object);
}
static guint
-e_minicard_view_right_click (EMinicardView *view, GdkEvent *event)
+e_minicard_view_right_click (EMinicardView *view,
+ GdkEvent *event)
{
guint ret_val = 0;
- gtk_signal_emit (GTK_OBJECT (view), signals[RIGHT_CLICK],
- event, &ret_val);
+ g_signal_emit (
+ view, signals[RIGHT_CLICK], 0,
+ event, &ret_val);
return ret_val;
}
static gboolean
-e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicardView *view;
-
+ guint event_button = 0;
+
view = E_MINICARD_VIEW (item);
- switch( event->type ) {
+ switch (event->type) {
case GDK_2BUTTON_PRESS:
- if (((GdkEventButton *)event)->button == 1) {
+ gdk_event_get_button (event, &event_button);
+ if (event_button == 1) {
gboolean editable;
- gtk_object_get(GTK_OBJECT(view->adapter), "editable", &editable, NULL);
-
- if (editable) {
- EBook *book;
- gtk_object_get(GTK_OBJECT(view), "book", &book, NULL);
-
- if (book && E_IS_BOOK (book))
- e_addressbook_show_contact_editor (book, e_card_new(""), TRUE, editable);
- }
+ g_object_get (view->adapter, "editable", &editable, NULL);
+
+ if (editable)
+ e_minicard_view_create_contact (view);
return TRUE;
}
case GDK_BUTTON_PRESS:
- if (event->button.button == 3) {
+ gdk_event_get_button (event, &event_button);
+ if (event_button == 3)
+ e_minicard_view_right_click (view, event);
+ break;
+ case GDK_KEY_PRESS:
+ if (event->key.keyval & GDK_SHIFT_MASK &&
+ event->key.keyval == GDK_KEY_F10) {
e_minicard_view_right_click (view, event);
}
break;
@@ -330,30 +436,29 @@ e_minicard_view_event (GnomeCanvasItem *item, GdkEvent *event)
break;
}
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->event)
- return GNOME_CANVAS_ITEM_CLASS(parent_class)->event(item, event);
- else
- return FALSE;
+ return GNOME_CANVAS_ITEM_CLASS (e_minicard_view_parent_class)->
+ event (item, event);
}
static gint
-e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_view_selection_event (EReflow *reflow,
+ GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicardView *view;
- int return_val = FALSE;
+ gint return_val = FALSE;
view = E_MINICARD_VIEW (reflow);
- if (parent_class->selection_event) {
- return_val = parent_class->selection_event (reflow, item, event);
- }
+ return_val = E_REFLOW_CLASS (e_minicard_view_parent_class)->
+ selection_event (reflow, item, event);
switch (event->type) {
case GDK_FOCUS_CHANGE:
if (event->focus_change.in) {
- int i;
+ gint i;
for (i = 0; i < reflow->count; i++) {
if (reflow->items[i] == item) {
- e_selection_model_maybe_do_something(reflow->selection, i, 0, 0);
+ e_selection_model_maybe_do_something (reflow->selection, i, 0, 0);
break;
}
}
@@ -363,7 +468,7 @@ e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEven
if (event->button.button == 3) {
return_val = e_minicard_view_right_click (view, event);
if (!return_val)
- e_selection_model_right_click_up(reflow->selection);
+ e_selection_model_right_click_up (reflow->selection);
}
break;
default:
@@ -372,176 +477,139 @@ e_minicard_view_selection_event (EReflow *reflow, GnomeCanvasItem *item, GdkEven
return return_val;
}
-typedef struct {
- EMinicardView *view;
- EBookCallback cb;
- gpointer closure;
-} ViewCbClosure;
-
-static void
-do_remove (int i, gpointer user_data)
-{
- EBook *book;
- ECard *card;
- ViewCbClosure *viewcbclosure = user_data;
- EMinicardView *view = viewcbclosure->view;
- EBookCallback cb = viewcbclosure->cb;
- gpointer closure = viewcbclosure->closure;
-
- gtk_object_get (GTK_OBJECT(view->adapter),
- "book", &book,
- NULL);
-
- card = e_addressbook_reflow_adapter_get_card (view->adapter, i);
-
- e_book_remove_card(book, card, cb, closure);
-
- gtk_object_unref (GTK_OBJECT (card));
-}
-
-#if 0
-static int
-compare_to_utf_str (EMinicard *card, const char *utf_str)
-{
- g_return_val_if_fail(card != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(card), 0);
-
- if (g_unichar_isdigit (g_utf8_get_char (utf_str))) {
- return 1;
- }
-
- if (card->card) {
- char *file_as;
- gtk_object_get(GTK_OBJECT(card->card),
- "file_as", &file_as,
- NULL);
- if (file_as)
- return g_utf8_strcasecmp (file_as, utf_str);
- else
- return 0;
- } else {
- return 0;
- }
-}
-#endif
-
static void
-e_minicard_view_class_init (EMinicardViewClass *klass)
+e_minicard_view_class_init (EMinicardViewClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GnomeCanvasItemClass *item_class;
EReflowClass *reflow_class;
-
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
- reflow_class = (EReflowClass *) klass;
-
- parent_class = gtk_type_class (PARENT_TYPE);
-
- gtk_object_add_arg_type ("EMinicardView::adapter", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_ADAPTER);
- gtk_object_add_arg_type ("EMinicardView::book", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_BOOK);
- gtk_object_add_arg_type ("EMinicardView::query", GTK_TYPE_STRING,
- GTK_ARG_READWRITE, ARG_QUERY);
- gtk_object_add_arg_type ("EMinicardView::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
-
- signals [RIGHT_CLICK] =
- gtk_signal_new ("right_click",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardViewClass, right_click),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_GDK_EVENT);
-
- gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_view_set_arg;
- object_class->get_arg = e_minicard_view_get_arg;
- object_class->destroy = e_minicard_view_destroy;
+
+ object_class = G_OBJECT_CLASS (class);
+ item_class = (GnomeCanvasItemClass *) class;
+ reflow_class = (EReflowClass *) class;
+
+ object_class->set_property = e_minicard_view_set_property;
+ object_class->get_property = e_minicard_view_get_property;
+ object_class->dispose = e_minicard_view_dispose;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ADAPTER,
+ g_param_spec_object (
+ "adapter",
+ "Adapter",
+ NULL,
+ E_TYPE_ADDRESSBOOK_REFLOW_ADAPTER,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CLIENT,
+ g_param_spec_object (
+ "client",
+ "EBookClient",
+ NULL,
+ E_TYPE_BOOK_CLIENT,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_QUERY,
+ g_param_spec_string (
+ "query",
+ "Query",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_EDITABLE,
+ g_param_spec_boolean (
+ "editable",
+ "Editable",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[CREATE_CONTACT] = g_signal_new (
+ "create-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[CREATE_CONTACT_LIST] = g_signal_new (
+ "create-contact-list",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ 0, NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+ signals[RIGHT_CLICK] = g_signal_new (
+ "right_click",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardViewClass, right_click),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
item_class->event = e_minicard_view_event;
reflow_class->selection_event = e_minicard_view_selection_event;
/* GnomeCanvasItem method overrides */
+
+ /* init the accessibility support for e_minicard_view */
+ e_minicard_view_a11y_init ();
}
static void
e_minicard_view_init (EMinicardView *view)
{
+ view->drag_list = NULL;
view->adapter = NULL;
view->canvas_drag_data_get_id = 0;
view->writable_status_id = 0;
+ view->stop_state_id = 0;
set_empty_message (view);
}
-GtkType
-e_minicard_view_get_type (void)
-{
- static GtkType reflow_type = 0;
-
- if (!reflow_type) {
- static const GtkTypeInfo reflow_info = {
- "EMinicardView",
- sizeof (EMinicardView),
- sizeof (EMinicardViewClass),
- (GtkClassInitFunc) e_minicard_view_class_init,
- (GtkObjectInitFunc) e_minicard_view_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- reflow_type = gtk_type_unique (PARENT_TYPE, &reflow_info);
- }
-
- return reflow_type;
-}
-
-void
-e_minicard_view_remove_selection(EMinicardView *view,
- EBookCallback cb,
- gpointer closure)
-{
- ViewCbClosure viewcbclosure;
- viewcbclosure.view = view;
- viewcbclosure.cb = cb;
- viewcbclosure.closure = closure;
-
- e_selection_model_foreach (E_REFLOW (view)->selection,
- do_remove,
- &viewcbclosure);
-}
-
void
e_minicard_view_jump_to_letter (EMinicardView *view,
gunichar letter)
{
#if 0
- char uft_str[6 + 1];
+ gchar uft_str[6 + 1];
- utf_str [g_unichar_to_utf8 (letter, utf_str)] = '\0';
- e_reflow_sorted_jump (E_REFLOW_SORTED (view),
- (GCompareFunc) compare_to_utf_str,
- utf_str);
+ utf_str[g_unichar_to_utf8 (letter, utf_str)] = '\0';
+ e_reflow_sorted_jump (
+ E_REFLOW_SORTED (view),
+ (GCompareFunc) compare_to_utf_str,
+ utf_str);
#endif
}
typedef struct {
- GList *list;
+ GSList *list;
EAddressbookReflowAdapter *adapter;
} ModelAndList;
static void
-add_to_list (int index, gpointer closure)
+add_to_list (gint index,
+ gpointer closure)
{
ModelAndList *mal = closure;
- mal->list = g_list_prepend (mal->list, e_addressbook_reflow_adapter_get_card (mal->adapter, index));
+ mal->list = g_slist_prepend (
+ mal->list, e_addressbook_reflow_adapter_get_contact (
+ mal->adapter, index));
}
-GList *
+GSList *
e_minicard_view_get_card_list (EMinicardView *view)
{
ModelAndList mal;
@@ -551,6 +619,21 @@ e_minicard_view_get_card_list (EMinicardView *view)
e_selection_model_foreach (E_REFLOW (view)->selection, add_to_list, &mal);
- mal.list = g_list_reverse (mal.list);
- return mal.list;
+ return g_slist_reverse (mal.list);
+}
+
+void
+e_minicard_view_create_contact (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT], 0);
+}
+
+void
+e_minicard_view_create_contact_list (EMinicardView *view)
+{
+ g_return_if_fail (E_IS_MINICARD_VIEW (view));
+
+ g_signal_emit (view, signals[CREATE_CONTACT_LIST], 0);
}
diff --git a/addressbook/gui/widgets/e-minicard-view.h b/addressbook/gui/widgets/e-minicard-view.h
index 1f23c62754..bf116e4513 100644
--- a/addressbook/gui/widgets/e-minicard-view.h
+++ b/addressbook/gui/widgets/e-minicard-view.h
@@ -1,37 +1,36 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-view.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_MINICARD_VIEW_H__
#define __E_MINICARD_VIEW_H__
#include "e-minicard.h"
-#include <gal/widgets/e-reflow.h>
-#include <gal/widgets/e-selection-model-simple.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
+#include <e-util/e-util.h>
+
#include "e-addressbook-reflow-adapter.h"
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
+G_BEGIN_DECLS
/* EMinicardView - A canvas item container.
*
@@ -52,12 +51,11 @@ extern "C" {
* height double RW height of the reflow
*/
-#define E_MINICARD_VIEW_TYPE (e_minicard_view_get_type ())
-#define E_MINICARD_VIEW(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_VIEW_TYPE, EMinicardView))
-#define E_MINICARD_VIEW_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_VIEW_TYPE, EMinicardViewClass))
-#define E_IS_MINICARD_VIEW(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_VIEW_TYPE))
-#define E_IS_MINICARD_VIEW_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_VIEW_TYPE))
-
+#define E_TYPE_MINICARD_VIEW (e_minicard_view_get_type ())
+#define E_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_MINICARD_VIEW, EMinicardView))
+#define E_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_MINICARD_VIEW, EMinicardViewClass))
+#define E_IS_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_MINICARD_VIEW))
+#define E_IS_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), E_TYPE_MINICARD_VIEW))
typedef struct _EMinicardView EMinicardView;
typedef struct _EMinicardViewClass EMinicardViewClass;
@@ -67,14 +65,14 @@ struct _EMinicardView
EReflow parent;
EAddressbookReflowAdapter *adapter;
-
+
/* item specific fields */
- GList *drag_list;
+ GSList *drag_list;
guint canvas_drag_data_get_id;
-
guint writable_status_id;
+ guint stop_state_id;
};
struct _EMinicardViewClass
@@ -84,17 +82,13 @@ struct _EMinicardViewClass
void (*right_click) (EMinicardView *view, GdkEvent *event);
};
-GtkType e_minicard_view_get_type (void);
-void e_minicard_view_remove_selection (EMinicardView *view,
- EBookCallback cb,
- gpointer closure);
+GType e_minicard_view_get_type (void);
void e_minicard_view_jump_to_letter (EMinicardView *view,
gunichar letter);
-GList *e_minicard_view_get_card_list (EMinicardView *view);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GSList *e_minicard_view_get_card_list (EMinicardView *view);
+void e_minicard_view_create_contact (EMinicardView *view);
+void e_minicard_view_create_contact_list (EMinicardView *view);
+G_END_DECLS
#endif /* __E_MINICARD_VIEW_H__ */
diff --git a/addressbook/gui/widgets/e-minicard-widget-test.c b/addressbook/gui/widgets/e-minicard-widget-test.c
deleted file mode 100644
index 04ef2f0823..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget-test.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@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.
- *
- * 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.
- *
- */
-
-#define TEST_VCARD \
-"BEGIN:VCARD
-" \
-"FN:Nat
-" \
-"N:Friedman;Nat;D;Mr.
-" \
-"ORG:Ximian, Inc.
-" \
-"TITLE:Head Geek
-" \
-"ROLE:Programmer/Executive
-" \
-"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
-" \
-"
-"
-
-#include "config.h"
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include "e-minicard-widget.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- 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 ( _( "Minicard Widget Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard widget" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *minicard;
- ECard *card;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Widget Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Widget Test", NULL);
-
- minicard = e_minicard_widget_new();
- card = e_card_new(TEST_VCARD);
- gtk_object_set(GTK_OBJECT(minicard),
- "card", card,
- NULL);
-
- gnome_app_set_contents( GNOME_APP( app ), minicard );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/e-minicard-widget.c b/addressbook/gui/widgets/e-minicard-widget.c
deleted file mode 100644
index 566a43b087..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget.c
+++ /dev/null
@@ -1,249 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-table-field-chooser.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 <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include "e-minicard-widget.h"
-#include "e-minicard.h"
-
-static void e_minicard_widget_init (EMinicardWidget *card);
-static void e_minicard_widget_class_init (EMinicardWidgetClass *klass);
-static void e_minicard_widget_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_widget_destroy (GtkObject *object);
-static void e_minicard_widget_size_request (GtkWidget *widget, GtkRequisition *requisition);
-static void e_minicard_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static void e_minicard_widget_reflow (ECanvas *canvas);
-
-static ECanvasClass *parent_class = NULL;
-
-/* The arguments we take */
-enum {
- ARG_0,
- ARG_CARD,
-};
-
-GtkType
-e_minicard_widget_get_type (void)
-{
- static GtkType type = 0;
-
- if (!type)
- {
- static const GtkTypeInfo info =
- {
- "EMinicardWidget",
- sizeof (EMinicardWidget),
- sizeof (EMinicardWidgetClass),
- (GtkClassInitFunc) e_minicard_widget_class_init,
- (GtkObjectInitFunc) e_minicard_widget_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (e_canvas_get_type (), &info);
- }
-
- return type;
-}
-
-static void
-e_minicard_widget_class_init (EMinicardWidgetClass *klass)
-{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECanvasClass *ecanvas_class;
-
- object_class = GTK_OBJECT_CLASS(klass);
- widget_class = GTK_WIDGET_CLASS(klass);
- ecanvas_class = E_CANVAS_CLASS(klass);
-
- parent_class = gtk_type_class (e_canvas_get_type ());
-
- object_class->set_arg = e_minicard_widget_set_arg;
- object_class->get_arg = e_minicard_widget_get_arg;
- object_class->destroy = e_minicard_widget_destroy;
-
- widget_class->size_request = e_minicard_widget_size_request;
- widget_class->size_allocate = e_minicard_widget_size_allocate;
-
- ecanvas_class->reflow = e_minicard_widget_reflow;
-
- gtk_object_add_arg_type ("EMinicardWidget::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
-}
-
-static void
-e_minicard_widget_size_request(GtkWidget *widget, GtkRequisition *requisition)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(widget);
- gtk_object_get(GTK_OBJECT(emw->item),
- "height", &height,
- NULL);
- if (height <= 0)
- height = 1;
- widget->requisition.height = height;
- widget->requisition.width = 200;
- requisition->height = height;
- requisition->width = 200;
-}
-
-static void
-e_minicard_widget_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(widget);
- gnome_canvas_item_set( emw->item,
- "width", (double) allocation->width,
- NULL );
- gtk_object_get(GTK_OBJECT(emw->item),
- "height", &height,
- NULL);
- height = MAX(height, allocation->height);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( emw ), 0, 0, allocation->width - 1, height - 1);
- gnome_canvas_item_set( emw->rect,
- "x2", (double) allocation->width,
- "y2", (double) height,
- NULL );
- if (GTK_WIDGET_CLASS(parent_class)->size_allocate)
- GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
-}
-
-static void e_minicard_widget_reflow(ECanvas *canvas)
-{
- double height;
- EMinicardWidget *emw = E_MINICARD_WIDGET(canvas);
- gtk_object_get(GTK_OBJECT(emw->item),
- "height", &height,
- NULL);
-
- height = MAX(height, GTK_WIDGET(emw)->allocation.height);
-
- gnome_canvas_set_scroll_region (GNOME_CANVAS(emw), 0, 0, GTK_WIDGET(emw)->allocation.width - 1, height - 1);
- gnome_canvas_item_set( emw->rect,
- "x2", (double) GTK_WIDGET(emw)->allocation.width,
- "y2", (double) height,
- NULL );
-
- gtk_widget_queue_resize(GTK_WIDGET(canvas));
-}
-
-static void
-e_minicard_widget_init (EMinicardWidget *emw)
-{
- emw->rect = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(emw)),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
-
- emw->item = gnome_canvas_item_new(gnome_canvas_root(GNOME_CANVAS(emw)),
- e_minicard_get_type(),
- "width", (double) 100,
- NULL );
-
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( emw ),
- 0, 0,
- 100, 100 );
-
- emw->card = NULL;
-}
-
-static void
-e_minicard_widget_destroy (GtkObject *object)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- if (emw->card)
- gtk_object_unref(GTK_OBJECT(emw->card));
-
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- GTK_OBJECT_CLASS(parent_class)->destroy(object);
-}
-
-GtkWidget*
-e_minicard_widget_new (void)
-{
- GtkWidget *widget = GTK_WIDGET (gtk_type_new (e_minicard_widget_get_type ()));
- return widget;
-}
-
-static void
-e_minicard_widget_set_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
- gpointer ptr;
-
- switch (arg_id){
- case ARG_CARD:
- ptr = GTK_VALUE_POINTER (*arg);
- e_minicard_widget_set_card (emw, ptr ? E_CARD (ptr) : NULL);
- break;
- default:
- break;
- }
-}
-
-static void
-e_minicard_widget_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
-{
- EMinicardWidget *emw = E_MINICARD_WIDGET(object);
-
- switch (arg_id) {
- case ARG_CARD:
- if (emw->card)
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(emw->card);
- else
- GTK_VALUE_OBJECT (*arg) = NULL;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-void
-e_minicard_widget_set_card (EMinicardWidget *emw, ECard *card)
-{
- g_return_if_fail (emw && E_IS_MINICARD_WIDGET (emw));
- g_return_if_fail (card == NULL || E_IS_CARD (card));
-
- if (card != emw->card) {
-
- if (emw->card)
- gtk_object_unref (GTK_OBJECT (emw->card));
-
- emw->card = card;
-
- if (emw->card)
- gtk_object_ref (GTK_OBJECT (emw->card));
-
- if (emw->item)
- gtk_object_set (GTK_OBJECT (emw->item),
- "card", emw->card,
- NULL);
- }
-}
diff --git a/addressbook/gui/widgets/e-minicard-widget.h b/addressbook/gui/widgets/e-minicard-widget.h
deleted file mode 100644
index eaf0f8edb6..0000000000
--- a/addressbook/gui/widgets/e-minicard-widget.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard-widget.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_MINICARD_WIDGET_H__
-#define __E_MINICARD_WIDGET_H__
-
-#include <gal/widgets/e-canvas.h>
-#include "addressbook/backend/ebook/e-card.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EMinicardWidget - A card displaying information about a contact.
- *
- * The following arguments are available:
- *
- * name type read/write description
- * --------------------------------------------------------------------------------
- */
-
-#define E_MINICARD_WIDGET_TYPE (e_minicard_widget_get_type ())
-#define E_MINICARD_WIDGET(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_WIDGET_TYPE, EMinicardWidget))
-#define E_MINICARD_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_WIDGET_TYPE, EMinicardWidgetClass))
-#define E_IS_MINICARD_WIDGET(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_WIDGET_TYPE))
-#define E_IS_MINICARD_WIDGET_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_WIDGET_TYPE))
-
-
-typedef struct _EMinicardWidget EMinicardWidget;
-typedef struct _EMinicardWidgetClass EMinicardWidgetClass;
-
-struct _EMinicardWidget
-{
- ECanvas parent;
-
- /* item specific fields */
- GnomeCanvasItem *item;
-
- GnomeCanvasItem *rect;
- ECard *card;
-};
-
-struct _EMinicardWidgetClass
-{
- ECanvasClass parent_class;
-};
-
-
-GtkWidget *e_minicard_widget_new(void);
-GtkType e_minicard_widget_get_type (void);
-
-void e_minicard_widget_set_card (EMinicardWidget *, ECard *);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-#endif /* __E_MINICARD_WIDGET_H__ */
diff --git a/addressbook/gui/widgets/e-minicard.c b/addressbook/gui/widgets/e-minicard.c
index 99e1d524fa..d5a1a3ce99 100644
--- a/addressbook/gui/widgets/e-minicard.c
+++ b/addressbook/gui/widgets/e-minicard.c
@@ -1,189 +1,243 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * e-minicard.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>
-#include <glib.h>
-#include <gtk/gtkdnd.h>
-#include <gdk/gdkkeysyms.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <gdk-pixbuf/gnome-canvas-pixbuf.h>
-#include <gal/e-text/e-text.h>
-#include <gal/util/e-util.h>
-#include <gal/widgets/e-canvas-utils.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/unicode/gunicode.h>
-#include "addressbook/backend/ebook/e-book.h"
-#include "e-addressbook-util.h"
+#endif
+
#include "e-minicard.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+
+#include <libgnomecanvas/libgnomecanvas.h>
+
+#include "e-util/e-util.h"
+
+#include "eab-book-util.h"
+#include "eab-gui-util.h"
#include "e-minicard-label.h"
#include "e-minicard-view.h"
-#include "e-contact-editor.h"
-#include "e-card-merging.h"
-
-static void e_minicard_init (EMinicard *card);
-static void e_minicard_class_init (EMinicardClass *klass);
-static void e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id);
-static void e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id);
-static void e_minicard_destroy (GtkObject *object);
-static void e_minicard_finalize (GtkObject *object);
+#include "ea-addressbook.h"
+
+static void e_minicard_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec);
+static void e_minicard_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec);
+static void e_minicard_dispose (GObject *object);
+static void e_minicard_finalize (GObject *object);
static gboolean e_minicard_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_minicard_realize (GnomeCanvasItem *item);
-static void e_minicard_unrealize (GnomeCanvasItem *item);
-static void e_minicard_reflow ( GnomeCanvasItem *item, int flags );
+static void e_minicard_reflow (GnomeCanvasItem *item, gint flags);
+static void e_minicard_style_set (EMinicard *minicard, GtkStyle *previous_style);
-static void e_minicard_resize_children( EMinicard *e_minicard );
-static void remodel( EMinicard *e_minicard );
+static void e_minicard_resize_children (EMinicard *e_minicard);
+static void remodel (EMinicard *e_minicard);
static gint e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event);
-static GnomeCanvasGroupClass *parent_class = NULL;
-
-typedef struct _EMinicardField EMinicardField;
-
-struct _EMinicardField {
- ECardSimpleField field;
- GnomeCanvasItem *label;
-};
-
#define d(x)
-#define LIST_ICON_FILENAME "contact-list-16.png"
-
-#define E_MINICARD_FIELD(field) ((EMinicardField *)(field))
+#define LIST_ICON_NAME "stock_contact-list"
static void
-e_minicard_field_destroy(EMinicardField *field)
+e_minicard_field_destroy (EMinicardField *field)
{
- gtk_object_destroy(GTK_OBJECT(field->label));
- g_free(field);
+ g_object_run_dispose (G_OBJECT (field->label));
+ g_free (field);
}
-/* The arguments we take */
enum {
- ARG_0,
- ARG_WIDTH,
- ARG_HEIGHT,
- ARG_HAS_FOCUS,
- ARG_SELECTED,
- ARG_HAS_CURSOR,
- ARG_EDITABLE,
- ARG_CARD
+ PROP_0,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_HAS_FOCUS,
+ PROP_SELECTED,
+ PROP_HAS_CURSOR,
+ PROP_EDITABLE,
+ PROP_CONTACT
};
enum {
SELECTED,
DRAG_BEGIN,
+ OPEN_CONTACT,
+ STYLE_SET,
LAST_SIGNAL
};
-static guint e_minicard_signals [LAST_SIGNAL] = {0, };
-
-GtkType
-e_minicard_get_type (void)
-{
- static GtkType minicard_type = 0;
-
- if (!minicard_type)
- {
- static const GtkTypeInfo minicard_info =
- {
- "EMinicard",
- sizeof (EMinicard),
- sizeof (EMinicardClass),
- (GtkClassInitFunc) e_minicard_class_init,
- (GtkObjectInitFunc) e_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- minicard_type = gtk_type_unique (gnome_canvas_group_get_type (), &minicard_info);
- }
-
- return minicard_type;
+static struct {
+ const gchar *name;
+ const gchar *pretty_name;
}
+common_location[] =
+{
+ { "WORK", N_ ("Work Email") },
+ { "HOME", N_ ("Home Email") },
+ { "OTHER", N_ ("Other Email") }
+};
+
+static guint signals[LAST_SIGNAL] = {0, };
+
+G_DEFINE_TYPE (EMinicard, e_minicard, GNOME_TYPE_CANVAS_GROUP)
static void
-e_minicard_class_init (EMinicardClass *klass)
+e_minicard_class_init (EMinicardClass *class)
{
- GtkObjectClass *object_class;
+ GObjectClass *object_class;
GnomeCanvasItemClass *item_class;
- object_class = (GtkObjectClass*) klass;
- item_class = (GnomeCanvasItemClass *) klass;
-
- parent_class = gtk_type_class (gnome_canvas_group_get_type ());
-
- gtk_object_add_arg_type ("EMinicard::width", GTK_TYPE_DOUBLE,
- GTK_ARG_READWRITE, ARG_WIDTH);
- gtk_object_add_arg_type ("EMinicard::height", GTK_TYPE_DOUBLE,
- GTK_ARG_READABLE, ARG_HEIGHT);
- gtk_object_add_arg_type ("EMinicard::has_focus", GTK_TYPE_ENUM,
- GTK_ARG_READWRITE, ARG_HAS_FOCUS);
- gtk_object_add_arg_type ("EMinicard::selected", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_SELECTED);
- gtk_object_add_arg_type ("EMinicard::has_cursor", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_HAS_CURSOR);
- gtk_object_add_arg_type ("EMinicard::editable", GTK_TYPE_BOOL,
- GTK_ARG_READWRITE, ARG_EDITABLE);
- gtk_object_add_arg_type ("EMinicard::card", GTK_TYPE_OBJECT,
- GTK_ARG_READWRITE, ARG_CARD);
-
- e_minicard_signals [SELECTED] =
- gtk_signal_new ("selected",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardClass, selected),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
- e_minicard_signals [DRAG_BEGIN] =
- gtk_signal_new ("drag_begin",
- GTK_RUN_LAST,
- object_class->type,
- GTK_SIGNAL_OFFSET (EMinicardClass, drag_begin),
- gtk_marshal_INT__POINTER,
- GTK_TYPE_INT, 1, GTK_TYPE_POINTER);
-
- gtk_object_class_add_signals (object_class, e_minicard_signals, LAST_SIGNAL);
-
- object_class->set_arg = e_minicard_set_arg;
- object_class->get_arg = e_minicard_get_arg;
- object_class->destroy = e_minicard_destroy;
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = e_minicard_set_property;
+ object_class->get_property = e_minicard_get_property;
+ object_class->dispose = e_minicard_dispose;
object_class->finalize = e_minicard_finalize;
-
- /* GnomeCanvasItem method overrides */
- item_class->realize = e_minicard_realize;
- item_class->unrealize = e_minicard_unrealize;
- item_class->event = e_minicard_event;
- klass->selected = NULL;
+ item_class = GNOME_CANVAS_ITEM_CLASS (class);
+ item_class->realize = e_minicard_realize;
+ item_class->event = e_minicard_event;
+
+ class->style_set = e_minicard_style_set;
+ class->selected = NULL;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_WIDTH,
+ g_param_spec_double (
+ "width",
+ "Width",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HEIGHT,
+ g_param_spec_double (
+ "height",
+ "Height",
+ NULL,
+ 0.0, G_MAXDOUBLE, 10.0,
+ G_PARAM_READABLE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_FOCUS,
+ /* XXX should be _enum */
+ g_param_spec_int (
+ "has_focus",
+ "Has Focus",
+ NULL,
+ E_MINICARD_FOCUS_TYPE_START,
+ E_MINICARD_FOCUS_TYPE_END,
+ E_MINICARD_FOCUS_TYPE_START,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SELECTED,
+ g_param_spec_boolean (
+ "selected",
+ "Selected",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_HAS_CURSOR,
+ g_param_spec_boolean (
+ "has_cursor",
+ "Has Cursor",
+ NULL,
+ FALSE,
+ 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_CONTACT,
+ g_param_spec_object (
+ "contact",
+ "Contact",
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ signals[SELECTED] = g_signal_new (
+ "selected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, selected),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[DRAG_BEGIN] = g_signal_new (
+ "drag_begin",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, drag_begin),
+ NULL, NULL,
+ e_marshal_INT__POINTER,
+ G_TYPE_INT, 1,
+ G_TYPE_POINTER);
+
+ signals[OPEN_CONTACT] = g_signal_new (
+ "open-contact",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EMinicardClass, open_contact),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_CONTACT);
+
+ signals[STYLE_SET] = g_signal_new (
+ "style_set",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EMinicardClass, style_set),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ GTK_TYPE_STYLE);
+
+ /* init the accessibility support for e_minicard */
+ e_minicard_a11y_init ();
}
static void
e_minicard_init (EMinicard *minicard)
{
- /* minicard->card = NULL;*/
minicard->rect = NULL;
minicard->fields = NULL;
minicard->width = 10;
@@ -193,163 +247,186 @@ e_minicard_init (EMinicard *minicard)
minicard->editable = FALSE;
minicard->has_cursor = FALSE;
- minicard->card = NULL;
- minicard->simple = e_card_simple_new(NULL);
+ minicard->contact = NULL;
- minicard->list_icon_pixbuf = gdk_pixbuf_new_from_file (EVOLUTION_IMAGESDIR "/" LIST_ICON_FILENAME);
+ minicard->list_icon_pixbuf = e_icon_factory_get_icon (LIST_ICON_NAME, GTK_ICON_SIZE_MENU);
minicard->list_icon_size = gdk_pixbuf_get_height (minicard->list_icon_pixbuf);
- minicard->editor = NULL;
-
minicard->changed = FALSE;
- e_canvas_item_set_reflow_callback(GNOME_CANVAS_ITEM(minicard), e_minicard_reflow);
+ e_canvas_item_set_reflow_callback (GNOME_CANVAS_ITEM (minicard), e_minicard_reflow);
}
static void
-set_selected (EMinicard *minicard, gboolean selected)
+set_selected (EMinicard *minicard,
+ gboolean selected)
{
- GtkWidget *canvas = GTK_WIDGET(GNOME_CANVAS_ITEM(minicard)->canvas);
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ canvas = GNOME_CANVAS_ITEM (minicard)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
if (selected) {
- gnome_canvas_item_set (minicard->rect,
- "outline_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL);
- gnome_canvas_item_set (minicard->header_rect,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_SELECTED],
- NULL);
- gnome_canvas_item_set (minicard->header_text,
- "fill_color_gdk", &canvas->style->text[GTK_STATE_SELECTED],
- NULL);
+ gnome_canvas_item_set (
+ minicard->rect,
+ "outline_color_gdk", &style->bg[GTK_STATE_ACTIVE],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_rect,
+ "fill_color_gdk", &style->bg[GTK_STATE_SELECTED],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_text,
+ "fill_color_gdk", &style->text[GTK_STATE_SELECTED],
+ NULL);
} else {
- gnome_canvas_item_set (minicard->rect,
- "outline_color", NULL,
- NULL);
- gnome_canvas_item_set (minicard->header_rect,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL);
- gnome_canvas_item_set (minicard->header_text,
- "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL],
- NULL);
+ gnome_canvas_item_set (
+ minicard->rect,
+ "outline_color", NULL,
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_rect,
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+ gnome_canvas_item_set (
+ minicard->header_text,
+ "fill_color_gdk", &style->text[GTK_STATE_NORMAL],
+ NULL);
}
minicard->selected = selected;
}
static void
-set_has_cursor (EMinicard *minicard, gboolean has_cursor)
+set_has_cursor (EMinicard *minicard,
+ gboolean has_cursor)
{
if (!minicard->has_focus && has_cursor)
- e_canvas_item_grab_focus(GNOME_CANVAS_ITEM (minicard), FALSE);
+ e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (minicard), FALSE);
minicard->has_cursor = has_cursor;
}
-
static void
-e_minicard_set_arg (GtkObject *o, GtkArg *arg, guint arg_id)
+e_minicard_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
GnomeCanvasItem *item;
EMinicard *e_minicard;
+ EContact *contact;
GList *l;
- item = GNOME_CANVAS_ITEM (o);
- e_minicard = E_MINICARD (o);
-
- switch (arg_id){
- case ARG_WIDTH:
- if (e_minicard->width != GTK_VALUE_DOUBLE (*arg)) {
- e_minicard->width = GTK_VALUE_DOUBLE (*arg);
- e_minicard_resize_children(e_minicard);
- if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED )
- e_canvas_item_request_reflow(item);
+ item = GNOME_CANVAS_ITEM (object);
+ e_minicard = E_MINICARD (object);
+
+ switch (property_id) {
+ case PROP_WIDTH:
+ if (e_minicard->width != g_value_get_double (value)) {
+ e_minicard->width = g_value_get_double (value);
+ e_minicard_resize_children (e_minicard);
+ if (item->flags & GNOME_CANVAS_ITEM_REALIZED)
+ e_canvas_item_request_reflow (item);
}
break;
- case ARG_HAS_FOCUS:
+ case PROP_HAS_FOCUS:
if (e_minicard->fields) {
- if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_START ||
- GTK_VALUE_ENUM(*arg) == E_FOCUS_CURRENT) {
- gnome_canvas_item_set(E_MINICARD_FIELD(e_minicard->fields->data)->label,
- "has_focus", GTK_VALUE_ENUM(*arg),
- NULL);
- } else if ( GTK_VALUE_ENUM(*arg) == E_FOCUS_END ) {
- gnome_canvas_item_set(E_MINICARD_FIELD(g_list_last(e_minicard->fields)->data)->label,
- "has_focus", GTK_VALUE_ENUM(*arg),
- NULL);
+ if (g_value_get_int (value) == E_FOCUS_START ||
+ g_value_get_int (value) == E_FOCUS_CURRENT) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (e_minicard->fields->data)->label,
+ "has_focus", g_value_get_int (value),
+ NULL);
+ } else if (g_value_get_int (value) == E_FOCUS_END) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (g_list_last (e_minicard->fields)->data)->label,
+ "has_focus", g_value_get_int (value),
+ NULL);
}
}
else {
if (!e_minicard->has_focus)
- e_canvas_item_grab_focus(item, FALSE);
+ e_canvas_item_grab_focus (item, FALSE);
}
break;
- case ARG_SELECTED:
- if (e_minicard->selected != GTK_VALUE_BOOL(*arg))
- set_selected (e_minicard, GTK_VALUE_BOOL(*arg));
+ case PROP_SELECTED:
+ if (e_minicard->selected != g_value_get_boolean (value))
+ set_selected (e_minicard, g_value_get_boolean (value));
break;
- case ARG_EDITABLE:
- e_minicard->editable = GTK_VALUE_BOOL(*arg);
- for (l = e_minicard->fields; l; l = l->next)
- gtk_object_set (GTK_OBJECT (E_MINICARD_FIELD (l->data)->label),
- "editable", e_minicard->editable,
- NULL);
+ case PROP_EDITABLE:
+ e_minicard->editable = g_value_get_boolean (value);
+ for (l = e_minicard->fields; l; l = l->next) {
+ g_object_set (
+ E_MINICARD_FIELD (l->data)->label,
+ "editable", FALSE /* e_minicard->editable */,
+ NULL);
+ }
break;
- case ARG_HAS_CURSOR:
- d(g_print("%s: ARG_HAS_CURSOR\n", __FUNCTION__));
- if (e_minicard->has_cursor != GTK_VALUE_BOOL(*arg))
- set_has_cursor (e_minicard, GTK_VALUE_BOOL(*arg));
+ case PROP_HAS_CURSOR:
+ d (g_print ("%s: PROP_HAS_CURSOR\n", G_STRFUNC));
+ if (e_minicard->has_cursor != g_value_get_boolean (value))
+ set_has_cursor (e_minicard, g_value_get_boolean (value));
break;
- case ARG_CARD:
- if (e_minicard->card)
- gtk_object_unref (GTK_OBJECT(e_minicard->card));
- e_minicard->card = E_CARD(GTK_VALUE_OBJECT (*arg));
- if (e_minicard->card)
- gtk_object_ref (GTK_OBJECT(e_minicard->card));
- gtk_object_set(GTK_OBJECT(e_minicard->simple),
- "card", e_minicard->card,
- NULL);
- remodel(e_minicard);
- e_canvas_item_request_reflow(item);
+ case PROP_CONTACT:
+ contact = E_CONTACT (g_value_get_object (value));
+ if (contact)
+ g_object_ref (contact);
+
+ if (e_minicard->contact)
+ g_object_unref (e_minicard->contact);
+
+ e_minicard->contact = contact;
+
+ remodel (e_minicard);
+ e_canvas_item_request_reflow (item);
e_minicard->changed = FALSE;
break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_get_arg (GtkObject *object, GtkArg *arg, guint arg_id)
+e_minicard_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
{
EMinicard *e_minicard;
e_minicard = E_MINICARD (object);
- switch (arg_id) {
- case ARG_WIDTH:
- GTK_VALUE_DOUBLE (*arg) = e_minicard->width;
- break;
- case ARG_HEIGHT:
- GTK_VALUE_DOUBLE (*arg) = e_minicard->height;
- break;
- case ARG_HAS_FOCUS:
- GTK_VALUE_ENUM (*arg) = e_minicard->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE;
+ switch (property_id) {
+ case PROP_WIDTH:
+ g_value_set_double (value, e_minicard->width);
+ break;
+ case PROP_HEIGHT:
+ g_value_set_double (value, e_minicard->height);
+ break;
+ case PROP_HAS_FOCUS:
+ g_value_set_int (value, e_minicard->has_focus ? E_FOCUS_CURRENT : E_FOCUS_NONE);
break;
- case ARG_SELECTED:
- GTK_VALUE_BOOL (*arg) = e_minicard->selected;
+ case PROP_SELECTED:
+ g_value_set_boolean (value, e_minicard->selected);
break;
- case ARG_HAS_CURSOR:
- GTK_VALUE_BOOL (*arg) = e_minicard->has_cursor;
+ case PROP_HAS_CURSOR:
+ g_value_set_boolean (value, e_minicard->has_cursor);
break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = e_minicard->editable;
+ case PROP_EDITABLE:
+ g_value_set_boolean (value, e_minicard->editable);
break;
- case ARG_CARD:
- e_card_simple_sync_card(e_minicard->simple);
- GTK_VALUE_OBJECT (*arg) = GTK_OBJECT(e_minicard->card);
+ case PROP_CONTACT:
+ g_value_set_object (value, e_minicard->contact);
break;
default:
- arg->type = GTK_TYPE_INVALID;
- break;
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
}
}
static void
-e_minicard_destroy (GtkObject *object)
+e_minicard_dispose (GObject *object)
{
EMinicard *e_minicard;
@@ -357,20 +434,24 @@ e_minicard_destroy (GtkObject *object)
g_return_if_fail (E_IS_MINICARD (object));
e_minicard = E_MINICARD (object);
-
- g_list_foreach(e_minicard->fields, (GFunc) e_minicard_field_destroy, NULL);
- g_list_free(e_minicard->fields);
-
- gdk_pixbuf_unref (e_minicard->list_icon_pixbuf);
- if (GTK_OBJECT_CLASS (parent_class)->destroy)
- (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
+ if (e_minicard->fields) {
+ g_list_foreach (e_minicard->fields, (GFunc) e_minicard_field_destroy, NULL);
+ g_list_free (e_minicard->fields);
+ e_minicard->fields = NULL;
+ }
+ if (e_minicard->list_icon_pixbuf) {
+ g_object_unref (e_minicard->list_icon_pixbuf);
+ e_minicard->list_icon_pixbuf = NULL;
+ }
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_minicard_parent_class)->dispose (object);
+}
static void
-e_minicard_finalize (GtkObject *object)
+e_minicard_finalize (GObject *object)
{
EMinicard *e_minicard;
@@ -378,178 +459,149 @@ e_minicard_finalize (GtkObject *object)
g_return_if_fail (E_IS_MINICARD (object));
e_minicard = E_MINICARD (object);
-
- if (e_minicard->card)
- gtk_object_unref (GTK_OBJECT(e_minicard->card));
- if (e_minicard->simple)
- gtk_object_unref (GTK_OBJECT(e_minicard->simple));
-
- if (GTK_OBJECT_CLASS (parent_class)->finalize)
- (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
-static void
-e_minicard_realize (GnomeCanvasItem *item)
-{
- EMinicard *e_minicard;
- GnomeCanvasGroup *group;
- GtkWidget *canvas;
- e_minicard = E_MINICARD (item);
- group = GNOME_CANVAS_GROUP( item );
- canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas);
-
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->realize)
- (* GNOME_CANVAS_ITEM_CLASS(parent_class)->realize) (item);
-
- e_minicard->rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) e_minicard->width - 1,
- "y2", (double) e_minicard->height - 1,
- "outline_color", NULL,
- NULL );
-
- e_minicard->header_rect =
- gnome_canvas_item_new( group,
- gnome_canvas_rect_get_type(),
- "x1", (double) 2,
- "y1", (double) 2,
- "x2", (double) e_minicard->width - 3,
- "y2", (double) e_minicard->height - 3,
- "fill_color_gdk", &canvas->style->bg[GTK_STATE_NORMAL],
- NULL );
-
- e_minicard->header_text =
- gnome_canvas_item_new( group,
- e_text_get_type(),
- "anchor", GTK_ANCHOR_NW,
- "width", (double) ( e_minicard->width - 12 ),
- "clip", TRUE,
- "use_ellipsis", TRUE,
-#if 0
- "font", "fixed-bold-10",
-#endif
- "fill_color_gdk", &canvas->style->fg[GTK_STATE_NORMAL],
- "text", "",
- "draw_background", FALSE,
- NULL );
-
- e_canvas_item_move_absolute(e_minicard->header_text, 6, 6);
-
- e_minicard->list_icon =
- gnome_canvas_item_new ( group,
- gnome_canvas_pixbuf_get_type(),
- "pixbuf", e_minicard->list_icon_pixbuf,
- NULL);
-
- remodel(e_minicard);
- e_canvas_item_request_reflow(item);
+ if (e_minicard->contact) {
+ g_object_unref (e_minicard->contact);
+ e_minicard->contact = NULL;
+ }
- if (!item->canvas->aa) {
+ if (e_minicard->list_icon_pixbuf) {
+ g_object_unref (e_minicard->list_icon_pixbuf);
+ e_minicard->list_icon_pixbuf = NULL;
}
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_minicard_parent_class)->finalize (object);
}
static void
-e_minicard_unrealize (GnomeCanvasItem *item)
+e_minicard_style_set (EMinicard *minicard,
+ GtkStyle *previous_style)
{
- EMinicard *e_minicard;
-
- e_minicard = E_MINICARD (item);
-
- if (!item->canvas->aa)
- {
- }
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (minicard);
- if (GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize)
- (* GNOME_CANVAS_ITEM_CLASS(parent_class)->unrealize) (item);
+ if ((item->flags & GNOME_CANVAS_ITEM_REALIZED))
+ set_selected (minicard, minicard->selected);
}
static void
-card_modified_cb (EBook* book, EBookStatus status, gpointer user_data)
+e_minicard_realize (GnomeCanvasItem *item)
{
- d(g_print ("%s: %s(): a card was modified\n", __FILE__, __FUNCTION__));
- if (status != E_BOOK_STATUS_SUCCESS)
- e_addressbook_error_dialog (_("Error modifying card"), status);
+ EMinicard *e_minicard;
+ GnomeCanvasGroup *group;
+ GnomeCanvas *canvas;
+ GtkStyle *style;
+
+ e_minicard = E_MINICARD (item);
+ group = GNOME_CANVAS_GROUP (item);
+
+ canvas = GNOME_CANVAS_ITEM (item)->canvas;
+ style = gtk_widget_get_style (GTK_WIDGET (canvas));
+
+ GNOME_CANVAS_ITEM_CLASS (e_minicard_parent_class)->realize (item);
+
+ e_minicard->rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 0,
+ "y1", (gdouble) 0,
+ "x2", (gdouble) MAX (e_minicard->width - 1, 0),
+ "y2", (gdouble) MAX (e_minicard->height - 1, 0),
+ "outline_color", NULL,
+ NULL);
+
+ e_minicard->header_rect = gnome_canvas_item_new (
+ group,
+ gnome_canvas_rect_get_type (),
+ "x1", (gdouble) 2,
+ "y1", (gdouble) 2,
+ "x2", (gdouble) MAX (e_minicard->width - 3, 0),
+ "y2", (gdouble) MAX (e_minicard->height - 3, 0),
+ "fill_color_gdk", &style->bg[GTK_STATE_NORMAL],
+ NULL);
+
+ e_minicard->header_text = gnome_canvas_item_new (
+ group,
+ e_text_get_type (),
+ "width", (gdouble) MAX (e_minicard->width - 12, 0),
+ "clip", TRUE,
+ "use_ellipsis", TRUE,
+ "fill_color_gdk", &style->fg[GTK_STATE_NORMAL],
+ "text", "",
+ NULL);
+
+ e_canvas_item_move_absolute (e_minicard->header_text, 6, 6);
+
+ e_minicard->list_icon = gnome_canvas_item_new (
+ group,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", e_minicard->list_icon_pixbuf,
+ NULL);
+
+ set_selected (e_minicard, e_minicard->selected);
+
+ remodel (e_minicard);
+ e_canvas_item_request_reflow (item);
}
-/* Callback used when the contact editor is closed */
-static void
-editor_closed_cb (GtkObject *editor, gpointer data)
+void
+e_minicard_activate_editor (EMinicard *minicard)
{
- EMinicard *minicard = data;
- gtk_object_unref (GTK_OBJECT (editor));
- minicard->editor = NULL;
+ g_return_if_fail (E_IS_MINICARD (minicard));
+
+ g_signal_emit (minicard, signals[OPEN_CONTACT], 0, minicard->contact);
}
static gboolean
-e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
+e_minicard_event (GnomeCanvasItem *item,
+ GdkEvent *event)
{
EMinicard *e_minicard;
- GtkWidget *canvas;
-
+
e_minicard = E_MINICARD (item);
- canvas = GTK_WIDGET (GNOME_CANVAS_ITEM (item)->canvas);
-
- switch( event->type ) {
+
+ switch (event->type) {
case GDK_FOCUS_CHANGE:
{
GdkEventFocus *focus_event = (GdkEventFocus *) event;
- d(g_print("%s: GDK_FOCUS_CHANGE: %s\n", __FUNCTION__, focus_event->in?"in":"out"));
+ d (g_print ("%s: GDK_FOCUS_CHANGE: %s\n", G_STRFUNC, focus_event->in?"in":"out"));
if (focus_event->in) {
/* Chris: When EMinicard gets the cursor, if it doesn't have the focus, it should take it. */
e_minicard->has_focus = TRUE;
if (!e_minicard->selected) {
- e_minicard_selected(e_minicard, event);
- }
- } else {
- EBook *book = NULL;
-
- if (e_minicard->changed) {
-
- e_card_simple_sync_card(e_minicard->simple);
-
- if (E_IS_MINICARD_VIEW(GNOME_CANVAS_ITEM(e_minicard)->parent)) {
-
- gtk_object_get(GTK_OBJECT(GNOME_CANVAS_ITEM(e_minicard)->parent),
- "book", &book,
- NULL);
-
- }
-
- if (book) {
-
- /* Add the card in the contact editor to our ebook */
- e_card_merging_book_commit_card (book,
- e_minicard->card,
- card_modified_cb,
- NULL);
- } else {
- remodel(e_minicard);
- e_canvas_item_request_reflow(GNOME_CANVAS_ITEM(e_minicard));
- }
- e_minicard->changed = FALSE;
+ e_minicard_selected (e_minicard, event);
}
+ }
+ else {
e_minicard->has_focus = FALSE;
}
}
break;
case GDK_BUTTON_PRESS: {
if (1 <= event->button.button && event->button.button <= 2) {
- int ret_val = e_minicard_selected(e_minicard, event);
- GdkEventMask mask = ((1 << (4 + event->button.button)) |
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK);
-
- e_canvas_item_grab_focus(item, TRUE);
-
- if (gnome_canvas_item_grab (GNOME_CANVAS_ITEM (e_minicard),
- mask, NULL, event->button.time)) {
+ gint ret_val = e_minicard_selected (e_minicard, event);
+ GdkGrabStatus grab_status;
+ GdkDevice *event_device;
+ guint32 event_time;
+
+ e_canvas_item_grab_focus (item, TRUE);
+
+ event_device = gdk_event_get_device (event);
+ event_time = gdk_event_get_time (event);
+
+ grab_status = gnome_canvas_item_grab (
+ GNOME_CANVAS_ITEM (e_minicard),
+ (1 << (4 + event->button.button)) |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK,
+ NULL,
+ event_device,
+ event_time);
+
+ if (grab_status != GDK_GRAB_SUCCESS)
return FALSE;
- }
+
gtk_grab_add (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
e_minicard->button_x = event->button.x;
e_minicard->button_y = event->button.y;
@@ -557,21 +609,21 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
e_minicard->drag_button_down = TRUE;
return ret_val;
} else if (event->button.button == 3) {
- int ret_val = e_minicard_selected(e_minicard, event);
+ gint ret_val = e_minicard_selected (e_minicard, event);
if (ret_val != 0)
return ret_val;
}
break;
}
case GDK_BUTTON_RELEASE:
- e_minicard_selected(e_minicard, event);
+ e_minicard_selected (e_minicard, event);
if (e_minicard->drag_button == event->button.button) {
e_minicard->drag_button = 0;
e_minicard->drag_button_down = FALSE;
e_minicard->button_x = -1;
e_minicard->button_y = -1;
- if (GTK_WIDGET_HAS_GRAB (GNOME_CANVAS_ITEM (e_minicard)->canvas)) {
+ if (gtk_widget_has_grab (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas))) {
gtk_grab_remove (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas));
gnome_canvas_item_ungrab (GNOME_CANVAS_ITEM (e_minicard), event->button.time);
}
@@ -583,7 +635,7 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
abs (e_minicard->button_y - event->motion.y)) > 3) {
gint ret_val;
- ret_val = e_minicard_drag_begin(e_minicard, event);
+ ret_val = e_minicard_drag_begin (e_minicard, event);
e_minicard->drag_button_down = FALSE;
@@ -592,408 +644,555 @@ e_minicard_event (GnomeCanvasItem *item, GdkEvent *event)
}
break;
case GDK_2BUTTON_PRESS:
- if (event->button.button == 1 && E_IS_MINICARD_VIEW(item->parent)) {
- if (e_minicard->editor) {
- if (e_card_evolution_list (e_minicard->card))
- e_contact_list_editor_raise (E_CONTACT_LIST_EDITOR(e_minicard->editor));
- else
- e_contact_editor_raise(E_CONTACT_EDITOR(e_minicard->editor));
- } else {
- EBook *book = NULL;
- if (E_IS_MINICARD_VIEW(item->parent)) {
- gtk_object_get(GTK_OBJECT(item->parent),
- "book", &book,
- NULL);
+ if (event->button.button == 1 && E_IS_MINICARD_VIEW (item->parent)) {
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
+ }
+ break;
+ case GDK_KEY_PRESS:
+ if (event->key.keyval == GDK_KEY_Tab ||
+ event->key.keyval == GDK_KEY_KP_Tab ||
+ event->key.keyval == GDK_KEY_ISO_Left_Tab) {
+
+ EMinicardView *view = E_MINICARD_VIEW (item->parent);
+ EReflow *reflow = E_REFLOW (view);
+
+ if (reflow == NULL) {
+ return FALSE;
+ }
+
+ if (event->key.state & GDK_SHIFT_MASK) {
+ if (event->key.state & GDK_CONTROL_MASK) {
+ return FALSE;
}
+ else {
+ gint row_count = e_selection_model_row_count (reflow->selection);
+ gint model_index = e_selection_model_cursor_row (reflow->selection);
+ gint view_index = e_sorter_model_to_sorted (reflow->selection->sorter, model_index);
- if (book != NULL) {
- if (e_card_evolution_list (e_minicard->card)) {
- EContactListEditor *editor = e_addressbook_show_contact_list_editor (book, e_minicard->card,
- FALSE, e_minicard->editable);
- e_minicard->editor = GTK_OBJECT (editor);
- }
- else {
- EContactEditor *editor = e_addressbook_show_contact_editor (book, e_minicard->card,
- FALSE, e_minicard->editable);
- e_minicard->editor = GTK_OBJECT (editor);
- }
- gtk_object_ref (e_minicard->editor);
+ if (view_index == 0)
+ view_index = row_count - 1;
+ else
+ view_index--;
- gtk_signal_connect (e_minicard->editor, "editor_closed",
- GTK_SIGNAL_FUNC (editor_closed_cb), e_minicard);
+ model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
+ if (reflow->items[model_index] == NULL) {
+ reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[model_index],
+ "width", (gdouble) reflow->column_width,
+ NULL);
+ }
+ e_canvas_item_grab_focus (reflow->items[model_index], FALSE);
+ return TRUE;
}
}
- return TRUE;
- }
- break;
- case GDK_KEY_PRESS:
- if (event->key.keyval == GDK_Tab ||
- event->key.keyval == GDK_KP_Tab ||
- event->key.keyval == GDK_ISO_Left_Tab) {
- GList *list;
- for (list = e_minicard->fields; list; list = list->next) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
- GnomeCanvasItem *item = field->label;
- EFocus has_focus;
- gtk_object_get(GTK_OBJECT(item),
- "has_focus", &has_focus,
- NULL);
- if (has_focus != E_FOCUS_NONE) {
- if (event->key.state & GDK_SHIFT_MASK)
- list = list->prev;
+ else {
+ if (event->key.state & GDK_CONTROL_MASK) {
+ return FALSE;
+ }
+ else {
+ gint row_count = e_selection_model_row_count (reflow->selection);
+ gint model_index = e_selection_model_cursor_row (reflow->selection);
+ gint view_index = e_sorter_model_to_sorted (reflow->selection->sorter, model_index);
+
+ if (view_index == row_count - 1)
+ view_index = 0;
else
- list = list->next;
- if (list) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
- GnomeCanvasItem *item = field->label;
- gnome_canvas_item_set(item,
- "has_focus", (event->key.state & GDK_SHIFT_MASK) ? E_FOCUS_END : E_FOCUS_START,
- NULL);
- return 1;
- } else {
- return 0;
+ view_index++;
+
+ model_index = e_sorter_sorted_to_model (E_SORTER (reflow->sorter), view_index);
+ if (reflow->items[model_index] == NULL) {
+ reflow->items[model_index] = e_reflow_model_incarnate (reflow->model, model_index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[model_index],
+ "width", (gdouble) reflow->column_width,
+ NULL);
+
}
+ e_canvas_item_grab_focus (reflow->items[model_index], FALSE);
+ return TRUE;
}
}
}
+ else if (event->key.keyval == GDK_KEY_Return ||
+ event->key.keyval == GDK_KEY_KP_Enter) {
+ e_minicard_activate_editor (e_minicard);
+ return TRUE;
+ }
+ break;
default:
break;
}
-
- if (GNOME_CANVAS_ITEM_CLASS( parent_class )->event)
- return (* GNOME_CANVAS_ITEM_CLASS( parent_class )->event) (item, event);
- else
- return 0;
+
+ return FALSE;
}
static void
-e_minicard_resize_children( EMinicard *e_minicard )
+e_minicard_resize_children (EMinicard *e_minicard)
{
GList *list;
-
+ gboolean is_list = GPOINTER_TO_INT (e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST));
+
if (e_minicard->header_text) {
- gnome_canvas_item_set( e_minicard->header_text,
- "width", ((double) e_minicard->width - 12
- - (e_card_evolution_list (e_minicard->card) ? e_minicard->list_icon_size : 0.0)),
- NULL );
+ gnome_canvas_item_set (
+ e_minicard->header_text,
+ "width", ((gdouble) e_minicard->width - 12
+ - (is_list ? e_minicard->list_icon_size : 0.0)),
+ NULL);
}
if (e_minicard->list_icon) {
- e_canvas_item_move_absolute(e_minicard->list_icon,
- e_minicard->width - e_minicard->list_icon_size - 3,
- 3);
+ e_canvas_item_move_absolute (
+ e_minicard->list_icon,
+ e_minicard->width - e_minicard->list_icon_size - 3,
+ 3);
}
- for ( list = e_minicard->fields; list; list = g_list_next( list ) ) {
- gnome_canvas_item_set( E_MINICARD_FIELD( list->data )->label,
- "width", (double) e_minicard->width - 4.0,
- NULL );
+ for (list = e_minicard->fields; list; list = g_list_next (list)) {
+ gnome_canvas_item_set (
+ E_MINICARD_FIELD (list->data)->label,
+ "width", (gdouble) e_minicard->width - 4.0,
+ NULL);
}
}
static void
-field_changed (EText *text, EMinicard *e_minicard)
+add_field (EMinicard *e_minicard,
+ EContactField field,
+ gdouble left_width)
{
- ECardSimpleType type;
- char *string;
-
- type = GPOINTER_TO_INT
- (gtk_object_get_data(GTK_OBJECT(text),
- "EMinicard:field"));
- gtk_object_get(GTK_OBJECT(text),
- "text", &string,
- NULL);
- e_card_simple_set(e_minicard->simple,
- type,
- string);
- g_free(string);
- e_minicard->changed = TRUE;
+ GnomeCanvasItem *new_item;
+ GnomeCanvasGroup *group;
+ EMinicardField *minicard_field;
+ gchar *name;
+ gchar *string;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
+
+ group = GNOME_CANVAS_GROUP (e_minicard);
+
+ name = g_strdup_printf ("%s:", e_contact_pretty_name (field));
+ string = e_contact_get (e_minicard->contact, field);
+
+ new_item = e_minicard_label_new (group);
+
+ if (e_minicard->contact && e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST))
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? "" : string,
+ "field", is_rtl ? string : "",
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+ else
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? string : name,
+ "field", is_rtl ? name : string,
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+
+#ifdef notyet
+ g_object_set (
+ E_MINICARD_LABEL (new_item)->field,
+ "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->contact, field),
+ NULL);
+#endif
+ g_object_set_data (
+ G_OBJECT (E_MINICARD_LABEL (new_item)->field),
+ "EMinicard:field",
+ GINT_TO_POINTER (field));
+
+ minicard_field = g_new (EMinicardField, 1);
+ minicard_field->field = field;
+ minicard_field->label = new_item;
+
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ e_canvas_item_move_absolute (new_item, 2, e_minicard->height);
+ g_free (name);
+ g_free (string);
}
-static void
-field_activated (EText *text, EMinicard *e_minicard)
+static const gchar *
+get_email_location (EVCardAttribute *attr)
{
- e_text_stop_editing (text);
- e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (e_minicard), FALSE);
+ gint i;
+
+ for (i = 0; i < G_N_ELEMENTS (common_location); i++) {
+ if (e_vcard_attribute_has_type (attr, common_location[i].name))
+ return _(common_location[i].pretty_name);
+ }
+
+ return _("Other Email");
}
static void
-add_field (EMinicard *e_minicard, ECardSimpleField field, gdouble left_width)
+add_email_field (EMinicard *e_minicard,
+ GList *email_list,
+ gdouble left_width,
+ gint limit,
+ gboolean is_list)
{
GnomeCanvasItem *new_item;
GnomeCanvasGroup *group;
- ECardSimpleType type;
EMinicardField *minicard_field;
- char *name;
- char *string;
-
- group = GNOME_CANVAS_GROUP( e_minicard );
-
- type = e_card_simple_type(e_minicard->simple, field);
- name = g_strdup_printf("%s:", e_card_simple_get_name(e_minicard->simple, field));
- string = e_card_simple_get(e_minicard->simple, field);
-
- /* Magically convert embedded XML into an address. */
- if (!strncmp (string, "<?xml", 5)) {
- EDestination *dest = e_destination_import (string);
- if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
- g_free (string);
- string = new_string;
- gtk_object_unref (GTK_OBJECT (dest));
+ gchar *name;
+ GList *l, *le;
+ gint count =0;
+ gboolean is_rtl = (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL);
+ GList *emails = e_contact_get (e_minicard->contact, E_CONTACT_EMAIL);
+ group = GNOME_CANVAS_GROUP (e_minicard);
+
+ for (l = email_list, le = emails; l != NULL && count < limit && le != NULL; l = l->next, le = le->next) {
+ const gchar *tmp;
+ gchar *email = NULL;
+ gchar *string = NULL;
+ gchar *parsed_name = NULL;
+ gboolean parser_check;
+
+ /* do not use name for fields in the contact list */
+ if (is_list) {
+ name = (gchar *)"";
+ } else {
+ tmp = get_email_location ((EVCardAttribute *) l->data);
+ name = g_strdup_printf ("%s:", tmp);
}
- }
- new_item = e_minicard_label_new(group);
- gnome_canvas_item_set( new_item,
- "width", e_minicard->width - 4.0,
- "fieldname", name,
- "field", string,
- "max_field_name_length", left_width,
- "editable", e_minicard->editable,
- NULL );
- gtk_signal_connect(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "changed", GTK_SIGNAL_FUNC(field_changed), e_minicard);
- gtk_signal_connect(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "activate", GTK_SIGNAL_FUNC(field_activated), e_minicard);
- gtk_object_set(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->simple, field),
- NULL);
- gtk_object_set_data(GTK_OBJECT(E_MINICARD_LABEL(new_item)->field),
- "EMinicard:field",
- GINT_TO_POINTER(field));
-
- minicard_field = g_new(EMinicardField, 1);
- minicard_field->field = field;
- minicard_field->label = new_item;
+ parser_check = eab_parse_qp_email ((const gchar *) le->data, &parsed_name, &email);
+ if (parser_check) {
+ /* if true, we had a quoted printable mail address */
+ string = g_strdup_printf ("%s <%s>", parsed_name, email);
+ } else {
+ /* we got a NON-quoted printable string */
+ string = g_strdup (le->data);
+ }
- e_minicard->fields = g_list_append( e_minicard->fields, minicard_field);
- e_canvas_item_move_absolute(new_item, 2, e_minicard->height);
- g_free(name);
- g_free(string);
+ new_item = e_minicard_label_new (group);
+
+ gnome_canvas_item_set (
+ new_item,
+ "fieldname", is_rtl ? string : name,
+ "field", is_rtl ? name : string,
+ "max_field_name_length", left_width,
+ "editable", FALSE /* e_minicard->editable */,
+ "width", e_minicard->width - 4.0,
+ NULL);
+
+#ifdef notyet
+ g_object_set (
+ E_MINICARD_LABEL (new_item)->field,
+ "allow_newlines", e_card_simple_get_allow_newlines (e_minicard->contact, field),
+ NULL);
+#endif
+ g_object_set_data (
+ G_OBJECT (E_MINICARD_LABEL (new_item)->field),
+ "EMinicard:field",
+ GINT_TO_POINTER (E_CONTACT_EMAIL));
+
+ minicard_field = g_new (EMinicardField, 1);
+ minicard_field->field = E_CONTACT_EMAIL;
+ minicard_field->label = new_item;
+
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ e_canvas_item_move_absolute (new_item, 2, e_minicard->height);
+ count++;
+ if (!is_list)
+ g_free (name);
+ g_free (string);
+ g_free (parsed_name);
+ g_free (email);
+ }
+ g_list_foreach (emails, (GFunc) g_free, NULL);
+ g_list_free (emails);
}
-static gdouble
-get_left_width(EMinicard *e_minicard)
+static gint
+get_left_width (EMinicard *e_minicard,
+ gboolean is_list)
{
gchar *name;
- ECardSimpleField field;
- gdouble width = -1;
- GdkFont *font;
+ EContactField field;
+ gint width = -1;
+ PangoLayout *layout;
+
+ if (is_list)
+ return 0;
+
+ layout = gtk_widget_create_pango_layout (GTK_WIDGET (GNOME_CANVAS_ITEM (e_minicard)->canvas), "");
+ for (field = E_CONTACT_FULL_NAME; field != E_CONTACT_LAST_SIMPLE_STRING; field++) {
+ gint this_width;
- font = ((GtkWidget *) ((GnomeCanvasItem *) e_minicard)->canvas)->style->font;
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME)
+ continue;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST; field++) {
- gdouble this_width;
- name = g_strdup_printf("%s:", e_card_simple_get_name(e_minicard->simple, field));
- this_width = gdk_text_width(font, name, strlen(name));
+ name = g_strdup_printf ("%s:", e_contact_pretty_name (field));
+ pango_layout_set_text (layout, name, -1);
+ pango_layout_get_pixel_size (layout, &this_width, NULL);
if (width < this_width)
width = this_width;
- g_free(name);
+ g_free (name);
}
+ g_object_unref (layout);
return width;
}
static void
-remodel( EMinicard *e_minicard )
+remodel (EMinicard *e_minicard)
{
- int count = 0;
- if ( !(GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED) )
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (e_minicard);
+ gint count = 0;
+
+ if (!(item->flags & GNOME_CANVAS_ITEM_REALIZED))
return;
- if (e_minicard->simple) {
- ECardSimpleField field;
+
+ if (e_minicard->contact) {
+ EContactField field;
GList *list;
- char *file_as;
- gdouble left_width = -1;
+ gchar *file_as;
+ gint left_width = -1;
+ gboolean is_list = FALSE;
+ gboolean email_rendered = FALSE;
+ gboolean has_voice = FALSE, has_fax = FALSE;
if (e_minicard->header_text) {
- file_as = e_card_simple_get(e_minicard->simple, E_CARD_SIMPLE_FIELD_FILE_AS);
- gnome_canvas_item_set( e_minicard->header_text,
- "text", file_as ? file_as : "",
- NULL );
- g_free(file_as);
+ file_as = e_contact_get (e_minicard->contact, E_CONTACT_FILE_AS);
+ gnome_canvas_item_set (
+ e_minicard->header_text,
+ "text", file_as ? file_as : "",
+ NULL);
+ g_free (file_as);
}
- if (e_minicard->card && e_card_evolution_list (e_minicard->card) ) {
+ if (e_minicard->contact && e_contact_get (e_minicard->contact, E_CONTACT_IS_LIST))
+ is_list = TRUE;
+
+ if (is_list)
gnome_canvas_item_show (e_minicard->list_icon);
- }
- else {
+ else
gnome_canvas_item_hide (e_minicard->list_icon);
- }
list = e_minicard->fields;
e_minicard->fields = NULL;
- for(field = E_CARD_SIMPLE_FIELD_FULL_NAME; field != E_CARD_SIMPLE_FIELD_LAST_SIMPLE_STRING && count < 5; field++) {
+ for (field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1) && count < 5; field++) {
EMinicardField *minicard_field = NULL;
+ gboolean is_email = FALSE;
+
+ if (field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_GIVEN_NAME ||
+ (has_voice && field == E_CONTACT_PHONE_OTHER) ||
+ (has_fax && field == E_CONTACT_PHONE_OTHER_FAX))
+ continue;
+
+ if (field == E_CONTACT_FULL_NAME && is_list)
+ continue;
+
+ if (field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) {
+ if (email_rendered)
+ continue;
+ email_rendered = TRUE;
+ is_email = TRUE;
+ }
if (list)
minicard_field = list->data;
if (minicard_field && minicard_field->field == field) {
GList *this_list = list;
- char *string;
+ gchar *string;
- string = e_card_simple_get(e_minicard->simple, field);
+ string = e_contact_get (e_minicard->contact, field);
if (string && *string) {
- /* Magically convert embedded XML into an address. */
- if (!strncmp (string, "<?xml", 4)) {
- EDestination *dest = e_destination_import (string);
- if (dest != NULL) {
- gchar *new_string = g_strdup (e_destination_get_address (dest));
- g_free (string);
- string = new_string;
- gtk_object_unref (GTK_OBJECT (dest));
- }
- }
-
- e_minicard->fields = g_list_append(e_minicard->fields, minicard_field);
- gtk_object_set(GTK_OBJECT(minicard_field->label),
- "field", string,
- NULL);
- count ++;
+ e_minicard->fields = g_list_append (e_minicard->fields, minicard_field);
+ g_object_set (
+ minicard_field->label,
+ "field", string,
+ NULL);
+ count++;
} else {
- e_minicard_field_destroy(minicard_field);
+ e_minicard_field_destroy (minicard_field);
}
- list = g_list_remove_link(list, this_list);
- g_list_free_1(this_list);
- g_free(string);
+ list = g_list_delete_link (list, this_list);
+ g_free (string);
} else {
- char *string;
+ gchar *string;
if (left_width == -1) {
- left_width = get_left_width(e_minicard);
+ left_width = get_left_width (e_minicard, is_list);
}
- string = e_card_simple_get(e_minicard->simple, field);
- if (string && *string) {
- add_field(e_minicard, field, left_width);
- count++;
+ if (is_email) {
+ GList *email;
+ gint limit;
+
+ limit = 5 - count;
+ email = e_contact_get_attributes (e_minicard->contact, E_CONTACT_EMAIL);
+ add_email_field (e_minicard, email, left_width, limit, is_list);
+ if (count + limit >5)
+ count = 5;
+ else
+ count = count + g_list_length (email);
+ g_list_free_full (email, (GDestroyNotify) e_vcard_attribute_free);
+ } else {
+ string = e_contact_get (e_minicard->contact, field);
+ if (string && *string) {
+ add_field (e_minicard, field, left_width);
+ count++;
+
+ has_voice = has_voice ||
+ field == E_CONTACT_PHONE_BUSINESS ||
+ field == E_CONTACT_PHONE_BUSINESS_2 ||
+ field == E_CONTACT_PHONE_HOME ||
+ field == E_CONTACT_PHONE_HOME_2;
+ has_fax = has_fax ||
+ field == E_CONTACT_PHONE_BUSINESS_FAX ||
+ field == E_CONTACT_PHONE_HOME_FAX;
+ }
+ g_free (string);
}
- g_free(string);
}
}
- g_list_foreach(list, (GFunc) e_minicard_field_destroy, NULL);
- g_list_free(list);
+ g_list_foreach (list, (GFunc) e_minicard_field_destroy, NULL);
+ g_list_free (list);
}
}
static void
-e_minicard_reflow( GnomeCanvasItem *item, int flags )
+e_minicard_reflow (GnomeCanvasItem *item,
+ gint flags)
{
- EMinicard *e_minicard = E_MINICARD(item);
- if ( GTK_OBJECT_FLAGS( e_minicard ) & GNOME_CANVAS_ITEM_REALIZED ) {
+ EMinicard *e_minicard = E_MINICARD (item);
+
+ if (item->flags & GNOME_CANVAS_ITEM_REALIZED) {
GList *list;
gdouble text_height;
gint old_height;
-
+
old_height = e_minicard->height;
- gtk_object_get( GTK_OBJECT( e_minicard->header_text ),
- "text_height", &text_height,
- NULL );
-
+ g_object_get (
+ e_minicard->header_text,
+ "text_height", &text_height,
+ NULL);
+
e_minicard->height = text_height + 10.0;
-
- gnome_canvas_item_set( e_minicard->header_rect,
- "y2", text_height + 9.0,
- NULL );
-
- for(list = e_minicard->fields; list; list = g_list_next(list)) {
- EMinicardField *field = E_MINICARD_FIELD(list->data);
+
+ gnome_canvas_item_set (
+ e_minicard->header_rect,
+ "y2", text_height + 9.0,
+ NULL);
+
+ for (list = e_minicard->fields; list; list = g_list_next (list)) {
+ EMinicardField *field = E_MINICARD_FIELD (list->data);
+ /* Why not use the item that is passed in? */
GnomeCanvasItem *item = field->label;
- gtk_object_get (GTK_OBJECT(item),
- "height", &text_height,
- NULL);
- e_canvas_item_move_absolute(item, 2, e_minicard->height);
+ g_object_get (
+ item,
+ "height", &text_height,
+ NULL);
+ e_canvas_item_move_absolute (item, 2, e_minicard->height);
e_minicard->height += text_height;
}
e_minicard->height += 2;
-
- gnome_canvas_item_set( e_minicard->rect,
- "y2", (double) e_minicard->height - 1,
- NULL );
-
- gnome_canvas_item_set( e_minicard->rect,
- "x2", (double) e_minicard->width - 1.0,
- "y2", (double) e_minicard->height - 1.0,
- NULL );
- gnome_canvas_item_set( e_minicard->header_rect,
- "x2", (double) e_minicard->width - 3.0,
- NULL );
+
+ gnome_canvas_item_set (
+ e_minicard->rect,
+ "x2", (gdouble) e_minicard->width - 1.0,
+ "y2", (gdouble) e_minicard->height - 1.0,
+ NULL);
+ gnome_canvas_item_set (
+ e_minicard->header_rect,
+ "x2", (gdouble) e_minicard->width - 3.0,
+ NULL);
if (old_height != e_minicard->height)
- e_canvas_item_request_parent_reflow(item);
+ e_canvas_item_request_parent_reflow (item);
}
}
-const char *
+const gchar *
e_minicard_get_card_id (EMinicard *minicard)
{
- g_return_val_if_fail(minicard != NULL, NULL);
- g_return_val_if_fail(E_IS_MINICARD(minicard), NULL);
+ g_return_val_if_fail (minicard != NULL, NULL);
+ g_return_val_if_fail (E_IS_MINICARD (minicard), NULL);
- if (minicard->card) {
- return e_card_get_id(minicard->card);
+ if (minicard->contact) {
+ return e_contact_get_const (minicard->contact, E_CONTACT_UID);
} else {
return "";
}
}
-int
-e_minicard_compare (EMinicard *minicard1, EMinicard *minicard2)
+gint
+e_minicard_compare (EMinicard *minicard1,
+ EMinicard *minicard2)
{
- g_return_val_if_fail(minicard1 != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(minicard1), 0);
- g_return_val_if_fail(minicard2 != NULL, 0);
- g_return_val_if_fail(E_IS_MINICARD(minicard2), 0);
-
- if (minicard1->card && minicard2->card) {
- char *file_as1, *file_as2;
- gtk_object_get(GTK_OBJECT(minicard1->card),
- "file_as", &file_as1,
- NULL);
- gtk_object_get(GTK_OBJECT(minicard2->card),
- "file_as", &file_as2,
- NULL);
+ gint cmp = 0;
+
+ g_return_val_if_fail (minicard1 != NULL, 0);
+ g_return_val_if_fail (E_IS_MINICARD (minicard1), 0);
+ g_return_val_if_fail (minicard2 != NULL, 0);
+ g_return_val_if_fail (E_IS_MINICARD (minicard2), 0);
+
+ if (minicard1->contact && minicard2->contact) {
+ gchar *file_as1, *file_as2;
+ g_object_get (
+ minicard1->contact,
+ "file_as", &file_as1,
+ NULL);
+ g_object_get (
+ minicard2->contact,
+ "file_as", &file_as2,
+ NULL);
+
if (file_as1 && file_as2)
- return g_utf8_collate(file_as1, file_as2);
- if (file_as1)
- return -1;
- if (file_as2)
- return 1;
- return strcmp(e_minicard_get_card_id(minicard1), e_minicard_get_card_id(minicard2));
- } else {
- return 0;
+ cmp = g_utf8_collate (file_as1, file_as2);
+ else if (file_as1)
+ cmp = -1;
+ else if (file_as2)
+ cmp = 1;
+ else
+ cmp = strcmp (e_minicard_get_card_id (minicard1), e_minicard_get_card_id (minicard2));
+
+ g_free (file_as1);
+ g_free (file_as2);
}
+
+ return cmp;
}
-int
-e_minicard_selected (EMinicard *minicard, GdkEvent *event)
+gint
+e_minicard_selected (EMinicard *minicard,
+ GdkEvent *event)
{
gint ret_val = 0;
GnomeCanvasItem *item = GNOME_CANVAS_ITEM (minicard);
if (item->parent) {
- guint signal_id = gtk_signal_lookup ("selection_event", GTK_OBJECT_TYPE (item->parent));
+ guint signal_id = g_signal_lookup ("selection_event", G_OBJECT_TYPE (item->parent));
/* We should probably check the signature here, but I
* don't think it's worth the time required to code
* it.
*/
if (signal_id != 0) {
- gtk_signal_emit(GTK_OBJECT(item->parent),
- signal_id,
- item, event, &ret_val);
+ g_signal_emit (
+ item->parent,
+ signal_id, 0,
+ item, event, &ret_val);
}
}
return ret_val;
}
static gint
-e_minicard_drag_begin (EMinicard *minicard, GdkEvent *event)
+e_minicard_drag_begin (EMinicard *minicard,
+ GdkEvent *event)
{
gint ret_val = 0;
GnomeCanvasItem *parent;
- gtk_signal_emit (GTK_OBJECT(minicard),
- e_minicard_signals[DRAG_BEGIN],
- event, &ret_val);
+ g_signal_emit (
+ minicard,
+ signals[DRAG_BEGIN], 0,
+ event, &ret_val);
parent = GNOME_CANVAS_ITEM (minicard)->parent;
if (parent && E_IS_REFLOW (parent)) {
diff --git a/addressbook/gui/widgets/e-minicard.h b/addressbook/gui/widgets/e-minicard.h
index bb6a3c072e..986f47194a 100644
--- a/addressbook/gui/widgets/e-minicard.h
+++ b/addressbook/gui/widgets/e-minicard.h
@@ -1,56 +1,56 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* e-minicard.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 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_MINICARD_H__
-#define __E_MINICARD_H__
-
-#include <libgnomeui/gnome-canvas.h>
-#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "addressbook/gui/contact-editor/e-contact-editor.h"
-#include "addressbook/backend/ebook/e-card.h"
-#include "addressbook/backend/ebook/e-card-simple.h"
-
-#ifdef __cplusplus
-extern "C" {
-#pragma }
-#endif /* __cplusplus */
-
-/* EMinicard - A small card displaying information about a contact.
+ * 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>
*
- * The following arguments are available:
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * name type read/write description
- * --------------------------------------------------------------------------------
- * width double RW width of the card
- * height double R height of the card
- * card ECard* RW Pointer to the ECard
*/
-#define E_MINICARD_TYPE (e_minicard_get_type ())
-#define E_MINICARD(obj) (GTK_CHECK_CAST ((obj), E_MINICARD_TYPE, EMinicard))
-#define E_MINICARD_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_MINICARD_TYPE, EMinicardClass))
-#define E_IS_MINICARD(obj) (GTK_CHECK_TYPE ((obj), E_MINICARD_TYPE))
-#define E_IS_MINICARD_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((obj), E_MINICARD_TYPE))
+#ifndef E_MINICARD_H
+#define E_MINICARD_H
+
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
+#include <libgnomecanvas/libgnomecanvas.h>
+
+/* Standard GObject macros */
+#define E_TYPE_MINICARD \
+ (e_minicard_get_type ())
+#define E_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), E_TYPE_MINICARD, EMinicard))
+#define E_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), E_TYPE_MINICARD, EMinicardClass))
+#define E_IS_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_MINICARD))
+#define E_IS_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((obj), E_TYPE_MINICARD))
+#define E_MINICARD_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), E_TYPE_MINICARD, EMinicardClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EMinicard EMinicard;
+typedef struct _EMinicardClass EMinicardClass;
-
-typedef struct _EMinicard EMinicard;
-typedef struct _EMinicardClass EMinicardClass;
typedef enum _EMinicardFocusType EMinicardFocusType;
enum _EMinicardFocusType {
@@ -61,20 +61,17 @@ enum _EMinicardFocusType {
struct _EMinicard
{
GnomeCanvasGroup parent;
-
+
/* item specific fields */
- ECard *card;
- ECardSimple *simple;
-
+ EContact *contact;
+
GnomeCanvasItem *rect;
GnomeCanvasItem *header_rect;
GnomeCanvasItem *header_text;
GnomeCanvasItem *list_icon;
GdkPixbuf *list_icon_pixbuf;
- double list_icon_size;
-
- GtkObject *editor;
+ gdouble list_icon_size;
GList *fields; /* Of type EMinicardField */
guint needs_remodeling : 1;
@@ -94,8 +91,8 @@ struct _EMinicard
gint button_x;
gint button_y;
- double width;
- double height;
+ gdouble width;
+ gdouble height;
};
struct _EMinicardClass
@@ -104,20 +101,28 @@ struct _EMinicardClass
gint (* selected) (EMinicard *minicard, GdkEvent *event);
gint (* drag_begin) (EMinicard *minicard, GdkEvent *event);
+ void (* open_contact) (EMinicard *minicard, EContact *contact);
+
+ void (* style_set) (EMinicard *minicard, GtkStyle *previous_style);
};
+typedef struct _EMinicardField EMinicardField;
-GtkType e_minicard_get_type (void);
-const char *e_minicard_get_card_id (EMinicard *minicard);
-int e_minicard_compare (EMinicard *minicard1,
- EMinicard *minicard2);
+struct _EMinicardField {
+ EContactField field;
+ GnomeCanvasItem *label;
+};
-int e_minicard_selected (EMinicard *minicard,
- GdkEvent *event);
+#define E_MINICARD_FIELD(field) ((EMinicardField *)(field))
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+GType e_minicard_get_type (void);
+const gchar * e_minicard_get_card_id (EMinicard *minicard);
+gint e_minicard_compare (EMinicard *minicard1,
+ EMinicard *minicard2);
+gint e_minicard_selected (EMinicard *minicard,
+ GdkEvent *event);
+void e_minicard_activate_editor (EMinicard *minicard);
+G_END_DECLS
-#endif /* __E_MINICARD_H__ */
+#endif /* E_MINICARD_H */
diff --git a/addressbook/gui/widgets/ea-addressbook-view.c b/addressbook/gui/widgets/ea-addressbook-view.c
new file mode 100644
index 0000000000..f1c21d1001
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook-view.c
@@ -0,0 +1,123 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include "ea-addressbook-view.h"
+
+static const gchar * ea_ab_view_get_name (AtkObject *accessible);
+static const gchar * ea_ab_view_get_description (AtkObject *accessible);
+
+static void ea_ab_view_class_init (EAddressbookViewClass *class);
+
+GType
+ea_ab_view_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EAddressbookViewClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_ab_view_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EAddressbookView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case) */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GTK_TYPE_EVENT_BOX);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaABView", &tinfo, 0);
+ }
+
+ return type;
+}
+
+static void
+ea_ab_view_class_init (EAddressbookViewClass *class)
+{
+ AtkObjectClass *atk_object_class;
+
+ atk_object_class = ATK_OBJECT_CLASS (class);
+ atk_object_class->get_name = ea_ab_view_get_name;
+ atk_object_class->get_description = ea_ab_view_get_description;
+}
+
+static const gchar *
+ea_ab_view_get_name (AtkObject *accessible)
+{
+ g_return_val_if_fail (EA_IS_AB_VIEW (accessible), NULL);
+ if (accessible->name)
+ return accessible->name;
+
+ return _("evolution address book");
+}
+
+static const gchar *
+ea_ab_view_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution address book");
+}
+
+AtkObject *
+ea_ab_view_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+ g_return_val_if_fail (E_IS_ADDRESSBOOK_VIEW (obj), NULL);
+
+ object = g_object_new (EA_TYPE_AB_VIEW, NULL);
+
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+ accessible->role = ATK_ROLE_CANVAS;
+
+ return accessible;
+}
diff --git a/addressbook/gui/widgets/ea-addressbook-view.h b/addressbook/gui/widgets/ea-addressbook-view.h
new file mode 100644
index 0000000000..55da1d5e37
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook-view.h
@@ -0,0 +1,55 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_ADDRESSBOOK_VIEW_H__
+#define __EA_ADDRESSBOOK_VIEW_H__
+
+#include <gtk/gtk.h>
+#include "e-addressbook-view.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_AB_VIEW (ea_ab_view_get_type ())
+#define EA_AB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_AB_VIEW, EaABView))
+#define EA_AB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_AB_VIEW, EaABViewClass))
+#define EA_IS_AB_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_AB_VIEW))
+#define EA_IS_AB_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_AB_VIEW))
+
+typedef struct _EaABView EaABView;
+typedef struct _EaABViewClass EaABViewClass;
+
+struct _EaABView
+{
+ GtkAccessible parent;
+};
+
+struct _EaABViewClass
+{
+ GtkAccessibleClass parent_class;
+};
+
+GType ea_ab_view_get_type (void);
+AtkObject * ea_ab_view_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_ADDRESSBOOK_VIEW_H__ */
diff --git a/addressbook/gui/widgets/ea-addressbook.c b/addressbook/gui/widgets/ea-addressbook.c
new file mode 100644
index 0000000000..51af22d0d4
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook.c
@@ -0,0 +1,90 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "e-util/e-util.h"
+
+#include "ea-addressbook.h"
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "ea-addressbook-view.h"
+
+EA_FACTORY_GOBJECT (EA_TYPE_MINICARD, ea_minicard, ea_minicard_new)
+EA_FACTORY_GOBJECT (EA_TYPE_MINICARD_VIEW, ea_minicard_view, ea_minicard_view_new)
+EA_FACTORY_GOBJECT (EA_TYPE_AB_VIEW, ea_ab_view, ea_ab_view_new)
+
+static gboolean ea_addressbook_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data);
+
+void e_minicard_a11y_init (void)
+{
+ EA_SET_FACTORY (e_minicard_get_type (), ea_minicard);
+}
+
+void e_minicard_view_a11y_init (void)
+{
+ EA_SET_FACTORY (e_minicard_view_get_type (), ea_minicard_view);
+
+ if (atk_get_root ()) {
+ g_signal_add_emission_hook (
+ g_signal_lookup ("event",
+ e_minicard_get_type ()),
+ 0, ea_addressbook_focus_watcher,
+ NULL, (GDestroyNotify) NULL);
+ }
+}
+
+void eab_view_a11y_init (void)
+{
+ EA_SET_FACTORY (E_TYPE_ADDRESSBOOK_VIEW, ea_ab_view);
+}
+
+static gboolean
+ea_addressbook_focus_watcher (GSignalInvocationHint *ihint,
+ guint n_param_values,
+ const GValue *param_values,
+ gpointer data)
+{
+ GObject *object;
+ GdkEvent *event;
+ AtkObject *ea_event = NULL;
+
+ object = g_value_get_object (param_values + 0);
+ event = g_value_get_boxed (param_values + 1);
+
+ if (E_IS_MINICARD (object)) {
+ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object);
+ ea_event = atk_gobject_accessible_for_object (object);
+ if (event->type == GDK_FOCUS_CHANGE) {
+ if ((event->focus_change.in) &&
+ (E_IS_MINICARD (item->canvas->focused_item)))
+ atk_focus_tracker_notify (ea_event);
+ }
+ }
+
+ return TRUE;
+}
diff --git a/addressbook/gui/widgets/ea-addressbook.h b/addressbook/gui/widgets/ea-addressbook.h
new file mode 100644
index 0000000000..97b691dc18
--- /dev/null
+++ b/addressbook/gui/widgets/ea-addressbook.h
@@ -0,0 +1,33 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Evolution Accessibility
+*/
+
+#ifndef _EA_ADDRESSBOOK_H__
+#define _EA_ADDRESSBOOK_H__
+
+void eab_view_a11y_init (void);
+void e_minicard_view_a11y_init (void);
+void e_minicard_a11y_init (void);
+
+#endif /* _EA_ADDRESSBOOK_H__ */
diff --git a/addressbook/gui/widgets/ea-minicard-view.c b/addressbook/gui/widgets/ea-minicard-view.c
new file mode 100644
index 0000000000..d1592df69e
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard-view.c
@@ -0,0 +1,446 @@
+/*
+ * 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:
+ * Leon Zhang < leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "eab-gui-util.h"
+#include "e-addressbook-view.h"
+
+static const gchar * action_name[] = {
+ N_("New Contact"),
+ N_("New Contact List")
+};
+
+static const gchar * ea_minicard_view_get_name (AtkObject *accessible);
+static const gchar * ea_minicard_view_get_description (AtkObject *accessible);
+
+static void ea_minicard_view_class_init (EaMinicardViewClass *klass);
+
+static gint ea_minicard_view_get_n_children (AtkObject *obj);
+static AtkObject *ea_minicard_view_ref_child (AtkObject *obj, gint i);
+
+static AtkStateSet *ea_minicard_view_ref_state_set (AtkObject *obj);
+
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean selection_interface_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean selection_interface_clear_selection (AtkSelection *selection);
+static AtkObject * selection_interface_ref_selection (AtkSelection *selection,
+ gint i);
+static gint selection_interface_get_selection_count (AtkSelection *selection);
+static gboolean selection_interface_is_child_selected (AtkSelection *selection,
+ gint i);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean atk_action_interface_do_action (AtkAction *iface, gint i);
+static gint atk_action_interface_get_n_action (AtkAction *iface);
+static const gchar *
+ atk_action_interface_get_description
+ (AtkAction *iface,
+ gint i);
+static const gchar *
+ atk_action_interface_get_name (AtkAction *iface,
+ gint i);
+
+static gpointer parent_class = NULL;
+
+GType
+ea_minicard_view_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaMinicardViewClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_minicard_view_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EaMinicardView),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_selection_info = {
+ (GInterfaceInitFunc) atk_selection_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case) */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GNOME_TYPE_CANVAS_GROUP);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaMinicardView", &tinfo, 0);
+ g_type_add_interface_static (
+ type, ATK_TYPE_SELECTION,
+ &atk_selection_info);
+ g_type_add_interface_static (
+ type, ATK_TYPE_ACTION,
+ &atk_action_info);
+
+ }
+
+ return type;
+}
+
+static void
+ea_minicard_view_class_init (EaMinicardViewClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_minicard_view_get_name;
+ class->get_description = ea_minicard_view_get_description;
+ class->ref_state_set = ea_minicard_view_ref_state_set;
+ class->get_n_children = ea_minicard_view_get_n_children;
+ class->ref_child = ea_minicard_view_ref_child;
+}
+
+static const gchar *
+ea_minicard_view_get_name (AtkObject *accessible)
+{
+ EReflow *reflow;
+ gchar *string;
+ EMinicardView *card_view;
+ EBookClient *book_client = NULL;
+ ESource *source;
+ const gchar *display_name;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+ if (!reflow)
+ return NULL;
+
+ /* Get the current name of minicard view*/
+ card_view = E_MINICARD_VIEW (reflow);
+ g_object_get (card_view->adapter, "client", &book_client, NULL);
+ g_return_val_if_fail (E_IS_BOOK_CLIENT (book_client), NULL);
+ source = e_client_get_source (E_CLIENT (book_client));
+ display_name = e_source_get_display_name (source);
+ if (display_name == NULL)
+ display_name = "";
+
+ string = g_strdup_printf (
+ ngettext ("current address book folder %s has %d card",
+ "current address book folder %s has %d cards",
+ reflow->count), display_name, reflow->count);
+
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, string);
+ g_free (string);
+ g_object_unref (book_client);
+ return accessible->name;
+}
+
+static const gchar *
+ea_minicard_view_get_description (AtkObject *accessible)
+{
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution address book");
+}
+
+AtkObject *
+ea_minicard_view_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (E_IS_MINICARD_VIEW (obj), NULL);
+ object = g_object_new (EA_TYPE_MINICARD_VIEW, NULL);
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+ accessible->role = ATK_ROLE_PANEL;
+ return accessible;
+}
+
+static gint
+ea_minicard_view_get_n_children (AtkObject *accessible)
+{
+ EReflow *reflow;
+
+ gint child_num = 0;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), -1);
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+ if (!reflow)
+ return -1;
+
+ child_num = reflow->count;
+
+ return child_num;
+}
+
+static AtkStateSet *ea_minicard_view_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set = NULL;
+ GObject *gobj = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj);
+ if (!state_set)
+ state_set = atk_state_set_new ();
+
+ gobj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj));
+ if (!gobj)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+
+ return state_set;
+}
+
+static AtkObject *
+ea_minicard_view_ref_child (AtkObject *accessible,
+ gint index)
+{
+ EReflow *reflow;
+ gint child_num;
+ AtkObject *atk_object = NULL;
+ EMinicard *card = NULL;
+
+ g_return_val_if_fail (EA_IS_MINICARD_VIEW (accessible), NULL);
+
+ child_num = atk_object_get_n_accessible_children (accessible);
+ if (child_num <= 0 || index < 0 || index >= child_num)
+ return NULL;
+
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+ if (!reflow)
+ return NULL;
+ if (!reflow->items)
+ return NULL;
+ /* a minicard */
+ if (index < child_num) {
+ if (reflow->items[index] == NULL) {
+ reflow->items[index] = e_reflow_model_incarnate (reflow->model, index, GNOME_CANVAS_GROUP (reflow));
+ g_object_set (
+ reflow->items[index],
+ "width", (double) reflow->column_width,
+ NULL);
+ }
+ card = E_MINICARD (reflow->items[index]);
+ atk_object = atk_gobject_accessible_for_object (G_OBJECT (card));
+ } else {
+ return NULL;
+ }
+
+ g_object_ref (atk_object);
+ return atk_object;
+}
+
+/* atkselection interface */
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->add_selection = selection_interface_add_selection;
+ iface->clear_selection = selection_interface_clear_selection;
+ iface->ref_selection = selection_interface_ref_selection;
+ iface->get_selection_count = selection_interface_get_selection_count;
+ iface->is_child_selected = selection_interface_is_child_selected;
+}
+
+static gboolean
+selection_interface_add_selection (AtkSelection *selection,
+ gint i)
+{
+ AtkGObjectAccessible *atk_gobj= NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ selection_interface_clear_selection (selection);
+ e_selection_model_select_single_row (reflow->selection, i);
+
+ return TRUE;
+}
+
+static gboolean
+selection_interface_clear_selection (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ e_selection_model_clear (reflow->selection);
+
+ return TRUE;
+}
+
+static AtkObject *
+selection_interface_ref_selection (AtkSelection *selection,
+ gint i)
+{
+ return ea_minicard_view_ref_child (ATK_OBJECT (selection), i);
+}
+
+static gint
+selection_interface_get_selection_count (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ return e_selection_model_selected_count (reflow->selection);
+}
+
+static gboolean
+selection_interface_is_child_selected (AtkSelection *selection,
+ gint i)
+{
+ AtkGObjectAccessible *atk_gobj = NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (selection);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (!reflow)
+ return FALSE;
+
+ return e_selection_model_is_row_selected (reflow->selection, i);
+}
+
+static void atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = atk_action_interface_do_action;
+ iface->get_n_actions = atk_action_interface_get_n_action;
+ iface->get_description = atk_action_interface_get_description;
+ iface->get_name = atk_action_interface_get_name;
+}
+
+static gboolean
+atk_action_interface_do_action (AtkAction *action,
+ gint i)
+{
+ gboolean return_value = TRUE;
+ EMinicardView *card_view;
+
+ AtkGObjectAccessible *atk_gobj= NULL;
+ EReflow *reflow = NULL;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (action);
+ reflow = E_REFLOW (atk_gobject_accessible_get_object (atk_gobj));
+
+ if (reflow == NULL)
+ return FALSE;
+
+ card_view = E_MINICARD_VIEW (reflow);
+
+ switch (i) {
+ case 0:
+ /* New Contact */
+ e_minicard_view_create_contact (card_view);
+ break;
+ case 1:
+ /* New Contact List */
+ e_minicard_view_create_contact_list (card_view);
+ break;
+ default:
+ return_value = FALSE;
+ break;
+ }
+
+ return return_value;
+}
+
+static gint
+atk_action_interface_get_n_action (AtkAction *iface)
+{
+ return G_N_ELEMENTS (action_name);
+}
+
+static const gchar *
+atk_action_interface_get_description (AtkAction *iface,
+ gint i)
+{
+ return atk_action_interface_get_name (iface, i);
+}
+
+static const gchar *
+atk_action_interface_get_name (AtkAction *iface,
+ gint i)
+{
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return NULL;
+
+ return action_name[i];
+}
+
diff --git a/addressbook/gui/widgets/ea-minicard-view.h b/addressbook/gui/widgets/ea-minicard-view.h
new file mode 100644
index 0000000000..889674bb92
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard-view.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_MINICARD_VIEW_H__
+#define __EA_MINICARD_VIEW_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include "e-minicard-view.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_MINICARD_VIEW (ea_minicard_view_get_type ())
+#define EA_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_MINICARD_VIEW, EaMinicardView))
+#define EA_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_MINICARD_VIEW, EaMiniCardViewClass))
+#define EA_IS_MINICARD_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_MINICARD_VIEW))
+#define EA_IS_MINICARD_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_MINICARD_VIEW))
+
+typedef struct _EaMinicardView EaMinicardView;
+typedef struct _EaMinicardViewClass EaMinicardViewClass;
+
+struct _EaMinicardView
+{
+ AtkGObjectAccessible parent;
+};
+
+struct _EaMinicardViewClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+GType ea_minicard_view_get_type (void);
+
+AtkObject * ea_minicard_view_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_MINICARD_VIEW_H__ */
diff --git a/addressbook/gui/widgets/ea-minicard.c b/addressbook/gui/widgets/ea-minicard.c
new file mode 100644
index 0000000000..cfa35db349
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard.c
@@ -0,0 +1,303 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+#include <glib/gi18n.h>
+#include "ea-minicard.h"
+#include "ea-minicard-view.h"
+#include "e-minicard.h"
+
+static const gchar * action_name[] = {
+ N_("Open")
+};
+
+static const gchar *
+ ea_minicard_get_name (AtkObject *accessible);
+static const gchar *
+ ea_minicard_get_description (AtkObject *accessible);
+
+static void ea_minicard_class_init (EaMinicardClass *klass);
+
+static gint ea_minicard_get_n_children (AtkObject *obj);
+static AtkObject *
+ ea_minicard_ref_child (AtkObject *obj,
+ gint i);
+
+static AtkStateSet *
+ ea_minicard_ref_state_set (AtkObject *obj);
+
+static void atk_action_interface_init (AtkActionIface *iface);
+static gboolean atk_action_interface_do_action (AtkAction *iface,
+ gint i);
+static gint atk_action_interface_get_n_action
+ (AtkAction *iface);
+static const gchar *
+ atk_action_interface_get_description
+ (AtkAction *iface,
+ gint i);
+static const gchar *
+ atk_action_interface_get_name (AtkAction *iface,
+ gint i);
+
+static gpointer parent_class = NULL;
+
+GType
+ea_minicard_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaMinicardClass),
+ (GBaseInitFunc) NULL, /* base_init */
+ (GBaseFinalizeFunc) NULL, /* base_finalize */
+ (GClassInitFunc) ea_minicard_class_init,
+ (GClassFinalizeFunc) NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (EaMinicard),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailWidget, in this case)
+ */
+
+ factory = atk_registry_get_factory (
+ atk_get_default_registry (),
+ GNOME_TYPE_CANVAS_GROUP);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (
+ derived_atk_type,
+ "EaMinicard", &tinfo, 0);
+ g_type_add_interface_static (
+ type, ATK_TYPE_ACTION,
+ &atk_action_info);
+ }
+
+ return type;
+}
+
+static void
+ea_minicard_class_init (EaMinicardClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_minicard_get_name;
+ class->get_description = ea_minicard_get_description;
+ class->ref_state_set = ea_minicard_ref_state_set;
+ class->get_n_children = ea_minicard_get_n_children;
+ class->ref_child = ea_minicard_ref_child;
+}
+
+/*
+ * we access the main content of current minicard, including
+ * header text, label(field, field name)
+ */
+static const gchar *
+ea_minicard_get_name (AtkObject *accessible)
+{
+#define BUFFERSIZE 500
+
+ static gchar name[BUFFERSIZE + 1];
+ GString *new_str = g_string_new (NULL);
+ gchar *string;
+ EMinicard *card;
+
+ g_return_val_if_fail (EA_IS_MINICARD (accessible), NULL);
+ memset (name, '\0', BUFFERSIZE);
+
+ card = E_MINICARD (
+ atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (accessible)));
+ if (!card)
+ return NULL;
+
+ g_object_get (card->header_text, "text", &string, NULL);
+
+ if (e_contact_get (card->contact, E_CONTACT_IS_LIST))
+ g_string_append (new_str, _("Contact List: "));
+ else g_string_append (new_str, _("Contact: "));
+
+ /* get header of current card */
+ g_string_append (new_str, string);
+ g_free (string);
+
+ /* if there exist no enough space for remain info, return */
+ if (new_str->len >= BUFFERSIZE) {
+ strncpy (name, new_str->str, BUFFERSIZE);
+ name[BUFFERSIZE] = '\0';
+ return name;
+ }
+
+ strcpy (name, new_str->str);
+ g_string_free (new_str, TRUE);
+
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name);
+
+ return accessible->name;
+}
+
+static const gchar *
+ea_minicard_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution minicard");
+}
+
+AtkObject *
+ea_minicard_new (GObject *obj)
+{
+ GObject *object;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (obj != NULL, NULL);
+ g_return_val_if_fail (E_IS_MINICARD (obj), NULL);
+
+ object = g_object_new (EA_TYPE_MINICARD, NULL);
+ accessible = ATK_OBJECT (object);
+ atk_object_initialize (accessible, obj);
+
+ accessible->role = ATK_ROLE_PANEL;
+ return accessible;
+}
+
+static AtkStateSet *
+ea_minicard_ref_state_set (AtkObject *obj)
+{
+ AtkStateSet *state_set = NULL;
+ GObject *gobj = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj);
+ if (!state_set)
+ state_set = atk_state_set_new ();
+
+ gobj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (obj));
+ if (!gobj)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE);
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+
+ return state_set;
+}
+
+static gint
+ea_minicard_get_n_children (AtkObject *accessible)
+{
+ return 0;
+}
+
+static AtkObject *
+ea_minicard_ref_child (AtkObject *accessible,
+ gint index)
+{
+ return NULL;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = atk_action_interface_do_action;
+ iface->get_n_actions = atk_action_interface_get_n_action;
+ iface->get_description = atk_action_interface_get_description;
+ iface->get_name = atk_action_interface_get_name;
+}
+
+static gboolean
+atk_action_interface_do_action (AtkAction *iface,
+ gint i)
+{
+ EMinicard *minicard = NULL;
+
+ minicard = E_MINICARD (
+ atk_gobject_accessible_get_object (
+ ATK_GOBJECT_ACCESSIBLE (iface)));
+ if (minicard == NULL)
+ return FALSE;
+
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return FALSE;
+
+ switch (i) {
+ /* open card */
+ case 0:
+ e_minicard_activate_editor (minicard);
+ break;
+ default:
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gint
+atk_action_interface_get_n_action (AtkAction *iface)
+{
+ return G_N_ELEMENTS (action_name);
+}
+
+static const gchar *
+atk_action_interface_get_description (AtkAction *iface,
+ gint i)
+{
+ return atk_action_interface_get_name (iface, i);
+}
+
+static const gchar *
+atk_action_interface_get_name (AtkAction *iface,
+ gint i)
+{
+ if (i >= G_N_ELEMENTS (action_name) || i < 0)
+ return NULL;
+
+ return action_name[i];
+}
+
diff --git a/addressbook/gui/widgets/ea-minicard.h b/addressbook/gui/widgets/ea-minicard.h
new file mode 100644
index 0000000000..ea27158011
--- /dev/null
+++ b/addressbook/gui/widgets/ea-minicard.h
@@ -0,0 +1,56 @@
+/*
+ * 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:
+ * Leon Zhang <leon.zhang@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_MINICARD_H__
+#define __EA_MINICARD_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include "e-minicard.h"
+#include "e-minicard-label.h"
+
+G_BEGIN_DECLS
+
+#define EA_TYPE_MINICARD (ea_minicard_get_type ())
+#define EA_MINICARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_MINICARD, EaMinicard))
+#define EA_MINICARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_MINICARD, EaMiniCardClass))
+#define EA_IS_MINICARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_MINICARD))
+#define EA_IS_MINICARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EA_TYPE_MINICARD))
+
+typedef struct _EaMinicard EaMinicard;
+typedef struct _EaMinicardClass EaMinicardClass;
+
+struct _EaMinicard
+{
+ AtkGObjectAccessible parent;
+};
+
+struct _EaMinicardClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+GType ea_minicard_get_type (void);
+AtkObject * ea_minicard_new (GObject *obj);
+
+G_END_DECLS
+
+#endif /* __EA_MINICARD_H__ */
diff --git a/addressbook/gui/widgets/eab-config.c b/addressbook/gui/widgets/eab-config.c
new file mode 100644
index 0000000000..ad15f1cca9
--- /dev/null
+++ b/addressbook/gui/widgets/eab-config.c
@@ -0,0 +1,160 @@
+/*
+ * 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:
+ * David Trowbridge <trowbrds@cs.colorado.edu>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "eab-config.h"
+
+#define EAB_CONFIG_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONFIG, EABConfigPrivate))
+
+struct _EABConfigPrivate {
+ guint source_changed_id;
+};
+
+G_DEFINE_TYPE (EABConfig, eab_config, E_TYPE_CONFIG)
+
+static void
+eab_config_init (EABConfig *cfg)
+{
+ cfg->priv = EAB_CONFIG_GET_PRIVATE (cfg);
+}
+
+static void
+ecp_target_free (EConfig *ec,
+ EConfigTarget *t)
+{
+ struct _EABConfigPrivate *p = EAB_CONFIG (ec)->priv;
+
+ if (ec->target == t) {
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ if (p->source_changed_id) {
+ g_signal_handler_disconnect (s->source, p->source_changed_id);
+ p->source_changed_id = 0;
+ }
+ break; }
+ case EAB_CONFIG_TARGET_PREFS:
+ break;
+ }
+ }
+
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ if (s->source)
+ g_object_unref (s->source);
+ break; }
+ case EAB_CONFIG_TARGET_PREFS: {
+ EABConfigTargetPrefs *s = (EABConfigTargetPrefs *) t;
+
+ if (s->settings)
+ g_object_unref (s->settings);
+ break; }
+ }
+
+ ((EConfigClass *) eab_config_parent_class)->target_free (ec, t);
+}
+
+static void
+ecp_source_changed (ESource *source,
+ EConfig *ec)
+{
+ e_config_target_changed (ec, E_CONFIG_TARGET_CHANGED_STATE);
+}
+
+static void
+ecp_set_target (EConfig *ec,
+ EConfigTarget *t)
+{
+ struct _EABConfigPrivate *p = EAB_CONFIG_GET_PRIVATE (ec);
+
+ ((EConfigClass *) eab_config_parent_class)->set_target (ec, t);
+
+ if (t) {
+ switch (t->type) {
+ case EAB_CONFIG_TARGET_SOURCE: {
+ EABConfigTargetSource *s = (EABConfigTargetSource *) t;
+
+ p->source_changed_id = g_signal_connect (
+ s->source, "changed",
+ G_CALLBACK (ecp_source_changed), ec);
+ break; }
+ case EAB_CONFIG_TARGET_PREFS:
+ break;
+ }
+ }
+}
+
+static void
+eab_config_class_init (EABConfigClass *class)
+{
+ EConfigClass *config_class;
+
+ g_type_class_add_private (class, sizeof (struct _EABConfigPrivate));
+
+ config_class = E_CONFIG_CLASS (class);
+ config_class->set_target = ecp_set_target;
+ config_class->target_free = ecp_target_free;
+}
+
+EABConfig *
+eab_config_new (const gchar *menuid)
+{
+ EABConfig *ecp = g_object_new (eab_config_get_type (), NULL);
+ e_config_construct (&ecp->config, menuid);
+ return ecp;
+}
+
+EABConfigTargetSource *
+eab_config_target_new_source (EABConfig *ecp,
+ ESource *source)
+{
+ EABConfigTargetSource *t = e_config_target_new (
+ &ecp->config, EAB_CONFIG_TARGET_SOURCE, sizeof (*t));
+
+ t->source = source;
+ g_object_ref (source);
+
+ return t;
+}
+
+EABConfigTargetPrefs *
+eab_config_target_new_prefs (EABConfig *ecp,
+ GSettings *settings)
+{
+ EABConfigTargetPrefs *t = e_config_target_new (
+ &ecp->config, EAB_CONFIG_TARGET_PREFS, sizeof (*t));
+
+ if (settings)
+ t->settings = g_object_ref (settings);
+ else
+ t->settings = NULL;
+
+ return t;
+}
diff --git a/addressbook/gui/widgets/eab-config.h b/addressbook/gui/widgets/eab-config.h
new file mode 100644
index 0000000000..55612ec65a
--- /dev/null
+++ b/addressbook/gui/widgets/eab-config.h
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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:
+ * David Trowbridge <trowbrds@cs.colorado.edu>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EAB_CONFIG_H__
+#define __EAB_CONFIG_H__
+
+#include <libedataserver/libedataserver.h>
+
+#include <e-util/e-util.h>
+
+#define EAB_TYPE_CONFIG (eab_config_get_type ())
+#define EAB_CONFIG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EAB_TYPE_CONFIG, EABConfig))
+
+G_BEGIN_DECLS
+
+typedef struct _EABConfig EABConfig;
+typedef struct _EABConfigClass EABConfigClass;
+typedef struct _EABConfigPrivate EABConfigPrivate;
+
+struct _EABConfig {
+ EConfig config;
+
+ EABConfigPrivate *priv;
+};
+
+struct _EABConfigClass {
+ EConfigClass config_class;
+};
+
+enum _eab_config_target_t {
+ EAB_CONFIG_TARGET_SOURCE,
+ EAB_CONFIG_TARGET_PREFS
+};
+
+typedef struct _EABConfigTargetSource EABConfigTargetSource;
+
+struct _EABConfigTargetSource {
+ EConfigTarget target;
+
+ ESource *source;
+};
+
+typedef struct _EABConfigTargetPrefs EABConfigTargetPrefs;
+
+struct _EABConfigTargetPrefs {
+ EConfigTarget target;
+
+ /* preferences are global from GSettings */
+ GSettings *settings;
+};
+
+typedef struct _EConfigItem EABConfigItem;
+
+GType eab_config_get_type (void);
+EABConfig *eab_config_new (const gchar *menuid);
+
+EABConfigTargetSource *eab_config_target_new_source (EABConfig *ecp, ESource *source);
+EABConfigTargetPrefs *eab_config_target_new_prefs (EABConfig *ecp, GSettings *settings);
+
+G_END_DECLS
+
+#endif
diff --git a/addressbook/gui/widgets/eab-contact-display.c b/addressbook/gui/widgets/eab-contact-display.c
new file mode 100644
index 0000000000..c467e385e4
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.c
@@ -0,0 +1,626 @@
+/*
+ * 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 "eab-contact-display.h"
+
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <webkit/webkit.h>
+
+#include "e-contact-map.h"
+#include "eab-contact-formatter.h"
+#include "eab-gui-util.h"
+
+#define EAB_CONTACT_DISPLAY_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayPrivate))
+
+#define TEXT_IS_RIGHT_TO_LEFT \
+ (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+
+struct _EABContactDisplayPrivate {
+ EContact *contact;
+
+ EABContactDisplayMode mode;
+ gboolean show_maps;
+};
+
+enum {
+ PROP_0,
+ PROP_CONTACT,
+ PROP_MODE,
+ PROP_SHOW_MAPS
+};
+
+enum {
+ SEND_MESSAGE,
+ LAST_SIGNAL
+};
+
+static const gchar *ui =
+"<ui>"
+" <popup name='context'>"
+" <placeholder name='custom-actions-1'>"
+" <menuitem action='contact-send-message'/>"
+" </placeholder>"
+" <placeholder name='custom-actions-2'>"
+" <menuitem action='contact-mailto-copy'/>"
+" </placeholder>"
+" </popup>"
+"</ui>";
+
+static guint signals[LAST_SIGNAL];
+
+G_DEFINE_TYPE (
+ EABContactDisplay,
+ eab_contact_display,
+ E_TYPE_WEB_VIEW)
+
+static void
+contact_display_emit_send_message (EABContactDisplay *display,
+ gint email_num)
+{
+ EDestination *destination;
+ EContact *contact;
+
+ g_return_if_fail (email_num >= 0);
+
+ destination = e_destination_new ();
+ contact = eab_contact_display_get_contact (display);
+ e_destination_set_contact (destination, contact, email_num);
+ g_signal_emit (display, signals[SEND_MESSAGE], 0, destination);
+ g_object_unref (destination);
+}
+
+static void
+action_contact_mailto_copy_cb (GtkAction *action,
+ EABContactDisplay *display)
+{
+ GtkClipboard *clipboard;
+ EWebView *web_view;
+ EContact *contact;
+ GList *list;
+ const gchar *text;
+ const gchar *uri;
+ gint index;
+
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ index = atoi (uri + strlen ("internal-mailto:"));
+ g_return_if_fail (index >= 0);
+
+ contact = eab_contact_display_get_contact (display);
+ list = e_contact_get (contact, E_CONTACT_EMAIL);
+ text = g_list_nth_data (list, index);
+
+ clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
+ gtk_clipboard_set_text (clipboard, text, -1);
+ gtk_clipboard_store (clipboard);
+
+ g_list_foreach (list, (GFunc) g_free, NULL);
+ g_list_free (list);
+}
+
+static void
+action_contact_send_message_cb (GtkAction *action,
+ EABContactDisplay *display)
+{
+ EWebView *web_view;
+ const gchar *uri;
+ gint index;
+
+ web_view = E_WEB_VIEW (display);
+ uri = e_web_view_get_selected_uri (web_view);
+ g_return_if_fail (uri != NULL);
+
+ index = atoi (uri + strlen ("internal-mailto:"));
+ contact_display_emit_send_message (display, index);
+}
+
+static GtkActionEntry internal_mailto_entries[] = {
+
+ { "contact-mailto-copy",
+ GTK_STOCK_COPY,
+ N_("Copy _Email Address"),
+ NULL,
+ N_("Copy the email address to the clipboard"),
+ G_CALLBACK (action_contact_mailto_copy_cb) },
+
+ { "contact-send-message",
+ "mail-message-new",
+ N_("_Send New Message To..."),
+ NULL,
+ N_("Send a mail message to this address"),
+ G_CALLBACK (action_contact_send_message_cb) }
+};
+
+static void
+load_contact (EABContactDisplay *display)
+{
+ EABContactFormatter *formatter;
+ GString *buffer;
+
+ if (!display->priv->contact) {
+ e_web_view_clear (E_WEB_VIEW (display));
+ return;
+ }
+
+ formatter = eab_contact_formatter_new ();
+ g_object_set (
+ G_OBJECT (formatter),
+ "display-mode", display->priv->mode,
+ "render-maps", display->priv->show_maps,
+ NULL);
+
+ buffer = g_string_sized_new (1024);
+
+ eab_contact_formatter_format_contact (
+ formatter, display->priv->contact, buffer);
+ e_web_view_load_string (E_WEB_VIEW (display), buffer->str);
+
+ g_string_free (buffer, TRUE);
+
+ g_object_unref (formatter);
+}
+
+static void
+contact_display_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONTACT:
+ eab_contact_display_set_contact (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_object (value));
+ return;
+
+ case PROP_MODE:
+ eab_contact_display_set_mode (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_SHOW_MAPS:
+ eab_contact_display_set_show_maps (
+ EAB_CONTACT_DISPLAY (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+contact_display_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_CONTACT:
+ g_value_set_object (
+ value, eab_contact_display_get_contact (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+
+ case PROP_MODE:
+ g_value_set_int (
+ value, eab_contact_display_get_mode (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+
+ case PROP_SHOW_MAPS:
+ g_value_set_boolean (
+ value, eab_contact_display_get_show_maps (
+ EAB_CONTACT_DISPLAY (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+contact_display_dispose (GObject *object)
+{
+ EABContactDisplayPrivate *priv;
+
+ priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (object);
+
+ if (priv->contact != NULL) {
+ g_object_unref (priv->contact);
+ priv->contact = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (eab_contact_display_parent_class)->dispose (object);
+}
+
+static void
+contact_display_hovering_over_link (EWebView *web_view,
+ const gchar *title,
+ const gchar *uri)
+{
+ EWebViewClass *web_view_class;
+ EABContactDisplay *display;
+ EContact *contact;
+ const gchar *name;
+ gchar *message;
+
+ if (uri == NULL || *uri == '\0')
+ goto chainup;
+
+ if (!g_str_has_prefix (uri, "internal-mailto:"))
+ goto chainup;
+
+ display = EAB_CONTACT_DISPLAY (web_view);
+ contact = eab_contact_display_get_contact (display);
+
+ name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (name == NULL)
+ e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+ g_return_if_fail (name != NULL);
+
+ message = g_strdup_printf (_("Click to mail %s"), name);
+ e_web_view_status_message (web_view, message);
+ g_free (message);
+
+ return;
+
+chainup:
+ /* Chain up to parent's hovering_over_link() method. */
+ web_view_class = E_WEB_VIEW_CLASS (eab_contact_display_parent_class);
+ web_view_class->hovering_over_link (web_view, title, uri);
+}
+
+static void
+contact_display_link_clicked (EWebView *web_view,
+ const gchar *uri)
+{
+ EABContactDisplay *display;
+ gsize length;
+
+ display = EAB_CONTACT_DISPLAY (web_view);
+
+ length = strlen ("internal-mailto:");
+ if (g_ascii_strncasecmp (uri, "internal-mailto:", length) == 0) {
+ gint index;
+
+ index = atoi (uri + length);
+ contact_display_emit_send_message (display, index);
+ return;
+ }
+
+ /* Chain up to parent's link_clicked() method. */
+ E_WEB_VIEW_CLASS (eab_contact_display_parent_class)->
+ link_clicked (web_view, uri);
+}
+
+#ifdef WITH_CONTACT_MAPS
+/* XXX Clutter event handling workaround. Clutter-gtk propagates events down
+ * to parent widgets. In this case it leads to GtkHTML scrolling up and
+ * down while user's trying to zoom in the champlain widget. This
+ * workaround stops the propagation from map widget down to GtkHTML. */
+static gboolean
+handle_map_scroll_event (GtkWidget *widget,
+ GdkEvent *event)
+{
+ return TRUE;
+}
+
+static GtkWidget *
+contact_display_object_requested (WebKitWebView *web_view,
+ gchar *mime_type,
+ gchar *uri,
+ GHashTable *param,
+ EABContactDisplay *display)
+{
+ EContact *contact = display->priv->contact;
+ const gchar *name = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ const gchar *contact_uid = e_contact_get_const (contact, E_CONTACT_UID);
+ gchar *full_name;
+ EContactAddress *address;
+ GtkWidget *map = NULL;
+
+ if (strstr (mime_type, "work") != NULL) {
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_WORK);
+ full_name = g_strconcat (name, " (", _("Work"), ")", NULL);
+ } else if (strstr (mime_type, "home") != NULL) {
+ address = e_contact_get (contact, E_CONTACT_ADDRESS_HOME);
+ full_name = g_strconcat (name, " (", _("Home"), ")", NULL);
+ }
+
+ if (address) {
+ map = e_contact_map_new ();
+ gtk_widget_set_size_request (map, 250, 250);
+ g_signal_connect (
+ E_CONTACT_MAP (map), "contact-added",
+ G_CALLBACK (e_contact_map_zoom_on_marker), NULL);
+ g_signal_connect_swapped (
+ E_CONTACT_MAP (map), "contact-added",
+ G_CALLBACK (gtk_widget_show_all), map);
+ g_signal_connect (
+ GTK_CHAMPLAIN_EMBED (map), "scroll-event",
+ G_CALLBACK (handle_map_scroll_event), NULL);
+
+ /* No need to display photo in contact preview. */
+ e_contact_map_add_marker (
+ E_CONTACT_MAP (map), full_name,
+ contact_uid, address, NULL);
+
+ gtk_widget_show_all (map);
+
+ e_contact_address_free (address);
+ }
+
+ g_free (full_name);
+
+ return map;
+}
+#endif
+
+static void
+contact_display_load_status_changed (WebKitWebView *web_view,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ WebKitLoadStatus load_status;
+ WebKitDOMDocument *document;
+
+ load_status = webkit_web_view_get_load_status (web_view);
+ if (load_status != WEBKIT_LOAD_FINISHED)
+ return;
+
+ document = webkit_web_view_get_dom_document (web_view);
+ eab_contact_formatter_bind_dom (document);
+}
+
+static void
+contact_display_update_actions (EWebView *web_view)
+{
+ GtkActionGroup *action_group;
+ gboolean scheme_is_internal_mailto;
+ gboolean visible;
+ const gchar *group_name;
+ const gchar *uri;
+
+ /* Chain up to parent's update_actions() method. */
+ E_WEB_VIEW_CLASS (eab_contact_display_parent_class)->
+ update_actions (web_view);
+
+ uri = e_web_view_get_selected_uri (web_view);
+
+ scheme_is_internal_mailto = (uri == NULL) ? FALSE :
+ (g_ascii_strncasecmp (uri, "internal-mailto:", 16) == 0);
+
+ /* Override how EWebView treats internal-mailto URIs. */
+ group_name = "uri";
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ visible = gtk_action_group_get_visible (action_group);
+ visible &= !scheme_is_internal_mailto;
+ gtk_action_group_set_visible (action_group, visible);
+
+ group_name = "internal-mailto";
+ visible = scheme_is_internal_mailto;
+ action_group = e_web_view_get_action_group (web_view, group_name);
+ gtk_action_group_set_visible (action_group, visible);
+}
+
+static void
+eab_contact_display_class_init (EABContactDisplayClass *class)
+{
+ GObjectClass *object_class;
+ EWebViewClass *web_view_class;
+
+ g_type_class_add_private (class, sizeof (EABContactDisplayPrivate));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = contact_display_set_property;
+ object_class->get_property = contact_display_get_property;
+ object_class->dispose = contact_display_dispose;
+
+ web_view_class = E_WEB_VIEW_CLASS (class);
+ web_view_class->hovering_over_link = contact_display_hovering_over_link;
+ web_view_class->link_clicked = contact_display_link_clicked;
+ web_view_class->update_actions = contact_display_update_actions;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_CONTACT,
+ g_param_spec_object (
+ "contact",
+ NULL,
+ NULL,
+ E_TYPE_CONTACT,
+ G_PARAM_READWRITE));
+
+ /* XXX Make this a real enum property. */
+ g_object_class_install_property (
+ object_class,
+ PROP_MODE,
+ g_param_spec_int (
+ "mode",
+ NULL,
+ NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_SHOW_MAPS,
+ g_param_spec_boolean (
+ "show-maps",
+ NULL,
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE));
+
+ signals[SEND_MESSAGE] = g_signal_new (
+ "send-message",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (EABContactDisplayClass, send_message),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1,
+ E_TYPE_DESTINATION);
+}
+
+static void
+eab_contact_display_init (EABContactDisplay *display)
+{
+ EWebView *web_view;
+ GtkUIManager *ui_manager;
+ GtkActionGroup *action_group;
+ const gchar *domain = GETTEXT_PACKAGE;
+ GError *error = NULL;
+
+ display->priv = EAB_CONTACT_DISPLAY_GET_PRIVATE (display);
+
+ web_view = E_WEB_VIEW (display);
+ ui_manager = e_web_view_get_ui_manager (web_view);
+
+#ifdef WITH_CONTACT_MAPS
+ g_signal_connect (
+ web_view, "create-plugin-widget",
+ G_CALLBACK (contact_display_object_requested), display);
+#endif
+ g_signal_connect (
+ web_view, "notify::load-status",
+ G_CALLBACK (contact_display_load_status_changed), NULL);
+ g_signal_connect (
+ web_view, "style-set",
+ G_CALLBACK (load_contact), NULL);
+
+ e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_FILE_REQUEST);
+ e_web_view_install_request_handler (E_WEB_VIEW (display), E_TYPE_STOCK_REQUEST);
+
+ action_group = gtk_action_group_new ("internal-mailto");
+ gtk_action_group_set_translation_domain (action_group, domain);
+ gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
+ g_object_unref (action_group);
+
+ gtk_action_group_add_actions (
+ action_group, internal_mailto_entries,
+ G_N_ELEMENTS (internal_mailto_entries), display);
+
+ /* Because we are loading from a hard-coded string, there is
+ * no chance of I/O errors. Failure here implies a malformed
+ * UI definition. Full stop. */
+ gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, &error);
+ if (error != NULL)
+ g_error ("%s", error->message);
+}
+
+GtkWidget *
+eab_contact_display_new (void)
+{
+ return g_object_new (EAB_TYPE_CONTACT_DISPLAY, NULL);
+}
+
+EContact *
+eab_contact_display_get_contact (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), NULL);
+
+ return display->priv->contact;
+}
+
+void
+eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->contact == contact)
+ return;
+
+ if (contact != NULL)
+ g_object_ref (contact);
+
+ if (display->priv->contact != NULL)
+ g_object_unref (display->priv->contact);
+
+ display->priv->contact = contact;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "contact");
+}
+
+EABContactDisplayMode
+eab_contact_display_get_mode (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), 0);
+
+ return display->priv->mode;
+}
+
+void
+eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->mode == mode)
+ return;
+
+ display->priv->mode = mode;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "mode");
+}
+
+gboolean
+eab_contact_display_get_show_maps (EABContactDisplay *display)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_DISPLAY (display), FALSE);
+
+ return display->priv->show_maps;
+}
+
+void
+eab_contact_display_set_show_maps (EABContactDisplay *display,
+ gboolean show_maps)
+{
+ g_return_if_fail (EAB_IS_CONTACT_DISPLAY (display));
+
+ if (display->priv->show_maps == show_maps)
+ return;
+
+ display->priv->show_maps = show_maps;
+
+ load_contact (display);
+
+ g_object_notify (G_OBJECT (display), "show-maps");
+}
diff --git a/addressbook/gui/widgets/eab-contact-display.h b/addressbook/gui/widgets/eab-contact-display.h
new file mode 100644
index 0000000000..484e312b6b
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-display.h
@@ -0,0 +1,103 @@
+/*
+ * 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_CONTACT_DISPLAY_H
+#define EAB_CONTACT_DISPLAY_H
+
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_CONTACT_DISPLAY \
+ (eab_contact_display_get_type ())
+#define EAB_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplay))
+#define EAB_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+#define EAB_IS_CONTACT_DISPLAY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_IS_CONTACT_DISPLAY_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_CONTACT_DISPLAY))
+#define EAB_CONTACT_DISPLAY_GET_CLASS(obj) \
+ (G_TYPE_ISNTANCE_GET_CLASS \
+ ((obj), EAB_TYPE_CONTACT_DISPLAY, EABContactDisplayClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EABContactDisplay EABContactDisplay;
+typedef struct _EABContactDisplayClass EABContactDisplayClass;
+typedef struct _EABContactDisplayPrivate EABContactDisplayPrivate;
+
+/**
+ * EABContactDisplayMode:
+ * @EAB_CONTACT_DISPLAY_RENDER_NORMAL:
+ * For use in the preview pane.
+ * @EAB_CONTACT_DISPLAY_RENDER_COMPACT:
+ * For use with embedded vcards.
+ **/
+typedef enum {
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT
+} EABContactDisplayMode;
+
+struct _EABContactDisplay {
+ EWebView parent;
+ EABContactDisplayPrivate *priv;
+};
+
+struct _EABContactDisplayClass {
+ EWebViewClass parent_class;
+
+ /* Signals */
+ void (*send_message) (EABContactDisplay *display,
+ EDestination *destination);
+};
+
+GType eab_contact_display_get_type (void);
+GtkWidget * eab_contact_display_new (void);
+
+EContact * eab_contact_display_get_contact (EABContactDisplay *display);
+void eab_contact_display_set_contact (EABContactDisplay *display,
+ EContact *contact);
+EABContactDisplayMode
+ eab_contact_display_get_mode (EABContactDisplay *display);
+void eab_contact_display_set_mode (EABContactDisplay *display,
+ EABContactDisplayMode mode);
+GtkOrientation eab_contact_display_get_orientation
+ (EABContactDisplay *display);
+void eab_contact_display_set_orientation
+ (EABContactDisplay *display,
+ GtkOrientation orientation);
+gboolean eab_contact_display_get_show_maps
+ (EABContactDisplay *display);
+void eab_contact_display_set_show_maps
+ (EABContactDisplay *display,
+ gboolean display_maps);
+
+G_END_DECLS
+
+#endif /* EAB_CONTACT_DISPLAY_H */
diff --git a/addressbook/gui/widgets/eab-contact-formatter.c b/addressbook/gui/widgets/eab-contact-formatter.c
new file mode 100644
index 0000000000..60beefa5c3
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-formatter.c
@@ -0,0 +1,1207 @@
+/*
+ * eab-contact-formatter.c
+ *
+ * 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/>
+ *
+ */
+
+#include "eab-contact-formatter.h"
+
+#include <config.h>
+#include <string.h>
+#include <glib/gi18n.h>
+
+#include <e-util/e-util.h>
+
+#include "eab-book-util.h"
+#include "eab-gui-util.h"
+
+#define EAB_CONTACT_FORMATTER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterPrivate))
+
+#define TEXT_IS_RIGHT_TO_LEFT \
+ (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL)
+
+#define IMAGE_COL_WIDTH "20"
+#define CONTACT_LIST_ICON "stock_contact-list"
+#define AIM_ICON "im-aim"
+#define GROUPWISE_ICON "im-nov"
+#define ICQ_ICON "im-icq"
+#define JABBER_ICON "im-jabber"
+#define MSN_ICON "im-msn"
+#define YAHOO_ICON "im-yahoo"
+#define GADUGADU_ICON "im-gadugadu"
+#define SKYPE_ICON "stock_people"
+#define TWITTER_ICON "im-twitter"
+#define VIDEOCONF_ICON "stock_video-conferencing"
+
+#define MAX_COMPACT_IMAGE_DIMENSION 48
+
+#define HTML_HEADER "<!doctype html public \"-//W3C//DTD HTML 4.0 TRANSITIONAL//EN\">\n<html>\n" \
+"<head>\n<meta name=\"generator\" content=\"Evolution Addressbook Component\">\n" \
+"<link type=\"text/css\" rel=\"stylesheet\" href=\"evo-file://" EVOLUTION_PRIVDATADIR "/theme/webview.css\">" \
+"<style type=\"text/css\">\n" \
+" div#header { width:100%; clear: both; }\n" \
+" div#columns { width: 100%; clear: both; }\n" \
+" div#footer { width: 100%; clear: both; }\n" \
+" div.column { width: auto; float: left; margin-right: 15px; }\n" \
+" img#contact-photo { float: left; }\n" \
+" div#contact-name { float: left; margin-left: 20px; }\n" \
+"</style>\n" \
+"</head>\n"
+
+struct _EABContactFormatterPrivate {
+ EABContactDisplayMode mode;
+ gboolean render_maps;
+};
+
+enum {
+ PROP_0,
+ PROP_DISPLAY_MODE,
+ PROP_RENDER_MAPS
+};
+
+static struct {
+ const gchar *name;
+ const gchar *pretty_name;
+} common_location[] = {
+ { "WORK", N_ ("Work") },
+ { "HOME", N_ ("Home") },
+ { "OTHER", N_ ("Other") }
+};
+
+G_DEFINE_TYPE (
+ EABContactFormatter,
+ eab_contact_formatter,
+ G_TYPE_OBJECT);
+
+static gboolean
+icon_available (const gchar *icon)
+{
+ GtkIconTheme *icon_theme;
+ GtkIconInfo *icon_info;
+
+ if (!icon)
+ return FALSE;
+
+ icon_theme = gtk_icon_theme_get_default ();
+ icon_info = gtk_icon_theme_lookup_icon (icon_theme, icon, 16, 0);
+ if (icon_info != NULL)
+ gtk_icon_info_free (icon_info);
+
+ return icon_info != NULL;
+}
+
+static void
+render_address_link (GString *buffer,
+ EContact *contact,
+ gint map_type)
+{
+ EContactAddress *adr;
+ GString *link = g_string_new ("");
+
+ adr = e_contact_get (contact, map_type);
+ if (adr &&
+ (adr->street || adr->locality || adr->region || adr->country)) {
+ gchar *escaped;
+
+ if (adr->street && *adr->street)
+ g_string_append_printf (link, "%s, ", adr->street);
+
+ if (adr->locality && *adr->locality)
+ g_string_append_printf (link, "%s, ", adr->locality);
+
+ if (adr->region && *adr->region)
+ g_string_append_printf (link, "%s, ", adr->region);
+
+ if (adr->country && *adr->country)
+ g_string_append_printf (link, "%s", adr->country);
+
+ escaped = g_uri_escape_string (link->str, NULL, TRUE);
+ g_string_assign (link, escaped);
+ g_free (escaped);
+
+ g_string_prepend (link, "<a href=\"http://maps.google.com?q=");
+ g_string_append_printf (link, "\">%s</a>", _("Open map"));
+ }
+
+ if (adr)
+ e_contact_address_free (adr);
+
+ g_string_append (buffer, link->str);
+ g_string_free (link, TRUE);
+}
+
+static void
+accum_address (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField adr_field,
+ EContactField label_field)
+{
+ EContactAddress *adr;
+ const gchar *label;
+ GString *map_link = g_string_new ("<br>");
+
+ render_address_link (map_link, contact, adr_field);
+
+ label = e_contact_get_const (contact, label_field);
+ if (label) {
+ gchar *html = e_text_to_html (label, E_TEXT_TO_HTML_CONVERT_NL);
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td align=\"right\" valign=\"top\" nowrap>%s</td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>",
+ html, html_label, map_link->str);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>%s</td>"
+ "</tr>",
+ html_label, map_link->str, html);
+ }
+
+ g_free (html);
+ g_string_free (map_link, TRUE);
+ return;
+ }
+
+ adr = e_contact_get (contact, adr_field);
+ if (adr &&
+ (adr->po || adr->ext || adr->street || adr->locality ||
+ adr->region || adr->code || adr->country)) {
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer, "<tr><td align=\"right\" valign=\"top\" nowrap>");
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "<th>%s:<br>%s</th>"
+ "<td valign=\"top\" nowrap>",
+ html_label, map_link->str);
+ }
+
+ if (adr->po && *adr->po)
+ g_string_append_printf (buffer, "%s<br>", adr->po);
+
+ if (adr->ext && *adr->ext)
+ g_string_append_printf (buffer, "%s<br>", adr->ext);
+
+ if (adr->street && *adr->street)
+ g_string_append_printf (buffer, "%s<br>", adr->street);
+
+ if (adr->locality && *adr->locality)
+ g_string_append_printf (buffer, "%s<br>", adr->locality);
+
+ if (adr->region && *adr->region)
+ g_string_append_printf (buffer, "%s<br>", adr->region);
+
+ if (adr->code && *adr->code)
+ g_string_append_printf (buffer, "%s<br>", adr->code);
+
+ if (adr->country && *adr->country)
+ g_string_append_printf (buffer, "%s<br>", adr->country);
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer,
+ "</td><th%s:<br>%s</th>"
+ "<td width=\"" IMAGE_COL_WIDTH "\"></td>"
+ "</tr>", html_label, map_link->str);
+ } else {
+ g_string_append_printf (buffer, "</td></tr>");
+ }
+
+ }
+
+ if (adr)
+ e_contact_address_free (adr);
+
+ g_string_free (map_link, TRUE);
+}
+
+static void
+render_table_row (GString *buffer,
+ const gchar *label,
+ const gchar *str,
+ const gchar *icon,
+ guint html_flags)
+{
+ const gchar *icon_html;
+ gchar *value;
+
+ if (html_flags)
+ value = e_text_to_html (str, html_flags);
+ else
+ value = (gchar *) str;
+
+ if (icon && icon_available (icon)) {
+ icon_html = g_strdup_printf ("<img src=\"gtk-stock://%s\" width=\"16\" height=\"16\" />", icon);
+ } else {
+ icon_html = "";
+ }
+
+ if (TEXT_IS_RIGHT_TO_LEFT) {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" align=\"right\">%s</td>"
+ "<th align=\"right\" valign=\"top\" width=\"100\" nowrap>:%s</th>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "</tr>",
+ value, label, icon_html);
+ } else {
+ g_string_append_printf (
+ buffer, "<tr>"
+ "<td valign=\"top\" width=\"" IMAGE_COL_WIDTH "\">%s</td>"
+ "<th valign=\"top\" width=\"100\" nowrap>%s:</th>"
+ "<td valign=\"top\">%s</td>"
+ "</tr>",
+ icon_html, label, value);
+ }
+
+ if (html_flags)
+ g_free (value);
+}
+
+static void
+accum_attribute (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ const gchar *str;
+
+ str = e_contact_get_const (contact, field);
+
+ if (str != NULL && *str != '\0')
+ render_table_row (buffer, html_label, str, icon, html_flags);
+}
+
+static void
+accum_time_attribute (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ EContactDate *date;
+ GDate *gdate = NULL;
+ gchar sdate[100];
+
+ date = e_contact_get (contact, field);
+ if (date) {
+ gdate = g_date_new_dmy (
+ date->day,
+ date->month,
+ date->year);
+ g_date_strftime (sdate, 100, "%x", gdate);
+ g_date_free (gdate);
+ render_table_row (buffer, html_label, sdate, icon, html_flags);
+ e_contact_date_free (date);
+ }
+}
+
+static void
+accum_attribute_multival (GString *buffer,
+ EContact *contact,
+ const gchar *html_label,
+ EContactField field,
+ const gchar *icon,
+ guint html_flags)
+{
+ GList *val_list, *l;
+ GString *val = g_string_new ("");
+
+ val_list = e_contact_get (contact, field);
+
+ for (l = val_list; l; l = l->next) {
+ if (l != val_list)
+ g_string_append (val, "<br>");
+
+ g_string_append (val, l->data);
+ }
+
+ if (val->str && *val->str)
+ render_table_row (buffer, html_label, val->str, icon, html_flags);
+
+ g_string_free (val, TRUE);
+ g_list_foreach (val_list, (GFunc) g_free, NULL);
+ g_list_free (val_list);
+}
+
+static const gchar *
+get_email_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 _(common_location[i].pretty_name);
+ }
+
+ return _("Other");
+}
+
+static void
+render_title_block (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+ gchar *html;
+ EContactPhoto *photo;
+
+ g_string_append_printf (
+ buffer,
+ "<table border=\"0\"><tr>"
+ "<td %s valign=\"middle\">", TEXT_IS_RIGHT_TO_LEFT ?
+ "align=\"right\"" : "");
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+ if (!photo)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+
+ if (photo && photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ gchar *photo_data;
+ photo_data = g_base64_encode (
+ photo->data.inlined.data,
+ photo->data.inlined.length);
+ g_string_append_printf (
+ buffer, "<img border=\"1\" src=\"data:%s;base64,%s\">",
+ photo->data.inlined.mime_type,
+ photo_data);
+ } else if (photo && photo->type == E_CONTACT_PHOTO_TYPE_URI && photo->data.uri && *photo->data.uri) {
+ gboolean is_local = g_str_has_prefix (photo->data.uri, "file://");
+ gchar *unescaped = g_uri_unescape_string (photo->data.uri, NULL);
+ g_string_append_printf (
+ buffer, "<img border=\"1\" src=\"%s%s\">",
+ is_local ? "evo-" : "", unescaped);
+ g_free (unescaped);
+ }
+
+ if (photo)
+ e_contact_photo_free (photo);
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ g_string_append_printf (buffer, "<img src=\"gtk-stock://%s\">", CONTACT_LIST_ICON);
+ }
+
+ g_string_append_printf (
+ buffer,
+ "</td><td width=\"20\"></td><td %s valign=\"top\">\n",
+ TEXT_IS_RIGHT_TO_LEFT ? "align=\"right\"" : "");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+ if (!str)
+ str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ g_string_append_printf (
+ buffer,
+ "<h2><a href=\"internal-mailto:0\">%s</a></h2>",
+ html);
+ } else {
+ g_string_append_printf (buffer, "<h2>%s</h2>", html);
+ }
+ g_free (html);
+ }
+
+ g_string_append (buffer, "</td></tr></table>");
+}
+
+static void
+render_contact_list_row (EABContactFormatter *formatter,
+ EDestination *destination,
+ GString *buffer)
+{
+ gchar *evolution_imagesdir;
+ gboolean list_collapsed = FALSE;
+ const gchar *textrep;
+ gchar *name = NULL, *email_addr = NULL;
+
+ evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
+
+ textrep = e_destination_get_textrep (destination, TRUE);
+ if (!eab_parse_qp_email (textrep, &name, &email_addr))
+ email_addr = g_strdup (textrep);
+
+ g_string_append (buffer, "<tr>");
+ if (e_destination_is_evolution_list (destination)) {
+ g_string_append_printf (
+ buffer,
+ "<td width=" IMAGE_COL_WIDTH " valign=\"top\" align=\"left\">"
+ "<img src=\"evo-file://%s/minus.png\" "
+ "id=\"%s\" "
+ "class=\"navigable _evo_collapse_button\">"
+ "</td><td width=\"100%%\" align=\"left\">%s",
+ evolution_imagesdir,
+ e_destination_get_contact_uid (destination),
+ name ? name : email_addr);
+
+ if (!list_collapsed) {
+ const GList *dest, *dests;
+ g_string_append_printf (
+ buffer,
+ "<br><table cellspacing=\"1\" id=\"list-%s\">",
+ e_destination_get_contact_uid (destination));
+
+ dests = e_destination_list_get_root_dests (destination);
+ for (dest = dests; dest; dest = dest->next) {
+ render_contact_list_row (
+ formatter, dest->data, buffer);
+ }
+
+ g_string_append (buffer, "</table>");
+ }
+
+ g_string_append (buffer, "</td>");
+
+ } else {
+ if (name && *name) {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">%s &lt"
+ "<a href=\"mailto:%s\">%s</a>&gt;"
+ "</td>",
+ name, email_addr, email_addr);
+ } else {
+ g_string_append_printf (
+ buffer,
+ "<td colspan=\"2\">"
+ "<a href=\"mailto:%s\">%s</a>"
+ "</td>",
+ email_addr, email_addr);
+ }
+ }
+
+ g_string_append (buffer, "</tr>");
+
+ g_free (evolution_imagesdir);
+ g_free (name);
+ g_free (email_addr);
+}
+
+static void
+render_contact_list (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ EDestination *destination;
+ const GList *dest, *dests;
+
+ destination = e_destination_new ();
+ e_destination_set_contact (destination, contact, 0);
+ dests = e_destination_list_get_root_dests (destination);
+
+ render_title_block (formatter, contact, buffer);
+
+ g_string_append_printf (
+ buffer,
+ "<table border=\"0\"><tr><th colspan=\"2\">%s</th></tr>"
+ "<tr><td with=" IMAGE_COL_WIDTH "></td><td>", _("List Members:"));
+
+ g_string_append (buffer, "<table border=\"0\" cellspacing=\"1\">");
+
+ for (dest = dests; dest; dest = dest->next)
+ render_contact_list_row (formatter, dest->data, buffer);
+
+ g_string_append (buffer, "</table>");
+ g_string_append (buffer, "</td></tr></table>");
+
+ g_object_unref (destination);
+}
+
+static void
+render_contact_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum, *email;
+ GList *email_list, *l, *email_attr_list, *al;
+ gint email_num = 0;
+ const gchar *nl;
+
+ email = g_string_new ("");
+ nl = "";
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+ email_attr_list = e_contact_get_attributes (contact, E_CONTACT_EMAIL);
+
+ for (l = email_list, al = email_attr_list; l && al; l = l->next, al = al->next) {
+ gchar *name = NULL, *mail = NULL;
+ gchar *attr_str = (gchar *) get_email_location ((EVCardAttribute *) al->data);
+
+ if (!eab_parse_qp_email (l->data, &name, &mail))
+ mail = e_text_to_html (l->data, 0);
+
+ g_string_append_printf (
+ email,
+ "%s%s%s<a href=\"internal-mailto:%d\">%s</a>%s "
+ "<span class=\"header\">(%s)</span>",
+ nl,
+ name ? name : "",
+ name ? " &lt;" : "",
+ email_num,
+ mail,
+ name ? "&gt;" : "",
+ attr_str ? attr_str : "");
+ email_num++;
+ nl = "<br>";
+
+ g_free (name);
+ g_free (mail);
+ }
+ g_list_foreach (email_list, (GFunc) g_free, NULL);
+ g_list_foreach (email_attr_list, (GFunc) e_vcard_attribute_free, NULL);
+ g_list_free (email_list);
+ g_list_free (email_attr_list);
+
+ accum = g_string_new ("");
+
+ if (email->len)
+ render_table_row (accum, _("Email"), email->str, NULL, 0);
+
+ accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0);
+ accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0);
+ accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0);
+ accum_attribute_multival (accum, contact, _("ICQ"), E_CONTACT_IM_ICQ, ICQ_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Jabber"), E_CONTACT_IM_JABBER, JABBER_ICON, 0);
+ accum_attribute_multival (accum, contact, _("MSN"), E_CONTACT_IM_MSN, MSN_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Yahoo"), E_CONTACT_IM_YAHOO, YAHOO_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Gadu-Gadu"), E_CONTACT_IM_GADUGADU, GADUGADU_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Skype"), E_CONTACT_IM_SKYPE, SKYPE_ICON, 0);
+ accum_attribute_multival (accum, contact, _("Twitter"), E_CONTACT_IM_TWITTER, TWITTER_ICON, 0);
+
+ if (accum->len)
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-internet\">"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", accum->str);
+
+ g_string_free (accum, TRUE);
+ g_string_free (email, TRUE);
+}
+
+static void
+accum_address_map (GString *buffer,
+ EContact *contact,
+ gint map_type)
+{
+#ifdef WITH_CONTACT_MAPS
+ g_string_append (buffer, "<tr><td colspan=\"3\">");
+
+ if (map_type == E_CONTACT_ADDRESS_WORK) {
+ g_string_append (
+ buffer,
+ "<object type=\"application/x-work-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ } else {
+ g_string_append (
+ buffer,
+ "<object type=\"application/x-home-map-widget\" "
+ "width=\"250\" height=\"250\"></object>");
+ }
+
+ g_string_append (buffer, "</td></tr>");
+#endif /* WITH_CONTACT_MAPS */
+}
+
+static void
+render_work_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum = g_string_new ("");
+
+ accum_attribute (accum, contact, _("Company"), E_CONTACT_ORG, NULL, 0);
+ accum_attribute (accum, contact, _("Department"), E_CONTACT_ORG_UNIT, NULL, 0);
+ accum_attribute (accum, contact, _("Profession"), E_CONTACT_ROLE, NULL, 0);
+ accum_attribute (accum, contact, _("Position"), E_CONTACT_TITLE, NULL, 0);
+ accum_attribute (accum, contact, _("Manager"), E_CONTACT_MANAGER, NULL, 0);
+ accum_attribute (accum, contact, _("Assistant"), E_CONTACT_ASSISTANT, NULL, 0);
+ accum_attribute (accum, contact, _("Video Chat"), E_CONTACT_VIDEO_URL, VIDEOCONF_ICON, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Calendar"), E_CONTACT_CALENDAR_URI, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Free/Busy"), E_CONTACT_FREEBUSY_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, 0);
+ accum_attribute (accum, contact, _("Fax"), E_CONTACT_PHONE_BUSINESS_FAX, NULL, 0);
+ accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK);
+ if (formatter->priv->render_maps)
+ accum_address_map (accum, contact, E_CONTACT_ADDRESS_WORK);
+
+ if (accum->len > 0) {
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-work\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Work"), accum->str);
+ }
+
+ g_string_free (accum, TRUE);
+}
+
+static void
+render_personal_column (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ GString *accum = g_string_new ("");
+
+ accum_attribute (accum, contact, _("Home Page"), E_CONTACT_HOMEPAGE_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Web Log"), E_CONTACT_BLOG_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS);
+ accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, 0);
+ accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, 0);
+ accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME);
+ accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0);
+ accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0);
+ accum_attribute (accum, contact, _("Spouse"), E_CONTACT_SPOUSE, NULL, 0);
+ if (formatter->priv->render_maps)
+ accum_address_map (accum, contact, E_CONTACT_ADDRESS_HOME);
+
+ if (accum->len > 0) {
+ g_string_append_printf (
+ buffer,
+ "<div class=\"column\" id=\"contact-personal\">"
+ "<h3>%s</h3>"
+ "<table border=\"0\" cellspacing=\"5\">%s</table>"
+ "</div>", _("Personal"), accum->str);
+ }
+
+ g_string_free (accum, TRUE);
+}
+
+static void
+render_footer (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+
+ str = e_contact_get_const (contact, E_CONTACT_NOTE);
+ if (!str || !*str)
+ return;
+
+ g_string_append (
+ buffer,
+ "<div id=\"footer\"><table border=\"0\" cellspacing=\"5\">");
+
+ render_table_row (
+ buffer, _("Note"),
+ e_contact_get_const (contact, E_CONTACT_NOTE),
+ NULL,
+ E_TEXT_TO_HTML_CONVERT_ADDRESSES |
+ E_TEXT_TO_HTML_CONVERT_URLS |
+ E_TEXT_TO_HTML_CONVERT_NL);
+
+ g_string_append (buffer, "</table></div>");
+}
+
+static void
+render_contact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ render_title_block (formatter, contact, buffer);
+
+ g_string_append (buffer, "<div id=\"columns\">");
+ render_contact_column (formatter, contact, buffer);
+ render_work_column (formatter, contact, buffer);
+ render_personal_column (formatter, contact, buffer);
+ g_string_append (buffer, "</div>");
+
+ render_footer (formatter, contact, buffer);
+}
+
+static void
+render_normal (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body bgcolor=\"white\">");
+
+ if (contact != NULL) {
+ if (e_contact_get (contact, E_CONTACT_IS_LIST))
+ render_contact_list (formatter, contact, buffer);
+ else
+ render_contact (formatter, contact, buffer);
+ }
+
+ g_string_append (buffer, "</body></html>\n");
+}
+
+static void
+render_compact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *buffer)
+{
+ const gchar *str;
+ gchar *html;
+ EContactPhoto *photo;
+
+ g_string_append (buffer, HTML_HEADER);
+ g_string_append (buffer, "<body>\n");
+
+ if (contact == NULL) {
+ g_string_append (buffer, "</body></html>");
+ return;
+ }
+
+ g_string_append_printf (
+ buffer,
+ "<table><tr><td valign=\"top\">");
+
+ photo = e_contact_get (contact, E_CONTACT_PHOTO);
+
+ if (photo == NULL)
+ photo = e_contact_get (contact, E_CONTACT_LOGO);
+
+ if (photo != NULL) {
+ gint calced_width = MAX_COMPACT_IMAGE_DIMENSION;
+ gint calced_height = MAX_COMPACT_IMAGE_DIMENSION;
+ GdkPixbufLoader *loader = gdk_pixbuf_loader_new ();
+ GdkPixbuf *pixbuf;
+
+ /* figure out if we need to downscale the
+ * image here. we don't scale the pixbuf
+ * itself, just insert width/height tags in
+ * the html */
+ if (photo->type == E_CONTACT_PHOTO_TYPE_INLINED) {
+ gdk_pixbuf_loader_write (
+ loader, photo->data.inlined.data,
+ photo->data.inlined.length, NULL);
+ } else if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
+ photo->data.uri &&
+ g_ascii_strncasecmp (photo->data.uri, "file://", 7) == 0) {
+ gchar *filename, *contents = NULL;
+ gsize length;
+
+ filename = g_filename_from_uri (photo->data.uri, NULL, NULL);
+
+ if (filename) {
+ if (g_file_get_contents (filename, &contents, &length, NULL)) {
+ gdk_pixbuf_loader_write (loader, (const guchar *) contents, length, NULL);
+ g_free (contents);
+ }
+
+ g_free (filename);
+ }
+ }
+
+ gdk_pixbuf_loader_close (loader, NULL);
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ if (pixbuf)
+ g_object_ref (pixbuf);
+
+ g_object_unref (loader);
+
+ if (pixbuf) {
+ gint max_dimension;
+
+ calced_width = gdk_pixbuf_get_width (pixbuf);
+ calced_height = gdk_pixbuf_get_height (pixbuf);
+
+ max_dimension = calced_width;
+
+ if (max_dimension < calced_height)
+ max_dimension = calced_height;
+
+ if (max_dimension > MAX_COMPACT_IMAGE_DIMENSION) {
+ calced_width *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
+ calced_height *= ((gfloat) MAX_COMPACT_IMAGE_DIMENSION / max_dimension);
+ }
+
+ g_object_unref (pixbuf);
+ }
+
+ if (photo->type == E_CONTACT_PHOTO_TYPE_URI &&
+ photo->data.uri && *photo->data.uri) {
+ gboolean is_local = g_str_has_prefix (photo->data.uri, "file://");
+ gchar *unescaped = g_uri_unescape_string (photo->data.uri, NULL);
+ g_string_append_printf (
+ buffer,
+ "<img width=\"%d\" height=\"%d\" src=\"%s%s\">",
+ calced_width, calced_height,
+ is_local ? "evo-" : "", unescaped);
+ g_free (unescaped);
+ } else {
+ gchar *photo_data;
+
+ photo_data = g_base64_encode (
+ photo->data.inlined.data,
+ photo->data.inlined.length);
+ g_string_append_printf (
+ buffer,
+ "<img border=\"1\" src=\"data:%s;base64,%s\" "
+ "width=\"%d\" height=\"%d\">",
+ photo->data.inlined.mime_type,
+ photo_data,
+ calced_width, calced_height);
+ g_free (photo_data);
+ }
+
+ e_contact_photo_free (photo);
+ }
+
+ g_string_append (buffer, "</td><td width=\"5\"></td><td valign=\"top\">\n");
+
+ str = e_contact_get_const (contact, E_CONTACT_FILE_AS);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ g_string_append_printf (buffer, "<b>%s</b>", html);
+ g_free (html);
+ } else {
+ str = e_contact_get_const (contact, E_CONTACT_FULL_NAME);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ g_string_append_printf (buffer, "<b>%s</b>", html);
+ g_free (html);
+ }
+ }
+
+ g_string_append (buffer, "<hr>");
+
+ if (e_contact_get (contact, E_CONTACT_IS_LIST)) {
+ GList *email_list;
+ GList *l;
+
+ g_string_append (
+ buffer,
+ "<table border=\"0\" cellspacing=\"0\" cellpadding=\"0\">"
+ "<tr><td valign=\"top\">");
+ g_string_append_printf (
+ buffer,
+ "<b>%s:</b>&nbsp;<td>", _ ("List Members"));
+
+ email_list = e_contact_get (contact, E_CONTACT_EMAIL);
+
+ for (l = email_list; l; l = l->next) {
+ if (l->data) {
+ html = e_text_to_html (l->data, 0);
+ g_string_append_printf (buffer, "%s, ", html);
+ g_free (html);
+ }
+ }
+
+ g_string_append (buffer, "</td></tr></table>");
+
+ } else {
+
+ gboolean comma = FALSE;
+ str = e_contact_get_const (contact, E_CONTACT_TITLE);
+
+ if (str) {
+ html = e_text_to_html (str, 0);
+ g_string_append_printf (buffer, "<b>%s:</b> %s<br>", _ ("Job Title"), str);
+ g_free (html);
+ }
+
+ #define print_email() { \
+ html = eab_parse_qp_email_to_html (str); \
+ \
+ if (!html) \
+ html = e_text_to_html (str, 0); \
+ \
+ g_string_append_printf (buffer, "%s%s", comma ? ", " : "", html); \
+ g_free (html); \
+ comma = TRUE; \
+ }
+
+ g_string_append_printf (buffer, "<b>%s:</b> ", _ ("Email"));
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_1);
+
+ if (str)
+ print_email ();
+
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_2);
+
+ if (str)
+ print_email ();
+
+ str = e_contact_get_const (contact, E_CONTACT_EMAIL_3);
+
+ if (str)
+ print_email ();
+
+ g_string_append (buffer, "<br>");
+
+ #undef print_email
+
+ str = e_contact_get_const (contact, E_CONTACT_HOMEPAGE_URL);
+
+ if (str) {
+ html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ g_string_append_printf (
+ buffer, "<b>%s:</b> %s<br>",
+ _ ("Home page"), html);
+ g_free (html);
+ }
+
+ str = e_contact_get_const (contact, E_CONTACT_BLOG_URL);
+
+ if (str) {
+ html = e_text_to_html (str, E_TEXT_TO_HTML_CONVERT_URLS);
+ g_string_append_printf (
+ buffer, "<b>%s:</b> %s<br>",
+ _ ("Blog"), html);
+ }
+ }
+
+ g_string_append (buffer, "</td></tr></table>\n");
+
+ g_string_append (buffer, "</body></html>\n");
+}
+
+static void
+eab_contact_formatter_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DISPLAY_MODE:
+ eab_contact_formatter_set_display_mode (
+ EAB_CONTACT_FORMATTER (object),
+ g_value_get_int (value));
+ return;
+
+ case PROP_RENDER_MAPS:
+ eab_contact_formatter_set_render_maps (
+ EAB_CONTACT_FORMATTER (object),
+ g_value_get_boolean (value));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_contact_formatter_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id) {
+ case PROP_DISPLAY_MODE:
+ g_value_set_int (
+ value,
+ eab_contact_formatter_get_display_mode (
+ EAB_CONTACT_FORMATTER (object)));
+ return;
+
+ case PROP_RENDER_MAPS:
+ g_value_set_boolean (
+ value,
+ eab_contact_formatter_get_render_maps (
+ EAB_CONTACT_FORMATTER (object)));
+ return;
+ }
+
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+}
+
+static void
+eab_contact_formatter_class_init (EABContactFormatterClass *class)
+{
+ GObjectClass *object_class;
+
+ g_type_class_add_private (class, sizeof (EABContactFormatterClass));
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = eab_contact_formatter_set_property;
+ object_class->get_property = eab_contact_formatter_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ PROP_DISPLAY_MODE,
+ g_param_spec_int (
+ "display-mode",
+ "Display Mode",
+ NULL,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ EAB_CONTACT_DISPLAY_RENDER_COMPACT,
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_RENDER_MAPS,
+ g_param_spec_boolean (
+ "render-maps",
+ "Render Maps",
+ NULL,
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+eab_contact_formatter_init (EABContactFormatter *formatter)
+{
+ formatter->priv = EAB_CONTACT_FORMATTER_GET_PRIVATE (formatter);
+
+ formatter->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL;
+ formatter->priv->render_maps = FALSE;
+}
+
+EABContactFormatter *
+eab_contact_formatter_new (void)
+{
+ return g_object_new (EAB_TYPE_CONTACT_FORMATTER, NULL);
+}
+
+gboolean
+eab_contact_formatter_get_render_maps (EABContactFormatter *formatter)
+{
+ g_return_val_if_fail (EAB_IS_CONTACT_FORMATTER (formatter), FALSE);
+
+ return formatter->priv->render_maps;
+}
+
+void
+eab_contact_formatter_set_render_maps (EABContactFormatter *formatter,
+ gboolean render_maps)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+
+ if (formatter->priv->render_maps == render_maps)
+ return;
+
+ formatter->priv->render_maps = render_maps;
+
+ g_object_notify (G_OBJECT (formatter), "render-maps");
+}
+
+EABContactDisplayMode
+eab_contact_formatter_get_display_mode (EABContactFormatter *formatter)
+{
+ g_return_val_if_fail (
+ EAB_IS_CONTACT_FORMATTER (formatter),
+ EAB_CONTACT_DISPLAY_RENDER_NORMAL);
+
+ return formatter->priv->mode;
+}
+
+void
+eab_contact_formatter_set_display_mode (EABContactFormatter *formatter,
+ EABContactDisplayMode mode)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+
+ if (formatter->priv->mode == mode)
+ return;
+
+ formatter->priv->mode = mode;
+
+ g_object_notify (G_OBJECT (formatter), "display-mode");
+}
+
+void
+eab_contact_formatter_format_contact (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *output_buffer)
+{
+ g_return_if_fail (EAB_IS_CONTACT_FORMATTER (formatter));
+ g_return_if_fail (E_IS_CONTACT (contact));
+ g_return_if_fail (output_buffer != NULL);
+
+ if (formatter->priv->mode == EAB_CONTACT_DISPLAY_RENDER_NORMAL)
+ render_normal (formatter, contact, output_buffer);
+ else
+ render_compact (formatter, contact, output_buffer);
+}
+
+static void
+collapse_contacts_list (WebKitDOMEventTarget *event_target,
+ WebKitDOMEvent *event,
+ gpointer user_data)
+{
+ WebKitDOMDocument *document;
+ WebKitDOMElement *list;
+ gchar *id, *list_id;
+ gchar *imagesdir, *src;
+ gboolean hidden;
+
+ document = user_data;
+ id = webkit_dom_html_element_get_id (WEBKIT_DOM_HTML_ELEMENT (event_target));
+
+ list_id = g_strconcat ("list-", id, NULL);
+ list = webkit_dom_document_get_element_by_id (document, list_id);
+ g_free (id);
+ g_free (list_id);
+
+ if (list == NULL)
+ return;
+
+ imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL);
+ hidden = webkit_dom_html_element_get_hidden (WEBKIT_DOM_HTML_ELEMENT (list));
+
+ if (hidden)
+ src = g_strdup_printf ("evo-file://%s/minus.png", imagesdir);
+ else
+ src = g_strdup_printf ("evo-file://%s/plus.png", imagesdir);
+
+ webkit_dom_html_element_set_hidden (
+ WEBKIT_DOM_HTML_ELEMENT (list), !hidden);
+ webkit_dom_html_image_element_set_src (
+ WEBKIT_DOM_HTML_IMAGE_ELEMENT (event_target), src);
+
+ g_free (src);
+ g_free (imagesdir);
+}
+
+void
+eab_contact_formatter_bind_dom (WebKitDOMDocument *document)
+{
+ WebKitDOMNodeList *nodes;
+ gulong ii, length;
+
+ nodes = webkit_dom_document_get_elements_by_class_name (
+ document, "_evo_collapse_button");
+
+ length = webkit_dom_node_list_get_length (nodes);
+ for (ii = 0; ii < length; ii++) {
+
+ WebKitDOMNode *node;
+
+ node = webkit_dom_node_list_item (nodes, ii);
+ webkit_dom_event_target_add_event_listener (
+ WEBKIT_DOM_EVENT_TARGET (node), "click",
+ G_CALLBACK (collapse_contacts_list), FALSE, document);
+ }
+}
diff --git a/addressbook/gui/widgets/eab-contact-formatter.h b/addressbook/gui/widgets/eab-contact-formatter.h
new file mode 100644
index 0000000000..4dc1427960
--- /dev/null
+++ b/addressbook/gui/widgets/eab-contact-formatter.h
@@ -0,0 +1,84 @@
+/*
+ * eab-contact-formatter.h
+ *
+ * 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/>
+ *
+ */
+
+#ifndef EAB_CONTACT_FORMATTER_H
+#define EAB_CONTACT_FORMATTER_H
+
+#include <camel/camel.h>
+#include <libebook/libebook.h>
+
+#include <addressbook/gui/widgets/eab-contact-display.h>
+
+/* Standard GObject macros */
+#define EAB_TYPE_CONTACT_FORMATTER \
+ (eab_contact_formatter_get_type ())
+#define EAB_CONTACT_FORMATTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatter))
+#define EAB_CONTACT_FORMATTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass))
+#define EAB_IS_CONTACT_FORMATTER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER))
+#define EAB_IS_CONTACT_FORMATTER_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), EAB_TYPE_CONTACT_FORMATTER))
+#define EAB_CONTACT_FORMATTER_GET_CLASS(obj) \
+ (G_TYPE_ISNTANCE_GET_CLASS \
+ ((obj), EAB_TYPE_CONTACT_FORMATTER, EABContactFormatterClass))
+
+G_BEGIN_DECLS
+
+typedef struct _EABContactFormatter EABContactFormatter;
+typedef struct _EABContactFormatterClass EABContactFormatterClass;
+typedef struct _EABContactFormatterPrivate EABContactFormatterPrivate;
+
+struct _EABContactFormatter {
+ GObject parent;
+ EABContactFormatterPrivate *priv;
+};
+
+struct _EABContactFormatterClass {
+ GObjectClass parent_class;
+};
+
+GType eab_contact_formatter_get_type (void) G_GNUC_CONST;
+EABContactFormatter *
+ eab_contact_formatter_new (void);
+gboolean eab_contact_formatter_get_render_maps
+ (EABContactFormatter *formatter);
+void eab_contact_formatter_set_render_maps
+ (EABContactFormatter *formatter,
+ gboolean render_maps);
+EABContactDisplayMode
+ eab_contact_formatter_get_display_mode
+ (EABContactFormatter *formatter);
+void eab_contact_formatter_set_display_mode
+ (EABContactFormatter *formatter,
+ EABContactDisplayMode mode);
+void eab_contact_formatter_format_contact
+ (EABContactFormatter *formatter,
+ EContact *contact,
+ GString *output_buffer);
+void eab_contact_formatter_bind_dom (WebKitDOMDocument *document);
+
+G_END_DECLS
+
+#endif /* EAB_CONTACT_FORMATTER_H */
+
diff --git a/addressbook/gui/widgets/eab-gui-util.c b/addressbook/gui/widgets/eab-gui-util.c
new file mode 100644
index 0000000000..5f155ad1b1
--- /dev/null
+++ b/addressbook/gui/widgets/eab-gui-util.c
@@ -0,0 +1,1119 @@
+/*
+ * 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>
+ * Dan Vratil <dvratil@redhat.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <locale.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+
+#include "shell/e-shell.h"
+
+#include "eab-gui-util.h"
+#include "util/eab-book-util.h"
+#include "eab-contact-merging.h"
+
+/* we link to camel for decoding quoted printable email addresses */
+#include <camel/camel.h>
+
+/* Template tags for address format localization */
+#define ADDRESS_REALNAME "%n" /* this is not used intentionally */
+#define ADDRESS_REALNAME_UPPER "%N" /* this is not used intentionally */
+#define ADDRESS_COMPANY "%m"
+#define ADDRESS_COMPANY_UPPER "%M"
+#define ADDRESS_POBOX "%p"
+#define ADDRESS_STREET "%s"
+#define ADDRESS_STREET_UPPER "%S"
+#define ADDRESS_ZIPCODE "%z"
+#define ADDRESS_LOCATION "%l"
+#define ADDRESS_LOCATION_UPPER "%L"
+#define ADDRESS_REGION "%r"
+#define ADDRESS_REGION_UPPER "%R"
+#define ADDRESS_CONDCOMMA "%," /* Conditional comma is removed when a surrounding tag is evaluated to zero */
+#define ADDRESS_CONDWHITE "%w" /* Conditional whitespace is removed when a surrounding tag is evaluated to zero */
+#define ADDRESS_COND_PURGEEMPTY "%0" /* Purge empty has following syntax: %0(...) and is removed when no tag within () is evaluated non-zero */
+
+/* Fallback formats */
+#define ADDRESS_DEFAULT_FORMAT "%0(%n\n)%0(%m\n)%0(%s\n)%0(PO BOX %p\n)%0(%l%w%r)%,%z"
+#define ADDRESS_DEFAULT_COUNTRY_POSITION "below"
+
+enum {
+ LOCALES_LANGUAGE = 0,
+ LOCALES_COUNTRY = 1
+};
+
+typedef enum {
+ ADDRESS_FORMAT_HOME = 0,
+ ADDRESS_FORMAT_BUSINESS = 1
+} AddressFormat;
+
+void
+eab_error_dialog (EAlertSink *alert_sink,
+ GtkWindow *parent,
+ const gchar *msg,
+ const GError *error)
+{
+ if (error && error->message) {
+ if (alert_sink)
+ e_alert_submit (
+ alert_sink,
+ "addressbook:generic-error",
+ msg, error->message, NULL);
+ else {
+ if (!parent)
+ parent = e_shell_get_active_window (NULL);
+
+ e_alert_run_dialog_for_args (
+ parent,
+ "addressbook:generic-error",
+ msg, error->message, NULL);
+ }
+ }
+}
+
+void
+eab_load_error_dialog (GtkWidget *parent,
+ EAlertSink *alert_sink,
+ ESource *source,
+ const GError *error)
+{
+ ESourceBackend *extension;
+ gchar *label_string, *label = NULL;
+ gboolean can_detail_error = TRUE;
+ const gchar *backend_name;
+ const gchar *extension_name;
+
+ g_return_if_fail (source != NULL);
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ extension = e_source_get_extension (source, extension_name);
+ backend_name = e_source_backend_get_backend_name (extension);
+
+ if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_OFFLINE_UNAVAILABLE)) {
+ can_detail_error = FALSE;
+ label_string =
+ _("This address book cannot be opened. This either "
+ "means this book is not marked for offline usage "
+ "or not yet downloaded for offline usage. Please "
+ "load the address book once in online mode to "
+ "download its contents.");
+ }
+
+ else if (g_strcmp0 (backend_name, "local") == 0) {
+ const gchar *user_data_dir;
+ const gchar *uid;
+ gchar *path;
+
+ uid = e_source_get_uid (source);
+ user_data_dir = e_get_user_data_dir ();
+
+ path = g_build_filename (
+ user_data_dir, "addressbook", uid, NULL);
+
+ label = g_strdup_printf (
+ _("This address book cannot be opened. Please check that the "
+ "path %s exists and that permissions are set to access it."), path);
+
+ g_free (path);
+ label_string = label;
+ }
+
+#ifndef HAVE_LDAP
+ else if (g_strcmp0 (backend_name, "ldap") == 0) {
+ /* special case for ldap: contact folders so we can tell the user about openldap */
+
+ can_detail_error = FALSE;
+ label_string =
+ _("This version of Evolution does not have LDAP support "
+ "compiled in to it. To use LDAP in Evolution "
+ "an LDAP-enabled Evolution package must be installed.");
+
+ }
+#endif
+ else {
+ /* other network folders (or if ldap is enabled and server is unreachable) */
+ label_string =
+ _("This address book cannot be opened. This either "
+ "means that an incorrect URI was entered, or the server "
+ "is unreachable.");
+ }
+
+ if (can_detail_error) {
+ /* do not show repository offline message, it's kind of generic error */
+ if (error && !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_REPOSITORY_OFFLINE)) {
+ label = g_strconcat (label_string, "\n\n", _("Detailed error message:"), " ", error->message, NULL);
+ label_string = label;
+ }
+ }
+
+ if (alert_sink) {
+ e_alert_submit (
+ alert_sink, "addressbook:load-error",
+ label_string, NULL);
+ } else {
+ GtkWidget *dialog;
+
+ dialog = e_alert_dialog_new_for_args (
+ (GtkWindow *) parent,
+ "addressbook:load-error",
+ label_string, NULL);
+ g_signal_connect (
+ dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+ gtk_widget_show (dialog);
+ }
+
+ g_free (label);
+}
+
+void
+eab_search_result_dialog (EAlertSink *alert_sink,
+ const GError *error)
+{
+ gchar *str = NULL;
+
+ if (!error)
+ return;
+
+ if (error->domain == E_CLIENT_ERROR) {
+ switch (error->code) {
+ case E_CLIENT_ERROR_SEARCH_SIZE_LIMIT_EXCEEDED:
+ str = _("More cards matched this query than either the server is \n"
+ "configured to return or Evolution is configured to display.\n"
+ "Please make your search more specific or raise the result limit in\n"
+ "the directory server preferences for this address book.");
+ str = g_strdup (str);
+ break;
+ case E_CLIENT_ERROR_SEARCH_TIME_LIMIT_EXCEEDED:
+ str = _("The time to execute this query exceeded the server limit or the limit\n"
+ "configured for this address book. Please make your search\n"
+ "more specific or raise the time limit in the directory server\n"
+ "preferences for this address book.");
+ str = g_strdup (str);
+ break;
+ case E_CLIENT_ERROR_INVALID_QUERY:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("The backend for this address book was unable to parse this query. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ case E_CLIENT_ERROR_QUERY_REFUSED:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("The backend for this address book refused to perform this query. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ case E_CLIENT_ERROR_OTHER_ERROR:
+ default:
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("This query did not complete successfully. %s");
+ str = g_strdup_printf (str, error->message);
+ break;
+ }
+ } else {
+ /* Translators: %s is replaced with a detailed error message, or an empty string, if not provided */
+ str = _("This query did not complete successfully. %s");
+ str = g_strdup_printf (str, error->message);
+ }
+
+ e_alert_submit (alert_sink, "addressbook:search-error", str, NULL);
+
+ g_free (str);
+}
+
+gint
+eab_prompt_save_dialog (GtkWindow *parent)
+{
+ return e_alert_run_dialog_for_args (parent, "addressbook:prompt-save", NULL);
+}
+
+static gchar *
+make_safe_filename (gchar *name)
+{
+ gchar *safe;
+
+ if (!name) {
+ /* This is a filename. Translators take note. */
+ name = _("card.vcf");
+ }
+
+ if (!g_strrstr (name, ".vcf"))
+ safe = g_strdup_printf ("%s%s", name, ".vcf");
+ else
+ safe = g_strdup (name);
+
+ e_filename_make_safe (safe);
+
+ return safe;
+}
+
+static void
+source_selection_changed_cb (ESourceSelector *selector,
+ GtkWidget *ok_button)
+{
+ ESource *except_source = NULL, *selected;
+ gboolean sensitive;
+
+ except_source = g_object_get_data (G_OBJECT (ok_button), "except-source");
+ selected = e_source_selector_ref_primary_selection (selector);
+
+ sensitive = (selected != NULL && selected != except_source);
+ gtk_widget_set_sensitive (ok_button, sensitive);
+
+ if (selected != NULL)
+ g_object_unref (selected);
+}
+
+ESource *
+eab_select_source (ESourceRegistry *registry,
+ ESource *except_source,
+ const gchar *title,
+ const gchar *message,
+ const gchar *select_uid,
+ GtkWindow *parent)
+{
+ ESource *source;
+ GtkWidget *content_area;
+ GtkWidget *dialog;
+ GtkWidget *ok_button;
+ /* GtkWidget *label; */
+ GtkWidget *selector;
+ GtkWidget *scrolled_window;
+ const gchar *extension_name;
+ gint response;
+
+ g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
+
+ dialog = gtk_dialog_new_with_buttons (
+ _("Select Address Book"), parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_window_set_default_size (GTK_WINDOW (dialog), 350, 300);
+
+ gtk_dialog_set_response_sensitive (
+ GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT, FALSE);
+
+ /* label = gtk_label_new (message); */
+
+ extension_name = E_SOURCE_EXTENSION_ADDRESS_BOOK;
+ selector = e_source_selector_new (registry, extension_name);
+ e_source_selector_set_show_toggles (
+ E_SOURCE_SELECTOR (selector), FALSE);
+
+ ok_button = gtk_dialog_get_widget_for_response (
+ GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
+
+ if (except_source)
+ g_object_set_data (
+ G_OBJECT (ok_button), "except-source", except_source);
+
+ g_signal_connect (
+ selector, "primary_selection_changed",
+ G_CALLBACK (source_selection_changed_cb), ok_button);
+
+ if (select_uid) {
+ source = e_source_registry_ref_source (registry, select_uid);
+ if (source != NULL) {
+ e_source_selector_set_primary_selection (
+ E_SOURCE_SELECTOR (selector), source);
+ g_object_unref (source);
+ }
+ }
+
+ scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window), GTK_SHADOW_IN);
+ gtk_container_add (GTK_CONTAINER (scrolled_window), selector);
+
+ content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
+ gtk_box_pack_start (GTK_BOX (content_area), scrolled_window, TRUE, TRUE, 4);
+
+ gtk_widget_show_all (dialog);
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ source = e_source_selector_ref_primary_selection (
+ E_SOURCE_SELECTOR (selector));
+ else
+ source = NULL;
+
+ gtk_widget_destroy (dialog);
+
+ /* XXX Return a borrowed reference for backward-compatibility. */
+ if (source != NULL)
+ g_object_unref (source);
+
+ return source;
+}
+
+gchar *
+eab_suggest_filename (const GSList *contact_list)
+{
+ gchar *res = NULL;
+
+ g_return_val_if_fail (contact_list != NULL, NULL);
+
+ if (!contact_list->next) {
+ EContact *contact = E_CONTACT (contact_list->data);
+ gchar *string;
+
+ string = e_contact_get (contact, E_CONTACT_FILE_AS);
+ if (string == NULL)
+ string = e_contact_get (contact, E_CONTACT_FULL_NAME);
+ if (string != NULL)
+ res = make_safe_filename (string);
+ g_free (string);
+ }
+
+ if (res == NULL)
+ res = make_safe_filename (_("list"));
+
+ return res;
+}
+
+typedef struct ContactCopyProcess_ ContactCopyProcess;
+
+struct ContactCopyProcess_ {
+ gint count;
+ gboolean book_status;
+ GSList *contacts;
+ EBookClient *source;
+ EBookClient *destination;
+ ESourceRegistry *registry;
+ gboolean delete_from_source;
+ EAlertSink *alert_sink;
+};
+
+static void process_unref (ContactCopyProcess *process);
+
+static void
+remove_contact_ready_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ EBookClient *book_client = E_BOOK_CLIENT (source_object);
+ ContactCopyProcess *process = user_data;
+ GError *error = NULL;
+
+ e_book_client_remove_contact_by_uid_finish (book_client, result, &error);
+
+ if (error != NULL) {
+ g_warning (
+ "%s: Remove contact by uid failed: %s",
+ G_STRFUNC, error->message);
+ g_error_free (error);
+ }
+
+ process_unref (process);
+}
+
+static void
+do_delete_from_source (gpointer data,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+ EContact *contact = data;
+ const gchar *id;
+ EBookClient *book_client = process->source;
+
+ id = e_contact_get_const (contact, E_CONTACT_UID);
+ g_return_if_fail (id != NULL);
+ g_return_if_fail (book_client != NULL);
+
+ process->count++;
+ e_book_client_remove_contact_by_uid (book_client, id, NULL, remove_contact_ready_cb, process);
+}
+
+static void
+delete_contacts (ContactCopyProcess *process)
+{
+ if (process->book_status == TRUE) {
+ g_slist_foreach (process->contacts,
+ do_delete_from_source,
+ process);
+ }
+}
+
+static void
+process_unref (ContactCopyProcess *process)
+{
+ process->count--;
+ if (process->count == 0) {
+ if (process->delete_from_source) {
+ delete_contacts (process);
+ /* to not repeate this again */
+ process->delete_from_source = FALSE;
+
+ if (process->count > 0)
+ return;
+ }
+ g_slist_free_full (
+ process->contacts,
+ (GDestroyNotify) g_object_unref);
+ g_object_unref (process->source);
+ g_object_unref (process->destination);
+ g_object_unref (process->registry);
+ g_free (process);
+ }
+}
+
+static void
+contact_added_cb (EBookClient *book_client,
+ const GError *error,
+ const gchar *id,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+
+ if (error && !g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) &&
+ !g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ process->book_status = FALSE;
+ eab_error_dialog (process->alert_sink, NULL, _("Error adding contact"), error);
+ } else if (g_error_matches (error, E_CLIENT_ERROR, E_CLIENT_ERROR_CANCELLED) ||
+ g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ process->book_status = FALSE;
+ }
+ else {
+ /* success */
+ process->book_status = TRUE;
+ }
+
+ process_unref (process);
+}
+
+static void
+do_copy (gpointer data,
+ gpointer user_data)
+{
+ EBookClient *book_client;
+ EContact *contact;
+ ContactCopyProcess *process;
+
+ process = user_data;
+ contact = data;
+
+ book_client = process->destination;
+ e_contact_inline_local_photos (contact, NULL);
+
+ process->count++;
+ eab_merging_book_add_contact (
+ process->registry, book_client,
+ contact, contact_added_cb, process);
+}
+
+static void
+book_client_connect_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ ContactCopyProcess *process = user_data;
+ EClient *client;
+ GError *error = NULL;
+
+ client = e_book_client_connect_finish (result, &error);
+
+ /* Sanity check. */
+ g_return_if_fail (
+ ((client != NULL) && (error == NULL)) ||
+ ((client == NULL) && (error != NULL)));
+
+ if (error != NULL) {
+ g_warning ("%s: %s", G_STRFUNC, error->message);
+ g_error_free (error);
+ goto exit;
+ }
+
+ process->destination = E_BOOK_CLIENT (client);
+ process->book_status = TRUE;
+ g_slist_foreach (process->contacts, do_copy, process);
+
+exit:
+ process_unref (process);
+}
+
+void
+eab_transfer_contacts (ESourceRegistry *registry,
+ EBookClient *source_client,
+ GSList *contacts /* adopted */,
+ gboolean delete_from_source,
+ EAlertSink *alert_sink)
+{
+ ESource *source;
+ ESource *destination;
+ static gchar *last_uid = NULL;
+ ContactCopyProcess *process;
+ gchar *desc;
+ GtkWindow *window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (alert_sink)));
+
+ g_return_if_fail (E_IS_SOURCE_REGISTRY (registry));
+ g_return_if_fail (E_IS_BOOK_CLIENT (source_client));
+
+ if (contacts == NULL)
+ return;
+
+ if (last_uid == NULL)
+ last_uid = g_strdup ("");
+
+ if (contacts->next == NULL) {
+ if (delete_from_source)
+ desc = _("Move contact to");
+ else
+ desc = _("Copy contact to");
+ } else {
+ if (delete_from_source)
+ desc = _("Move contacts to");
+ else
+ desc = _("Copy contacts to");
+ }
+
+ source = e_client_get_source (E_CLIENT (source_client));
+
+ destination = eab_select_source (
+ registry, source, desc, NULL, last_uid, window);
+
+ if (!destination)
+ return;
+
+ if (strcmp (last_uid, e_source_get_uid (destination)) != 0) {
+ g_free (last_uid);
+ last_uid = g_strdup (e_source_get_uid (destination));
+ }
+
+ process = g_new (ContactCopyProcess, 1);
+ process->count = 1;
+ process->book_status = FALSE;
+ process->source = g_object_ref (source_client);
+ process->contacts = contacts;
+ process->destination = NULL;
+ process->registry = g_object_ref (registry);
+ process->alert_sink = alert_sink;
+ process->delete_from_source = delete_from_source;
+
+ e_book_client_connect (
+ destination, NULL, book_client_connect_cb, process);
+}
+
+/*
+ * eab_format_address helper function
+ *
+ * Splits locales from en_US to array "en","us",NULL. When
+ * locales don't have the second part (for example "C"),
+ * the output array is "c",NULL
+ */
+static gchar **
+get_locales (void)
+{
+ gchar *locale, *l_locale;
+ gchar *dot;
+ gchar **split;
+
+#ifdef LC_ADDRESS
+ locale = g_strdup (setlocale (LC_ADDRESS, NULL));
+#else
+ locale = NULL;
+#endif
+ if (!locale)
+ return NULL;
+
+ l_locale = g_utf8_strdown (locale, -1);
+ g_free (locale);
+
+ dot = strchr (l_locale, '.');
+ if (dot != NULL) {
+ gchar *p = l_locale;
+ l_locale = g_strndup (l_locale, dot - l_locale);
+ g_free (p);
+ }
+
+ split = g_strsplit (l_locale, "_", 2);
+
+ g_free (l_locale);
+ return split;
+
+}
+
+static gchar *
+get_locales_str (void)
+{
+ gchar *ret;
+ gchar **loc = get_locales ();
+
+ if (!loc)
+ return g_strdup ("C");
+
+ if (!loc[0] ||
+ (loc[0] && !loc[1])) /* We don't care about language now, we need a country at first! */
+ ret = g_strdup ("C");
+ else if (loc[0] && loc[1]) {
+ if (*loc[0])
+ ret = g_strconcat (loc[LOCALES_COUNTRY], "_", loc[LOCALES_LANGUAGE], NULL);
+ else
+ ret = g_strdup (loc[LOCALES_COUNTRY]);
+ }
+
+ g_strfreev (loc);
+ return ret;
+}
+
+/*
+ * Reads countrytransl.map file, which contains map of localized
+ * country names and their ISO codes and tries to find matching record
+ * for given country. The search is case insensitive.
+ * When no record is found (country is probably in untranslated language), returns
+ * code of local computer country (from locales)
+ */
+static gchar *
+country_to_ISO (const gchar *country)
+{
+ FILE *file = fopen (EVOLUTION_RULEDIR "/countrytransl.map", "r");
+ gchar buffer[100];
+ gint length = 100;
+ gchar **pair;
+ gchar *res;
+ gchar *l_country = g_utf8_strdown (country, -1);
+
+ if (!file) {
+ gchar **loc;
+ g_warning ("%s: Failed to open countrytransl.map. Check your installation.", G_STRFUNC);
+ loc = get_locales ();
+ res = g_strdup (loc ? loc[LOCALES_COUNTRY] : NULL);
+ g_free (l_country);
+ g_strfreev (loc);
+ return res;
+ }
+
+ while (fgets (buffer, length, file) != NULL) {
+ gchar *low = NULL;
+ pair = g_strsplit (buffer, "\t", 2);
+
+ if (pair[0]) {
+ low = g_utf8_strdown (pair[0], -1);
+ if (g_utf8_collate (low, l_country) == 0) {
+ gchar *ret = g_strdup (pair[1]);
+ gchar *pos;
+ /* Remove trailing newline character */
+ if ((pos = g_strrstr (ret, "\n")) != NULL)
+ pos[0] = '\0';
+ fclose (file);
+ g_strfreev (pair);
+ g_free (low);
+ g_free (l_country);
+ return ret;
+ }
+ }
+
+ g_strfreev (pair);
+ g_free (low);
+ }
+
+ /* If we get here, then no match was found in the map file and we
+ * fallback to local system locales */
+ fclose (file);
+
+ pair = get_locales ();
+ res = g_strdup (pair ? pair[LOCALES_COUNTRY] : NULL);
+ g_strfreev (pair);
+ g_free (l_country);
+ return res;
+}
+
+/*
+ * Tries to find given key in "country_LANGUAGE" group. When fails to find
+ * such group, then fallbacks to "country" group. When such group does not
+ * exist either, NULL is returned
+ */
+static gchar *
+get_key_file_locale_string (GKeyFile *key_file,
+ const gchar *key,
+ const gchar *locale)
+{
+ gchar *result;
+ gchar *group;
+
+ g_return_val_if_fail (locale, NULL);
+
+ /* Default locale is in "country_lang", but such group may not exist. In such case use group "country" */
+ if (g_key_file_has_group (key_file, locale))
+ group = g_strdup (locale);
+ else {
+ gchar **locales = g_strsplit (locale, "_", 0);
+ group = g_strdup (locales[LOCALES_COUNTRY]);
+ g_strfreev (locales);
+ }
+
+ /* When group or key does not exist, returns NULL and fallback string will be used */
+ result = g_key_file_get_string (key_file, group, key, NULL);
+ g_free (group);
+ return result;
+}
+
+static void
+get_address_format (AddressFormat address_format,
+ const gchar *locale,
+ gchar **format,
+ gchar **country_position)
+{
+ GKeyFile *key_file;
+ GError *error;
+ gchar *loc;
+ const gchar *addr_key, *country_key;
+
+ if (address_format == ADDRESS_FORMAT_HOME) {
+ addr_key = "AddressFormat";
+ country_key = "CountryPosition";
+ } else if (address_format == ADDRESS_FORMAT_BUSINESS) {
+ addr_key = "BusinessAddressFormat";
+ country_key = "BusinessCountryPosition";
+ } else {
+ return;
+ }
+
+ if (locale == NULL)
+ loc = get_locales_str ();
+ else
+ loc = g_strdup (locale);
+
+ error = NULL;
+ key_file = g_key_file_new ();
+ g_key_file_load_from_file (key_file, EVOLUTION_RULEDIR "/address_formats.dat", 0, &error);
+ if (error) {
+ g_warning ("%s: Failed to load address_formats.dat file: %s", G_STRFUNC, error->message);
+ *format = g_strdup (ADDRESS_DEFAULT_FORMAT);
+ *country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
+ g_key_file_free (key_file);
+ g_free (loc);
+ g_error_free (error);
+ return;
+ }
+
+ if (format) {
+ if (*format)
+ g_free (*format);
+ *format = get_key_file_locale_string (key_file, addr_key, loc);
+ if (!*format && address_format == ADDRESS_FORMAT_HOME) {
+ *format = g_strdup (ADDRESS_DEFAULT_FORMAT);
+ } else if (!*format && address_format == ADDRESS_FORMAT_BUSINESS)
+ get_address_format (ADDRESS_FORMAT_HOME, loc, format, NULL);
+ }
+
+ if (country_position) {
+ if (*country_position)
+ g_free (*country_position);
+ *country_position = get_key_file_locale_string (key_file, country_key, loc);
+ if (!*country_position && address_format == ADDRESS_FORMAT_HOME)
+ *country_position = g_strdup (ADDRESS_DEFAULT_COUNTRY_POSITION);
+ else if (!*country_position && address_format == ADDRESS_FORMAT_BUSINESS)
+ get_address_format (ADDRESS_FORMAT_HOME, loc, NULL, country_position);
+ }
+
+ g_free (loc);
+ g_key_file_free (key_file);
+}
+
+static const gchar *
+find_balanced_bracket (const gchar *str)
+{
+ gint balance_counter = 0;
+ gint i = 0;
+
+ do {
+ if (str[i] == '(')
+ balance_counter++;
+
+ if (str[i] == ')')
+ balance_counter--;
+
+ i++;
+
+ } while ((balance_counter > 0) && (str[i]));
+
+ if (balance_counter > 0)
+ return str;
+
+ return str + i;
+}
+
+static GString *
+string_append_upper (GString *str,
+ const gchar *c)
+{
+ gchar *up_c;
+
+ g_return_val_if_fail (str, NULL);
+
+ if (!c || !*c)
+ return str;
+
+ up_c = g_utf8_strup (c, -1);
+ str = g_string_append (str, up_c);
+ g_free (up_c);
+
+ return str;
+}
+
+static gboolean
+parse_address_template_section (const gchar *format,
+ const gchar *realname,
+ const gchar *org_name,
+ EContactAddress *address,
+ gchar **result)
+
+{
+ const gchar *pos, *old_pos;
+ gboolean ret = FALSE; /* Indicates, wheter at least something was replaced */
+
+ GString *res = g_string_new ("");
+
+ pos = format;
+ old_pos = pos;
+ while ((pos = strchr (pos, '%')) != NULL) {
+
+ if (old_pos != pos)
+ g_string_append_len (res, old_pos, pos - old_pos);
+
+ switch (pos[1]) {
+ case 'n':
+ if (realname && *realname) {
+ g_string_append (res, realname);
+ ret = TRUE;
+ }
+ pos += 2; /* Jump behind the modifier, see what's next */
+ break;
+ case 'N':
+ if (realname && *realname) {
+ string_append_upper (res, realname);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'm':
+ if (org_name && *org_name) {
+ g_string_append (res, org_name);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'M':
+ if (org_name && *org_name) {
+ string_append_upper (res, org_name);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'p':
+ if (address->po && *(address->po)) {
+ g_string_append (res, address->po);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 's':
+ if (address->street && *(address->street)) {
+ g_string_append (res, address->street);
+ if (address->ext && *(address->ext))
+ g_string_append_printf (
+ res, "\n%s",
+ address->ext);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'S':
+ if (address->street && *(address->street)) {
+ string_append_upper (res, address->street);
+ if (address->ext && *(address->ext)) {
+ g_string_append (res, "\n");
+ string_append_upper (res, address->ext);
+ }
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'z':
+ if (address->code && *(address->code)) {
+ g_string_append (res, address->code);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'l':
+ if (address->locality && *(address->locality)) {
+ g_string_append (res, address->locality);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'L':
+ if (address->locality && *(address->locality)) {
+ string_append_upper (res, address->locality);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'r':
+ if (address->region && *(address->region)) {
+ g_string_append (res, address->region);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case 'R':
+ if (address->region && *(address->region)) {
+ string_append_upper (res, address->region);
+ ret = TRUE;
+ }
+ pos += 2;
+ break;
+ case ',':
+ if (ret && (pos >= format + 2) && /* If there's something before %, */
+ (g_ascii_strcasecmp (pos - 2, "\n") != 0) && /* And if it is not a newline */
+ (g_ascii_strcasecmp (pos - 2, "%w") != 0)) /* Nor whitespace */
+ g_string_append (res, ", ");
+ pos += 2;
+ break;
+ case 'w':
+ if (ret && (pos >= format + 2) &&
+ (g_ascii_strcasecmp (pos - 2, "\n") != 0) &&
+ (g_ascii_strcasecmp (pos - 1, " ") != 0))
+ g_string_append (res, " ");
+ pos += 2;
+ break;
+ case '0': {
+ const gchar *bpos1, *bpos2;
+ gchar *inner;
+ gchar *ires;
+ gboolean replaced;
+
+ bpos1 = pos + 2;
+ bpos2 = find_balanced_bracket (bpos1);
+
+ inner = g_strndup (bpos1 + 1, bpos2 - bpos1 - 2); /* Get inner content of the %0 (...) */
+ replaced = parse_address_template_section (inner, realname, org_name, address, &ires);
+ if (replaced)
+ g_string_append (res, ires);
+
+ g_free (ires);
+ g_free (inner);
+
+ ret = replaced;
+ pos += (bpos2 - bpos1 + 2);
+ } break;
+ }
+
+ old_pos = pos;
+ }
+ g_string_append (res, old_pos);
+
+ *result = g_strdup (res->str);
+
+ g_string_free (res, TRUE);
+
+ return ret;
+}
+
+gchar *
+eab_format_address (EContact *contact,
+ EContactField address_type)
+{
+ gchar *result;
+ gchar *format = NULL;
+ gchar *country_position = NULL;
+ gchar *locale;
+ EContactAddress *addr = e_contact_get (contact, address_type);
+
+ if (!addr)
+ return NULL;
+
+ if (!addr->po && !addr->ext && !addr->street && !addr->locality && !addr->region &&
+ !addr->code && !addr->country) {
+ e_contact_address_free (addr);
+ return NULL;
+ }
+
+ if (addr->country) {
+ gchar *cntry = country_to_ISO (addr->country);
+ gchar **loc = get_locales ();
+ locale = g_strconcat (loc ? loc[LOCALES_LANGUAGE] : "C", "_", cntry, NULL);
+ g_strfreev (loc);
+ g_free (cntry);
+ } else
+ locale = get_locales_str ();
+
+ if (address_type == E_CONTACT_ADDRESS_HOME)
+ get_address_format (ADDRESS_FORMAT_HOME, locale, &format, &country_position);
+ else if (address_type == E_CONTACT_ADDRESS_WORK)
+ get_address_format (ADDRESS_FORMAT_BUSINESS, locale, &format, &country_position);
+ else {
+ e_contact_address_free (addr);
+ g_free (locale);
+ return NULL;
+ }
+
+ /* Expand all the variables in format.
+ * Don't display organization in home address;
+ * and skip full names, as it's part of the EContact itself,
+ * check this bug for reason: https://bugzilla.gnome.org/show_bug.cgi?id=667912
+ */
+ parse_address_template_section (
+ format,
+ NULL,
+ (address_type == E_CONTACT_ADDRESS_WORK) ?
+ e_contact_get_const (contact, E_CONTACT_ORG) : NULL,
+ addr,
+ &result);
+
+ /* Add the country line. In some countries, the address can be located above the
+ * rest of the address */
+ if (addr->country && country_position) {
+ gchar *country_upper = g_utf8_strup (addr->country, -1);
+ gchar *p = result;
+ if (g_strcmp0 (country_position, "BELOW") == 0) {
+ result = g_strconcat (p, "\n\n", country_upper, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "below") == 0) {
+ result = g_strconcat (p, "\n\n", addr->country, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "ABOVE") == 0) {
+ result = g_strconcat (country_upper, "\n\n", p, NULL);
+ g_free (p);
+ } else if (g_strcmp0 (country_position, "above") == 0) {
+ result = g_strconcat (addr->country, "\n\n", p, NULL);
+ g_free (p);
+ }
+ g_free (country_upper);
+ }
+
+ e_contact_address_free (addr);
+ g_free (locale);
+ g_free (format);
+ g_free (country_position);
+
+ return result;
+}
diff --git a/addressbook/gui/widgets/eab-gui-util.h b/addressbook/gui/widgets/eab-gui-util.h
new file mode 100644
index 0000000000..f169f8b8d3
--- /dev/null
+++ b/addressbook/gui/widgets/eab-gui-util.h
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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 __E_ADDRESSBOOK_UTIL_H__
+#define __E_ADDRESSBOOK_UTIL_H__
+
+#include <gtk/gtk.h>
+#include <libebook/libebook.h>
+
+#include <e-util/e-util.h>
+
+G_BEGIN_DECLS
+
+void eab_error_dialog (EAlertSink *alert_sink,
+ GtkWindow *parent,
+ const gchar *msg,
+ const GError *error);
+void eab_load_error_dialog (GtkWidget *parent,
+ EAlertSink *alert_sink,
+ ESource *source,
+ const GError *error);
+void eab_search_result_dialog (EAlertSink *alert_sink,
+ const GError *error);
+gint eab_prompt_save_dialog (GtkWindow *parent);
+void eab_transfer_contacts (ESourceRegistry *registry,
+ EBookClient *source_client,
+ GSList *contacts, /* adopted */
+ gboolean delete_from_source,
+ EAlertSink *alert_sink);
+gchar * eab_suggest_filename (const GSList *contact_list);
+ESource * eab_select_source (ESourceRegistry *registry,
+ ESource *except_source,
+ const gchar *title,
+ const gchar *message,
+ const gchar *select_uid,
+ GtkWindow *parent);
+
+gchar * eab_format_address (EContact *contact,
+ EContactField address_type);
+
+G_END_DECLS
+
+#endif /* __E_ADDRESSBOOK_UTIL_H__ */
diff --git a/addressbook/gui/widgets/gal-view-factory-minicard.c b/addressbook/gui/widgets/gal-view-factory-minicard.c
deleted file mode 100644
index 10e13d9bdf..0000000000
--- a/addressbook/gui/widgets/gal-view-factory-minicard.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * gal-view-factory-minicard.c: A View Factory
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * (C) 2000, 2001 Ximian, Inc.
- */
-#include <config.h>
-#include <glib.h>
-#include <libgnome/gnome-defs.h>
-#include <libgnome/gnome-i18n.h>
-#include "gal-view-factory-minicard.h"
-#include "gal-view-minicard.h"
-
-#define GVFE_CLASS(e) ((GalViewFactoryMinicardClass *)((GtkObject *)e)->klass)
-
-#define PARENT_TYPE gal_view_factory_get_type ()
-
-static GalViewFactoryClass *gal_view_factory_minicard_parent_class;
-
-static const char *
-gal_view_factory_minicard_get_title (GalViewFactory *factory)
-{
- return _("Card View");
-}
-
-static GalView *
-gal_view_factory_minicard_new_view (GalViewFactory *factory,
- const char *name)
-{
- return gal_view_minicard_new(name);
-}
-
-static const char *
-gal_view_factory_minicard_get_type_code (GalViewFactory *factory)
-{
- return "minicard";
-}
-
-static void
-gal_view_factory_minicard_destroy (GtkObject *object)
-{
-#if 0
- GalViewFactoryMinicard *factory = GAL_VIEW_FACTORY_MINICARD(object);
-#endif
-}
-
-static void
-gal_view_factory_minicard_class_init (GtkObjectClass *object_class)
-{
- GalViewFactoryClass *view_factory_class = GAL_VIEW_FACTORY_CLASS(object_class);
- gal_view_factory_minicard_parent_class = gtk_type_class (PARENT_TYPE);
-
- view_factory_class->get_title = gal_view_factory_minicard_get_title;
- view_factory_class->new_view = gal_view_factory_minicard_new_view;
- view_factory_class->get_type_code = gal_view_factory_minicard_get_type_code;
-
- object_class->destroy = gal_view_factory_minicard_destroy;
-}
-
-static void
-gal_view_factory_minicard_init (GalViewFactoryMinicard *factory)
-{
-}
-
-/**
- * gal_view_minicard_new
- *
- * A new GalViewFactory for creating Minicard views. Create one of
- * these and pass it to GalViewCollection for use.
- *
- * Returns: The new GalViewFactoryMinicard.
- */
-GalViewFactory *
-gal_view_factory_minicard_new (void)
-{
- return gal_view_factory_minicard_construct (gtk_type_new (gal_view_factory_minicard_get_type ()));
-}
-
-/**
- * gal_view_minicard_construct
- * @factory: The factory to construct
- *
- * constructs the GalViewFactoryMinicard. To be used by subclasses and
- * language bindings.
- *
- * Returns: The GalViewFactoryMinicard.
- */
-GalViewFactory *
-gal_view_factory_minicard_construct (GalViewFactoryMinicard *factory)
-{
- return GAL_VIEW_FACTORY(factory);
-}
-
-GtkType
-gal_view_factory_minicard_get_type (void)
-{
- static guint type = 0;
-
- if (!type)
- {
- GtkTypeInfo info =
- {
- "GalViewFactoryMinicard",
- sizeof (GalViewFactoryMinicard),
- sizeof (GalViewFactoryMinicardClass),
- (GtkClassInitFunc) gal_view_factory_minicard_class_init,
- (GtkObjectInitFunc) gal_view_factory_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
-
- return type;
-}
diff --git a/addressbook/gui/widgets/gal-view-factory-minicard.h b/addressbook/gui/widgets/gal-view-factory-minicard.h
deleted file mode 100644
index 3816fdba46..0000000000
--- a/addressbook/gui/widgets/gal-view-factory-minicard.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * gal-view-factory-minicard.c: A View Factory
- *
- * Authors:
- * Chris Lahey <clahey@ximian.com>
- *
- * (C) 2000, 2001 Ximian, Inc.
- */
-#ifndef _GAL_VIEW_FACTORY_MINICARD_H_
-#define _GAL_VIEW_FACTORY_MINICARD_H_
-
-#include <gtk/gtkobject.h>
-#include <gal/menus/gal-view-factory.h>
-
-#define GAL_VIEW_FACTORY_MINICARD_TYPE (gal_view_factory_minicard_get_type ())
-#define GAL_VIEW_FACTORY_MINICARD(o) (GTK_CHECK_CAST ((o), GAL_VIEW_FACTORY_MINICARD_TYPE, GalViewFactoryMinicard))
-#define GAL_VIEW_FACTORY_MINICARD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_FACTORY_MINICARD_TYPE, GalViewFactoryMinicardClass))
-#define GAL_IS_VIEW_FACTORY_MINICARD(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_FACTORY_MINICARD_TYPE))
-#define GAL_IS_VIEW_FACTORY_MINICARD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_FACTORY_MINICARD_TYPE))
-
-typedef struct {
- GalViewFactory base;
-} GalViewFactoryMinicard;
-
-typedef struct {
- GalViewFactoryClass parent_class;
-} GalViewFactoryMinicardClass;
-
-/* Standard functions */
-GtkType gal_view_factory_minicard_get_type (void);
-GalViewFactory *gal_view_factory_minicard_new (void);
-GalViewFactory *gal_view_factory_minicard_construct (GalViewFactoryMinicard *factory);
-
-#endif /* _GAL_VIEW_FACTORY_MINICARD_H_ */
diff --git a/addressbook/gui/widgets/gal-view-minicard.c b/addressbook/gui/widgets/gal-view-minicard.c
index b3162e51d1..99e8686675 100644
--- a/addressbook/gui/widgets/gal-view-minicard.c
+++ b/addressbook/gui/widgets/gal-view-minicard.c
@@ -1,120 +1,146 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
+ *
* gal-view-minicard.c: An Minicard View
*
+ * 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 Lahey <clahey@ximian.com>
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 2000, 2001 Ximian, Inc.
*/
+
+#ifdef HAVE_CONFIG_H
#include <config.h>
-#include "gal-view-minicard.h"
-#include <gnome-xml/parser.h>
-#include <gal/util/e-xml-utils.h>
+#endif
+
+#include <libxml/parser.h>
-#define PARENT_TYPE gal_view_get_type ()
-#define d(x) x
+#include "gal-view-minicard.h"
-static GalViewClass *gal_view_minicard_parent_class;
+G_DEFINE_TYPE (
+ GalViewMinicard,
+ gal_view_minicard,
+ GAL_TYPE_VIEW)
static void
-gal_view_minicard_edit (GalView *view)
+view_minicard_column_width_changed (EAddressbookView *address_view,
+ gdouble width)
{
- /* GalViewMinicard *minicard_view = GAL_VIEW_MINICARD(view); */
+ GalView *view;
+ GalViewInstance *view_instance;
+ GalViewMinicard *view_minicard;
+
+ view_instance = e_addressbook_view_get_view_instance (address_view);
+ view = gal_view_instance_get_current_view (view_instance);
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ if (view_minicard->column_width != width) {
+ view_minicard->column_width = width;
+ gal_view_changed (view);
+ }
}
-static void
-gal_view_minicard_load (GalView *view,
- const char *filename)
+static void
+view_minicard_finalize (GObject *object)
{
- xmlDoc *doc;
- doc = xmlParseFile (filename);
- if (doc) {
- xmlNode *root = xmlDocGetRootElement(doc);
- GAL_VIEW_MINICARD (view)->column_width = e_xml_get_double_prop_by_name_with_default (root, "column_width", 150);
- xmlFreeDoc(doc);
- }
+ GalViewMinicard *view = GAL_VIEW_MINICARD (object);
+
+ gal_view_minicard_detach (view);
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (gal_view_minicard_parent_class)->finalize (object);
}
static void
-gal_view_minicard_save (GalView *view,
- const char *filename)
+view_minicard_load (GalView *view,
+ const gchar *filename)
{
+ GalViewMinicard *view_minicard;
xmlDoc *doc;
xmlNode *root;
- doc = xmlNewDoc("1.0");
- root = xmlNewNode (NULL, "EMinicardViewState");
- e_xml_set_double_prop_by_name (root, "column_width", GAL_VIEW_MINICARD (view)->column_width);
- xmlDocSetRootElement(doc, root);
- xmlSaveFile(filename, doc);
- xmlFreeDoc(doc);
-}
+ view_minicard = GAL_VIEW_MINICARD (view);
-static const char *
-gal_view_minicard_get_title (GalView *view)
-{
- return GAL_VIEW_MINICARD(view)->title;
+ doc = e_xml_parse_file (filename);
+ g_return_if_fail (doc != NULL);
+
+ root = xmlDocGetRootElement (doc);
+ view_minicard->column_width =
+ e_xml_get_double_prop_by_name_with_default (
+ root, (guchar *) "column_width", 225);
+ xmlFreeDoc (doc);
}
static void
-gal_view_minicard_set_title (GalView *view,
- const char *title)
+view_minicard_save (GalView *view,
+ const gchar *filename)
{
- g_free(GAL_VIEW_MINICARD(view)->title);
- GAL_VIEW_MINICARD(view)->title = g_strdup(title);
-}
+ GalViewMinicard *view_minicard;
+ xmlDoc *doc;
+ xmlNode *root;
-static const char *
-gal_view_minicard_get_type_code (GalView *view)
-{
- return "minicard";
+ view_minicard = GAL_VIEW_MINICARD (view);
+
+ doc = xmlNewDoc ((guchar *) "1.0");
+ root = xmlNewNode (NULL, (guchar *) "EMinicardViewState");
+ e_xml_set_double_prop_by_name (
+ root, (guchar *) "column_width",
+ view_minicard->column_width);
+ xmlDocSetRootElement (doc, root);
+ e_xml_save_file (filename, doc);
+ xmlFreeDoc (doc);
}
static GalView *
-gal_view_minicard_clone (GalView *view)
+view_minicard_clone (GalView *view)
{
- GalViewMinicard *gvm, *new;
+ GalViewMinicard *view_minicard;
+ GalView *clone;
- gvm = GAL_VIEW_MINICARD(view);
+ /* Chain up to parent's clone() method. */
+ clone = GAL_VIEW_CLASS (gal_view_minicard_parent_class)->clone (view);
- new = gtk_type_new (gal_view_minicard_get_type ());
- new->title = g_strdup (gvm->title);
- new->column_width = gvm->column_width;
+ view_minicard = GAL_VIEW_MINICARD (view);
+ GAL_VIEW_MINICARD (clone)->column_width = view_minicard->column_width;
- return GAL_VIEW(new);
+ return clone;
}
static void
-gal_view_minicard_destroy (GtkObject *object)
+gal_view_minicard_class_init (GalViewMinicardClass *class)
{
- GalViewMinicard *view = GAL_VIEW_MINICARD(object);
- gal_view_minicard_detach (view);
- g_free(view->title);
-}
+ GObjectClass *object_class;
+ GalViewClass *gal_view_class;
+
+ object_class = G_OBJECT_CLASS (class);
+ object_class->finalize = view_minicard_finalize;
+
+ gal_view_class = GAL_VIEW_CLASS (class);
+ gal_view_class->type_code = "minicard";
+ gal_view_class->load = view_minicard_load;
+ gal_view_class->save = view_minicard_save;
+ gal_view_class->clone = view_minicard_clone;
-static void
-gal_view_minicard_class_init (GtkObjectClass *object_class)
-{
- GalViewClass *gal_view_class = GAL_VIEW_CLASS(object_class);
- gal_view_minicard_parent_class = gtk_type_class (PARENT_TYPE);
-
- gal_view_class->edit = gal_view_minicard_edit ;
- gal_view_class->load = gal_view_minicard_load ;
- gal_view_class->save = gal_view_minicard_save ;
- gal_view_class->get_title = gal_view_minicard_get_title ;
- gal_view_class->set_title = gal_view_minicard_set_title ;
- gal_view_class->get_type_code = gal_view_minicard_get_type_code;
- gal_view_class->clone = gal_view_minicard_clone ;
-
- object_class->destroy = gal_view_minicard_destroy ;
}
static void
-gal_view_minicard_init (GalViewMinicard *gvm)
+gal_view_minicard_init (GalViewMinicard *gvm)
{
- gvm->title = NULL;
- gvm->column_width = 150.0;
+ gvm->column_width = 225.0;
gvm->emvw = NULL;
gvm->emvw_column_width_changed_id = 0;
@@ -132,90 +158,47 @@ gal_view_minicard_init (GalViewMinicard *gvm)
GalView *
gal_view_minicard_new (const gchar *title)
{
- return gal_view_minicard_construct (gtk_type_new (gal_view_minicard_get_type ()), title);
-}
-
-/**
- * gal_view_minicard_construct
- * @view: The view to construct.
- * @title: The name of the new view.
- *
- * constructs the GalViewMinicard. To be used by subclasses and
- * language bindings.
- *
- * Returns: The GalViewMinicard.
- */
-GalView *
-gal_view_minicard_construct (GalViewMinicard *view,
- const gchar *title)
-{
- view->title = g_strdup(title);
- return GAL_VIEW(view);
+ return g_object_new (GAL_TYPE_VIEW_MINICARD, "title", title, NULL);
}
-GtkType
-gal_view_minicard_get_type (void)
+void
+gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view)
{
- static guint type = 0;
-
- if (!type)
- {
- GtkTypeInfo info =
- {
- "GalViewMinicard",
- sizeof (GalViewMinicard),
- sizeof (GalViewMinicardClass),
- (GtkClassInitFunc) gal_view_minicard_class_init,
- (GtkObjectInitFunc) gal_view_minicard_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
- };
-
- type = gtk_type_unique (PARENT_TYPE, &info);
- }
+ GObject *object;
- return type;
-}
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+ g_return_if_fail (E_IS_ADDRESSBOOK_VIEW (address_view));
-static void
-column_width_changed (ETable *table, double width, GalViewMinicard *view)
-{
- d(g_print("%s: Old width = %f, New width = %f\n", __FUNCTION__, view->column_width, width));
- if (view->column_width != width) {
- view->column_width = width;
- gal_view_changed(GAL_VIEW(view));
- }
-}
+ object = e_addressbook_view_get_view_object (address_view);
+ g_return_if_fail (E_IS_MINICARD_VIEW_WIDGET (object));
-void
-gal_view_minicard_attach (GalViewMinicard *view, EMinicardViewWidget *emvw)
-{
gal_view_minicard_detach (view);
+ view->emvw = g_object_ref (object);
- view->emvw = emvw;
-
- gtk_object_ref (GTK_OBJECT (view->emvw));
-
- gtk_object_set (GTK_OBJECT (view->emvw),
- "column_width", (int) view->column_width,
- NULL);
+ g_object_set (view->emvw, "column-width", view->column_width, NULL);
view->emvw_column_width_changed_id =
- gtk_signal_connect(GTK_OBJECT(view->emvw), "column_width_changed",
- GTK_SIGNAL_FUNC (column_width_changed), view);
+ g_signal_connect_swapped (
+ view->emvw, "column-width-changed",
+ G_CALLBACK (view_minicard_column_width_changed),
+ address_view);
}
void
gal_view_minicard_detach (GalViewMinicard *view)
{
+ g_return_if_fail (GAL_IS_VIEW_MINICARD (view));
+
if (view->emvw == NULL)
return;
- if (view->emvw_column_width_changed_id) {
- gtk_signal_disconnect (GTK_OBJECT (view->emvw),
- view->emvw_column_width_changed_id);
+
+ if (view->emvw_column_width_changed_id > 0) {
+ g_signal_handler_disconnect (
+ view->emvw, view->emvw_column_width_changed_id);
view->emvw_column_width_changed_id = 0;
}
- gtk_object_unref (GTK_OBJECT (view->emvw));
+
+ g_object_unref (view->emvw);
view->emvw = NULL;
}
diff --git a/addressbook/gui/widgets/gal-view-minicard.h b/addressbook/gui/widgets/gal-view-minicard.h
index 31a28c56d9..4cec9568ca 100644
--- a/addressbook/gui/widgets/gal-view-minicard.h
+++ b/addressbook/gui/widgets/gal-view-minicard.h
@@ -1,46 +1,77 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* gal-view-minicard.h: An Minicard View
*
+ * 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 Lahey <clahey@ximian.com>
+ * Chris Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
- * (C) 2000, 2001 Ximian, Inc.
*/
-#ifndef _GAL_VIEW_MINICARD_H_
-#define _GAL_VIEW_MINICARD_H_
-#include <gtk/gtkobject.h>
-#include <gal/menus/gal-view.h>
+#ifndef GAL_VIEW_MINICARD_H
+#define GAL_VIEW_MINICARD_H
+
+#include <e-util/e-util.h>
#include <e-minicard-view-widget.h>
+#include "e-addressbook-view.h"
-#define GAL_VIEW_MINICARD_TYPE (gal_view_minicard_get_type ())
-#define GAL_VIEW_MINICARD(o) (GTK_CHECK_CAST ((o), GAL_VIEW_MINICARD_TYPE, GalViewMinicard))
-#define GAL_VIEW_MINICARD_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GAL_VIEW_MINICARD_TYPE, GalViewMinicardClass))
-#define GAL_IS_VIEW_MINICARD(o) (GTK_CHECK_TYPE ((o), GAL_VIEW_MINICARD_TYPE))
-#define GAL_IS_VIEW_MINICARD_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GAL_VIEW_MINICARD_TYPE))
+/* Standard GObject macros */
+#define GAL_TYPE_VIEW_MINICARD \
+ (gal_view_minicard_get_type ())
+#define GAL_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicard))
+#define GAL_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_CAST \
+ ((cls), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
+#define GAL_IS_VIEW_MINICARD(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), GAL_TYPE_VIEW_MINICARD))
+#define GAL_IS_VIEW_MINICARD_CLASS(cls) \
+ (G_TYPE_CHECK_CLASS_TYPE \
+ ((cls), GAL_TYPE_VIEW_MINICARD))
+#define GAL_VIEW_MINICARD_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS \
+ ((obj), GAL_TYPE_VIEW_MINICARD, GalViewMinicardClass))
-typedef struct {
- GalView base;
+G_BEGIN_DECLS
- char *title;
- double column_width;
+typedef struct _GalViewMinicard GalViewMinicard;
+typedef struct _GalViewMinicardClass GalViewMinicardClass;
+
+struct _GalViewMinicard {
+ GalView parent;
+
+ gdouble column_width;
EMinicardViewWidget *emvw;
guint emvw_column_width_changed_id;
-} GalViewMinicard;
+};
-typedef struct {
+struct _GalViewMinicardClass {
GalViewClass parent_class;
-} GalViewMinicardClass;
-
-/* Standard functions */
-GtkType gal_view_minicard_get_type (void);
-GalView *gal_view_minicard_new (const gchar *title);
-GalView *gal_view_minicard_construct (GalViewMinicard *view,
- const gchar *title);
-void gal_view_minicard_attach (GalViewMinicard *view,
- EMinicardViewWidget *emvw);
-void gal_view_minicard_detach (GalViewMinicard *view);
-
-#endif /* _GAL_VIEW_MINICARD_H_ */
+};
+
+GType gal_view_minicard_get_type (void);
+GalView * gal_view_minicard_new (const gchar *title);
+void gal_view_minicard_attach (GalViewMinicard *view,
+ EAddressbookView *address_view);
+void gal_view_minicard_detach (GalViewMinicard *view);
+
+G_END_DECLS
+
+#endif /* GAL_VIEW_MINICARD_H */
diff --git a/addressbook/gui/widgets/test-minicard-label.c b/addressbook/gui/widgets/test-minicard-label.c
deleted file mode 100644
index 7b1919aef4..0000000000
--- a/addressbook/gui/widgets/test-minicard-label.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard-label.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@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.
- *
- * 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.
- */
-
-#include "config.h"
-
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <libgnomeui/gnome-init.h>
-#include <gal/widgets/e-canvas.h>
-#include "e-minicard-label.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *label;
-GnomeCanvasItem *rect;
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, allocation->width, allocation->height );
- gnome_canvas_item_set( label,
- "width", (double) allocation->width,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( rect,
- "x2", (double) allocation->width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-#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 ( _( "Minicard Label Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard label canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-static void button_press_callback( GtkWidget *widget, gpointer data )
-{
- gnome_canvas_item_grab_focus( label );
-}
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Label Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Label Test", NULL);
-
- canvas = e_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- label = e_minicard_label_new(gnome_canvas_root( GNOME_CANVAS( canvas ) ));
- gnome_canvas_item_set( label,
- "width", (double) 100,
- "height", (double) 100,
- "fieldname", "Full Name:",
- "field", "Christopher James Lahey",
- NULL );
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gnome_app_set_contents( GNOME_APP( app ), canvas );
-
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "button_press_event",
- GTK_SIGNAL_FUNC( button_press_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-minicard-view.c b/addressbook/gui/widgets/test-minicard-view.c
deleted file mode 100644
index caa9dac270..0000000000
--- a/addressbook/gui/widgets/test-minicard-view.c
+++ /dev/null
@@ -1,208 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-reflow.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@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.
- *
- * 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.
- */
-
-#include "config.h"
-
-#include <libgnorba/gnorba.h>
-#include <e-util/e-canvas.h>
-#include "e-minicard-view.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *reflow;
-GnomeCanvasItem *rect;
-GtkAllocation last_alloc;
-
-CORBA_Environment ev;
-CORBA_ORB orb;
-
-static void
-init_bonobo (int argc, char **argv)
-{
-
- gnome_CORBA_init_with_popt_table (
- "Reflow Test", VERSION,
- &argc, argv, NULL, 0, NULL, GNORBA_INIT_SERVER_FUNC, &ev);
-
- orb = gnome_CORBA_ORB ();
-
- if (bonobo_init (orb, NULL, NULL) == FALSE)
- g_error (_("Could not initialize Bonobo"));
-
-}
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- double width;
- last_alloc = *allocation;
- gnome_canvas_item_set( reflow,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( reflow,
- "minimum_width", (double) allocation->width,
- NULL );
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, width, allocation->height );
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-static void resize(GnomeCanvas *canvas, gpointer data)
-{
- double width;
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, last_alloc.width);
- gnome_canvas_set_scroll_region(canvas , 0, 0, width, last_alloc.height );
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) last_alloc.height,
- NULL );
-}
-
-#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 ( _( "Reflow Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the reflow canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-static void
-book_open_cb (EBook *book, EBookStatus status, gpointer closure)
-{
- if (status == E_BOOK_STATUS_SUCCESS)
- gnome_canvas_item_set(reflow,
- "book", book,
- NULL);
-}
-
-static guint
-ebook_create (void)
-{
- EBook *book;
-
- book = e_book_new ();
-
- if (!book) {
- printf ("%s: %s(): Couldn't create EBook, bailing.\n",
- __FILE__,
- __FUNCTION__);
- return FALSE;
- }
-
-
- if (! e_book_load_uri (book, "file:/tmp/test.db", book_open_cb, NULL)) {
- printf ("error calling load_uri!\n");
- }
-
-
- return FALSE;
-}
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- GtkWidget *vbox;
- GtkWidget *scrollbar;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- CORBA_exception_init (&ev);
- init_bonobo (argc, argv);
-
- app = gnome_app_new("Reflow Test", NULL);
-
- vbox = gtk_vbox_new(FALSE, 0);
-
- canvas = e_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- reflow = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- e_minicard_view_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
- NULL );
- gtk_signal_connect( GTK_OBJECT( canvas ), "reflow",
- GTK_SIGNAL_FUNC( resize ),
- ( gpointer ) app);
-
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gtk_box_pack_start(GTK_BOX(vbox), canvas, TRUE, TRUE, 0);
-
- scrollbar = gtk_hscrollbar_new(gtk_layout_get_hadjustment(GTK_LAYOUT(canvas)));
-
- gtk_box_pack_start(GTK_BOX(vbox), scrollbar, FALSE, FALSE, 0);
-
- gnome_app_set_contents( GNOME_APP( app ), vbox );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
- gdk_window_set_back_pixmap( GTK_LAYOUT(canvas)->bin_window, NULL, FALSE);
-
- gtk_idle_add ((GtkFunction) ebook_create, NULL);
-
- bonobo_main ();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-minicard.c b/addressbook/gui/widgets/test-minicard.c
deleted file mode 100644
index b84a591bbb..0000000000
--- a/addressbook/gui/widgets/test-minicard.c
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-minicard.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@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.
- *
- * 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.
- *
- */
-
-#include "config.h"
-
-#include <gtk/gtkmain.h>
-#include <libgnomeui/gnome-app.h>
-#include <libgnomeui/gnome-init.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-
-#include "e-minicard.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *card;
-GnomeCanvasItem *rect;
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, allocation->width, allocation->height );
- gnome_canvas_item_set( card,
- "width", (double) allocation->width,
- NULL );
- gnome_canvas_item_set( rect,
- "x2", (double) allocation->width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-#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 ( _( "Minicard Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the minicard canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- int i;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Minicard Test", VERSION, argc, argv);
- app = gnome_app_new("Minicard Test", NULL);
-
- canvas = gnome_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- for ( i = 0; i < 1; i++ )
- {
- card = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- e_minicard_get_type(),
- "width", (double) 100,
- NULL );
- }
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- gnome_app_set_contents( GNOME_APP( app ), canvas );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}
diff --git a/addressbook/gui/widgets/test-reflow.c b/addressbook/gui/widgets/test-reflow.c
deleted file mode 100644
index 14066c4cd0..0000000000
--- a/addressbook/gui/widgets/test-reflow.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/* test-reflow.c
- *
- * Copyright (C) 2000 Ximian, Inc.
- * Author: Chris Lahey <clahey@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.
- *
- * 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.
- */
-
-#define TEST_VCARD \
-"BEGIN:VCARD
-" \
-"FN:Nat
-" \
-"N:Friedman;Nat;D;Mr.
-" \
-"TITLE:Head Geek
-" \
-"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
-" \
-"
-"
-
-
-#include "config.h"
-
-#include <gtk/gtkmain.h>
-#include <gtk/gtkvbox.h>
-#include <libgnomeui/gnome-canvas-rect-ellipse.h>
-#include <libgnomeui/gnome-init.h>
-#include <gal/widgets/e-canvas.h>
-#include <gal/widgets/e-reflow.h>
-#include <gal/widgets/e-scroll-frame.h>
-
-#include "e-minicard.h"
-
-/* This is a horrible thing to do, but it is just a test. */
-GnomeCanvasItem *reflow;
-GnomeCanvasItem *rect;
-GtkAllocation last_alloc;
-
-static void destroy_callback(GtkWidget *app, gpointer data)
-{
- exit(0);
-}
-
-static void allocate_callback(GtkWidget *canvas, GtkAllocation *allocation, gpointer data)
-{
- double width;
- last_alloc = *allocation;
- gnome_canvas_item_set( reflow,
- "height", (double) allocation->height,
- NULL );
- gnome_canvas_item_set( reflow,
- "minimum_width", (double) allocation->width,
- NULL );
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, allocation->width);
- gnome_canvas_set_scroll_region(GNOME_CANVAS( canvas ), 0, 0, width - 1, allocation->height - 1);
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) allocation->height,
- NULL );
-}
-
-static void resize(GnomeCanvas *canvas, gpointer data)
-{
- double width;
- gtk_object_get(GTK_OBJECT(reflow),
- "width", &width,
- NULL);
- width = MAX(width, last_alloc.width);
- gnome_canvas_set_scroll_region(canvas , 0, 0, width - 1, last_alloc.height - 1);
- gnome_canvas_item_set( rect,
- "x2", (double) width,
- "y2", (double) last_alloc.height,
- NULL );
-}
-
-#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 ( _( "Reflow Test" ), VERSION,
- _( "Copyright (C) 2000, Ximian, Inc." ),
- authors,
- _( "This should test the reflow canvas item" ),
- NULL);
- gtk_widget_show (about);
-}
-#endif
-
-int main( int argc, char *argv[] )
-{
- GtkWidget *app;
- GtkWidget *canvas;
- GtkWidget *vbox;
- GtkWidget *scrollframe;
- int i;
-
- /* bindtextdomain (PACKAGE, GNOMELOCALEDIR);
- textdomain (PACKAGE);*/
-
- gnome_init( "Reflow Test", VERSION, argc, argv);
- app = gnome_app_new("Reflow Test", NULL);
-
- vbox = gtk_vbox_new(FALSE, 0);
-
- canvas = e_canvas_new();
- rect = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- gnome_canvas_rect_get_type(),
- "x1", (double) 0,
- "y1", (double) 0,
- "x2", (double) 100,
- "y2", (double) 100,
- "fill_color", "white",
- NULL );
- reflow = gnome_canvas_item_new( gnome_canvas_root( GNOME_CANVAS( canvas ) ),
- e_reflow_get_type(),
- "height", (double) 100,
- "minimum_width", (double) 100,
- NULL );
- gtk_signal_connect( GTK_OBJECT( canvas ), "reflow",
- GTK_SIGNAL_FUNC( resize ),
- ( gpointer ) app);
- for ( i = 0; i < 200; i++ )
- {
- GnomeCanvasItem *item;
- ECard *card = e_card_new (TEST_VCARD);
- item = gnome_canvas_item_new( GNOME_CANVAS_GROUP(reflow),
- e_minicard_get_type(),
- "card", card,
- NULL);
- e_reflow_add_item(E_REFLOW(reflow), item, NULL);
- }
- gnome_canvas_set_scroll_region ( GNOME_CANVAS( canvas ),
- 0, 0,
- 100, 100 );
-
- scrollframe = e_scroll_frame_new (gtk_layout_get_hadjustment(GTK_LAYOUT(canvas)),
- gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)));
- e_scroll_frame_set_policy (E_SCROLL_FRAME (scrollframe),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_NEVER);
-
- gtk_container_add (GTK_CONTAINER (scrollframe), canvas);
-
- gnome_app_set_contents( GNOME_APP( app ), scrollframe );
-
- /* Connect the signals */
- gtk_signal_connect( GTK_OBJECT( app ), "destroy",
- GTK_SIGNAL_FUNC( destroy_callback ),
- ( gpointer ) app );
-
- gtk_signal_connect( GTK_OBJECT( canvas ), "size_allocate",
- GTK_SIGNAL_FUNC( allocate_callback ),
- ( gpointer ) app );
-
- gtk_widget_show_all( app );
- gdk_window_set_back_pixmap( GTK_LAYOUT(canvas)->bin_window, NULL, FALSE);
-
- gtk_main();
-
- /* Not reached. */
- return 0;
-}