* Added hildon2 directory, with a copy of the contents of maemo
authorJose Dapena Paz <jdapena@igalia.com>
Tue, 30 Sep 2008 17:10:22 +0000 (17:10 +0000)
committerJose Dapena Paz <jdapena@igalia.com>
Tue, 30 Sep 2008 17:10:22 +0000 (17:10 +0000)
  directory.
* For hildon2, we removed the easysetup directory to have all the
  hildon2 ui in the same place.
* Modified libalarm, to use the new API in fremantle.

pmo-trunk-r5823

59 files changed:
configure.ac
libmodest-dbus-client/Makefile.am
src/Makefile.am
src/hildon2/Makefile.am [new file with mode: 0644]
src/hildon2/com.nokia.modest.service.in [new file with mode: 0644]
src/hildon2/maemo-provider-data.keyfile [new file with mode: 0644]
src/hildon2/mcc_mapping [new file with mode: 0644]
src/hildon2/mcc_mapping.en_GB [new file with mode: 0644]
src/hildon2/modest-account-view-window.c [new file with mode: 0644]
src/hildon2/modest-address-book.c [new file with mode: 0644]
src/hildon2/modest-connection-specific-smtp-edit-window.c [new file with mode: 0644]
src/hildon2/modest-connection-specific-smtp-edit-window.h [new file with mode: 0644]
src/hildon2/modest-connection-specific-smtp-window.c [new file with mode: 0644]
src/hildon2/modest-connection-specific-smtp-window.h [new file with mode: 0644]
src/hildon2/modest-default-account-settings-dialog.c [new file with mode: 0644]
src/hildon2/modest-easysetup-country-combo-box.c [new file with mode: 0644]
src/hildon2/modest-easysetup-country-combo-box.h [new file with mode: 0644]
src/hildon2/modest-easysetup-provider-combo-box.c [new file with mode: 0644]
src/hildon2/modest-easysetup-provider-combo-box.h [new file with mode: 0644]
src/hildon2/modest-easysetup-servertype-combo-box.c [new file with mode: 0644]
src/hildon2/modest-easysetup-servertype-combo-box.h [new file with mode: 0644]
src/hildon2/modest-easysetup-wizard-dialog.c [new file with mode: 0644]
src/hildon2/modest-easysetup-wizard-dialog.h [new file with mode: 0644]
src/hildon2/modest-hildon-includes.h [new file with mode: 0644]
src/hildon2/modest-hildon-sort-dialog.c [new file with mode: 0644]
src/hildon2/modest-hildon-sort-dialog.h [new file with mode: 0644]
src/hildon2/modest-icon-names.h [new file with mode: 0644]
src/hildon2/modest-maemo-global-settings-dialog.c [new file with mode: 0644]
src/hildon2/modest-maemo-global-settings-dialog.h [new file with mode: 0644]
src/hildon2/modest-maemo-security-options-view.c [new file with mode: 0644]
src/hildon2/modest-maemo-security-options-view.h [new file with mode: 0644]
src/hildon2/modest-maemo-utils.c [new file with mode: 0644]
src/hildon2/modest-maemo-utils.h [new file with mode: 0644]
src/hildon2/modest-main-window-ui-dimming.h [new file with mode: 0644]
src/hildon2/modest-main-window-ui.h [new file with mode: 0644]
src/hildon2/modest-main-window.c [new file with mode: 0644]
src/hildon2/modest-msg-edit-window-ui-dimming.h [new file with mode: 0644]
src/hildon2/modest-msg-edit-window.c [new file with mode: 0644]
src/hildon2/modest-msg-view-window-ui-dimming.h [new file with mode: 0644]
src/hildon2/modest-msg-view-window.c [new file with mode: 0644]
src/hildon2/modest-osso-autosave-callbacks.c [new file with mode: 0644]
src/hildon2/modest-osso-autosave-callbacks.h [new file with mode: 0644]
src/hildon2/modest-osso-state-saving.c [new file with mode: 0644]
src/hildon2/modest-osso-state-saving.h [new file with mode: 0644]
src/hildon2/modest-platform.c [new file with mode: 0644]
src/hildon2/modest-presets.c [new file with mode: 0644]
src/hildon2/modest-presets.h [new file with mode: 0644]
src/hildon2/modest-signature-editor-dialog.c [new file with mode: 0644]
src/hildon2/modest-signature-editor-dialog.h [new file with mode: 0644]
src/hildon2/modest.conf [new file with mode: 0644]
src/hildon2/modest.desktop.in [new file with mode: 0644]
src/hildon2/pixmaps/modest-icon.png [new file with mode: 0644]
src/hildon2/ui/modest-main-window-ui.xml [new file with mode: 0644]
src/hildon2/ui/modest-msg-edit-window-ui.xml [new file with mode: 0644]
src/hildon2/ui/modest-msg-view-window-ui.xml [new file with mode: 0644]
src/modest-ui-actions.c
src/widgets/Makefile.am
tests/Makefile.am
tests/dbus_api/Makefile.am

index cf443cd..8efe412 100644 (file)
@@ -247,7 +247,7 @@ else
    PKG_CHECK_MODULES(MODEST_TOOLKIT,$hildonpkgs)
    if test "$with_toolkit" = "hildon2"; then
       AC_DEFINE_UNQUOTED(MODEST_TOOLKIT_HILDON2, 1, ["Whether modest is being build for the hildon2 toolkit."])
-      MODEST_TOOLKIT_DIR=maemo
+      MODEST_TOOLKIT_DIR=hildon2
    else
       AC_DEFINE_UNQUOTED(MODEST_TOOLKIT_HILDON1, 1, ["Whether modest is being build for the hildon2 toolkit."])
       MODEST_TOOLKIT_DIR=maemo
@@ -296,15 +296,15 @@ fi
 # check libalarm
 #
 if test "x$with_platform" == "xmaemo"; then  
-PKG_CHECK_MODULES(MODEST_LIBALARM,libalarm,have_libalarm=true,have_libalarm=false)
-if test "x$have_libalarm" == "xtrue"; then
-   libalarm="libalarm" 
-   AC_DEFINE_UNQUOTED(MODEST_HAVE_LIBALARM, 1, ["Whether libalarm is used."])          
-   AC_SUBST(MODEST_LIBALARM_CFLAGS)
-   AC_SUBST(MODEST_LIBALARM_LIBS)
-else
-   libalarm=""
-fi
+   PKG_CHECK_MODULES(MODEST_LIBALARM,libalarm,have_libalarm=true,have_libalarm=false)
+   if test "x$have_libalarm" == "xfalse"; then
+      PKG_CHECK_MODULES(MODEST_LIBALARM, alarm, have_libalarm=true,have_libalarm=false)
+   fi
+   if test "x$have_libalarm" == "xtrue"; then
+      AC_DEFINE_UNQUOTED(MODEST_HAVE_LIBALARM, 1, ["Whether libalarm is used."])               
+      AC_SUBST(MODEST_LIBALARM_CFLAGS)
+      AC_SUBST(MODEST_LIBALARM_LIBS)
+   fi
 fi
 
 #
@@ -560,6 +560,7 @@ src/dbus_api/Makefile
 src/gnome/Makefile
 src/maemo/Makefile
 src/maemo/easysetup/Makefile
+src/hildon2/Makefile
 src/widgets/Makefile
 docs/Makefile
 docs/reference/Makefile
@@ -567,6 +568,8 @@ tests/Makefile
 tests/dbus_api/Makefile
 src/maemo/modest.desktop
 src/maemo/com.nokia.modest.service
+src/hildon2/modest.desktop
+src/hildon2/com.nokia.modest.service
 libmodest-dbus-client/Makefile
 libmodest-dbus-client/libmodest-dbus-client-1.0.pc
 ])
index 2fe3606..141bfc4 100644 (file)
@@ -31,7 +31,7 @@ INCLUDES=\
        $(MODEST_LIBTINYMAIL_GNOME_DESKTOP_CFLAGS) \
        $(MODEST_LIBTINYMAIL_MAEMO_CFLAGS) \
        $(MODEST_PLATFORM_CFLAGS) \
-       -I$(MODEST_PLATFORM) \
+       -I$(MODEST_TOOLKIT_DIR) \
        -I$(top_srcdir)/src \
        -DPREFIX=\"@prefix@\" \
        -DMODEST_LOCALEDIR=\"$(MODEST_LOCALEDIR)\" \
index 379915e..993d1ba 100644 (file)
@@ -3,7 +3,7 @@
 # Time-stamp: <2008-01-06 10:18:49 (djcb)>
 
 SUBDIRS= $(MODEST_TOOLKIT_DIR) widgets $(dbus_api)
-DIST_SUBDIRS = widgets gnome maemo dbus_api
+DIST_SUBDIRS = widgets gnome maemo hildon2 dbus_api
 
 INCLUDES=\
        $(MODEST_GSTUFF_CFLAGS)                                 \
@@ -15,11 +15,12 @@ INCLUDES=\
        $(MODEST_HILDON_NOTIFY_CFLAGS)                          \
        $(MODEST_MOZEMBED_CFLAGS)                               \
        -fPIC \
-       -I$(MODEST_PLATFORM)                                    \
+       -I$(MODEST_TOOLKIT_DIR)                                 \
        -DPREFIX=\"@prefix@\"                                   \
        -DMAEMO_CHANGES                                         \
        -DMODEST_LOCALEDIR=\"$(MODEST_LOCALEDIR)\"              \
        -DMODEST_PLATFORM=\"$(MODEST_PLATFORM)\"                \
+       -DMODEST_TOOLKIT=\"$(MODEST_TOOLKIT)\"          \
        -DPIXMAP_PREFIX=\"${datadir}/pixmaps/modest/\"          \
        -DMODEST_UIDIR=\"$(datadir)/modest/ui/\"                \
        -DMODEST_MAILPLUGINDIR=\"$(libdir)/modest/mail-plugins\"
@@ -169,7 +170,7 @@ libmodest_la_LIBADD =                                               \
        $(MODEST_OGS_LIBS)                              \
        ${easysetupmaybe} \
        widgets/libmodest-widgets.la                    \
-       $(MODEST_PLATFORM)/libmodest-ui.la              
+       $(MODEST_TOOLKIT_DIR)/libmodest-ui.la           
 libmodest_la_LDFLAGS = -rdynamic -export-dynamic -no-undefined -Wl,--version-script=export.map
 
 if MODEST_HAVE_DBUS_API
diff --git a/src/hildon2/Makefile.am b/src/hildon2/Makefile.am
new file mode 100644 (file)
index 0000000..d35d0c4
--- /dev/null
@@ -0,0 +1,142 @@
+# Copyright (c) 2006,2007 Nokia Corporation
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+# 
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# * Neither the name of the Nokia Corporation nor the names of its
+#   contributors may be used to endorse or promote products derived from
+#   this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+INCLUDES=\
+       $(MODEST_GSTUFF_CFLAGS)             \
+       $(MODEST_WPEDITOR_CFLAGS)           \
+       $(MODEST_PLATFORM_CFLAGS)           \
+       $(MODEST_TOOLKIT_CFLAGS)           \
+       $(MODEST_ABOOK_CFLAGS)              \
+       $(MODEST_HILDON_HELP_CFLAGS)        \
+       $(MODEST_LIBCONIC_CFLAGS)           \
+       $(MODEST_HILDON_MIME_CFLAGS)        \
+       $(MODEST_HILDON_NOTIFY_CFLAGS)      \
+       $(MODEST_LIBALARM_CFLAGS)           \
+       -I ${top_srcdir}/src/widgets        \
+       -I ${top_srcdir}/src                \
+       -DPREFIX=\"@prefix@\"               \
+       -DMAEMO_CHANGES                     \
+       -DPIXMAP_PREFIX=\"${datadir}/pixmaps/modest/\" \
+       -DMODEST_UIDIR=\""$(datadir)/modest/ui/"\" \
+       -Wall
+
+noinst_LTLIBRARIES=\
+       libmodest-ui.la
+
+libmodest_ui_la_SOURCES=              \
+       modest-account-view-window.c  \
+       modest-default-account-settings-dialog.c \
+       modest-easysetup-wizard-dialog.h modest-easysetup-wizard-dialog.c \
+       modest-easysetup-country-combo-box.h modest-easysetup-country-combo-box.c \
+       modest-easysetup-provider-combo-box.h modest-easysetup-provider-combo-box.c \
+       modest-easysetup-servertype-combo-box.h modest-easysetup-servertype-combo-box.c \
+       modest-icon-names.h           \
+       modest-maemo-global-settings-dialog.c \
+       modest-maemo-global-settings-dialog.h \
+       modest-maemo-security-options-view.c \
+       modest-main-window.c          \
+       modest-main-window-ui.h       \
+       modest-hildon-includes.h      \
+       modest-hildon-sort-dialog.c   \
+       modest-hildon-sort-dialog.h   \
+       modest-platform.c             \
+       modest-signature-editor-dialog.c         \
+       modest-signature-editor-dialog.h         \
+       modest-msg-view-window.c      \
+       modest-msg-edit-window.c      \
+       modest-maemo-utils.c          \
+       modest-connection-specific-smtp-window.h \
+       modest-connection-specific-smtp-window.c \
+       modest-connection-specific-smtp-edit-window.h \
+       modest-connection-specific-smtp-edit-window.c \
+       modest-osso-autosave-callbacks.c \
+       modest-osso-autosave-callbacks.h \
+       modest-osso-state-saving.c \
+       modest-osso-state-saving.h   \
+       modest-presets.h modest-presets.c
+
+if MODEST_USE_DUMMY_ADDRESS_BOOK
+#       nothing 
+else
+libmodest_ui_la_SOURCES += modest-address-book.c
+endif 
+
+
+libmodest_ui_la_LIBADD = \
+       $(MODEST_GSTUFF_LIBS) \
+       $(MODEST_ABOOK_LIBS) \
+       $(MODEST_PLATFORM_LIBS) \
+       $(MODEST_TOOLKIT_LIBS) \
+       $(MODEST_WPEDITOR_LIBS) \
+       $(MODEST_HILDON_MIME_LIBS) \
+       $(MODEST_LIBCONIC_LIBS) \
+       $(MODEST_HILDON_HELP_LIBS) \
+       $(MODEST_LIBALARM_LIBS)   \
+       $(MODEST_HILDON_NOTIFY_LIBS)
+
+PIXMAP_FILES=\
+       pixmaps/*.png 
+
+pixmapdir = $(datadir)/pixmaps/modest
+pixmap_DATA = $(PIXMAP_FILES)
+
+
+
+UI_FILES=\
+       ui/modest-main-window-ui.xml \
+       ui/modest-msg-edit-window-ui.xml \
+       ui/modest-msg-view-window-ui.xml
+
+uidir = $(datadir)/modest/ui
+ui_DATA = $(UI_FILES)
+
+serviceentry_DATA   = com.nokia.modest.service
+desktopentry_DATA   = modest.desktop
+backupsettings_DATA = modest.conf
+
+icon_26x26_DATA     = pixmaps/modest-icon.png
+
+# mcc_mapping may be provided by the operator-wizard-settings package:
+# the one here is a copy, as that package is not available in chinook
+MMC_MAPPING_FILE=mcc_mapping
+mmccmappingdir=$(datadir)/modest/provider-data
+mmccmapping_DATA = $(MMC_MAPPING_FILE)
+
+PROVIDER_DATA_FILE=maemo-provider-data.keyfile
+providerdatadir=$(datadir)/modest/provider-data
+providerdata_DATA = $(PROVIDER_DATA_FILE)
+
+EXTRA_DIST=\
+       $(UI_FILES) \
+       $(PIXMAP_FILES) \
+       $(serviceentry_DATA) \
+       $(desktopentry_DATA) \
+       $(backupsettings_DATA) \
+       $(icon_26x26_DATA)     \
+       $(MMC_MAPPING_FILE)    \
+       $(PROVIDER_DATA_FILE)
diff --git a/src/hildon2/com.nokia.modest.service.in b/src/hildon2/com.nokia.modest.service.in
new file mode 100644 (file)
index 0000000..7ab396c
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service]
+Name=com.nokia.modest
+Exec=@prefix@/bin/modest
diff --git a/src/hildon2/maemo-provider-data.keyfile b/src/hildon2/maemo-provider-data.keyfile
new file mode 100644 (file)
index 0000000..9152172
--- /dev/null
@@ -0,0 +1,90 @@
+# maemo-provider-data.keyfile -*-mode:sh-*-
+# Time-stamp: <2007-12-01 13:39:11 (djcb)>
+
+# Copyright (c) 2006, Nokia Corporation
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in the
+#   documentation and/or other materials provided with the distribution.
+# * Neither the name of the Nokia Corporation nor the names of its
+#   contributors may be used to endorse or promote products derived from
+#   this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+# OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+[aim.com]
+Name=AIM
+MCC=0
+Domain=aim.com
+OutgoingMailServer=smtp.aim.com
+IncomingMailServer=imap.aim.com
+IncomingSecurity=0
+MailboxType=imap
+[aol.com]
+Name=AOL
+MCC=0
+Domain=aol.com
+OutgoingMailServer=smtp.aol.com
+IncomingMailServer=imap.aol.com
+IncomingSecurity=0
+MailboxType=imap
+[imap.gmail.com]
+Name=Gmail/IMAP
+MCC=0
+Domain=gmail.com
+OutgoingMailServer=smtp.gmail.com
+SecureSmtp=true
+IncomingMailServer=imap.gmail.com
+IncomingSecurity=2
+MailboxType=imap
+[pop.gmail.com]
+Name=Gmail/POP3
+MCC=0
+Domain=gmail.com
+OutgoingMailServer=smtp.gmail.com
+SecureSmtp=true
+IncomingMailServer=pop.gmail.com
+IncomingSecurity=2
+MailboxType=pop
+[lycos.com]
+Name=Lycos Mail
+MCC=0
+Domain=lycos.com
+OutgoingMailServer=smtp.mail.lycos.com
+IncomingMailServer=pop.mail.lycos.com
+IncomingSecurity=0
+MailboxType=pop
+[yahoo.com]
+Name=Yahoo Mail Plus
+MCC=0
+Domain=yahoo.com
+OutgoingMailServer=smtp.mail.yahoo.com
+IncomingMailServer=pop.mail.yahoo.com
+IncomingSecurity=0
+MailboxType=pop
+[Tinymail]
+Name=Tinymail
+MCC=206
+Domain=tinymail.org
+IncomingMailServer=imap1.tinymail.org
+IncomingSecurity=0
+MailboxType=imap
+
diff --git a/src/hildon2/mcc_mapping b/src/hildon2/mcc_mapping
new file mode 100644 (file)
index 0000000..6b984d1
--- /dev/null
@@ -0,0 +1,230 @@
+412    osso_db_country_afghanistan\r
+276    osso_db_country_albania\r
+603    osso_db_country_algeria\r
+544    osso_db_country_american_samoa\r
+213    osso_db_country_andorra\r
+631    osso_db_country_angola\r
+365    osso_db_country_anguilla\r
+344    osso_db_country_antigua_and_barbuda\r
+722    osso_db_country_argentina\r
+283    osso_db_country_armenia\r
+363    osso_db_country_aruba\r
+505    osso_db_country_australia\r
+232    osso_db_country_austria\r
+400    osso_db_country_azerbaijani_republic\r
+364    osso_db_country_bahamas\r
+426    osso_db_country_bahrain\r
+470    osso_db_country_bangladesh\r
+342    osso_db_country_barbados\r
+257    osso_db_country_belarus\r
+206    osso_db_country_belgium\r
+702    osso_db_country_belize\r
+616    osso_db_country_benin\r
+350    osso_db_country_bermuda\r
+402    osso_db_country_bhutan\r
+736    osso_db_country_bolivia\r
+218    osso_db_country_bosnia_and_herzegovina\r
+652    osso_db_country_botswana\r
+724    osso_db_country_brazil\r
+348    osso_db_country_british_virgin_islands\r
+528    osso_db_country_brunei_darussalam\r
+284    osso_db_country_bulgaria\r
+613    osso_db_country_burkina_faso\r
+642    osso_db_country_burundi\r
+456    osso_db_country_cambodia\r
+624    osso_db_country_cameroon\r
+302    osso_db_country_canada\r
+625    osso_db_country_cape_verde\r
+346    osso_db_country_cayman_islands\r
+623    osso_db_country_central_african_republic\r
+622    osso_db_country_chad\r
+730    osso_db_country_chile\r
+461    osso_db_country_china\r
+460    osso_db_country_china\r
+732    osso_db_country_colombia\r
+654    osso_db_country_comoros\r
+629    osso_db_country_republic_of_the_congo\r
+548    osso_db_country_cook_islands\r
+712    osso_db_country_costa_rica\r
+612    osso_db_country_cote_dlvoire\r
+219    osso_db_country_croatia\r
+368    osso_db_country_cuba\r
+280    osso_db_country_cyprus\r
+230    osso_db_country_czech_republic\r
+630    osso_db_country_democratic_republic_of_the_congo\r
+238    osso_db_country_denmark\r
+638    osso_db_country_djibouti\r
+366    osso_db_country_dominica\r
+370    osso_db_country_dominican_republic\r
+514    osso_db_country_east_timor\r
+740    osso_db_country_ecuador\r
+602    osso_db_country_egypt\r
+706    osso_db_country_el_salvador\r
+627    osso_db_country_equatorial_guinea\r
+657    osso_db_country_eritrea\r
+248    osso_db_country_estonia\r
+636    osso_db_country_ethiopia\r
+288    osso_db_country_faroe_islands\r
+542    osso_db_country_fiji\r
+244    osso_db_country_finland\r
+208    osso_db_country_france\r
+742    osso_db_country_french_guiana\r
+547    osso_db_country_french_polynesia\r
+628    osso_db_country_gobonese_republic\r
+607    osso_db_country_gambia\r
+282    osso_db_country_georgia\r
+262    osso_db_country_germany\r
+620    osso_db_country_ghana\r
+266    osso_db_country_gibraltar\r
+202    osso_db_country_greece\r
+290    osso_db_country_greenland\r
+352    osso_db_country_grenada\r
+340    osso_db_country_guadeloupe\r
+535    osso_db_country_guam\r
+704    osso_db_country_guatemala\r
+611    osso_db_country_guinea\r
+632    osso_db_country_guinea_bissaus\r
+738    osso_db_country_guyana\r
+372    osso_db_country_haiti\r
+708    osso_db_country_honduras\r
+454    osso_db_country_hong_kong\r
+216    osso_db_country_hungary\r
+274    osso_db_country_iceland\r
+404    osso_db_country_india\r
+510    osso_db_country_indonesia\r
+432    osso_db_country_iran\r
+418    osso_db_country_iraq\r
+272    osso_db_country_republic_of_ireland\r
+425    osso_db_country_israel\r
+222    osso_db_country_italy\r
+338    osso_db_country_jamaica\r
+441    osso_db_country_japan\r
+440    osso_db_country_japan\r
+416    osso_db_country_jordan\r
+401    osso_db_country_kazakhstan\r
+639    osso_db_country_kenya\r
+545    osso_db_country_kiribati\r
+467    osso_db_country_korea_north\r
+450    osso_db_country_country_south_korea\r
+419    osso_db_country_kuwait\r
+437    osso_db_country_kyrgyz_republic\r
+457    osso_db_country_laos\r
+247    osso_db_country_latvia\r
+415    osso_db_country_lebanon\r
+651    osso_db_country_lesotho\r
+618    osso_db_country_liberia\r
+606    osso_db_country_libya\r
+295    osso_db_country_liechtenstein\r
+246    osso_db_country_lithuania\r
+270    osso_db_country_luxembourg\r
+455    osso_db_country_macao\r
+294    osso_db_country_the_former_yugoslav_republic_of_macedonia\r
+646    osso_db_country_madagascar\r
+650    osso_db_country_malawi\r
+502    osso_db_country_malaysia\r
+472    osso_db_country_maldives\r
+610    osso_db_country_mali\r
+278    osso_db_country_malta\r
+551    osso_db_country_marshall_islands\r
+340    osso_db_country_martinique\r
+609    osso_db_country_mauritania\r
+617    osso_db_country_mauritius\r
+334    osso_db_country_mexico\r
+550    osso_db_country_micronesia\r
+259    osso_db_country_republic_of_moldova\r
+212    osso_db_country_monaco\r
+428    osso_db_country_mongolia\r
+354    osso_db_country_montserrat\r
+604    osso_db_country_morocco\r
+643    osso_db_country_mozambique\r
+414    osso_db_country_myanmar\r
+649    osso_db_country_namibia\r
+536    osso_db_country_nauru\r
+429    osso_db_country_nepal\r
+204    osso_db_country_netherlands\r
+362    osso_db_country_netherlands_antilles\r
+546    osso_db_country_new_caledonia\r
+530    osso_db_country_new_zealand\r
+710    osso_db_country_nicaraqua\r
+614    osso_db_country_niger\r
+621    osso_db_country_nigeria\r
+534    osso_db_country_northern_mariana_islands\r
+242    osso_db_country_norway\r
+422    osso_db_country_oman\r
+410    osso_db_country_pakistan\r
+552    osso_db_country_palau\r
+714    osso_db_country_panama\r
+537    osso_db_country_papua_new_guinea\r
+744    osso_db_country_paraquay\r
+716    osso_db_country_peru\r
+515    osso_db_country_philippines\r
+260    osso_db_country_poland\r
+268    osso_db_country_portugal\r
+330    osso_db_country_puerto_rico\r
+427    osso_db_country_qatar\r
+647    osso_db_country_reunion\r
+226    osso_db_country_romania\r
+250    osso_db_country_russian_federation\r
+635    osso_db_country_rwandese_republic\r
+356    osso_db_country_saint_kitts_and_nevis\r
+358    osso_db_country_saint_lucia\r
+308    osso_db_country_saint_pierre_and_miquelon\r
+360    osso_db_country_saint_vincent_and_grenadines\r
+549    osso_db_country_samoa\r
+292    osso_db_country_san_marino\r
+626    osso_db_country_sao_tome_and_principe\r
+420    osso_db_country_saudi_arabia\r
+608    osso_db_country_senegal\r
+220    osso_db_country_serbia_and_montenegro\r
+633    osso_db_country_seychelles\r
+619    osso_db_country_sierra_leone\r
+525    osso_db_country_singapore\r
+231    osso_db_country_slovakia\r
+293    osso_db_country_slovenia\r
+540    osso_db_country_solomon_islands\r
+637    osso_db_country_somalia\r
+655    osso_db_country_south_africa\r
+214    osso_db_country_spain\r
+413    osso_db_country_sri_lanka\r
+634    osso_db_country_sudan\r
+746    osso_db_country_suriname\r
+653    osso_db_country_swaziland\r
+240    osso_db_country_sweden\r
+228    osso_db_country_switzerland\r
+417    osso_db_country_syrian_arab_republic\r
+466    osso_db_country_taiwan\r
+436    osso_db_country_tajikistan\r
+640    osso_db_country_united_republic_of_tanzania\r
+520    osso_db_country_thailand\r
+615    osso_db_country_togolese_republic\r
+539    osso_db_country_tonga\r
+374    osso_db_country_trinidad_and_tobago\r
+605    osso_db_country_tunisia\r
+286    osso_db_country_turkey\r
+438    osso_db_country_turkmenistan\r
+376    osso_db_country_turks_and_caicos_islands\r
+641    osso_db_country_uganda\r
+255    osso_db_country_ukraine\r
+424    osso_db_country_united_arab_emirates\r
+430    osso_db_country_united_arab_emirates_abu_dhabi\r
+431    osso_db_country_united_arab_emirates_dubai\r
+235    osso_db_country_united_kingdom_of_great_britain_and_northern_ireland\r
+234    osso_db_country_united_kingdom_of_great_britain_and_northern_ireland\r
+310    osso_db_country_united_states_of_america\r
+316    osso_db_country_united_states_of_america\r
+311    osso_db_country_united_states_of_america\r
+312    osso_db_country_united_states_of_america\r
+313    osso_db_country_united_states_of_america\r
+314    osso_db_country_united_states_of_america\r
+315    osso_db_country_united_states_of_america\r
+332    osso_db_country_unites_states_virgin_islands\r
+748    osso_db_country_uruguay\r
+434    osso_db_country_uzbekistan\r
+541    osso_db_country_vanuatu\r
+225    osso_db_country_the_vatican\r
+734    osso_db_country_venezuela\r
+452    osso_db_country_viet_nam\r
+543    osso_db_country_wallis_and_futuna\r
+421    osso_db_country_yemen\r
+645    osso_db_country_zambia\r
+648    osso_db_country_zimbabwe\r
diff --git a/src/hildon2/mcc_mapping.en_GB b/src/hildon2/mcc_mapping.en_GB
new file mode 100644 (file)
index 0000000..491e504
--- /dev/null
@@ -0,0 +1,107 @@
+276    Albania\r
+213    Andorra\r
+722    Argentina\r
+363    Aruba\r
+505    Australia\r
+232    Austria\r
+400    Azerbaijan\r
+426    Bahrain\r
+470    Bangladesh\r
+257    Belarus\r
+206    Belgium\r
+736    Bolivia\r
+218    Bosnia and Herzegovina\r
+652    Botswana\r
+724    Brazil\r
+528    Brunei Darussalam\r
+284    Bulgaria\r
+456    Cambodia\r
+302    Canada\r
+730    Chile\r
+460    China\r
+732    Colombia\r
+219    Croatia\r
+280    Cyprus\r
+230    Czech Republic\r
+238    Denmark\r
+370    Dominican Republic\r
+740    Ecuador\r
+602    Egypt\r
+706    El Salvador\r
+248    Estonia\r
+244    Finland\r
+208    France\r
+282    Georgia\r
+262    Germany\r
+620    Ghana\r
+266    Gibraltar\r
+202    Greece\r
+340    Guadeloupe\r
+704    Guatemala\r
+708    Honduras\r
+454    Hong Kong, China\r
+216    Hungary\r
+274    Iceland\r
+404    India\r
+510    Indonesia\r
+272    Ireland\r
+425    Israel\r
+222    Italy\r
+338    Jamaica\r
+440    Japan\r
+416    Jordan\r
+401    Kazakhstan\r
+639    Kenya\r
+419    Kuwait\r
+247    Latvia\r
+415    Lebanon\r
+295    Liechtenstein\r
+246    Lithuania\r
+270    Luxembourg\r
+455    Macao, China\r
+294    Macedonia\r
+502    Malaysia\r
+472    Maldives\r
+278    Malta\r
+340    Martinique\r
+334    Mexico\r
+259    Moldova\r
+212    Monaco\r
+428    Mongolia\r
+220    Montenegro\r
+604    Morocco\r
+204    Netherlands\r
+530    New Zealand\r
+621    Nigeria\r
+242    Norway\r
+422    Oman\r
+410    Pakistan\r
+714    Panama\r
+744    Paraguay\r
+716    Peru\r
+515    Philippines\r
+260    Poland\r
+268    Portugal\r
+427    Qatar\r
+226    Romania\r
+250    Russian Federation\r
+420    Saudi Arabia\r
+220    Serbia\r
+525    Singapore\r
+231    Slovakia\r
+293    Slovenia\r
+655    South Africa\r
+214    Spain\r
+413    Sri Lanka\r
+240    Sweden\r
+228    Switzerland\r
+417    Syria\r
+466    Taiwan\r
+520    Thailand\r
+374    Trinidad and Tobago\r
+286    Turkey\r
+255    Ukraine\r
+234    United Kingdom\r
+748    Uruguay\r
+310    USA\r
+734    Venezuela\r
diff --git a/src/hildon2/modest-account-view-window.c b/src/hildon2/modest-account-view-window.c
new file mode 100644 (file)
index 0000000..8c7e36c
--- /dev/null
@@ -0,0 +1,540 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <glib/gi18n.h>
+#include <gtk/gtk.h>
+
+#include <widgets/modest-account-view-window.h>
+#include <widgets/modest-account-view.h>
+
+#include <modest-runtime.h>
+#include "modest-platform.h"
+#include "modest-account-protocol.h"
+#include <modest-account-mgr-helpers.h>
+#include <string.h>
+#include "modest-tny-platform-factory.h"
+#include "modest-easysetup-wizard-dialog.h"
+#include "modest-account-settings-dialog.h"
+#include <modest-utils.h>
+#include "widgets/modest-ui-constants.h"
+
+/* 'private'/'protected' functions */
+static void                            modest_account_view_window_class_init   (ModestAccountViewWindowClass *klass);
+static void                            modest_account_view_window_init         (ModestAccountViewWindow *obj);
+static void                            modest_account_view_window_finalize     (GObject *obj);
+
+/* list my signals */
+enum {
+       /* MY_SIGNAL_1, */
+       /* MY_SIGNAL_2, */
+       LAST_SIGNAL
+};
+
+typedef struct _ModestAccountViewWindowPrivate ModestAccountViewWindowPrivate;
+struct _ModestAccountViewWindowPrivate {
+       GtkWidget           *new_button;
+       GtkWidget           *edit_button;
+       GtkWidget           *delete_button;
+       GtkWidget           *close_button;
+       ModestAccountView   *account_view;
+       guint acc_removed_handler;
+};
+#define MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(o)      (G_TYPE_INSTANCE_GET_PRIVATE((o), \
+                                                        MODEST_TYPE_ACCOUNT_VIEW_WINDOW, \
+                                                        ModestAccountViewWindowPrivate))
+/* globals */
+static GtkDialogClass *parent_class = NULL;
+
+/* uncomment the following if you have defined any signals */
+/* static guint signals[LAST_SIGNAL] = {0}; */
+
+GType
+modest_account_view_window_get_type (void)
+{
+       static GType my_type = 0;
+       if (!my_type) {
+               static const GTypeInfo my_info = {
+                       sizeof(ModestAccountViewWindowClass),
+                       NULL,           /* base init */
+                       NULL,           /* base finalize */
+                       (GClassInitFunc) modest_account_view_window_class_init,
+                       NULL,           /* class finalize */
+                       NULL,           /* class data */
+                       sizeof(ModestAccountViewWindow),
+                       1,              /* n_preallocs */
+                       (GInstanceInitFunc) modest_account_view_window_init,
+                       NULL
+               };
+               my_type = g_type_register_static (GTK_TYPE_DIALOG,
+                                                 "ModestAccountViewWindow",
+                                                 &my_info, 0);
+       }
+       return my_type;
+}
+
+static void
+modest_account_view_window_class_init (ModestAccountViewWindowClass *klass)
+{
+       GObjectClass *gobject_class;
+       gobject_class = (GObjectClass*) klass;
+
+       parent_class            = g_type_class_peek_parent (klass);
+       gobject_class->finalize = modest_account_view_window_finalize;
+
+       g_type_class_add_private (gobject_class, sizeof(ModestAccountViewWindowPrivate));
+}
+
+static void
+modest_account_view_window_finalize (GObject *self)
+{
+       ModestAccountViewWindowPrivate *priv;
+       ModestAccountMgr *mgr;
+       
+       priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (self);
+       mgr = modest_runtime_get_account_mgr ();
+
+       if (g_signal_handler_is_connected (mgr, priv->acc_removed_handler))
+               g_signal_handler_disconnect (mgr, priv->acc_removed_handler);
+       priv->acc_removed_handler = 0;
+
+       G_OBJECT_CLASS(parent_class)->finalize (self);
+}
+
+
+static void
+on_selection_changed (GtkTreeSelection *sel, ModestAccountViewWindow *self)
+{
+       ModestAccountViewWindowPrivate *priv;
+       GtkTreeModel                   *model;
+       GtkTreeIter                     iter;
+       gboolean                        has_selection;
+       
+       priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+
+       has_selection =
+               gtk_tree_selection_get_selected (sel, &model, &iter);
+
+       /* Set the status of the buttons */
+       gtk_widget_set_sensitive (priv->edit_button, has_selection);
+       gtk_widget_set_sensitive (priv->delete_button, has_selection);
+}
+
+/** Check whether any connections are active, and cancel them if 
+ * the user wishes.
+ * Returns TRUE is there was no problem, 
+ * or if an operation was cancelled so we can continue.
+ * Returns FALSE if the user chose to cancel his request instead.
+ */
+static gboolean
+check_for_active_account (ModestAccountViewWindow *self, const gchar* account_name)
+{
+       ModestTnySendQueue *send_queue;
+       ModestTnyAccountStore *acc_store;
+       ModestMailOperationQueue* queue;
+       TnyConnectionStatus store_conn_status;
+       TnyAccount *store_account = NULL, *transport_account = NULL;
+       gboolean retval = TRUE, sending = FALSE;
+
+       acc_store = modest_runtime_get_account_store ();
+       queue = modest_runtime_get_mail_operation_queue ();
+
+       store_account = 
+               modest_tny_account_store_get_server_account (acc_store,
+                                                            account_name,
+                                                            TNY_ACCOUNT_TYPE_STORE);
+
+       /* This could happen if the account was deleted before the
+          call to this function */
+       if (!store_account)
+               return FALSE;
+
+       transport_account = 
+               modest_tny_account_store_get_server_account (acc_store,
+                                                            account_name,
+                                                            TNY_ACCOUNT_TYPE_TRANSPORT);
+
+       /* This could happen if the account was deleted before the
+          call to this function */
+       if (!transport_account) {
+               g_object_unref (store_account);
+               return FALSE;
+       }
+
+       /* If the transport account was not used yet, then the send
+          queue could not exist (it's created on demand) */
+       send_queue = modest_runtime_get_send_queue (TNY_TRANSPORT_ACCOUNT (transport_account), FALSE);
+       if (TNY_IS_SEND_QUEUE (send_queue))
+               sending = modest_tny_send_queue_sending_in_progress (send_queue);
+
+       store_conn_status = tny_account_get_connection_status (store_account);
+       if (store_conn_status == TNY_CONNECTION_STATUS_CONNECTED || sending) {
+               gint response;
+
+               response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self), 
+                                                               _("emev_nc_disconnect_account"));
+               if (response == GTK_RESPONSE_OK) {
+                       retval = TRUE;
+               } else {
+                       retval = FALSE;
+               }
+       }
+
+       if (retval) {
+
+               /* FIXME: We should only cancel those of this account */
+               modest_mail_operation_queue_cancel_all (queue);
+
+               /* Also disconnect the account */
+               if ((tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED) &&
+                   (tny_account_get_connection_status (store_account) != TNY_CONNECTION_STATUS_DISCONNECTED_BROKEN)) {
+                       tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
+                                                     FALSE, NULL, NULL);
+               }
+               if (sending) {
+                       tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (transport_account),
+                                                     FALSE, NULL, NULL);
+               }
+       }
+               
+       /* Frees */
+       g_object_unref (store_account);
+       g_object_unref (transport_account);
+       
+       return retval;
+}
+
+static void
+on_delete_button_clicked (GtkWidget *button, ModestAccountViewWindow *self)
+{
+       ModestAccountViewWindowPrivate *priv;
+       ModestAccountMgr *account_mgr;
+       gchar *account_title = NULL, *account_name = NULL;
+       
+       priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+
+       account_mgr = modest_runtime_get_account_mgr(); 
+       account_name = modest_account_view_get_selected_account (priv->account_view);
+       if(!account_name)
+               return;
+
+       account_title = modest_account_mgr_get_display_name(account_mgr, account_name);
+       /* This could happen if the account is being deleted */
+       if (!account_title)
+               return;
+       
+       if (check_for_active_account (self, account_name)) {
+               /* The warning text depends on the account type: */
+               gchar *txt = NULL;      
+               gint response;
+               ModestProtocol *protocol;
+
+               protocol = modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (),
+                                                                         modest_account_mgr_get_store_protocol (account_mgr, account_name));
+               txt = modest_protocol_get_translation (protocol, MODEST_PROTOCOL_TRANSLATION_DELETE_MAILBOX, account_title);
+               if (txt == NULL) {
+                       txt = g_strdup_printf (_("emev_nc_delete_mailbox"), 
+                                              account_title);
+               }
+               
+               response = modest_platform_run_confirmation_dialog (GTK_WINDOW (self), txt);
+               g_free (txt);
+               txt = NULL;
+               
+               if (response == GTK_RESPONSE_OK) {
+                       /* Remove account. If it succeeds then it also removes
+                          the account from the ModestAccountView: */                             
+                       gboolean is_default = FALSE;
+                       gchar *default_account_name = modest_account_mgr_get_default_account (account_mgr);
+                       if (default_account_name && (strcmp (default_account_name, account_name) == 0))
+                               is_default = TRUE;
+                       g_free (default_account_name);
+                       
+                               gboolean removed = modest_account_mgr_remove_account (account_mgr, account_name);
+                               if (!removed) {
+                                       g_warning ("%s: modest_account_mgr_remove_account() failed.\n", __FUNCTION__);
+                               }
+
+               }
+               g_free (account_title);
+       }               
+       g_free (account_name);
+}
+
+static void
+on_account_settings_dialog_response (GtkDialog *dialog,
+                                    gint response,
+                                    gpointer user_data)
+{
+       TnyAccount *store_account = NULL;
+       gchar* account_name = NULL;
+       ModestAccountViewWindowPrivate *priv = NULL;
+
+       priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (user_data);
+       account_name = modest_account_view_get_selected_account (priv->account_view);
+       store_account = modest_tny_account_store_get_server_account (modest_runtime_get_account_store (),
+                                                                    account_name,
+                                                                    TNY_ACCOUNT_TYPE_STORE);
+       
+       /* Reconnect the store account, no need to reconnect the
+          transport account because it will connect when needed */
+       if (tny_account_get_connection_status (store_account) == 
+           TNY_CONNECTION_STATUS_DISCONNECTED)
+               tny_camel_account_set_online (TNY_CAMEL_ACCOUNT (store_account),
+                                             TRUE, NULL, NULL);
+
+       /* Disconnect this handler */
+       g_signal_handlers_disconnect_by_func (dialog, on_account_settings_dialog_response, user_data);
+
+       /* Free */
+       g_free (account_name);
+       g_object_unref (store_account);
+}
+
+static void
+on_edit_button_clicked (GtkWidget *button, ModestAccountViewWindow *self)
+{
+       ModestAccountViewWindowPrivate *priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (self);
+       
+       gchar* account_name = modest_account_view_get_selected_account (priv->account_view);
+       if (!account_name)
+               return;
+               
+       /* Check whether any connections are active, and cancel them if 
+        * the user wishes.
+        */
+       if (check_for_active_account (self, account_name)) {
+               ModestAccountProtocol *proto;
+               ModestProtocolType proto_type;
+
+               /* Get proto */
+               proto_type = modest_account_mgr_get_store_protocol (modest_runtime_get_account_mgr (), 
+                                                                   account_name);
+               proto = (ModestAccountProtocol *)
+                       modest_protocol_registry_get_protocol_by_type (modest_runtime_get_protocol_registry (), 
+                                                                      proto_type);
+
+               /* Create and show the dialog */
+               if (proto && MODEST_IS_ACCOUNT_PROTOCOL (proto)) {
+                       ModestAccountSettingsDialog *dialog =
+                               modest_account_protocol_get_account_settings_dialog (proto, account_name);
+                       gtk_widget_show (GTK_WIDGET (dialog));
+               }
+       }
+       g_free (account_name);
+}
+
+static void
+on_wizard_response (GtkDialog *dialog, 
+                   gint response, 
+                   gpointer user_data)
+{      
+       /* The response has already been handled by the wizard dialog itself,
+        * creating the new account.
+        */      
+       if (dialog)
+               gtk_widget_destroy (GTK_WIDGET (dialog));
+
+       /* Re-focus the account list view widget */
+       if (MODEST_IS_ACCOUNT_VIEW_WINDOW (user_data)) {
+               ModestAccountViewWindowPrivate *priv;
+               priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (user_data);
+               gtk_widget_grab_focus (GTK_WIDGET (priv->account_view));
+       }
+}
+
+static void
+on_new_button_clicked (GtkWidget *button, ModestAccountViewWindow *self)
+{
+       GtkDialog *wizard;
+       GtkWindow *dialog;
+
+       /* Show the easy-setup wizard: */       
+       dialog = modest_window_mgr_get_modal (modest_runtime_get_window_mgr());
+       if (dialog && MODEST_IS_EASYSETUP_WIZARD_DIALOG(dialog)) {
+               /* old wizard is active already; 
+                */
+               gtk_window_present (dialog);
+               return;
+       }
+       
+       /* there is no such wizard yet */
+       wizard = GTK_DIALOG (modest_easysetup_wizard_dialog_new ());
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr(), 
+                                    GTK_WINDOW (wizard));
+
+       /* if there is already another modal dialog, make it non-modal */
+       if (dialog)
+               gtk_window_set_modal (GTK_WINDOW(dialog), FALSE);
+       
+       gtk_window_set_modal (GTK_WINDOW (wizard), TRUE);
+       gtk_window_set_transient_for (GTK_WINDOW (wizard), GTK_WINDOW (self));
+       /* Destroy the dialog when it is closed: */
+       g_signal_connect (G_OBJECT (wizard), "response", G_CALLBACK
+                         (on_wizard_response), self);
+       gtk_widget_show (GTK_WIDGET (wizard));
+}
+
+static void
+on_close_button_clicked (GtkWidget *button, gpointer user_data)
+{              
+       ModestAccountViewWindow *self = MODEST_ACCOUNT_VIEW_WINDOW (user_data);
+
+       gtk_dialog_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
+}
+
+static void
+setup_button_box (ModestAccountViewWindow *self, GtkButtonBox *box)
+{
+       ModestAccountViewWindowPrivate *priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+       
+       gtk_button_box_set_spacing (GTK_BUTTON_BOX (box), 6);
+       gtk_button_box_set_layout (GTK_BUTTON_BOX (box), 
+                                  GTK_BUTTONBOX_START);
+       
+       priv->new_button     = gtk_button_new_from_stock(_("mcen_bd_new"));
+       priv->edit_button = gtk_button_new_with_label(_("mcen_bd_edit"));
+       priv->delete_button  = gtk_button_new_from_stock(_("mcen_bd_delete"));
+       priv->close_button    = gtk_button_new_from_stock(_("mcen_bd_close"));
+       
+       g_signal_connect (G_OBJECT(priv->new_button), "clicked",
+                         G_CALLBACK(on_new_button_clicked),
+                         self);
+       g_signal_connect (G_OBJECT(priv->delete_button), "clicked",
+                         G_CALLBACK(on_delete_button_clicked),
+                         self);
+       g_signal_connect (G_OBJECT(priv->edit_button), "clicked",
+                         G_CALLBACK(on_edit_button_clicked),
+                         self);
+       g_signal_connect (G_OBJECT(priv->close_button), "clicked",
+                         G_CALLBACK(on_close_button_clicked),
+                         self);
+
+       gtk_box_pack_start (GTK_BOX(box), priv->new_button, FALSE, FALSE,2);
+       gtk_box_pack_start (GTK_BOX(box), priv->edit_button, FALSE, FALSE,2);
+       gtk_box_pack_start (GTK_BOX(box), priv->delete_button, FALSE, FALSE,2);
+       gtk_box_pack_start (GTK_BOX(box), priv->close_button, FALSE, FALSE,2);
+
+       /* Should has been created by window_vbox_new */
+       if (priv->account_view) {
+               GtkTreeSelection *sel;
+               sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->account_view));
+               if (gtk_tree_selection_count_selected_rows (sel) == 0) {
+                       gtk_widget_set_sensitive (priv->edit_button, FALSE);
+                       gtk_widget_set_sensitive (priv->delete_button, FALSE);  
+               }
+       }
+
+       gtk_widget_show_all (GTK_WIDGET (box));
+}
+
+static GtkWidget*
+window_vbox_new (ModestAccountViewWindow *self)
+{
+       ModestAccountViewWindowPrivate *priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+
+       GtkWidget *main_vbox     = gtk_vbox_new (FALSE, 6);
+       GtkWidget *main_hbox     = gtk_hbox_new (FALSE, 6);
+       
+       priv->account_view = modest_account_view_new (modest_runtime_get_account_mgr());
+
+       /* Only force the height, the width of the widget will depend
+          on the size of the column titles */
+       gtk_widget_set_size_request (GTK_WIDGET(priv->account_view), -1, 400);
+       gtk_widget_show (GTK_WIDGET (priv->account_view));
+
+       GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW(priv->account_view));
+       g_signal_connect (G_OBJECT(sel), "changed",  G_CALLBACK(on_selection_changed),
+                         self);
+                         
+       GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), MODEST_MARGIN_DEFAULT);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, 
+               GTK_POLICY_AUTOMATIC);
+       gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (priv->account_view));
+       gtk_widget_show (GTK_WIDGET (scrolled_window));
+       
+       gtk_box_pack_start (GTK_BOX(main_hbox), GTK_WIDGET(scrolled_window), TRUE, TRUE, 2);
+       
+       gtk_box_pack_start (GTK_BOX(main_vbox), main_hbox, TRUE, TRUE, 2);
+       gtk_widget_show (GTK_WIDGET (main_hbox));
+       gtk_widget_show (GTK_WIDGET (main_vbox));
+
+       return main_vbox;
+}
+
+
+static void
+modest_account_view_window_init (ModestAccountViewWindow *self)
+{
+       ModestAccountViewWindowPrivate *priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+
+       priv->acc_removed_handler = 0;
+}
+
+static void
+on_account_removed (ModestAccountMgr *acc_mgr, 
+                   const gchar *account,
+                   gpointer user_data)
+{
+       ModestAccountViewWindowPrivate *priv;
+
+       /* If there is no account left then close the window */
+       if (!modest_account_mgr_has_accounts (acc_mgr, TRUE)) {
+               gboolean ret_value;
+               g_signal_emit_by_name (G_OBJECT (user_data), "delete-event", NULL, &ret_value);
+       } else {                
+               /* Re-focus the account list view widget */
+               priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE (user_data);
+               gtk_widget_grab_focus (GTK_WIDGET (priv->account_view));
+       }
+}
+
+GtkWidget*
+modest_account_view_window_new (void)
+{
+       GObject *self = g_object_new(MODEST_TYPE_ACCOUNT_VIEW_WINDOW, NULL);
+       ModestAccountViewWindowPrivate *priv;
+       ModestAccountMgr *account_mgr = modest_runtime_get_account_mgr ();
+
+       /* Add widgets */
+       gtk_box_pack_start (GTK_BOX((GTK_DIALOG (self)->vbox)), 
+                           window_vbox_new (MODEST_ACCOUNT_VIEW_WINDOW (self)), 
+                           TRUE, TRUE, 2);
+       
+       setup_button_box (MODEST_ACCOUNT_VIEW_WINDOW (self), GTK_BUTTON_BOX (GTK_DIALOG (self)->action_area));
+
+       gtk_window_set_title (GTK_WINDOW (self), _("mcen_ti_emailsetup_accounts"));
+
+       /* Connect signals */
+       priv = MODEST_ACCOUNT_VIEW_WINDOW_GET_PRIVATE(self);
+       priv->acc_removed_handler = g_signal_connect (G_OBJECT(account_mgr), "account_removed",
+                                                     G_CALLBACK (on_account_removed), self);
+       
+       return GTK_WIDGET (self);
+}
diff --git a/src/hildon2/modest-address-book.c b/src/hildon2/modest-address-book.c
new file mode 100644 (file)
index 0000000..b636c6e
--- /dev/null
@@ -0,0 +1,996 @@
+/* Copyright (c) 2007, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* modest-address-book.c */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <modest-address-book.h>
+#include <modest-text-utils.h>
+#include <libebook/e-book.h>
+#include <libebook/e-book-view.h>
+#include <libosso-abook/osso-abook.h>
+#include "modest-hildon-includes.h"
+#include "modest-platform.h"
+#include "modest-runtime.h"
+#include "widgets/modest-window-mgr.h"
+#include <string.h>
+#include <gtk/gtksizegroup.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtktreeselection.h>
+#include <gtk/gtkentry.h>
+
+static OssoABookContactModel *contact_model =  NULL;
+static EBook *book = NULL;
+static EBookView * book_view = NULL;
+
+static GSList *get_recipients_for_given_contact(EContact * contact);
+static void commit_contact(EContact * contact, gboolean is_new);
+static gchar *get_email_addr_from_user(const gchar * given_name);
+static gchar *ui_get_formatted_email_id(gchar * current_given_name,
+                                       gchar * current_sur_name, gchar * current_email_id);
+static gchar *run_add_email_addr_to_contact_dlg(const gchar * contact_name);
+static GSList *select_email_addrs_for_contact(GList * email_addr_list);
+static gboolean resolve_address (const gchar *address, GSList **resolved_addresses, gchar **contact_id);
+static gchar *unquote_string (const gchar *str);
+
+
+static void
+unref_gobject (GObject *obj)
+{
+       if (obj)
+               g_object_unref (obj);
+}
+       
+
+static void
+get_book_view_cb (EBook *book, EBookStatus status, EBookView *bookview, gpointer data)
+{
+       if (status != E_BOOK_ERROR_OK) {
+               g_object_unref (book);
+               book = NULL;
+               return;
+       }
+       book_view = bookview;
+
+       if (contact_model)
+#if MODEST_ABOOK_API < 4
+               osso_abook_tree_model_set_book_view (OSSO_ABOOK_TREE_MODEL (contact_model),
+                                                    book_view);
+#else /* MODEST_ABOOK_API < 4 */
+               osso_abook_list_store_set_book_view (OSSO_ABOOK_LIST_STORE (contact_model),
+                                                    book_view);
+#endif /* MODEST_ABOOK_API < 4 */
+
+       e_book_view_start (book_view);
+}
+
+static void
+book_open_cb (EBook *view, EBookStatus status, gpointer data)
+{
+       EBookQuery *query = NULL;
+
+       if (status != E_BOOK_ERROR_OK) {
+               g_object_unref (book);
+               book = NULL;
+               return;
+       }
+       query = e_book_query_any_field_contains ("");
+       e_book_async_get_book_view (book, query, NULL, -1, get_book_view_cb, NULL);
+       e_book_query_unref (query);
+}
+
+static gboolean 
+open_addressbook ()
+{
+       book = e_book_new_system_addressbook (NULL);
+       if (!book)
+               return FALSE;
+
+       e_book_async_open (book, FALSE, book_open_cb, NULL);
+
+       return TRUE; /* FIXME */        
+}
+
+static gboolean
+open_addressbook_sync ()
+{
+       book = e_book_new_system_addressbook (NULL);
+       if (!book)
+               return FALSE;
+
+       e_book_open (book, FALSE, NULL);
+
+       return TRUE;
+}
+
+void
+modest_address_book_add_address (const gchar *address)
+{
+       OssoABookAccount *account = NULL;
+       GtkWidget *dialog = NULL;
+       gchar *email_address = NULL;
+
+       contact_model = osso_abook_contact_model_new ();
+       if (!open_addressbook ()) {
+               if (contact_model) {
+                       g_object_unref (contact_model);
+                       contact_model = NULL;
+               }
+               return;
+       }
+
+       email_address = modest_text_utils_get_email_address (address);
+       
+       account = osso_abook_account_get (EVC_EMAIL, NULL, email_address);
+       g_free (email_address);
+       if (account)
+       {
+               dialog = osso_abook_add_to_contacts_dialog_new (contact_model, account);
+               g_object_unref (account);
+               gtk_dialog_run (GTK_DIALOG (dialog));
+
+               if (contact_model) {
+                       g_object_unref (contact_model);
+                       contact_model = NULL;
+               }
+
+               gtk_widget_destroy (dialog);
+       }
+
+}
+
+void
+modest_address_book_select_addresses (ModestRecptEditor *recpt_editor)
+{
+#if MODEST_ABOOK_API < 4
+       GtkWidget *contact_view = NULL;
+       GtkWidget *contact_dialog;
+#else /* MODEST_ABOOK_API < 4 */
+       OssoABookContactChooser *contact_chooser = NULL;
+#endif /* MODEST_ABOOK_API < 4 */
+
+       GList *contacts_list = NULL;
+       GSList *email_addrs_per_contact = NULL;
+       gchar *econtact_id;
+       gboolean focus_recpt_editor = FALSE;
+
+       g_return_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor));
+
+#if MODEST_ABOOK_API < 4
+       if (!open_addressbook ()) {
+               if (contact_model) {
+                       g_object_unref (contact_model);
+                       contact_model = NULL;
+               }
+               return;
+       }
+       contact_model = osso_abook_contact_model_new ();
+
+       contact_view = osso_abook_contact_selector_new_basic (contact_model);
+       osso_abook_contact_selector_set_minimum_selection (OSSO_ABOOK_CONTACT_SELECTOR (contact_view), 1);
+
+       contact_dialog = osso_abook_select_dialog_new (OSSO_ABOOK_TREE_VIEW (contact_view));
+       gtk_window_set_title (GTK_WINDOW (contact_dialog), _("mcen_ti_select_recipients"));
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (contact_dialog));
+
+       gtk_widget_show (contact_dialog);
+
+       if (gtk_dialog_run (GTK_DIALOG (contact_dialog)) == GTK_RESPONSE_OK) {
+               contacts_list = 
+                       osso_abook_contact_selector_get_extended_selection (OSSO_ABOOK_CONTACT_SELECTOR
+                                                                            (contact_view));
+       }
+#else /* MODEST_ABOOK_API < 4 */
+       /* TODO: figure out how to make the contact chooser modal */
+       contact_chooser = osso_abook_contact_chooser_new
+               ("title", _("mcen_ti_select_recipients"),
+                "help-topic", "",
+                "minimum-selection", 1, NULL);
+
+       if (osso_abook_contact_chooser_run (contact_chooser) == GTK_RESPONSE_OK)
+               contacts_list = osso_abook_contact_chooser_get_selection (contact_chooser);
+
+       g_object_unref (contact_chooser);
+#endif
+       
+       if (contacts_list) {
+               GList *node;
+
+               for (node = contacts_list; node != NULL; node = g_list_next (node)) {
+                       EContact *contact = (EContact *) node->data;
+
+                       email_addrs_per_contact = get_recipients_for_given_contact (contact);
+                       if (email_addrs_per_contact) {
+                               econtact_id = (gchar *) e_contact_get_const (contact, E_CONTACT_UID);
+                               modest_recpt_editor_add_resolved_recipient (MODEST_RECPT_EDITOR (recpt_editor), 
+                                                                           email_addrs_per_contact, econtact_id);
+                               g_slist_foreach (email_addrs_per_contact, (GFunc) g_free, NULL);
+                               g_slist_free (email_addrs_per_contact);
+                               email_addrs_per_contact = NULL;
+                               focus_recpt_editor = TRUE;
+                       }
+               }
+               g_list_free (contacts_list);
+       }
+
+#if MODEST_ABOOK_API < 4
+       if (contact_model) {
+               g_object_unref (contact_model);
+               contact_model = NULL;
+       }
+
+       gtk_widget_destroy (contact_dialog);
+#endif
+
+       if (focus_recpt_editor)
+               modest_recpt_editor_grab_focus (MODEST_RECPT_EDITOR (recpt_editor));
+
+}
+
+/**
+ * This function returns the resolved recipients for a given EContact.
+ * If no e-mail address is defined, it launches 'Add e-mail address to contact'
+ * dialog to obtain one. If multiple e-mail addresses are found, it launches
+ * 'Select e-mail address' dialog to allow user to select one or more e-mail
+ * addresses for that contact.
+ *
+ * @param  Contact of type #EContact
+ * @return List of resolved recipient strings, to be freed by calling function.
+ */
+static GSList *get_recipients_for_given_contact(EContact * contact)
+{
+       gchar *givenname = NULL;
+       gchar *familyname = NULL;
+       gchar *nickname = NULL;
+       gchar *emailid = NULL;
+       const gchar *display_name = NULL;
+       GList *list = NULL;
+       gchar *formatted_string = NULL;
+       gboolean email_not_present = FALSE;
+       GSList *formattedlist = NULL, *selected_email_addr_list = NULL, *node = NULL;
+
+       if (!contact) {
+               return NULL;
+       }
+
+       givenname = (gchar *) e_contact_get_const(contact, E_CONTACT_GIVEN_NAME);
+       familyname = (gchar *) e_contact_get_const(contact, E_CONTACT_FAMILY_NAME);
+       nickname = (gchar *) e_contact_get_const(contact, E_CONTACT_NICKNAME);
+       if (!nickname)
+               nickname = "";
+       list = (GList *) e_contact_get(contact, E_CONTACT_EMAIL);
+
+       if (!list) {
+               email_not_present = TRUE;
+       }
+
+       if (list && g_list_length(list) == 1) {
+               if (list->data == NULL || g_utf8_strlen(list->data, -1) == 0) {
+                       email_not_present = TRUE;
+               } else {
+                       emailid = g_strstrip(g_strdup(list->data));
+                       if (g_utf8_strlen(emailid, -1) == 0) {
+                               g_free(emailid);
+                               email_not_present = TRUE;
+                       }
+               }
+       }
+
+       /*Launch the 'Add e-mail addr to contact' dialog if required */
+       if (email_not_present) {
+#if MODEST_ABOOK_API < 4
+               display_name = osso_abook_contact_get_display_name(contact);            
+#else
+               OssoABookContact *abook_contact;
+              
+               abook_contact = osso_abook_contact_new_from_template (contact);
+               display_name = osso_abook_contact_get_display_name(abook_contact);
+               g_object_unref (abook_contact);
+#endif
+
+               emailid = get_email_addr_from_user(display_name);
+               if (emailid) {
+                       e_contact_set(contact, E_CONTACT_EMAIL_1, emailid);
+                       commit_contact(contact, FALSE);
+               }
+       }
+
+       if (emailid) {
+               if (givenname || familyname)
+                       formatted_string =
+                           ui_get_formatted_email_id(givenname, familyname, emailid);
+               else
+                       formatted_string = g_strdup(emailid);
+               formattedlist = g_slist_append(formattedlist, formatted_string);
+               g_free(emailid);
+       }
+
+       /*Launch the 'Select e-mail address' dialog if required */
+       if (g_list_length(list) > 1) {
+               selected_email_addr_list = select_email_addrs_for_contact(list);
+               for (node = selected_email_addr_list; node != NULL; node = node->next) {
+                       if (givenname || familyname)
+                               formatted_string =
+                                   ui_get_formatted_email_id(givenname, familyname, node->data);
+                       else
+                               formatted_string = g_strdup(node->data);
+                       formattedlist = g_slist_append(formattedlist, formatted_string);
+               }
+               if (selected_email_addr_list) {
+                       g_slist_foreach(selected_email_addr_list, (GFunc) g_free, NULL);
+                       g_slist_free(selected_email_addr_list);
+               }
+       }
+
+       if (list) {
+               g_list_foreach(list, (GFunc) g_free, NULL);
+               g_list_free(list);
+       }
+
+       return formattedlist;
+}
+
+/**
+ * This is a helper function to commit a EContact to Address_Book application.
+ *
+ * @param  contact  Contact of type #EContact
+ * @return void
+ */
+static void 
+commit_contact(EContact * contact, gboolean is_new)
+{
+       g_return_if_fail (contact);
+       g_return_if_fail (book);
+       
+       if (!contact || !book)
+               return;
+       
+#if MODEST_ABOOK_API < 2
+       osso_abook_contact_commit(contact, is_new, book);
+#else
+       osso_abook_contact_commit(contact, is_new, book, NULL);
+#endif /* MODEST_ABOOK_API < 2 */
+}
+
+/**
+ * This is a helper function used to launch 'Add e-mail address to contact' dialog
+ * after showing appropriate notification, when there is no e-mail address defined
+ * for a selected contact.
+ *
+ * @param  given_name  Given name of the contact
+ * @param  family_name  Family name of the contact
+ * @return E-mail address string entered by user, to be freed by calling function.
+ */
+static gchar *
+get_email_addr_from_user(const gchar * given_name)
+{
+       gchar *notification = NULL;
+       gchar *email_addr = NULL;
+       GtkWidget *note;
+       gboolean note_response;
+
+
+       notification = g_strdup_printf(_("mcen_nc_email_address_not_defined"), given_name);
+
+       note = hildon_note_new_confirmation (NULL, notification);
+       note_response = gtk_dialog_run (GTK_DIALOG(note));
+       gtk_widget_destroy (note);
+       g_free(notification);
+
+       if (note_response == GTK_RESPONSE_OK) {
+               email_addr = run_add_email_addr_to_contact_dlg(given_name);
+       }
+
+       return email_addr;
+}
+
+/**
+This function is used to get the formated email id with given name and sur name
+in the format "GIVENNAME SURNAME <EMAIL ADDRESS>".
+@param current_given_name    to hold the given name
+@param current_sur_name      to hold the sur name
+@param current_email_id      to hold the email id. 
+@return gchar* string to be freed by calling function
+*/
+static gchar *
+ui_get_formatted_email_id(gchar * current_given_name,
+                         gchar * current_sur_name, gchar * current_email_id)
+{
+       GString *email_id_str = NULL;
+
+       email_id_str = g_string_new(NULL);
+
+       if ((current_given_name != NULL) && ((strlen(current_given_name) != 0))
+           && (current_sur_name != NULL) && ((strlen(current_sur_name) != 0))) {
+               g_string_append_printf(email_id_str, "%s %s", current_given_name, current_sur_name);
+       } else if ((current_given_name != NULL) && (strlen(current_given_name) != 0)) {
+               g_string_append_printf(email_id_str, "%s", current_given_name);
+       } else if ((current_sur_name != NULL) && (strlen(current_sur_name) != 0)) {
+               g_string_append_printf(email_id_str, "%s", current_sur_name);
+       }
+       if (g_utf8_strchr (email_id_str->str, -1, ' ')) {
+               g_string_prepend_c (email_id_str, '\"');
+               g_string_append_c (email_id_str, '\"');
+       }
+       g_string_append_printf (email_id_str, " %c%s%c", '<', current_email_id, '>');
+       return g_string_free (email_id_str, FALSE);
+}
+
+/**
+ * This is a helper function used to create & run 'Add e-mail address to contact' dialog.
+ * It allows user to enter an e-mail address, and shows appropriate infonote if the
+ * entered string is not a valid e-mail address.
+ *
+ * @param  contact_name  Full name of the contact
+ * @return E-mail address string entered by user, to be freed by calling function.
+ */
+static gchar *
+run_add_email_addr_to_contact_dlg(const gchar * contact_name)
+{
+       GtkWidget *add_email_addr_to_contact_dlg = NULL;
+       GtkSizeGroup *size_group = NULL;
+       GtkWidget *cptn_cntrl = NULL;
+       GtkWidget *name_label = NULL;
+       GtkWidget *email_entry = NULL;
+       gint result = -1;
+       gchar *new_email_addr = NULL;
+       gboolean run_dialog = TRUE;
+
+       add_email_addr_to_contact_dlg =
+           gtk_dialog_new_with_buttons(_("mcen_ti_add_email_title"), NULL,
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT,
+                                       _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT, NULL);
+       gtk_dialog_set_has_separator(GTK_DIALOG(add_email_addr_to_contact_dlg), FALSE);
+       /*Set app_name & state_save related tags to the window */
+
+       size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+       name_label = gtk_label_new(contact_name);
+       gtk_misc_set_alignment(GTK_MISC(name_label), 0, 0);
+       cptn_cntrl =
+           hildon_caption_new(size_group, _("mcen_ia_add_email_name"), name_label, NULL,
+                              HILDON_CAPTION_OPTIONAL);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(add_email_addr_to_contact_dlg)->vbox), cptn_cntrl,
+                          FALSE, FALSE, 0);
+
+       email_entry = gtk_entry_new();
+       cptn_cntrl =
+           hildon_caption_new(size_group, _("mcen_fi_add_email_name"), email_entry, NULL,
+                              HILDON_CAPTION_OPTIONAL);
+       hildon_gtk_entry_set_input_mode(GTK_ENTRY(email_entry), HILDON_GTK_INPUT_MODE_FULL);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(add_email_addr_to_contact_dlg)->vbox), cptn_cntrl,
+                          TRUE, TRUE, 0);
+
+       gtk_widget_show_all(add_email_addr_to_contact_dlg);
+
+       while (run_dialog) {
+               run_dialog = FALSE;
+               gtk_widget_grab_focus(email_entry);
+               result = gtk_dialog_run(GTK_DIALOG(add_email_addr_to_contact_dlg));
+
+               if (result == GTK_RESPONSE_ACCEPT) {
+                       const gchar *invalid_char_offset = NULL;
+                       new_email_addr = g_strdup(gtk_entry_get_text(GTK_ENTRY(email_entry)));
+                       new_email_addr = g_strstrip(new_email_addr);
+                       if (!modest_text_utils_validate_email_address (new_email_addr, &invalid_char_offset)) {
+                               gtk_widget_grab_focus(email_entry);
+                               if ((invalid_char_offset != NULL)&&(*invalid_char_offset != '\0')) {
+                                       gchar *char_in_string = g_strdup_printf ("%c", *invalid_char_offset);
+                                       gchar *message = g_strdup_printf(
+                                               dgettext("hildon-common-strings", "ckdg_ib_illegal_characters_entered"), 
+                                               char_in_string);
+                                       hildon_banner_show_information (
+                                               add_email_addr_to_contact_dlg, NULL, message );
+                                       g_free (message);
+                               } else {
+                                       hildon_banner_show_information (add_email_addr_to_contact_dlg, NULL, _("mcen_ib_invalid_email"));
+                                       run_dialog = TRUE;
+                               }
+                               gtk_editable_select_region((GtkEditable *) email_entry, 0, -1);
+                               g_free(new_email_addr);
+                               new_email_addr = NULL;
+                       }
+               }
+       }
+
+       gtk_widget_destroy(add_email_addr_to_contact_dlg);
+
+       return new_email_addr;
+}
+
+/**
+ * This is helper function to create & run 'Select e-mail address' dialog, used when
+ * multiple e-mail addresses are found for a selected contact. It allows user to select
+ * one or more e-mail addresses for that contact.
+ *
+ * @param  email_addr_list  List of e-mail addresses for that contact
+ * @return List of user selected e-mail addresses, to be freed by calling function.
+ */
+static GSList *
+select_email_addrs_for_contact(GList * email_addr_list)
+{
+       GtkWidget *select_email_addr_dlg = NULL;
+       GtkWidget *view = NULL, *scrolledwindow = NULL;
+       GtkTreeSelection *selection = NULL;
+       GtkCellRenderer *renderer = NULL;
+       GtkTreeViewColumn *col = NULL;
+       GtkListStore *list_store = NULL;
+       GtkTreeModel *model = NULL;
+       GtkTreeIter iter;
+       GList *pathslist = NULL, *node = NULL;
+       gint result = -1;
+       gchar *email_addr = NULL;
+       GSList *selected_email_addr_list = NULL;
+
+       if (!email_addr_list)
+               return NULL;
+
+       select_email_addr_dlg =
+           gtk_dialog_new_with_buttons(_("mcen_ti_select_email_title"),
+                                       NULL,
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       _("mcen_bd_dialog_ok"), GTK_RESPONSE_ACCEPT,
+                                       _("mcen_bd_dialog_cancel"), GTK_RESPONSE_REJECT, NULL);
+       gtk_dialog_set_has_separator(GTK_DIALOG(select_email_addr_dlg), FALSE);
+
+       /* Make the window approximately big enough, because it doesn't resize to be big enough 
+        * for the window title text: */
+       gtk_window_set_default_size (GTK_WINDOW (select_email_addr_dlg), 400, -1);
+
+       scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(select_email_addr_dlg)->vbox), scrolledwindow, TRUE,
+                          TRUE, 0);
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC,
+                                      GTK_POLICY_AUTOMATIC);
+
+       view = gtk_tree_view_new();
+       col = gtk_tree_view_column_new();
+       renderer = gtk_cell_renderer_text_new();
+       gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
+       gtk_tree_view_column_pack_start(col, renderer, TRUE);
+       gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
+       selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+       gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
+       gtk_container_add(GTK_CONTAINER(scrolledwindow), view);
+
+       list_store = gtk_list_store_new(1, G_TYPE_STRING);
+       model = GTK_TREE_MODEL(list_store);
+       gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
+
+       for (node = email_addr_list; node != NULL && node->data != NULL; node = node->next) {
+               email_addr = g_strstrip(g_strdup(node->data));
+               gtk_list_store_append(list_store, &iter);
+               gtk_list_store_set(list_store, &iter, 0, email_addr, -1);
+               g_free(email_addr);
+       }
+       gtk_tree_model_get_iter_first (GTK_TREE_MODEL (list_store), &iter);
+       gtk_tree_selection_select_iter (selection, &iter);
+
+       gtk_widget_show_all(select_email_addr_dlg);
+       result = gtk_dialog_run(GTK_DIALOG(select_email_addr_dlg));
+
+       if (result == GTK_RESPONSE_ACCEPT) {
+               pathslist = gtk_tree_selection_get_selected_rows(selection, NULL);
+               for (node = pathslist; node != NULL; node = node->next) {
+                       if (gtk_tree_model_get_iter(model, &iter, (GtkTreePath *) node->data)) {
+                               gtk_tree_model_get(model, &iter, 0, &email_addr, -1);
+                               selected_email_addr_list =
+                                   g_slist_append(selected_email_addr_list, g_strdup(email_addr));
+                               g_free(email_addr);
+                       }
+               }
+       }
+
+       gtk_list_store_clear(list_store);
+       gtk_widget_destroy(select_email_addr_dlg);
+       return selected_email_addr_list;
+}
+
+
+static gboolean /* make this public? */
+add_to_address_book (const gchar* address)
+{
+       EBookQuery *query;
+       GList *contacts = NULL;
+       GError *err = NULL;
+       gchar *email;
+       
+       g_return_val_if_fail (address, FALSE);
+       
+       if (!book)
+               open_addressbook ();
+       
+       g_return_val_if_fail (book, FALSE);
+
+       email = modest_text_utils_get_email_address (address);
+       
+       query = e_book_query_field_test (E_CONTACT_EMAIL, E_BOOK_QUERY_IS, email);
+       if (!e_book_get_contacts (book, query, &contacts, &err)) {
+               g_printerr ("modest: failed to get contacts: %s",
+                           err ? err->message : "<unknown>");
+               if (err)
+                       g_error_free (err);
+               return FALSE;
+       }
+       e_book_query_unref (query);
+       
+       /*  we need to 'commit' it, even if we already found the email
+        * address in the addressbook; thus, it will show up in the 'recent list' */
+       if (contacts)  {                
+               g_debug ("%s already in the address book", address);
+               commit_contact ((EContact*)contacts->data, FALSE);
+               
+               g_list_foreach (contacts, (GFunc)unref_gobject, NULL);
+               g_list_free (contacts);
+
+       } else {
+               /* it's not yet in the addressbook, add it now! */
+               EContact *new_contact = e_contact_new ();
+               gchar *display_address;
+               display_address = g_strdup (address);
+               if (display_address) {
+                       modest_text_utils_get_display_address (display_address);
+                       if ((display_address[0] != '\0') && (strlen (display_address) != strlen (address)))
+                               e_contact_set (new_contact, E_CONTACT_FULL_NAME, (const gpointer)display_address);
+               }
+               e_contact_set (new_contact, E_CONTACT_EMAIL_1, (const gpointer)email);
+               g_free (display_address);
+               commit_contact (new_contact, TRUE);
+               g_debug ("%s added to address book", address);
+               g_object_unref (new_contact);
+       }
+
+       g_free (email);
+
+       return TRUE;
+}
+
+static gboolean
+show_check_names_banner (gpointer userdata)
+{
+       GtkWidget **banner = (GtkWidget **) userdata;
+
+       gdk_threads_enter ();
+       *banner = modest_platform_animation_banner (NULL, NULL, _("mail_ib_checking_names"));
+       gdk_threads_leave ();
+
+       return FALSE;
+}
+
+static void
+hide_check_names_banner (GtkWidget **banner, guint banner_timeout)
+{
+       if (*banner != NULL) {
+               gtk_widget_destroy (*banner);
+               *banner = NULL;
+       } else {
+               g_source_remove (banner_timeout);
+       }
+
+}
+
+gboolean
+modest_address_book_check_names (ModestRecptEditor *recpt_editor, gboolean update_addressbook)
+{
+       const gchar *recipients = NULL;
+       GSList *start_indexes = NULL, *end_indexes = NULL;
+       GSList *current_start, *current_end;
+       gboolean result = TRUE;
+       GtkTextBuffer *buffer;
+       gint offset_delta = 0;
+       gint last_length;
+       GtkTextIter start_iter, end_iter;
+
+       g_return_val_if_fail (MODEST_IS_RECPT_EDITOR (recpt_editor), FALSE);
+
+       recipients = modest_recpt_editor_get_recipients (recpt_editor);
+       last_length = g_utf8_strlen (recipients, -1);
+       modest_text_utils_get_addresses_indexes (recipients, &start_indexes, &end_indexes);
+
+       if (start_indexes == NULL) {
+               if (last_length != 0) {
+                       hildon_banner_show_information (NULL, NULL, _("mcen_nc_no_matching_contacts"));
+                       return FALSE;
+               } else {
+                       return TRUE;
+               }
+       }
+
+       current_start = start_indexes;
+       current_end = end_indexes;
+       buffer = modest_recpt_editor_get_buffer (recpt_editor);
+
+       while (current_start != NULL) {
+               gchar *address;
+               gchar *start_ptr, *end_ptr;
+               gint start_pos, end_pos;
+               const gchar *invalid_char_position = NULL;
+               gboolean store_address = FALSE;
+
+               start_pos = (*((gint*) current_start->data)) + offset_delta;
+               end_pos = (*((gint*) current_end->data)) + offset_delta;
+              
+               start_ptr = g_utf8_offset_to_pointer (recipients, start_pos);
+               end_ptr = g_utf8_offset_to_pointer (recipients, end_pos);
+
+               address = g_strstrip (g_strndup (start_ptr, end_ptr - start_ptr));
+               gtk_text_buffer_get_iter_at_offset (buffer, &start_iter, start_pos);
+               gtk_text_buffer_get_iter_at_offset (buffer, &end_iter, end_pos);
+               gtk_text_buffer_select_range (buffer, &start_iter, &end_iter);
+
+               if (!modest_text_utils_validate_recipient (address, &invalid_char_position)) {
+                       if ((invalid_char_position != NULL) && (*invalid_char_position != '\0')) {
+                               gchar *char_in_string = g_strdup_printf("%c", *invalid_char_position);
+                               gchar *message = g_strdup_printf(
+                                       dgettext("hildon-common-strings", "ckdg_ib_illegal_characters_entered"), 
+                                       char_in_string);
+                               g_free (char_in_string);
+                               hildon_banner_show_information (NULL, NULL, message );
+                               g_free (message);                               
+                               result = FALSE;
+                       } else if (strstr (address, "@") == NULL) {
+                               /* here goes searching in addressbook */
+                               gchar *contact_id = NULL;
+                               GSList *resolved_addresses = NULL;
+
+                               result = resolve_address (address, &resolved_addresses, &contact_id);
+
+                               if (result) {
+                                       gint new_length;
+                                       /* replace string */
+                                       modest_recpt_editor_replace_with_resolved_recipient (recpt_editor,
+                                                                                            &start_iter, &end_iter,
+                                                                                            resolved_addresses, 
+                                                                                            contact_id);
+                                       g_free (contact_id);
+                                       g_slist_foreach (resolved_addresses, (GFunc) g_free, NULL);
+                                       g_slist_free (resolved_addresses);
+
+                                       /* update offset delta */
+                                       recipients = modest_recpt_editor_get_recipients (recpt_editor);
+                                       new_length = g_utf8_strlen (recipients, -1);
+                                       offset_delta = offset_delta + new_length - last_length;
+                                       last_length = new_length;                                       
+                               }
+                       } else {
+                               /* this address is not valid, select it and return control to user showing banner */
+                               hildon_banner_show_information (NULL, NULL, _("mcen_ib_invalid_email"));
+                               result = FALSE;
+                       }
+               } else {
+                       GSList *tags, *node;
+                       gboolean has_recipient = FALSE;
+
+                       tags = gtk_text_iter_get_tags (&start_iter);
+                       for (node = tags; node != NULL; node = g_slist_next (node)) {
+                               GtkTextTag *tag = GTK_TEXT_TAG (node->data);
+                               if (g_object_get_data (G_OBJECT (tag), "recipient-tag-id") != NULL) {
+                                       has_recipient = TRUE;
+                                       break;
+                               }
+                       }
+                       g_slist_free (tags);
+                       if (!has_recipient) {
+                               GSList * address_list = NULL;
+
+                               address_list = g_slist_prepend (address_list, address);
+                               modest_recpt_editor_replace_with_resolved_recipient (recpt_editor,
+                                                                                    &start_iter, &end_iter,
+                                                                                    address_list, 
+                                                                                    "");
+                               g_slist_free (address_list);
+                               store_address = TRUE;
+                       }
+               }
+
+               /* so, it seems a valid address */
+               /* note: adding it the to the addressbook if it did not exist yet,
+                * and adding it to the recent_list */
+               if (result && update_addressbook && store_address)
+                       add_to_address_book (address);
+
+               g_free (address);
+               if (result == FALSE)
+                       break;
+
+               current_start = g_slist_next (current_start);
+               current_end = g_slist_next (current_end);
+       }
+
+       if (current_start == NULL) {
+               gtk_text_buffer_get_end_iter (buffer, &end_iter);
+               gtk_text_buffer_place_cursor (buffer, &end_iter);
+       }
+
+       g_slist_foreach (start_indexes, (GFunc) g_free, NULL);
+       g_slist_foreach (end_indexes, (GFunc) g_free, NULL);
+       g_slist_free (start_indexes);
+       g_slist_free (end_indexes);
+
+       return result;
+
+}
+
+static GList *
+get_contacts_for_name (const gchar *name)
+{
+       EBookQuery *full_name_book_query = NULL;
+       GList *result;
+       gchar *unquoted;
+
+       if (name == NULL)
+               return NULL;
+
+       unquoted = unquote_string (name);
+       full_name_book_query = e_book_query_field_test (E_CONTACT_FULL_NAME, E_BOOK_QUERY_CONTAINS, unquoted);
+       g_free (unquoted);
+
+       e_book_get_contacts (book, full_name_book_query, &result, NULL);
+       e_book_query_unref (full_name_book_query);
+
+       return result;
+}
+
+static GList *
+select_contacts_for_name_dialog (const gchar *name)
+{
+       EBookQuery *full_name_book_query = NULL;
+       EBookView *book_view = NULL;
+       GList *result = NULL;
+       gchar *unquoted;
+
+       unquoted = unquote_string (name);
+       full_name_book_query = e_book_query_field_test (E_CONTACT_FULL_NAME, E_BOOK_QUERY_CONTAINS, unquoted);
+       g_free (unquoted);
+       e_book_get_book_view (book, full_name_book_query, NULL, -1, &book_view, NULL);
+       e_book_query_unref (full_name_book_query);
+
+       if (book_view) {
+               GtkWidget *contact_view = NULL;
+               GtkWidget *contact_dialog = NULL;
+#if MODEST_ABOOK_API < 4
+               osso_abook_tree_model_set_book_view (OSSO_ABOOK_TREE_MODEL (contact_model), book_view);
+#else /* MODEST_ABOOK_API < 4 */
+               osso_abook_list_store_set_book_view (OSSO_ABOOK_LIST_STORE (contact_model), book_view);
+#endif /* MODEST_ABOOK_API < 4 */
+               e_book_view_start (book_view);
+               
+               contact_view = osso_abook_contact_selector_new_basic (contact_model);
+               contact_dialog = osso_abook_select_dialog_new (OSSO_ABOOK_TREE_VIEW (contact_view));
+               gtk_window_set_title (GTK_WINDOW (contact_dialog), _("mcen_ti_select_recipients"));
+
+               if (gtk_dialog_run (GTK_DIALOG (contact_dialog)) == GTK_RESPONSE_OK) {
+                       result = osso_abook_contact_view_get_selection (OSSO_ABOOK_CONTACT_VIEW (contact_view));
+               }
+               e_book_view_stop (book_view);
+               g_object_unref (book_view);
+               gtk_widget_destroy (contact_dialog);
+       }
+
+       return result;
+}
+
+static gboolean
+resolve_address (const gchar *address, GSList **resolved_addresses, gchar **contact_id)
+{
+       GList *resolved_contacts;
+       guint banner_timeout;
+       GtkWidget *banner = NULL;
+       
+       banner_timeout = g_timeout_add (500, show_check_names_banner, &banner);
+
+       contact_model = osso_abook_contact_model_new ();
+       if (!open_addressbook_sync ()) {
+               if (contact_model) {
+                       g_object_unref (contact_model);
+                       contact_model = NULL;
+               }
+               return FALSE;
+       }
+
+       resolved_contacts = get_contacts_for_name (address);
+
+       if (resolved_contacts == NULL) {
+               /* no matching contacts for the search string */
+               modest_platform_run_information_dialog (NULL, _("mcen_nc_no_matching_contacts"), FALSE);
+               hide_check_names_banner (&banner, banner_timeout);
+     
+               return FALSE;
+       }
+
+       if (g_list_length (resolved_contacts) > 1) {
+               /* show a dialog to select the contact from the resolved ones */
+               g_list_free (resolved_contacts);
+
+               hide_check_names_banner (&banner, banner_timeout);     
+               resolved_contacts = select_contacts_for_name_dialog (address);
+               banner_timeout = g_timeout_add (500, show_check_names_banner, &banner);
+
+       }
+       
+       /* get the resolved contacts (can be no contact) */
+       if (resolved_contacts) {
+               gboolean found;
+               EContact *contact = (EContact *) resolved_contacts->data;
+
+               *resolved_addresses = get_recipients_for_given_contact (contact);
+               hide_check_names_banner (&banner, banner_timeout);     
+               if (*resolved_addresses) {
+                       *contact_id = g_strdup (e_contact_get_const (contact, E_CONTACT_UID));
+                       found = TRUE;
+               } else {
+                       found = FALSE;
+               }
+
+               g_list_foreach (resolved_contacts, (GFunc)unref_gobject, NULL);
+               g_list_free (resolved_contacts);
+
+               return found;
+       } else {
+               /* cancelled dialog to select more than one contact or
+                * selected no contact */
+               hide_check_names_banner (&banner, banner_timeout);     
+               return FALSE;
+       }
+
+}
+
+static gchar *
+unquote_string (const gchar *str)
+{
+       GString *buffer;
+       gchar *p;
+
+       if (str == NULL)
+               return NULL;
+
+       buffer = g_string_new_len (NULL, strlen (str));
+       for (p = (gchar *) str; *p != '\0'; p = g_utf8_next_char (p)) {
+               if (*p == '"') {
+                       p = g_utf8_next_char (p);
+                       while ((*p != '\0')&&(*p != '"')) {
+                               if (*p == '\\') {
+                                       g_string_append_unichar (buffer, g_utf8_get_char (p));
+                                       p = g_utf8_next_char (p);
+                                       
+                               }
+                               g_string_append_unichar (buffer, g_utf8_get_char (p));
+                               p = g_utf8_next_char (p);
+                       }
+               } else {
+                       g_string_append_unichar (buffer, g_utf8_get_char (p));
+               }
+       }
+
+       return g_string_free (buffer, FALSE);
+
+}
diff --git a/src/hildon2/modest-connection-specific-smtp-edit-window.c b/src/hildon2/modest-connection-specific-smtp-edit-window.c
new file mode 100644 (file)
index 0000000..37886bc
--- /dev/null
@@ -0,0 +1,525 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "modest-connection-specific-smtp-edit-window.h"
+#include "widgets/modest-ui-constants.h"
+#include "modest-hildon-includes.h"
+#include "modest-runtime.h"
+
+#include "widgets/modest-serversecurity-combo-box.h"
+#include "widgets/modest-secureauth-combo-box.h"
+#include "widgets/modest-validating-entry.h"
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkstock.h>
+#include "modest-text-utils.h"
+#include "modest-maemo-utils.h"
+
+#include <glib/gi18n.h>
+
+#define PORT_RANGE_MIN 1
+#define PORT_RANGE_MAX 65535
+
+G_DEFINE_TYPE (ModestConnectionSpecificSmtpEditWindow, modest_connection_specific_smtp_edit_window, GTK_TYPE_DIALOG);
+
+#define CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindowPrivate))
+
+static void on_response (GtkDialog *dialog,
+                        gint arg1,
+                        gpointer user_data);
+
+typedef struct _ModestConnectionSpecificSmtpEditWindowPrivate ModestConnectionSpecificSmtpEditWindowPrivate;
+
+struct _ModestConnectionSpecificSmtpEditWindowPrivate
+{
+       GtkWidget *entry_outgoingserver;
+       GtkWidget *combo_outgoing_auth;
+       GtkWidget *entry_user_username;
+       GtkWidget *entry_user_password;
+       GtkWidget *combo_outgoing_security;
+       GtkWidget *entry_port;
+       
+       GtkWidget *button_ok;
+       GtkWidget *button_cancel;
+
+       gchar     *account_name;
+       
+       gboolean is_dirty;
+       gboolean range_error_occured;
+       guint range_error_banner_timeout;
+};
+
+static void
+modest_connection_specific_smtp_edit_window_get_property (GObject *object, guint property_id,
+                                                                                                                       GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+modest_connection_specific_smtp_edit_window_set_property (GObject *object, guint property_id,
+                                                                                                                       const GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+modest_connection_specific_smtp_edit_window_dispose (GObject *object)
+{
+
+       
+       if (G_OBJECT_CLASS (modest_connection_specific_smtp_edit_window_parent_class)->dispose)
+               G_OBJECT_CLASS (modest_connection_specific_smtp_edit_window_parent_class)->dispose (object);
+}
+
+static void
+modest_connection_specific_smtp_edit_window_finalize (GObject *object)
+{
+       ModestConnectionSpecificSmtpEditWindow *self = (ModestConnectionSpecificSmtpEditWindow *) object;
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+
+       if (priv->range_error_banner_timeout > 0) {
+               g_source_remove (priv->range_error_banner_timeout);
+               priv->range_error_banner_timeout = 0;
+       }
+       if (priv->account_name) {
+               g_free (priv->account_name);
+               priv->account_name = NULL;
+       }
+       G_OBJECT_CLASS (modest_connection_specific_smtp_edit_window_parent_class)->finalize (object);
+}
+
+static void
+modest_connection_specific_smtp_edit_window_class_init (ModestConnectionSpecificSmtpEditWindowClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (ModestConnectionSpecificSmtpEditWindowPrivate));
+
+       object_class->get_property = modest_connection_specific_smtp_edit_window_get_property;
+       object_class->set_property = modest_connection_specific_smtp_edit_window_set_property;
+       object_class->dispose = modest_connection_specific_smtp_edit_window_dispose;
+       object_class->finalize = modest_connection_specific_smtp_edit_window_finalize;
+}
+
+enum MODEL_COLS {
+       MODEL_COL_NAME = 0,
+       MODEL_COL_SERVER_NAME = 1,
+       MODEL_COL_ID = 2
+};
+
+static void
+on_change(GtkWidget* widget, ModestConnectionSpecificSmtpEditWindow *self)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+       priv->is_dirty = TRUE;
+}
+
+static void
+on_value_changed(GtkWidget* widget, GValue* value, ModestConnectionSpecificSmtpEditWindow *self)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+
+       priv->range_error_occured = FALSE;
+       on_change(widget, self);
+}
+
+gboolean
+show_banner_handler (gpointer userdata)
+{
+       ModestConnectionSpecificSmtpEditWindow *self = userdata;
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+       gchar *msg;
+
+       msg = g_strdup_printf (dgettext("hildon-libs", "ckct_ib_set_a_value_within_range"), PORT_RANGE_MIN, PORT_RANGE_MAX);
+
+       hildon_banner_show_information (NULL, NULL, msg);
+       g_free (msg);
+
+       priv->range_error_banner_timeout = 0;
+       return FALSE;
+}
+
+static gboolean
+on_range_error (GtkWidget *widget, HildonNumberEditorErrorType type, gpointer user_data)
+{
+       ModestConnectionSpecificSmtpEditWindow *self = user_data;
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+
+       /* We want to prevent the closure of the dialog when a range error occured. The problem is that
+        * the hildon number editor already resets the value to the default value, so we have to
+        * remember that such an error occured. */
+       priv->range_error_occured = TRUE;
+       if (priv->range_error_banner_timeout == 0)
+               priv->range_error_banner_timeout = g_timeout_add (200, show_banner_handler, self);
+
+       /* Show error message by not returning TRUE */
+       return TRUE;
+}
+
+static void
+on_response (GtkDialog *dialog, int response_id, gpointer user_data)
+{
+       const gchar *hostname;
+       ModestConnectionSpecificSmtpEditWindow *self = user_data;
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+
+       hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
+
+       if ((response_id == GTK_RESPONSE_CANCEL) &&
+           (priv->range_error_banner_timeout > 0)) {
+               g_source_remove (priv->range_error_banner_timeout);
+               priv->range_error_banner_timeout = 0;
+       }
+
+       /* Don't close the dialog if a range error occured */
+       if(response_id == GTK_RESPONSE_OK && priv->range_error_occured)
+       {
+               priv->range_error_occured = FALSE;
+               g_signal_stop_emission_by_name (dialog, "response");
+               gtk_widget_grab_focus (priv->entry_port);
+               return;
+       }
+
+       /* Don't close the dialog if a range error occured */
+       if(response_id == GTK_RESPONSE_OK) {
+               if (hostname && (hostname[0] != '\0') &&
+                   (!modest_text_utils_validate_domain_name (hostname))) { 
+                       g_signal_stop_emission_by_name (dialog, "response");
+                       hildon_banner_show_information (NULL, NULL, _("mcen_ib_invalid_servername"));
+                       gtk_widget_grab_focus (priv->entry_outgoingserver);
+                       gtk_editable_select_region (GTK_EDITABLE (priv->entry_outgoingserver), 0, -1);
+                       return;
+               }
+       } else {
+               /* Ask user if they want to discard changes */
+               if (priv->is_dirty) {
+                       gint response;
+                       response = modest_platform_run_confirmation_dialog (GTK_WINDOW (user_data), 
+                                                                           _("imum_nc_wizard_confirm_lose_changes"));
+                       if (response == GTK_RESPONSE_CANCEL)
+                               g_signal_stop_emission_by_name (dialog, "response");
+               }
+       }
+}
+
+static void on_set_focus_child (GtkContainer *container, GtkWidget *widget, gpointer user_data)
+{
+       ModestConnectionSpecificSmtpEditWindow *self = user_data;
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv =
+                       CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+
+       /* Another child gained focus. Since the number editor already reset a
+        * possible range error to the default value, we allow closure of the
+        * dialog */
+       priv->range_error_occured = FALSE;
+}
+
+static void
+on_combo_security_changed (GtkComboBox *widget, gpointer user_data)
+{
+       ModestConnectionSpecificSmtpEditWindow *self = 
+               MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW (user_data);
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+       
+       on_change(GTK_WIDGET(widget), self);
+       
+       const gint port_number = 
+               modest_serversecurity_combo_box_get_active_serversecurity_port (
+                       MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security));
+
+       if(port_number != 0) {
+               hildon_number_editor_set_value (
+                       HILDON_NUMBER_EDITOR (priv->entry_port), port_number);
+       }               
+}
+
+static void
+modest_connection_specific_smtp_edit_window_init (ModestConnectionSpecificSmtpEditWindow *self)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv; 
+       GtkWidget *dialog_box;
+       GtkWidget *scrolled_window, *vbox;
+
+       /* The title of this dialog is quite long, so make the window wide enough */
+       gtk_widget_set_size_request (GTK_WIDGET (self), 600, -1);
+
+       priv = CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (self);
+       dialog_box = GTK_DIALOG(self)->vbox; /* gtk_vbox_new (FALSE, MODEST_MARGIN_HALF); */
+       gtk_box_set_spacing (GTK_BOX (dialog_box), MODEST_MARGIN_NONE);
+       gtk_container_set_border_width (GTK_CONTAINER (dialog_box), MODEST_MARGIN_HALF);
+
+       vbox = gtk_vbox_new (FALSE, 0);
+       
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The outgoing server widgets: */
+       if (!priv->entry_outgoingserver)
+               priv->entry_outgoingserver = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_outgoingserver), HILDON_GTK_INPUT_MODE_FULL);
+       g_signal_connect(G_OBJECT(priv->entry_outgoingserver), "changed", G_CALLBACK(on_change), self);
+       
+       GtkWidget *caption = hildon_caption_new (sizegroup, 
+               _("mcen_li_emailsetup_smtp"), priv->entry_outgoingserver, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->entry_outgoingserver);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The secure authentication widgets: */
+       if (!priv->combo_outgoing_auth)
+               priv->combo_outgoing_auth = GTK_WIDGET (modest_secureauth_combo_box_new ());
+       caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_authentication"), 
+               priv->combo_outgoing_auth, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect (G_OBJECT (priv->combo_outgoing_auth), "changed", G_CALLBACK(on_change), self);
+       gtk_widget_show (priv->combo_outgoing_auth);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The username widgets: */     
+       priv->entry_user_username = GTK_WIDGET (modest_validating_entry_new ());
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_username), HILDON_GTK_INPUT_MODE_FULL);
+       caption = hildon_caption_new (sizegroup, _("mail_fi_username"), 
+               priv->entry_user_username, NULL, HILDON_CAPTION_MANDATORY);
+       g_signal_connect(G_OBJECT(priv->entry_user_username), "changed", G_CALLBACK(on_change), self);
+       gtk_widget_show (priv->entry_user_username);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the username, 
+        * as required by our UI specification: */
+       modest_validating_entry_set_unallowed_characters_whitespace (
+               MODEST_VALIDATING_ENTRY (priv->entry_user_username));
+       
+       /* Set max length as in the UI spec:
+        * TODO: The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_username), 64);
+       
+       /* The password widgets: */     
+       priv->entry_user_password = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_password), 
+               HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
+       gtk_entry_set_visibility (GTK_ENTRY (priv->entry_user_password), FALSE);
+       /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_user_password), '*'); */
+       caption = hildon_caption_new (sizegroup, 
+               _("mail_fi_password"), priv->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect(G_OBJECT(priv->entry_user_password), "changed", G_CALLBACK(on_change), self);
+       gtk_widget_show (priv->entry_user_password);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The secure connection widgets: */    
+       if (!priv->combo_outgoing_security)
+               priv->combo_outgoing_security = GTK_WIDGET (modest_serversecurity_combo_box_new ());
+       modest_serversecurity_combo_box_fill (
+               MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security), MODEST_PROTOCOLS_TRANSPORT_SMTP);
+       modest_serversecurity_combo_box_set_active_serversecurity (
+               MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security), MODEST_PROTOCOLS_CONNECTION_NONE);
+       caption = hildon_caption_new (sizegroup, _("mcen_li_emailsetup_secure_connection"), 
+               priv->combo_outgoing_security, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->combo_outgoing_security);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The port number widgets: */
+       if (!priv->entry_port)
+               priv->entry_port = GTK_WIDGET (hildon_number_editor_new (PORT_RANGE_MIN, PORT_RANGE_MAX));
+       caption = hildon_caption_new (sizegroup, 
+               _("mcen_fi_emailsetup_port"), priv->entry_port, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_add_events(GTK_WIDGET(priv->entry_port), GDK_FOCUS_CHANGE_MASK);
+       g_signal_connect(G_OBJECT(priv->entry_port), "range-error", G_CALLBACK(on_range_error), self);
+       g_signal_connect(G_OBJECT(priv->entry_port), "notify::value", G_CALLBACK(on_value_changed), self);
+       gtk_widget_show (priv->entry_port);
+       gtk_box_pack_start (GTK_BOX (vbox), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Show a default port number when the security method changes, as per the UI spec: */
+       g_signal_connect (G_OBJECT (priv->combo_outgoing_security), "changed", (GCallback)on_combo_security_changed, self);
+       on_combo_security_changed (GTK_COMBO_BOX (priv->combo_outgoing_security), self);
+       
+       /* Add the buttons: */
+       gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK);
+       gtk_dialog_add_button (GTK_DIALOG (self), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL);
+       
+       priv->is_dirty = FALSE;
+       priv->range_error_occured = FALSE;
+       g_signal_connect(G_OBJECT(self), "response", G_CALLBACK(on_response), self);
+       g_signal_connect(G_OBJECT(vbox), "set-focus-child", G_CALLBACK(on_set_focus_child), self);
+
+       priv->range_error_banner_timeout = 0;
+       priv->account_name = NULL;
+
+       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), vbox);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+       gtk_box_pack_start (GTK_BOX (dialog_box), scrolled_window, TRUE, TRUE, 0);
+       gtk_container_set_focus_vadjustment (GTK_CONTAINER (vbox), 
+                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
+       
+       gtk_widget_show_all (dialog_box);
+       gtk_window_set_default_size (GTK_WINDOW (self), -1, 220);
+       
+       
+       /* When this window is shown, hibernation should not be possible, 
+        * because there is no sensible way to save the state: */
+       modest_window_mgr_prevent_hibernation_while_window_is_shown (
+               modest_runtime_get_window_mgr (), GTK_WINDOW (self)); 
+       
+       hildon_help_dialog_help_enable (GTK_DIALOG(self),
+                                       "applications_email_connectionspecificsmtpconf",
+                                       modest_maemo_utils_get_osso_context());
+}
+
+ModestConnectionSpecificSmtpEditWindow*
+modest_connection_specific_smtp_edit_window_new (void)
+{
+       return g_object_new (MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, NULL);
+}
+
+void
+modest_connection_specific_smtp_edit_window_set_connection (
+       ModestConnectionSpecificSmtpEditWindow *window, const gchar* iap_id, const gchar* iap_name,
+       ModestServerAccountSettings *server_settings)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (window);
+
+       /* This causes a warning because of the %s in the translation, but not in the original string: */
+       gchar* title = g_strdup_printf (_("mcen_ti_connection_connection_name"), iap_name);
+       gtk_window_set_title (GTK_WINDOW (window), title);
+       g_free (title);
+
+       if (server_settings) 
+       {
+               
+               if (priv->account_name)
+                       g_free (priv->account_name);
+               priv->account_name = g_strdup (modest_server_account_settings_get_account_name (server_settings));
+               gtk_entry_set_text (GTK_ENTRY (priv->entry_outgoingserver), 
+                                   modest_server_account_settings_get_hostname (server_settings));
+               gtk_entry_set_text (GTK_ENTRY (priv->entry_user_username),
+                                   modest_server_account_settings_get_username (server_settings));     
+               gtk_entry_set_text (GTK_ENTRY (priv->entry_user_password), 
+                                   modest_server_account_settings_get_password (server_settings));
+       
+               modest_serversecurity_combo_box_set_active_serversecurity (
+               MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security), 
+               modest_server_account_settings_get_security_protocol (server_settings));
+       
+               modest_secureauth_combo_box_set_active_secureauth (
+               MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth), 
+               modest_server_account_settings_get_auth_protocol (server_settings));
+               
+               /* port: */
+               hildon_number_editor_set_value (
+                       HILDON_NUMBER_EDITOR (priv->entry_port), 
+                       modest_server_account_settings_get_port (server_settings));
+               
+               
+               /* This will cause changed signals so we set dirty back to FALSE */
+               priv->is_dirty = FALSE;
+               if (priv->range_error_banner_timeout > 0) {
+                       g_source_remove (priv->range_error_banner_timeout);
+                       priv->range_error_banner_timeout = 0;
+               }
+       
+       }
+}
+
+ModestServerAccountSettings*
+modest_connection_specific_smtp_edit_window_get_settings (ModestConnectionSpecificSmtpEditWindow *window)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv = NULL;
+       ModestServerAccountSettings *server_settings = NULL;
+       const gchar *outgoing_server = NULL;
+
+       priv =  CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (window);
+       outgoing_server = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
+
+       /* If the outgoing server is NULL, we are removing the connection specific
+        * settings */
+       if ((outgoing_server == NULL) || (outgoing_server[0] == '\0')) {
+               return NULL;
+       }
+       
+       server_settings = modest_server_account_settings_new ();
+       
+       modest_server_account_settings_set_hostname (server_settings, 
+                                                    gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver)));
+       modest_server_account_settings_set_protocol (server_settings,
+                                                    MODEST_PROTOCOLS_TRANSPORT_SMTP);
+       modest_server_account_settings_set_username (server_settings,
+                                                    gtk_entry_get_text (GTK_ENTRY (priv->entry_user_username)));
+       modest_server_account_settings_set_password (server_settings,
+                                                    gtk_entry_get_text (GTK_ENTRY (priv->entry_user_password)));
+       
+       modest_server_account_settings_set_security_protocol (server_settings, 
+                                                    modest_serversecurity_combo_box_get_active_serversecurity (
+                                                    MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security)));
+       modest_server_account_settings_set_auth_protocol (server_settings,
+                                                         modest_secureauth_combo_box_get_active_secureauth (
+                                                         MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth)));
+       modest_server_account_settings_set_account_name (server_settings,
+                                                        priv->account_name);
+       
+       /* port: */
+       modest_server_account_settings_set_port (server_settings,
+                                                hildon_number_editor_get_value (HILDON_NUMBER_EDITOR (priv->entry_port)));
+                       
+       return server_settings;
+}
+
+gboolean 
+modest_connection_specific_smtp_edit_window_is_dirty(ModestConnectionSpecificSmtpEditWindow *window)
+{
+       ModestConnectionSpecificSmtpEditWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_PRIVATE (window);
+       
+       return priv->is_dirty;
+}
diff --git a/src/hildon2/modest-connection-specific-smtp-edit-window.h b/src/hildon2/modest-connection-specific-smtp-edit-window.h
new file mode 100644 (file)
index 0000000..4efcee5
--- /dev/null
@@ -0,0 +1,86 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived from
+ *      this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW
+#define __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW
+
+#include <gtk/gtkdialog.h>
+#include <gtk/gtktreeview.h>
+#include <modest-server-account-settings.h>
+
+G_BEGIN_DECLS
+
+#define MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW modest_connection_specific_smtp_edit_window_get_type()
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindow))
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindowClass))
+
+#define MODEST_IS_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW))
+
+#define MODEST_IS_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW))
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW, ModestConnectionSpecificSmtpEditWindowClass))
+
+typedef struct {
+       GtkDialog parent;
+       
+} ModestConnectionSpecificSmtpEditWindow;
+
+typedef struct {
+       GtkDialogClass parent_class;
+} ModestConnectionSpecificSmtpEditWindowClass;
+
+GType modest_connection_specific_smtp_edit_window_get_type (void);
+
+ModestConnectionSpecificSmtpEditWindow* modest_connection_specific_smtp_edit_window_new (void);
+
+void modest_connection_specific_smtp_edit_window_set_connection (
+       ModestConnectionSpecificSmtpEditWindow *window, const gchar* iap_id, const gchar* iap_name, 
+       ModestServerAccountSettings *server_settings);
+       
+ModestServerAccountSettings* modest_connection_specific_smtp_edit_window_get_settings (
+       ModestConnectionSpecificSmtpEditWindow *window);
+
+gboolean modest_connection_specific_smtp_edit_window_is_dirty(
+       ModestConnectionSpecificSmtpEditWindow *window);
+       
+G_END_DECLS
+
+#endif /* __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_WINDOW */
diff --git a/src/hildon2/modest-connection-specific-smtp-window.c b/src/hildon2/modest-connection-specific-smtp-window.c
new file mode 100644 (file)
index 0000000..3f98ded
--- /dev/null
@@ -0,0 +1,581 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "modest-connection-specific-smtp-window.h"
+#include "modest-connection-specific-smtp-edit-window.h"
+#include <modest-account-mgr-helpers.h>
+#include "widgets/modest-ui-constants.h"
+
+#include <modest-runtime.h>
+#include <tny-maemo-conic-device.h>
+
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtkliststore.h>
+#include <gtk/gtkscrolledwindow.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkstock.h>
+
+#include "modest-hildon-includes.h"
+#include "modest-platform.h"
+#include "modest-maemo-utils.h"
+
+#include <glib/gi18n.h>
+#include <string.h>
+
+G_DEFINE_TYPE (ModestConnectionSpecificSmtpWindow, modest_connection_specific_smtp_window,
+              GTK_TYPE_DIALOG);
+
+#define CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW, ModestConnectionSpecificSmtpWindowPrivate))
+
+typedef struct _ModestConnectionSpecificSmtpWindowPrivate ModestConnectionSpecificSmtpWindowPrivate;
+
+struct _ModestConnectionSpecificSmtpWindowPrivate
+{
+       GtkTreeView *treeview;
+       GtkTreeModel *model;
+       GtkWidget *button_edit;
+       
+       ModestAccountMgr *account_manager;
+};
+
+static void on_response (GtkDialog *dialog, 
+                        gint response, 
+                        gpointer user_data);
+
+/* static gboolean on_key_pressed (GtkWidget *self, GdkEventKey *event, gpointer user_data); */
+
+static void
+modest_connection_specific_smtp_window_get_property (GObject *object, guint property_id,
+                                                                                                                       GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+modest_connection_specific_smtp_window_set_property (GObject *object, guint property_id,
+                                                                                                                       const GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+modest_connection_specific_smtp_window_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (modest_connection_specific_smtp_window_parent_class)->dispose)
+               G_OBJECT_CLASS (modest_connection_specific_smtp_window_parent_class)->dispose (object);
+}
+
+enum MODEL_COLS {
+       MODEL_COL_NAME = 0, /* libconic IAP Name: a string */
+       MODEL_COL_ID = 1, /* libconic IAP ID: a string */
+       MODEL_COL_SERVER_ACCOUNT_NAME = 2, /* a string */
+       MODEL_COL_SERVER_NAME = 3, /* a string */
+       MODEL_COL_SERVER_ACCOUNT_SETTINGS = 4 /* a gpointer */
+};
+
+
+void update_model_server_names (ModestConnectionSpecificSmtpWindow *self);
+
+static void
+modest_connection_specific_smtp_window_finalize (GObject *object)
+{
+       ModestConnectionSpecificSmtpWindowPrivate *priv = CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (object);
+       
+       /* Free all the data items from the treemodel: */
+       GtkTreeIter iter;
+       gboolean valid = gtk_tree_model_get_iter_first (priv->model, &iter);
+       while (valid) {
+               ModestServerAccountSettings *server_settings = NULL;
+               
+               gtk_tree_model_get (priv->model, &iter, 
+                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, &server_settings,
+                                   -1);
+                                
+               if (server_settings)
+                       g_object_unref (server_settings);
+                       
+               /* Get next row: */
+               valid = gtk_tree_model_iter_next (priv->model, &iter);
+       }
+       
+       g_object_unref (G_OBJECT (priv->model));
+       
+       G_OBJECT_CLASS (modest_connection_specific_smtp_window_parent_class)->finalize (object);
+}
+
+static void
+modest_connection_specific_smtp_window_class_init (ModestConnectionSpecificSmtpWindowClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (ModestConnectionSpecificSmtpWindowPrivate));
+
+       object_class->get_property = modest_connection_specific_smtp_window_get_property;
+       object_class->set_property = modest_connection_specific_smtp_window_set_property;
+       object_class->dispose = modest_connection_specific_smtp_window_dispose;
+       object_class->finalize = modest_connection_specific_smtp_window_finalize;
+}
+
+/* libconic does not return a list of connections in scratchbox,
+ * so enable this to put a fake row in the list,
+ * so we can test other parts of the code. */
+/* #define DEBUG_WITHOUT_LIBCONIC 1 */
+
+void
+modest_connection_specific_smtp_window_fill_with_connections (ModestConnectionSpecificSmtpWindow *self,
+                                                             ModestAccountMgr *account_manager)
+{
+#ifdef MODEST_HAVE_CONIC
+       ModestConnectionSpecificSmtpWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+       priv->account_manager = account_manager;
+       
+       GtkListStore *liststore = GTK_LIST_STORE (priv->model);
+       
+       TnyDevice *device = modest_runtime_get_device ();
+       g_assert (TNY_IS_MAEMO_CONIC_DEVICE (device));
+       
+       /* Get the list of Internet Access Points: */
+       #ifdef DEBUG_WITHOUT_LIBCONIC
+       GSList *list_iaps = g_slist_append(NULL, (gpointer)1);
+       #else
+       TnyMaemoConicDevice *maemo_device = TNY_MAEMO_CONIC_DEVICE (device);
+       GSList *list_iaps = tny_maemo_conic_device_get_iap_list (maemo_device);
+       #endif
+       
+       /* printf("debug: list_iaps=%p, list_iaps size = %d\n", list_iaps, g_slist_length(list_iaps)); */
+       
+       GSList* iter = list_iaps;
+       while (iter) {
+               ConIcIap *iap = (ConIcIap*)iter->data;
+               if (iap) {
+                       #ifdef DEBUG_WITHOUT_LIBCONIC
+                       const gchar *connection_name = "debug name";
+                       const gchar *connection_id = "debug id";
+                       #else
+                       const gchar *connection_name = con_ic_iap_get_name (iap);
+                       const gchar *connection_id = con_ic_iap_get_id (iap);
+                       #endif
+                       
+                       printf ("debug: iac name=%s, id=%s\n", connection_name, connection_id);
+                       
+                       /* Get any already-associated connection-specific server account: */
+                       gchar *server_account_name = NULL;
+                       server_account_name = modest_account_mgr_get_connection_specific_smtp (
+                               priv->account_manager, connection_id);
+                                       
+                       /* Add the row to the model: */
+                       GtkTreeIter iter;
+                       gtk_list_store_append (liststore, &iter);
+                       gtk_list_store_set(liststore, &iter, 
+                               MODEL_COL_ID, connection_id, 
+                               MODEL_COL_NAME, connection_name,
+                               MODEL_COL_SERVER_ACCOUNT_NAME, server_account_name,
+                               -1);
+                               
+                       g_free (server_account_name);
+               }
+               
+               iter = g_slist_next (iter);     
+       }
+               
+       #ifndef DEBUG_WITHOUT_LIBCONIC
+       if (list_iaps)
+               tny_maemo_conic_device_free_iap_list (maemo_device, list_iaps);
+       #endif
+               
+       update_model_server_names (self);
+#endif /*MODEST_HAVE_CONIC */
+}
+       
+static void
+on_button_edit (ModestConnectionSpecificSmtpWindow *self)
+{
+       ModestConnectionSpecificSmtpWindowPrivate *priv = CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+       ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
+       
+       gchar *id = NULL;
+       gchar *connection_name = NULL;
+       gchar *server_account_name = NULL;
+       ModestServerAccountSettings *server_settings = NULL;
+       GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview));
+       GtkTreeIter iter;
+       GtkTreeModel *model = 0;
+       if (gtk_tree_selection_get_selected (sel, &model, &iter)) {
+               gtk_tree_model_get (priv->model, &iter,
+                                   MODEL_COL_ID, &id,
+                                   MODEL_COL_NAME, &connection_name,
+                                   MODEL_COL_SERVER_ACCOUNT_NAME, &server_account_name,
+                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, &server_settings,
+                                   -1);
+       
+               /* printf("DEBUG: %s: BEFORE: connection-specific server_account_name=%s\n", __FUNCTION__, server_account_name); */
+               /* TODO: Is 0 an allowed libconic IAP ID?
+                * If not then we should check for it. */
+               
+               /* Get existing server account data if a server account is already specified: */
+               gboolean settings_were_retrieved = FALSE;
+               if (server_account_name && !server_settings) {
+                       server_settings = modest_account_mgr_load_server_settings(mgr, server_account_name, TRUE);
+                       if (server_settings)
+                               settings_were_retrieved = TRUE;
+               }
+               
+               GtkWidget * window = GTK_WIDGET (modest_connection_specific_smtp_edit_window_new ());
+               modest_connection_specific_smtp_edit_window_set_connection (
+                       MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW (window), id, connection_name, server_settings);
+                       
+               /* Delete data, unless it was data from the rowmodel: */
+               if (settings_were_retrieved) {
+                       g_object_unref (server_settings);
+                       server_settings = NULL;
+               }
+                       
+               modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (window));
+               
+               gint response = gtk_dialog_run (GTK_DIALOG (window));
+               if (response == GTK_RESPONSE_OK) {
+
+                       /* Delete any previous data for this row: */
+                       if (server_settings) {
+                               g_object_unref (server_settings);
+                               server_settings = NULL;
+                       }
+                       
+                       /* Get the new account data and save it in the row for later:
+                        * We free this in finalize(),
+                        * and save it to our configuration in
+                        * modest_connection_specific_smtp_window_save_server_accounts(). */
+                       server_settings = modest_connection_specific_smtp_edit_window_get_settings (
+                                                                                                   MODEST_CONNECTION_SPECIFIC_SMTP_EDIT_WINDOW (window));
+                       
+                       if (server_settings) {
+                               gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
+                                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, server_settings,
+                                                   MODEL_COL_SERVER_NAME, modest_server_account_settings_get_hostname (server_settings),
+                                                   -1);
+                       } else {
+                               gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
+                                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, NULL,
+                                                   MODEL_COL_SERVER_NAME, NULL,
+                                                   MODEL_COL_SERVER_ACCOUNT_NAME, NULL,
+                                                   -1);
+                       }
+               }
+               gtk_widget_destroy (window);
+       }
+       g_free (connection_name);
+       g_free (id);
+       g_free (server_account_name);
+       update_model_server_names (self);
+}
+
+static void
+on_selection_changed (GtkTreeSelection *sel, ModestConnectionSpecificSmtpWindow *self)
+{
+       ModestConnectionSpecificSmtpWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+
+       GtkTreeModel *model = NULL;
+       GtkTreeIter iter;
+       const gboolean has_selection =
+               gtk_tree_selection_get_selected (sel, &model, &iter);
+
+       gtk_widget_set_sensitive (priv->button_edit, has_selection);
+}
+
+static void
+modest_connection_specific_smtp_window_init (ModestConnectionSpecificSmtpWindow *self)
+{
+       ModestWindowMgr *mgr;
+
+       /* Specify a default size, because the GtkTreeView's default requested size  
+        * is not big enough: */
+       gtk_window_set_default_size (GTK_WINDOW (self), 500, 300);
+       
+       /* This seems to be necessary to make the window show at the front with decoration.
+        * If we use property type=GTK_WINDOW_TOPLEVEL instead of the default GTK_WINDOW_POPUP+decoration, 
+        * then the window will be below the others. */
+       gtk_window_set_type_hint (GTK_WINDOW (self),
+                           GDK_WINDOW_TYPE_HINT_DIALOG);
+                           
+       ModestConnectionSpecificSmtpWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+
+       /* Create a tree model for the tree view:
+        * with a string for the name, a string for the server name, and an int for the ID.
+        * This must match our MODEL_COLS enum constants.
+        */
+       priv->model = GTK_TREE_MODEL (gtk_list_store_new (5, 
+               G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
+
+       /* Setup the tree view: */
+       priv->treeview = GTK_TREE_VIEW (gtk_tree_view_new_with_model (priv->model));
+
+       /* Show the column headers,
+        * which does not seem to be the default on Maemo.
+        */
+       gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(priv->treeview), TRUE);
+       
+       /* name column:
+        * The ID model column in not shown in the view. */
+       GtkTreeViewColumn *view_column = gtk_tree_view_column_new ();
+       GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_column_pack_start(view_column, renderer, TRUE);
+       gtk_tree_view_column_set_attributes (view_column, renderer, 
+       "text", MODEL_COL_NAME, NULL);
+       gtk_tree_view_column_set_title (view_column, _("mcen_ia_optionalsmtp_connection_name"));
+       gtk_tree_view_append_column (priv->treeview, view_column);
+
+       
+       /* server name column: */
+       view_column = gtk_tree_view_column_new ();
+       renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_column_pack_start(view_column, renderer, TRUE);
+       gtk_tree_view_column_set_attributes (view_column, renderer, 
+       "text", MODEL_COL_SERVER_NAME, NULL);
+       gtk_tree_view_column_set_title (view_column, _("mcen_ia_optionalsmtp_servername"));
+       gtk_tree_view_append_column (priv->treeview, view_column);
+       
+       /* The application must call modest_connection_specific_smtp_window_fill_with_connections(). */
+       
+       GtkWidget *vbox = GTK_DIALOG(self)->vbox;
+       //gtk_vbox_new (FALSE, MODEST_MARGIN_DEFAULT);
+
+       /* Introductory note: */
+       /* TODO: For some reason this label does not wrap. It is truncated. */
+       GtkWidget *label = gtk_label_new(_("mcen_ia_optionalsmtp_note"));
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       /* So that it is shown without being truncated: */
+       gtk_label_set_max_width_chars (GTK_LABEL (label), 20);
+       /* The documentation for gtk_label_set_line_wrap() says that we must 
+        * call gtk_widget_set_size_request() with a hard-coded width, 
+        * though I wonder why gtk_label_set_max_width_chars() isn't enough. */
+       gtk_widget_set_size_request (label, 400, -1);
+       gtk_widget_show (label);
+       gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, MODEST_MARGIN_HALF);
+       
+       /* Put the treeview in a scrolled window and add it to the box: */
+       GtkWidget *scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+       gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), MODEST_MARGIN_DEFAULT);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_NEVER, 
+               GTK_POLICY_AUTOMATIC);
+       gtk_widget_show (scrolled_window);
+       gtk_container_add (GTK_CONTAINER (scrolled_window), GTK_WIDGET (priv->treeview));
+       gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (scrolled_window), TRUE, TRUE, MODEST_MARGIN_HALF);
+       gtk_widget_show (GTK_WIDGET (priv->treeview));
+       gtk_widget_show (vbox);
+       
+       /* Hack: we use the response apply to identify the click on the edit button */
+       priv->button_edit = gtk_dialog_add_button (GTK_DIALOG(self), _("mcen_bd_edit"), GTK_RESPONSE_APPLY);
+       gtk_dialog_add_button (GTK_DIALOG(self), _("mcen_bd_close"), GTK_RESPONSE_CLOSE);
+       
+       /* Disable the Edit button when nothing is selected: */
+       GtkTreeSelection *sel = gtk_tree_view_get_selection (priv->treeview);
+       g_signal_connect (sel, "changed",
+                         G_CALLBACK(on_selection_changed), self);
+       on_selection_changed (sel, self);
+       
+       /* When this window is shown, hibernation should not be possible, 
+        * because there is no sensible way to save the state: */
+       mgr = modest_runtime_get_window_mgr ();
+       modest_window_mgr_prevent_hibernation_while_window_is_shown (mgr, 
+                                                                    GTK_WINDOW (self)); 
+
+       /* Set window title */
+       gtk_window_set_title (GTK_WINDOW (self), _("mcen_ti_optionalsmtp_servers"));
+
+       g_signal_connect (self, "response", G_CALLBACK (on_response), NULL);
+       
+       hildon_help_dialog_help_enable (GTK_DIALOG(self),
+                                       "email_connectionsspecificsmtpconf",
+                                       modest_maemo_utils_get_osso_context());
+}
+
+ModestConnectionSpecificSmtpWindow*
+modest_connection_specific_smtp_window_new (void)
+{
+       return g_object_new (MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW, NULL);
+}
+
+/** The application should call this when the user changes should be saved.
+ */
+gboolean
+modest_connection_specific_smtp_window_save_server_accounts (ModestConnectionSpecificSmtpWindow *self)
+{
+       ModestAccountMgr *mgr = modest_runtime_get_account_mgr ();
+       ModestConnectionSpecificSmtpWindowPrivate *priv = 
+               CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+       
+       
+       /* Get the first iter in the list */
+       GtkTreeIter iter;
+       gboolean valid = gtk_tree_model_get_iter_first (priv->model, &iter);
+
+       /* Walk through the list, reading each row */
+       while (valid) {
+               gchar *id = NULL;
+               gchar *connection_name = NULL;
+               gchar *server_account_name = NULL;
+               gchar *server_name = NULL;
+               ModestServerAccountSettings *server_settings = NULL;
+               
+               gtk_tree_model_get (priv->model, &iter, 
+                                   MODEL_COL_ID, &id, 
+                                   MODEL_COL_NAME, &connection_name, 
+                                   MODEL_COL_SERVER_NAME, &server_name,
+                                   MODEL_COL_SERVER_ACCOUNT_NAME, &server_account_name,
+                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, &server_settings,
+                                   -1);
+                                
+               gboolean success = TRUE;   
+               if (id && server_settings) { /* The presence of data suggests that there is something to save. */
+                       if (!server_account_name) {
+                               /* Add a new server account, building a (non-human-visible) name: */
+                               gchar *name_start = g_strdup_printf("specific_%s", connection_name);
+                               server_account_name = modest_account_mgr_get_unused_account_name (
+                                       priv->account_manager, name_start, TRUE /* server account. */);
+                               g_assert (server_account_name);
+                               g_free (name_start);
+                               
+                               modest_server_account_settings_set_account_name (server_settings, server_account_name);
+                               success = modest_account_mgr_save_server_settings (mgr, server_settings);
+                               if (success) {
+                                       TnyAccount *account = TNY_ACCOUNT (modest_tny_account_store_new_connection_specific_transport_account 
+                                                                          (modest_runtime_get_account_store (),
+                                                                           server_account_name));
+                                       if (account)
+                                               g_object_unref (account);
+                               }
+                               
+                               /* associate the specific server account with this connection for this account: */
+                               success = success && modest_account_mgr_set_connection_specific_smtp (
+                                       priv->account_manager, id, server_account_name);
+                               
+                               /* Save the new name in the treemodel, so it can be edited again later: */
+                               gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter, 
+                                       MODEL_COL_SERVER_ACCOUNT_NAME, server_account_name, -1);
+                               
+                       } else {
+                               modest_account_mgr_save_server_settings (mgr, server_settings);
+                       }
+               } else if (id && server_name && 
+                          !strcmp (server_name, _("mcen_ia_optionalsmtp_notdefined"))) {
+                       modest_account_mgr_remove_connection_specific_smtp (priv->account_manager, 
+                                                                           id);
+                       gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter, 
+                                           MODEL_COL_SERVER_ACCOUNT_NAME, NULL, -1);
+               }
+               
+               g_free (connection_name);
+               g_free (id);
+               g_free (server_account_name);
+               g_free (server_name);
+               
+               if (!success)
+                       return FALSE;
+                       
+               /* Get next row: */
+               valid = gtk_tree_model_iter_next (priv->model, &iter);
+       }
+       
+       update_model_server_names (self);
+       
+       return TRUE;
+}
+
+void update_model_server_names (ModestConnectionSpecificSmtpWindow *self)
+{
+       ModestConnectionSpecificSmtpWindowPrivate *priv = CONNECTION_SPECIFIC_SMTP_WINDOW_GET_PRIVATE (self);
+
+       GtkTreeIter iter;
+       gboolean valid = gtk_tree_model_get_iter_first (priv->model, &iter);
+       while (valid) {
+               
+               gchar *server_account_name = NULL;
+               ModestServerAccountSettings *server_settings = NULL;
+               gtk_tree_model_get (priv->model, &iter, 
+                                   MODEL_COL_SERVER_ACCOUNT_NAME, &server_account_name,
+                                   MODEL_COL_SERVER_ACCOUNT_SETTINGS, &server_settings,
+                                   -1);        
+               if (server_settings && modest_server_account_settings_get_hostname (server_settings)
+                   && (modest_server_account_settings_get_hostname (server_settings) [0] != '\0')) {
+                       gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter, 
+                                           MODEL_COL_SERVER_NAME, modest_server_account_settings_get_hostname (server_settings),
+                                           -1);
+               } else if (server_account_name) {
+                       
+                       /* Get the server hostname and show it in the treemodel: */     
+                       gchar *hostname = modest_account_mgr_get_server_account_hostname (priv->account_manager, 
+                                                                                         server_account_name);
+                       gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter, 
+                                           MODEL_COL_SERVER_NAME, hostname,
+                                           -1);
+                       g_free (hostname);
+               } else {
+                       gtk_list_store_set (GTK_LIST_STORE (priv->model), &iter,
+                                           MODEL_COL_SERVER_NAME, _("mcen_ia_optionalsmtp_notdefined"),
+                                           -1);
+               }
+                       
+               /* Get next row: */
+               valid = gtk_tree_model_iter_next (priv->model, &iter);
+       }
+}
+
+static void
+on_response (GtkDialog *dialog,
+            gint response,
+            gpointer user_data)
+{
+       switch (response) {
+       case GTK_RESPONSE_APPLY:
+               /* We use it for the edit button */
+               on_button_edit (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (dialog));
+               g_signal_stop_emission_by_name (dialog, "response");
+               break;
+       case GTK_RESPONSE_CLOSE:
+       case GTK_RESPONSE_NONE:
+       case GTK_RESPONSE_DELETE_EVENT:
+               /* Generated as a response to delete-event, i.e,
+                  pressin Esc, or by pressing the Close button */
+               modest_connection_specific_smtp_window_save_server_accounts (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (dialog));
+               gtk_widget_destroy (GTK_WIDGET (dialog));
+       }
+}
diff --git a/src/hildon2/modest-connection-specific-smtp-window.h b/src/hildon2/modest-connection-specific-smtp-window.h
new file mode 100644 (file)
index 0000000..279681e
--- /dev/null
@@ -0,0 +1,84 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *      notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *      notice, this list of conditions and the following disclaimer in the
+ *      documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *      contributors may be used to endorse or promote products derived from
+ *      this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_WINDOW
+#define __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_WINDOW
+
+#include <modest-account-mgr.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtktreeview.h>
+#include <gtk/gtkdialog.h>
+
+G_BEGIN_DECLS
+
+#define MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW modest_connection_specific_smtp_window_get_type()
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW, ModestConnectionSpecificSmtpWindow))
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW, ModestConnectionSpecificSmtpWindowClass))
+
+#define MODEST_IS_CONNECTION_SPECIFIC_SMTP_WINDOW(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW))
+
+#define MODEST_IS_CONNECTION_SPECIFIC_SMTP_WINDOW_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW))
+
+#define MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+       MODEST_TYPE_CONNECTION_SPECIFIC_SMTP_WINDOW, ModestConnectionSpecificSmtpWindowClass))
+
+typedef struct {
+       GtkDialog parent;
+       
+} ModestConnectionSpecificSmtpWindow;
+
+typedef struct {
+       GtkDialogClass parent_class;
+} ModestConnectionSpecificSmtpWindowClass;
+
+GType modest_connection_specific_smtp_window_get_type (void);
+
+ModestConnectionSpecificSmtpWindow* modest_connection_specific_smtp_window_new (void);
+
+void
+modest_connection_specific_smtp_window_fill_with_connections (ModestConnectionSpecificSmtpWindow *self, 
+       ModestAccountMgr *account_manager);
+
+gboolean
+modest_connection_specific_smtp_window_save_server_accounts (ModestConnectionSpecificSmtpWindow *self);
+
+G_END_DECLS
+
+#endif /* __MODEST_MAEMO_CONNECTION_SPECIFIC_SMTP_WINDOW */
diff --git a/src/hildon2/modest-default-account-settings-dialog.c b/src/hildon2/modest-default-account-settings-dialog.c
new file mode 100644 (file)
index 0000000..bdfb231
--- /dev/null
@@ -0,0 +1,1566 @@
+/* Copyright (c) 2008, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <glib/gi18n.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkmessagedialog.h>
+#include <gtk/gtkstock.h>
+#include "modest-hildon-includes.h"
+#include "modest-default-account-settings-dialog.h"
+#include "modest-account-mgr.h"
+#include "widgets/modest-serversecurity-combo-box.h"
+#include "widgets/modest-secureauth-combo-box.h"
+#include "widgets/modest-validating-entry.h"
+#include "widgets/modest-retrieve-combo-box.h"
+#include "widgets/modest-limit-retrieve-combo-box.h"
+#include "modest-text-utils.h"
+#include "modest-account-mgr.h"
+#include "modest-account-mgr-helpers.h" /* For modest_account_mgr_get_account_data(). */
+#include <modest-server-account-settings.h>
+#include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
+#include "maemo/modest-connection-specific-smtp-window.h"
+#include "maemo/modest-signature-editor-dialog.h"
+#include <modest-utils.h>
+#include <modest-defs.h>
+#include "maemo/modest-maemo-utils.h"
+#include "maemo/modest-maemo-security-options-view.h"
+#include "widgets/modest-ui-constants.h"
+#include <tny-account.h>
+#include <tny-status.h>
+
+#include <gconf/gconf-client.h>
+#include <string.h> /* For strlen(). */
+
+/* Include config.h so that _() works: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define PORT_MIN 1
+#define PORT_MAX 65535
+
+static void modest_account_settings_dialog_init (gpointer g, gpointer iface_data);
+
+G_DEFINE_TYPE_EXTENDED (ModestDefaultAccountSettingsDialog, 
+                        modest_default_account_settings_dialog, 
+                        GTK_TYPE_DIALOG,
+                        0, 
+                        G_IMPLEMENT_INTERFACE (MODEST_TYPE_ACCOUNT_SETTINGS_DIALOG, 
+                                               modest_account_settings_dialog_init));
+
+#define MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), MODEST_TYPE_DEFAULT_ACCOUNT_SETTINGS_DIALOG, ModestDefaultAccountSettingsDialogPrivate))
+
+typedef struct _ModestDefaultAccountSettingsDialogPrivate ModestDefaultAccountSettingsDialogPrivate;
+
+struct _ModestDefaultAccountSettingsDialogPrivate
+{
+       /* Used by derived widgets to query existing accounts,
+        * and to create new accounts: */
+       ModestAccountMgr *account_manager;
+       ModestAccountSettings *settings;
+       
+       gboolean modified;
+       gchar * account_name; /* This may not change. It is not user visible. */
+       ModestProtocolType incoming_protocol; /* This may not change. */
+       ModestProtocolType outgoing_protocol; /* This may not change. */
+       gchar * original_account_title;
+
+       ModestProtocolType protocol_authentication_incoming;
+       
+       GtkNotebook *notebook;
+       
+       GtkWidget *page_account_details;
+       GtkWidget *entry_account_title;
+       GtkWidget *combo_retrieve;
+       GtkWidget *combo_limit_retrieve;
+       GtkWidget *caption_leave_messages;
+       GtkWidget *checkbox_leave_messages;
+       
+       GtkWidget *page_user_details;
+       GtkWidget *entry_user_name;
+       GtkWidget *entry_user_username;
+       GtkWidget *entry_user_password;
+       GtkWidget *entry_user_email;
+/*     GtkWidget *entry_incoming_port; */
+       GtkWidget *button_signature;
+       
+       GtkWidget *page_complete_easysetup;
+       
+       GtkWidget *page_incoming;
+       GtkWidget *caption_incoming;
+       GtkWidget *entry_incomingserver;
+/*     GtkWidget *combo_incoming_security; */
+/*     GtkWidget *checkbox_incoming_auth; */
+
+       GtkWidget *page_outgoing;
+       GtkWidget *entry_outgoingserver;
+/*     GtkWidget *caption_outgoing_username; */
+/*     GtkWidget *entry_outgoing_username; */
+/*     GtkWidget *caption_outgoing_password; */
+/*     GtkWidget *entry_outgoing_password; */
+/*     GtkWidget *combo_outgoing_security; */
+/*     GtkWidget *combo_outgoing_auth; */
+/*     GtkWidget *entry_outgoing_port; */
+       GtkWidget *checkbox_outgoing_smtp_specific;
+       GtkWidget *button_outgoing_smtp_servers;
+       
+       GtkWidget *signature_dialog;
+
+       GtkWidget *incoming_security;
+       GtkWidget *outgoing_security;
+};
+
+static void
+enable_buttons (ModestDefaultAccountSettingsDialog *self);
+
+static gboolean
+save_configuration (ModestDefaultAccountSettingsDialog *dialog);
+
+static const gchar * null_means_empty (const gchar * str);
+
+static const gchar *
+null_means_empty (const gchar * str)
+{
+       return str ? str : "";
+}
+
+static void
+modest_default_account_settings_dialog_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->dispose)
+               G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->dispose (object);
+}
+
+static void
+modest_default_account_settings_dialog_finalize (GObject *object)
+{
+       ModestDefaultAccountSettingsDialog *self;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (object);
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       
+       if (priv->account_name)
+               g_free (priv->account_name);
+               
+       if (priv->original_account_title)
+               g_free (priv->original_account_title);
+               
+       if (priv->account_manager)
+               g_object_unref (G_OBJECT (priv->account_manager));
+               
+       if (priv->signature_dialog)
+               gtk_widget_destroy (priv->signature_dialog);
+
+       if (priv->settings) {
+               g_object_unref (priv->settings);
+               priv->settings = NULL;
+       }
+       
+       G_OBJECT_CLASS (modest_default_account_settings_dialog_parent_class)->finalize (object);
+}
+
+static void 
+set_modified (ModestDefaultAccountSettingsDialog *self, gboolean modified)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       priv->modified = modified;
+}
+
+static void
+on_modified_combobox_changed (GtkComboBox *widget, gpointer user_data)
+{
+       set_modified (MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data), TRUE);
+}
+
+static void
+on_modified_entry_changed (GtkEditable *editable, gpointer user_data)
+{
+       set_modified (MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data), TRUE);
+}
+
+static void
+on_modified_checkbox_toggled (GtkToggleButton *togglebutton, gpointer user_data)
+{
+       set_modified (MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data), TRUE);
+}
+
+static void
+on_modified_number_editor_changed (HildonNumberEditor *number_editor, gint new_value, gpointer user_data)
+{
+       set_modified (MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data), TRUE);
+}
+
+static void       
+on_number_editor_notify (HildonNumberEditor *editor, GParamSpec *arg1, gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog *dialog = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data);
+       gint value = hildon_number_editor_get_value (editor);
+
+       gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, value > 0);
+}
+
+/* Set a modified boolean whenever the widget is changed, 
+ * so we can check for it later.
+ */
+static void
+connect_for_modified (ModestDefaultAccountSettingsDialog *self, GtkWidget *widget)
+{
+       if (HILDON_IS_NUMBER_EDITOR (widget)) {
+               g_signal_connect (G_OBJECT (widget), "notify::value",
+                       G_CALLBACK (on_modified_number_editor_changed), self);
+               g_signal_connect (G_OBJECT (widget), "notify", G_CALLBACK (on_number_editor_notify), self);
+       }
+       else if (GTK_IS_ENTRY (widget)) {
+               g_signal_connect (G_OBJECT (widget), "changed",
+                       G_CALLBACK (on_modified_entry_changed), self);
+       } else if (GTK_IS_COMBO_BOX (widget)) {
+               g_signal_connect (G_OBJECT (widget), "changed",
+                       G_CALLBACK (on_modified_combobox_changed), self);       
+       } else if (GTK_IS_TOGGLE_BUTTON (widget)) {
+               g_signal_connect (G_OBJECT (widget), "toggled",
+                       G_CALLBACK (on_modified_checkbox_toggled), self);
+       }
+}
+
+static void
+on_caption_entry_changed (GtkEditable *editable, gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog *self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data);
+       g_assert(self);
+       enable_buttons(self);
+}
+
+static void
+on_caption_combobox_changed (GtkComboBox *widget, gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog *self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data);
+       g_assert(self);
+       enable_buttons(self);
+}
+
+/** This is a convenience function to create a caption containing a mandatory widget.
+ * When the widget is edited, the enable_buttons() vfunc will be called.
+ */
+static GtkWidget* 
+create_caption_new_with_asterisk(ModestDefaultAccountSettingsDialog *self,
+       GtkSizeGroup *group,
+       const gchar *value,
+       GtkWidget *control,
+       GtkWidget *icon,
+       HildonCaptionStatus flag)
+{
+       GtkWidget *caption = NULL;
+  
+       /* Note: Previously, the translated strings already contained the "*",
+        * Comment out this code if they do again.
+        */
+       /* Add a * character to indicate mandatory fields,
+        * as specified in our "Email UI Specification": */
+       if (flag == HILDON_CAPTION_MANDATORY) {
+               gchar* title = g_strdup_printf("%s*", value);
+               caption = hildon_caption_new (group, title, control, icon, flag);       
+               g_free(title);
+       }       
+       else
+               caption = hildon_caption_new (group, value, control, icon, flag);
+
+       /* Connect to the appropriate changed signal for the widget, 
+        * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
+        */
+       if (GTK_IS_ENTRY (control)) {
+               g_signal_connect (G_OBJECT (control), "changed",
+               G_CALLBACK (on_caption_entry_changed), self);
+               
+       }
+       else if (GTK_IS_COMBO_BOX (control)) {
+               g_signal_connect (G_OBJECT (control), "changed",
+               G_CALLBACK (on_caption_combobox_changed), self);
+       }
+        
+       return caption;
+}
+
+static void
+on_entry_invalid_account_title_character (ModestValidatingEntry *self, const gchar* character, gpointer user_data)
+{
+       gchar *tmp, *msg;
+                       
+       tmp = g_strndup (account_title_forbidden_chars, ACCOUNT_TITLE_FORBIDDEN_CHARS_LENGTH);
+       msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
+
+       modest_platform_information_banner (GTK_WIDGET (self), NULL, msg);
+
+       g_free (msg);
+       g_free (tmp);
+}
+
+static void
+on_entry_invalid_fullname_character (ModestValidatingEntry *self, const gchar* character, gpointer user_data)
+{
+       gchar *tmp, *msg;
+                       
+       tmp = g_strndup (user_name_forbidden_chars, USER_NAME_FORBIDDEN_CHARS_LENGTH);
+       msg = g_strdup_printf (_CS("ckdg_ib_illegal_characters_entered"), tmp);
+
+       modest_platform_information_banner (GTK_WIDGET (self), NULL, msg);
+
+       g_free (msg);
+       g_free (tmp);
+}
+
+
+static void
+on_entry_max (ModestValidatingEntry *self, gpointer user_data)
+{
+       modest_platform_information_banner (GTK_WIDGET (self), NULL, 
+                                           _CS("ckdg_ib_maximum_characters_reached"));
+}
+
+static GtkWidget*
+create_page_account_details (ModestDefaultAccountSettingsDialog *self)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       GtkWidget *box;
+       GtkAdjustment *focus_adjustment = NULL;
+       GtkSizeGroup* sizegroup;
+       GtkWidget *scrollwin;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+       scrollwin = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
+                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+           
+       /* The description widgets: */  
+       priv->entry_account_title = GTK_WIDGET (modest_validating_entry_new ());
+       /* Do use auto-capitalization: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_account_title), 
+               HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_account_title"), 
+               priv->entry_account_title, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->entry_account_title);
+       connect_for_modified (self, priv->entry_account_title);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the account title, 
+        * as required by our UI specification: */
+       GList *list_prevent = NULL;
+       list_prevent = g_list_append (list_prevent, "\\");
+       list_prevent = g_list_append (list_prevent, "/");
+       list_prevent = g_list_append (list_prevent, ":");
+       list_prevent = g_list_append (list_prevent, "*");
+       list_prevent = g_list_append (list_prevent, "?");
+       list_prevent = g_list_append (list_prevent, "\"");
+       list_prevent = g_list_append (list_prevent, "<"); 
+       list_prevent = g_list_append (list_prevent, ">"); 
+       list_prevent = g_list_append (list_prevent, "|");
+       list_prevent = g_list_append (list_prevent, "^");       
+       modest_validating_entry_set_unallowed_characters (
+               MODEST_VALIDATING_ENTRY (priv->entry_account_title), list_prevent);
+       g_list_free (list_prevent);
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_account_title),
+                                        on_entry_invalid_account_title_character, self);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_account_title), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_account_title), 
+               on_entry_max, self);
+       
+       /* The retrieve combobox: */
+       priv->combo_retrieve = GTK_WIDGET (modest_retrieve_combo_box_new ());
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_advsetup_retrievetype"), 
+               priv->combo_retrieve, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->combo_retrieve);
+       connect_for_modified (self, priv->combo_retrieve);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The limit-retrieve combobox: */
+       priv->combo_limit_retrieve = GTK_WIDGET (modest_limit_retrieve_combo_box_new ());
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_advsetup_limit_retrieve"), 
+               priv->combo_limit_retrieve, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->combo_limit_retrieve);
+       connect_for_modified (self, priv->combo_limit_retrieve);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+
+       /* The leave-messages widgets: */
+       if(!priv->checkbox_leave_messages)
+               priv->checkbox_leave_messages = gtk_check_button_new ();
+       if (!priv->caption_leave_messages) {
+               priv->caption_leave_messages = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_advsetup_leave_on_server"), 
+                       priv->checkbox_leave_messages, NULL, HILDON_CAPTION_MANDATORY);
+       }
+                       
+       gtk_widget_show (priv->checkbox_leave_messages);
+       connect_for_modified (self, priv->checkbox_leave_messages);
+       gtk_box_pack_start (GTK_BOX (box), priv->caption_leave_messages, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (priv->caption_leave_messages);
+
+       g_object_unref (sizegroup);
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       
+       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), box);
+       gtk_widget_show (scrollwin);
+
+       focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin));
+       gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment); 
+       
+       return GTK_WIDGET (scrollwin);
+}
+
+static gchar*
+get_entered_account_title (ModestDefaultAccountSettingsDialog *dialog)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       const gchar* account_title;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
+       account_title = gtk_entry_get_text (GTK_ENTRY (priv->entry_account_title));
+
+       if (!account_title || (strlen (account_title) == 0))
+               return NULL;
+       else {
+               /* Strip it of whitespace at the start and end: */
+               gchar *result = g_strdup (account_title);
+               result = g_strstrip (result);
+               
+               if (!result)
+                       return NULL;
+                       
+               if (strlen (result) == 0) {
+                       g_free (result);
+                       return NULL;    
+               }
+               
+               return result;
+       }
+}
+
+
+static void
+on_button_signature (GtkButton *button, gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog *self;
+       gint response;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data);
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       /* Create the window, if necessary: */
+       if (!(priv->signature_dialog)) {
+               priv->signature_dialog = GTK_WIDGET (modest_signature_editor_dialog_new ());
+       
+               gboolean use_signature = modest_account_settings_get_use_signature (priv->settings);
+               const gchar *signature = modest_account_settings_get_signature(priv->settings);
+               gchar* account_title = get_entered_account_title (self);
+               modest_signature_editor_dialog_set_settings (
+                       MODEST_SIGNATURE_EDITOR_DIALOG (priv->signature_dialog), 
+                       use_signature, signature, account_title);
+
+               g_free (account_title);
+               account_title = NULL;
+               signature = NULL;
+       }
+
+       /* Show the window: */  
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (),
+                                    GTK_WINDOW (priv->signature_dialog));
+
+       response = gtk_dialog_run (GTK_DIALOG (priv->signature_dialog));
+       gtk_widget_hide (priv->signature_dialog);
+       if (response != GTK_RESPONSE_OK) {
+               /* Destroy the widget now, and its data: */
+               gtk_widget_destroy (priv->signature_dialog);
+               priv->signature_dialog = NULL;
+       } else {
+               /* Mark modified, so we use the dialog's data later: */
+               priv->modified = TRUE;  
+       }
+}
+
+static GtkWidget*
+create_page_user_details (ModestDefaultAccountSettingsDialog *self)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       GtkWidget *box;
+       GtkAdjustment *focus_adjustment = NULL;
+       GtkSizeGroup* sizegroup;
+       GtkWidget *scrollwin;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+       scrollwin = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrollwin),
+                                       GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+        
+       /* The name widgets: */
+       priv->entry_user_name = GTK_WIDGET (modest_validating_entry_new ());
+
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_name), HILDON_GTK_INPUT_MODE_FULL);
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_name), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_name), 
+               on_entry_max, self);
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
+               _("mcen_li_emailsetup_name"), priv->entry_user_name, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->entry_user_name);
+       connect_for_modified (self, priv->entry_user_name);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+
+
+       /* Prevent the use of some characters in the name, 
+        * as required by our UI specification: */
+       GList *list_prevent = NULL;
+       list_prevent = g_list_append (list_prevent, "<");
+       list_prevent = g_list_append (list_prevent, ">");
+       modest_validating_entry_set_unallowed_characters (
+               MODEST_VALIDATING_ENTRY (priv->entry_user_name), list_prevent);
+       g_list_free (list_prevent);
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_name),
+                                        on_entry_invalid_fullname_character, self);
+       
+       /* The username widgets: */     
+       priv->entry_user_username = GTK_WIDGET (modest_validating_entry_new ());
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_username), HILDON_GTK_INPUT_MODE_FULL);
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mail_fi_username"), 
+               priv->entry_user_username, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->entry_user_username);
+       connect_for_modified (self, priv->entry_user_username);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the username, 
+        * as required by our UI specification: */
+       modest_validating_entry_set_unallowed_characters_whitespace (
+               MODEST_VALIDATING_ENTRY (priv->entry_user_username));
+       modest_validating_entry_set_func (MODEST_VALIDATING_ENTRY (priv->entry_user_username), 
+                                         modest_utils_on_entry_invalid_character, 
+                                         self);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_username), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_username), 
+               on_entry_max, self);
+       
+       /* The password widgets: */     
+       priv->entry_user_password = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_password), 
+               HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
+       gtk_entry_set_visibility (GTK_ENTRY (priv->entry_user_password), FALSE);
+       /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_user_password), '*'); */
+       caption = create_caption_new_with_asterisk (self, sizegroup, 
+               _("mail_fi_password"), priv->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->entry_user_password);
+       connect_for_modified (self, priv->entry_user_password);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The email address widgets: */        
+       priv->entry_user_email = GTK_WIDGET (modest_validating_entry_new ());
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_email), HILDON_GTK_INPUT_MODE_FULL);
+       caption = create_caption_new_with_asterisk (self, sizegroup, 
+               _("mcen_li_emailsetup_email_address"), priv->entry_user_email, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_entry_set_text (GTK_ENTRY (priv->entry_user_email), MODEST_EXAMPLE_EMAIL_ADDRESS); /* Default text. */
+       gtk_widget_show (priv->entry_user_email);
+       connect_for_modified (self, priv->entry_user_email);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_email), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_email), 
+               on_entry_max, self);
+       
+       /* Signature button: */
+       if (!priv->button_signature)
+               priv->button_signature = gtk_button_new_with_label (_("mcen_bd_edit"));
+       caption = hildon_caption_new (sizegroup, _("mcen_fi_email_signature"), 
+               priv->button_signature, NULL, HILDON_CAPTION_OPTIONAL);
+       hildon_caption_set_child_expand (HILDON_CAPTION (caption), FALSE);
+       gtk_widget_show (priv->button_signature);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+
+       g_object_unref (sizegroup);
+               
+       g_signal_connect (G_OBJECT (priv->button_signature), "clicked",
+               G_CALLBACK (on_button_signature), self);
+               
+       gtk_widget_show (GTK_WIDGET (box));
+       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrollwin), box);
+       gtk_widget_show (scrollwin);
+
+       focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin));
+       gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment); 
+       
+       return GTK_WIDGET (scrollwin);
+}
+
+/* Change the caption title for the incoming server */
+static void
+update_incoming_server_title (ModestDefaultAccountSettingsDialog *self,
+                             ModestProtocolType protocol_type)
+{
+       ModestProtocolRegistry *protocol_registry;
+       ModestProtocol *protocol;
+       const gchar *protocol_display_name;
+       gchar* incomingserver_title;
+       gchar *with_asterisk;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       protocol_registry = modest_runtime_get_protocol_registry ();
+       protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, protocol_type);
+       protocol_display_name = modest_protocol_get_display_name (protocol);
+       incomingserver_title = g_strdup_printf(_("mcen_li_emailsetup_servertype"), 
+                                              protocol_display_name);
+       
+       /* This is a mandatory field, so add a *. This is usually done by
+        * create_caption_new_with_asterisk() but we can't use that here. */
+       with_asterisk = g_strconcat (incomingserver_title, "*", NULL);
+       g_free (incomingserver_title);
+       
+       g_object_set (G_OBJECT (priv->caption_incoming), "label", with_asterisk, NULL);
+       g_free (with_asterisk);
+}
+
+/** Change the caption title for the incoming server, 
+ * as specified in the UI spec:
+ */
+/* static void  */
+/* update_incoming_server_security_choices (ModestDefaultAccountSettingsDialog *self,  */
+/*                                      ModestProtocolType protocol) */
+/* { */
+/*     /\* Fill the combo with appropriately titled choices for POP or IMAP. *\/ */
+/*     /\* The choices are the same, but the titles are different, as in the UI spec. *\/ */
+/*     modest_serversecurity_combo_box_fill ( */
+/*             MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security), protocol); */
+/* } */
+           
+static GtkWidget* 
+create_page_incoming (ModestDefaultAccountSettingsDialog *self)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       GtkWidget *box;
+       GtkSizeGroup *sizegroup;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE); 
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The incoming server widgets: */
+       if(!priv->entry_incomingserver)
+               priv->entry_incomingserver = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_incomingserver), HILDON_GTK_INPUT_MODE_FULL);
+
+       if (priv->caption_incoming)
+               gtk_widget_destroy (priv->caption_incoming);
+          
+       /* The caption title will be updated in update_incoming_server_title().
+        * so this default text will never be seen: */
+       /* (Note: Changing the title seems pointless. murrayc) */
+       priv->caption_incoming = create_caption_new_with_asterisk (self, sizegroup, 
+               "Incoming Server", priv->entry_incomingserver, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->entry_incomingserver);
+       connect_for_modified (self, priv->entry_incomingserver);
+       gtk_box_pack_start (GTK_BOX (box), priv->caption_incoming, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (priv->caption_incoming);
+
+       /* Incoming security widgets */
+       priv->incoming_security = 
+               modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_INCOMING,
+                                                       TRUE, sizegroup);
+       gtk_box_pack_start (GTK_BOX (box), priv->incoming_security, 
+                           FALSE, FALSE, MODEST_MARGIN_HALF);
+
+       gtk_widget_show (priv->incoming_security);
+
+       g_object_unref (sizegroup);     
+       gtk_widget_show (GTK_WIDGET (box));
+       
+       return GTK_WIDGET (box);
+}
+
+static void
+on_toggle_button_changed (GtkToggleButton *togglebutton, gpointer user_data)
+{
+       GtkWidget *widget = GTK_WIDGET (user_data);
+       
+       /* Enable the widget only if the toggle button is active: */
+       const gboolean enable = gtk_toggle_button_get_active (togglebutton);
+       gtk_widget_set_sensitive (widget, enable);
+}
+
+/* Make the sensitivity of a widget depend on a toggle button.
+ */
+static void
+enable_widget_for_togglebutton (GtkWidget *widget, GtkToggleButton* button)
+{
+       g_signal_connect (G_OBJECT (button), "toggled",
+               G_CALLBACK (on_toggle_button_changed), widget);
+       
+       /* Set the starting sensitivity: */
+       on_toggle_button_changed (button, widget);
+}
+
+static void
+on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog * self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data);
+       ModestConnectionSpecificSmtpWindow *smtp_win;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       /* Create the window if necessary: */
+       smtp_win = modest_connection_specific_smtp_window_new ();
+       modest_connection_specific_smtp_window_fill_with_connections (smtp_win, priv->account_manager);
+
+       /* Show the window: */  
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (smtp_win));
+       gtk_widget_show (GTK_WIDGET (smtp_win));
+       priv->modified = TRUE;
+}
+
+/* static void */
+/* on_combo_outgoing_auth_changed (GtkComboBox *widget, gpointer user_data) */
+/* { */
+/*     ModestDefaultAccountSettingsDialog *self; */
+/*     ModestProtocolRegistry *protocol_registry; */
+/*     ModestProtocolType protocol_security;    */
+/*     gboolean secureauth_used; */
+
+/*     self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data); */
+/*     protocol_registry = modest_runtime_get_protocol_registry (); */
+       
+/*     protocol_security =  */
+/*             modest_secureauth_combo_box_get_active_secureauth ( */
+/*                     MODEST_SECUREAUTH_COMBO_BOX (priv->combo_outgoing_auth)); */
+/*     secureauth_used = modest_protocol_registry_protocol_type_is_secure (protocol_registry, protocol_security); */
+       
+/*     gtk_widget_set_sensitive (priv->caption_outgoing_username, secureauth_used); */
+/*     gtk_widget_set_sensitive (priv->caption_outgoing_password, secureauth_used); */
+/* } */
+
+/* static void */
+/* on_combo_outgoing_security_changed (GtkComboBox *widget, gpointer user_data) */
+/* { */
+/*     ModestDefaultAccountSettingsDialog *self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (user_data); */
+       
+/*     const gint port_number =  */
+/*             modest_serversecurity_combo_box_get_active_serversecurity_port ( */
+/*                     MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_outgoing_security)); */
+
+/*     if(port_number != 0) { */
+/*             hildon_number_editor_set_value ( */
+/*                     HILDON_NUMBER_EDITOR (priv->entry_outgoing_port), port_number); */
+/*     }                */
+/* } */
+
+static void
+on_missing_mandatory_data (ModestSecurityOptionsView *security_view,
+                          gboolean missing,
+                          gpointer user_data)
+{
+       /* Disable the OK button */
+       gtk_dialog_set_response_sensitive (GTK_DIALOG (user_data),
+                                          GTK_RESPONSE_OK,
+                                          !missing);
+}
+
+static GtkWidget* 
+create_page_outgoing (ModestDefaultAccountSettingsDialog *self)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       GtkAdjustment *focus_adjustment = NULL;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       
+       /* Put it all in a scrolled window, so that all widgets can be 
+        * accessed even when the on-screen keyboard is visible: */
+       GtkWidget *scrollwin = gtk_scrolled_window_new(NULL, NULL);
+       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwin), 
+               GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+       
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The outgoing server widgets: */
+       if (!priv->entry_outgoingserver)
+               priv->entry_outgoingserver = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_outgoingserver), HILDON_GTK_INPUT_MODE_FULL);
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
+               _("mcen_li_emailsetup_smtp"), priv->entry_outgoingserver, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->entry_outgoingserver);
+       connect_for_modified (self, priv->entry_outgoingserver);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+
+       /* Outgoing security widgets */
+       priv->outgoing_security = 
+               modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_OUTGOING,
+                                                       TRUE, sizegroup);
+       gtk_box_pack_start (GTK_BOX (box), priv->outgoing_security, 
+                           FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (priv->outgoing_security);
+       g_signal_connect (priv->outgoing_security, "missing-mandatory-data",
+                         G_CALLBACK (on_missing_mandatory_data), self);
+
+       GtkWidget *separator = gtk_hseparator_new ();
+       gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (separator);
+       
+       /* connection-specific checkbox: */
+       if (!priv->checkbox_outgoing_smtp_specific) {
+               priv->checkbox_outgoing_smtp_specific = gtk_check_button_new ();
+               gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific), 
+                       FALSE);
+       }
+       caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_connection_smtp"), 
+               priv->checkbox_outgoing_smtp_specific, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->checkbox_outgoing_smtp_specific);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       connect_for_modified (self, priv->checkbox_outgoing_smtp_specific);
+       
+       /* Connection-specific SMTP-Severs Edit button: */
+       if (!priv->button_outgoing_smtp_servers)
+               priv->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_edit"));
+       caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_optional_smtp"), 
+               priv->button_outgoing_smtp_servers, NULL, HILDON_CAPTION_OPTIONAL);
+       hildon_caption_set_child_expand (HILDON_CAPTION (caption), FALSE);
+       gtk_widget_show (priv->button_outgoing_smtp_servers);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Only enable the button when the checkbox is checked: */
+       enable_widget_for_togglebutton (priv->button_outgoing_smtp_servers, 
+               GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific));
+
+       g_object_unref (sizegroup);
+               
+       g_signal_connect (G_OBJECT (priv->button_outgoing_smtp_servers), "clicked",
+               G_CALLBACK (on_button_outgoing_smtp_servers), self);
+               
+       gtk_widget_show (GTK_WIDGET (box));
+       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW(scrollwin), box);
+       gtk_widget_show(scrollwin);
+
+       focus_adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrollwin));
+       gtk_container_set_focus_vadjustment (GTK_CONTAINER (box), focus_adjustment);
+       
+       return GTK_WIDGET (scrollwin);
+}
+       
+static gboolean
+check_data (ModestDefaultAccountSettingsDialog *self)
+{
+       gchar* account_title;
+       const gchar* email_address; 
+       const gchar* hostname;
+       const gchar* hostname2;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+
+       /* Check that the title is not already in use: */
+       account_title = get_entered_account_title (self);
+       if (!account_title)
+               return FALSE; /* Should be prevented already anyway. */
+               
+       if (strcmp(account_title, priv->original_account_title) != 0) {
+               gboolean name_in_use; 
+
+               /* Check the changed title: */
+               name_in_use = modest_account_mgr_account_with_display_name_exists (priv->account_manager,
+                                                                                  account_title);
+               
+               if (name_in_use) {
+                       /* Warn the user via a dialog: */
+                       modest_platform_information_banner(NULL, NULL, _("mail_ib_account_name_already_existing"));
+                       
+                       g_free (account_title);
+                       return FALSE;
+               }
+       }
+       
+       g_free (account_title);
+       account_title  = NULL;
+
+       /* Check that the email address is valid: */
+       email_address = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_email));
+       if ((!email_address) || (strlen(email_address) == 0)) {
+               return FALSE;
+       }
+                       
+       if (!modest_text_utils_validate_email_address (email_address, NULL)) {
+               /* Warn the user via a dialog: */
+               modest_platform_information_banner (NULL, NULL, _("mcen_ib_invalid_email"));
+                                         
+               /* Return focus to the email address entry: */
+               gtk_widget_grab_focus (priv->entry_user_email);
+               gtk_editable_select_region (GTK_EDITABLE (priv->entry_user_email), 0, -1);
+               return FALSE;
+       }
+
+       /* make sure the domain name for the incoming server is valid */
+       hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_incomingserver));
+       if ((!hostname) || (strlen(hostname) == 0)) {
+               return FALSE;
+       }
+       
+       if (!modest_text_utils_validate_domain_name (hostname)) {
+               /* Warn the user via a dialog: */
+               modest_platform_information_banner (NULL, NULL, _("mcen_ib_invalid_servername"));
+                                         
+               /* Return focus to the email address entry: */
+               gtk_widget_grab_focus (priv->entry_incomingserver);
+               gtk_editable_select_region (GTK_EDITABLE (priv->entry_incomingserver), 0, -1);
+               return FALSE;
+       }
+
+       /* make sure the domain name for the outgoing server is valid */
+       hostname2 = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
+       if ((!hostname2) || (strlen(hostname2) == 0)) {
+               return FALSE;
+       }
+       
+       if (!modest_text_utils_validate_domain_name (hostname2)) {
+               /* Warn the user via a dialog: */
+               modest_platform_information_banner (priv->entry_outgoingserver, NULL, _("mcen_ib_invalid_servername"));
+
+               /* Return focus to the email address entry: */
+               gtk_widget_grab_focus (priv->entry_outgoingserver);
+               gtk_editable_select_region (GTK_EDITABLE (priv->entry_outgoingserver), 0, -1);
+               return FALSE;
+       }
+       
+/*     /\* Find a suitable authentication method when secure authentication is desired *\/ */
+/*     port_num = hildon_number_editor_get_value ( */
+/*             HILDON_NUMBER_EDITOR (priv->entry_incoming_port)); */
+/*     username = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_username)); */
+
+/*     protocol_registry = modest_runtime_get_protocol_registry (); */
+
+/*     protocol_security_incoming = modest_serversecurity_combo_box_get_active_serversecurity ( */
+/*             MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security)); */
+/*     if (!modest_protocol_registry_protocol_type_is_secure(protocol_registry, protocol_security_incoming)) */
+/*     { */
+/*             if (gtk_toggle_button_get_active ( */
+/*                             GTK_TOGGLE_BUTTON (priv->checkbox_incoming_auth))) { */
+/*                     GError *error = NULL; */
+/*                     GList *list_auth_methods; */
+
+/*                     list_auth_methods =  */
+/*                             modest_utils_get_supported_secure_authentication_methods (priv->incoming_protocol,  */
+/*                                                                                       hostname, port_num, username, GTK_WINDOW (self), &error); */
+/*                     if (list_auth_methods) { */
+/*                             GList* method; */
+
+/*                             /\* Use the first supported method. */
+/*                              * TODO: Should we prioritize them, to prefer a particular one? *\/ */
+/*                             for (method = list_auth_methods; method != NULL; method = g_list_next(method)) */
+/*                             { */
+/*                                     ModestProtocolType proto = (ModestProtocolType)(GPOINTER_TO_INT(method->data)); */
+/*                                     // Allow secure methods, e.g MD5 only */
+/*                                     if (modest_protocol_registry_protocol_type_is_secure(protocol_registry, proto)) */
+/*                                     { */
+/*                                             priv->protocol_authentication_incoming = proto; */
+/*                                             break; */
+/*                                     } */
+/*                             } */
+/*                             g_list_free (list_auth_methods); */
+/*                     } */
+
+/*                     if (list_auth_methods == NULL ||  */
+/*                         !modest_protocol_registry_protocol_type_is_secure(protocol_registry, priv->protocol_authentication_incoming)) */
+/*                     { */
+/*                             if(error == NULL || error->domain != modest_utils_get_supported_secure_authentication_error_quark() || */
+/*                                             error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED) */
+/*                                     modest_platform_information_banner(GTK_WIDGET (self), NULL,  */
+/*                                                                    _("mcen_ib_unableto_discover_auth_methods")); */
+
+/*                             if(error != NULL) */
+/*                                     g_error_free(error); */
+                                       
+/*                             /\* This is a nasty hack. jschmid. *\/ */
+/*                             /\* Don't let the dialog close *\/ */
+/*                             /\*g_signal_stop_emission_by_name (dialog, "response");*\/ */
+/*                             return FALSE; */
+/*                     } */
+/*             } */
+/*     } */
+       
+       return TRUE;
+}
+
+static void 
+on_response (GtkDialog *wizard_dialog,
+            gint response_id,
+            gpointer user_data)
+{
+       ModestDefaultAccountSettingsDialog *self = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (wizard_dialog);
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       gboolean prevent_response = FALSE, sec_changed;
+       ModestSecurityOptionsView *incoming_sec, *outgoing_sec;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       enable_buttons (self);
+
+       /* Check if security widgets changed */
+       incoming_sec = MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security);
+       outgoing_sec = MODEST_SECURITY_OPTIONS_VIEW (priv->outgoing_security);
+       sec_changed =
+               modest_security_options_view_changed (incoming_sec, priv->settings) ||
+               modest_security_options_view_changed (outgoing_sec, priv->settings);
+
+       /* Warn about unsaved changes: */
+       if (response_id == GTK_RESPONSE_CANCEL && (priv->modified || sec_changed)) {
+               GtkDialog *dialog = GTK_DIALOG (hildon_note_new_confirmation (GTK_WINDOW (self), 
+                       _("imum_nc_wizard_confirm_lose_changes")));
+               /* TODO: These button names will be ambiguous, and not specified in the UI specification. */
+                
+                const gint dialog_response = gtk_dialog_run (dialog);
+                gtk_widget_destroy (GTK_WIDGET (dialog));
+                
+               if (dialog_response != GTK_RESPONSE_OK)
+                       prevent_response = TRUE;
+       }
+       /* Check for invalid input: */
+       else if (response_id != GTK_RESPONSE_CANCEL && !check_data (self)) {
+               prevent_response = TRUE;
+       }
+               
+       if (prevent_response) {
+               /* This is a nasty hack. murrayc. */
+               /* Don't let the dialog close */
+               g_signal_stop_emission_by_name (wizard_dialog, "response");
+               return; 
+       } else {
+               modest_tny_account_store_set_send_mail_blocked (modest_runtime_get_account_store (), FALSE);
+       }
+               
+       if (response_id == GTK_RESPONSE_OK) {
+               /* Try to save the changes if modified (NB #59251): */
+               if (priv->modified || sec_changed) {
+                       if (save_configuration (self)) {
+                               /* Do not show the account-saved dialog if we are just saving this 
+                                * temporarily, because from the user's point of view it will not 
+                                * really be saved (saved + enabled) until later
+                                */
+                               if (modest_account_settings_get_account_name (priv->settings) != NULL) {
+                                       ModestServerAccountSettings *store_settings;
+                                       ModestServerAccountSettings *transport_settings;
+                                       const gchar *store_account_name;
+                                       const gchar *transport_account_name;
+
+
+                                       store_settings = modest_account_settings_get_store_settings (priv->settings);
+                                       transport_settings = modest_account_settings_get_transport_settings (priv->settings);
+                                       store_account_name = modest_server_account_settings_get_account_name (store_settings);
+                                       transport_account_name = modest_server_account_settings_get_account_name (transport_settings);
+                                       
+                                       if (store_account_name) {
+                                               modest_account_mgr_notify_account_update (priv->account_manager, 
+                                                                                         store_account_name);
+                                       }
+                                       if (transport_account_name) {
+                                               modest_account_mgr_notify_account_update (priv->account_manager, 
+                                                                                         transport_account_name);
+                                       }
+                                       g_object_unref (store_settings);
+                                       g_object_unref (transport_settings);
+                                       
+                                       modest_platform_information_banner(NULL, NULL, _("mcen_ib_advsetup_settings_saved"));
+                               }
+                       } else {
+                               modest_platform_information_banner (NULL, NULL, _("mail_ib_setting_failed"));
+                       }
+               }
+       }
+}
+
+static void
+modest_default_account_settings_dialog_init (ModestDefaultAccountSettingsDialog *self)
+{
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE(self);
+
+       priv->incoming_security = NULL;
+       priv->outgoing_security = NULL;
+
+       /* Create the notebook to be used by the GtkDialog base class:
+        * Each page of the notebook will be a page of the wizard: */
+       priv->notebook = GTK_NOTEBOOK (gtk_notebook_new());
+       priv->settings = modest_account_settings_new ();
+
+       /* Get the account manager object, 
+        * so we can check for existing accounts,
+        * and create new accounts: */
+       priv->account_manager = modest_runtime_get_account_mgr ();
+       g_assert (priv->account_manager);
+       g_object_ref (priv->account_manager);
+       
+       priv->protocol_authentication_incoming = MODEST_PROTOCOLS_AUTH_PASSWORD;
+
+    /* Create the common pages, 
+     */
+       priv->page_account_details = create_page_account_details (self);
+       priv->page_user_details = create_page_user_details (self);
+       priv->page_incoming = create_page_incoming (self);
+       priv->page_outgoing = create_page_outgoing (self);
+       
+       /* Add the notebook pages: */
+       gtk_notebook_append_page (priv->notebook, priv->page_account_details, 
+               gtk_label_new (_("mcen_ti_account_settings_account")));
+       gtk_notebook_append_page (priv->notebook, priv->page_user_details, 
+               gtk_label_new (_("mcen_ti_account_settings_userinfo")));
+       gtk_notebook_append_page (priv->notebook, priv->page_incoming,
+               gtk_label_new (_("mcen_ti_advsetup_retrieval")));
+       gtk_notebook_append_page (priv->notebook, priv->page_outgoing,
+               gtk_label_new (_("mcen_ti_advsetup_sending")));
+               
+       GtkDialog *dialog = GTK_DIALOG (self);
+       gtk_container_add (GTK_CONTAINER (dialog->vbox), GTK_WIDGET (priv->notebook));
+       gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), MODEST_MARGIN_HALF);
+       gtk_widget_show (GTK_WIDGET (priv->notebook));
+        
+    /* Add the buttons: */
+    gtk_dialog_add_button (GTK_DIALOG(self), _("mcen_bd_dialog_ok"), GTK_RESPONSE_OK);
+    gtk_dialog_add_button (GTK_DIALOG(self), _("mcen_bd_dialog_cancel"), GTK_RESPONSE_CANCEL);
+    
+    /* Connect to the dialog's response signal: */
+    /* We use connect-before 
+     * so we can stop the signal emission, 
+     * to stop the default signal handler from closing the dialog.
+     */
+    g_signal_connect (G_OBJECT (self), "response",
+            G_CALLBACK (on_response), self); 
+            
+    priv->modified = FALSE;
+
+    /* When this window is shown, hibernation should not be possible, 
+        * because there is no sensible way to save the state: */
+    modest_window_mgr_prevent_hibernation_while_window_is_shown (
+       modest_runtime_get_window_mgr (), GTK_WINDOW (self)); 
+
+    /* Prevent sending mails while editing an account, to avoid hangs on unprotected locks
+     * while sending messages causes an error dialog and we have a lock */
+    modest_tny_account_store_set_send_mail_blocked (modest_runtime_get_account_store (), TRUE);
+
+    hildon_help_dialog_help_enable (GTK_DIALOG(self), "applications_email_accountsettings",
+                                   modest_maemo_utils_get_osso_context());
+}
+
+ModestAccountSettingsDialog*
+modest_default_account_settings_dialog_new (void)
+{
+       return g_object_new (MODEST_TYPE_DEFAULT_ACCOUNT_SETTINGS_DIALOG, NULL);
+}
+
+/** Update the UI with the stored account details, so they can be edited.
+ * @account_name: Name of the account, which should contain incoming and outgoing server accounts.
+ */
+static void 
+modest_default_account_settings_dialog_load_settings (ModestAccountSettingsDialog *dialog, 
+                                                     ModestAccountSettings *settings)
+{
+       ModestServerAccountSettings *incoming_account;
+       ModestServerAccountSettings *outgoing_account;
+       ModestProtocolRegistry *protocol_registry;
+       const gchar *account_name, *server_account_name;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       gint page_num;
+       gboolean username_known;
+
+       g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS_DIALOG (dialog));
+       g_return_if_fail (MODEST_IS_ACCOUNT_SETTINGS (settings));
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
+       protocol_registry = modest_runtime_get_protocol_registry ();
+
+       incoming_account = modest_account_settings_get_store_settings (settings);
+       outgoing_account = modest_account_settings_get_transport_settings (settings);
+
+       account_name = modest_account_settings_get_account_name (settings);
+               
+       /* Save the account name so we can refer to it later: */
+       if (priv->account_name)
+               g_free (priv->account_name);
+       priv->account_name = g_strdup (account_name);
+
+       if (priv->settings)
+               g_object_unref (priv->settings);
+       priv->settings = g_object_ref (settings);
+       
+       /* Save the account title so we can refer to it if the user changes it: */
+       if (priv->original_account_title)
+               g_free (priv->original_account_title);
+       priv->original_account_title = g_strdup (modest_account_settings_get_display_name (settings));
+       
+       /* Show the account data in the widgets: */
+       
+       /* Note that we never show the non-display name in the UI.
+        * (Though the display name defaults to the non-display name at the start.) */
+       gtk_entry_set_text( GTK_ENTRY (priv->entry_account_title),
+                           null_means_empty (modest_account_settings_get_display_name (settings)));
+       gtk_entry_set_text( GTK_ENTRY (priv->entry_user_name), 
+                           null_means_empty (modest_account_settings_get_fullname (settings)));
+       gtk_entry_set_text( GTK_ENTRY (priv->entry_user_email), 
+                           null_means_empty (modest_account_settings_get_email_address (settings)));
+       modest_retrieve_combo_box_set_active_retrieve_conf (MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve), 
+                                                           modest_account_settings_get_retrieve_type (settings));
+       modest_limit_retrieve_combo_box_set_active_limit_retrieve (
+               MODEST_LIMIT_RETRIEVE_COMBO_BOX (priv->combo_limit_retrieve), 
+               modest_account_settings_get_retrieve_limit (settings));
+       
+       
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox_leave_messages), 
+                                     modest_account_settings_get_leave_messages_on_server (settings));
+       
+
+       if (incoming_account) {
+               const gchar *username, *password, *hostname, *proto_str, *account_title;
+               gchar *proto_name, *title;
+               ModestProtocolType incoming_protocol;
+
+               modest_retrieve_combo_box_fill (MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve), modest_server_account_settings_get_protocol (incoming_account));
+               
+               if (!modest_protocol_registry_protocol_type_has_leave_on_server (protocol_registry,
+                                                                                modest_server_account_settings_get_protocol (incoming_account))) {
+                       gtk_widget_hide (priv->caption_leave_messages);
+               } else {
+                       gtk_widget_show (priv->caption_leave_messages);
+               }
+
+               /* Remember this for later: */
+               incoming_protocol = modest_server_account_settings_get_protocol (incoming_account);;
+               
+               hostname = modest_server_account_settings_get_hostname (incoming_account);
+               username = modest_server_account_settings_get_username (incoming_account);
+               password = modest_server_account_settings_get_password (incoming_account);
+               gtk_entry_set_text( GTK_ENTRY (priv->entry_user_username),
+                                   null_means_empty (username));
+               gtk_entry_set_text( GTK_ENTRY (priv->entry_user_password), 
+                                   null_means_empty (password));
+                       
+               gtk_entry_set_text( GTK_ENTRY (priv->entry_incomingserver), 
+                                   null_means_empty (hostname));
+
+               /* Load security settings */
+               modest_security_options_view_load_settings (
+                           MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security), 
+                           settings);
+               gtk_widget_show (priv->incoming_security);
+                                       
+               /* Update the incoming label */
+               update_incoming_server_title (MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG (dialog), 
+                                             incoming_protocol);
+               
+               /* Set window title according to account */
+               proto_str = modest_protocol_get_display_name (modest_protocol_registry_get_protocol_by_type (protocol_registry, incoming_protocol));
+               proto_name = g_utf8_strup (proto_str, -1);
+               account_title = modest_account_settings_get_display_name(settings);
+               title = g_strdup_printf(_("mcen_ti_account_settings"), proto_name, account_title);
+               
+               gtk_window_set_title (GTK_WINDOW (dialog), title);
+
+               g_free (proto_name);
+               g_free (title);
+               g_object_unref (incoming_account);
+       }
+       
+       outgoing_account = modest_account_settings_get_transport_settings (settings);
+       if (outgoing_account) {
+               const gchar *hostname;
+               const gchar *username;
+               const gchar *password;
+               ModestProtocolType outgoing_protocol;
+
+               /* Remember this for later: */
+               outgoing_protocol = 
+                       modest_server_account_settings_get_protocol (outgoing_account);
+
+               hostname = modest_server_account_settings_get_hostname (outgoing_account);
+               username = modest_server_account_settings_get_username (outgoing_account);
+               password = modest_server_account_settings_get_password (outgoing_account);
+               gtk_entry_set_text( GTK_ENTRY (priv->entry_outgoingserver), 
+                                   null_means_empty (hostname));
+
+               /* Load security settings */
+               modest_security_options_view_load_settings (
+                           MODEST_SECURITY_OPTIONS_VIEW (priv->outgoing_security), 
+                           settings);
+               gtk_widget_show (priv->outgoing_security);
+
+               const gboolean has_specific = 
+                       modest_account_settings_get_use_connection_specific_smtp (settings);
+               gtk_toggle_button_set_active (
+                       GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific), 
+                       has_specific);
+               g_object_unref (outgoing_account);
+       }
+
+       /* Switch to user page */
+       page_num = gtk_notebook_page_num (priv->notebook,priv->page_user_details);
+       gtk_notebook_set_current_page (priv->notebook, page_num);
+
+       /* Check if we allow changes or not */
+       server_account_name = modest_server_account_settings_get_account_name (incoming_account);
+       username_known = 
+               modest_account_mgr_get_server_account_username_has_succeeded (priv->account_manager,
+                                                                             server_account_name);
+       gtk_widget_set_sensitive (priv->entry_user_username, !username_known);
+       gtk_widget_set_sensitive (priv->entry_incomingserver, !username_known);
+       modest_security_options_view_enable_changes (MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security),
+                                                    !username_known);
+
+
+       /* Unset the modified flag so we can detect changes later: */
+       priv->modified = FALSE;
+}
+
+static gboolean
+save_configuration (ModestDefaultAccountSettingsDialog *dialog)
+{
+       const gchar* user_fullname;
+       const gchar* emailaddress;
+       ModestServerAccountSettings *store_settings;
+       ModestServerAccountSettings *transport_settings;
+       ModestAccountRetrieveType retrieve_type;
+       gint retrieve_limit;
+       gboolean leave_on_server;
+       const gchar* hostname;
+       const gchar* username;
+       const gchar* password;
+       gchar* account_title;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+       const gchar* account_name;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (dialog);
+       account_name = priv->account_name;
+
+       /* Set the account data from the widgets: */
+       user_fullname = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_name));
+       modest_account_settings_set_fullname (priv->settings, user_fullname);
+       
+       emailaddress = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_email));
+       modest_account_settings_set_email_address (priv->settings, emailaddress);
+               
+       /* Signature: */
+       if (priv->signature_dialog) {
+               gboolean use_signature = FALSE;
+               gchar *signature;
+               signature = modest_signature_editor_dialog_get_settings (MODEST_SIGNATURE_EDITOR_DIALOG (priv->signature_dialog),
+                                                                        &use_signature);
+       
+               modest_account_settings_set_use_signature (priv->settings, use_signature);
+               modest_account_settings_set_signature (priv->settings, signature);
+       }
+       
+       retrieve_type = modest_retrieve_combo_box_get_active_retrieve_conf (
+               MODEST_RETRIEVE_COMBO_BOX (priv->combo_retrieve));
+       modest_account_settings_set_retrieve_type (priv->settings, retrieve_type);
+       
+       retrieve_limit = modest_limit_retrieve_combo_box_get_active_limit_retrieve (
+               MODEST_LIMIT_RETRIEVE_COMBO_BOX (priv->combo_limit_retrieve));
+       modest_account_settings_set_retrieve_limit (priv->settings, retrieve_limit);
+       
+       leave_on_server = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->checkbox_leave_messages));
+       modest_account_settings_set_leave_messages_on_server (priv->settings, leave_on_server); 
+
+       store_settings = modest_account_settings_get_store_settings (priv->settings);
+                       
+       hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_incomingserver));
+       modest_server_account_settings_set_hostname (store_settings, hostname);
+                               
+       username = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_username));
+       modest_server_account_settings_set_username (store_settings, username);
+       
+       password = gtk_entry_get_text (GTK_ENTRY (priv->entry_user_password));
+       modest_server_account_settings_set_password (store_settings, password);
+
+       /* Save security settings */
+       modest_security_options_view_save_settings (MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security), 
+                                                   priv->settings);
+
+       g_object_unref (store_settings);
+       
+       /* Outgoing: */
+       transport_settings = modest_account_settings_get_transport_settings (priv->settings);
+       
+       hostname = gtk_entry_get_text (GTK_ENTRY (priv->entry_outgoingserver));
+       modest_server_account_settings_set_hostname (transport_settings, hostname);
+                       
+       /* Save security settings */
+       modest_security_options_view_save_settings (
+           MODEST_SECURITY_OPTIONS_VIEW (priv->outgoing_security), 
+           priv->settings);
+       
+       /* Set the changed account title last, to simplify the previous code: */
+       account_title = get_entered_account_title (dialog);
+       if (!account_title)
+               return FALSE; /* Should be prevented already anyway. */
+               
+/*     if (strcmp (account_title, account_name) != 0) { */
+       modest_account_settings_set_display_name (priv->settings, account_title);
+/*     } */
+       g_free (account_title);
+       account_title = NULL;
+       
+       /* Save connection-specific SMTP server accounts: */
+       modest_account_settings_set_use_connection_specific_smtp 
+               (priv->settings, 
+                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->checkbox_outgoing_smtp_specific)));
+
+       /* this configuration is not persistent, we should not save */
+       if (account_name != NULL)
+               modest_account_mgr_save_account_settings (priv->account_manager, priv->settings);
+
+       return TRUE;
+}
+
+static gboolean entry_is_empty (GtkWidget *entry)
+{
+       if (!entry)
+               return FALSE;
+               
+       const gchar* text = gtk_entry_get_text (GTK_ENTRY (entry));
+       if ((!text) || (strlen(text) == 0))
+               return TRUE;
+       else {
+               /* Strip it of whitespace at the start and end: */
+               gchar *stripped = g_strdup (text);
+               stripped = g_strstrip (stripped);
+               
+               if (!stripped)
+                       return TRUE;
+                       
+               const gboolean result = (strlen (stripped) == 0);
+               
+               g_free (stripped);
+               return result;
+       }
+}
+
+static void
+enable_buttons (ModestDefaultAccountSettingsDialog *self)
+{
+       gboolean enable_ok = TRUE;
+       ModestProtocolRegistry *protocol_registry;
+       ModestDefaultAccountSettingsDialogPrivate *priv;
+
+       priv = MODEST_DEFAULT_ACCOUNT_SETTINGS_DIALOG_GET_PRIVATE (self);
+       
+       /* The account details title is mandatory: */
+       if (entry_is_empty(priv->entry_account_title))
+               enable_ok = FALSE;
+
+       /* The user details username is mandatory: */
+       if (enable_ok && entry_is_empty(priv->entry_user_username))
+               enable_ok = FALSE;
+               
+       /* The user details email address is mandatory: */
+       if (enable_ok && entry_is_empty (priv->entry_user_email))
+               enable_ok = FALSE;
+
+       /* The custom incoming server is mandatory: */
+       if (enable_ok && entry_is_empty(priv->entry_incomingserver))
+               enable_ok = FALSE;
+
+       /* The custom outgoing server is mandatory: */
+       if (enable_ok && entry_is_empty(priv->entry_outgoingserver))
+               enable_ok = FALSE;
+
+       protocol_registry = modest_runtime_get_protocol_registry ();
+                       
+       /* Enable the buttons, 
+        * identifying them via their associated response codes:
+        */
+       GtkDialog *dialog_base = GTK_DIALOG (self);
+       gtk_dialog_set_response_sensitive (dialog_base,
+                                          GTK_RESPONSE_OK,
+                                          enable_ok);
+}
+
+static void
+modest_default_account_settings_dialog_class_init (ModestDefaultAccountSettingsDialogClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       g_type_class_add_private (klass, sizeof (ModestDefaultAccountSettingsDialogPrivate));
+
+       object_class->dispose = modest_default_account_settings_dialog_dispose;
+       object_class->finalize = modest_default_account_settings_dialog_finalize;
+}
+
+static void 
+modest_account_settings_dialog_init (gpointer g_iface, gpointer iface_data)
+{
+       ModestAccountSettingsDialogClass *iface = (ModestAccountSettingsDialogClass *) g_iface;
+
+       iface->load_settings = modest_default_account_settings_dialog_load_settings;
+}
diff --git a/src/hildon2/modest-easysetup-country-combo-box.c b/src/hildon2/modest-easysetup-country-combo-box.c
new file mode 100644 (file)
index 0000000..683c365
--- /dev/null
@@ -0,0 +1,394 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE /* So we can use the getline() function, which is a convenient GNU extension. */
+#endif
+
+#include <stdio.h>
+
+#include "modest-maemo-utils.h"
+#include "modest-easysetup-country-combo-box.h"
+#include <gtk/gtkliststore.h>
+#include <gtk/gtkcelllayout.h>
+#include <gtk/gtkcellrenderertext.h>
+
+#include <stdlib.h>
+#include <string.h> /* For memcpy() */
+#include <langinfo.h>
+#include <locale.h>
+#include <libintl.h> /* For dgettext(). */
+
+/* Include config.h so that _() works: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define MAX_LINE_LEN 128 /* max length of a line in MCC file */
+
+#if MODEST_HILDON_API < 2
+G_DEFINE_TYPE (EasysetupCountryComboBox, easysetup_country_combo_box, GTK_TYPE_COMBO_BOX);
+#else
+G_DEFINE_TYPE (EasysetupCountryComboBox, easysetup_country_combo_box, HILDON_TYPE_PICKER_BUTTON);
+#endif
+
+typedef struct
+{
+       gint locale_mcc;
+/*     GtkTreeModel *model; */
+} ModestEasysetupCountryComboBoxPrivate;
+
+#define MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+                                                       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, \
+                                                       ModestEasysetupCountryComboBoxPrivate))
+
+static void
+easysetup_country_combo_box_get_property (GObject *object, guint property_id,
+                                                                                                                       GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_country_combo_box_set_property (GObject *object, guint property_id,
+                                                                                                                       const GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_country_combo_box_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->dispose)
+               G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->dispose (object);
+}
+
+enum MODEL_COLS {
+       MODEL_COL_NAME = 0, /* string */
+       MODEL_COL_MCC  = 1 /* the 'effective mcc' for this country */
+};
+
+       
+static void
+easysetup_country_combo_box_finalize (GObject *object)
+{
+       G_OBJECT_CLASS (easysetup_country_combo_box_parent_class)->finalize (object);
+}
+
+static void
+easysetup_country_combo_box_class_init (EasysetupCountryComboBoxClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (ModestEasysetupCountryComboBoxPrivate));
+
+       object_class->get_property = easysetup_country_combo_box_get_property;
+       object_class->set_property = easysetup_country_combo_box_set_property;
+       object_class->dispose = easysetup_country_combo_box_dispose;
+       object_class->finalize = easysetup_country_combo_box_finalize;
+}
+
+
+
+
+/* cluster mcc's, based on the list
+ * http://en.wikipedia.org/wiki/Mobile_country_code
+ */
+static int
+effective_mcc (gint mcc)
+{
+       switch (mcc) {
+       case 405: return 404; /* india */
+       case 441: return 440; /* japan */       
+       case 235: return 234; /* united kingdom */
+       case 311:
+       case 312:
+       case 313:
+       case 314:
+       case 315:
+       case 316: return 310; /* united states */
+       default:  return mcc;
+       }
+}
+
+
+/* each line is of the form:
+   xxx    logical_id
+   
+  NOTE: this function is NOT re-entrant, the out-param country
+  are static strings that should NOT be freed. and will change when
+  calling this function again
+
+  also note, this function will return the "effective mcc", which
+  is the normalized mcc for a country - ie. even if the there
+  are multiple entries for the United States with various mccs,
+  this function will always return 310, even if the real mcc parsed
+  would be 314. see the 'effective_mcc' function above.
+*/
+static int
+parse_mcc_mapping_line (const char* line,  char** country)
+{
+       int i, j;
+       char mcc[4];  /* the mcc code, always 3 bytes*/
+       static char my_country[128];
+
+       if (!line) {
+               *country = NULL;
+               return 0;
+       }
+       
+       for (i = 3, j = 0; i < 128; ++i) {
+               char kar = line[i];
+               if (kar == '\0')
+                       break;
+               else if (kar < '_')
+                       continue;
+               else 
+                       my_country [j++] = kar;
+       }
+       my_country[j] = '\0';
+
+       mcc[0] = line[0];
+       mcc[1] = line[1];
+       mcc[2] = line[2];
+       mcc[3] = '\0';
+       
+       *country = my_country;
+
+       return effective_mcc ((int) strtol ((const char*)mcc, NULL, 10));
+}
+
+/** Note that the mcc_mapping file is installed 
+ * by the operator-wizard-settings package.
+ */
+static void
+load_from_file (EasysetupCountryComboBox *self, GtkListStore *liststore)
+{
+       ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
+       
+       char line[MAX_LINE_LEN];
+       guint previous_mcc = 0;
+       gchar *territory, *fallback = NULL;
+       gchar *current_locale;
+
+       /* Get the territory specified for the current locale */
+       territory = nl_langinfo (_NL_ADDRESS_COUNTRY_NAME);
+
+       /* Tricky stuff, the translations of the OSSO countries does
+          not always correspond to the country names in locale
+          databases. Add all these cases here. sergio */
+       if (!strcmp (territory, "United Kingdom"))
+               fallback = g_strdup ("UK");
+
+       current_locale = setlocale (LC_ALL ,NULL);
+
+       FILE *file = modest_maemo_open_mcc_mapping_file ();
+       if (!file) {
+               g_warning("Could not open mcc_mapping file");
+               return;
+       }
+
+       while (fgets (line, MAX_LINE_LEN, file) != NULL) { 
+
+               int mcc;
+               char *country = NULL;
+               const gchar *name_translated, *english_translation;
+
+               mcc = parse_mcc_mapping_line (line, &country);
+               if (!country || mcc == 0) {
+                       g_warning ("%s: error parsing line: '%s'", __FUNCTION__, line);
+                       continue;
+               }
+
+               if (mcc == previous_mcc) {
+                       /* g_warning ("already seen: %s", line); */
+                       continue;
+               }
+               previous_mcc = mcc;
+
+               if (!priv->locale_mcc) {
+                       english_translation = dgettext ("osso-countries", country);
+                       if (!strcmp (english_translation, territory) ||
+                           (fallback && !strcmp (english_translation, fallback)))
+                               priv->locale_mcc = mcc;
+               }
+               name_translated = dgettext ("osso-countries", country);
+               
+               /* Add the row to the model: */
+               GtkTreeIter iter;
+               gtk_list_store_append (liststore, &iter);
+               gtk_list_store_set(liststore, &iter, MODEL_COL_MCC, mcc, MODEL_COL_NAME, name_translated, -1);
+       }       
+       fclose (file);
+
+       /* Sort the items: */
+       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (liststore), 
+                                             MODEL_COL_NAME, GTK_SORT_ASCENDING);
+
+       g_free (fallback);
+}
+
+static void
+easysetup_country_combo_box_init (EasysetupCountryComboBox *self)
+{
+       ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
+       priv->locale_mcc = 0;
+}
+
+void
+easysetup_country_combo_box_load_data(EasysetupCountryComboBox *self)
+{
+       GtkListStore *model;
+
+       /* Create a tree model for the combo box,
+        * with a string for the name, and an int for the MCC ID.
+        * This must match our MODEL_COLS enum constants.
+        */
+       model = gtk_list_store_new (2,  G_TYPE_STRING, G_TYPE_INT);
+       
+       /* Country column:
+        * The ID model column in not shown in the view. */
+       GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+       g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
+#if MODEST_HILDON_API < 2
+       gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (self), renderer, TRUE);
+       gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (self), renderer, 
+                                       "text", MODEL_COL_NAME, NULL);
+#else
+       GtkWidget *selector = hildon_touch_selector_new ();
+       hildon_picker_button_set_selector (HILDON_PICKER_BUTTON (self), HILDON_TOUCH_SELECTOR (selector));
+       hildon_touch_selector_append_column (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (self)),
+                                            GTK_TREE_MODEL (model),
+                                            renderer, "text", MODEL_COL_NAME, NULL);
+#endif
+
+       /* Fill the model with rows: */
+       load_from_file (self, model);
+
+       /* Set this _after_ loading from file, it makes loading faster */
+#if MODEST_HILDON_API < 2
+       gtk_combo_box_set_model (GTK_COMBO_BOX (self), GTK_TREE_MODEL (model));
+#else
+       hildon_touch_selector_set_model (hildon_picker_button_get_selector (HILDON_PICKER_BUTTON (self)),
+                                        0, GTK_TREE_MODEL (model));
+#endif
+}
+
+EasysetupCountryComboBox*
+easysetup_country_combo_box_new (void)
+{
+#if MODEST_HILDON_API >= 2
+       return g_object_new (MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, 
+                            "arrangement", HILDON_BUTTON_ARRANGEMENT_VERTICAL,
+                            "size", HILDON_SIZE_AUTO,
+                            NULL);
+#else
+       return g_object_new (MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, 
+                            NULL);
+#endif
+}
+
+/**
+ * Returns the MCC number of the selected country, or 0 if no country was selected. 
+ */
+gint
+easysetup_country_combo_box_get_active_country_mcc (EasysetupCountryComboBox *self)
+{
+       GtkTreeIter active;
+       gboolean found;
+
+#if MODEST_HILDON_API < 2
+       found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (self), &active);
+#else
+       found = hildon_touch_selector_get_selected (hildon_picker_button_get_selector
+                                                   (HILDON_PICKER_BUTTON (self)), 0, &active);
+#endif
+       if (found) {
+               gint mcc = 0;
+#if MODEST_HILDON_API < 2
+               gtk_tree_model_get (gtk_combo_box_get_model (GTK_COMBO_BOX (self)), 
+                                   &active, MODEL_COL_MCC, &mcc, -1);
+#else
+               gtk_tree_model_get (hildon_touch_selector_get_model (hildon_picker_button_get_selector
+                                                                    (HILDON_PICKER_BUTTON (self)), 
+                                                                    0), 
+                                   &active, MODEL_COL_MCC, &mcc, -1);
+#endif
+               return mcc;     
+       }
+       return 0; /* Failed. */
+}
+
+
+/**
+ * Selects the MCC number of the selected country.
+ * Specify 0 to select no country. 
+ */
+gboolean
+easysetup_country_combo_box_set_active_country_locale (EasysetupCountryComboBox *self)
+{
+       ModestEasysetupCountryComboBoxPrivate *priv = MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_PRIVATE (self);
+       GtkTreeIter iter;
+       gint current_mcc;
+       GtkTreeModel *model;
+
+#if MODEST_HILDON_API < 2
+       model = gtk_combo_box_get_model (GTK_COMBO_BOX (self));
+       g_message ("HILDON < 2");
+#else
+       model = hildon_touch_selector_get_model (hildon_picker_button_get_selector 
+                                                (HILDON_PICKER_BUTTON (self)), 0);
+       g_message ("HILDON >= 2");
+#endif
+       if (!gtk_tree_model_get_iter_first (model, &iter))
+               return FALSE;
+       do {
+               gtk_tree_model_get (model, &iter, MODEL_COL_MCC, &current_mcc, -1);
+               if (priv->locale_mcc == current_mcc) {
+#if MODEST_HILDON_API < 2
+                       gtk_combo_box_set_active_iter (GTK_COMBO_BOX (self), &iter);
+#else
+                       hildon_touch_selector_select_iter (hildon_picker_button_get_selector 
+                                                          (HILDON_PICKER_BUTTON (self)), 0, 
+                                                          &iter, TRUE);
+#endif
+                       return TRUE;
+               }
+       } while (gtk_tree_model_iter_next (model, &iter));
+       
+       return FALSE; /* not found */
+}
+
diff --git a/src/hildon2/modest-easysetup-country-combo-box.h b/src/hildon2/modest-easysetup-country-combo-box.h
new file mode 100644 (file)
index 0000000..56f1741
--- /dev/null
@@ -0,0 +1,93 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _MODEST_EASYSETUP_COUNTRY_COMBO_BOX
+#define _MODEST_EASYSETUP_COUNTRY_COMBO_BOX
+
+#if MODEST_HILDON_API < 2
+#include <gtk/gtkcombobox.h>
+#else
+#include <hildon/hildon-picker-button.h>
+#endif
+
+G_BEGIN_DECLS
+
+#define MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX easysetup_country_combo_box_get_type()
+
+#define MODEST_EASYSETUP_COUNTRY_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, EasysetupCountryComboBox))
+
+#define MODEST_EASYSETUP_COUNTRY_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), \
+       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, EasysetupCountryComboBoxClass))
+
+#define MODEST_EASYSETUP_IS_COUNTRY_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX))
+
+#define MODEST_EASYSETUP_IS_COUNTRY_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX))
+
+#define MODEST_EASYSETUP_COUNTRY_COMBO_BOX_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+       MODEST_EASYSETUP_TYPE_COUNTRY_COMBO_BOX, EasysetupCountryComboBoxClass))
+
+#if MODEST_HILDON_API < 2
+typedef struct {
+       GtkComboBox parent;
+} EasysetupCountryComboBox;
+
+typedef struct {
+       GtkComboBoxClass parent_class;
+} EasysetupCountryComboBoxClass;
+#else
+typedef struct {
+       HildonPickerButton parent;
+} EasysetupCountryComboBox;
+
+typedef struct {
+       HildonPickerButtonClass parent_class;
+} EasysetupCountryComboBoxClass;
+#endif
+GType easysetup_country_combo_box_get_type (void);
+
+EasysetupCountryComboBox* easysetup_country_combo_box_new (void);
+
+void easysetup_country_combo_box_load_data(EasysetupCountryComboBox *self);
+
+gint easysetup_country_combo_box_get_active_country_mcc (EasysetupCountryComboBox *self);
+
+
+gboolean easysetup_country_combo_box_set_active_country_locale (EasysetupCountryComboBox *self);
+
+G_END_DECLS
+
+#endif /* _MODEST_EASYSETUP_COUNTRY_COMBO_BOX */
diff --git a/src/hildon2/modest-easysetup-provider-combo-box.c b/src/hildon2/modest-easysetup-provider-combo-box.c
new file mode 100644 (file)
index 0000000..1147a1d
--- /dev/null
@@ -0,0 +1,332 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "modest-easysetup-provider-combo-box.h"
+#include <gtk/gtkliststore.h>
+#include <gtk/gtkcelllayout.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <glib/gi18n.h>
+#include <modest-text-utils.h>
+#include "modest-protocol-registry.h"
+#include "modest-runtime.h"
+
+#include <stdlib.h>
+#include <string.h> /* For memcpy() */
+
+/* Include config.h so that _() works: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+G_DEFINE_TYPE (EasysetupProviderComboBox, easysetup_provider_combo_box, GTK_TYPE_COMBO_BOX);
+
+#define PROVIDER_COMBO_BOX_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), EASYSETUP_TYPE_PROVIDER_COMBO_BOX, EasysetupProviderComboBoxPrivate))
+
+typedef struct _EasysetupProviderComboBoxPrivate EasysetupProviderComboBoxPrivate;
+
+struct _EasysetupProviderComboBoxPrivate
+{
+       GtkTreeModel *model;
+};
+
+static void
+easysetup_provider_combo_box_get_property (GObject *object, guint property_id,
+                                                                                                                       GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_provider_combo_box_set_property (GObject *object, guint property_id,
+                                                                                                                       const GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_provider_combo_box_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (easysetup_provider_combo_box_parent_class)->dispose)
+               G_OBJECT_CLASS (easysetup_provider_combo_box_parent_class)->dispose (object);
+}
+
+static void
+easysetup_provider_combo_box_finalize (GObject *object)
+{
+       EasysetupProviderComboBoxPrivate *priv = PROVIDER_COMBO_BOX_GET_PRIVATE (object);
+
+       g_object_unref (G_OBJECT (priv->model));
+
+       G_OBJECT_CLASS (easysetup_provider_combo_box_parent_class)->finalize (object);
+}
+
+static void
+easysetup_provider_combo_box_class_init (EasysetupProviderComboBoxClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (EasysetupProviderComboBoxPrivate));
+
+       object_class->get_property = easysetup_provider_combo_box_get_property;
+       object_class->set_property = easysetup_provider_combo_box_set_property;
+       object_class->dispose = easysetup_provider_combo_box_dispose;
+       object_class->finalize = easysetup_provider_combo_box_finalize;
+}
+
+enum MODEL_COLS {
+       MODEL_COL_ID, /* a string, not an int. */
+       MODEL_COL_NAME,
+       MODEL_COL_ID_TYPE
+};
+
+
+/*
+ * strictly, we should sort providers with mcc=0 after the other ones.... but, we don't have
+ * that info here, so ignoring for now.
+ */
+static gint
+provider_sort_func (GtkTreeModel *model, GtkTreeIter *iter1, GtkTreeIter *iter2, gpointer user_data)
+{
+       gchar *prov1, *prov2;
+       gint retval;
+       
+       gtk_tree_model_get (model, iter1, MODEL_COL_NAME, &prov1, -1);
+       gtk_tree_model_get (model, iter2, MODEL_COL_NAME, &prov2, -1);
+
+       if (strcmp (prov1, prov2) == 0) 
+               retval = 0;
+       else if (strcmp (_("mcen_va_serviceprovider_other"), prov1) == 0)
+               retval = -1;
+       else if (strcmp (_("mcen_va_serviceprovider_other"), prov2) == 0)
+               retval = 1;
+       else
+               retval = modest_text_utils_utf8_strcmp (prov1, prov2, TRUE);
+       
+       g_free (prov1);
+       g_free (prov2);
+
+       return retval;
+}
+
+static void
+easysetup_provider_combo_box_init (EasysetupProviderComboBox *self)
+{
+       EasysetupProviderComboBoxPrivate *priv = PROVIDER_COMBO_BOX_GET_PRIVATE (self);
+
+       /* Create a tree model for the combo box,
+        * with a string for the name, and a string for the ID (e.g. "vodafone.it"), and the mcc
+        * This must match our MODEL_COLS enum constants.
+        */
+       priv->model = GTK_TREE_MODEL (gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT));
+
+       /* Setup the combo box: */
+       GtkComboBox *combobox = GTK_COMBO_BOX (self);
+       gtk_combo_box_set_model (combobox, priv->model);
+
+       /* Provider column:
+        * The ID model column in not shown in the view. */
+       GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+       gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combobox), renderer, TRUE);
+       gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer,  "text", MODEL_COL_NAME, NULL);
+       
+       gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE(priv->model),
+                                             MODEL_COL_NAME, GTK_SORT_ASCENDING);
+       gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE(priv->model),
+                                         MODEL_COL_NAME,
+                                         (GtkTreeIterCompareFunc)provider_sort_func,
+                                         NULL, NULL);
+}
+
+EasysetupProviderComboBox*
+easysetup_provider_combo_box_new (void)
+{
+       return g_object_new (EASYSETUP_TYPE_PROVIDER_COMBO_BOX, NULL);
+}
+
+void
+easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, 
+                                  ModestPresets *presets,
+                                  gint mcc)
+{      
+       GtkTreeIter other_iter;
+       EasysetupProviderComboBoxPrivate *priv;
+       GtkListStore *liststore;        
+       GSList *provider_ids_used_already = NULL, *provider_protos, *tmp;
+       gchar ** provider_ids = NULL;
+       gchar ** provider_names;        
+       gchar ** iter_provider_names;
+       gchar ** iter_provider_ids;
+       ModestProtocolRegistry *registry;
+
+       g_return_if_fail (EASYSETUP_IS_PROVIDER_COMBO_BOX(combobox));
+
+       priv = PROVIDER_COMBO_BOX_GET_PRIVATE (combobox);
+       liststore = GTK_LIST_STORE (priv->model);
+       gtk_list_store_clear (liststore);
+       provider_names = modest_presets_get_providers (presets, mcc, TRUE, &provider_ids);
+
+       iter_provider_names = provider_names;
+       iter_provider_ids = provider_ids;
+
+       while(iter_provider_names && *iter_provider_names && iter_provider_ids && *iter_provider_ids) {
+               const gchar* provider_name = *iter_provider_names;
+               const gchar* provider_id = *iter_provider_ids;
+
+               /* Prevent duplicate providers: */
+               if (g_slist_find_custom (provider_ids_used_already, 
+                                        provider_id, (GCompareFunc)strcmp) == NULL) {
+                       /* printf("debug: provider_name=%s\n", provider_name); */
+
+                       /* Add the row: */
+                       GtkTreeIter iter;
+                       gtk_list_store_append (liststore, &iter);
+                       
+                       gtk_list_store_set(liststore, &iter, 
+                                          MODEL_COL_ID, provider_id, 
+                                          MODEL_COL_NAME, provider_name, 
+                                          MODEL_COL_ID_TYPE, EASYSETUP_PROVIDER_COMBO_BOX_ID_PROVIDER,
+                                          -1);
+                       
+                       provider_ids_used_already = g_slist_prepend (
+                               provider_ids_used_already, (gpointer)g_strdup (provider_id));
+               }
+               
+               ++iter_provider_names;
+               ++iter_provider_ids;
+       }
+       
+       /* Free the result of modest_presets_get_providers()
+        * as specified by its documentation: */
+       g_strfreev (provider_names);
+       g_strfreev (provider_ids);
+
+       /* Add the provider protocols */
+       registry = modest_runtime_get_protocol_registry ();
+       provider_protos = modest_protocol_registry_get_by_tag (registry, 
+                                                              MODEST_PROTOCOL_REGISTRY_PROVIDER_PROTOCOLS);
+       tmp = provider_protos;
+       while (tmp) {
+               GtkTreeIter iter;
+               ModestProtocol *proto = MODEST_PROTOCOL (tmp->data);
+               const gchar *name = modest_protocol_get_display_name (proto);
+
+               /* only add store protocols, no need to duplicate them */
+               if (modest_protocol_registry_protocol_type_has_tag (registry, 
+                                                                   modest_protocol_get_type_id (proto),
+                                                                   MODEST_PROTOCOL_REGISTRY_STORE_PROTOCOLS)) {
+                       gtk_list_store_append (liststore, &iter);
+                       gtk_list_store_set (liststore, &iter,
+                                           MODEL_COL_ID, modest_protocol_get_name (proto),
+                                           MODEL_COL_NAME, name,
+                                           MODEL_COL_ID_TYPE, EASYSETUP_PROVIDER_COMBO_BOX_ID_PLUGIN_PROTOCOL,
+                                           -1);
+               }
+               tmp = g_slist_next (tmp);
+       }
+       g_slist_free (provider_protos);
+       
+       /* Add the "Other" item: */
+       /* Note that ID 0 means "Other" for us: */
+       gtk_list_store_prepend (liststore, &other_iter);
+       gtk_list_store_set (liststore, &other_iter,
+                           MODEL_COL_ID, 0,
+                           MODEL_COL_NAME, _("mcen_va_serviceprovider_other"),
+                           MODEL_COL_ID_TYPE, EASYSETUP_PROVIDER_COMBO_BOX_ID_OTHER,
+                           -1);
+
+       /* Select the "Other" item: */
+       gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combobox), &other_iter);
+       
+       g_slist_foreach (provider_ids_used_already, (GFunc)g_free, NULL);
+       g_slist_free (provider_ids_used_already);
+}
+
+/**
+ * Returns the MCC number of the selected provider, 
+ * or NULL if no provider was selected, or "Other" was selected. 
+ */
+gchar*
+easysetup_provider_combo_box_get_active_provider_id (EasysetupProviderComboBox *combobox)
+{
+       GtkTreeIter active;
+
+       g_return_val_if_fail (EASYSETUP_IS_PROVIDER_COMBO_BOX(combobox), NULL);
+
+       const gboolean found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &active);
+       if (found) {
+               EasysetupProviderComboBoxPrivate *priv = PROVIDER_COMBO_BOX_GET_PRIVATE (combobox);
+
+               gchar *id = NULL;
+               gtk_tree_model_get (priv->model, &active, MODEL_COL_ID, &id, -1);
+               return g_strdup(id);    
+       }
+
+       return NULL; /* Failed. */
+}
+
+void 
+easysetup_provider_combo_box_set_others_provider (EasysetupProviderComboBox *combobox)
+{
+       GtkTreeModel *model;
+       GtkTreeIter others_iter;
+
+       g_return_if_fail (EASYSETUP_IS_PROVIDER_COMBO_BOX(combobox));
+       
+       model = gtk_combo_box_get_model (GTK_COMBO_BOX (combobox));
+       
+       if (gtk_tree_model_get_iter_first (model, &others_iter))
+               gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combobox), &others_iter);
+}
+
+EasysetupProviderComboBoxIdType 
+easysetup_provider_combo_box_get_active_id_type (EasysetupProviderComboBox *combobox)
+{
+       GtkTreeIter active;
+
+       g_return_val_if_fail (EASYSETUP_IS_PROVIDER_COMBO_BOX (combobox), 
+                             EASYSETUP_PROVIDER_COMBO_BOX_ID_OTHER);
+
+       if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &active)) {
+               EasysetupProviderComboBoxPrivate *priv = PROVIDER_COMBO_BOX_GET_PRIVATE (combobox);
+               EasysetupProviderComboBoxIdType id_type;
+
+               gtk_tree_model_get (priv->model, &active, MODEL_COL_ID_TYPE, &id_type, -1);
+               return id_type; 
+       } else {
+               /* Fallback to other */
+               return EASYSETUP_PROVIDER_COMBO_BOX_ID_OTHER;
+       }
+}
diff --git a/src/hildon2/modest-easysetup-provider-combo-box.h b/src/hildon2/modest-easysetup-provider-combo-box.h
new file mode 100644 (file)
index 0000000..d4bc283
--- /dev/null
@@ -0,0 +1,96 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _EASYSETUP_PROVIDER_COMBO_BOX
+#define _EASYSETUP_PROVIDER_COMBO_BOX
+
+#include <gtk/gtkcombobox.h>
+#include "modest-presets.h"
+
+G_BEGIN_DECLS
+
+#define EASYSETUP_TYPE_PROVIDER_COMBO_BOX easysetup_provider_combo_box_get_type()
+
+#define EASYSETUP_PROVIDER_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+       EASYSETUP_TYPE_PROVIDER_COMBO_BOX, EasysetupProviderComboBox))
+
+#define EASYSETUP_PROVIDER_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), \
+       EASYSETUP_TYPE_PROVIDER_COMBO_BOX, EasysetupProviderComboBoxClass))
+
+#define EASYSETUP_IS_PROVIDER_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+       EASYSETUP_TYPE_PROVIDER_COMBO_BOX))
+
+#define EASYSETUP_IS_PROVIDER_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+       EASYSETUP_TYPE_PROVIDER_COMBO_BOX))
+
+#define EASYSETUP_PROVIDER_COMBO_BOX_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+       EASYSETUP_TYPE_PROVIDER_COMBO_BOX, EasysetupProviderComboBoxClass))
+
+/** The thype of the ID
+ *
+ * this means the value of returned by get_active_provider_id will be
+ * different depending on the value returned by get_active_id_type
+ *
+ * If the selected option is a provider then the ID will be the provider ID
+ * If the selected option is "Other..." the the ID will be 0
+ * If the selected option is a provider protocol () the the ID will be protocol name
+ **/
+typedef enum {
+       EASYSETUP_PROVIDER_COMBO_BOX_ID_PROVIDER,
+       EASYSETUP_PROVIDER_COMBO_BOX_ID_OTHER,
+       EASYSETUP_PROVIDER_COMBO_BOX_ID_PLUGIN_PROTOCOL
+} EasysetupProviderComboBoxIdType;
+
+typedef struct {
+       GtkComboBox parent;
+} EasysetupProviderComboBox;
+
+typedef struct {
+       GtkComboBoxClass parent_class;
+} EasysetupProviderComboBoxClass;
+
+GType easysetup_provider_combo_box_get_type (void);
+
+EasysetupProviderComboBox* easysetup_provider_combo_box_new (void);
+
+void easysetup_provider_combo_box_fill (EasysetupProviderComboBox *combobox, ModestPresets *presets,
+                                       gint mcc);
+
+gchar* easysetup_provider_combo_box_get_active_provider_id (EasysetupProviderComboBox *combobox);
+
+EasysetupProviderComboBoxIdType easysetup_provider_combo_box_get_active_id_type (EasysetupProviderComboBox *combobox);
+
+G_END_DECLS
+
+#endif /* _EASYSETUP_PROVIDER_COMBO_BOX */
diff --git a/src/hildon2/modest-easysetup-servertype-combo-box.c b/src/hildon2/modest-easysetup-servertype-combo-box.c
new file mode 100644 (file)
index 0000000..ab54656
--- /dev/null
@@ -0,0 +1,276 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <modest-runtime.h>
+#include "modest-easysetup-servertype-combo-box.h"
+#include <gtk/gtkliststore.h>
+#include <gtk/gtkcelllayout.h>
+#include <gtk/gtkcellrenderertext.h>
+#include <glib/gi18n.h>
+
+#include <stdlib.h>
+#include <string.h> /* For memcpy() */
+
+/* Include config.h so that _() works: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+G_DEFINE_TYPE (EasysetupServertypeComboBox, easysetup_servertype_combo_box, GTK_TYPE_COMBO_BOX);
+
+#define SERVERTYPE_COMBO_BOX_GET_PRIVATE(o) \
+       (G_TYPE_INSTANCE_GET_PRIVATE ((o), EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX, EasysetupServertypeComboBoxPrivate))
+
+typedef struct _EasysetupServertypeComboBoxPrivate EasysetupServertypeComboBoxPrivate;
+
+struct _EasysetupServertypeComboBoxPrivate
+{
+       GtkTreeModel *model;
+};
+
+static void
+easysetup_servertype_combo_box_get_property (GObject *object, guint property_id,
+                                                                                                                       GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_servertype_combo_box_set_property (GObject *object, guint property_id,
+                                                                                                                       const GValue *value, GParamSpec *pspec)
+{
+       switch (property_id) {
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+easysetup_servertype_combo_box_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (easysetup_servertype_combo_box_parent_class)->dispose)
+               G_OBJECT_CLASS (easysetup_servertype_combo_box_parent_class)->dispose (object);
+}
+
+static void
+easysetup_servertype_combo_box_finalize (GObject *object)
+{
+       EasysetupServertypeComboBoxPrivate *priv = SERVERTYPE_COMBO_BOX_GET_PRIVATE (object);
+
+       g_object_unref (G_OBJECT (priv->model));
+
+       G_OBJECT_CLASS (easysetup_servertype_combo_box_parent_class)->finalize (object);
+}
+
+static void
+easysetup_servertype_combo_box_class_init (EasysetupServertypeComboBoxClass *klass)
+{
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+       g_type_class_add_private (klass, sizeof (EasysetupServertypeComboBoxPrivate));
+
+       object_class->get_property = easysetup_servertype_combo_box_get_property;
+       object_class->set_property = easysetup_servertype_combo_box_set_property;
+       object_class->dispose = easysetup_servertype_combo_box_dispose;
+       object_class->finalize = easysetup_servertype_combo_box_finalize;
+}
+
+enum MODEL_COLS {
+       MODEL_COL_NAME = 0, /* a string */
+       MODEL_COL_ID = 1 /* an int. */
+};
+
+static void
+easysetup_servertype_combo_box_init (EasysetupServertypeComboBox *self)
+{
+       EasysetupServertypeComboBoxPrivate *priv = SERVERTYPE_COMBO_BOX_GET_PRIVATE (self);
+
+       /* Create a tree model for the combo box,
+        * with a string for the name, and an ID for the servertype.
+        * This must match our MODEL_COLS enum constants.
+        */
+       priv->model = GTK_TREE_MODEL (gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT));
+
+       /* Setup the combo box: */
+       GtkComboBox *combobox = GTK_COMBO_BOX (self);
+       gtk_combo_box_set_model (combobox, priv->model);
+
+       /* Servertype column:
+        * The ID model column in not shown in the view. */
+       GtkCellRenderer *renderer = gtk_cell_renderer_text_new ();
+       gtk_cell_layout_pack_start(GTK_CELL_LAYOUT (combobox), renderer, TRUE);
+       gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combobox), renderer, 
+       "text", MODEL_COL_NAME, NULL);
+}
+
+static void 
+easysetup_servertype_combo_box_fill (EasysetupServertypeComboBox *combobox,
+                                    gboolean filter_providers)
+{      
+       EasysetupServertypeComboBoxPrivate *priv;
+       GtkListStore *liststore;
+       ModestProtocolRegistry *protocol_registry;
+       GSList *remote_protocols, *node;
+       GtkTreeIter iter;
+       
+       /* Remove any existing rows: */
+       priv = SERVERTYPE_COMBO_BOX_GET_PRIVATE (combobox);
+       protocol_registry = modest_runtime_get_protocol_registry ();
+       remote_protocols = modest_protocol_registry_get_by_tag (protocol_registry, MODEST_PROTOCOL_REGISTRY_REMOTE_STORE_PROTOCOLS);
+
+       liststore = GTK_LIST_STORE (priv->model);
+       gtk_list_store_clear (liststore);
+
+       for (node = remote_protocols; node != NULL; node = g_slist_next (node)) {
+               ModestProtocol* protocol;
+               gboolean add = TRUE;
+
+               protocol = (ModestProtocol *) node->data;
+
+               /* Do not include the protocols that would be listed
+                  in the providers combo */
+               if (filter_providers)
+                       if (modest_protocol_registry_protocol_type_is_provider (protocol_registry,
+                                                                               modest_protocol_get_type_id (protocol))) {
+                               add = FALSE;
+                       }
+               
+               if (add) {
+                       gtk_list_store_append (liststore, &iter);
+                       gtk_list_store_set (liststore, &iter, 
+                                           MODEL_COL_ID, 
+                                           modest_protocol_get_type_id (protocol),
+                                           MODEL_COL_NAME, 
+                                           modest_protocol_get_display_name (protocol),
+                                           -1);
+               }
+       }
+       
+       g_slist_free (remote_protocols);
+}
+
+EasysetupServertypeComboBox*
+easysetup_servertype_combo_box_new (gboolean filter_providers)
+{
+       EasysetupServertypeComboBox *combo;
+
+       combo = g_object_new (EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX, NULL);
+
+       /* Fill the combo */    
+       easysetup_servertype_combo_box_fill (combo, filter_providers);
+
+       return combo;
+}
+
+/**
+ * Returns the selected servertype, 
+ * or MODEST_PROTOCOL_REGISTRY_TYPE_INVALID if no servertype was selected.
+ */
+ModestProtocolType
+easysetup_servertype_combo_box_get_active_servertype (EasysetupServertypeComboBox *combobox)
+{
+       GtkTreeIter active;
+       gboolean found;
+
+       found = gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combobox), &active);
+       if (found) {
+               EasysetupServertypeComboBoxPrivate *priv;
+               ModestProtocolType servertype;
+
+               priv = SERVERTYPE_COMBO_BOX_GET_PRIVATE (combobox);
+
+               servertype = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
+               gtk_tree_model_get (priv->model, &active, MODEL_COL_ID, &servertype, -1);
+               return servertype;      
+       }
+
+       return MODEST_PROTOCOL_REGISTRY_TYPE_INVALID; /* Failed. */
+}
+
+/* This allows us to pass more than one piece of data to the signal handler,
+ * and get a result: */
+typedef struct 
+{
+               EasysetupServertypeComboBox* self;
+               ModestProtocolType id;
+               gboolean found;
+} ForEachData;
+
+static gboolean
+on_model_foreach_select_id(GtkTreeModel *model, 
+       GtkTreePath *path, GtkTreeIter *iter, gpointer user_data)
+{
+       ModestProtocolType id = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
+       ForEachData *state = (ForEachData*)(user_data);
+       
+       /* Select the item if it has the matching ID: */
+       gtk_tree_model_get (model, iter, MODEL_COL_ID, &id, -1); 
+       if(id == state->id) {
+               gtk_combo_box_set_active_iter (GTK_COMBO_BOX (state->self), iter);
+               
+               state->found = TRUE;
+               return TRUE; /* Stop walking the tree. */
+       }
+       
+       return FALSE; /* Keep walking the tree. */
+}
+
+/**
+ * Selects the specified servertype, 
+ * or MODEST_PROTOCOL_TRANSPORT_STORE_UNKNOWN if no servertype was selected.
+ */
+gboolean
+easysetup_servertype_combo_box_set_active_servertype (EasysetupServertypeComboBox *combobox, ModestProtocolType servertype)
+{
+       EasysetupServertypeComboBoxPrivate *priv;
+       ForEachData *state;
+       gboolean result;
+       
+       priv = SERVERTYPE_COMBO_BOX_GET_PRIVATE (combobox);
+
+       /* Create a state instance so we can send two items of data to the signal handler: */
+       state = g_new0 (ForEachData, 1);
+       state->self = combobox;
+       state->id = servertype;
+       state->found = FALSE;
+       
+       /* Look at each item, and select the one with the correct ID: */
+       gtk_tree_model_foreach (priv->model, &on_model_foreach_select_id, state);
+
+       result = state->found;
+       
+       /* Free the state instance: */
+       g_free(state);
+       
+       return result;
+}
+
diff --git a/src/hildon2/modest-easysetup-servertype-combo-box.h b/src/hildon2/modest-easysetup-servertype-combo-box.h
new file mode 100644 (file)
index 0000000..bb7a6b4
--- /dev/null
@@ -0,0 +1,79 @@
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _EASYSETUP_SERVERTYPE_COMBO_BOX
+#define _EASYSETUP_SERVERTYPE_COMBO_BOX
+
+#include <gtk/gtkcombobox.h>
+#include "modest-protocol-registry.h"
+
+G_BEGIN_DECLS
+
+#define EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX easysetup_servertype_combo_box_get_type()
+
+#define EASYSETUP_SERVERTYPE_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+       EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX, EasysetupServertypeComboBox))
+
+#define EASYSETUP_SERVERTYPE_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_CAST ((klass), \
+       EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX, EasysetupServertypeComboBoxClass))
+
+#define EASYSETUP_IS_SERVERTYPE_COMBO_BOX(obj) \
+       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+       EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX))
+
+#define EASYSETUP_IS_SERVERTYPE_COMBO_BOX_CLASS(klass) \
+       (G_TYPE_CHECK_CLASS_TYPE ((klass), \
+       EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX))
+
+#define EASYSETUP_SERVERTYPE_COMBO_BOX_GET_CLASS(obj) \
+       (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+       EASYSETUP_TYPE_SERVERTYPE_COMBO_BOX, EasysetupServertypeComboBoxClass))
+
+typedef struct {
+       GtkComboBox parent;
+} EasysetupServertypeComboBox;
+
+typedef struct {
+       GtkComboBoxClass parent_class;
+} EasysetupServertypeComboBoxClass;
+
+GType easysetup_servertype_combo_box_get_type (void);
+
+EasysetupServertypeComboBox* easysetup_servertype_combo_box_new (gboolean filter_providers);
+
+ModestProtocolType easysetup_servertype_combo_box_get_active_servertype (EasysetupServertypeComboBox *combobox);
+
+gboolean easysetup_servertype_combo_box_set_active_servertype (EasysetupServertypeComboBox *combobox, ModestProtocolType servertype);
+
+
+G_END_DECLS
+
+#endif /* _EASYSETUP_PROVIDER_COMBO_BOX */
diff --git a/src/hildon2/modest-easysetup-wizard-dialog.c b/src/hildon2/modest-easysetup-wizard-dialog.c
new file mode 100644 (file)
index 0000000..9e61d43
--- /dev/null
@@ -0,0 +1,2101 @@
+
+/* Copyright (c) 2006, Nokia Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ * * Neither the name of the Nokia Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived from
+ *   this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <config.h>
+#include "modest-easysetup-wizard-dialog.h"
+#include <glib/gi18n.h>
+#include <gtk/gtknotebook.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkcombobox.h>
+#include <gtk/gtkentry.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkmessagedialog.h>
+#include <gtk/gtkseparator.h>
+#include "maemo/easysetup/modest-easysetup-country-combo-box.h"
+#include "maemo/easysetup/modest-easysetup-provider-combo-box.h"
+#include "maemo/easysetup/modest-easysetup-servertype-combo-box.h"
+#include "widgets/modest-validating-entry.h"
+#include "modest-text-utils.h"
+#include "modest-conf.h"
+#include "modest-defs.h"
+#include "modest-account-mgr.h"
+#include "modest-signal-mgr.h"
+#include "modest-account-mgr-helpers.h"
+#include "modest-runtime.h" /* For modest_runtime_get_account_mgr(). */
+#include "maemo/modest-connection-specific-smtp-window.h"
+#include "widgets/modest-ui-constants.h"
+#include "widgets/modest-default-account-settings-dialog.h"
+#include "widgets/modest-easysetup-wizard-page.h"
+#include "maemo/modest-maemo-utils.h"
+#include "modest-utils.h"
+#include "maemo/modest-hildon-includes.h"
+#include "maemo/modest-maemo-security-options-view.h"
+#include <modest-account-protocol.h>
+
+/* Include config.h so that _() works: */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+G_DEFINE_TYPE (ModestEasysetupWizardDialog, modest_easysetup_wizard_dialog, MODEST_TYPE_WIZARD_DIALOG);
+
+#define MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
+                                                   MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, \
+                                                   ModestEasysetupWizardDialogPrivate))
+
+typedef struct _ModestEasysetupWizardDialogPrivate ModestEasysetupWizardDialogPrivate;
+
+
+typedef enum {
+       MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED = 0x01,
+       MODEST_EASYSETUP_WIZARD_DIALOG_OUTGOING_CHANGED = 0x02
+} ModestEasysetupWizardDialogServerChanges;
+
+struct _ModestEasysetupWizardDialogPrivate
+{
+       ModestPresets *presets;
+
+       /* Remember what fields the user edited manually to not prefill them
+        * again. */
+       ModestEasysetupWizardDialogServerChanges server_changes;
+       
+       /* Check if the user changes a field to show a confirmation dialog */
+       gboolean dirty;
+
+       /* If we have a pending load of settings or not. */
+       gboolean pending_load_settings;
+       
+       /* Used by derived widgets to query existing accounts,
+        * and to create new accounts: */
+       ModestAccountMgr *account_manager;
+       ModestAccountSettings *settings;
+       
+       /* notebook pages: */
+       GtkWidget *page_welcome;
+       
+       GtkWidget *page_account_details;
+       GtkWidget *combo_account_country;
+       GtkWidget *combo_account_serviceprovider;
+       GtkWidget *entry_account_title;
+       
+       GtkWidget *page_user_details;
+       GtkWidget *entry_user_name;
+       GtkWidget *entry_user_username;
+       GtkWidget *entry_user_password;
+       GtkWidget *entry_user_email;
+       
+       GtkWidget *page_complete_easysetup;
+       
+       GtkWidget *page_custom_incoming;
+       GtkWidget *combo_incoming_servertype;
+       GtkWidget *caption_incoming;
+       GtkWidget *entry_incomingserver;
+
+       /* Security widgets */
+       GtkWidget *incoming_security;
+       GtkWidget *outgoing_security;
+
+       GtkWidget *page_custom_outgoing;
+       GtkWidget *entry_outgoingserver;
+       GtkWidget *combo_outgoing_security;
+       GtkWidget *combo_outgoing_auth;
+       GtkWidget *checkbox_outgoing_smtp_specific;
+       GtkWidget *button_outgoing_smtp_servers;
+       
+       GtkWidget *page_complete_customsetup;
+
+       ModestProtocolType last_plugin_protocol_selected;
+       GSList *missing_data_signals;
+};
+
+static void save_to_settings (ModestEasysetupWizardDialog *self);
+static void real_enable_buttons (ModestWizardDialog *dialog, gboolean enable_next);
+
+static gboolean
+on_delete_event (GtkWidget *widget,
+                GdkEvent *event,
+                ModestEasysetupWizardDialog *wizard)
+{
+       gtk_dialog_response (GTK_DIALOG (wizard), GTK_RESPONSE_CANCEL);
+       return TRUE;
+}
+
+static void
+on_easysetup_changed(GtkWidget* widget, ModestEasysetupWizardDialog* wizard)
+{
+       ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(wizard);
+       g_return_if_fail (priv != NULL);
+       priv->dirty = TRUE;
+}
+
+static void
+modest_easysetup_wizard_dialog_dispose (GObject *object)
+{
+       if (G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose)
+               G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->dispose (object);
+}
+
+static void
+modest_easysetup_wizard_dialog_finalize (GObject *object)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (object);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       
+       if (priv->account_manager)
+               g_object_unref (G_OBJECT (priv->account_manager));
+               
+       if (priv->presets)
+               modest_presets_destroy (priv->presets);
+
+       if (priv->settings)
+               g_object_unref (priv->settings);
+
+       if (priv->missing_data_signals) {
+               modest_signal_mgr_disconnect_all_and_destroy (priv->missing_data_signals);
+               priv->missing_data_signals = NULL;
+       }
+               
+       G_OBJECT_CLASS (modest_easysetup_wizard_dialog_parent_class)->finalize (object);
+}
+
+static void
+create_subsequent_easysetup_pages (ModestEasysetupWizardDialog *self);
+
+static void
+set_default_custom_servernames(ModestEasysetupWizardDialog *dialog);
+
+static void on_combo_servertype_changed(GtkComboBox *combobox, gpointer user_data);
+
+static gint 
+get_port_from_protocol (ModestProtocolType server_type,
+                       gboolean alternate_port)
+{
+       int server_port = 0;
+       ModestProtocol *protocol;
+       ModestProtocolRegistry *protocol_registry;
+
+       protocol_registry = modest_runtime_get_protocol_registry ();
+       protocol = modest_protocol_registry_get_protocol_by_type (protocol_registry, server_type);
+
+       if (alternate_port) {
+               server_port = modest_account_protocol_get_alternate_port (MODEST_ACCOUNT_PROTOCOL (protocol));
+       } else {
+               server_port = modest_account_protocol_get_port (MODEST_ACCOUNT_PROTOCOL (protocol));
+       }
+       return server_port;
+}
+
+/* static GList*  */
+/* check_for_supported_auth_methods (ModestEasysetupWizardDialog* self) */
+/* { */
+/*     GError *error = NULL; */
+/*     ModestProtocolType protocol_type; */
+/*     const gchar* hostname; */
+/*     const gchar* username; */
+/*     ModestProtocolType security_protocol_incoming_type; */
+/*     ModestProtocolRegistry *registry; */
+/*     int port_num;  */
+/*     GList *list_auth_methods; */
+/*     ModestEasysetupWizardDialogPrivate *priv; */
+       
+/*     priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self); */
+/*     registry = modest_runtime_get_protocol_registry (); */
+/*     protocol_type = easysetup_servertype_combo_box_get_active_servertype ( */
+/*             EASYSETUP_SERVERTYPE_COMBO_BOX (priv->combo_incoming_servertype)); */
+/*     hostname = gtk_entry_get_text(GTK_ENTRY(priv->entry_incomingserver)); */
+/*     username = gtk_entry_get_text(GTK_ENTRY(priv->entry_user_username)); */
+/*     security_protocol_incoming_type = modest_serversecurity_combo_box_get_active_serversecurity */
+/*             (MODEST_SERVERSECURITY_COMBO_BOX (priv->combo_incoming_security)); */
+/*     port_num = get_port_from_protocol(protocol_type, FALSE);  */
+/*     list_auth_methods = modest_utils_get_supported_secure_authentication_methods (protocol_type, hostname, port_num,  */
+/*                                                                                   username, GTK_WINDOW (self), &error); */
+
+/*     if (list_auth_methods) { */
+/*             /\* TODO: Select the correct method *\/ */
+/*             GList* list = NULL; */
+/*             GList* method; */
+/*             for (method = list_auth_methods; method != NULL; method = g_list_next(method)) { */
+/*                     ModestProtocolType auth_protocol_type = (ModestProtocolType) (GPOINTER_TO_INT(method->data)); */
+/*                     if (modest_protocol_registry_protocol_type_has_tag (registry, auth_protocol_type, */
+/*                                                                         MODEST_PROTOCOL_REGISTRY_SECURE_PROTOCOLS)) { */
+/*                             list = g_list_append(list, GINT_TO_POINTER(auth_protocol_type)); */
+/*                     } */
+/*             } */
+
+/*             g_list_free(list_auth_methods); */
+
+/*             if (list) */
+/*                     return list; */
+/*     } */
+
+/*     if(error == NULL || error->domain != modest_utils_get_supported_secure_authentication_error_quark() || */
+/*                     error->code != MODEST_UTILS_GET_SUPPORTED_SECURE_AUTHENTICATION_ERROR_CANCELED) */
+/*     { */
+/*             modest_platform_information_banner (GTK_WIDGET(self), NULL, */
+/*                                                 _("mcen_ib_unableto_discover_auth_methods")); */
+/*     } */
+
+/*     if(error != NULL) */
+/*             g_error_free(error); */
+
+/*     return NULL; */
+/* } */
+
+/* static gboolean check_has_supported_auth_methods(ModestEasysetupWizardDialog* self) */
+/* { */
+/*     GList* methods = check_for_supported_auth_methods(self); */
+/*     if (!methods) */
+/*     { */
+/*             return FALSE; */
+/*     } */
+
+/*     g_list_free(methods); */
+/*     return TRUE; */
+/* } */
+
+/* static ModestProtocolType check_first_supported_auth_method(ModestEasysetupWizardDialog* self) */
+/* { */
+/*     ModestProtocolType result; */
+
+/*     result = MODEST_PROTOCOLS_AUTH_PASSWORD; */
+
+/*     GList* methods = check_for_supported_auth_methods(self); */
+/*     if (methods) */
+/*     { */
+/*             /\* Use the first one: *\/ */
+/*             result = (ModestProtocolType) (GPOINTER_TO_INT(methods->data)); */
+/*             g_list_free(methods); */
+/*     } */
+
+/*     return result; */
+/* } */
+
+static void
+invoke_enable_buttons_vfunc (ModestEasysetupWizardDialog *wizard_dialog)
+{
+       ModestWizardDialogClass *klass = MODEST_WIZARD_DIALOG_GET_CLASS (wizard_dialog);
+       
+       /* Call the vfunc, which may be overridden by derived classes: */
+       if (klass->enable_buttons) {
+               GtkNotebook *notebook = NULL;
+               g_object_get (wizard_dialog, "wizard-notebook", &notebook, NULL);
+               
+               const gint current_page_num = gtk_notebook_get_current_page (notebook);
+               if (current_page_num == -1)
+                       return;
+                       
+               GtkWidget* current_page_widget = gtk_notebook_get_nth_page (notebook, current_page_num);
+               (*(klass->enable_buttons))(MODEST_WIZARD_DIALOG (wizard_dialog), current_page_widget);
+       }
+}
+
+static void
+on_caption_entry_changed (GtkEditable *editable, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       g_assert(self);
+       invoke_enable_buttons_vfunc(self);
+}
+
+static void
+on_caption_combobox_changed (GtkComboBox *widget, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       g_assert(self);
+       invoke_enable_buttons_vfunc(self);
+}
+
+/** This is a convenience function to create a caption containing a mandatory widget.
+ * When the widget is edited, the enable_buttons() vfunc will be called.
+ */
+static GtkWidget* 
+create_caption_new_with_asterisk (ModestEasysetupWizardDialog *self,
+                                 GtkSizeGroup *group,
+                                 const gchar *value,
+                                 GtkWidget *control,
+                                 GtkWidget *icon,
+                                 HildonCaptionStatus flag)
+{
+       GtkWidget *caption = NULL;
+  
+       /* Note: Previously, the translated strings already contained the "*",
+        * Comment out this code if they do again.
+        */
+       /* Add a * character to indicate mandatory fields,
+        * as specified in our "Email UI Specification": */
+       if (flag == HILDON_CAPTION_MANDATORY) {
+               gchar* title = g_strdup_printf("%s*", value);
+               caption = hildon_caption_new (group, title, control, icon, flag);       
+               g_free(title);
+       }       
+       else
+               caption = hildon_caption_new (group, value, control, icon, flag);
+
+       /* Connect to the appropriate changed signal for the widget, 
+        * so we can ask for the prev/next buttons to be enabled/disabled appropriately:
+        */
+       if (GTK_IS_ENTRY (control)) {
+               g_signal_connect (G_OBJECT (control), "changed",
+                                 G_CALLBACK (on_caption_entry_changed), self);
+               
+       }
+       else if (GTK_IS_COMBO_BOX (control)) {
+               g_signal_connect (G_OBJECT (control), "changed",
+                                 G_CALLBACK (on_caption_combobox_changed), self);
+       }
+        
+       return caption;
+}
+           
+static GtkWidget*
+create_page_welcome (ModestEasysetupWizardDialog *self)
+{
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_intro"));
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       /* So that it is not truncated: */
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       gtk_widget_show (GTK_WIDGET (box));
+       return GTK_WIDGET (box);
+}
+
+#if MODEST_HILDON_API < 2
+static void
+on_combo_account_country (GtkComboBox *widget, gpointer user_data)
+#else
+static void
+on_combo_account_country (HildonTouchSelector *widget, gint column, gpointer user_data)
+#endif
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       g_assert(self);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       
+       priv->dirty = TRUE;
+       
+       /* Fill the providers combo, based on the selected country: */
+       if (priv->presets != NULL) {
+               gint mcc = easysetup_country_combo_box_get_active_country_mcc (
+                       MODEST_EASYSETUP_COUNTRY_COMBO_BOX (priv->combo_account_country));
+               easysetup_provider_combo_box_fill (
+                       EASYSETUP_PROVIDER_COMBO_BOX (priv->combo_account_serviceprovider), priv->presets, mcc);
+       }
+}
+
+static void
+on_combo_account_serviceprovider (GtkComboBox *widget, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       g_assert(self);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       
+       priv->dirty = TRUE;
+       
+       /* Fill the providers combo, based on the selected country: */
+       gchar* provider_id = easysetup_provider_combo_box_get_active_provider_id (
+               EASYSETUP_PROVIDER_COMBO_BOX (priv->combo_account_serviceprovider));
+       
+       gchar* domain_name = NULL;
+       if(provider_id)
+               domain_name = modest_presets_get_domain (priv->presets, provider_id);
+       
+       if(!domain_name)
+               domain_name = g_strdup (MODEST_EXAMPLE_EMAIL_ADDRESS);
+               
+       if (priv->entry_user_email)
+               gtk_entry_set_text (GTK_ENTRY (priv->entry_user_email), domain_name);
+               
+       g_free (domain_name);
+       
+       g_free (provider_id);
+}
+
+static void
+on_entry_max (ModestValidatingEntry *self, gpointer user_data)
+{
+       modest_platform_information_banner (GTK_WIDGET (self), NULL,
+                                           _CS("ckdg_ib_maximum_characters_reached"));
+}
+
+static GtkWidget*
+create_page_account_details (ModestEasysetupWizardDialog *self)
+{
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       GtkWidget *label = gtk_label_new(_("mcen_ia_accountdetails"));
+       ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (label);
+
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       GtkSizeGroup* sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+
+       /* The country widgets: */
+       priv->combo_account_country = GTK_WIDGET (easysetup_country_combo_box_new ());
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_country"), 
+                                                             priv->combo_account_country, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->combo_account_country);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* connect to country combo's changed signal, so we can fill the provider combo: */
+#if MODEST_HILDON_API < 2
+       g_signal_connect (G_OBJECT (priv->combo_account_country), "changed",
+                         G_CALLBACK (on_combo_account_country), self);
+#else
+       g_signal_connect (G_OBJECT (hildon_picker_button_get_selector 
+                                   (HILDON_PICKER_BUTTON (priv->combo_account_country))),
+                         "changed",
+                         G_CALLBACK (on_combo_account_country), self);
+#endif
+            
+       GtkWidget *separator = gtk_hseparator_new ();
+       gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (separator);
+            
+       /* The service provider widgets: */     
+       priv->combo_account_serviceprovider = GTK_WIDGET (easysetup_provider_combo_box_new ());
+       gtk_widget_set_size_request (priv->combo_account_serviceprovider, 320, -1);
+       
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_serviceprovider"), 
+                                                  priv->combo_account_serviceprovider, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->combo_account_serviceprovider);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* connect to providers combo's changed signal, so we can fill the email address: */
+       g_signal_connect (G_OBJECT (priv->combo_account_serviceprovider), "changed",
+                         G_CALLBACK (on_combo_account_serviceprovider), self);
+       
+       /* The description widgets: */  
+       priv->entry_account_title = GTK_WIDGET (modest_validating_entry_new ());
+       g_signal_connect(G_OBJECT(priv->entry_account_title), "changed",
+                        G_CALLBACK(on_easysetup_changed), self);
+       /* Do use auto-capitalization: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_account_title), 
+                                        HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
+       
+       /* Set a default account title, choosing one that does not already exist: */
+       /* Note that this is irrelevant to the non-user visible name, which we will create later. */
+       gchar* default_account_name_start = g_strdup (_("mcen_ia_emailsetup_defaultname"));
+       gchar* default_account_name = modest_account_mgr_get_unused_account_display_name (
+               priv->account_manager, default_account_name_start);
+       g_free (default_account_name_start);
+       default_account_name_start = NULL;
+       
+       gtk_entry_set_text( GTK_ENTRY (priv->entry_account_title), default_account_name);
+       g_free (default_account_name);
+       default_account_name = NULL;
+
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mcen_fi_account_title"), 
+                                                  priv->entry_account_title, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->entry_account_title);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the account title, 
+        * as required by our UI specification: */
+       GList *list_prevent = NULL;
+       list_prevent = g_list_append (list_prevent, "\\");
+       list_prevent = g_list_append (list_prevent, "/");
+       list_prevent = g_list_append (list_prevent, ":");
+       list_prevent = g_list_append (list_prevent, "*");
+       list_prevent = g_list_append (list_prevent, "?");
+       list_prevent = g_list_append (list_prevent, "\""); /* The UI spec mentions “, but maybe means ", maybe both. */
+       list_prevent = g_list_append (list_prevent, "“");
+       list_prevent = g_list_append (list_prevent, "<"); 
+       list_prevent = g_list_append (list_prevent, ">"); 
+       list_prevent = g_list_append (list_prevent, "|");
+       list_prevent = g_list_append (list_prevent, "^");       
+       modest_validating_entry_set_unallowed_characters (
+               MODEST_VALIDATING_ENTRY (priv->entry_account_title), list_prevent);
+       g_list_free (list_prevent);
+       list_prevent = NULL;
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_account_title),
+                                                                                                                                        modest_utils_on_entry_invalid_character, self);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_account_title), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_account_title), 
+                                             on_entry_max, self);
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       
+       return GTK_WIDGET (box);
+}
+
+static GtkWidget*
+create_page_user_details (ModestEasysetupWizardDialog *self)
+{
+       GtkSizeGroup* sizegroup;
+       GtkWidget *box;
+       ModestEasysetupWizardDialogPrivate *priv;
+
+       priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The name widgets: (use auto cap) */
+       priv->entry_user_name = GTK_WIDGET (modest_validating_entry_new ());
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_name), 
+                                        HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_AUTOCAP);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_name), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_name), 
+                                             on_entry_max, self);
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
+                                                             _("mcen_li_emailsetup_name"), priv->entry_user_name, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect(G_OBJECT(priv->entry_user_name), "changed", 
+                        G_CALLBACK(on_easysetup_changed), self);
+       gtk_widget_show (priv->entry_user_name);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the name, 
+        * as required by our UI specification: */
+       GList *list_prevent = NULL;
+       list_prevent = g_list_append (list_prevent, "<");
+       list_prevent = g_list_append (list_prevent, ">");
+       modest_validating_entry_set_unallowed_characters (
+               MODEST_VALIDATING_ENTRY (priv->entry_user_name), list_prevent);
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_name),
+               modest_utils_on_entry_invalid_character, self);
+       g_list_free (list_prevent);
+       
+       /* The username widgets: */     
+       priv->entry_user_username = GTK_WIDGET (modest_validating_entry_new ());
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_username), 
+                                        HILDON_GTK_INPUT_MODE_FULL);
+       caption = create_caption_new_with_asterisk (self, sizegroup, _("mail_fi_username"), 
+                                                  priv->entry_user_username, 
+                                                   NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->entry_user_username);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       g_signal_connect(G_OBJECT(priv->entry_user_username), "changed", 
+                        G_CALLBACK(on_easysetup_changed), self);
+       gtk_widget_show (caption);
+       
+       /* Prevent the use of some characters in the username, 
+        * as required by our UI specification: */
+       modest_validating_entry_set_unallowed_characters_whitespace (
+               MODEST_VALIDATING_ENTRY (priv->entry_user_username));
+       modest_validating_entry_set_func(MODEST_VALIDATING_ENTRY(priv->entry_user_username),
+               modest_utils_on_entry_invalid_character, self);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_username), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_username), 
+                                             on_entry_max, self);
+       
+       /* The password widgets: */     
+       priv->entry_user_password = gtk_entry_new ();
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_password), 
+                                        HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
+       gtk_entry_set_visibility (GTK_ENTRY (priv->entry_user_password), FALSE);
+       /* gtk_entry_set_invisible_char (GTK_ENTRY (priv->entry_user_password), '*'); */
+       caption = create_caption_new_with_asterisk (self, sizegroup, 
+                                                  _("mail_fi_password"), priv->entry_user_password, NULL, HILDON_CAPTION_OPTIONAL);
+       g_signal_connect(G_OBJECT(priv->entry_user_password), "changed", 
+                        G_CALLBACK(on_easysetup_changed), self);
+       gtk_widget_show (priv->entry_user_password);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* The email address widgets: */        
+       priv->entry_user_email = GTK_WIDGET (modest_validating_entry_new ());
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_user_email), HILDON_GTK_INPUT_MODE_FULL);
+       caption = create_caption_new_with_asterisk (self, sizegroup, 
+                                                  _("mcen_li_emailsetup_email_address"), priv->entry_user_email, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_entry_set_text (GTK_ENTRY (priv->entry_user_email), MODEST_EXAMPLE_EMAIL_ADDRESS); /* Default text. */
+       gtk_widget_show (priv->entry_user_email);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       g_signal_connect(G_OBJECT(priv->entry_user_email), "changed", 
+                        G_CALLBACK(on_easysetup_changed), self);
+       gtk_widget_show (caption);
+       
+       /* Set max length as in the UI spec:
+        * The UI spec seems to want us to show a dialog if we hit the maximum. */
+       gtk_entry_set_max_length (GTK_ENTRY (priv->entry_user_email), 64);
+       modest_validating_entry_set_max_func (MODEST_VALIDATING_ENTRY (priv->entry_user_email), 
+                                             on_entry_max, self);
+       
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       
+       return GTK_WIDGET (box);
+}
+
+static GtkWidget* 
+create_page_complete_easysetup (ModestEasysetupWizardDialog *self)
+{
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       
+       GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_setup_complete"));
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+       /* The documentation for gtk_label_set_line_wrap() says that we must 
+        * call gtk_widget_set_size_request() with a hard-coded width, 
+        * though I wonder why gtk_label_set_max_width_chars() isn't enough. */
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (_("mcen_ia_easysetup_complete"));
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_widget_set_size_request (label, 600, -1);
+       
+       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       return GTK_WIDGET (box);
+}
+
+/** Change the caption title for the incoming server, 
+ * as specified in the UI spec:
+ */
+static void 
+update_incoming_server_title (ModestEasysetupWizardDialog *self)
+{
+       ModestEasysetupWizardDialogPrivate* priv; 
+       ModestProtocolType protocol_type; 
+       ModestProtocolRegistry *protocol_registry;
+
+       priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       protocol_registry = modest_runtime_get_protocol_registry ();
+       
+       protocol_type = easysetup_servertype_combo_box_get_active_servertype (
+               EASYSETUP_SERVERTYPE_COMBO_BOX (priv->combo_incoming_servertype));
+
+       /* This could happen when the combo box has still no active iter */
+       if (protocol_type != MODEST_PROTOCOL_REGISTRY_TYPE_INVALID) {
+               gchar* incomingserver_title;
+               const gchar *protocol_display_name; 
+
+               protocol_display_name = modest_protocol_get_display_name (modest_protocol_registry_get_protocol_by_type (protocol_registry, protocol_type));
+               
+               incomingserver_title = g_strdup_printf(_("mcen_li_emailsetup_servertype"), protocol_display_name);
+               g_object_set (G_OBJECT (priv->caption_incoming), "label", incomingserver_title, NULL);
+               g_free(incomingserver_title);
+       }
+}
+
+/** Change the caption title for the incoming server, 
+ * as specified in the UI spec:
+ */
+static void 
+update_incoming_server_security_choices (ModestEasysetupWizardDialog *self)
+{
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       EasysetupServertypeComboBox *server_type_combo;
+       ModestProtocolType protocol_type;
+       ModestSecurityOptionsView *view;
+
+       server_type_combo = 
+               EASYSETUP_SERVERTYPE_COMBO_BOX (priv->combo_incoming_servertype);
+       protocol_type = 
+               easysetup_servertype_combo_box_get_active_servertype (server_type_combo);
+       
+       /* Fill the combo with appropriately titled choices for all
+          those protocols */
+       view = MODEST_SECURITY_OPTIONS_VIEW (priv->incoming_security);
+       modest_security_options_view_set_server_type (view, protocol_type);
+}
+
+static void 
+on_combo_servertype_changed(GtkComboBox *combobox, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       EasysetupServertypeComboBox *combo;
+       ModestProtocolType protocol_type;
+
+       priv->dirty = TRUE;
+       
+       /* Update title */
+       update_incoming_server_title (self);
+
+       /* Update security options if needed */
+       combo = EASYSETUP_SERVERTYPE_COMBO_BOX (combobox);
+       protocol_type = easysetup_servertype_combo_box_get_active_servertype (combo);
+       update_incoming_server_security_choices (self);
+       gtk_widget_show (priv->incoming_security);
+
+       set_default_custom_servernames (self);
+}
+
+static void 
+on_entry_incoming_servername_changed(GtkEntry *entry, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       priv->dirty = TRUE;
+       priv->server_changes |= MODEST_EASYSETUP_WIZARD_DIALOG_INCOMING_CHANGED;
+}
+
+static GtkWidget* 
+create_page_custom_incoming (ModestEasysetupWizardDialog *self)
+{
+       ModestProtocolRegistry *protocol_registry;
+       ModestEasysetupWizardDialogPrivate* priv; 
+       GtkWidget *box; 
+       GtkWidget *scrolled_window;
+       GtkWidget *label;
+       GtkSizeGroup *sizegroup;
+       GtkWidget *caption;
+
+       priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       protocol_registry = modest_runtime_get_protocol_registry ();
+
+       box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                       GTK_POLICY_NEVER,
+                                       GTK_POLICY_AUTOMATIC);
+
+       /* Show note that account type cannot be changed in future: */
+       label = gtk_label_new (_("mcen_ia_emailsetup_account_type"));
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The incoming server widgets: */
+       priv->combo_incoming_servertype = GTK_WIDGET (easysetup_servertype_combo_box_new (TRUE));
+       caption = create_caption_new_with_asterisk (self, sizegroup, 
+                                                   _("mcen_li_emailsetup_type"), priv->combo_incoming_servertype, NULL, HILDON_CAPTION_MANDATORY);
+       gtk_widget_show (priv->combo_incoming_servertype);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       priv->entry_incomingserver = gtk_entry_new ();
+       g_signal_connect(G_OBJECT(priv->entry_incomingserver), "changed", G_CALLBACK(on_easysetup_changed), self);
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_incomingserver), HILDON_GTK_INPUT_MODE_FULL);
+       set_default_custom_servernames (self);
+
+       /* The caption title will be updated in update_incoming_server_title().
+        * so this default text will never be seen: */
+       /* (Note: Changing the title seems pointless. murrayc) */
+       priv->caption_incoming = create_caption_new_with_asterisk (self, sizegroup, 
+                                                                 "Incoming Server", 
+                                                                  priv->entry_incomingserver, 
+                                                                  NULL, HILDON_CAPTION_MANDATORY);
+       update_incoming_server_title (self);
+       gtk_widget_show (priv->entry_incomingserver);
+       gtk_box_pack_start (GTK_BOX (box), priv->caption_incoming, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (priv->caption_incoming);
+       
+       /* Change the caption title when the servertype changes, 
+        * as in the UI spec: */
+       g_signal_connect (G_OBJECT (priv->combo_incoming_servertype), "changed",
+                         G_CALLBACK (on_combo_servertype_changed), self);
+
+       /* Remember when the servername was changed manually: */
+       g_signal_connect (G_OBJECT (priv->entry_incomingserver), "changed",
+                         G_CALLBACK (on_entry_incoming_servername_changed), self);
+
+       /* The secure connection widgets. These are only valid for
+          protocols with security */   
+       priv->incoming_security = 
+               modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_INCOMING,
+                                                       FALSE, sizegroup);
+       gtk_box_pack_start (GTK_BOX (box), priv->incoming_security, 
+                           FALSE, FALSE, MODEST_MARGIN_HALF);
+
+       /* Set default selection */
+       easysetup_servertype_combo_box_set_active_servertype (
+               EASYSETUP_SERVERTYPE_COMBO_BOX (priv->combo_incoming_servertype), 
+               MODEST_PROTOCOLS_STORE_POP);
+
+       gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), box);
+       gtk_container_set_focus_vadjustment (GTK_CONTAINER (box),
+                                            gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)));
+       gtk_widget_show (GTK_WIDGET (box));
+       gtk_widget_show (scrolled_window);
+
+       return GTK_WIDGET (scrolled_window);
+}
+
+static void
+on_toggle_button_changed (GtkToggleButton *togglebutton, gpointer user_data)
+{
+       GtkWidget *widget = GTK_WIDGET (user_data);
+       
+       /* Enable the widget only if the toggle button is active: */
+       const gboolean enable = gtk_toggle_button_get_active (togglebutton);
+       gtk_widget_set_sensitive (widget, enable);
+}
+
+/* Make the sensitivity of a widget depend on a toggle button.
+ */
+static void
+enable_widget_for_togglebutton (GtkWidget *widget, GtkToggleButton* button)
+{
+       g_signal_connect (G_OBJECT (button), "toggled",
+                         G_CALLBACK (on_toggle_button_changed), widget);
+       
+       /* Set the starting sensitivity: */
+       on_toggle_button_changed (button, widget);
+}
+
+static void
+on_button_outgoing_smtp_servers (GtkButton *button, gpointer user_data)
+{
+       ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate* priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(self);
+       GtkWidget *specific_window;
+       
+       /* We set dirty here because setting it depending on the connection specific dialog
+       seems overkill */
+       priv->dirty = TRUE;
+       
+       /* Create the window, if necessary: */
+       specific_window = (GtkWidget *) modest_connection_specific_smtp_window_new ();
+       modest_connection_specific_smtp_window_fill_with_connections (MODEST_CONNECTION_SPECIFIC_SMTP_WINDOW (specific_window), priv->account_manager);
+
+       /* Show the window */
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (specific_window));
+       gtk_widget_show (specific_window);
+}
+
+static void 
+on_entry_outgoing_servername_changed (GtkEntry *entry, gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       priv->server_changes |= MODEST_EASYSETUP_WIZARD_DIALOG_OUTGOING_CHANGED;
+}
+
+static GtkWidget* 
+create_page_custom_outgoing (ModestEasysetupWizardDialog *self)
+{
+       ModestEasysetupWizardDialogPrivate *priv;
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       
+       /* Create a size group to be used by all captions.
+        * Note that HildonCaption does not create a default size group if we do not specify one.
+        * We use GTK_SIZE_GROUP_HORIZONTAL, so that the widths are the same. */
+       GtkSizeGroup *sizegroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
+        
+       /* The outgoing server widgets: */
+       priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       priv->entry_outgoingserver = gtk_entry_new ();
+       g_signal_connect (G_OBJECT (priv->entry_outgoingserver), "changed",
+                  G_CALLBACK (on_easysetup_changed), self);
+       /* Auto-capitalization is the default, so let's turn it off: */
+       hildon_gtk_entry_set_input_mode (GTK_ENTRY (priv->entry_outgoingserver), HILDON_GTK_INPUT_MODE_FULL);
+       GtkWidget *caption = create_caption_new_with_asterisk (self, sizegroup, 
+                                                             _("mcen_li_emailsetup_smtp"), priv->entry_outgoingserver, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->entry_outgoingserver);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       set_default_custom_servernames (self);
+
+       /* The secure connection widgets. These are only valid for
+          protocols with security */   
+       priv->outgoing_security = 
+               modest_maemo_security_options_view_new (MODEST_SECURITY_OPTIONS_OUTGOING,
+                                                       FALSE, sizegroup);
+       gtk_box_pack_start (GTK_BOX (box), priv->outgoing_security, 
+                           FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (priv->outgoing_security);
+       
+       GtkWidget *separator = gtk_hseparator_new ();
+       gtk_box_pack_start (GTK_BOX (box), separator, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (separator);
+       
+       /* connection-specific checkbox: */
+       priv->checkbox_outgoing_smtp_specific = gtk_check_button_new ();
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific), 
+                                     FALSE);
+       g_signal_connect (G_OBJECT (priv->checkbox_outgoing_smtp_specific), "toggled",
+                  G_CALLBACK (on_easysetup_changed), self);
+
+       caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_connection_smtp"), 
+                                     priv->checkbox_outgoing_smtp_specific, NULL, HILDON_CAPTION_OPTIONAL);
+       gtk_widget_show (priv->checkbox_outgoing_smtp_specific);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Connection-specific SMTP-Severs Edit button: */
+       priv->button_outgoing_smtp_servers = gtk_button_new_with_label (_("mcen_bd_edit"));
+       caption = hildon_caption_new (sizegroup, _("mcen_fi_advsetup_optional_smtp"), 
+                                     priv->button_outgoing_smtp_servers, NULL, HILDON_CAPTION_OPTIONAL);
+       hildon_caption_set_child_expand (HILDON_CAPTION (caption), FALSE);
+       gtk_widget_show (priv->button_outgoing_smtp_servers);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       /* Only enable the button when the checkbox is checked: */
+       enable_widget_for_togglebutton (priv->button_outgoing_smtp_servers, 
+                                       GTK_TOGGLE_BUTTON (priv->checkbox_outgoing_smtp_specific));
+               
+       g_signal_connect (G_OBJECT (priv->button_outgoing_smtp_servers), "clicked",
+                         G_CALLBACK (on_button_outgoing_smtp_servers), self);
+
+       g_signal_connect (G_OBJECT (priv->entry_outgoingserver), "changed",
+                         G_CALLBACK (on_entry_outgoing_servername_changed), self);
+       
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       
+       return GTK_WIDGET (box);
+}
+
+static gboolean
+show_advanced_edit(gpointer user_data)
+{
+       ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       gint response;
+       
+       /* Show the Account Settings window: */
+       ModestAccountSettingsDialog *dialog = modest_default_account_settings_dialog_new ();
+       if (priv->pending_load_settings) {
+               save_to_settings (self);
+               priv->pending_load_settings = FALSE;
+       }
+       modest_account_settings_dialog_load_settings (dialog, priv->settings);
+       
+       modest_window_mgr_set_modal (modest_runtime_get_window_mgr (), GTK_WINDOW (dialog));
+       
+       response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+       gtk_widget_destroy (GTK_WIDGET (dialog));
+       
+       return FALSE; /* Do not call this timeout callback again. */
+}
+
+static void
+on_button_edit_advanced_settings (GtkButton *button, gpointer user_data)
+{
+       ModestEasysetupWizardDialog * self = MODEST_EASYSETUP_WIZARD_DIALOG (user_data);
+       
+       /* Show the Account Settings window: */
+       show_advanced_edit(self);
+}
+static GtkWidget* 
+create_page_complete_custom (ModestEasysetupWizardDialog *self)
+{
+       GtkWidget *box = gtk_vbox_new (FALSE, MODEST_MARGIN_NONE);
+       GtkWidget *label = gtk_label_new(_("mcen_ia_emailsetup_setup_complete"));
+       GtkWidget *button_edit = gtk_button_new_with_label (_("mcen_bd_edit"));
+       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (_("mcen_ia_customsetup_complete"));
+       gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5);
+       gtk_widget_set_size_request (label, 600, -1);
+       gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
+       gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0);
+       gtk_widget_show (label);
+       
+       GtkWidget *caption = hildon_caption_new (NULL, _("mcen_fi_advanced_settings"), 
+                                                button_edit, NULL, HILDON_CAPTION_OPTIONAL);
+       hildon_caption_set_child_expand (HILDON_CAPTION (caption), FALSE);
+       gtk_widget_show (button_edit);
+       gtk_box_pack_start (GTK_BOX (box), caption, FALSE, FALSE, MODEST_MARGIN_HALF);
+       gtk_widget_show (caption);
+       
+       g_signal_connect (G_OBJECT (button_edit), "clicked", 
+                         G_CALLBACK (on_button_edit_advanced_settings), self);
+       
+       gtk_widget_show (GTK_WIDGET (box));
+       return GTK_WIDGET (box);
+}
+
+
+/*
+ */
+static void 
+on_response (ModestWizardDialog *wizard_dialog,
+            gint response_id,
+            gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
+
+       invoke_enable_buttons_vfunc (self);
+}
+
+static void 
+on_response_before (ModestWizardDialog *wizard_dialog,
+                    gint response_id,
+                    gpointer user_data)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (wizard_dialog);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE(wizard_dialog);
+       if (response_id == GTK_RESPONSE_CANCEL) {
+               /* This is mostly copied from
+                * src/maemo/modest-account-settings-dialog.c */
+               if (priv->dirty) {
+                       GtkDialog *dialog = GTK_DIALOG (hildon_note_new_confirmation (GTK_WINDOW (self), 
+                               _("imum_nc_wizard_confirm_lose_changes")));
+                       /* TODO: These button names will be ambiguous, and not
+                        * specified in the UI specification. */
+
+                       const gint dialog_response = gtk_dialog_run (dialog);
+                       gtk_widget_destroy (GTK_WIDGET (dialog));
+
+                       if (dialog_response != GTK_RESPONSE_OK) {
+                               /* Don't let the dialog close */
+                               g_signal_stop_emission_by_name (wizard_dialog, "response");
+                       }
+               }
+       }
+}
+
+typedef struct IdleData {
+       ModestEasysetupWizardDialog *dialog;
+       ModestPresets *presets;
+} IdleData;
+
+static gboolean
+presets_idle (gpointer userdata)
+{
+       IdleData *idle_data = (IdleData *) userdata;
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (idle_data->dialog);
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+
+       g_assert (idle_data->presets);
+
+       gdk_threads_enter ();
+
+       priv->presets = idle_data->presets;
+
+       if (MODEST_EASYSETUP_IS_COUNTRY_COMBO_BOX (priv->combo_account_country)) {
+/*             gint mcc = get_default_country_code(); */
+               gint mcc;
+               /* Fill the combo in an idle call, as it takes a lot of time */
+               easysetup_country_combo_box_load_data(
+                       MODEST_EASYSETUP_COUNTRY_COMBO_BOX (priv->combo_account_country));
+/*             easysetup_country_combo_box_set_active_country_mcc ( */
+/*                     MODEST_EASYSETUP_COUNTRY_COMBO_BOX (priv->combo_account_country), mcc); */
+               easysetup_country_combo_box_set_active_country_locale (
+                       MODEST_EASYSETUP_COUNTRY_COMBO_BOX (priv->combo_account_country));
+               mcc = easysetup_country_combo_box_get_active_country_mcc (
+                       MODEST_EASYSETUP_COUNTRY_COMBO_BOX (priv->combo_account_country));
+               easysetup_provider_combo_box_fill (
+                       EASYSETUP_PROVIDER_COMBO_BOX (priv->combo_account_serviceprovider),
+                       priv->presets, mcc);
+       }
+
+       priv->dirty = FALSE;
+
+       g_object_unref (idle_data->dialog);
+       g_free (idle_data);
+
+       gdk_threads_leave ();
+
+       return FALSE;
+}
+
+static gpointer
+presets_loader (gpointer userdata)
+{
+       ModestEasysetupWizardDialog *self = MODEST_EASYSETUP_WIZARD_DIALOG (userdata);
+       ModestPresets *presets = NULL;
+       IdleData *idle_data;
+
+       const gchar* path  = NULL;
+       const gchar* path1 = MODEST_PROVIDER_DATA_FILE;
+       const gchar* path2 = MODEST_MAEMO_PROVIDER_DATA_FILE;
+       
+       if (access(path1, R_OK) == 0) 
+               path = path1;
+       else if (access(path2, R_OK) == 0)
+               path = path2;
+       else {
+               g_warning ("%s: neither '%s' nor '%s' is a readable provider data file",
+                          __FUNCTION__, path1, path2);
+               return NULL;
+       }
+
+       presets = modest_presets_new (path);
+       if (!presets) {
+               g_warning ("%s: failed to parse '%s'", __FUNCTION__, path);
+               return NULL;
+       }
+       
+       idle_data = g_new0 (IdleData, 1);
+       idle_data->dialog = self;
+       idle_data->presets = presets;
+       
+       g_idle_add (presets_idle, idle_data);   
+
+       return NULL;
+}
+
+static void
+modest_easysetup_wizard_dialog_append_page (GtkNotebook *notebook,
+                                           GtkWidget *page,
+                                           const gchar *label)
+{
+       gint index;
+       /* Append page and set attributes */
+       index = gtk_notebook_append_page (notebook, page, gtk_label_new (label));
+       gtk_container_child_set (GTK_CONTAINER (notebook), page,
+                                "tab-expand", TRUE, "tab-fill", TRUE,
+                                NULL);
+       gtk_widget_show (page);
+}
+
+static void
+init_user_page (ModestEasysetupWizardDialogPrivate *priv)
+{
+       priv->page_user_details = NULL;
+       priv->entry_user_name = NULL;
+       priv->entry_user_username = NULL;
+       priv->entry_user_password = NULL;
+       priv->entry_user_email = NULL;
+}
+
+static void
+init_incoming_page (ModestEasysetupWizardDialogPrivate *priv)
+{
+       priv->page_custom_incoming = NULL;
+       priv->combo_incoming_servertype = NULL;
+       priv->caption_incoming = NULL;
+       priv->entry_incomingserver = NULL;
+       priv->entry_user_email = NULL;
+       priv->incoming_security = NULL;
+}
+
+static void
+init_outgoing_page (ModestEasysetupWizardDialogPrivate *priv)
+{
+       priv->page_custom_outgoing = NULL;
+       priv->entry_outgoingserver = NULL;
+       priv->combo_outgoing_security = NULL;
+       priv->combo_outgoing_auth = NULL;
+       priv->checkbox_outgoing_smtp_specific = NULL;
+       priv->button_outgoing_smtp_servers = NULL;
+       priv->outgoing_security = NULL;
+}
+
+static void
+modest_easysetup_wizard_dialog_init (ModestEasysetupWizardDialog *self)
+{
+       gtk_container_set_border_width (GTK_CONTAINER (self), MODEST_MARGIN_HALF);
+       
+       /* Create the notebook to be used by the ModestWizardDialog base class:
+        * Each page of the notebook will be a page of the wizard: */
+       GtkNotebook *notebook = GTK_NOTEBOOK (gtk_notebook_new());
+       
+       /* Set the notebook used by the ModestWizardDialog base class: */
+       g_object_set (G_OBJECT(self), "wizard-notebook", notebook, NULL);
+    
+       /* Set the wizard title:
+        * The actual window title will be a combination of this and the page's tab label title. */
+       g_object_set (G_OBJECT(self), "wizard-name", _("mcen_ti_emailsetup"), NULL);
+
+       /* Read in the information about known service providers: */
+       ModestEasysetupWizardDialogPrivate *priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+       
+       /* The server fields did not have been manually changed yet */
+       priv->server_changes = 0;
+       priv->pending_load_settings = TRUE;
+
+       /* Get the account manager object, 
+        * so we can check for existing accounts,
+        * and create new accounts: */
+       priv->account_manager = modest_runtime_get_account_mgr ();
+       g_object_ref (priv->account_manager);
+       
+       /* Initialize fields */
+       priv->page_welcome = create_page_welcome (self);
+       priv->page_account_details = create_page_account_details (self);
+
+       init_user_page (priv);
+       init_incoming_page (priv);
+       init_outgoing_page (priv);
+
+       priv->page_complete_easysetup = NULL;       
+       priv->page_complete_customsetup = NULL;
+       priv->last_plugin_protocol_selected = MODEST_PROTOCOL_REGISTRY_TYPE_INVALID;
+       priv->missing_data_signals = NULL;
+
+       /* Add the common pages */
+       modest_easysetup_wizard_dialog_append_page (notebook, priv->page_welcome, 
+                                                   _("mcen_ti_emailsetup_welcome"));
+       modest_easysetup_wizard_dialog_append_page (notebook, priv->page_account_details, 
+                                                   _("mcen_ti_accountdetails"));
+               
+       /* Connect to the dialog's response signal so we can enable/disable buttons 
+        * for the newly-selected page, because the prev/next buttons cause response to be emitted.
+        * Note that we use g_signal_connect_after() instead of g_signal_connect()
+        * so that we can be enable/disable after ModestWizardDialog has done its own 
+        * enabling/disabling of buttons.
+        * 
+        * HOWEVER, this doesn't work because ModestWizardDialog's response signal handler 
+        * does g_signal_stop_emission_by_name(), stopping our signal handler from running.
+        * 
+        * It's not enough to connect to the notebook's switch-page signal, because 
+        * ModestWizardDialog's "response" signal handler enables the buttons itself, 
+        * _after_ switching the page (understandably).
+        * (Note that if we had, if we used g_signal_connect() instead of g_signal_connect_after()
+        * then gtk_notebook_get_current_page() would return an incorrect value.)
+        */
+       g_signal_connect_after (G_OBJECT (self), "response",
+                               G_CALLBACK (on_response), self);
+
+       /* This is to show a confirmation dialog when the user hits cancel */
+       g_signal_connect (G_OBJECT (self), "response",
+                         G_CALLBACK (on_response_before), self);
+
+       g_signal_connect (G_OBJECT (self), "delete-event",
+                         G_CALLBACK (on_delete_event), self);
+
+       /* Reset dirty, because there was no user input until now */
+       priv->dirty = FALSE;
+       
+       /* When this window is shown, hibernation should not be possible, 
+        * because there is no sensible way to save the state: */
+       modest_window_mgr_prevent_hibernation_while_window_is_shown (
+               modest_runtime_get_window_mgr (), GTK_WINDOW (self)); 
+
+       /* Load provider presets */
+       g_object_ref (self);
+       g_thread_create (presets_loader, self, FALSE, NULL);
+
+       hildon_help_dialog_help_enable (GTK_DIALOG(self), "applications_email_wizardwelcome",
+                                       modest_maemo_utils_get_osso_context()); 
+
+       priv->settings = modest_account_settings_new ();
+}
+
+ModestEasysetupWizardDialog*
+modest_easysetup_wizard_dialog_new (void)
+{      
+       
+       return g_object_new (MODEST_TYPE_EASYSETUP_WIZARD_DIALOG, NULL);
+}
+
+static void 
+create_subsequent_customsetup_pages (ModestEasysetupWizardDialog *self)
+{
+       ModestEasysetupWizardDialogPrivate *priv;
+       GtkNotebook *notebook = NULL;
+
+       g_object_get (self, "wizard-notebook", &notebook, NULL);
+       g_assert(notebook);
+
+       priv = MODEST_EASYSETUP_WIZARD_DIALOG_GET_PRIVATE (self);
+
+       if (!priv->page_user_details) {
+               priv->page_user_details = create_page_user_details (self);
+       }                       
+
+       /* Create the custom pages: */
+       if(!(priv->page_custom_incoming)) {
+               priv->page_custom_incoming = create_page_custom_incoming (self);
+       }
+               
+       /* TODO: only if needed */