diff -Nru evolution-3.16.0/aclocal.m4 evolution-3.12.11/aclocal.m4 --- evolution-3.16.0/aclocal.m4 2015-03-23 06:59:14.000000000 +0000 +++ evolution-3.12.11/aclocal.m4 2015-02-09 08:21:51.000000000 +0000 @@ -20,187 +20,6 @@ If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# SYNOPSIS -# -# AX_CODE_COVERAGE() -# -# DESCRIPTION -# -# Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be -# included in the CFLAGS and LIBS/LDFLAGS variables of every build target -# (program or library) which should be built with code coverage support. -# Also defines CODE_COVERAGE_RULES which should be substituted in your -# Makefile; and $enable_code_coverage which can be used in subsequent -# configure output. CODE_COVERAGE_ENABLED is defined and substituted, and -# corresponds to the value of the --enable-code-coverage option, which -# defaults to being disabled. -# -# Note that all optimisation flags in CFLAGS must be disabled when code -# coverage is enabled. -# -# Usage example: -# configure.ac: -# AX_CODE_COVERAGE -# -# Makefile.am: -# @CODE_COVERAGE_RULES@ -# my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) … -# my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) … -# -# This results in a “check-code-coverage” rule being added to any Makefile.am -# which includes “@CODE_COVERAGE_RULES@” (assuming the module has been -# configured with --enable-code-coverage). Running `make check-code-coverage` -# in that directory will run the module’s test suite (`make check`) and build -# a code coverage report detailing the code which was touched, then print the -# URI for the report. -# -# LICENSE -# -# Copyright © 2012, 2014 Philip Withnall -# Copyright © 2012 Xan Lopez -# Copyright © 2012 Christian Persch -# Copyright © 2012 Paolo Borelli -# Copyright © 2012 Dan Winship -# -# Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+. -# This file is licenced under LGPLv2.1+. - -#serial 1 - -AC_DEFUN([AX_CODE_COVERAGE],[ - dnl Check for --enable-code-coverage - AC_MSG_CHECKING([whether to build with code coverage support]) - AC_ARG_ENABLE([code-coverage], AS_HELP_STRING([--enable-code-coverage], [Whether to enable code coverage support]),, enable_code_coverage=no) - AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes]) - AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage]) - AC_MSG_RESULT($enable_code_coverage) - - AS_IF([ test "$enable_code_coverage" = "yes" ], [ - dnl Check if gcc is being used - AS_IF([ test "$GCC" = "no" ], [ - AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage]) - ]) - - # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" - - AC_CHECK_PROG([LCOV], [lcov], [lcov]) - AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) - - AS_IF([ test "$LCOV" ], [ - AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [ - ax_cv_lcov_version=invalid - lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` - for lcov_check_version in $lcov_version_list; do - if test "$lcov_version" = "$lcov_check_version"; then - ax_cv_lcov_version="$lcov_check_version (ok)" - fi - done - ]) - ], [ - lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" - AC_MSG_ERROR([$lcov_msg]) - ]) - - case $ax_cv_lcov_version in - ""|invalid[)] - lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." - AC_MSG_ERROR([$lcov_msg]) - LCOV="exit 0;" - ;; - esac - - AS_IF([ test -z "$GENHTML" ], [ - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - ]) - - dnl Build the code coverage flags - CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage" - CODE_COVERAGE_LDFLAGS="-lgcov" - - AC_SUBST([CODE_COVERAGE_CFLAGS]) - AC_SUBST([CODE_COVERAGE_LDFLAGS]) - ]) - -CODE_COVERAGE_RULES=' -# Code coverage -# -# Optional: -# - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting. -# (Default: $(top_builddir)) -# - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated -# by lcov for code coverage. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info) -# - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage -# reports to be created. (Default: -# $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage) -# - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the lcov instance. -# (Default: empty) -# - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml -# instance. (Default: empty) -# - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore -# -# The generated report will be titled using the $(PACKAGE_NAME) and -# $(PACKAGE_VERSION). In order to add the current git hash to the title, -# use the git-version-gen script, available online. - -# Optional variables -CODE_COVERAGE_DIRECTORY ?= $(top_builddir) -CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info -CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage -CODE_COVERAGE_LCOV_OPTIONS ?= -CODE_COVERAGE_GENHTML_OPTIONS ?= -CODE_COVERAGE_IGNORE_PATTERN ?= - -code_coverage_quiet = $(code_coverage_quiet_$(V)) -code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY)) -code_coverage_quiet_0 = --quiet - -# Use recursive makes in order to ignore errors during check -check-code-coverage: -ifeq ($(CODE_COVERAGE_ENABLED),yes) - -$(MAKE) $(AM_MAKEFLAGS) -k check - $(MAKE) $(AM_MAKEFLAGS) code-coverage-capture -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Capture code coverage data -code-coverage-capture: code-coverage-capture-hook -ifeq ($(CODE_COVERAGE_ENABLED),yes) - $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_OPTIONS) - $(LCOV) $(code_coverage_quiet) --directory $(CODE_COVERAGE_DIRECTORY) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" - -@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp - LANG=C $(GENHTML) $(code_coverage_quiet) --prefix $(CODE_COVERAGE_DIRECTORY) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS) - @echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html" -else - @echo "Need to reconfigure with --enable-code-coverage" -endif - -# Hook rule executed before code-coverage-capture, overridable by the user -code-coverage-capture-hook: - -ifeq ($(CODE_COVERAGE_ENABLED),yes) -clean: code-coverage-clean -code-coverage-clean: - -$(LCOV) --directory $(top_builddir) -z - -rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -find . -name "*.gcda" -o -name "*.gcov" -delete -endif - -GITIGNOREFILES ?= -GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY) - -DISTCHECK_CONFIGURE_FLAGS ?= -DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage - -.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean -' - - AC_SUBST([CODE_COVERAGE_RULES]) - m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])]) -]) - # Configure paths for GLIB # Owen Taylor 1997-2001 @@ -413,48 +232,6 @@ rm -f conf.glibtest ]) -dnl GNOME_CODE_COVERAGE -dnl -dnl Defines CODE_COVERAGE_CFLAGS and CODE_COVERAGE_LDFLAGS which should be -dnl included in the CFLAGS and LIBS/LDFLAGS variables of every build target -dnl (program or library) which should be built with code coverage support. -dnl Also defines GNOME_CODE_COVERAGE_RULES which should be substituted in your -dnl Makefile; and $enable_code_coverage which can be used in subsequent -dnl configure output. -dnl -dnl Note that all optimisation flags in CFLAGS must be disabled when code -dnl coverage is enabled. -dnl -dnl Derived from Makefile.decl in GLib, originally licenced under LGPLv2.1+. -dnl This file is licenced under LGPLv2.1+. -dnl -dnl Usage example: -dnl configure.ac: -dnl GNOME_CODE_COVERAGE -dnl -dnl Makefile.am: -dnl @GNOME_CODE_COVERAGE_RULES@ -dnl my_program_LIBS = … $(CODE_COVERAGE_LDFLAGS) … -dnl my_program_CFLAGS = … $(CODE_COVERAGE_CFLAGS) … -dnl -dnl This results in a “check-code-coverage” rule being added to any Makefile.am -dnl which includes “@GNOME_CODE_COVERAGE_RULES@” (assuming the module has been -dnl configured with --enable-code-coverage). Running `make check-code-coverage` -dnl in that directory will run the module’s test suite (`make check`) and build -dnl a code coverage report detailing the code which was touched, then print the -dnl URI for the report. - -AU_DEFUN([GNOME_CODE_COVERAGE],[ - AX_CODE_COVERAGE - GNOME_CODE_COVERAGE_RULES=$CODE_COVERAGE_RULES - - AC_SUBST([GNOME_CODE_COVERAGE_RULES]) - m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([GNOME_CODE_COVERAGE_RULES])]) -], -[[$0: This macro is deprecated. You should use AX_CODE_COVERAGE instead and -replace uses of GNOME_CODE_COVERAGE_RULES with CODE_COVERAGE_RULES. -See: http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html#ax_code_coverage]]) - dnl GLIB_GSETTINGS dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether dnl the schema should be compiled @@ -2166,7 +1943,6 @@ m4_include([m4/as-ac-expand.m4]) m4_include([m4/as-compiler-flag.m4]) -m4_include([m4/behave-installed-tests.m4]) m4_include([m4/evo_check_langinfo.m4]) m4_include([m4/evo_ldap_check.m4]) m4_include([m4/evo_purify_support.m4]) diff -Nru evolution-3.16.0/addressbook/addressbook.error.xml evolution-3.12.11/addressbook/addressbook.error.xml --- evolution-3.16.0/addressbook/addressbook.error.xml 2014-05-12 14:59:18.000000000 +0000 +++ evolution-3.12.11/addressbook/addressbook.error.xml 2014-03-24 09:25:23.000000000 +0000 @@ -65,11 +65,6 @@ {0} - - <_primary>Failed to refresh address book '{0}' - {1} - - <_primary>Would you like to save your changes? <_secondary>You have made modifications to this contact. Do you want to save these changes? diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/contact-editor.ui evolution-3.12.11/addressbook/gui/contact-editor/contact-editor.ui --- evolution-3.16.0/addressbook/gui/contact-editor/contact-editor.ui 2014-09-24 06:50:29.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/contact-editor.ui 2014-03-24 09:25:23.000000000 +0000 @@ -307,38 +307,68 @@ vertical 10 - + True + 0 + none - + True - - + 12 + 3 + 4 + 6 + 6 + + True - Email - - - + True + email-3 + + 1 + 2 + 1 + 2 + + - - - 0 - - - - - True - 12 - vertical - 6 - + True + True + email-1 - 0 + 1 + 2 + + + + + + True + True + email-2 + + + 3 + 4 + + + + + + True + True + email-4 + + + 3 + 4 + 1 + 2 + @@ -351,51 +381,124 @@ True - 1 + 4 + 2 + 3 + GTK_FILL + + + + + + True + model2 + + + + 0 + + + + + GTK_FILL + GTK_FILL + + + + + True + model3 + + + + 0 + + + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + model4 + + + + 0 + + + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + model5 + + + + 0 + + + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL - - 1 - - - - False - False - 0 - - - - - True - - + + True - - + 4 + + True - Telephone + Email + + False + False + 0 + - - - 0 - - - - - True - 12 - vertical - 6 - + + 20 + 20 True + True + False + none + + + Email + + + + + True + none + + 1 @@ -406,99 +509,424 @@ False - 1 + False + 0 - + True + vertical - + True - - + 0 + none + + True - SIP Address - - - + 12 + vertical + 6 + + + True + 2 + 4 + 6 + 6 + + + True + True + + + 1 + 2 + + + + + + True + True + + + 1 + 2 + 1 + 2 + + + + + + True + True + + + 3 + 4 + 1 + 2 + + + + + + True + True + + + 3 + 4 + + + + + + True + + + GTK_FILL + GTK_FILL + + + + + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + False + 0 + + + + + 2 + 4 + 6 + 6 + + + True + True + + + 1 + 2 + + + + + + True + True + + + 1 + 2 + 1 + 2 + + + + + + True + True + + + 3 + 4 + + + + + + True + True + + + 3 + 4 + 1 + 2 + + + + + + True + + + GTK_FILL + GTK_FILL + + + + + True + + + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + False + 1 + + - - - 0 - - - - - True - 12 - vertical - 6 - - + + True + 4 + + + True + Telephone + + + + + + False + False + 0 + + + + + 20 + 20 + True + True + False + none + + + Telephone + + + + + True + none + + + + + 1 + + - - 0 - - 1 + False + 0 False - 2 + 1 - + True + 0 + none - + True - - + 12 + 2 + 4 + 6 + 6 + + True - Instant Messaging - - - + True + + 1 + 2 + 0 + 1 + + - - - 0 - - - - - True - 12 - vertical - 6 - + True + True - 0 + 1 + 2 + 1 + 2 + + + + + + True + True + + + 3 + 4 + 0 + 1 + + + + + + True + True + + + 3 + 4 + 1 + 2 + + + + + + True + + + 0 + 1 + 0 + 1 + GTK_FILL + GTK_FILL + + + + + True + + + 0 + 1 + 1 + 2 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + 0 + 1 + GTK_FILL + GTK_FILL + + + + + True + + + 2 + 3 + 1 + 2 + GTK_FILL + GTK_FILL - - 1 - + + + + True + Instant Messaging + + + + False - 3 + 2 @@ -522,7 +950,7 @@ - + True True automatic @@ -539,10 +967,12 @@ True 12 vertical - 0 + 12 - + True + 0 + none True @@ -711,12 +1141,45 @@ - + True - Web Addresses - - - + 4 + + + True + Web Addresses + + + + + + 0 + + + + + 20 + 20 + True + True + False + none + + + Web addresses + + + + + True + none + + + + + 1 + + @@ -726,8 +1189,10 @@ - + True + 0 + none True @@ -1134,7 +1599,7 @@ - + True True automatic @@ -1151,13 +1616,11 @@ True vertical - + True 6 0 none - FALSE - GTK_ALIGN_START True @@ -1392,18 +1855,14 @@ 0 - FALSE - FALSE - + True 6 0 none - FALSE - GTK_ALIGN_START True @@ -1638,8 +2097,6 @@ 1 - FALSE - FALSE @@ -1647,8 +2104,6 @@ True True 6 - FALSE - GTK_ALIGN_START True @@ -1883,8 +2338,6 @@ 2 - FALSE - FALSE @@ -1907,7 +2360,7 @@ - + True True 12 @@ -1958,34 +2411,7 @@ False False - 4 - - - - - up - True - True - True - False - False - True - end - Options - - - True - emblem-system-symbolic - 1 - - - - - False - False - 1 + 0 @@ -2001,7 +2427,7 @@ False False - 2 + 1 @@ -2019,7 +2445,7 @@ False False - 3 + 2 @@ -2037,108 +2463,4 @@ button-ok - - - True - False - - - True - False - Show Telephone - True - - - - - True - False - Show SIP Address - True - - - - - True - False - Show Instant Messaging - True - - - - - True - False - - - - - True - False - Show Web Addresses - True - - - - - True - False - Show Job section - True - - - - - True - False - Show Miscellaneous - True - - - - - True - False - - - - - True - False - Show Home Mailing Address - True - - - - - True - False - Show Work Mailing Address - True - - - - - True - False - Show Other Mailing Address - True - - - - - True - False - - - - - True - False - Show Notes - True - - - - diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor.c evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor.c --- evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor.c 2014-11-13 07:31:44.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor.c 2014-09-02 08:21:25.000000000 +0000 @@ -40,39 +40,18 @@ #include "addressbook/printing/e-contact-print.h" #include "addressbook/gui/widgets/eab-gui-util.h" -#include "addressbook/util/eab-book-util.h" #include "eab-contact-merging.h" #include "e-contact-editor-fullname.h" -#include "e-contact-editor-dyntable.h" -#define SLOTS_PER_LINE 2 -#define SLOTS_IN_COLLAPSED_STATE SLOTS_PER_LINE -#define EMAIL_SLOTS 50 -#define PHONE_SLOTS 50 -#define SIP_SLOTS 4 -#define IM_SLOTS 50 +#define EMAIL_SLOTS 4 +#define PHONE_SLOTS 8 +#define IM_SLOTS 4 #define ADDRESS_SLOTS 3 -/* represents index in address_name */ -#define ADDRESS_SLOT_HOME 1 -#define ADDRESS_SLOT_WORK 0 -#define ADDRESS_SLOT_OTHER 2 - #define EVOLUTION_UI_SLOT_PARAM "X-EVOLUTION-UI-SLOT" -#define CHECK_PHONE 1 -#define CHECK_SIP 2 -#define CHECK_IM 3 -#define CHECK_HOME 4 -#define CHECK_WORK 5 -#define CHECK_OTHER 6 -#define CHECK_WEB 7 -#define CHECK_JOB 8 -#define CHECK_MISC 9 -#define CHECK_NOTE 10 - /* IM columns */ enum { COLUMN_IM_ICON, @@ -137,7 +116,32 @@ DYNAMIC_LIST_ADDRESS }; -/* Defaults selected from eab_phone_types */ +static struct { + EContactField field_id; + const gchar *type_1; + const gchar *type_2; +} +phones[] = { + { E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT, NULL }, + { E_CONTACT_PHONE_BUSINESS, "WORK", "VOICE" }, + { E_CONTACT_PHONE_BUSINESS_FAX, "WORK", "FAX" }, + { E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK, NULL }, + { E_CONTACT_PHONE_CAR, "CAR", NULL }, + { E_CONTACT_PHONE_COMPANY, "X-EVOLUTION-COMPANY", NULL }, + { E_CONTACT_PHONE_HOME, "HOME", "VOICE" }, + { E_CONTACT_PHONE_HOME_FAX, "HOME", "FAX" }, + { E_CONTACT_PHONE_ISDN, "ISDN", NULL }, + { E_CONTACT_PHONE_MOBILE, "CELL", NULL }, + { E_CONTACT_PHONE_OTHER, "VOICE", NULL }, + { E_CONTACT_PHONE_OTHER_FAX, "FAX", NULL }, + { E_CONTACT_PHONE_PAGER, "PAGER", NULL }, + { E_CONTACT_PHONE_PRIMARY, "PREF", NULL }, + { E_CONTACT_PHONE_RADIO, EVC_X_RADIO, NULL }, + { E_CONTACT_PHONE_TELEX, EVC_X_TELEX, NULL }, + { E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD, NULL } +}; + +/* Defaults from the table above */ static const gint phones_default[] = { 1, 6, 9, 2, 7, 12, 10, 10 }; static EContactField addresses[] = { @@ -158,31 +162,39 @@ "other" }; -/* - * keep fetch_set in sync with labels from eab_im_service - */ -static EContactField -im_service_fetch_set[] = -{ - E_CONTACT_IM_AIM, - E_CONTACT_IM_JABBER, - E_CONTACT_IM_YAHOO, - E_CONTACT_IM_GADUGADU, - E_CONTACT_IM_MSN, - E_CONTACT_IM_ICQ, - E_CONTACT_IM_GROUPWISE, - E_CONTACT_IM_SKYPE, - E_CONTACT_IM_TWITTER, - E_CONTACT_IM_GOOGLE_TALK +static struct { + EContactField field; + const gchar *pretty_name; +} +im_service[] = +{ + { E_CONTACT_IM_AIM, N_ ("AIM") }, + { E_CONTACT_IM_JABBER, N_ ("Jabber") }, + { E_CONTACT_IM_YAHOO, N_ ("Yahoo") }, + { E_CONTACT_IM_GADUGADU, N_ ("Gadu-Gadu") }, + { E_CONTACT_IM_MSN, N_ ("MSN") }, + { E_CONTACT_IM_ICQ, N_ ("ICQ") }, + { E_CONTACT_IM_GROUPWISE, N_ ("GroupWise") }, + { E_CONTACT_IM_SKYPE, N_ ("Skype") }, + { E_CONTACT_IM_TWITTER, N_ ("Twitter") } }; -/* Defaults selected from eab_get_im_type_labels */ +/* Defaults from the table above */ static const gint im_service_default[] = { 0, 2, 4, 5 }; +static struct { + const gchar *name; + const gchar *pretty_name; +} +common_location[] = +{ + { "WORK", N_ ("Work") }, + { "HOME", N_ ("Home") }, + { "OTHER", N_ ("Other") } +}; /* Default from the table above */ static const gint email_default[] = { 0, 1, 2, 2 }; -static const gint sips_default[] = { 0, 1, 2, 2 }; #define STRING_IS_EMPTY(x) (!(x) || !(*(x))) #define STRING_MAKE_NON_NULL(x) ((x) ? (x) : "") @@ -254,14 +266,14 @@ { "undo", "edit-undo", - N_("_Undo"), + N_("Undo"), "z", N_("Undo"), NULL }, /* Handled by EFocusTracker */ { "redo", "edit-redo", - N_("_Redo"), + N_("Redo"), "y", N_("Redo"), NULL } /* Handled by EFocusTracker */ @@ -869,29 +881,170 @@ } static void -init_email_record_location (EContactEditor *editor) +set_combo_box_active (EContactEditor *editor, + GtkComboBox *combo_box, + gint active) { - GtkWidget *w; + g_signal_handlers_block_matched ( + combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); + gtk_combo_box_set_active (combo_box, active); + g_signal_handlers_unblock_matched ( + combo_box, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, editor); +} + +static void +init_email_record_location (EContactEditor *editor, + gint record) +{ + GtkComboBox *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + gint i; + GtkTreeIter iter; GtkListStore *store; - gint i, n_elements; - EContactEditorDynTable *dyntable; - const EABTypeLabel *email_types = eab_get_email_type_labels (&n_elements); - - w = e_builder_get_widget (editor->priv->builder, "mail-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - store = e_contact_editor_dyntable_get_combo_store (dyntable); - for (i = 0; i < n_elements; i++) { - GtkTreeIter iter; + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = GTK_COMBO_BOX ( + e_builder_get_widget (editor->priv->builder, widget_name)); + g_free (widget_name); + + store = GTK_LIST_STORE (gtk_combo_box_get_model (location_combo_box)); + gtk_list_store_clear (store); + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - DYNTABLE_COMBO_COLUMN_TEXT, _(email_types[i].text), - DYNTABLE_COMBO_COLUMN_SENSITIVE, TRUE, - -1); + gtk_list_store_set ( + store, &iter, + 0, _(common_location[i].pretty_name), + -1); + } + + g_signal_connect_swapped ( + location_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), email_entry); + g_signal_connect ( + location_combo_box, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect ( + email_entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + email_entry, "activate", + G_CALLBACK (entry_activated), editor); +} + +static void +fill_in_email_record (EContactEditor *editor, + gint record, + const gchar *address, + gint location) +{ + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + set_combo_box_active ( + editor, GTK_COMBO_BOX (location_combo_box), + location >= 0 ? location : email_default[2]); + set_entry_text (editor, GTK_ENTRY (email_entry), address ? address : ""); +} + +static void +extract_email_record (EContactEditor *editor, + gint record, + gchar **address, + gint *location) +{ + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; + const gchar *text; + + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + text = gtk_entry_get_text (GTK_ENTRY (email_entry)); + *address = g_strstrip (g_strdup (text)); + *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box)); +} + +static const gchar * +email_index_to_location (gint index) +{ + return common_location[index].name; +} + +static const gchar * +im_index_to_location (gint index) +{ + return common_location[index].name; +} + +static void +phone_index_to_type (gint index, + const gchar **type_1, + const gchar **type_2) +{ + *type_1 = phones [index].type_1; + *type_2 = phones [index].type_2; +} + +static gint +get_email_location (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return i; + } + + return -1; +} + +static gint +get_im_location (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return i; + } + + return -1; +} + +static gint +get_phone_type (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + if (e_vcard_attribute_has_type (attr, phones[i].type_1) && + (phones[i].type_2 == NULL || + e_vcard_attribute_has_type (attr, phones[i].type_2))) + return i; } - e_contact_editor_dyntable_set_combo_defaults (dyntable, email_default, G_N_ELEMENTS (email_default)); + return -1; } static EVCardAttributeParam * @@ -956,55 +1109,99 @@ g_free (slot_str); } +static gint +alloc_ui_slot (EContactEditor *editor, + const gchar *widget_base, + gint preferred_slot, + gint num_slots) +{ + gchar *widget_name; + GtkWidget *widget; + const gchar *entry_contents; + gint i; + + /* See if we can get the preferred slot */ + + if (preferred_slot >= 1) { + widget_name = g_strdup_printf ("%s-%d", widget_base, preferred_slot); + widget = e_builder_get_widget (editor->priv->builder, widget_name); + entry_contents = gtk_entry_get_text (GTK_ENTRY (widget)); + g_free (widget_name); + + if (STRING_IS_EMPTY (entry_contents)) + return preferred_slot; + } + + /* Find first empty slot */ + + for (i = 1; i <= num_slots; i++) { + widget_name = g_strdup_printf ("%s-%d", widget_base, i); + widget = e_builder_get_widget (editor->priv->builder, widget_name); + entry_contents = gtk_entry_get_text (GTK_ENTRY (widget)); + g_free (widget_name); + + if (STRING_IS_EMPTY (entry_contents)) + return i; + } + + return -1; +} + +static void +free_attr_list (GList *attr_list) +{ + GList *l; + + for (l = attr_list; l; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + e_vcard_attribute_free (attr); + } + + g_list_free (attr_list); +} + static void fill_in_email (EContactEditor *editor) { GList *email_attr_list; GList *l; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeIter iter; - - w = e_builder_get_widget (editor->priv->builder, "mail-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); + gint record_n; /* Clear */ - e_contact_editor_dyntable_clear_data (dyntable); + for (record_n = 1; record_n <= EMAIL_SLOTS; record_n++) { + fill_in_email_record ( + editor, record_n, NULL, email_default[record_n - 1]); + } /* Fill in */ - data_store = e_contact_editor_dyntable_extract_data (dyntable); - email_attr_list = e_contact_get_attributes ( editor->priv->contact, E_CONTACT_EMAIL); - for (l = email_attr_list; l; l = g_list_next (l)) { + for (record_n = 1, l = email_attr_list; + l && record_n <= EMAIL_SLOTS; l = g_list_next (l)) { EVCardAttribute *attr = l->data; gchar *email_address; - gint email_location; gint slot; email_address = e_vcard_attribute_get_value (attr); - email_location = eab_get_email_type_index (attr); - slot = get_ui_slot (attr); + slot = alloc_ui_slot ( + editor, "entry-email", + get_ui_slot (attr), EMAIL_SLOTS); if (slot < 1) - slot = EMAIL_SLOTS + 1; //add at the end + break; + + fill_in_email_record ( + editor, slot, email_address, + get_email_location (attr)); - gtk_list_store_append (data_store, &iter); - gtk_list_store_set (data_store, &iter, - DYNTABLE_STORE_COLUMN_SORTORDER, slot, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, email_location, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, email_address, - -1); + record_n++; g_free (email_address); } g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free); - - e_contact_editor_dyntable_fill_in_data (dyntable); } static void @@ -1014,48 +1211,32 @@ GList *old_attr_list; GList *ll; gint i; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeModel *tree_model; - GtkTreeIter iter; - gboolean valid; - - w = e_builder_get_widget (editor->priv->builder, "mail-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - data_store = e_contact_editor_dyntable_extract_data (dyntable); - tree_model = GTK_TREE_MODEL (data_store); - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - while (valid) { + for (i = 1; i <= EMAIL_SLOTS; i++) { gchar *address; gint location; - EVCardAttribute *attr; - attr = e_vcard_attribute_new ( - "", e_contact_vcard_attribute (E_CONTACT_EMAIL)); + extract_email_record (editor, i, &address, &location); - gtk_tree_model_get (tree_model,&iter, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &location, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, &address, - -1); - - if (location >= 0) { - const gchar *type; - eab_email_index_to_type (location, &type); - e_vcard_attribute_add_param_with_value ( - attr, - e_vcard_attribute_param_new (EVC_TYPE), - type); - } + if (!STRING_IS_EMPTY (address)) { + EVCardAttribute *attr; + attr = e_vcard_attribute_new ( + "", e_contact_vcard_attribute (E_CONTACT_EMAIL)); + + if (location >= 0) + e_vcard_attribute_add_param_with_value ( + attr, + e_vcard_attribute_param_new (EVC_TYPE), + email_index_to_location (location)); - e_vcard_attribute_add_value (attr, address); + e_vcard_attribute_add_value (attr, address); + set_ui_slot (attr, i); - attr_list = g_list_prepend (attr_list, attr); + attr_list = g_list_append (attr_list, attr); + } - valid = gtk_tree_model_iter_next (tree_model, &iter); + g_free (address); } - attr_list = g_list_reverse (attr_list); /* Splice in the old attributes, minus the EMAIL_SLOTS first */ @@ -1070,976 +1251,624 @@ e_contact_set_attributes (editor->priv->contact, E_CONTACT_EMAIL, attr_list); - g_list_free_full (attr_list, (GDestroyNotify) e_vcard_attribute_free); + free_attr_list (attr_list); } static void -sensitize_email (EContactEditor *editor) +sensitize_email_record (EContactEditor *editor, + gint record, + gboolean enabled) { - gboolean enabled = FALSE; - GtkWidget *w; - EContactEditorDynTable *dyntable; - guint max_entries = SLOTS_IN_COLLAPSED_STATE; - - w = e_builder_get_widget (editor->priv->builder, "mail-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - - if (editor->priv->target_editable) { - if (is_field_supported (editor, E_CONTACT_EMAIL)) { - enabled = TRUE; - max_entries = EMAIL_SLOTS; - } else if (is_field_supported (editor, E_CONTACT_EMAIL_4)) { - enabled = TRUE; - max_entries = 4; - } else if (is_field_supported (editor, E_CONTACT_EMAIL_3)) { - enabled = TRUE; - max_entries = 3; - } else if (is_field_supported (editor, E_CONTACT_EMAIL_2)) { - enabled = TRUE; - max_entries = 2; - } else if (is_field_supported (editor, E_CONTACT_EMAIL_1)) { - enabled = TRUE; - max_entries = 1; - } - } + GtkWidget *location_combo_box; + GtkWidget *email_entry; + gchar *widget_name; - gtk_widget_set_sensitive (w, enabled); - e_contact_editor_dyntable_set_max_entries (dyntable, max_entries); -} + widget_name = g_strdup_printf ("combobox-email-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); -static void -row_added_cb (GtkExpander *expander) -{ - /* newly added row is always visible, setting expanded=true */ - gtk_expander_set_expanded (expander, TRUE); + widget_name = g_strdup_printf ("entry-email-%d", record); + email_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + gtk_widget_set_sensitive (location_combo_box, enabled); + gtk_editable_set_editable (GTK_EDITABLE (email_entry), enabled); } static void -init_email (EContactEditor *editor) +sensitize_email (EContactEditor *editor) { - EContactEditorDynTable *dyntable; - GtkExpander *expander; + gint i; - expander = GTK_EXPANDER ( - e_builder_get_widget (editor->priv->builder, "expander-contact-email")); - dyntable = E_CONTACT_EDITOR_DYNTABLE ( - e_builder_get_widget (editor->priv->builder, "mail-dyntable")); - - e_contact_editor_dyntable_set_max_entries (dyntable, EMAIL_SLOTS); - e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE); - e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE); + for (i = 1; i <= EMAIL_SLOTS; i++) { + gboolean enabled = TRUE; - g_signal_connect ( - dyntable, "changed", - G_CALLBACK (object_changed), editor); - g_signal_connect_swapped ( - dyntable, "activate", - G_CALLBACK (entry_activated), editor); - g_signal_connect_swapped ( - dyntable, "row-added", - G_CALLBACK (row_added_cb), expander); + if (!editor->priv->target_editable) + enabled = FALSE; - init_email_record_location (editor); + if (E_CONTACT_FIRST_EMAIL_ID + i - 1 <= E_CONTACT_LAST_EMAIL_ID && + !is_field_supported (editor, E_CONTACT_FIRST_EMAIL_ID + i - 1)) + enabled = FALSE; - gtk_expander_set_expanded (expander, TRUE); + sensitize_email_record (editor, i, enabled); + } } static void -fill_in_phone (EContactEditor *editor) +init_item_sensitiveable_combo_box (GtkComboBox *combo) { - GList *tel_attr_list; - GList *l; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeIter iter; + GtkCellRenderer *cell; + GtkListStore *store; - w = e_builder_get_widget (editor->priv->builder, "phone-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); + g_return_if_fail (combo != NULL); + g_return_if_fail (GTK_IS_COMBO_BOX (combo)); - /* Clear */ + store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_BOOLEAN); + gtk_combo_box_set_model (combo, GTK_TREE_MODEL (store)); + g_object_unref (store); - e_contact_editor_dyntable_clear_data (dyntable); + gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); - /* Fill in */ + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_attributes ( + GTK_CELL_LAYOUT (combo), cell, + "text", 0, "sensitive", 1, NULL); +} - tel_attr_list = e_contact_get_attributes (editor->priv->contact, E_CONTACT_TEL); +/* EContact can get attributes by field ID only, + * and there is none for TEL, so we need this */ +static GList * +get_attributes_named (EVCard *vcard, + const gchar *attr_name) +{ + GList *attr_list_in; + GList *attr_list_out = NULL; + GList *l; - data_store = e_contact_editor_dyntable_extract_data (dyntable); + attr_list_in = e_vcard_get_attributes (vcard); - for (l = tel_attr_list; l; l = g_list_next (l)) { + for (l = attr_list_in; l; l = g_list_next (l)) { EVCardAttribute *attr = l->data; - gchar *phone; - gint slot; - gint phone_type; + const gchar *name; - slot = get_ui_slot (attr); - if (slot < 0) - slot = PHONE_SLOTS + 1; /* append at the end */ + name = e_vcard_attribute_get_name (attr); - phone_type = eab_get_phone_type_index (attr); - phone = e_vcard_attribute_get_value (attr); - - gtk_list_store_append (data_store, &iter); - gtk_list_store_set (data_store,&iter, - DYNTABLE_STORE_COLUMN_SORTORDER, slot, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, phone_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, phone, - -1); - - g_free (phone); + if (!g_ascii_strcasecmp (attr_name, name)) { + attr_list_out = g_list_append ( + attr_list_out, + e_vcard_attribute_copy (attr)); + } } - e_contact_editor_dyntable_fill_in_data (dyntable); - - g_list_free_full (tel_attr_list, (GDestroyNotify) e_vcard_attribute_free); + return attr_list_out; } +/* EContact can set attributes by field ID only, + * and there is none for TEL, so we need this */ static void -extract_phone (EContactEditor *editor) +set_attributes_named (EVCard *vcard, + const gchar *attr_name, + GList *attr_list) { - GList *tel_attr_list = NULL; - GList *old_attr_list; - GList *ll; - gint i; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeModel *tree_model; - GtkTreeIter iter; - gboolean valid; - - w = e_builder_get_widget (editor->priv->builder, "phone-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - data_store = e_contact_editor_dyntable_extract_data (dyntable); - tree_model = GTK_TREE_MODEL (data_store); - - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - while (valid) { - gint phone_type; - gchar *phone; - EVCardAttribute *attr; - - gtk_tree_model_get (tree_model,&iter, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &phone_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, &phone, - -1); - - attr = e_vcard_attribute_new ("", EVC_TEL); - if (phone_type >= 0) { - const gchar *type_1; - const gchar *type_2; - - eab_phone_index_to_type (phone_type, &type_1, &type_2); - - e_vcard_attribute_add_param_with_value ( - attr, e_vcard_attribute_param_new (EVC_TYPE), type_1); - - if (type_2) - e_vcard_attribute_add_param_with_value ( - attr, e_vcard_attribute_param_new (EVC_TYPE), type_2); - } - - e_vcard_attribute_add_value (attr, phone); - - tel_attr_list = g_list_prepend (tel_attr_list, attr); + GList *l; - valid = gtk_tree_model_iter_next (tree_model, &iter); - } + e_vcard_remove_attributes (vcard, NULL, attr_name); - /* Splice in the old attributes, minus the PHONE_SLOTS first */ + for (l = attr_list; l; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; - tel_attr_list = g_list_reverse (tel_attr_list); - old_attr_list = e_contact_get_attributes (editor->priv->contact, E_CONTACT_TEL); - for (ll = old_attr_list, i = 1; ll && i <= PHONE_SLOTS; i++) { - e_vcard_attribute_free (ll->data); - ll = g_list_delete_link (ll, ll); + e_vcard_add_attribute (vcard, e_vcard_attribute_copy (attr)); } +} - old_attr_list = ll; - tel_attr_list = g_list_concat (tel_attr_list, old_attr_list); - - e_contact_set_attributes (editor->priv->contact, E_CONTACT_TEL, tel_attr_list); +static void +set_arrow_image (EContactEditor *editor, + const gchar *arrow_widget, + gboolean expanded) +{ + GtkWidget *arrow; - g_list_free_full (tel_attr_list, (GDestroyNotify) e_vcard_attribute_free); + arrow = e_builder_get_widget (editor->priv->builder, arrow_widget); + if (expanded) + gtk_arrow_set ( + GTK_ARROW (arrow), GTK_ARROW_DOWN, GTK_SHADOW_NONE); + else + gtk_arrow_set ( + GTK_ARROW (arrow), GTK_ARROW_RIGHT, GTK_SHADOW_NONE); } static void -init_phone_record_type (EContactEditor *editor) +expand_widget_list (EContactEditor *editor, + const gchar **widget_names, + gboolean expanded) { - GtkWidget *w; - GtkListStore *store; - gint i, n_elements; - EContactEditorDynTable *dyntable; - const EABTypeLabel *eab_phone_types; - - w = e_builder_get_widget (editor->priv->builder, "phone-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - store = e_contact_editor_dyntable_get_combo_store (dyntable); - eab_phone_types = eab_get_phone_type_labels (&n_elements); + gint i; + for (i = 0; widget_names[i]; i++) + gtk_widget_set_visible ( + e_builder_get_widget (editor->priv->builder, widget_names[i]), + expanded); +} - for (i = 0; i < n_elements; i++) { - GtkTreeIter iter; +static void +expand_web (EContactEditor *editor, + gboolean expanded) +{ + const gchar *names[] = { + "label-videourl", "label-fburl", + "entry-videourl", "entry-fburl", + NULL + }; + set_arrow_image (editor, "arrow-web-expand", expanded); + expand_widget_list (editor, names, expanded); +} - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - DYNTABLE_COMBO_COLUMN_TEXT, _(eab_phone_types[i].text), - DYNTABLE_COMBO_COLUMN_SENSITIVE, TRUE, - -1); - } +static void +expand_phone (EContactEditor *editor, + gboolean expanded) +{ + const gchar *names[] = { + "entry-phone-3", "combobox-phone-3", + "entry-phone-4", "combobox-phone-4", + "table-phone-extended", NULL + }; + set_arrow_image (editor, "arrow-phone-expand", expanded); + expand_widget_list (editor, names, expanded); +} - e_contact_editor_dyntable_set_combo_defaults (dyntable, phones_default, G_N_ELEMENTS (phones_default)); +static void +expand_mail (EContactEditor *editor, + gboolean expanded) +{ + GtkTable *table; + GtkWidget *check; + const gchar *names[] = { + "entry-email-2", "combobox-email-2", + "entry-email-3", "combobox-email-3", + "entry-email-4", "combobox-email-4", + NULL + }; + set_arrow_image (editor, "arrow-mail-expand", expanded); + expand_widget_list (editor, names, expanded); + + /* move 'use html mail' into position */ + check = e_builder_get_widget (editor->priv->builder, "checkbutton-htmlmail"); + table = GTK_TABLE (e_builder_get_widget (editor->priv->builder, "email-table")); + if (check != NULL && table != NULL) { + GtkWidget *parent; + + g_object_ref (check); + parent = gtk_widget_get_parent (check); + gtk_container_remove (GTK_CONTAINER (parent), check); + if (expanded) + gtk_table_attach_defaults (table, check, 0, 4, 2, 3); + else + gtk_table_attach_defaults (table, check, 2, 4, 0, 1); + g_object_unref (check); + } } static void -init_phone (EContactEditor *editor) +init_email (EContactEditor *editor) { - EContactEditorDynTable *dyntable; - GtkExpander *expander; - - expander = GTK_EXPANDER ( - e_builder_get_widget (editor->priv->builder, "expander-contact-phone")); - dyntable = E_CONTACT_EDITOR_DYNTABLE ( - e_builder_get_widget (editor->priv->builder, "phone-dyntable")); - - e_contact_editor_dyntable_set_max_entries (dyntable, PHONE_SLOTS); - e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE); - e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE); - - g_signal_connect ( - dyntable, "changed", - G_CALLBACK (object_changed), editor); - g_signal_connect_swapped ( - dyntable, "activate", - G_CALLBACK (entry_activated), editor); - g_signal_connect_swapped ( - dyntable, "row-added", - G_CALLBACK (row_added_cb), expander); + gint i; - init_phone_record_type (editor); + for (i = 1; i <= EMAIL_SLOTS; i++) + init_email_record_location (editor, i); - gtk_expander_set_expanded (expander, TRUE); + expand_mail (editor, !editor->priv->compress_ui); } static void -sensitize_phone_types (EContactEditor *editor) +fill_in_phone_record (EContactEditor *editor, + gint record, + const gchar *phone, + gint phone_type) { - GtkWidget *w; - GtkListStore *listStore; - GtkTreeModel *model; - GtkTreeIter iter; - gint i, n_elements; - gboolean valid; - const EABTypeLabel *eab_phone_types; - - w = e_builder_get_widget (editor->priv->builder, "phone-dyntable"); - listStore = e_contact_editor_dyntable_get_combo_store (E_CONTACT_EDITOR_DYNTABLE (w)); - model = GTK_TREE_MODEL (listStore); + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; - valid = gtk_tree_model_get_iter_first (model, &iter); + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - eab_phone_types = eab_get_phone_type_labels (&n_elements); - for (i = 0; i < n_elements; i++) { - if (!valid) { - g_warning (G_STRLOC ": Unexpected end of phone items in combo box"); - return; - } + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - DYNTABLE_COMBO_COLUMN_SENSITIVE, - is_field_supported (editor, eab_phone_types[i].field_id), - -1); + set_combo_box_active ( + editor, GTK_COMBO_BOX (phone_type_combo_box), + phone_type >= 0 ? phone_type : phones_default[record - 1]); + set_entry_text (editor, GTK_ENTRY (phone_entry), phone ? phone : ""); - valid = gtk_tree_model_iter_next (model, &iter); - } + if (phone && *phone && record >= 3) + expand_phone (editor, TRUE); } static void -sensitize_phone (EContactEditor *editor) +extract_phone_record (EContactEditor *editor, + gint record, + gchar **phone, + gint *phone_type) { - GtkWidget *w; - gboolean enabled = FALSE; - gint i, n_elements; - const EABTypeLabel *eab_phone_types; - - w = e_builder_get_widget (editor->priv->builder, "phone-dyntable"); - - eab_phone_types = eab_get_phone_type_labels (&n_elements); - if (editor->priv->target_editable) { - enabled = is_field_supported (editor, E_CONTACT_TEL); - for (i = 0; i < n_elements && !enabled; i++) { - enabled = is_field_supported (editor, eab_phone_types[i].field_id); - } - } + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; - gtk_widget_set_sensitive (w, enabled); + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - sensitize_phone_types (editor); + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + *phone = g_strdup (gtk_entry_get_text (GTK_ENTRY (phone_entry))); + *phone_type = gtk_combo_box_get_active (GTK_COMBO_BOX (phone_type_combo_box)); } static void -fill_in_sip (EContactEditor *editor) +fill_in_phone (EContactEditor *editor) { - GList *sip_attr_list; + GList *phone_attr_list; GList *l; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeIter iter; - - w = e_builder_get_widget (editor->priv->builder, "sip-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); + gint record_n; /* Clear */ - e_contact_editor_dyntable_clear_data (dyntable); + for (record_n = 1; record_n <= PHONE_SLOTS; record_n++) { + fill_in_phone_record (editor, record_n, NULL, -1); + } /* Fill in */ - sip_attr_list = e_contact_get_attributes (editor->priv->contact, E_CONTACT_SIP); + phone_attr_list = get_attributes_named (E_VCARD (editor->priv->contact), "TEL"); - data_store = e_contact_editor_dyntable_extract_data (dyntable); - - for (l = sip_attr_list; l; l = g_list_next (l)) { + for (record_n = 1, l = phone_attr_list; + l && record_n <= PHONE_SLOTS; l = g_list_next (l)) { EVCardAttribute *attr = l->data; - gchar *sip; - gint sip_type; + gchar *phone; + gint slot; - sip_type = eab_get_sip_type_index (attr); - sip = e_vcard_attribute_get_value (attr); + phone = e_vcard_attribute_get_value (attr); + slot = alloc_ui_slot (editor, "entry-phone", get_ui_slot (attr), PHONE_SLOTS); + if (slot < 1) + break; - if (sip_type < 0) - sip_type = 2; + fill_in_phone_record ( + editor, slot, phone, get_phone_type (attr)); - gtk_list_store_append (data_store, &iter); - gtk_list_store_set (data_store,&iter, - DYNTABLE_STORE_COLUMN_SORTORDER, -1, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, sip_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, sip, - -1); + record_n++; - g_free (sip); + g_free (phone); } - - e_contact_editor_dyntable_fill_in_data (dyntable); - g_list_free_full (sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); } static void -extract_sip (EContactEditor *editor) +extract_phone (EContactEditor *editor) { - GList *sip_attr_list = NULL; + GList *attr_list = NULL; GList *old_attr_list; GList *ll; - gint i; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeModel *tree_model; - GtkTreeIter iter; - gboolean valid; + gint i; - w = e_builder_get_widget (editor->priv->builder, "sip-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - data_store = e_contact_editor_dyntable_extract_data (dyntable); - tree_model = GTK_TREE_MODEL (data_store); - - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - while (valid) { - gint sip_type; - gchar *sip; - EVCardAttribute *attr; + for (i = 1; i <= PHONE_SLOTS; i++) { + gchar *phone; + gint phone_type; - gtk_tree_model_get (tree_model,&iter, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &sip_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, &sip, - -1); - - attr = e_vcard_attribute_new ("", EVC_X_SIP); - if (sip_type >= 0) { - const gchar *type_1; + extract_phone_record (editor, i, &phone, &phone_type); - eab_sip_index_to_type (sip_type, &type_1); + if (!STRING_IS_EMPTY (phone)) { + EVCardAttribute *attr; - e_vcard_attribute_add_param_with_value ( - attr, e_vcard_attribute_param_new (EVC_TYPE), type_1); - } + attr = e_vcard_attribute_new ("", "TEL"); + + if (phone_type >= 0) { + const gchar *type_1; + const gchar *type_2; - e_vcard_attribute_add_value (attr, sip); + phone_index_to_type (phone_type, &type_1, &type_2); - sip_attr_list = g_list_prepend (sip_attr_list, attr); + e_vcard_attribute_add_param_with_value ( + attr, e_vcard_attribute_param_new (EVC_TYPE), type_1); + + if (type_2) + e_vcard_attribute_add_param_with_value ( + attr, e_vcard_attribute_param_new (EVC_TYPE), type_2); + + } - valid = gtk_tree_model_iter_next (tree_model, &iter); + e_vcard_attribute_add_value (attr, phone); + set_ui_slot (attr, i); + + attr_list = g_list_append (attr_list, attr); + } + + g_free (phone); } - /* Splice in the old attributes, minus the SIP_SLOTS first */ + /* Splice in the old attributes, minus the PHONE_SLOTS first */ - sip_attr_list = g_list_reverse (sip_attr_list); - old_attr_list = e_contact_get_attributes (editor->priv->contact, E_CONTACT_SIP); - for (ll = old_attr_list, i = 1; ll && i <= SIP_SLOTS; i++) { + old_attr_list = get_attributes_named (E_VCARD (editor->priv->contact), "TEL"); + for (ll = old_attr_list, i = 1; ll && i <= PHONE_SLOTS; i++) { e_vcard_attribute_free (ll->data); ll = g_list_delete_link (ll, ll); } old_attr_list = ll; - sip_attr_list = g_list_concat (sip_attr_list, old_attr_list); + attr_list = g_list_concat (attr_list, old_attr_list); - e_contact_set_attributes (editor->priv->contact, E_CONTACT_SIP, sip_attr_list); + set_attributes_named (E_VCARD (editor->priv->contact), "TEL", attr_list); - g_list_free_full (sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); + free_attr_list (attr_list); } static void -init_sip_record_type (EContactEditor *editor) +init_phone_record_type (EContactEditor *editor, + gint record) { - GtkWidget *w; + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; + gint i; GtkListStore *store; - gint i, n_elements; - EContactEditorDynTable *dyntable; - const EABTypeLabel *sip_types = eab_get_sip_type_labels (&n_elements); - - w = e_builder_get_widget (editor->priv->builder, "sip-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - store = e_contact_editor_dyntable_get_combo_store (dyntable); - for (i = 0; i < n_elements; i++) { - GtkTreeIter iter; + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - DYNTABLE_COMBO_COLUMN_TEXT, _(sip_types[i].text), - DYNTABLE_COMBO_COLUMN_SENSITIVE, TRUE, - -1); - } + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - e_contact_editor_dyntable_set_combo_defaults (dyntable, sips_default, G_N_ELEMENTS (sips_default)); -} + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (phone_type_combo_box)); -static void -init_sip (EContactEditor *editor) -{ - EContactEditorDynTable *dyntable; - GtkExpander *expander; + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (phone_type_combo_box))); - expander = GTK_EXPANDER ( - e_builder_get_widget (editor->priv->builder, "expander-contact-sip")); - dyntable = E_CONTACT_EDITOR_DYNTABLE ( - e_builder_get_widget (editor->priv->builder, "sip-dyntable")); + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + GtkTreeIter iter; - e_contact_editor_dyntable_set_max_entries (dyntable, SIP_SLOTS); - e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE); - e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE); + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, e_contact_pretty_name (phones[i].field_id), + 1, TRUE, + -1); + } + g_signal_connect_swapped ( + phone_type_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), phone_entry); + g_signal_connect ( + phone_type_combo_box, "changed", + G_CALLBACK (object_changed), editor); g_signal_connect ( - dyntable, "changed", + phone_entry, "changed", G_CALLBACK (object_changed), editor); g_signal_connect_swapped ( - dyntable, "activate", + phone_entry, "activate", G_CALLBACK (entry_activated), editor); - g_signal_connect_swapped ( - dyntable, "row-added", - G_CALLBACK (row_added_cb), expander); - - init_sip_record_type (editor); - - gtk_expander_set_expanded (expander, TRUE); -} - -static gboolean -check_dyntable_for_data (EContactEditor *editor, - const gchar *name) -{ - EContactEditorDynTable *dyntable; - GtkTreeModel *tree_model; - GtkTreeIter iter; - - dyntable = E_CONTACT_EDITOR_DYNTABLE (e_builder_get_widget (editor->priv->builder, name)); - tree_model = GTK_TREE_MODEL (e_contact_editor_dyntable_extract_data (dyntable)); - - return gtk_tree_model_get_iter_first (tree_model, &iter); -} - -static void -extract_address_textview (EContactEditor *editor, - gint record, - EContactAddress *address) -{ - gchar *textview_name; - GtkWidget *textview; - GtkTextBuffer *text_buffer; - GtkTextIter iter_1, iter_2; - - textview_name = g_strdup_printf ("textview-%s-address", address_name[record]); - textview = e_builder_get_widget (editor->priv->builder, textview_name); - g_free (textview_name); - - text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); - gtk_text_buffer_get_start_iter (text_buffer, &iter_1); - - /* Skip blank lines */ - while (gtk_text_iter_get_chars_in_line (&iter_1) < 1 && - !gtk_text_iter_is_end (&iter_1)) - gtk_text_iter_forward_line (&iter_1); - - if (gtk_text_iter_is_end (&iter_1)) - return; - - iter_2 = iter_1; - gtk_text_iter_forward_to_line_end (&iter_2); - - /* Extract street (first line of text) */ - address->street = gtk_text_iter_get_text (&iter_1, &iter_2); - - iter_1 = iter_2; - gtk_text_iter_forward_line (&iter_1); - - if (gtk_text_iter_is_end (&iter_1)) - return; - - gtk_text_iter_forward_to_end (&iter_2); - - /* Extract extended address (remaining lines of text) */ - address->ext = gtk_text_iter_get_text (&iter_1, &iter_2); -} - -static gchar * -extract_address_field (EContactEditor *editor, - gint record, - const gchar *widget_field_name) -{ - gchar *entry_name; - GtkWidget *entry; - - entry_name = g_strdup_printf ( - "entry-%s-%s", address_name[record], widget_field_name); - entry = e_builder_get_widget (editor->priv->builder, entry_name); - g_free (entry_name); - - return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); -} - -static void -extract_address_from_gui (EContactEditor* editor, - EContactAddress* address, - gint record) -{ - extract_address_textview (editor, record, address); - address->locality = extract_address_field (editor, record, "city"); - address->region = extract_address_field (editor, record, "state"); - address->code = extract_address_field (editor, record, "zip"); - address->country = extract_address_field (editor, record, "country"); - address->po = extract_address_field (editor, record, "pobox"); -} - -static gboolean -check_address_for_data (EContactEditor *editor, - gint record) -{ - gboolean has_data = FALSE; - EContactAddress *address; - - address = g_new0 (EContactAddress, 1); - - extract_address_from_gui (editor, address, record); - if (!STRING_IS_EMPTY (address->street) || - !STRING_IS_EMPTY (address->ext) || - !STRING_IS_EMPTY (address->locality) || - !STRING_IS_EMPTY (address->region) || - !STRING_IS_EMPTY (address->code) || - !STRING_IS_EMPTY (address->po) || - !STRING_IS_EMPTY (address->country)) { - has_data = TRUE; - } - - g_free (address); - - return has_data; -} - -static gboolean -check_web_for_data (EContactEditor *editor) -{ - GtkBuilder *b = editor->priv->builder; - - return !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-homepage")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-weblog")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-caluri")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-fburl")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-videourl")))) ; -} - -static gboolean -check_job_for_data (EContactEditor *editor) -{ - GtkBuilder *b = editor->priv->builder; - - return !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-manager")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-assistant")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-profession")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-jobtitle")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-company")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-department")))) || - !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-office")))); -} - -static gboolean -check_misc_for_data (EContactEditor *editor) -{ - GtkBuilder *b = editor->priv->builder; - gint year, month, day; - - return !STRING_IS_EMPTY (gtk_entry_get_text (GTK_ENTRY (e_builder_get_widget (b, "entry-spouse")))) || - e_date_edit_get_date (E_DATE_EDIT (e_builder_get_widget (b, "dateedit-birthday")), &year, &month, &day) || - e_date_edit_get_date (E_DATE_EDIT (e_builder_get_widget (b, "dateedit-anniversary")), &year, &month, &day); -} - -static gboolean -check_notes_for_data (EContactEditor *editor) -{ - GtkWidget *tv = e_builder_get_widget (editor->priv->builder, "text-comments"); - GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (tv)); - - return gtk_text_buffer_get_char_count (buffer) > 0; -} - -static gboolean -check_section_for_data (EContactEditor *editor, - gint check) -{ - gboolean has_data = TRUE; - - switch (check) { - case CHECK_PHONE: - has_data = check_dyntable_for_data (editor, "phone-dyntable"); - break; - case CHECK_SIP: - has_data = check_dyntable_for_data (editor, "sip-dyntable"); - break; - case CHECK_IM: - has_data = check_dyntable_for_data (editor, "im-dyntable"); - break; - case CHECK_HOME: - has_data = check_address_for_data (editor, ADDRESS_SLOT_HOME); - break; - case CHECK_WORK: - has_data = check_address_for_data (editor, ADDRESS_SLOT_WORK); - break; - case CHECK_OTHER: - has_data = check_address_for_data (editor, ADDRESS_SLOT_OTHER); - break; - case CHECK_WEB: - has_data = check_web_for_data (editor); - break; - case CHECK_JOB: - has_data = check_job_for_data (editor); - break; - case CHECK_MISC: - has_data = check_misc_for_data (editor); - break; - case CHECK_NOTE: - has_data = check_notes_for_data (editor); - break; - default: - g_warning ("unknown data check requested"); - } - - return has_data; } static void -config_sensitize_item (EContactEditor *editor, - const gchar *item_name, - gint check) -{ - GtkWidget *item; - gboolean has_data; - - has_data = check_section_for_data (editor, check); - item = e_builder_get_widget (editor->priv->builder, item_name); - - if (has_data) { - gtk_widget_set_sensitive (item, FALSE); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), TRUE); - } else { - gtk_widget_set_sensitive (item, TRUE); - } -} - -static void -config_sensitize_cb (GtkWidget *button, - EContactEditor *editor) -{ - config_sensitize_item (editor, "menuitem-config-phone", CHECK_PHONE); - config_sensitize_item (editor, "menuitem-config-sip", CHECK_SIP); - config_sensitize_item (editor, "menuitem-config-im", CHECK_IM); - - config_sensitize_item (editor, "menuitem-config-web", CHECK_WEB); - config_sensitize_item (editor, "menuitem-config-job", CHECK_JOB); - config_sensitize_item (editor, "menuitem-config-misc", CHECK_MISC); - - config_sensitize_item (editor, "menuitem-config-home", CHECK_HOME); - config_sensitize_item (editor, "menuitem-config-work", CHECK_WORK); - config_sensitize_item (editor, "menuitem-config-other", CHECK_OTHER); - - config_sensitize_item (editor, "menuitem-config-notes", CHECK_NOTE); -} - -/* - * get the value from GSettings and check if there is data in the widget. - * if no data is found set_visible (value), set_visible (true) otherwise - * - * Returns: the new visibility - */ -static gboolean -configure_widget_visibility (EContactEditor *editor, - GSettings *settings, - const gchar *widget_name, - const gchar *settings_name, - gint check) +init_phone (EContactEditor *editor) { - gboolean config, has_data; - GtkWidget *widget; - - config = g_settings_get_boolean (settings, settings_name); - widget = e_builder_get_widget (editor->priv->builder, widget_name); - has_data = check_section_for_data (editor, check); + gint i; - gtk_widget_set_visible (widget, config || has_data); + expand_phone (editor, FALSE); - return config || has_data; + for (i = 1; i <= PHONE_SLOTS; i++) + init_phone_record_type (editor, i); } static void -configure_visibility (EContactEditor *editor) +sensitize_phone_types (EContactEditor *editor, + GtkWidget *combo_box) { - gboolean show_tab; - GSettings *settings = e_util_ref_settings ("org.gnome.evolution.addressbook"); - - configure_widget_visibility (editor, settings, "vbox-contact-phone", "editor-show-contact-phone", CHECK_PHONE); - configure_widget_visibility (editor, settings, "vbox-contact-sip", "editor-show-contact-sip", CHECK_SIP); - configure_widget_visibility (editor, settings, "vbox-contact-im", "editor-show-contact-im", CHECK_IM); - - show_tab = configure_widget_visibility (editor, settings, "frame-mailing-home", "editor-show-mailing-home", CHECK_HOME); - show_tab |= configure_widget_visibility (editor, settings, "frame-mailing-work", "editor-show-mailing-work", CHECK_WORK); - show_tab |= configure_widget_visibility (editor, settings, "expander-address-other", "editor-show-mailing-other", CHECK_OTHER); - gtk_widget_set_visible ( - e_builder_get_widget (editor->priv->builder, "scrolledwindow-mailing"), - show_tab); - - show_tab = configure_widget_visibility (editor, settings, "expander-personal-web", "editor-show-personal-web", CHECK_WEB); - show_tab |= configure_widget_visibility (editor, settings, "expander-personal-job", "editor-show-personal-job", CHECK_JOB); - show_tab |= configure_widget_visibility (editor, settings, "expander-personal-misc", "editor-show-personal-misc", CHECK_MISC); - gtk_widget_set_visible ( - e_builder_get_widget (editor->priv->builder, "scrolledwindow-personal"), - show_tab); - - configure_widget_visibility (editor, settings, "scrolledwindow-notes", "editor-show-notes", CHECK_NOTE); + GtkTreeModel *model; + GtkTreeIter iter; + gint i; + gboolean valid; - g_object_unref (settings); -} + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); + valid = gtk_tree_model_get_iter_first (model, &iter); -static void -config_menuitem_save (EContactEditor *editor, - GSettings *settings, - const gchar *item_name, - const gchar *key) -{ - GtkWidget *item; - gboolean active, sensitive; + for (i = 0; i < G_N_ELEMENTS (phones); i++) { + if (!valid) { + g_warning (G_STRLOC ": Unexpected end of phone items in combo box"); + return; + } - item = e_builder_get_widget (editor->priv->builder, item_name); - active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (item)); - sensitive = gtk_widget_get_sensitive (item); + gtk_list_store_set ( + GTK_LIST_STORE (model), &iter, + 1, is_field_supported (editor, phones[i].field_id), + -1); - if (sensitive) - g_settings_set_boolean (settings, key, active); + valid = gtk_tree_model_iter_next (model, &iter); + } } static void -config_save_cb (GtkWidget *button, - EContactEditor *editor) +sensitize_phone_record (EContactEditor *editor, + gint record, + gboolean enabled) { - GSettings *settings; - - settings = e_util_ref_settings ("org.gnome.evolution.addressbook"); - - config_menuitem_save (editor, settings, "menuitem-config-phone", "editor-show-contact-phone"); - config_menuitem_save (editor, settings, "menuitem-config-sip", "editor-show-contact-sip"); - config_menuitem_save (editor, settings, "menuitem-config-im", "editor-show-contact-im"); - - config_menuitem_save (editor, settings, "menuitem-config-web", "editor-show-personal-web"); - config_menuitem_save (editor, settings, "menuitem-config-job", "editor-show-personal-job"); - config_menuitem_save (editor, settings, "menuitem-config-misc", "editor-show-personal-misc"); + GtkWidget *phone_type_combo_box; + GtkWidget *phone_entry; + gchar *widget_name; - config_menuitem_save (editor, settings, "menuitem-config-home", "editor-show-mailing-home"); - config_menuitem_save (editor, settings, "menuitem-config-work", "editor-show-mailing-work"); - config_menuitem_save (editor, settings, "menuitem-config-other", "editor-show-mailing-other"); + widget_name = g_strdup_printf ("combobox-phone-%d", record); + phone_type_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - config_menuitem_save (editor, settings, "menuitem-config-notes", "editor-show-notes"); + widget_name = g_strdup_printf ("entry-phone-%d", record); + phone_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - g_object_unref (settings); + gtk_widget_set_sensitive (phone_type_combo_box, enabled); + gtk_editable_set_editable (GTK_EDITABLE (phone_entry), enabled); - configure_visibility (editor); + sensitize_phone_types (editor, phone_type_combo_box); } static void -init_config_menuitem (EContactEditor *editor, - GSettings *settings, - const gchar *item_name, - const gchar *key) +sensitize_phone (EContactEditor *editor) { - gboolean show; - GtkWidget *item; + gint i; - show = g_settings_get_boolean (settings, key); - item = e_builder_get_widget (editor->priv->builder, item_name); - gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), show); + for (i = 1; i <= PHONE_SLOTS; i++) { + gboolean enabled = TRUE; - g_signal_connect ( - item, "activate", - G_CALLBACK (config_save_cb), editor); + if (!editor->priv->target_editable) + enabled = FALSE; + + sensitize_phone_record (editor, i, enabled); + } } static void -init_config (EContactEditor *editor) +init_im_record_location (EContactEditor *editor, + gint record) { - GtkWidget *button, *menu; - GSettings *settings; - button = e_builder_get_widget (editor->priv->builder, "button-config"); - menu = e_builder_get_widget (editor->priv->builder, "menu-editor-config"); - gtk_menu_button_set_popup (GTK_MENU_BUTTON (button), menu); - - /* save resources by only doing the data checks and sensitizing upon request, - * instead of doing it with each change in object_changed() - */ - g_signal_connect ( - button, "clicked", - G_CALLBACK (config_sensitize_cb), editor); +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; + GtkListStore *store; + gint i; + gchar *widget_name; - settings = e_util_ref_settings ("org.gnome.evolution.addressbook"); + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - init_config_menuitem (editor, settings, "menuitem-config-phone", "editor-show-contact-phone"); - init_config_menuitem (editor, settings, "menuitem-config-sip", "editor-show-contact-sip"); - init_config_menuitem (editor, settings, "menuitem-config-im", "editor-show-contact-im"); + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (location_combo_box)); - init_config_menuitem (editor, settings, "menuitem-config-web", "editor-show-personal-web"); - init_config_menuitem (editor, settings, "menuitem-config-job", "editor-show-personal-job"); - init_config_menuitem (editor, settings, "menuitem-config-misc", "editor-show-personal-misc"); + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (location_combo_box))); - init_config_menuitem (editor, settings, "menuitem-config-home", "editor-show-mailing-home"); - init_config_menuitem (editor, settings, "menuitem-config-work", "editor-show-mailing-work"); - init_config_menuitem (editor, settings, "menuitem-config-other", "editor-show-mailing-other"); + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + GtkTreeIter iter; - init_config_menuitem (editor, settings, "menuitem-config-notes", "editor-show-notes"); + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, _(common_location[i].pretty_name), + 1, TRUE, + -1); + } - g_object_unref (settings); + g_signal_connect ( + location_combo_box, "changed", + G_CALLBACK (object_changed), editor); +#endif } static void -sensitize_sip_types (EContactEditor *editor) +init_im_record_service (EContactEditor *editor, + gint record) { - GtkWidget *w; - GtkListStore *listStore; - GtkTreeModel *model; - GtkTreeIter iter; - gint i, n_elements; - gboolean valid; - const EABTypeLabel *sip_types = eab_get_sip_type_labels (&n_elements); - - w = e_builder_get_widget (editor->priv->builder, "sip-dyntable"); - listStore = e_contact_editor_dyntable_get_combo_store (E_CONTACT_EDITOR_DYNTABLE (w)); - model = GTK_TREE_MODEL (listStore); - - valid = gtk_tree_model_get_iter_first (model, &iter); + GtkWidget *service_combo_box; + GtkListStore *store; + GtkWidget *name_entry; + gchar *widget_name; + gint i; - for (i = 0; i < n_elements; i++) { - if (!valid) { - g_warning (G_STRLOC ": Unexpected end of sip items in combo box"); - return; - } + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - gtk_list_store_set (GTK_LIST_STORE (model), &iter, - DYNTABLE_COMBO_COLUMN_SENSITIVE, - is_field_supported (editor, sip_types[i].field_id), - -1); + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - valid = gtk_tree_model_iter_next (model, &iter); + if (editor->priv->compress_ui && record > 2) { + gtk_widget_hide (name_entry); + gtk_widget_hide (service_combo_box); } -} -static void -sensitize_sip (EContactEditor *editor) -{ - GtkWidget *w; - gboolean enabled = TRUE; + init_item_sensitiveable_combo_box (GTK_COMBO_BOX (service_combo_box)); - w = e_builder_get_widget (editor->priv->builder, "sip-dyntable"); + store = GTK_LIST_STORE ( + gtk_combo_box_get_model ( + GTK_COMBO_BOX (service_combo_box))); - if (!editor->priv->target_editable || - !is_field_supported (editor, E_CONTACT_SIP)) - enabled = FALSE; + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { + GtkTreeIter iter; - gtk_widget_set_sensitive (w, enabled); + gtk_list_store_append (store, &iter); + gtk_list_store_set ( + store, &iter, + 0, _(im_service[i].pretty_name), + 1, TRUE, + -1); + } - sensitize_sip_types (editor); + g_signal_connect_swapped ( + service_combo_box, "changed", + G_CALLBACK (gtk_widget_grab_focus), name_entry); + g_signal_connect ( + service_combo_box, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect ( + name_entry, "changed", + G_CALLBACK (object_changed), editor); + g_signal_connect_swapped ( + name_entry, "activate", + G_CALLBACK (entry_activated), editor); } static void -init_im_record_type (EContactEditor *editor) +init_im (EContactEditor *editor) { - GtkWidget *w; - GtkListStore *store; - gint i, n_elements; - EContactEditorDynTable *dyntable; - const EABTypeLabel *im_service; - - w = e_builder_get_widget (editor->priv->builder, "im-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - store = e_contact_editor_dyntable_get_combo_store (dyntable); - - im_service = eab_get_im_type_labels (&n_elements); - for (i = 0; i < n_elements; i++) { - GtkTreeIter iter; + gint i; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - DYNTABLE_COMBO_COLUMN_TEXT, _(im_service[i].text), - DYNTABLE_COMBO_COLUMN_SENSITIVE, TRUE, - -1); + for (i = 1; i <= IM_SLOTS; i++) { + init_im_record_service (editor, i); + init_im_record_location (editor, i); } - - e_contact_editor_dyntable_set_combo_defaults (dyntable, im_service_default, G_N_ELEMENTS (im_service_default)); } static void -init_im (EContactEditor *editor) +fill_in_im_record (EContactEditor *editor, + gint record, + gint service, + const gchar *name, + gint location) { - EContactEditorDynTable *dyntable; - GtkExpander *expander; + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; +#endif + GtkWidget *name_entry; + gchar *widget_name; - expander = GTK_EXPANDER ( - e_builder_get_widget (editor->priv->builder, "expander-contact-im")); - dyntable = E_CONTACT_EDITOR_DYNTABLE ( - e_builder_get_widget (editor->priv->builder, "im-dyntable")); - - e_contact_editor_dyntable_set_max_entries (dyntable, IM_SLOTS); - e_contact_editor_dyntable_set_num_columns (dyntable, SLOTS_PER_LINE, TRUE); - e_contact_editor_dyntable_set_show_min (dyntable, SLOTS_IN_COLLAPSED_STATE); + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - g_signal_connect ( - dyntable, "changed", - G_CALLBACK (object_changed), editor); - g_signal_connect_swapped ( - dyntable, "activate", - G_CALLBACK (entry_activated), editor); - g_signal_connect_swapped ( - dyntable, "row-added", - G_CALLBACK (row_added_cb), expander); +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); +#endif - init_im_record_type (editor); + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - gtk_expander_set_expanded (expander, TRUE); +#ifdef ENABLE_IM_LOCATION + set_combo_box_active ( + editor, GTK_COMBO_BOX (location_combo_box), + location >= 0 ? location : 0); +#endif + set_combo_box_active ( + editor, GTK_COMBO_BOX (service_combo_box), + service >= 0 ? service : im_service_default[record - 1]); + set_entry_text (editor, GTK_ENTRY (name_entry), name ? name : ""); } static void @@ -2047,156 +1876,170 @@ { GList *im_attr_list; GList *l; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeIter iter; - - w = e_builder_get_widget (editor->priv->builder, "im-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); + gint record_n; + gint i; /* Clear */ - e_contact_editor_dyntable_clear_data (dyntable); + for (record_n = 1; record_n <= IM_SLOTS; record_n++) { + fill_in_im_record (editor, record_n, -1, NULL, -1); + } /* Fill in */ - data_store = e_contact_editor_dyntable_extract_data (dyntable); - - im_attr_list = e_contact_get_attributes_set ( - editor->priv->contact, - im_service_fetch_set, - G_N_ELEMENTS (im_service_fetch_set) - ); + for (record_n = 1, i = 0; i < G_N_ELEMENTS (im_service); i++) { + im_attr_list = e_contact_get_attributes (editor->priv->contact, im_service[i].field); - for (l = im_attr_list; l; l = g_list_next(l)) { - EVCardAttribute *attr = l->data; - gchar *im_name; - gint service_type; - gint slot; + for (l = im_attr_list; l && record_n <= IM_SLOTS; l = g_list_next (l)) { + EVCardAttribute *attr = l->data; + gchar *im_name; + gint slot; + + im_name = e_vcard_attribute_get_value (attr); + slot = alloc_ui_slot ( + editor, "entry-im-name", + get_ui_slot (attr), IM_SLOTS); + if (slot < 1) + break; - im_name = e_vcard_attribute_get_value (attr); - service_type = eab_get_im_type_index (attr); + fill_in_im_record ( + editor, slot, i, im_name, + get_im_location (attr)); - slot = get_ui_slot (attr); - if (slot < 0) - slot = IM_SLOTS + 1; //attach at the end + record_n++; - gtk_list_store_append (data_store, &iter); - gtk_list_store_set (data_store, &iter, - DYNTABLE_STORE_COLUMN_SORTORDER, slot, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, service_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, im_name, - -1); + g_free (im_name); + } - g_free (im_name); + g_list_free_full (im_attr_list, (GDestroyNotify) e_vcard_attribute_free); } +} + +static void +extract_im_record (EContactEditor *editor, + gint record, + gint *service, + gchar **name, + gint *location) +{ + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; +#endif + GtkWidget *name_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); +#endif - g_list_free_full (im_attr_list, (GDestroyNotify) e_vcard_attribute_free); + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); - e_contact_editor_dyntable_fill_in_data (dyntable); + *name = g_strdup (gtk_entry_get_text (GTK_ENTRY (name_entry))); + *service = gtk_combo_box_get_active (GTK_COMBO_BOX (service_combo_box)); +#ifdef ENABLE_IM_LOCATION + *location = gtk_combo_box_get_active (GTK_COMBO_BOX (location_combo_box)); +#else + *location = 1; /* set everything to HOME */ +#endif } static void extract_im (EContactEditor *editor) { - GList *attr_list = NULL; - GList *old_attr_list = NULL; - GList *ll; - gint ii; - GtkWidget *w; - EContactEditorDynTable *dyntable; - GtkListStore *data_store; - GtkTreeModel *tree_model; - GtkTreeIter iter; - gboolean valid; + GList **service_attr_list; + gint remaining_slots = IM_SLOTS; + gint i; - w = e_builder_get_widget (editor->priv->builder, "im-dyntable"); - dyntable = E_CONTACT_EDITOR_DYNTABLE (w); - data_store = e_contact_editor_dyntable_extract_data (dyntable); - tree_model = GTK_TREE_MODEL (data_store); - - valid = gtk_tree_model_get_iter_first (tree_model, &iter); - while (valid) { - gint service_type; - gint slot; - gchar *im_name; + service_attr_list = g_new0 (GList *, G_N_ELEMENTS (im_service)); + + for (i = 1; i <= IM_SLOTS; i++) { EVCardAttribute *attr; - const EABTypeLabel *im_service = eab_get_im_type_labels (&service_type); + gchar *name; + gint service; + gint location; + + extract_im_record (editor, i, &service, &name, &location); + + if (!STRING_IS_EMPTY (name)) { + attr = e_vcard_attribute_new ( + "", e_contact_vcard_attribute ( + im_service[service].field)); - gtk_tree_model_get (tree_model,&iter, - DYNTABLE_STORE_COLUMN_SORTORDER, &slot, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &service_type, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, &im_name, - -1); + if (location >= 0) + e_vcard_attribute_add_param_with_value ( + attr, + e_vcard_attribute_param_new (EVC_TYPE), + im_index_to_location (location)); - attr = e_vcard_attribute_new ("", - e_contact_vcard_attribute ( - im_service[service_type].field_id)); + e_vcard_attribute_add_value (attr, name); + set_ui_slot (attr, i); - /* older evolution versions (<=3.12) will crash if SLOT>4 is stored, - * but if we don't store the slot we loose sortorder. - * this works only for <=4 IM slots. for more, old evolution - * will go through types (AIM, Jabber, ...) and stop after 4 - * no matter what x-evo-slot says. - */ - if (slot < 4) - set_ui_slot (attr, slot + 1); + service_attr_list[service] = g_list_append ( + service_attr_list[service], attr); + } - e_vcard_attribute_add_value (attr, im_name); + g_free (name); + } - attr_list = g_list_prepend (attr_list, attr); + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { + GList *old_service_attr_list; + gint filled_in_slots; + GList *ll; + gint j; - valid = gtk_tree_model_iter_next (tree_model, &iter); - } - attr_list = g_list_reverse (attr_list); + /* Splice in the old attributes, minus the filled_in_slots first */ - /* Splice in the old attributes, minus the IM_SLOTS first */ + old_service_attr_list = e_contact_get_attributes ( + editor->priv->contact, im_service[i].field); + filled_in_slots = MIN ( + remaining_slots, + g_list_length (old_service_attr_list)); + remaining_slots -= filled_in_slots; - old_attr_list = e_contact_get_attributes_set ( - editor->priv->contact, - im_service_fetch_set, - G_N_ELEMENTS (im_service_fetch_set) - ); - for (ll = old_attr_list, ii = 0; ll && ii < IM_SLOTS; ii++) { - e_vcard_attribute_free (ll->data); - ll = g_list_delete_link (ll, ll); - } + for (ll = old_service_attr_list, j = 0; + ll && j < filled_in_slots; j++) { - old_attr_list = ll; - attr_list = g_list_concat (attr_list, old_attr_list); + e_vcard_attribute_free (ll->data); + ll = g_list_delete_link (ll, ll); + } - for (ii = 0; ii < G_N_ELEMENTS (im_service_fetch_set); ii++) { - e_contact_set_attributes (editor->priv->contact, im_service_fetch_set[ii], NULL); - } + old_service_attr_list = ll; + service_attr_list[i] = g_list_concat ( + service_attr_list[i], old_service_attr_list); + + e_contact_set_attributes ( + editor->priv->contact, + im_service[i].field, + service_attr_list[i]); - for (ll = attr_list; ll; ll = ll->next) { - EVCard *vcard; - vcard = E_VCARD (editor->priv->contact); - e_vcard_append_attribute (vcard, e_vcard_attribute_copy ((EVCardAttribute *) ll->data)); + free_attr_list (service_attr_list[i]); } - g_list_free_full (attr_list, (GDestroyNotify) e_vcard_attribute_free); + g_free (service_attr_list); } static void -sensitize_im_types (EContactEditor *editor) +sensitize_im_types (EContactEditor *editor, + GtkWidget *combo_box) { - GtkWidget *w; - GtkListStore *list_store; GtkTreeModel *model; GtkTreeIter iter; - gint i, n_elements; + gint i; gboolean valid; - const EABTypeLabel *im_service = eab_get_im_type_labels (&n_elements); - - w = e_builder_get_widget (editor->priv->builder, "im-dyntable"); - list_store = e_contact_editor_dyntable_get_combo_store (E_CONTACT_EDITOR_DYNTABLE (w)); - model = GTK_TREE_MODEL (list_store); + model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo_box)); valid = gtk_tree_model_get_iter_first (model, &iter); - for (i = 0; i < n_elements; i++) { + for (i = 0; i < G_N_ELEMENTS (im_service); i++) { if (!valid) { g_warning (G_STRLOC ": Unexpected end of im items in combo box"); return; @@ -2204,8 +2047,7 @@ gtk_list_store_set ( GTK_LIST_STORE (model), &iter, - DYNTABLE_COMBO_COLUMN_SENSITIVE, - is_field_supported (editor, im_service[i].field_id), + 1, is_field_supported (editor, im_service[i].field), -1); valid = gtk_tree_model_iter_next (model, &iter); @@ -2213,19 +2055,51 @@ } static void +sensitize_im_record (EContactEditor *editor, + gint record, + gboolean enabled) +{ + GtkWidget *service_combo_box; +#ifdef ENABLE_IM_LOCATION + GtkWidget *location_combo_box; +#endif + GtkWidget *name_entry; + gchar *widget_name; + + widget_name = g_strdup_printf ("combobox-im-service-%d", record); + service_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + +#ifdef ENABLE_IM_LOCATION + widget_name = g_strdup_printf ("combobox-im-location-%d", record); + location_combo_box = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); +#endif + + widget_name = g_strdup_printf ("entry-im-name-%d", record); + name_entry = e_builder_get_widget (editor->priv->builder, widget_name); + g_free (widget_name); + + gtk_widget_set_sensitive (service_combo_box, enabled); +#ifdef ENABLE_IM_LOCATION + gtk_widget_set_sensitive (location_combo_box, enabled); +#endif + gtk_editable_set_editable (GTK_EDITABLE (name_entry), enabled); + sensitize_im_types (editor, service_combo_box); +} + +static void sensitize_im (EContactEditor *editor) { - gint i, n_elements; + gint i; gboolean enabled; gboolean no_ims_supported; - GtkWidget *w; - const EABTypeLabel *im_service = eab_get_im_type_labels (&n_elements); enabled = editor->priv->target_editable; no_ims_supported = TRUE; - for (i = 0; i < n_elements; i++) - if (is_field_supported (editor, im_service[i].field_id)) { + for (i = 0; i < G_N_ELEMENTS (im_service); i++) + if (is_field_supported (editor, im_service[i].field)) { no_ims_supported = FALSE; break; } @@ -2233,10 +2107,20 @@ if (no_ims_supported) enabled = FALSE; - w = e_builder_get_widget (editor->priv->builder, "im-dyntable"); - gtk_widget_set_sensitive (w, enabled); + for (i = 1; i <= IM_SLOTS; i++) { + sensitize_im_record (editor, i, enabled); + } +} + +static void +init_personal (EContactEditor *editor) +{ + gtk_expander_set_expanded ( + GTK_EXPANDER (e_builder_get_widget ( + editor->priv->builder, "expander-personal-misc")), + !editor->priv->compress_ui); - sensitize_im_types (editor); + expand_web (editor, !editor->priv->compress_ui); } static void @@ -2301,8 +2185,9 @@ init_address_record (editor, i); gtk_expander_set_expanded ( - GTK_EXPANDER (e_builder_get_widget (editor->priv->builder, "expander-address-other")), - !editor->priv->compress_ui); + GTK_EXPANDER (e_builder_get_widget ( + editor->priv->builder, "expander-address-other")), + !editor->priv->compress_ui); } static void @@ -2410,6 +2295,65 @@ fill_in_address_record (editor, i); } +static void +extract_address_textview (EContactEditor *editor, + gint record, + EContactAddress *address) +{ + gchar *textview_name; + GtkWidget *textview; + GtkTextBuffer *text_buffer; + GtkTextIter iter_1, iter_2; + + textview_name = g_strdup_printf ("textview-%s-address", address_name[record]); + textview = e_builder_get_widget (editor->priv->builder, textview_name); + g_free (textview_name); + + text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textview)); + gtk_text_buffer_get_start_iter (text_buffer, &iter_1); + + /* Skip blank lines */ + while (gtk_text_iter_get_chars_in_line (&iter_1) < 1 && + !gtk_text_iter_is_end (&iter_1)) + gtk_text_iter_forward_line (&iter_1); + + if (gtk_text_iter_is_end (&iter_1)) + return; + + iter_2 = iter_1; + gtk_text_iter_forward_to_line_end (&iter_2); + + /* Extract street (first line of text) */ + address->street = gtk_text_iter_get_text (&iter_1, &iter_2); + + iter_1 = iter_2; + gtk_text_iter_forward_line (&iter_1); + + if (gtk_text_iter_is_end (&iter_1)) + return; + + gtk_text_iter_forward_to_end (&iter_2); + + /* Extract extended address (remaining lines of text) */ + address->ext = gtk_text_iter_get_text (&iter_1, &iter_2); +} + +static gchar * +extract_address_field (EContactEditor *editor, + gint record, + const gchar *widget_field_name) +{ + gchar *entry_name; + GtkWidget *entry; + + entry_name = g_strdup_printf ( + "entry-%s-%s", address_name[record], widget_field_name); + entry = e_builder_get_widget (editor->priv->builder, entry_name); + g_free (entry_name); + + return g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); +} + static gchar * append_to_address_label (gchar *address_label, const gchar *part, @@ -2445,7 +2389,7 @@ return; } - settings = e_util_ref_settings ("org.gnome.evolution.addressbook"); + settings = g_settings_new ("org.gnome.evolution.addressbook"); format_address = g_settings_get_boolean (settings, "address-formatting"); g_object_unref (settings); @@ -2486,7 +2430,13 @@ address = g_new0 (EContactAddress, 1); - extract_address_from_gui (editor, address, record); + extract_address_textview (editor, record, address); + address->locality = extract_address_field (editor, record, "city"); + address->region = extract_address_field (editor, record, "state"); + address->code = extract_address_field (editor, record, "zip"); + address->country = extract_address_field (editor, record, "country"); + address->po = extract_address_field (editor, record, "pobox"); + if (!STRING_IS_EMPTY (address->street) || !STRING_IS_EMPTY (address->ext) || !STRING_IS_EMPTY (address->locality) || @@ -3162,16 +3112,9 @@ fill_in_simple (editor); fill_in_email (editor); fill_in_phone (editor); - fill_in_sip (editor); fill_in_im (editor); fill_in_address (editor); - /* Visibility of sections and status of menuitems in the config-menu depend on data - * they have to be initialized here instead of init_all() and sensitize_all() - */ - configure_visibility (editor); - config_sensitize_cb (NULL, editor); - if (weak_pointer) { g_object_remove_weak_pointer (G_OBJECT (focused_widget), &weak_pointer); gtk_widget_grab_focus (focused_widget); @@ -3184,7 +3127,6 @@ extract_simple (editor); extract_email (editor); extract_phone (editor); - extract_sip (editor); extract_im (editor); extract_address (editor); } @@ -3192,44 +3134,12 @@ static void sensitize_all (EContactEditor *editor) { - GtkWidget *focused_widget; - gpointer weak_pointer; - - /* Widget changes can cause focus widget change, thus remember the current - widget and restore it after the fill is done; some fill operations - can delete widgets, like the dyntable, thus do the weak_pointer as well. - */ - focused_widget = gtk_window_get_focus (eab_editor_get_window (EAB_EDITOR (editor))); - weak_pointer = focused_widget; - if (focused_widget) - g_object_add_weak_pointer (G_OBJECT (focused_widget), &weak_pointer); - sensitize_ok (editor); sensitize_simple (editor); sensitize_email (editor); sensitize_phone (editor); - sensitize_sip (editor); sensitize_im (editor); sensitize_address (editor); - - if (weak_pointer) { - g_object_remove_weak_pointer (G_OBJECT (focused_widget), &weak_pointer); - gtk_widget_grab_focus (focused_widget); - } -} - -static void -init_personal (EContactEditor *editor) -{ - gtk_expander_set_expanded ( - GTK_EXPANDER (e_builder_get_widget (editor->priv->builder, "expander-personal-web")), - !editor->priv->compress_ui); - gtk_expander_set_expanded ( - GTK_EXPANDER (e_builder_get_widget (editor->priv->builder, "expander-personal-job")), - !editor->priv->compress_ui); - gtk_expander_set_expanded ( - GTK_EXPANDER (e_builder_get_widget (editor->priv->builder, "expander-personal-misc")), - !editor->priv->compress_ui); } static void @@ -3243,11 +3153,9 @@ init_simple (editor); init_email (editor); init_phone (editor); - init_sip (editor); init_im (editor); init_personal (editor); init_address (editor); - init_config (editor); /* with so many scrolled windows, we need to * do some manual sizing */ @@ -4256,56 +4164,31 @@ } static void -expand_dyntable (GtkExpander *expander, - EContactEditorDynTable *dyntable, - gint max_slots) +expand_web_toggle (EContactEditor *ce) { - if (gtk_expander_get_expanded (expander)) { - e_contact_editor_dyntable_set_show_max (dyntable, max_slots); - } else { - e_contact_editor_dyntable_set_show_max (dyntable, - SLOTS_IN_COLLAPSED_STATE); - } -} + GtkWidget *widget; -static void -expander_contact_mail_cb (GObject *object, - GParamSpec *param_spec, - gpointer user_data) -{ - expand_dyntable (GTK_EXPANDER (object), - E_CONTACT_EDITOR_DYNTABLE (user_data), - EMAIL_SLOTS); + widget = e_builder_get_widget (ce->priv->builder, "label-videourl"); + expand_web (ce, !gtk_widget_get_visible (widget)); } static void -expander_contact_phone_cb (GObject *object, - GParamSpec *param_spec, - gpointer user_data) +expand_phone_toggle (EContactEditor *ce) { - expand_dyntable (GTK_EXPANDER (object), - E_CONTACT_EDITOR_DYNTABLE (user_data), - PHONE_SLOTS); -} + GtkWidget *phone_ext_table; -static void -expander_contact_sip_cb (GObject *object, - GParamSpec *param_spec, - gpointer user_data) -{ - expand_dyntable (GTK_EXPANDER (object), - E_CONTACT_EDITOR_DYNTABLE (user_data), - SIP_SLOTS); + phone_ext_table = e_builder_get_widget ( + ce->priv->builder, "table-phone-extended"); + expand_phone (ce, !gtk_widget_get_visible (phone_ext_table)); } static void -expander_contact_im_cb (GObject *object, - GParamSpec *param_spec, - gpointer user_data) +expand_mail_toggle (EContactEditor *ce) { - expand_dyntable (GTK_EXPANDER (object), - E_CONTACT_EDITOR_DYNTABLE (user_data), - IM_SLOTS); + GtkWidget *mail; + + mail = e_builder_get_widget (ce->priv->builder, "entry-email-4"); + expand_mail (ce, !gtk_widget_get_visible (mail)); } static void @@ -4329,7 +4212,7 @@ EShell *shell; EClientCache *client_cache; GtkWidget *container; - GtkWidget *widget, *label, *dyntable; + GtkWidget *widget, *label; GtkEntryCompletion *completion; e_contact_editor->priv = G_TYPE_INSTANCE_GET_PRIVATE ( @@ -4356,7 +4239,6 @@ /* Make sure custom widget types are available */ g_type_ensure (E_TYPE_IMAGE_CHOOSER); g_type_ensure (E_TYPE_CLIENT_COMBO_BOX); - g_type_ensure (E_TYPE_CONTACT_EDITOR_DYNTABLE); g_type_ensure (E_TYPE_URL_ENTRY); g_type_ensure (E_TYPE_DATE_EDIT); @@ -4420,34 +4302,21 @@ g_signal_connect ( widget, "clicked", G_CALLBACK (show_help_cb), e_contact_editor); - - widget = e_builder_get_widget ( - e_contact_editor->priv->builder, "expander-contact-phone"); - dyntable = e_builder_get_widget ( - e_contact_editor->priv->builder, "phone-dyntable"); - g_signal_connect (widget, "notify::expanded", - G_CALLBACK (expander_contact_phone_cb), dyntable); - widget = e_builder_get_widget ( - e_contact_editor->priv->builder, "expander-contact-sip"); - dyntable = e_builder_get_widget ( - e_contact_editor->priv->builder, "sip-dyntable"); - g_signal_connect (widget, "notify::expanded", - G_CALLBACK (expander_contact_sip_cb), dyntable); - + e_contact_editor->priv->builder, "button-web-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_web_toggle), e_contact_editor); widget = e_builder_get_widget ( - e_contact_editor->priv->builder, "expander-contact-im"); - dyntable = e_builder_get_widget ( - e_contact_editor->priv->builder, "im-dyntable"); - g_signal_connect (widget, "notify::expanded", - G_CALLBACK (expander_contact_im_cb), dyntable); - + e_contact_editor->priv->builder, "button-phone-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_phone_toggle), e_contact_editor); widget = e_builder_get_widget ( - e_contact_editor->priv->builder, "expander-contact-email"); - dyntable = e_builder_get_widget ( - e_contact_editor->priv->builder, "mail-dyntable"); - g_signal_connect (widget, "notify::expanded", - G_CALLBACK (expander_contact_mail_cb), dyntable); + e_contact_editor->priv->builder, "button-mail-expand"); + g_signal_connect_swapped ( + widget, "clicked", + G_CALLBACK (expand_mail_toggle), e_contact_editor); widget = e_builder_get_widget ( e_contact_editor->priv->builder, "entry-fullname"); diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-dyntable.c evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-dyntable.c --- evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-dyntable.c 2014-05-06 10:59:33.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-dyntable.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,754 +0,0 @@ -/* - * e-contact-editor-dyntable.c - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - */ - -#include "e-contact-editor-dyntable.h" - -G_DEFINE_TYPE(EContactEditorDynTable, e_contact_editor_dyntable, GTK_TYPE_GRID) - -/* one position is occupied by two widgets: combo+entry */ -#define ENTRY_SIZE 2 -#define MAX_CAPACITY 100 - -enum { - CHANGED_SIGNAL, - ACTIVATE_SIGNAL, - ROW_ADDED_SIGNAL, - LAST_SIGNAL -}; - -static guint dyntable_signals[LAST_SIGNAL]; - -struct _EContactEditorDynTablePrivate { - - /* absolute max, dyntable will ignore the rest */ - guint max_entries; - - /* current number of entries with text or requested by user*/ - guint curr_entries; - - /* minimum to show, with or without text */ - guint show_min_entries; - - /* no matter how much data, show only */ - guint show_max_entries; - - /* number of entries (combo/text) per row */ - guint columns; - - /* if true, fill line with empty slots*/ - gboolean justified; - - GtkWidget *add_button; - GtkListStore *combo_store; - GtkListStore *data_store; - - /* array of default values for combo box */ - const gint *combo_defaults; - - /* number of elements in the array */ - size_t combo_defaults_n; -}; - -GtkWidget* -e_contact_editor_dyntable_new (void) -{ - GtkWidget* widget; - widget = GTK_WIDGET (g_object_new (e_contact_editor_dyntable_get_type (), NULL)); - return widget; -} - -static void -set_combo_box_active (EContactEditorDynTable *dyntable, - GtkComboBox *combo_box, - gint active) -{ - g_signal_handlers_block_matched (combo_box, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, - NULL, dyntable); - gtk_combo_box_set_active (combo_box, active); - g_signal_handlers_unblock_matched (combo_box, - G_SIGNAL_MATCH_DATA, 0, 0, NULL, - NULL, dyntable); -} - -/* translate position into column/row */ -static void -position_to_grid (EContactEditorDynTable *dyntable, - guint pos, - guint *col, - guint *row) -{ - *row = pos / dyntable->priv->columns; - *col = pos % dyntable->priv->columns * ENTRY_SIZE; -} - -static void -move_widget (GtkGrid *grid, GtkWidget *w, guint col, guint row) -{ - GValue rowValue = G_VALUE_INIT, colValue = G_VALUE_INIT; - - g_value_init (&rowValue, G_TYPE_UINT); - g_value_init (&colValue, G_TYPE_UINT); - - g_value_set_uint (&rowValue, row); - g_value_set_uint (&colValue, col); - - gtk_container_child_set_property (GTK_CONTAINER (grid), w, - "left-attach", &colValue); - gtk_container_child_set_property (GTK_CONTAINER (grid), w, - "top-attach", &rowValue); -} - -static gboolean -is_button_required (EContactEditorDynTable *dyntable) -{ - if (dyntable->priv->curr_entries >= dyntable->priv->max_entries) - return FALSE; - if (dyntable->priv->curr_entries <= dyntable->priv->show_max_entries) - return TRUE; - else - return FALSE; -} - -static void -sensitize_button (EContactEditorDynTable *dyntable) -{ - guint row, col, current_entries; - GtkWidget *w; - GtkGrid *grid; - EContactEditorDynTableClass *class; - gboolean enabled; - - grid = GTK_GRID (dyntable); - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS (dyntable); - - current_entries = dyntable->priv->curr_entries; - enabled = TRUE; - if (current_entries > 0) { - /* last entry */ - current_entries--; - position_to_grid (dyntable, current_entries, &col, &row); - w = gtk_grid_get_child_at (grid, col + 1, row); - - enabled = !class->widget_is_empty (dyntable, w); - } - - gtk_widget_set_sensitive (dyntable->priv->add_button, enabled); -} - -static void -show_button (EContactEditorDynTable *dyntable) -{ - guint col,row, pos; - gboolean visible = FALSE; - GtkGrid *grid; - - grid = GTK_GRID (dyntable); - - /* move button to end of current line */ - pos = dyntable->priv->curr_entries; - if (pos > 0) - pos--; - position_to_grid(dyntable, pos, &col, &row); - move_widget (grid, dyntable->priv->add_button, - dyntable->priv->columns*ENTRY_SIZE+1, row); - - /* set visibility */ - if (is_button_required (dyntable)) - visible = TRUE; - - gtk_widget_set_visible (dyntable->priv->add_button, visible); - - sensitize_button (dyntable); -} - -static void -increment_counter (EContactEditorDynTable *dyntable) -{ - dyntable->priv->curr_entries++; - show_button (dyntable); -} - -static void -decrement_counter (EContactEditorDynTable *dyntable) -{ - dyntable->priv->curr_entries--; - show_button (dyntable); -} - -static gint -get_next_combo_index (EContactEditorDynTable *dyntable) -{ - size_t array_size = dyntable->priv->combo_defaults_n; - gint idx = 0; - - if (dyntable->priv->combo_defaults != NULL) { - idx = dyntable->priv->combo_defaults[dyntable->priv->curr_entries % array_size]; - } - - return idx; -} - -static GtkWidget* -combo_box_create (EContactEditorDynTable *dyntable) -{ - GtkWidget *w; - GtkComboBox *combo; - GtkListStore *store; - GtkCellRenderer *cell; - - w = gtk_combo_box_new (); - combo = GTK_COMBO_BOX (w); - store = dyntable->priv->combo_store; - - gtk_combo_box_set_model (combo, GTK_TREE_MODEL(store)); - - gtk_cell_layout_clear (GTK_CELL_LAYOUT (combo)); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); - gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell, - "text", DYNTABLE_COMBO_COLUMN_TEXT, - "sensitive", DYNTABLE_COMBO_COLUMN_SENSITIVE, - NULL); - - gtk_combo_box_set_active (combo, get_next_combo_index (dyntable)); - - return w; -} - -static void -emit_changed (EContactEditorDynTable *dyntable) -{ - g_signal_emit (dyntable, dyntable_signals[CHANGED_SIGNAL], 0); -} - -static void -emit_activated (EContactEditorDynTable *dyntable) -{ - g_signal_emit (dyntable, dyntable_signals[ACTIVATE_SIGNAL], 0); -} - -static void -emit_row_added (EContactEditorDynTable *dyntable) -{ - g_signal_emit (dyntable, dyntable_signals[ROW_ADDED_SIGNAL], 0); -} - -static void -add_empty_entry (EContactEditorDynTable *dyntable) -{ - GtkGrid *grid; - guint row, col; - GtkWidget *box, *entry; - EContactEditorDynTableClass *class; - - if (dyntable->priv->curr_entries >= dyntable->priv->max_entries) - return; - - grid = GTK_GRID (dyntable); - position_to_grid (dyntable, dyntable->priv->curr_entries, &col, &row); - - /* create new entry at last position */ - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS (dyntable); - box = combo_box_create (dyntable); - gtk_grid_attach (grid, box, col, row, 1, 1); - gtk_widget_show (box); - - entry = class->widget_create (dyntable); - g_object_set (entry, "margin-left", 2, NULL); - g_object_set (entry, "margin-right", 5, NULL); - gtk_widget_set_hexpand (entry, GTK_EXPAND); - gtk_grid_attach (grid, entry, col + 1, row, 1, 1); - gtk_widget_show (entry); - - g_signal_connect_swapped(box, "changed", - G_CALLBACK (gtk_widget_grab_focus), entry); - g_signal_connect_swapped(box, "changed", - G_CALLBACK (emit_changed), dyntable); - g_signal_connect_swapped(entry, "changed", - G_CALLBACK (emit_changed), dyntable); - g_signal_connect_swapped(entry, "changed", - G_CALLBACK (sensitize_button), dyntable); - g_signal_connect_swapped(entry, "activate", - G_CALLBACK (emit_activated), dyntable); - - increment_counter (dyntable); - - if ( (dyntable->priv->justified && col < dyntable->priv->columns-1) || - (dyntable->priv->curr_entries < dyntable->priv->show_min_entries) ) - add_empty_entry (dyntable); - - gtk_widget_grab_focus (entry); -} - -static void -remove_empty_entries (EContactEditorDynTable *dyntable, gboolean fillup) -{ - guint row, col, pos; - GtkGrid* grid; - GtkWidget* w; - EContactEditorDynTableClass *class; - - grid = GTK_GRID (dyntable); - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS (dyntable); - - for (pos = 0; pos < dyntable->priv->curr_entries; pos++) { - position_to_grid (dyntable, pos, &col, &row); - w = gtk_grid_get_child_at (grid, col + 1, row); - - if (w != NULL && class->widget_is_empty (dyntable, w)) { - guint pos2, next_col, next_row; - - gtk_widget_destroy (w); - w = gtk_grid_get_child_at (grid, col, row); - gtk_widget_destroy (w); - - /* now fill gap */ - for (pos2 = pos + 1; pos2 < dyntable->priv->curr_entries; pos2++) { - position_to_grid (dyntable, pos2, &next_col, &next_row); - w = gtk_grid_get_child_at (grid, next_col, next_row); - move_widget (grid, w, col, row); - w = gtk_grid_get_child_at (grid, next_col + 1, next_row); - move_widget (grid, w, col + 1, row); - col = next_col; - row = next_row; - } - decrement_counter (dyntable); - pos--; /* check the new widget on our current position */ - } - - } - - if (fillup - && (dyntable->priv->curr_entries < dyntable->priv->show_min_entries - || (dyntable->priv->justified && col < dyntable->priv->columns-1))) - add_empty_entry (dyntable); - -} - -/* clears data, not the combo box list store */ -void -e_contact_editor_dyntable_clear_data (EContactEditorDynTable *dyntable) -{ - guint i, col, row; - GtkGrid *grid; - GtkWidget *w; - EContactEditorDynTableClass *class; - - grid = GTK_GRID(dyntable); - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS(dyntable); - - for (i = 0; i < dyntable->priv->curr_entries; i++) { - position_to_grid (dyntable, i, &col, &row); - w = gtk_grid_get_child_at (grid, col + 1, row); - class->widget_clear (dyntable, w); - } - remove_empty_entries (dyntable, TRUE); - - gtk_list_store_clear (dyntable->priv->data_store); -} - -static void -adjust_visibility_of_widgets (EContactEditorDynTable *dyntable) -{ - guint pos, col, row; - GtkGrid *grid; - GtkWidget *w; - - grid = GTK_GRID (dyntable); - for (pos = 0; pos < dyntable->priv->curr_entries; pos++) { - gboolean visible = FALSE; - - if (pos < dyntable->priv->show_max_entries) - visible = TRUE; - - position_to_grid (dyntable, pos, &col, &row); - w = gtk_grid_get_child_at (grid, col, row); - gtk_widget_set_visible (w, visible); - w = gtk_grid_get_child_at (grid, col + 1, row); - gtk_widget_set_visible (w, visible); - } - - show_button (dyntable); -} - -/* number of columns can only be set before any data is added to this dyntable */ -void e_contact_editor_dyntable_set_num_columns (EContactEditorDynTable *dyntable, - guint number_of_columns, - gboolean justified) -{ - GtkTreeIter iter; - GtkTreeModel *store; - gboolean holds_data; - - g_return_if_fail (number_of_columns > 0); - - store = GTK_TREE_MODEL (dyntable->priv->data_store); - holds_data = gtk_tree_model_get_iter_first (store, &iter); - g_return_if_fail (!holds_data); - - remove_empty_entries(dyntable, FALSE); - - dyntable->priv->columns = number_of_columns; - dyntable->priv->justified = justified; - - remove_empty_entries(dyntable, TRUE); -} - -void -e_contact_editor_dyntable_set_max_entries (EContactEditorDynTable *dyntable, - guint max) -{ - GtkTreeModel *store; - gint n_children; - - g_return_if_fail (max > 0); - - store = GTK_TREE_MODEL (dyntable->priv->data_store); - - n_children = gtk_tree_model_iter_n_children (store, NULL); - if (n_children > max) { - g_warning ("Dyntable holds %i items, setting max to %i, instead of %i", - n_children, n_children, max); - max = n_children; - } - - dyntable->priv->max_entries = max; - if (dyntable->priv->show_max_entries>max) - dyntable->priv->show_max_entries = max; - if (dyntable->priv->show_min_entries>max) - dyntable->priv->show_min_entries = max; - - remove_empty_entries (dyntable, TRUE); - show_button (dyntable); -} - -/* show at least number_of_entries, with or without data */ -void -e_contact_editor_dyntable_set_show_min (EContactEditorDynTable *dyntable, - guint number_of_entries) -{ - if (number_of_entries > dyntable->priv->show_max_entries) - dyntable->priv->show_min_entries = dyntable->priv->show_max_entries; - else - dyntable->priv->show_min_entries = number_of_entries; - - if (dyntable->priv->curr_entries < dyntable->priv->show_min_entries) - add_empty_entry (dyntable); - - adjust_visibility_of_widgets (dyntable); -} - -/* show no more than number_of_entries, hide the rest */ -void -e_contact_editor_dyntable_set_show_max (EContactEditorDynTable *dyntable, - guint number_of_entries) -{ - if (number_of_entries > dyntable->priv->max_entries) { - dyntable->priv->show_max_entries = dyntable->priv->max_entries; - } else if (number_of_entries < dyntable->priv->show_min_entries) { - dyntable->priv->show_max_entries = dyntable->priv->show_min_entries; - } else { - dyntable->priv->show_max_entries = number_of_entries; - } - - adjust_visibility_of_widgets (dyntable); -} - -/* use data_store to fill data into widgets */ -void -e_contact_editor_dyntable_fill_in_data (EContactEditorDynTable *dyntable) -{ - guint pos = 0, col, row; - EContactEditorDynTableClass *class; - GtkGrid *grid; - GtkTreeIter iter; - GtkTreeModel *store; - GtkWidget *w; - gboolean valid; - gchar *str_data; - gint int_data; - - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS (dyntable); - grid = GTK_GRID (dyntable); - store = GTK_TREE_MODEL (dyntable->priv->data_store); - - valid = gtk_tree_model_get_iter_first (store, &iter); - while (valid) { - gtk_tree_model_get (store, &iter, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, &str_data, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, &int_data, - -1); - - if (pos >= dyntable->priv->curr_entries) - add_empty_entry (dyntable); - - position_to_grid (dyntable, pos++, &col, &row); - w = gtk_grid_get_child_at (grid, col, row); - set_combo_box_active (dyntable, GTK_COMBO_BOX(w), int_data); - w = gtk_grid_get_child_at (grid, col + 1, row); - class->widget_fill (dyntable, w, str_data); - - valid = gtk_tree_model_iter_next (store, &iter); - - if (valid && pos >= dyntable->priv->max_entries) { - g_warning ("dyntable is configured with max_entries = %i, ignoring the rest.", dyntable->priv->max_entries); - break; - } - } - - /* fix visibility of added items */ - adjust_visibility_of_widgets (dyntable); -} - -/* the model returned has 3 columns - * - * UINT: sort order - * UINT: active combo item - * STRING: data extracted with widget_extract() - */ -GtkListStore* -e_contact_editor_dyntable_extract_data (EContactEditorDynTable *dyntable) -{ - EContactEditorDynTableClass *class; - GtkGrid *grid; - GtkListStore *data_store; - GtkWidget *w; - guint pos, col, row; - - grid = GTK_GRID(dyntable); - class = E_CONTACT_EDITOR_DYNTABLE_GET_CLASS(dyntable); - data_store = dyntable->priv->data_store; - - gtk_list_store_clear (data_store); - - for (pos = 0; pos < dyntable->priv->curr_entries; pos++) { - - position_to_grid (dyntable, pos, &col, &row); - w = gtk_grid_get_child_at (grid, col + 1, row); - - if (!class->widget_is_empty (dyntable, w)) { - GtkTreeIter iter; - gchar *dup; - gint combo_item; - const gchar *data; - - data = class->widget_extract (dyntable, w); - w = gtk_grid_get_child_at (grid, col, row); - combo_item = gtk_combo_box_get_active (GTK_COMBO_BOX(w)); - - dup = g_strdup (data); - g_strstrip(dup); - - gtk_list_store_append (data_store, &iter); - gtk_list_store_set (data_store, &iter, - DYNTABLE_STORE_COLUMN_SORTORDER, pos, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, combo_item, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, dup, - -1); - - g_free (dup); - } - } - - return dyntable->priv->data_store; -} - -/* the model returned has two columns - * - * STRING: bound to attribute "text" - * BOOLEAN: bound to attribute "sensitive" - */ -GtkListStore* -e_contact_editor_dyntable_get_combo_store (EContactEditorDynTable *dyntable) -{ - return dyntable->priv->combo_store; -} - -void -e_contact_editor_dyntable_set_combo_defaults (EContactEditorDynTable *dyntable, - const gint *defaults, - size_t defaults_n) -{ - dyntable->priv->combo_defaults = defaults; - dyntable->priv->combo_defaults_n = defaults_n; -} - -static void -dispose_impl (GObject *object) -{ - GtkListStore *store; - EContactEditorDynTable *dyntable; - - dyntable = E_CONTACT_EDITOR_DYNTABLE(object); - - store = dyntable->priv->data_store; - if (store) { - gtk_list_store_clear (store); - g_object_unref (store); - dyntable->priv->data_store = NULL; - } - - store = dyntable->priv->combo_store; - if (store) { - g_object_unref (store); - dyntable->priv->combo_store = NULL; - } - - G_OBJECT_CLASS(e_contact_editor_dyntable_parent_class)->dispose (object); -} - -static GtkWidget* -default_impl_widget_create (EContactEditorDynTable *dyntable) -{ - return gtk_entry_new (); -} - -static void -default_impl_widget_clear (EContactEditorDynTable *dyntable, - GtkWidget *w) -{ - GtkEntry *e; - e = GTK_ENTRY(w); - gtk_entry_set_text (e, ""); -} - -static const gchar* -default_impl_widget_extract (EContactEditorDynTable *dyntable, - GtkWidget *w) -{ - GtkEntry *e; - - e = GTK_ENTRY(w); - return gtk_entry_get_text (e); -} - -static void -default_impl_widget_fill (EContactEditorDynTable *dyntable, - GtkWidget *w, - const gchar *value) -{ - GtkEntry *e; - - e = GTK_ENTRY(w); - gtk_entry_set_text (e, value); -} - -static gboolean -default_impl_widget_is_empty (EContactEditorDynTable *dyntable, - GtkWidget *w) -{ - GtkEntry *e; - const gchar *data; - gchar * dup; - size_t len = -1; - - e = GTK_ENTRY(w); - if (0 == gtk_entry_get_text_length (e)) - return TRUE; - - data = gtk_entry_get_text (e); - - dup = g_strdup (data); - g_strchug (dup); - len = strlen (dup); - g_free (dup); - - return len <= 0; -} - -static void -e_contact_editor_dyntable_init (EContactEditorDynTable *dyntable) -{ - GtkGrid *grid; - - dyntable->priv = G_TYPE_INSTANCE_GET_PRIVATE(dyntable, - E_TYPE_CONTACT_EDITOR_DYNTABLE, - EContactEditorDynTablePrivate); - - /* fill in defaults */ - dyntable->priv->max_entries = MAX_CAPACITY; - dyntable->priv->curr_entries = 0; - dyntable->priv->show_min_entries = 0; - dyntable->priv->show_max_entries = dyntable->priv->max_entries; - dyntable->priv->columns = 2; - dyntable->priv->justified = FALSE; - dyntable->priv->combo_defaults = NULL; - - dyntable->priv->combo_store = gtk_list_store_new (DYNTABLE_COBMO_COLUMN_NUM_COLUMNS, - G_TYPE_STRING, G_TYPE_BOOLEAN); - dyntable->priv->data_store = gtk_list_store_new (DYNTABLE_STORE_COLUMN_NUM_COLUMNS, - G_TYPE_UINT, G_TYPE_INT, G_TYPE_STRING); - gtk_tree_sortable_set_sort_column_id ( - GTK_TREE_SORTABLE (dyntable->priv->data_store), - DYNTABLE_STORE_COLUMN_SORTORDER, - GTK_SORT_ASCENDING); - - dyntable->priv->add_button = gtk_button_new_with_label ("+"); - g_signal_connect_swapped (dyntable->priv->add_button, "clicked", - G_CALLBACK (add_empty_entry), dyntable); - g_signal_connect_swapped(dyntable->priv->add_button, "clicked", - G_CALLBACK (emit_row_added), dyntable); - - grid = GTK_GRID (dyntable); - - gtk_grid_attach (grid, dyntable->priv->add_button, 0, 0, 1, 1); - gtk_widget_set_valign (dyntable->priv->add_button, GTK_ALIGN_CENTER); - gtk_widget_set_halign (dyntable->priv->add_button, GTK_ALIGN_START); - gtk_widget_show (dyntable->priv->add_button); - - if (dyntable->priv->curr_entries < dyntable->priv->show_min_entries) - add_empty_entry (dyntable); -} - -static void -e_contact_editor_dyntable_class_init (EContactEditorDynTableClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof(EContactEditorDynTablePrivate)); - - dyntable_signals[CHANGED_SIGNAL] = g_signal_new ("changed", - G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(EContactEditorDynTableClass, changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - dyntable_signals[ACTIVATE_SIGNAL] = g_signal_new ("activate", - G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(EContactEditorDynTableClass, activate), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - dyntable_signals[ROW_ADDED_SIGNAL] = g_signal_new ("row-added", - G_TYPE_FROM_CLASS(class), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET(EContactEditorDynTableClass, row_added), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - object_class = G_OBJECT_CLASS (class); - object_class->dispose = dispose_impl; - - /* virtual functions */ - class->widget_create = default_impl_widget_create; - class->widget_is_empty = default_impl_widget_is_empty; - class->widget_clear = default_impl_widget_clear; - class->widget_extract = default_impl_widget_extract; - class->widget_fill = default_impl_widget_fill; -} diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-dyntable.h evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-dyntable.h --- evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-dyntable.h 2014-04-29 11:48:18.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-dyntable.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,126 +0,0 @@ -/* - * e-contact-editor-dyntable.h - * - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - */ - -#ifndef E_CONTACT_EDITOR_DYNTABLE_H_ -#define E_CONTACT_EDITOR_DYNTABLE_H_ - -#include -#include - -#define E_TYPE_CONTACT_EDITOR_DYNTABLE \ - (e_contact_editor_dyntable_get_type ()) -#define E_CONTACT_EDITOR_DYNTABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CONTACT_EDITOR_DYNTABLE, EContactEditorDynTable)) -#define E_CONTACT_EDITOR_DYNTABLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((klass), E_TYPE_CONTACT_EDITOR_DYNTABLE, EContactEditorDynTableClass)) -#define E_IS_CONTACT_EDITOR_DYNTABLE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CONTACT_EDITOR_DYNTABLE)) -#define E_IS_CONTACT_EDITOR_DYNTABLE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((obj), E_TYPE_CONTACT_EDITOR_DYNTABLE)) -#define E_CONTACT_EDITOR_DYNTABLE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - (obj,E_TYPE_CONTACT_EDITOR_DYNTABLE, EContactEditorDynTableClass)) - -G_BEGIN_DECLS - -typedef enum { - DYNTABLE_STORE_COLUMN_SORTORDER, - DYNTABLE_STORE_COLUMN_SELECTED_ITEM, - DYNTABLE_STORE_COLUMN_ENTRY_STRING, - DYNTABLE_STORE_COLUMN_NUM_COLUMNS -} EContactEditorDynTableStoreColumns; - -typedef enum { - DYNTABLE_COMBO_COLUMN_TEXT, - DYNTABLE_COMBO_COLUMN_SENSITIVE, - DYNTABLE_COBMO_COLUMN_NUM_COLUMNS -} EContactEditorDynTableComboColumns; - -typedef struct _EContactEditorDynTable EContactEditorDynTable; -typedef struct _EContactEditorDynTableClass EContactEditorDynTableClass; -typedef struct _EContactEditorDynTablePrivate EContactEditorDynTablePrivate; - -struct _EContactEditorDynTableClass { - GtkGridClass parent_class; - - /* Signals */ - void (*changed) (EContactEditorDynTable* dyntable); - void (*activate) (EContactEditorDynTable* dyntable); - void (*row_added) (EContactEditorDynTable* dyntable); - - /* virtual */ - - /* defaults to GtkEntiy */ - GtkWidget* (*widget_create) (EContactEditorDynTable *dyntable); - - /* defaults to string_is_empty(txt) */ - gboolean (*widget_is_empty) (EContactEditorDynTable *dyntable, - GtkWidget *w); - - /* defaults to entry_set_text("") */ - void (*widget_clear) (EContactEditorDynTable *dyntable, - GtkWidget *w); - - /* default impl gtk_entry_set_text - * other widgets may need to "parse" value before usage. - */ - void (*widget_fill) (EContactEditorDynTable *dyntable, - GtkWidget *w, - const gchar *value); - - /* default impl returns gtk_entry_get_text - * other widget may require some kind of "encoding" - */ - const gchar* (*widget_extract) (EContactEditorDynTable *dyntable, - GtkWidget *w); - -}; - -struct _EContactEditorDynTable { - GtkGrid parent; - - EContactEditorDynTablePrivate* priv; -}; - -GtkWidget* e_contact_editor_dyntable_new (void); -GType e_contact_editor_dyntable_get_type (void) G_GNUC_CONST; -void e_contact_editor_dyntable_set_show_min (EContactEditorDynTable *dyntable, - guint number_of_entries); -void e_contact_editor_dyntable_set_show_max (EContactEditorDynTable *dyntable, - guint number_of_entries); -void e_contact_editor_dyntable_set_num_columns (EContactEditorDynTable *dyntable, - guint number_of_columns, - gboolean justified); -void e_contact_editor_dyntable_set_max_entries (EContactEditorDynTable *dyntable, - guint max); - -GtkListStore* e_contact_editor_dyntable_get_combo_store (EContactEditorDynTable* dyntable); -void e_contact_editor_dyntable_set_combo_defaults (EContactEditorDynTable* dyntable, - const gint *defaults, - size_t defaults_n); -void e_contact_editor_dyntable_clear_data (EContactEditorDynTable *dyntable); -void e_contact_editor_dyntable_fill_in_data (EContactEditorDynTable *dyntable); -GtkListStore* e_contact_editor_dyntable_extract_data (EContactEditorDynTable *dyntable); - -G_END_DECLS - -#endif /* E_CONTACT_EDITOR_DYNTABLE_H_ */ diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-fullname.c evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-fullname.c --- evolution-3.16.0/addressbook/gui/contact-editor/e-contact-editor-fullname.c 2015-03-09 14:21:55.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/e-contact-editor-fullname.c 2014-03-24 09:25:23.000000000 +0000 @@ -214,6 +214,7 @@ action_area = gtk_dialog_get_action_area (dialog); content_area = gtk_dialog_get_content_area (dialog); + gtk_widget_realize (GTK_WIDGET (e_contact_editor_fullname)); gtk_container_set_border_width (GTK_CONTAINER (action_area), 12); gtk_container_set_border_width (GTK_CONTAINER (content_area), 0); diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/e-contact-quick-add.c evolution-3.12.11/addressbook/gui/contact-editor/e-contact-quick-add.c --- evolution-3.16.0/addressbook/gui/contact-editor/e-contact-quick-add.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/e-contact-quick-add.c 2014-07-10 09:13:26.000000000 +0000 @@ -190,7 +190,7 @@ e_client_cache_get_client ( qa->client_cache, qa->source, - E_SOURCE_EXTENSION_ADDRESS_BOOK, 30, + E_SOURCE_EXTENSION_ADDRESS_BOOK, qa->cancellable, merge_cb, qa); } @@ -337,7 +337,7 @@ e_client_cache_get_client ( qa->client_cache, qa->source, - E_SOURCE_EXTENSION_ADDRESS_BOOK, 30, + E_SOURCE_EXTENSION_ADDRESS_BOOK, qa->cancellable, ce_have_book, qa); } diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/fullname.ui evolution-3.12.11/addressbook/gui/contact-editor/fullname.ui --- evolution-3.16.0/addressbook/gui/contact-editor/fullname.ui 2015-03-09 14:21:55.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/fullname.ui 2014-03-24 09:25:23.000000000 +0000 @@ -9,7 +9,7 @@ - + Mr. @@ -35,7 +35,7 @@ - + Sr. diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/Makefile.am evolution-3.12.11/addressbook/gui/contact-editor/Makefile.am --- evolution-3.16.0/addressbook/gui/contact-editor/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -11,8 +11,7 @@ -DG_LOG_DOMAIN=\"contact-editor\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libecontacteditor_la_SOURCES = \ eab-editor.c \ @@ -22,11 +21,9 @@ e-contact-editor.c \ e-contact-editor.h \ e-contact-quick-add.c \ - e-contact-quick-add.h \ - e-contact-editor-dyntable.h \ - e-contact-editor-dyntable.c + e-contact-quick-add.h -libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libecontacteditor_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ @@ -36,7 +33,7 @@ $(EVOLUTION_ADDRESSBOOK_LIBS) \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) ui_DATA = \ contact-editor.ui \ diff -Nru evolution-3.16.0/addressbook/gui/contact-editor/Makefile.in evolution-3.12.11/addressbook/gui/contact-editor/Makefile.in --- evolution-3.16.0/addressbook/gui/contact-editor/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-editor/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -85,7 +85,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -135,12 +134,12 @@ $(top_builddir)/addressbook/util/libeabutil.la \ $(top_builddir)/addressbook/gui/widgets/libeabwidgets.la \ $(top_builddir)/addressbook/printing/libecontactprint.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libecontacteditor_la_OBJECTS = libecontacteditor_la-eab-editor.lo \ libecontacteditor_la-e-contact-editor-fullname.lo \ libecontacteditor_la-e-contact-editor.lo \ - libecontacteditor_la-e-contact-quick-add.lo \ - libecontacteditor_la-e-contact-editor-dyntable.lo + libecontacteditor_la-e-contact-quick-add.lo libecontacteditor_la_OBJECTS = $(am_libecontacteditor_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) @@ -221,14 +220,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -241,9 +237,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -257,8 +250,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -269,7 +260,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -296,6 +286,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -319,13 +313,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -473,8 +464,7 @@ -DG_LOG_DOMAIN=\"contact-editor\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libecontacteditor_la_SOURCES = \ eab-editor.c \ @@ -484,11 +474,9 @@ e-contact-editor.c \ e-contact-editor.h \ e-contact-quick-add.c \ - e-contact-quick-add.h \ - e-contact-editor-dyntable.h \ - e-contact-editor-dyntable.c + e-contact-quick-add.h -libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libecontacteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libecontacteditor_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/addressbook/util/libeabutil.la \ @@ -497,7 +485,7 @@ $(EVOLUTION_ADDRESSBOOK_LIBS) \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) ui_DATA = \ contact-editor.ui \ @@ -583,32 +571,28 @@ distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontacteditor_la-e-contact-editor-dyntable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontacteditor_la-e-contact-editor-fullname.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontacteditor_la-e-contact-editor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontacteditor_la-e-contact-quick-add.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontacteditor_la-eab-editor.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @@ -641,13 +625,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libecontacteditor_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libecontacteditor_la-e-contact-quick-add.lo `test -f 'e-contact-quick-add.c' || echo '$(srcdir)/'`e-contact-quick-add.c -libecontacteditor_la-e-contact-editor-dyntable.lo: e-contact-editor-dyntable.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libecontacteditor_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libecontacteditor_la-e-contact-editor-dyntable.lo -MD -MP -MF $(DEPDIR)/libecontacteditor_la-e-contact-editor-dyntable.Tpo -c -o libecontacteditor_la-e-contact-editor-dyntable.lo `test -f 'e-contact-editor-dyntable.c' || echo '$(srcdir)/'`e-contact-editor-dyntable.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libecontacteditor_la-e-contact-editor-dyntable.Tpo $(DEPDIR)/libecontacteditor_la-e-contact-editor-dyntable.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-contact-editor-dyntable.c' object='libecontacteditor_la-e-contact-editor-dyntable.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libecontacteditor_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libecontacteditor_la-e-contact-editor-dyntable.lo `test -f 'e-contact-editor-dyntable.c' || echo '$(srcdir)/'`e-contact-editor-dyntable.c - mostlyclean-libtool: -rm -f *.lo diff -Nru evolution-3.16.0/addressbook/gui/contact-list-editor/Makefile.am evolution-3.12.11/addressbook/gui/contact-list-editor/Makefile.am --- evolution-3.16.0/addressbook/gui/contact-list-editor/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-list-editor/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -11,8 +11,7 @@ -DG_LOG_DOMAIN=\"contact-list-editor\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libecontactlisteditor_la_SOURCES = \ e-contact-list-editor.c \ @@ -20,7 +19,7 @@ e-contact-list-model.c \ e-contact-list-model.h -libecontactlisteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libecontactlisteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libecontactlisteditor_la_LIBADD = \ $(top_builddir)/addressbook/util/libeabutil.la \ @@ -29,7 +28,7 @@ $(top_builddir)/shell/libevolution-shell.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) ui_DATA = contact-list-editor.ui diff -Nru evolution-3.16.0/addressbook/gui/contact-list-editor/Makefile.in evolution-3.12.11/addressbook/gui/contact-list-editor/Makefile.in --- evolution-3.16.0/addressbook/gui/contact-list-editor/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/contact-list-editor/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -85,7 +85,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -135,7 +134,8 @@ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libecontactlisteditor_la_OBJECTS = \ libecontactlisteditor_la-e-contact-list-editor.lo \ libecontactlisteditor_la-e-contact-list-model.lo @@ -220,14 +220,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -240,9 +237,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -256,8 +250,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -268,7 +260,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -295,6 +286,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -318,13 +313,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -472,8 +464,7 @@ -DG_LOG_DOMAIN=\"contact-list-editor\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libecontactlisteditor_la_SOURCES = \ e-contact-list-editor.c \ @@ -481,7 +472,7 @@ e-contact-list-model.c \ e-contact-list-model.h -libecontactlisteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libecontactlisteditor_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libecontactlisteditor_la_LIBADD = \ $(top_builddir)/addressbook/util/libeabutil.la \ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ @@ -489,7 +480,7 @@ $(top_builddir)/shell/libevolution-shell.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) ui_DATA = contact-list-editor.ui EXTRA_DIST = $(ui_DATA) @@ -576,25 +567,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontactlisteditor_la-e-contact-list-model.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/addressbook/gui/Makefile.in evolution-3.12.11/addressbook/gui/Makefile.in --- evolution-3.16.0/addressbook/gui/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -82,7 +82,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -187,14 +186,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -207,9 +203,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -223,8 +216,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -235,7 +226,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -262,6 +252,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -285,13 +279,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ diff -Nru evolution-3.16.0/addressbook/gui/widgets/ea-addressbook.c evolution-3.12.11/addressbook/gui/widgets/ea-addressbook.c --- evolution-3.16.0/addressbook/gui/widgets/ea-addressbook.c 2015-01-05 13:56:08.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/ea-addressbook.c 2014-03-24 09:25:23.000000000 +0000 @@ -79,10 +79,9 @@ GnomeCanvasItem *item = GNOME_CANVAS_ITEM (object); ea_event = atk_gobject_accessible_for_object (object); if (event->type == GDK_FOCUS_CHANGE) { - if (E_IS_MINICARD (item->canvas->focused_item)) - atk_object_notify_state_change (ea_event, - ATK_STATE_FOCUSED, - event->focus_change.in); + if ((event->focus_change.in) && + (E_IS_MINICARD (item->canvas->focused_item))) + atk_focus_tracker_notify (ea_event); } } diff -Nru evolution-3.16.0/addressbook/gui/widgets/eab-contact-compare.c evolution-3.12.11/addressbook/gui/widgets/eab-contact-compare.c --- evolution-3.16.0/addressbook/gui/widgets/eab-contact-compare.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/eab-contact-compare.c 2014-03-24 09:25:23.000000000 +0000 @@ -831,7 +831,7 @@ source = e_source_registry_ref_default_address_book (registry); - e_book_client_connect (source, 30, NULL, book_client_connect_cb, info); + e_book_client_connect (source, NULL, book_client_connect_cb, info); g_object_unref (source); } diff -Nru evolution-3.16.0/addressbook/gui/widgets/eab-contact-formatter.c evolution-3.12.11/addressbook/gui/widgets/eab-contact-formatter.c --- evolution-3.16.0/addressbook/gui/widgets/eab-contact-formatter.c 2015-02-27 11:40:10.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/eab-contact-formatter.c 2014-07-17 10:47:57.000000000 +0000 @@ -64,8 +64,6 @@ struct _EABContactFormatterPrivate { EABContactDisplayMode mode; gboolean render_maps; - gboolean supports_tel; - gboolean supports_sip; }; enum { @@ -88,9 +86,6 @@ eab_contact_formatter, G_TYPE_OBJECT); -#define E_CREATE_TEL_URL (E_TEXT_TO_HTML_LAST_FLAG << 0) -#define E_CREATE_SIP_URL (E_TEXT_TO_HTML_LAST_FLAG << 1) - static gboolean icon_available (const gchar *icon) { @@ -290,36 +285,6 @@ g_free (value); } -/* Returns NULL if no replace had been done (and - original 'str' should be used instead). Otherwise - free the returned pointer with g_free(). -*/ -static gchar * -maybe_create_url (const gchar *str, - guint html_flags) -{ - gchar *tmp = NULL; - const gchar *url = NULL; - - g_return_val_if_fail (str != NULL, NULL); - - if ((html_flags & E_CREATE_TEL_URL) != 0) { - /* RFC 3966 requires either the phone number begins with '+', - or the URL contains a 'phone-context' parameter, but that - also requires changing phone number for some countries, thus - rather mandate the '+' at the beginning. */ - if (*str == '+') - url = "tel:"; - } else if ((html_flags & E_CREATE_SIP_URL) != 0) { - url = "sip:"; - } - - if (url && g_ascii_strncasecmp (str, url, strlen (url)) != 0) - tmp = g_strconcat (url, str, NULL); - - return tmp; -} - static void accum_attribute (GString *buffer, EContact *contact, @@ -332,17 +297,8 @@ str = e_contact_get_const (contact, field); - if (str != NULL && *str != '\0') { - gchar *tmp = NULL; - - tmp = maybe_create_url (str, html_flags); - if (tmp) - str = tmp; - + if (str != NULL && *str != '\0') render_table_row (buffer, html_label, str, icon, html_flags); - - g_free (tmp); - } } static void @@ -380,125 +336,24 @@ { GList *val_list, *l; GString *val = g_string_new (""); - const gchar *str; - gchar *tmp; val_list = e_contact_get (contact, field); for (l = val_list; l; l = l->next) { - str = l->data; - if (l != val_list) g_string_append (val, "
"); - tmp = maybe_create_url (str, html_flags); - if (tmp) - str = tmp; - - if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) { - gchar *value = e_text_to_html (str, html_flags); - - if (value && *value) - g_string_append (val, value); - - g_free (value); - } else { - g_string_append (val, str); - } - - g_free (tmp); + g_string_append (val, l->data); } - if (val->str && *val->str) { - if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) - html_flags = 0; - + if (val->str && *val->str) render_table_row (buffer, html_label, val->str, icon, html_flags); - } g_string_free (val, TRUE); g_list_foreach (val_list, (GFunc) g_free, NULL); g_list_free (val_list); } -typedef enum { - EAB_CONTACT_FORMATTER_SIP_TYPE_HOME, - EAB_CONTACT_FORMATTER_SIP_TYPE_WORK, - EAB_CONTACT_FORMATTER_SIP_TYPE_OTHER -} EABContactFormatterSIPType; - -static void -accum_sip (GString *buffer, - EContact *contact, - EABContactFormatterSIPType use_sip_type, - const gchar *icon, - guint html_flags) -{ - const gchar *html_label = _("SIP"); - GList *sip_attr_list, *l; - GString *val = g_string_new (""); - gchar *tmp; - - sip_attr_list = e_contact_get_attributes (contact, E_CONTACT_SIP); - for (l = sip_attr_list; l; l = g_list_next (l)) { - EVCardAttribute *attr = l->data; - gchar *sip; - const gchar *str; - EABContactFormatterSIPType sip_type; - - if (e_vcard_attribute_has_type (attr, "HOME")) - sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_HOME; - else if (e_vcard_attribute_has_type (attr, "WORK")) - sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_WORK; - else - sip_type = EAB_CONTACT_FORMATTER_SIP_TYPE_OTHER; - - if (sip_type != use_sip_type) - continue; - - sip = e_vcard_attribute_get_value (attr); - if (!sip || !*sip) { - g_free (sip); - continue; - } - - tmp = maybe_create_url (sip, html_flags); - if (tmp) - str = tmp; - else - str = sip; - - if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) { - gchar *value = e_text_to_html (str, html_flags); - - if (value && *value) { - if (val->len) - g_string_append (val, "
"); - g_string_append (val, value); - } - - g_free (value); - } else { - if (val->len) - g_string_append (val, "
"); - g_string_append (val, str); - } - - g_free (tmp); - g_free (sip); - } - - if (val->str && *val->str) { - if ((html_flags & E_TEXT_TO_HTML_CONVERT_URLS) != 0) - html_flags = 0; - - render_table_row (buffer, html_label, val->str, icon, html_flags); - } - - g_string_free (val, TRUE); - g_list_free_full (sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); -} - static const gchar * get_email_location (EVCardAttribute *attr) { @@ -700,13 +555,6 @@ GList *email_list, *l, *email_attr_list, *al; gint email_num = 0; const gchar *nl; - guint32 sip_flags = 0; - - if (formatter->priv->supports_sip) - sip_flags = E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_HIDE_URL_SCHEME | - E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | - E_CREATE_SIP_URL; email = g_string_new (""); nl = ""; @@ -748,8 +596,6 @@ if (email->len) render_table_row (accum, _("Email"), email->str, NULL, 0); - accum_sip (accum, contact, EAB_CONTACT_FORMATTER_SIP_TYPE_OTHER, NULL, sip_flags); - accum_attribute (accum, contact, _("Nickname"), E_CONTACT_NICKNAME, NULL, 0); accum_attribute_multival (accum, contact, _("AIM"), E_CONTACT_IM_AIM, AIM_ICON, 0); accum_attribute_multival (accum, contact, _("GroupWise"), E_CONTACT_IM_GROUPWISE, GROUPWISE_ICON, 0); @@ -802,19 +648,6 @@ GString *buffer) { GString *accum = g_string_new (""); - guint32 phone_flags = 0, sip_flags = 0; - - if (formatter->priv->supports_tel) - phone_flags = E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_HIDE_URL_SCHEME | - E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | - E_CREATE_TEL_URL; - - if (formatter->priv->supports_sip) - sip_flags = E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_HIDE_URL_SCHEME | - E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | - E_CREATE_SIP_URL; accum_attribute (accum, contact, _("Company"), E_CONTACT_ORG, NULL, 0); accum_attribute (accum, contact, _("Department"), E_CONTACT_ORG_UNIT, NULL, 0); @@ -826,9 +659,8 @@ accum_attribute (accum, contact, _("Video Chat"), E_CONTACT_VIDEO_URL, VIDEOCONF_ICON, E_TEXT_TO_HTML_CONVERT_URLS); accum_attribute (accum, contact, _("Calendar"), E_CONTACT_CALENDAR_URI, NULL, E_TEXT_TO_HTML_CONVERT_URLS); accum_attribute (accum, contact, _("Free/Busy"), E_CONTACT_FREEBUSY_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, phone_flags); + accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_BUSINESS, NULL, 0); accum_attribute (accum, contact, _("Fax"), E_CONTACT_PHONE_BUSINESS_FAX, NULL, 0); - accum_sip (accum, contact, EAB_CONTACT_FORMATTER_SIP_TYPE_WORK, NULL, sip_flags); accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_WORK, E_CONTACT_ADDRESS_LABEL_WORK); if (formatter->priv->render_maps) accum_address_map (accum, contact, E_CONTACT_ADDRESS_WORK); @@ -851,25 +683,11 @@ GString *buffer) { GString *accum = g_string_new (""); - guint32 phone_flags = 0, sip_flags = 0; - - if (formatter->priv->supports_tel) - phone_flags = E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_HIDE_URL_SCHEME | - E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | - E_CREATE_TEL_URL; - - if (formatter->priv->supports_sip) - sip_flags = E_TEXT_TO_HTML_CONVERT_URLS | - E_TEXT_TO_HTML_HIDE_URL_SCHEME | - E_TEXT_TO_HTML_URL_IS_WHOLE_TEXT | - E_CREATE_SIP_URL; accum_attribute (accum, contact, _("Home Page"), E_CONTACT_HOMEPAGE_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); accum_attribute (accum, contact, _("Web Log"), E_CONTACT_BLOG_URL, NULL, E_TEXT_TO_HTML_CONVERT_URLS); - accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, phone_flags); - accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, phone_flags); - accum_sip (accum, contact, EAB_CONTACT_FORMATTER_SIP_TYPE_HOME, NULL, sip_flags); + accum_attribute (accum, contact, _("Phone"), E_CONTACT_PHONE_HOME, NULL, 0); + accum_attribute (accum, contact, _("Mobile Phone"), E_CONTACT_PHONE_MOBILE, NULL, 0); accum_address (accum, contact, _("Address"), E_CONTACT_ADDRESS_HOME, E_CONTACT_ADDRESS_LABEL_HOME); accum_time_attribute (accum, contact, _("Birthday"), E_CONTACT_BIRTH_DATE, NULL, 0); accum_time_attribute (accum, contact, _("Anniversary"), E_CONTACT_ANNIVERSARY, NULL, 0); @@ -1205,21 +1023,6 @@ g_string_append (buffer, "\n"); } -static gboolean -eab_contact_formatter_scheme_supported (const gchar *scheme) -{ - GAppInfo *app_info; - gboolean supported; - - app_info = g_app_info_get_default_for_uri_scheme (scheme); - supported = app_info != NULL; - - if (app_info && g_app_info_can_delete (app_info)) - g_app_info_delete (app_info); - - return supported; -} - static void eab_contact_formatter_set_property (GObject *object, guint property_id, @@ -1313,8 +1116,6 @@ formatter->priv->mode = EAB_CONTACT_DISPLAY_RENDER_NORMAL; formatter->priv->render_maps = FALSE; - formatter->priv->supports_tel = eab_contact_formatter_scheme_supported ("tel"); - formatter->priv->supports_sip = eab_contact_formatter_scheme_supported ("sip"); } EABContactFormatter * @@ -1396,7 +1197,13 @@ gboolean hidden; document = user_data; - id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (event_target)); +#if WEBKIT_CHECK_VERSION(2,2,0) /* XXX should really be (2,1,something) */ + id = webkit_dom_element_get_id ( + WEBKIT_DOM_ELEMENT (event_target)); +#else + id = webkit_dom_html_element_get_id ( + WEBKIT_DOM_HTML_ELEMENT (event_target)); +#endif list_id = g_strconcat ("list-", id, NULL); list = webkit_dom_document_get_element_by_id (document, list_id); @@ -1434,6 +1241,7 @@ length = webkit_dom_node_list_get_length (nodes); for (ii = 0; ii < length; ii++) { + WebKitDOMNode *node; node = webkit_dom_node_list_item (nodes, ii); @@ -1441,6 +1249,4 @@ WEBKIT_DOM_EVENT_TARGET (node), "click", G_CALLBACK (collapse_contacts_list), FALSE, document); } - - g_object_unref (nodes); } diff -Nru evolution-3.16.0/addressbook/gui/widgets/eab-contact-merging.c evolution-3.12.11/addressbook/gui/widgets/eab-contact-merging.c --- evolution-3.16.0/addressbook/gui/widgets/eab-contact-merging.c 2014-06-26 13:53:28.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/eab-contact-merging.c 2014-03-24 09:25:23.000000000 +0000 @@ -31,29 +31,12 @@ #include #include #include "addressbook/gui/widgets/eab-contact-display.h" -#include "addressbook/util/eab-book-util.h" #include "e-util/e-util.h" #include "e-util/e-util-private.h" #include #include -/* should be kept in synch with e-contact-editor */ -static EContactField -im_fetch_set[] = -{ - E_CONTACT_IM_AIM, - E_CONTACT_IM_JABBER, - E_CONTACT_IM_YAHOO, - E_CONTACT_IM_GADUGADU, - E_CONTACT_IM_MSN, - E_CONTACT_IM_ICQ, - E_CONTACT_IM_GROUPWISE, - E_CONTACT_IM_SKYPE, - E_CONTACT_IM_TWITTER, - E_CONTACT_IM_GOOGLE_TALK -}; - typedef struct dropdown_data dropdown_data; typedef enum { E_CONTACT_MERGING_ADD, @@ -87,7 +70,6 @@ static void match_query_callback (EContact *contact, EContact *match, EABContactMatchType type, gpointer closure); #define SIMULTANEOUS_MERGING_REQUESTS 20 -#define EVOLUTION_UI_SLOT_PARAM "X-EVOLUTION-UI-SLOT" static GList *merging_queue = NULL; static gint running_merge_requests = 0; @@ -306,7 +288,7 @@ } static void -attr_dropdown_changed (GtkWidget *dropdown, +email_dropdown_changed (GtkWidget *dropdown, dropdown_data *data) { gchar *str = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (dropdown)); @@ -345,98 +327,6 @@ add_contact_ready_cb, lookup); } -static void -create_dropdowns_for_multival_attr(GList *match_attr_list, - GList *contact_attr_list, - GList **use_attr_list, - gint *row, - GtkTable *table, - const gchar * (*label_str) (EVCardAttribute*) ) -{ - GtkWidget *label, *hbox, *dropdown; - GList *miter, *citer; - GHashTable *match_attrs; /* attr in the 'match' contact from address book */ - - match_attrs = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL); - - for (miter = match_attr_list; miter; miter = g_list_next (miter)) { - EVCardAttribute *attr = miter->data; - gchar *value; - - value = e_vcard_attribute_get_value (attr); - if (value && *value) { - g_hash_table_insert (match_attrs, value, attr); - *use_attr_list = g_list_prepend (*use_attr_list, attr); - } else { - g_free (value); - } - } - - *use_attr_list = g_list_reverse (*use_attr_list); - - for (citer = contact_attr_list; citer; citer = g_list_next (citer)) { - EVCardAttribute *attr = citer->data; - gchar *value; - - value = e_vcard_attribute_get_value (attr); - if (value && *value) { - if (!g_hash_table_lookup (match_attrs, value)) { - dropdown_data *data; - - /* the attr is not set in both contacts */ - *use_attr_list = g_list_append (*use_attr_list, attr); - - /* remove to avoid collisions with match UI_SLOTs */ - e_vcard_attribute_remove_param (attr, EVOLUTION_UI_SLOT_PARAM); - - (*row)++; - label = gtk_label_new (label_str (attr)); - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0); - gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, *row, *row + 1); - - dropdown = gtk_combo_box_text_new (); - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), value); - - data = g_new0 (dropdown_data, 1); - - gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), ""); - - gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0); - data->email_attr_list_item = g_list_last (*use_attr_list); - data->email_attr = attr; - - g_signal_connect ( - dropdown, "changed", - G_CALLBACK (attr_dropdown_changed), data); - g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free); - - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0); - gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, *row, *row + 1); - gtk_widget_show ((GtkWidget *) dropdown); - } - } - g_free (value); - } - g_hash_table_destroy (match_attrs); -} - -static void -set_attributes(EContact *contact, EContactField field, GList *use_attr_list) -{ - GList *miter, *citer; - - citer = NULL; - for (miter = use_attr_list; miter; miter = g_list_next (miter)) { - if (miter->data) - citer = g_list_prepend (citer, miter->data); - } - citer = g_list_reverse (citer); - e_contact_set_attributes (contact, field, citer); - g_list_free (citer); -} - static gint mergeit (EContactMergingLookup *lookup) { @@ -446,10 +336,8 @@ GtkTable *table; EContactField field; gchar *string = NULL, *string1 = NULL; - GList *use_email_attr_list, *contact_email_attr_list, *match_email_attr_list; - GList *use_tel_attr_list, *contact_tel_attr_list, *match_tel_attr_list; - GList *use_im_attr_list, *contact_im_attr_list, *match_im_attr_list; - GList *use_sip_attr_list, *contact_sip_attr_list, *match_sip_attr_list; + GList *match_email_attr_list, *contact_email_attr_list, *miter, *citer, *use_email_attr_list; + GHashTable *match_emails; /* emails in the 'match' contact */ gint row = -1; gint value = 0, result; @@ -475,6 +363,25 @@ _("_Merge"), GTK_RESPONSE_OK, NULL); + match_emails = g_hash_table_new_full (camel_strcase_hash, camel_strcase_equal, g_free, NULL); + match_email_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_EMAIL); + contact_email_attr_list = e_contact_get_attributes (lookup->contact, E_CONTACT_EMAIL); + use_email_attr_list = NULL; + + for (miter = match_email_attr_list; miter; miter = g_list_next (miter)) { + EVCardAttribute *attr = miter->data; + gchar *email; + + email = e_vcard_attribute_get_value (attr); + if (email && *email) { + g_hash_table_insert (match_emails, email, attr); + use_email_attr_list = g_list_prepend (use_email_attr_list, attr); + } else { + g_free (email); + } + } + + use_email_attr_list = g_list_reverse (use_email_attr_list); /*we match all the string fields of the already existing contact and the new contact.*/ for (field = E_CONTACT_FULL_NAME; field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) { @@ -484,13 +391,74 @@ /*the field must exist in the new as well as the duplicate contact*/ if (string && *string) { - if ((field >= E_CONTACT_FIRST_EMAIL_ID && field <= E_CONTACT_LAST_EMAIL_ID) || - (field >= E_CONTACT_FIRST_PHONE_ID && field <= E_CONTACT_LAST_PHONE_ID) || - (field >= E_CONTACT_IM_AIM_HOME_1 && field <= E_CONTACT_IM_ICQ_WORK_3) ) { - /* ignore multival attributes, they are compared after this for-loop */ + if (field == E_CONTACT_EMAIL_1) { + for (citer = contact_email_attr_list; citer; citer = g_list_next (citer)) { + EVCardAttribute *attr = citer->data; + gchar *email; + + email = e_vcard_attribute_get_value (attr); + if (email && *email) { + if (!g_hash_table_lookup (match_emails, email)) { + dropdown_data *data; + + /* the email is not set in both contacts */ + use_email_attr_list = g_list_append (use_email_attr_list, attr); + + row++; + label = gtk_label_new (_("Email")); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0); + gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1); + + dropdown = gtk_combo_box_text_new (); + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), email); + + data = g_new0 (dropdown_data, 1); + + gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), ""); + + gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0); + data->field = E_CONTACT_EMAIL; + data->match = lookup->match; + data->email_attr_list_item = g_list_last (use_email_attr_list); + data->email_attr = attr; + + g_signal_connect ( + dropdown, "changed", + G_CALLBACK (email_dropdown_changed), data); + g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free); + + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0); + gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1); + gtk_widget_show ((GtkWidget *) dropdown); + } + } + g_free (email); + } + continue; + } + + if (field == E_CONTACT_EMAIL_2 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) { + /* emails are compared above */ + continue; + } + + if (((field == E_CONTACT_FULL_NAME) && (!g_ascii_strcasecmp (string, string1)))) { + row++; + label = gtk_label_new (e_contact_pretty_name (field)); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0); + gtk_table_attach_defaults (table, (GtkWidget *) hbox, 0, 1, row, row + 1); + + label = gtk_label_new (string); + hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) label, FALSE, FALSE, 0); + gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1); continue; } + /*for all string fields except name and email*/ if (!(string1 && *string1) || (g_ascii_strcasecmp (string, string1))) { row++; label = gtk_label_new (e_contact_pretty_name (field)); @@ -500,25 +468,25 @@ data = g_new0 (dropdown_data, 1); dropdown = gtk_combo_box_text_new (); gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string); + e_contact_set (lookup->match, field, string); if (string1 && *string1) gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), string1); else gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (dropdown), ""); + gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0); data->field = field; data->match = lookup->match; + if (field == E_CONTACT_NICKNAME || field == E_CONTACT_GIVEN_NAME) + gtk_widget_set_sensitive ((GtkWidget *) dropdown, FALSE); + g_signal_connect ( dropdown, "changed", G_CALLBACK (dropdown_changed), data); g_object_set_data_full (G_OBJECT (dropdown), "eab-contact-merging::dropdown-data", data, g_free); - if (field == E_CONTACT_NICKNAME || field == E_CONTACT_GIVEN_NAME || field == E_CONTACT_FAMILY_NAME || field == E_CONTACT_FULL_NAME) - gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 1); - else - gtk_combo_box_set_active (GTK_COMBO_BOX (dropdown), 0); - hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); gtk_box_pack_start (GTK_BOX (hbox), (GtkWidget *) dropdown, FALSE, FALSE, 0); gtk_table_attach_defaults (table, (GtkWidget *) hbox, 1, 2, row, row + 1); @@ -527,30 +495,6 @@ } } - match_email_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_EMAIL); - contact_email_attr_list = e_contact_get_attributes (lookup->contact, E_CONTACT_EMAIL); - use_email_attr_list = NULL; - create_dropdowns_for_multival_attr (match_email_attr_list, contact_email_attr_list, - &use_email_attr_list, &row, table, eab_get_email_label_text); - - match_tel_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_TEL); - contact_tel_attr_list = e_contact_get_attributes (lookup->contact, E_CONTACT_TEL); - use_tel_attr_list = NULL; - create_dropdowns_for_multival_attr (match_tel_attr_list, contact_tel_attr_list, - &use_tel_attr_list, &row, table, eab_get_phone_label_text); - - match_sip_attr_list = e_contact_get_attributes (lookup->match, E_CONTACT_SIP); - contact_sip_attr_list = e_contact_get_attributes (lookup->contact, E_CONTACT_SIP); - use_sip_attr_list = NULL; - create_dropdowns_for_multival_attr (match_sip_attr_list, contact_sip_attr_list, - &use_sip_attr_list, &row, table, eab_get_sip_label_text); - - match_im_attr_list = e_contact_get_attributes_set (lookup->match, im_fetch_set, G_N_ELEMENTS (im_fetch_set)); - contact_im_attr_list = e_contact_get_attributes_set (lookup->contact, im_fetch_set, G_N_ELEMENTS (im_fetch_set)); - use_im_attr_list = NULL; - create_dropdowns_for_multival_attr (match_im_attr_list, contact_im_attr_list, - &use_im_attr_list, &row, table, eab_get_im_label_text); - gtk_window_set_default_size (GTK_WINDOW (dialog), 420, 300); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window), GTK_WIDGET (table)); gtk_box_pack_start (GTK_BOX (content_area), GTK_WIDGET (scrolled_window), TRUE, TRUE, 0); @@ -562,22 +506,15 @@ result = gtk_dialog_run (GTK_DIALOG (dialog)); switch (result) { - gint ii; - GList *ll; case GTK_RESPONSE_OK: - set_attributes (lookup->match, E_CONTACT_EMAIL, use_email_attr_list); - set_attributes (lookup->match, E_CONTACT_TEL, use_tel_attr_list); - set_attributes (lookup->match, E_CONTACT_SIP, use_sip_attr_list); - - for (ii = 0; ii < G_N_ELEMENTS (im_fetch_set); ii++) { - e_contact_set_attributes (lookup->match, im_fetch_set[ii], NULL); - } - - for (ll = use_im_attr_list; ll; ll = ll->next) { - EVCard *vcard; - vcard = E_VCARD (lookup->match); - e_vcard_append_attribute (vcard, e_vcard_attribute_copy ((EVCardAttribute *) ll->data)); + citer = NULL; + for (miter = use_email_attr_list; miter; miter = g_list_next (miter)) { + if (miter->data) + citer = g_list_prepend (citer, miter->data); } + citer = g_list_reverse (citer); + e_contact_set_attributes (lookup->match, E_CONTACT_EMAIL, citer); + g_list_free (citer); g_object_unref (lookup->contact); lookup->contact = g_object_ref (lookup->match); @@ -593,22 +530,10 @@ break; } gtk_widget_destroy (dialog); - g_list_free_full (match_email_attr_list, (GDestroyNotify) e_vcard_attribute_free); g_list_free_full (contact_email_attr_list, (GDestroyNotify) e_vcard_attribute_free); g_list_free (use_email_attr_list); - - g_list_free_full (match_tel_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free_full (contact_tel_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free (use_tel_attr_list); - - g_list_free_full (match_im_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free_full (contact_im_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free (use_im_attr_list); - - g_list_free_full (match_sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free_full (contact_sip_attr_list, (GDestroyNotify) e_vcard_attribute_free); - g_list_free (use_sip_attr_list); + g_hash_table_destroy (match_emails); return value; } @@ -618,64 +543,40 @@ EContact *match) { EContactField field; - gchar *string = NULL, *string1 = NULL; + GList *email_attr_list; + gint num_of_email; + gchar *str = NULL, *string = NULL, *string1 = NULL; gboolean res = TRUE; + email_attr_list = e_contact_get_attributes (match, E_CONTACT_EMAIL); + num_of_email = g_list_length (email_attr_list); for (field = E_CONTACT_FULL_NAME; res && field != (E_CONTACT_LAST_SIMPLE_STRING -1); field++) { - if (field == E_CONTACT_EMAIL_1) { - GList *email_attr_list1, *email_attr_list2, *iter1, *iter2; - gint num_of_email1, num_of_email2; - - email_attr_list1 = e_contact_get_attributes (contact, E_CONTACT_EMAIL); - num_of_email1 = g_list_length (email_attr_list1); - - email_attr_list2 = e_contact_get_attributes (match, E_CONTACT_EMAIL); - num_of_email2 = g_list_length (email_attr_list2); - - if (num_of_email1 != num_of_email2) { + if ((field == E_CONTACT_EMAIL_1 || field == E_CONTACT_EMAIL_2 + || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) && (num_of_email < 4)) { + str = (gchar *) e_contact_get_const (contact, field); + switch (num_of_email) + { + case 0: res = FALSE; break; - } else { /* Do pairwise-comparisons on all of the e-mail addresses. */ - iter1 = email_attr_list1; - while (iter1) { - gboolean match = FALSE; - EVCardAttribute *attr; - gchar *email_address1; - - attr = iter1->data; - email_address1 = e_vcard_attribute_get_value (attr); - - iter2 = email_attr_list2; - while ( iter2 && match == FALSE) { - gchar *email_address2; - - attr = iter2->data; - email_address2 = e_vcard_attribute_get_value (attr); - - if (g_ascii_strcasecmp (email_address1, email_address2) == 0) { - match = TRUE; - } - - g_free (email_address2); - iter2 = g_list_next (iter2); - } - - g_free (email_address1); - iter1 = g_list_next (iter1); - - if (match == FALSE) { - res = FALSE; - break; - } - } + case 1: + if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str))) + res = FALSE; + break; + case 2: + if ((str && *str) && (g_ascii_strcasecmp (str,e_contact_get_const (match, E_CONTACT_EMAIL_1))) && + (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str))) + res = FALSE; + break; + case 3: + if ((str && *str) && (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_1),str)) && + (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_2),str)) && + (g_ascii_strcasecmp (e_contact_get_const (match, E_CONTACT_EMAIL_3),str))) + res = FALSE; + break; } - - g_list_free_full (email_attr_list1, (GDestroyNotify) e_vcard_attribute_free); - g_list_free_full (email_attr_list2, (GDestroyNotify) e_vcard_attribute_free); - } else if (field > E_CONTACT_FIRST_EMAIL_ID && field <= E_CONTACT_LAST_EMAIL_ID) { - /* nothing to do, all emails are checked above */ } else { string = (gchar *) e_contact_get_const (contact, field); @@ -691,6 +592,8 @@ } } + g_list_free_full (email_attr_list, (GDestroyNotify) e_vcard_attribute_free); + return res; } diff -Nru evolution-3.16.0/addressbook/gui/widgets/eab-gui-util.c evolution-3.12.11/addressbook/gui/widgets/eab-gui-util.c --- evolution-3.16.0/addressbook/gui/widgets/eab-gui-util.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/eab-gui-util.c 2014-03-24 09:25:23.000000000 +0000 @@ -618,7 +618,7 @@ process->delete_from_source = delete_from_source; e_book_client_connect ( - destination, 30, NULL, book_client_connect_cb, process); + destination, NULL, book_client_connect_cb, process); } /* diff -Nru evolution-3.16.0/addressbook/gui/widgets/e-addressbook-selector.c evolution-3.12.11/addressbook/gui/widgets/e-addressbook-selector.c --- evolution-3.16.0/addressbook/gui/widgets/e-addressbook-selector.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/e-addressbook-selector.c 2014-07-17 10:48:07.000000000 +0000 @@ -326,7 +326,7 @@ merge_context->pending_adds = TRUE; e_client_selector_get_client ( - E_CLIENT_SELECTOR (selector), destination, FALSE, 30, NULL, + E_CLIENT_SELECTOR (selector), destination, NULL, target_client_connect_cb, merge_context); return TRUE; diff -Nru evolution-3.16.0/addressbook/gui/widgets/e-minicard.c evolution-3.12.11/addressbook/gui/widgets/e-minicard.c --- evolution-3.16.0/addressbook/gui/widgets/e-minicard.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/e-minicard.c 2014-10-09 09:05:38.000000000 +0000 @@ -83,6 +83,17 @@ LAST_SIGNAL }; +static struct { + const gchar *name; + const gchar *pretty_name; +} +common_location[] = +{ + { "WORK", N_ ("Work Email") }, + { "HOME", N_ ("Home Email") }, + { "OTHER", N_ ("Other Email") } +}; + static guint signals[LAST_SIGNAL] = {0, }; G_DEFINE_TYPE (EMinicard, e_minicard, GNOME_TYPE_CANVAS_GROUP) @@ -803,6 +814,19 @@ g_free (string); } +static const gchar * +get_email_location (EVCardAttribute *attr) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (common_location); i++) { + if (e_vcard_attribute_has_type (attr, common_location[i].name)) + return _(common_location[i].pretty_name); + } + + return _("Other Email"); +} + static void add_email_field (EMinicard *e_minicard, GList *email_list, @@ -831,7 +855,7 @@ if (is_list) { name = (gchar *)""; } else { - tmp = eab_get_email_label_text ((EVCardAttribute *) l->data); + tmp = get_email_location ((EVCardAttribute *) l->data); name = g_strdup_printf ("%s:", tmp); } diff -Nru evolution-3.16.0/addressbook/gui/widgets/Makefile.am evolution-3.12.11/addressbook/gui/widgets/Makefile.am --- evolution-3.16.0/addressbook/gui/widgets/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -18,10 +18,9 @@ -I$(top_builddir)/shell \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) \ $(CHAMPLAIN_CFLAGS) \ - $(GEO_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GEO_CFLAGS) eabincludedir = $(privincludedir)/addressbook/gui/widgets @@ -73,17 +72,15 @@ ea-addressbook.c \ ea-addressbook.h -libeabwidgets_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) - libeabwidgets_la_LIBADD = \ $(top_builddir)/shell/libevolution-shell.la \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ + $(GTKHTML_LIBS) \ $(CHAMPLAIN_LIBS) \ - $(GEO_LIBS) \ - $(NULL) + $(GEO_LIBS) dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) diff -Nru evolution-3.16.0/addressbook/gui/widgets/Makefile.in evolution-3.12.11/addressbook/gui/widgets/Makefile.in --- evolution-3.16.0/addressbook/gui/widgets/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/gui/widgets/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -86,7 +86,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -108,7 +107,8 @@ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/addressbook/util/libeabutil.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libeabwidgets_la_OBJECTS = libeabwidgets_la-eab-config.lo \ libeabwidgets_la-eab-contact-compare.lo \ libeabwidgets_la-eab-contact-display.lo \ @@ -136,10 +136,6 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libeabwidgets_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libeabwidgets_la_LDFLAGS) $(LDFLAGS) \ - -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -241,14 +237,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -261,9 +254,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -277,8 +267,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -289,7 +277,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -316,6 +303,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -339,13 +330,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -499,10 +487,9 @@ -I$(top_builddir)/shell \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) \ $(CHAMPLAIN_CFLAGS) \ - $(GEO_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GEO_CFLAGS) eabincludedir = $(privincludedir)/addressbook/gui/widgets eabinclude_HEADERS = \ @@ -553,16 +540,15 @@ ea-addressbook.c \ ea-addressbook.h -libeabwidgets_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) libeabwidgets_la_LIBADD = \ $(top_builddir)/shell/libevolution-shell.la \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ + $(GTKHTML_LIBS) \ $(CHAMPLAIN_LIBS) \ - $(GEO_LIBS) \ - $(NULL) + $(GEO_LIBS) etspec_DATA = e-addressbook-view.etspec EXTRA_DIST = \ @@ -616,7 +602,7 @@ } libeabwidgets.la: $(libeabwidgets_la_OBJECTS) $(libeabwidgets_la_DEPENDENCIES) $(EXTRA_libeabwidgets_la_DEPENDENCIES) - $(AM_V_CCLD)$(libeabwidgets_la_LINK) $(libeabwidgets_la_OBJECTS) $(libeabwidgets_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libeabwidgets_la_OBJECTS) $(libeabwidgets_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -648,25 +634,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeabwidgets_la-gal-view-minicard.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/addressbook/importers/evolution-csv-importer.c evolution-3.12.11/addressbook/importers/evolution-csv-importer.c --- evolution-3.16.0/addressbook/importers/evolution-csv-importer.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/importers/evolution-csv-importer.c 2014-03-24 09:25:23.000000000 +0000 @@ -929,7 +929,7 @@ source = g_datalist_get_data (&target->data, "csv-source"); - e_book_client_connect (source, 30, NULL, book_client_connect_cb, gci); + e_book_client_connect (source, NULL, book_client_connect_cb, gci); } static void diff -Nru evolution-3.16.0/addressbook/importers/evolution-ldif-importer.c evolution-3.12.11/addressbook/importers/evolution-ldif-importer.c --- evolution-3.16.0/addressbook/importers/evolution-ldif-importer.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/importers/evolution-ldif-importer.c 2014-03-24 09:25:23.000000000 +0000 @@ -723,7 +723,7 @@ source = g_datalist_get_data (&target->data, "ldif-source"); - e_book_client_connect (source, 30, NULL, book_client_connect_cb, gci); + e_book_client_connect (source, NULL, book_client_connect_cb, gci); } static void diff -Nru evolution-3.16.0/addressbook/importers/evolution-vcard-importer.c evolution-3.12.11/addressbook/importers/evolution-vcard-importer.c --- evolution-3.16.0/addressbook/importers/evolution-vcard-importer.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/importers/evolution-vcard-importer.c 2014-03-24 09:25:23.000000000 +0000 @@ -548,7 +548,7 @@ source = g_datalist_get_data (&target->data, "vcard-source"); - e_book_client_connect (source, 30, NULL, book_client_connect_cb, gci); + e_book_client_connect (source, NULL, book_client_connect_cb, gci); } static void diff -Nru evolution-3.16.0/addressbook/importers/Makefile.am evolution-3.12.11/addressbook/importers/Makefile.am --- evolution-3.16.0/addressbook/importers/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/importers/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -10,8 +10,7 @@ -I$(top_builddir)/addressbook \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libevolution_addressbook_importers_la_SOURCES = \ evolution-ldif-importer.c \ @@ -19,7 +18,7 @@ evolution-csv-importer.c \ evolution-addressbook-importers.h -libevolution_addressbook_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_addressbook_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libevolution_addressbook_importers_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ @@ -27,7 +26,7 @@ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(IMPORTERS_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(IMPORTERS_LIBS) -include $(top_srcdir)/git.mk diff -Nru evolution-3.16.0/addressbook/importers/Makefile.in evolution-3.12.11/addressbook/importers/Makefile.in --- evolution-3.16.0/addressbook/importers/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/importers/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -84,7 +84,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -133,7 +132,8 @@ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(top_builddir)/addressbook/util/libeabutil.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libevolution_addressbook_importers_la_OBJECTS = libevolution_addressbook_importers_la-evolution-ldif-importer.lo \ libevolution_addressbook_importers_la-evolution-vcard-importer.lo \ libevolution_addressbook_importers_la-evolution-csv-importer.lo @@ -218,14 +218,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -238,9 +235,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -254,8 +248,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -266,7 +258,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -293,6 +284,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -316,13 +311,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -469,8 +461,7 @@ -I$(top_builddir)/addressbook \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libevolution_addressbook_importers_la_SOURCES = \ evolution-ldif-importer.c \ @@ -478,15 +469,15 @@ evolution-csv-importer.c \ evolution-addressbook-importers.h -libevolution_addressbook_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_addressbook_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libevolution_addressbook_importers_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(IMPORTERS_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(IMPORTERS_LIBS) all: all-am @@ -572,25 +563,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_addressbook_importers_la-evolution-vcard-importer.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/addressbook/Makefile.in evolution-3.12.11/addressbook/Makefile.in --- evolution-3.16.0/addressbook/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -83,7 +83,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -217,14 +216,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -237,9 +233,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -253,8 +246,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -265,7 +256,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -292,6 +282,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -315,13 +309,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ diff -Nru evolution-3.16.0/addressbook/printing/e-contact-print.c evolution-3.12.11/addressbook/printing/e-contact-print.c --- evolution-3.16.0/addressbook/printing/e-contact-print.c 2014-06-26 13:53:28.000000000 +0000 +++ evolution-3.12.11/addressbook/printing/e-contact-print.c 2014-03-24 09:25:23.000000000 +0000 @@ -227,30 +227,6 @@ } } -/* - * returns (transfer-full) a formated email or a copy of value if parsing failed. - */ -static gchar* -format_email (const gchar* value) -{ - gchar *email = NULL, *name = NULL; - - if (eab_parse_qp_email (value, &name, &email)) { - gchar* res; - if (name && *name) - res = g_strdup_printf ("%s <%s>", name, email); - else - res = g_strdup_printf ("%s", email); - - g_free (name); - g_free (email); - - return res; - } - - return g_strdup (value); -} - static gchar * get_contact_string_value (EContact *contact, gint field) @@ -267,8 +243,21 @@ field == E_CONTACT_EMAIL_2 || field == E_CONTACT_EMAIL_3 || field == E_CONTACT_EMAIL_4) { - gchar* res = format_email (value); - return res; + gchar *email = NULL, *name = NULL; + + if (eab_parse_qp_email (value, &name, &email)) { + gchar *res; + + if (name && *name) + res = g_strdup_printf ("%s <%s>", name, email); + else + res = g_strdup_printf ("%s", email); + + g_free (name); + g_free (email); + + return res; + } } return g_strdup (value); } @@ -307,34 +296,8 @@ "%s: %s", e_contact_pretty_name (field), value); - if (field == E_CONTACT_FIRST_EMAIL_ID) { - GList *emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL); - guint n = g_list_length (emails); - cntct_height += n * e_contact_text_height ( - ctxt->context, - ctxt->style->body_font, - text); - g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free); - } else if (field > E_CONTACT_FIRST_EMAIL_ID && - field <= E_CONTACT_LAST_EMAIL_ID) { - /* ignore */ - } else if (field == E_CONTACT_FIRST_PHONE_ID) { - GList *phones = e_contact_get_attributes (contact, E_CONTACT_TEL); - guint n = g_list_length (phones); - cntct_height += n * e_contact_text_height ( - ctxt->context, - ctxt->style->body_font, - text); - g_list_free_full (phones, (GDestroyNotify) e_vcard_attribute_free); - } else if (field > E_CONTACT_FIRST_PHONE_ID && - field <= E_CONTACT_LAST_PHONE_ID) { - /* ignore */ - } else { - cntct_height += e_contact_text_height ( - ctxt->context, - ctxt->style->body_font, - text); - } + cntct_height += e_contact_text_height ( + ctxt->context, ctxt->style->body_font, text); cntct_height += .2 * get_font_height (ctxt->style->body_font); @@ -346,109 +309,19 @@ return cntct_height; } -static void -print_line (EContactPrintContext *ctxt, - const gchar *pretty_name, - const gchar *value) -{ - GtkPageSetup *setup; - gdouble page_height; - gint wrapped_lines = 0; - gchar *text; - - setup = gtk_print_context_get_page_setup (ctxt->context); - page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS); - - text = g_strdup_printf ( - "%s: %s", - pretty_name, value); - - - if (ctxt->y > page_height) - e_contact_start_new_column (ctxt); - - if (ctxt->pages == ctxt->page_nr) - e_contact_output ( - ctxt->context, ctxt->style->body_font, - ctxt->x, ctxt->y, ctxt->column_width + 4, text); - - if (get_font_width (ctxt->context, - ctxt->style->body_font, text) > ctxt->column_width) - wrapped_lines = - (get_font_width (ctxt->context, - ctxt->style->body_font, text) / - (ctxt->column_width + 4)) + 1; - ctxt->y = - ctxt->y + ((wrapped_lines + 1) * - e_contact_text_height ( - ctxt->context, - ctxt->style->body_font, - text)); - - ctxt->y += .2 * get_font_height (ctxt->style->body_font); - - g_free (text); -} - -static void -print_emails (EContact *contact, - EContactPrintContext *ctxt) -{ - gint i; - GList *emails, *l; - - emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL); - - for (i = 1, l = emails; l; l = g_list_next (l), i++) { - EVCardAttribute *attr = l->data; - gchar *email_address; - gchar *formatted_email; - const gchar *pretty_name; - - email_address = e_vcard_attribute_get_value (attr); - formatted_email = format_email (email_address); - pretty_name = eab_get_email_label_text (attr); - - print_line (ctxt, pretty_name, formatted_email); - - g_free (email_address); - g_free (formatted_email); - } - - g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free); -} - -static void -print_phones (EContact *contact, - EContactPrintContext * ctxt) -{ - GList *phones, *l; - - phones = e_contact_get_attributes (contact, E_CONTACT_TEL); - - for (l = phones; l; l = g_list_next (l)) { - EVCardAttribute *attr = l->data; - gchar *phone; - const gchar *pretty_name; - - phone = e_vcard_attribute_get_value (attr); - pretty_name = eab_get_phone_label_text (attr); - print_line (ctxt, pretty_name, phone); - - g_free (phone); - } - - g_list_free_full (phones, (GDestroyNotify) e_vcard_attribute_free); -} static void e_contact_print_contact (EContact *contact, EContactPrintContext *ctxt) { + GtkPageSetup *setup; gchar *file_as; cairo_t *cr; + gdouble page_height; gint field; + setup = gtk_print_context_get_page_setup (ctxt->context); + page_height = gtk_page_setup_get_page_height (setup, GTK_UNIT_POINTS); cr = gtk_print_context_get_cairo_context (ctxt->context); cairo_save (cr); @@ -480,29 +353,45 @@ for (field = E_CONTACT_FILE_AS; field != E_CONTACT_LAST_SIMPLE_STRING; field++) { - if (field == E_CONTACT_FIRST_EMAIL_ID) - print_emails (contact, ctxt); - else if (field > E_CONTACT_FIRST_EMAIL_ID && - field <= E_CONTACT_LAST_EMAIL_ID) - ; /* ignore, all emails are printed in print_emails() */ - else if (field == E_CONTACT_FIRST_PHONE_ID) - print_phones (contact, ctxt); - else if (field > E_CONTACT_FIRST_PHONE_ID && - field <= E_CONTACT_LAST_PHONE_ID) - ; /* ignore, all phones are printed in print_phones() */ - else { - gchar *value; - - value = get_contact_string_value (contact, field); - if (value == NULL || *value == '\0') { - g_free (value); - continue; - } + gchar *value; + gchar *text; + gint wrapped_lines = 0; - print_line (ctxt, e_contact_pretty_name (field), value); + if (ctxt->y > page_height) + e_contact_start_new_column (ctxt); + value = get_contact_string_value (contact, field); + if (value == NULL || *value == '\0') { g_free (value); + continue; } + + text = g_strdup_printf ( + "%s: %s", + e_contact_pretty_name (field), value); + + if (ctxt->pages == ctxt->page_nr) + e_contact_output ( + ctxt->context, ctxt->style->body_font, + ctxt->x, ctxt->y, ctxt->column_width + 4, text); + + if (get_font_width (ctxt->context, + ctxt->style->body_font, text) > ctxt->column_width) + wrapped_lines = + (get_font_width (ctxt->context, + ctxt->style->body_font, text) / + (ctxt->column_width + 4)) + 1; + ctxt->y = + ctxt->y + ((wrapped_lines + 1) * + e_contact_text_height ( + ctxt->context, + ctxt->style->body_font, + text)); + + ctxt->y += .2 * get_font_height (ctxt->style->body_font); + + g_free (value); + g_free (text); } ctxt->y += get_font_height (ctxt->style->headings_font) * .4 + 8; diff -Nru evolution-3.16.0/addressbook/printing/Makefile.am evolution-3.12.11/addressbook/printing/Makefile.am --- evolution-3.16.0/addressbook/printing/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/printing/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -13,13 +13,10 @@ -DEVOLUTION_ECPSDIR=\""$(ecpsdir)"\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) noinst_LTLIBRARIES = libecontactprint.la -libecontactprint_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) - libecontactprint_la_SOURCES = \ e-contact-print-types.h \ e-contact-print.c \ @@ -30,7 +27,7 @@ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) EXTRA_DIST = \ $(ecps_DATA) diff -Nru evolution-3.16.0/addressbook/printing/Makefile.in evolution-3.12.11/addressbook/printing/Makefile.in --- evolution-3.16.0/addressbook/printing/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/printing/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -85,7 +85,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -105,7 +104,8 @@ libecontactprint_la_DEPENDENCIES = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/addressbook/util/libeabutil.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libecontactprint_la_OBJECTS = \ libecontactprint_la-e-contact-print.lo libecontactprint_la_OBJECTS = $(am_libecontactprint_la_OBJECTS) @@ -113,10 +113,6 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libecontactprint_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libecontactprint_la_LDFLAGS) \ - $(LDFLAGS) -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -216,14 +212,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -236,9 +229,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -252,8 +242,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -264,7 +252,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -291,6 +278,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -314,13 +305,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -471,11 +459,9 @@ -DEVOLUTION_ECPSDIR=\""$(ecpsdir)"\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) noinst_LTLIBRARIES = libecontactprint.la -libecontactprint_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) libecontactprint_la_SOURCES = \ e-contact-print-types.h \ e-contact-print.c \ @@ -486,7 +472,7 @@ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) EXTRA_DIST = \ $(ecps_DATA) @@ -538,7 +524,7 @@ } libecontactprint.la: $(libecontactprint_la_OBJECTS) $(libecontactprint_la_DEPENDENCIES) $(EXTRA_libecontactprint_la_DEPENDENCIES) - $(AM_V_CCLD)$(libecontactprint_la_LINK) $(libecontactprint_la_OBJECTS) $(libecontactprint_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libecontactprint_la_OBJECTS) $(libecontactprint_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -549,25 +535,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libecontactprint_la-e-contact-print.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/addressbook/tools/evolution-addressbook-export.c evolution-3.12.11/addressbook/tools/evolution-addressbook-export.c --- evolution-3.16.0/addressbook/tools/evolution-addressbook-export.c 2014-11-13 08:04:39.000000000 +0000 +++ evolution-3.12.11/addressbook/tools/evolution-addressbook-export.c 2014-03-24 09:25:23.000000000 +0000 @@ -29,16 +29,20 @@ #include -#include -#include "e-util/e-util-private.h" - #include "evolution-addressbook-export.h" #ifdef G_OS_WIN32 #ifdef DATADIR #undef DATADIR #endif -#include +#include +#include +#ifndef PROCESS_DEP_ENABLE +#define PROCESS_DEP_ENABLE 0x00000001 +#endif +#ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION +#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002 +#endif #endif /* Command-Line Options */ @@ -78,7 +82,25 @@ gint IsVCard = FALSE; #ifdef G_OS_WIN32 - e_util_win32_initialize (); + /* Reduce risks */ + { + typedef BOOL (WINAPI *t_SetDllDirectoryA) (LPCSTR lpPathName); + t_SetDllDirectoryA p_SetDllDirectoryA; + + p_SetDllDirectoryA = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetDllDirectoryA"); + if (p_SetDllDirectoryA) + (*p_SetDllDirectoryA) (""); + } +#ifndef _WIN64 + { + typedef BOOL (WINAPI *t_SetProcessDEPPolicy) (DWORD dwFlags); + t_SetProcessDEPPolicy p_SetProcessDEPPolicy; + + p_SetProcessDEPPolicy = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetProcessDEPPolicy"); + if (p_SetProcessDEPPolicy) + (*p_SetProcessDEPPolicy) (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION); + } +#endif #endif /*i18n-lize */ @@ -159,8 +181,6 @@ g_object_unref (actctx.registry); - e_util_cleanup_settings (); - /*FIXME:should free actctx's some gchar * field, such as output_file! but since the program will end, so that will not cause mem leak. */ return 0; diff -Nru evolution-3.16.0/addressbook/tools/evolution-addressbook-export-list-cards.c evolution-3.12.11/addressbook/tools/evolution-addressbook-export-list-cards.c --- evolution-3.16.0/addressbook/tools/evolution-addressbook-export-list-cards.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/tools/evolution-addressbook-export-list-cards.c 2014-03-24 09:25:23.000000000 +0000 @@ -461,17 +461,6 @@ GSList *csv_all_fields) { gchar *aline; - GList *emails; - guint n_emails; - gchar *full_name; - - emails = e_contact_get_attributes (contact, E_CONTACT_EMAIL); - n_emails = g_list_length (emails); - full_name = e_contact_get (contact, E_CONTACT_FULL_NAME); - if (n_emails > 4) - g_warning ("%s: only 4 out of %i emails have been exported", full_name, n_emails); - g_free (full_name); - g_list_free_full (emails, (GDestroyNotify) e_vcard_attribute_free); aline = e_contact_to_csv (contact, csv_all_fields); return aline; @@ -719,7 +708,7 @@ else source = e_source_registry_ref_default_address_book (registry); - client = e_book_client_connect_sync (source, 30, NULL, &error); + client = e_book_client_connect_sync (source, NULL, &error); g_object_unref (source); diff -Nru evolution-3.16.0/addressbook/tools/evolution-addressbook-export-list-folders.c evolution-3.12.11/addressbook/tools/evolution-addressbook-export-list-folders.c --- evolution-3.16.0/addressbook/tools/evolution-addressbook-export-list-folders.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/addressbook/tools/evolution-addressbook-export-list-folders.c 2014-03-24 09:25:23.000000000 +0000 @@ -63,7 +63,7 @@ source = E_SOURCE (iter->data); - client = e_book_client_connect_sync (source, 30, NULL, &error); + client = e_book_client_connect_sync (source, NULL, &error); /* Sanity check. */ g_warn_if_fail ( diff -Nru evolution-3.16.0/addressbook/tools/Makefile.am evolution-3.12.11/addressbook/tools/Makefile.am --- evolution-3.16.0/addressbook/tools/Makefile.am 2014-11-13 08:05:32.000000000 +0000 +++ evolution-3.12.11/addressbook/tools/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -15,9 +15,7 @@ -DLIBDIR=\""$(libdir)"\" \ -I$(top_srcdir)/addressbook \ -I$(top_builddir)/addressbook \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) + $(EVOLUTION_DATA_SERVER_CFLAGS) evolution_addressbook_export_SOURCES = \ evolution-addressbook-export.c \ @@ -26,14 +24,10 @@ evolution-addressbook-export.h evolution_addressbook_export_LDADD = \ - $(top_builddir)/e-util/libevolution-util.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) - -evolution_addressbook_export_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) + $(EVOLUTION_DATA_SERVER_LIBS) if OS_WIN32 -evolution_addressbook_export_LDFLAGS += -mwindows +evolution_addressbook_export_LDFLAGS = -mwindows endif EXTRA_DIST = $(privlibexec_SCRIPTS) diff -Nru evolution-3.16.0/addressbook/tools/Makefile.in evolution-3.12.11/addressbook/tools/Makefile.in --- evolution-3.16.0/addressbook/tools/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/tools/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -80,14 +80,12 @@ build_triplet = @build@ host_triplet = @host@ privlibexec_PROGRAMS = evolution-addressbook-export$(EXEEXT) -@OS_WIN32_TRUE@am__append_1 = -mwindows subdir = addressbook/tools DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(srcdir)/csv2vcard.in $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -111,9 +109,7 @@ evolution_addressbook_export_OBJECTS = \ $(am_evolution_addressbook_export_OBJECTS) am__DEPENDENCIES_1 = -evolution_addressbook_export_DEPENDENCIES = \ - $(top_builddir)/e-util/libevolution-util.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +evolution_addressbook_export_DEPENDENCIES = $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -220,14 +216,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -240,9 +233,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -256,8 +246,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -268,7 +256,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -295,6 +282,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -318,13 +309,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -475,9 +463,7 @@ -DLIBDIR=\""$(libdir)"\" \ -I$(top_srcdir)/addressbook \ -I$(top_builddir)/addressbook \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) + $(EVOLUTION_DATA_SERVER_CFLAGS) evolution_addressbook_export_SOURCES = \ evolution-addressbook-export.c \ @@ -486,12 +472,9 @@ evolution-addressbook-export.h evolution_addressbook_export_LDADD = \ - $(top_builddir)/e-util/libevolution-util.la \ - $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) + $(EVOLUTION_DATA_SERVER_LIBS) -evolution_addressbook_export_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) \ - $(am__append_1) +@OS_WIN32_TRUE@evolution_addressbook_export_LDFLAGS = -mwindows EXTRA_DIST = $(privlibexec_SCRIPTS) all: all-am @@ -629,25 +612,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evolution_addressbook_export-evolution-addressbook-export.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/addressbook/util/eab-book-util.c evolution-3.12.11/addressbook/util/eab-book-util.c --- evolution-3.16.0/addressbook/util/eab-book-util.c 2014-11-21 09:58:59.000000000 +0000 +++ evolution-3.12.11/addressbook/util/eab-book-util.c 2014-11-21 10:13:40.000000000 +0000 @@ -24,265 +24,11 @@ #include #endif -#include #include #include "e-util/e-util.h" #include "eab-book-util.h" -static EABTypeLabel -email_types[] = -{ - { -1, "WORK", NULL, NC_ ("addressbook-label", "Work Email") }, - { -1, "HOME", NULL, NC_ ("addressbook-label", "Home Email") }, - { -1, "OTHER", NULL, NC_ ("addressbook-label", "Other Email") } -}; - -static EABTypeLabel -sip_types[] = -{ - { E_CONTACT_SIP, "WORK", NULL, NC_ ("addressbook-label", "Work SIP") }, - { E_CONTACT_SIP, "HOME", NULL, NC_ ("addressbook-label", "Home SIP") }, - { E_CONTACT_SIP, "OTHER", NULL, NC_ ("addressbook-label", "Other SIP") } -}; - -static EABTypeLabel -eab_phone_types[] = { - { E_CONTACT_PHONE_ASSISTANT, EVC_X_ASSISTANT, NULL, NULL }, - { E_CONTACT_PHONE_BUSINESS, "WORK", "VOICE", NULL }, - { E_CONTACT_PHONE_BUSINESS_FAX, "WORK", "FAX", NULL }, - { E_CONTACT_PHONE_CALLBACK, EVC_X_CALLBACK, NULL, NULL }, - { E_CONTACT_PHONE_CAR, "CAR", NULL, NULL }, - { E_CONTACT_PHONE_COMPANY, "X-EVOLUTION-COMPANY", NULL, NULL }, - { E_CONTACT_PHONE_HOME, "HOME", "VOICE", NULL }, - { E_CONTACT_PHONE_HOME_FAX, "HOME", "FAX", NULL }, - { E_CONTACT_PHONE_ISDN, "ISDN", NULL, NULL }, - { E_CONTACT_PHONE_MOBILE, "CELL", NULL, NULL }, - { E_CONTACT_PHONE_OTHER, "VOICE", NULL, NULL }, - { E_CONTACT_PHONE_OTHER_FAX, "FAX", NULL, NULL }, - { E_CONTACT_PHONE_PAGER, "PAGER", NULL, NULL }, - { E_CONTACT_PHONE_PRIMARY, "PREF", NULL, NULL }, - { E_CONTACT_PHONE_RADIO, EVC_X_RADIO, NULL, NULL }, - { E_CONTACT_PHONE_TELEX, EVC_X_TELEX, NULL, NULL }, - { E_CONTACT_PHONE_TTYTDD, EVC_X_TTYTDD, NULL, NULL } -}; -static gboolean eab_phone_types_init = TRUE; - -static EABTypeLabel -eab_im_service[] = -{ - { E_CONTACT_IM_AIM, NULL, NULL, NC_ ("addressbook-label", "AIM") }, - { E_CONTACT_IM_JABBER, NULL, NULL, NC_ ("addressbook-label", "Jabber") }, - { E_CONTACT_IM_YAHOO, NULL, NULL, NC_ ("addressbook-label", "Yahoo") }, - { E_CONTACT_IM_GADUGADU, NULL, NULL, NC_ ("addressbook-label", "Gadu-Gadu") }, - { E_CONTACT_IM_MSN, NULL, NULL, NC_ ("addressbook-label", "MSN") }, - { E_CONTACT_IM_ICQ, NULL, NULL, NC_ ("addressbook-label", "ICQ") }, - { E_CONTACT_IM_GROUPWISE, NULL, NULL, NC_ ("addressbook-label", "GroupWise") }, - { E_CONTACT_IM_SKYPE, NULL, NULL, NC_ ("addressbook-label", "Skype") }, - { E_CONTACT_IM_TWITTER, NULL, NULL, NC_ ("addressbook-label", "Twitter") }, - { E_CONTACT_IM_GOOGLE_TALK, NULL, NULL, NC_ ("addressbook-label", "Google Talk")} -}; - -const EABTypeLabel* -eab_get_email_type_labels (gint *n_elements) -{ - *n_elements = G_N_ELEMENTS (email_types); - return email_types; -} - -gint -eab_get_email_type_index (EVCardAttribute *attr) -{ - gint ii; - - for (ii = 0; ii < G_N_ELEMENTS (email_types); ii++) { - if (e_vcard_attribute_has_type (attr, email_types[ii].type_1)) - return ii; - } - - return -1; -} - -void -eab_email_index_to_type (gint index, const gchar **type_1) -{ - *type_1 = email_types[index].type_1; -} - -const gchar* -eab_get_email_label_text (EVCardAttribute *attr) -{ - const gchar *result; - gint n_elements; - gint index = eab_get_email_type_index (attr); - - if (index >= 0) { - result = _(eab_get_email_type_labels (&n_elements) [index].text); - } else { - /* To Translators: - * if an email address type is not one of the predefined types, - * this generic label is used instead of one of the predefined labels. - */ - result = C_("addressbook-label", "Email"); - } - - return result; -} - -const EABTypeLabel* -eab_get_sip_type_labels (gint *n_elements) -{ - *n_elements = G_N_ELEMENTS (sip_types); - return sip_types; -} - -gint -eab_get_sip_type_index (EVCardAttribute *attr) -{ - gint ii; - - for (ii = 0; ii < G_N_ELEMENTS (sip_types); ii++) { - if (e_vcard_attribute_has_type (attr, sip_types[ii].type_1)) - return ii; - } - - return -1; -} - -void -eab_sip_index_to_type (gint index, const gchar **type_1) -{ - *type_1 = sip_types[index].type_1; -} - -const gchar* -eab_get_sip_label_text (EVCardAttribute *attr) -{ - const gchar *result; - gint n_elements; - gint index = eab_get_sip_type_index (attr); - - if (index >= 0) { - result = _(eab_get_sip_type_labels (&n_elements) [index].text); - } else { - /* To Translators: - * if a SIP address type is not one of the predefined types, - * this generic label is used instead of one of the predefined labels. - * SIP=Session Initiation Protocol, used for voice over IP - */ - result = C_("addressbook-label", "SIP"); - } - - return result; -} - -const EABTypeLabel* -eab_get_im_type_labels (gint *n_elements) -{ - *n_elements = G_N_ELEMENTS (eab_im_service); - return eab_im_service; -} - -gint -eab_get_im_type_index (EVCardAttribute *attr) -{ - gint ii; - const gchar *name; - EContactField field; - - for (ii = 0; ii < G_N_ELEMENTS (eab_im_service); ii++) { - name = e_vcard_attribute_get_name (attr); - field = e_contact_field_id_from_vcard (name); - if (field == eab_im_service[ii].field_id) - return ii; - } - return -1; -} - -const gchar * -eab_get_im_label_text (EVCardAttribute *attr) -{ - const gchar *result; - gint index = eab_get_im_type_index (attr); - - if (index >= 0) { - result = _(eab_im_service [index].text); - } else { - /* To Translators: - * if an IM address type is not one of the predefined types, - * this generic label is used instead of one of the predefined labels. - * IM=Instant Messaging - */ - result = C_("addressbook-label", "IM"); - } - - return result; -} - -const EABTypeLabel* -eab_get_phone_type_labels (gint *n_elements) -{ - *n_elements = G_N_ELEMENTS (eab_phone_types); - - if (eab_phone_types_init) { - gint i; - eab_phone_types_init = FALSE; - for (i = 0; i < *n_elements; i++) { - eab_phone_types[i].text = e_contact_pretty_name (eab_phone_types[i].field_id); - } - } - - return eab_phone_types; -} - -/* - * return the index within eab_phone_types[] - */ -gint -eab_get_phone_type_index (EVCardAttribute *attr) -{ - gint i; - - for (i = 0; i < G_N_ELEMENTS (eab_phone_types); i++) { - if (e_vcard_attribute_has_type (attr, eab_phone_types[i].type_1) && - (eab_phone_types[i].type_2 == NULL || e_vcard_attribute_has_type (attr, eab_phone_types[i].type_2) || - (g_ascii_strcasecmp (eab_phone_types[i].type_2, "VOICE") == 0 && - g_list_length (e_vcard_attribute_get_param (attr, EVC_TYPE)) == 1))) - return i; - } - - return -1; -} - -const gchar* -eab_get_phone_label_text (EVCardAttribute *attr) -{ - const gchar *result; - gint n_elements; - gint index = eab_get_phone_type_index (attr); - - if (index >= 0) { - result = _(eab_get_phone_type_labels (&n_elements) [index].text); - } else { - /* To Translators: - * if a phone number type is not one of the predefined types, - * this generic label is used instead of one of the predefined labels. - */ - result = C_("addressbook-label", "Phone"); - } - - return result; -} - -void -eab_phone_index_to_type (gint index, - const gchar **type_1, - const gchar **type_2) -{ - *type_1 = eab_phone_types [index].type_1; - *type_2 = eab_phone_types [index].type_2; -} - /* Copied from camel_strstrcase */ static gchar * eab_strstrcase (const gchar *haystack, diff -Nru evolution-3.16.0/addressbook/util/eab-book-util.h evolution-3.12.11/addressbook/util/eab-book-util.h --- evolution-3.16.0/addressbook/util/eab-book-util.h 2014-06-26 14:05:54.000000000 +0000 +++ evolution-3.12.11/addressbook/util/eab-book-util.h 2014-03-24 09:25:23.000000000 +0000 @@ -27,36 +27,6 @@ G_BEGIN_DECLS -typedef struct { - EContactField field_id; - const gchar *type_1; - const gchar *type_2; - const gchar *text; -} EABTypeLabel; - -const EABTypeLabel *eab_get_phone_type_labels (gint *n_elements); -const gchar * eab_get_phone_label_text (EVCardAttribute *attr); -gint eab_get_phone_type_index (EVCardAttribute *attr); -void eab_phone_index_to_type (gint index, - const gchar **type_1, - const gchar **type_2); - -const EABTypeLabel *eab_get_im_type_labels (gint *n_elements); -gint eab_get_im_type_index (EVCardAttribute *attr); -const gchar * eab_get_im_label_text (EVCardAttribute *attr); - -const EABTypeLabel *eab_get_email_type_labels (gint *n_elements); -const gchar * eab_get_email_label_text (EVCardAttribute *attr); -gint eab_get_email_type_index (EVCardAttribute *attr); -void eab_email_index_to_type (gint index, - const gchar **type_1); - -const EABTypeLabel *eab_get_sip_type_labels (gint *n_elements); -const gchar * eab_get_sip_label_text (EVCardAttribute *attr); -gint eab_get_sip_type_index (EVCardAttribute *attr); -void eab_sip_index_to_type (gint index, - const gchar **type_1); - GSList * eab_contact_list_from_string (const gchar *str); gchar * eab_contact_list_to_string (const GSList *contacts); diff -Nru evolution-3.16.0/addressbook/util/Makefile.am evolution-3.12.11/addressbook/util/Makefile.am --- evolution-3.16.0/addressbook/util/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/addressbook/util/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -12,23 +12,22 @@ -I$(top_srcdir)/shell \ $(CAMEL_CFLAGS) \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) libeabutil_la_SOURCES = \ eab-book-util.c \ eab-book-util.h -libeabutil_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libeabutil_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libeabutil_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(CAMEL_LIBS) \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(GNOME_PLATFORM_LIBS) dist-hook: cd $(distdir); rm -f $(BUILT_SOURCES) diff -Nru evolution-3.16.0/addressbook/util/Makefile.in evolution-3.12.11/addressbook/util/Makefile.in --- evolution-3.16.0/addressbook/util/Makefile.in 2015-03-23 06:59:16.000000000 +0000 +++ evolution-3.12.11/addressbook/util/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -84,7 +84,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -132,7 +131,8 @@ libeabutil_la_DEPENDENCIES = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libeabutil_la_OBJECTS = libeabutil_la-eab-book-util.lo libeabutil_la_OBJECTS = $(am_libeabutil_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -212,14 +212,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -232,9 +229,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -248,8 +242,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -260,7 +252,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -287,6 +278,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -310,13 +305,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -465,22 +457,21 @@ -I$(top_srcdir)/shell \ $(CAMEL_CFLAGS) \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) libeabutil_la_SOURCES = \ eab-book-util.c \ eab-book-util.h -libeabutil_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libeabutil_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libeabutil_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(CAMEL_LIBS) \ $(EVOLUTION_DATA_SERVER_LIBS) \ - $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(GNOME_PLATFORM_LIBS) all: all-am @@ -564,25 +555,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libeabutil_la-eab-book-util.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/confidential-stamp.jpg and /tmp/I5PcnJuXui/evolution-3.12.11/art/confidential-stamp.jpg differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/draft-paper.png and /tmp/I5PcnJuXui/evolution-3.12.11/art/draft-paper.png differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/draft-stamp.jpg and /tmp/I5PcnJuXui/evolution-3.12.11/art/draft-stamp.jpg differ diff -Nru evolution-3.16.0/art/Makefile.am evolution-3.12.11/art/Makefile.am --- evolution-3.16.0/art/Makefile.am 2014-06-27 11:09:05.000000000 +0000 +++ evolution-3.12.11/art/Makefile.am 2014-06-27 11:42:53.000000000 +0000 @@ -1,16 +1,8 @@ images_DATA = \ - confidential-stamp.jpg \ - draft-paper.png \ - draft-stamp.jpg \ - midnight-stars.jpg \ - minus.png \ - paper.png \ - plus.png \ - rect.png \ - ribbon.jpg \ - texture.png \ working.png \ - world_map-960.png + world_map-960.png \ + plus.png \ + minus.png EXTRA_DIST = \ README \ diff -Nru evolution-3.16.0/art/Makefile.in evolution-3.12.11/art/Makefile.in --- evolution-3.16.0/art/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/art/Makefile.in 2015-02-09 08:21:53.000000000 +0000 @@ -83,7 +83,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -157,14 +156,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -177,9 +173,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -193,8 +186,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -205,7 +196,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -232,6 +222,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -255,13 +249,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -398,18 +389,10 @@ uidir = @uidir@ viewsdir = @viewsdir@ images_DATA = \ - confidential-stamp.jpg \ - draft-paper.png \ - draft-stamp.jpg \ - midnight-stars.jpg \ - minus.png \ - paper.png \ - plus.png \ - rect.png \ - ribbon.jpg \ - texture.png \ working.png \ - world_map-960.png + world_map-960.png \ + plus.png \ + minus.png EXTRA_DIST = \ README \ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/midnight-stars.jpg and /tmp/I5PcnJuXui/evolution-3.12.11/art/midnight-stars.jpg differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/paper.png and /tmp/I5PcnJuXui/evolution-3.12.11/art/paper.png differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/rect.png and /tmp/I5PcnJuXui/evolution-3.12.11/art/rect.png differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/ribbon.jpg and /tmp/I5PcnJuXui/evolution-3.12.11/art/ribbon.jpg differ Binary files /tmp/2tg8Q0c2vM/evolution-3.16.0/art/texture.png and /tmp/I5PcnJuXui/evolution-3.12.11/art/texture.png differ diff -Nru evolution-3.16.0/calendar/alarm-notify/alarm-notify.c evolution-3.12.11/calendar/alarm-notify/alarm-notify.c --- evolution-3.16.0/calendar/alarm-notify/alarm-notify.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/calendar/alarm-notify/alarm-notify.c 2014-03-24 09:25:23.000000000 +0000 @@ -312,7 +312,9 @@ debug (("Opening '%s' (%s)", e_source_get_display_name (source), e_source_get_uid (source))); - e_cal_client_connect (source, source_type, 30, NULL, client_connect_cb, an); + e_cal_client_connect ( + source, source_type, NULL, + client_connect_cb, an); g_mutex_unlock (&an->priv->mutex); } diff -Nru evolution-3.16.0/calendar/alarm-notify/config-data.c evolution-3.12.11/calendar/alarm-notify/config-data.c --- evolution-3.16.0/calendar/alarm-notify/config-data.c 2014-11-13 08:09:03.000000000 +0000 +++ evolution-3.12.11/calendar/alarm-notify/config-data.c 2014-03-24 09:25:23.000000000 +0000 @@ -26,7 +26,6 @@ #endif #include -#include #include "config-data.h" /* Whether we have initied ourselves by reading @@ -61,7 +60,7 @@ if (calendar_settings) return; - calendar_settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + calendar_settings = g_settings_new ("org.gnome.evolution.calendar"); } icaltimezone * diff -Nru evolution-3.16.0/calendar/alarm-notify/Makefile.am evolution-3.12.11/calendar/alarm-notify/Makefile.am --- evolution-3.16.0/calendar/alarm-notify/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/calendar/alarm-notify/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -21,8 +21,7 @@ $(GNOME_PLATFORM_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ $(CANBERRA_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) ui_DATA = \ alarm-notify.ui @@ -55,13 +54,11 @@ $(GNOME_PLATFORM_LIBS) \ $(LIBNOTIFY_LIBS) \ $(CANBERRA_LIBS) \ - $(EVOLUTIONALARMNOTIFYICON) \ - $(NULL) - -evolution_alarm_notify_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) + $(GTKHTML_LIBS) + $(EVOLUTIONALARMNOTIFYICON) if OS_WIN32 -evolution_alarm_notify_LDFLAGS += -mwindows +evolution_alarm_notify_LDFLAGS = -mwindows endif EXTRA_DIST = $(ui_DATA) \ diff -Nru evolution-3.16.0/calendar/alarm-notify/Makefile.in evolution-3.12.11/calendar/alarm-notify/Makefile.in --- evolution-3.16.0/calendar/alarm-notify/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/calendar/alarm-notify/Makefile.in 2015-02-09 08:21:54.000000000 +0000 @@ -82,14 +82,12 @@ @OS_WIN32_TRUE@bin_PROGRAMS = evolution-alarm-notify$(EXEEXT) @OS_WIN32_FALSE@privlibexec_PROGRAMS = \ @OS_WIN32_FALSE@ evolution-alarm-notify$(EXEEXT) -@OS_WIN32_TRUE@am__append_1 = -mwindows subdir = calendar/alarm-notify DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \ $(top_srcdir)/depcomp ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -128,7 +126,7 @@ $(top_builddir)/addressbook/util/libeabutil.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(EVOLUTIONALARMNOTIFYICON) + $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent @@ -235,14 +233,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -255,9 +250,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -271,8 +263,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -283,7 +273,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -310,6 +299,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -333,13 +326,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -489,8 +479,7 @@ $(GNOME_PLATFORM_CFLAGS) \ $(LIBNOTIFY_CFLAGS) \ $(CANBERRA_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) ui_DATA = \ alarm-notify.ui @@ -523,11 +512,9 @@ $(GNOME_PLATFORM_LIBS) \ $(LIBNOTIFY_LIBS) \ $(CANBERRA_LIBS) \ - $(EVOLUTIONALARMNOTIFYICON) \ - $(NULL) + $(GTKHTML_LIBS) -evolution_alarm_notify_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) \ - $(am__append_1) +@OS_WIN32_TRUE@evolution_alarm_notify_LDFLAGS = -mwindows EXTRA_DIST = $(ui_DATA) \ evolution-alarm-notify-icon.rc \ evolution-alarm-notify.ico @@ -684,25 +671,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/evolution_alarm_notify-util.Po@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @@ -1042,6 +1026,7 @@ tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-privlibexecPROGRAMS uninstall-uiDATA + $(EVOLUTIONALARMNOTIFYICON) evolution-alarm-notify-icon.o: evolution-alarm-notify.ico evolution-alarm-notify-icon.rc $(WINDRES) evolution-alarm-notify-icon.rc evolution-alarm-notify-icon.o diff -Nru evolution-3.16.0/calendar/alarm-notify/notify-main.c evolution-3.12.11/calendar/alarm-notify/notify-main.c --- evolution-3.16.0/calendar/alarm-notify/notify-main.c 2014-12-05 11:36:43.000000000 +0000 +++ evolution-3.12.11/calendar/alarm-notify/notify-main.c 2014-12-05 11:41:37.000000000 +0000 @@ -29,13 +29,18 @@ #include #include -#include - #include "alarm-notify.h" #include "config-data.h" #ifdef G_OS_WIN32 -#include +#include +#include +#ifndef PROCESS_DEP_ENABLE +#define PROCESS_DEP_ENABLE 0x00000001 +#endif +#ifndef PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION +#define PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION 0x00000002 +#endif #endif #include "e-util/e-util-private.h" @@ -59,9 +64,28 @@ AlarmNotify *alarm_notify_service; gint exit_status; GError *error = NULL; - #ifdef G_OS_WIN32 - e_util_win32_initialize (); + gchar *path; + + /* Reduce risks */ + { + typedef BOOL (WINAPI *t_SetDllDirectoryA) (LPCSTR lpPathName); + t_SetDllDirectoryA p_SetDllDirectoryA; + + p_SetDllDirectoryA = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetDllDirectoryA"); + if (p_SetDllDirectoryA) + (*p_SetDllDirectoryA) (""); + } +#ifndef _WIN64 + { + typedef BOOL (WINAPI *t_SetProcessDEPPolicy) (DWORD dwFlags); + t_SetProcessDEPPolicy p_SetProcessDEPPolicy; + + p_SetProcessDEPPolicy = GetProcAddress (GetModuleHandle ("kernel32.dll"), "SetProcessDEPPolicy"); + if (p_SetProcessDEPPolicy) + (*p_SetProcessDEPPolicy) (PROCESS_DEP_ENABLE | PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION); + } +#endif #endif bindtextdomain (GETTEXT_PACKAGE, EVOLUTION_LOCALEDIR); @@ -70,6 +94,15 @@ gtk_init (&argc, &argv); + e_gdbus_templates_init_main_thread (); + +#ifdef G_OS_WIN32 + path = g_build_path (";", _e_get_bindir (), g_getenv ("PATH"), NULL); + + if (!g_setenv ("PATH", path, TRUE)) + g_warning ("Could not set PATH for Evolution Alarm Notifier"); +#endif + alarm_notify_service = alarm_notify_new (NULL, &error); if (error != NULL) { @@ -103,7 +136,6 @@ g_object_unref (alarm_notify_service); config_data_cleanup (); - e_util_cleanup_settings (); return exit_status; } diff -Nru evolution-3.16.0/calendar/calendar.error.xml evolution-3.12.11/calendar/calendar.error.xml --- evolution-3.16.0/calendar/calendar.error.xml 2015-02-12 11:45:58.000000000 +0000 +++ evolution-3.12.11/calendar/calendar.error.xml 2014-03-24 09:25:23.000000000 +0000 @@ -287,127 +287,19 @@ - <_primary>Failed to open calendar '{0}' - {1} - - - - - <_primary>Failed to open memo list '{0}' + <_primary>Error loading calendar '{0}' {1} - <_primary>Failed to open task list '{0}' - {1} - - - - - <_primary>Failed to create an event in the calendar '{0}' - {1} - - - - - <_primary>Failed to create a memo in the memo list '{0}' - {1} - - - - - <_primary>Failed to create a task in the task list '{0}' - {1} - - - - - <_primary>Failed to modify an event in the calendar '{0}' - {1} - - - - - <_primary>Failed to modify a memo in the memo list '{0}' - {1} - - - - - <_primary>Failed to modify a task in the task list '{0}' - {1} - - - - - <_primary>Failed to delete an event in the calendar '{0}' - {1} - - - - - <_primary>Failed to delete a memo in the memo list '{0}' - {1} - - - - - <_primary>Failed to delete a task in the task list '{0}' - {1} - - - - - <_primary>Failed to update an event in the calendar '{0}' + <_primary>Error loading task list '{0}' {1} - - - <_primary>Failed to update a memo in the memo list '{0}' - {1} - - - - - <_primary>Failed to update a task in the task list '{0}' - {1} - - - - - <_primary>Failed to send an event to the calendar '{0}' - {1} - - - - - <_primary>Failed to send a memo to the memo list '{0}' - {1} - - - - - <_primary>Failed to send a task to the task list '{0}' - {1} - - - - - <_primary>Error creating view for the calendar '{0}' - {1} - - - - - <_primary>Error creating view for the task list '{0}' - {1} - - - + - <_primary>Error creating view for the memo list '{0}' + <_primary>Error loading memo list '{0}' {1} @@ -481,27 +373,4 @@ <_primary>Moving a memo into the memo list '{0}' - - - <_primary>Failed to refresh calendar '{0}' - {1} - - - - - <_primary>Failed to refresh task list '{0}' - {1} - - - - - <_primary>Failed to refresh memo list '{0}' - {1} - - - - <_primary>Failed to make an occurrence movable - {1} - - diff -Nru evolution-3.16.0/calendar/gui/calendar-config.c evolution-3.12.11/calendar/gui/calendar-config.c --- evolution-3.16.0/calendar/gui/calendar-config.c 2014-11-13 07:32:12.000000000 +0000 +++ evolution-3.12.11/calendar/gui/calendar-config.c 2014-03-24 09:25:23.000000000 +0000 @@ -52,7 +52,7 @@ if (config) return; - config = e_util_ref_settings ("org.gnome.evolution.calendar"); + config = g_settings_new ("org.gnome.evolution.calendar"); /* will be freed together with EShell */ g_object_set_data_full ( @@ -102,7 +102,7 @@ GSettings *settings; gboolean use_system_timezone; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); use_system_timezone = g_settings_get_boolean (settings, "use-system-timezone"); @@ -445,7 +445,7 @@ gchar *prefer_new_item; gboolean prefer_meeting; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); prefer_new_item = g_settings_get_string (settings, "prefer-new-item"); prefer_meeting = g_strcmp0 (prefer_new_item, "event-meeting-new") == 0; diff -Nru evolution-3.16.0/calendar/gui/comp-util.c evolution-3.12.11/calendar/gui/comp-util.c --- evolution-3.16.0/calendar/gui/comp-util.c 2014-12-09 14:38:35.000000000 +0000 +++ evolution-3.12.11/calendar/gui/comp-util.c 2014-11-04 05:54:18.000000000 +0000 @@ -30,9 +30,9 @@ #include "calendar-config.h" #include "comp-util.h" -#include "e-calendar-view.h" #include "dialogs/delete-comp.h" +#include "gnome-cal.h" #include "shell/e-shell-window.h" #include "shell/e-shell-view.h" @@ -204,28 +204,31 @@ } /** - * cal_comp_is_on_server_sync: - * @comp: an #ECalComponent - * @client: an #ECalClient - * @cancellable: (allow none): a #GCancellable - * @error: (out): (allow none): a #GError + * cal_comp_confirm_delete_empty_comp: + * @comp: A calendar component. + * @client: Calendar client where the component purportedly lives. + * @widget: Widget to be used as the basis for UTF8 conversion. * - * Checks whether @client contains @comp. A "No Such Object" error is not - * propagated to the caller, any other errors are. + * Assumming a calendar component with an empty SUMMARY property (as per + * string_is_empty()), asks whether the user wants to delete it based on + * whether the appointment is on the calendar server or not. If the + * component is on the server, this function will present a confirmation + * dialog and delete the component if the user tells it to. If the component + * is not on the server it will just return TRUE. * - * Returns: #TRUE, when the @client contains @comp, #FALSE when not or on error. - * The @error is not set when the @client doesn't contain the @comp. + * Return value: A result code indicating whether the component + * was not on the server and is to be deleted locally, whether it + * was on the server and the user deleted it, or whether the + * user cancelled the deletion. **/ gboolean -cal_comp_is_on_server_sync (ECalComponent *comp, - ECalClient *client, - GCancellable *cancellable, - GError **error) +cal_comp_is_on_server (ECalComponent *comp, + ECalClient *client) { const gchar *uid; gchar *rid = NULL; icalcomponent *icalcomp = NULL; - GError *local_error = NULL; + GError *error = NULL; g_return_val_if_fail (comp != NULL, FALSE); g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE); @@ -247,34 +250,33 @@ rid = e_cal_component_get_recurid_as_string (comp); } - if (e_cal_client_get_object_sync (client, uid, rid, &icalcomp, cancellable, &local_error) && - icalcomp != NULL) { + e_cal_client_get_object_sync ( + client, uid, rid, &icalcomp, NULL, &error); + + if (icalcomp != NULL) { icalcomponent_free (icalcomp); g_free (rid); return TRUE; } - if (g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) - g_clear_error (&local_error); - else - g_propagate_error (error, local_error); + if (!g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) + g_warning (G_STRLOC ": %s", error->message); + g_clear_error (&error); g_free (rid); return FALSE; } /** - * cal_comp_is_icalcomp_on_server_sync: - * The same as cal_comp_is_on_server_sync(), only the component parameter is + * is_icalcomp_on_the_server: + * same as @cal_comp_is_on_server, only the component parameter is * icalcomponent, not the ECalComponent. **/ gboolean -cal_comp_is_icalcomp_on_server_sync (icalcomponent *icalcomp, - ECalClient *client, - GCancellable *cancellable, - GError **error) +is_icalcomp_on_the_server (icalcomponent *icalcomp, + ECalClient *client) { gboolean on_server; ECalComponent *comp; @@ -282,11 +284,10 @@ if (!icalcomp || !client || !icalcomponent_get_uid (icalcomp)) return FALSE; - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icalcomp)); - if (!comp) - return FALSE; + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp)); - on_server = cal_comp_is_on_server_sync (comp, client, cancellable, error); + on_server = cal_comp_is_on_server (comp, client); g_object_unref (comp); @@ -294,7 +295,7 @@ } /** - * cal_comp_event_new_with_defaults_sync: + * cal_comp_event_new_with_defaults: * * Creates a new VEVENT component and adds any default alarms to it as set in * the program's configuration values, but only if not the all_day event. @@ -302,13 +303,11 @@ * Return value: A newly-created calendar component. **/ ECalComponent * -cal_comp_event_new_with_defaults_sync (ECalClient *client, - gboolean all_day, - gboolean use_default_reminder, - gint default_reminder_interval, - EDurationType default_reminder_units, - GCancellable *cancellable, - GError **error) +cal_comp_event_new_with_defaults (ECalClient *client, + gboolean all_day, + gboolean use_default_reminder, + gint default_reminder_interval, + EDurationType default_reminder_units) { icalcomponent *icalcomp = NULL; ECalComponent *comp; @@ -316,9 +315,7 @@ icalproperty *icalprop; ECalComponentAlarmTrigger trigger; - if (client && !e_cal_client_get_default_object_sync (client, &icalcomp, cancellable, error)) - return NULL; - + e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL); if (icalcomp == NULL) icalcomp = icalcomponent_new (ICAL_VEVENT_COMPONENT); @@ -377,25 +374,21 @@ } ECalComponent * -cal_comp_event_new_with_current_time_sync (ECalClient *client, - gboolean all_day, - gboolean use_default_reminder, - gint default_reminder_interval, - EDurationType default_reminder_units, - GCancellable *cancellable, - GError **error) +cal_comp_event_new_with_current_time (ECalClient *client, + gboolean all_day, + gboolean use_default_reminder, + gint default_reminder_interval, + EDurationType default_reminder_units) { ECalComponent *comp; struct icaltimetype itt; ECalComponentDateTime dt; icaltimezone *zone; - comp = cal_comp_event_new_with_defaults_sync ( + comp = cal_comp_event_new_with_defaults ( client, all_day, use_default_reminder, - default_reminder_interval, default_reminder_units, - cancellable, error); - if (!comp) - return NULL; + default_reminder_interval, default_reminder_units); + g_return_val_if_fail (comp != NULL, NULL); zone = calendar_config_get_icaltimezone (); @@ -423,16 +416,12 @@ } ECalComponent * -cal_comp_task_new_with_defaults_sync (ECalClient *client, - GCancellable *cancellable, - GError **error) +cal_comp_task_new_with_defaults (ECalClient *client) { ECalComponent *comp; icalcomponent *icalcomp = NULL; - if (client && !e_cal_client_get_default_object_sync (client, &icalcomp, cancellable, error)) - return NULL; - + e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL); if (icalcomp == NULL) icalcomp = icalcomponent_new (ICAL_VTODO_COMPONENT); @@ -447,16 +436,12 @@ } ECalComponent * -cal_comp_memo_new_with_defaults_sync (ECalClient *client, - GCancellable *cancellable, - GError **error) +cal_comp_memo_new_with_defaults (ECalClient *client) { ECalComponent *comp; icalcomponent *icalcomp = NULL; - if (client && !e_cal_client_get_default_object_sync (client, &icalcomp, cancellable, error)) - return NULL; - + e_cal_client_get_default_object_sync (client, &icalcomp, NULL, NULL); if (icalcomp == NULL) icalcomp = icalcomponent_new (ICAL_VJOURNAL_COMPONENT); @@ -491,23 +476,26 @@ if (g_strcmp0 (active_view, "calendar") == 0) { EShellContent *shell_content; EShellView *shell_view; - ECalendarView *cal_view; + GnomeCalendar *gnome_cal; time_t start = 0, end = 0; icaltimezone *zone; struct icaltimetype itt; icalcomponent *icalcomp; icalproperty *prop; - shell_view = e_shell_window_peek_shell_view (shell_window, "calendar"); + shell_view = e_shell_window_peek_shell_view ( + shell_window, "calendar"); g_return_if_fail (shell_view != NULL); - cal_view = NULL; + gnome_cal = NULL; shell_content = e_shell_view_get_shell_content (shell_view); - g_object_get (shell_content, "current-view", &cal_view, NULL); - g_return_if_fail (cal_view != NULL); - g_return_if_fail (e_calendar_view_get_visible_time_range (cal_view, &start, &end)); + g_object_get (shell_content, "calendar", &gnome_cal, NULL); + g_return_if_fail (gnome_cal != NULL); + + gnome_calendar_get_current_time_range (gnome_cal, &start, &end); + g_return_if_fail (start != 0); - zone = e_cal_model_get_timezone (e_calendar_view_get_model (cal_view)); + zone = e_cal_model_get_timezone (gnome_calendar_get_model (gnome_cal)); itt = icaltime_from_timet_with_zone (start, FALSE, zone); icalcomp = e_cal_component_get_icalcomponent (comp); @@ -520,8 +508,6 @@ } e_cal_component_rescan (comp); - - g_clear_object (&cal_view); } } } @@ -744,28 +730,37 @@ e_cal_component_free_datetime (&olddate); } -gboolean -comp_util_sanitize_recurrence_master_sync (ECalComponent *comp, - ECalClient *client, - GCancellable *cancellable, - GError **error) +void +comp_util_sanitize_recurrence_master (ECalComponent *comp, + ECalClient *client) { ECalComponent *master = NULL; icalcomponent *icalcomp = NULL; ECalComponentRange rid; ECalComponentDateTime sdt; const gchar *uid; + GError *error = NULL; /* Get the master component */ e_cal_component_get_uid (comp, &uid); - if (!e_cal_client_get_object_sync (client, uid, NULL, &icalcomp, cancellable, error)) - return FALSE; + e_cal_client_get_object_sync ( + client, uid, NULL, &icalcomp, NULL, &error); - master = e_cal_component_new_from_icalcomponent (icalcomp); - if (!master) { - g_warn_if_reached (); - return FALSE; + if (error != NULL) { + g_warning ( + "Unable to get the master component: %s", + error->message); + g_error_free (error); + return; + } + + master = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (master, icalcomp)) { + icalcomponent_free (icalcomp); + g_object_unref (master); + g_return_if_reached (); + return; } /* Compare recur id and start date */ @@ -783,16 +778,9 @@ e_cal_component_get_dtend (comp, &edt); - if (!msdt.value || !medt.value || !edt.value) { - g_warn_if_reached (); - e_cal_component_free_datetime (&msdt); - e_cal_component_free_datetime (&medt); - e_cal_component_free_datetime (&edt); - e_cal_component_free_datetime (&sdt); - e_cal_component_free_range (&rid); - g_object_unref (master); - return FALSE; - } + g_return_if_fail (msdt.value != NULL); + g_return_if_fail (medt.value != NULL); + g_return_if_fail (edt.value != NULL); sdt.value->year = msdt.value->year; sdt.value->month = msdt.value->month; @@ -818,8 +806,6 @@ e_cal_component_set_recurid (comp, NULL); g_object_unref (master); - - return TRUE; } gchar * @@ -842,106 +828,6 @@ return g_strconcat (summary, ".ics", NULL); } -void -cal_comp_get_instance_times (ECalClient *client, - icalcomponent *icalcomp, - const icaltimezone *default_zone, - time_t *instance_start, - gboolean *start_is_date, - time_t *instance_end, - gboolean *end_is_date, - GCancellable *cancellable) -{ - struct icaltimetype start_time, end_time; - const icaltimezone *zone = default_zone; - - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - g_return_if_fail (instance_start != NULL); - g_return_if_fail (instance_end != NULL); - - start_time = icalcomponent_get_dtstart (icalcomp); - end_time = icalcomponent_get_dtend (icalcomp); - - /* Some event can have missing DTEND, then use the start_time for them */ - if (icaltime_is_null_time (end_time)) - end_time = start_time; - - if (start_time.zone) { - zone = start_time.zone; - } else { - icalparameter *param = NULL; - icalproperty *prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY); - - if (prop) { - param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); - - if (param) { - const gchar *tzid = NULL; - icaltimezone *st_zone = NULL; - - tzid = icalparameter_get_tzid (param); - if (tzid) - e_cal_client_get_timezone_sync (client, tzid, &st_zone, cancellable, NULL); - - if (st_zone) - zone = st_zone; - } - } - } - - *instance_start = icaltime_as_timet_with_zone (start_time, zone); - if (start_is_date) - *start_is_date = start_time.is_date; - - if (end_time.zone) { - zone = end_time.zone; - } else { - icalparameter *param = NULL; - icalproperty *prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY); - - if (prop) { - param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); - - if (param) { - const gchar *tzid = NULL; - icaltimezone *end_zone = NULL; - - tzid = icalparameter_get_tzid (param); - if (tzid) - e_cal_client_get_timezone_sync (client, tzid, &end_zone, cancellable, NULL); - - if (end_zone) - zone = end_zone; - } - } - - } - - *instance_end = icaltime_as_timet_with_zone (end_time, zone); - if (end_is_date) - *end_is_date = end_time.is_date; -} - -time_t -cal_comp_gdate_to_timet (const GDate *date, - const icaltimezone *with_zone) -{ - struct tm tm; - struct icaltimetype tt; - - g_return_val_if_fail (date != NULL, (time_t) -1); - g_return_val_if_fail (g_date_valid (date), (time_t) -1); - - g_date_to_struct_tm (date, &tm); - - tt = tm_to_icaltimetype (&tm, TRUE); - if (with_zone) - return icaltime_as_timet_with_zone (tt, with_zone); - - return icaltime_as_timet (tt); -} - typedef struct _AsyncContext { ECalClient *src_client; icalcomponent *icalcomp_clone; @@ -1139,19 +1025,19 @@ success = e_cal_client_get_object_sync (dest_client, uid, NULL, &icalcomp, cancellable, &local_error); if (success) { success = e_cal_client_modify_object_sync ( - dest_client, icalcomp_event, E_CAL_OBJ_MOD_ALL, cancellable, error); + dest_client, icalcomp_event, CALOBJ_MOD_ALL, cancellable, error); icalcomponent_free (icalcomp); if (!success) goto exit; if (!do_copy) { - ECalObjModType mod_type = E_CAL_OBJ_MOD_THIS; + ECalObjModType mod_type = CALOBJ_MOD_THIS; /* Remove the item from the source calendar. */ if (e_cal_util_component_is_instance (icalcomp_event) || e_cal_util_component_has_recurrences (icalcomp_event)) - mod_type = E_CAL_OBJ_MOD_ALL; + mod_type = CALOBJ_MOD_ALL; success = e_cal_client_remove_object_sync ( src_client, uid, NULL, mod_type, cancellable, error); @@ -1267,7 +1153,7 @@ if (did_add) { success = e_cal_client_modify_object_sync ( dest_client, subcomp, - E_CAL_OBJ_MOD_THIS, cancellable, error); + CALOBJ_MOD_THIS, cancellable, error); } else { /* just in case there are only detached instances and no master object */ did_add = TRUE; @@ -1288,12 +1174,12 @@ goto exit; if (!do_copy) { - ECalObjModType mod_type = E_CAL_OBJ_MOD_THIS; + ECalObjModType mod_type = CALOBJ_MOD_THIS; /* Remove the item from the source calendar. */ if (e_cal_util_component_is_instance (icalcomp_event) || e_cal_util_component_has_recurrences (icalcomp_event)) - mod_type = E_CAL_OBJ_MOD_ALL; + mod_type = CALOBJ_MOD_ALL; success = e_cal_client_remove_object_sync (src_client, uid, NULL, mod_type, cancellable, error); if (!success) diff -Nru evolution-3.16.0/calendar/gui/comp-util.h evolution-3.12.11/calendar/gui/comp-util.h --- evolution-3.16.0/calendar/gui/comp-util.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/comp-util.h 2014-03-24 09:25:23.000000000 +0000 @@ -28,7 +28,6 @@ #include #include -#include struct _EShell; @@ -44,40 +43,24 @@ /* Returns the number of icons owned by the ECalComponent */ gint cal_comp_util_get_n_icons (ECalComponent *comp, GSList **pixbufs); -gboolean cal_comp_is_on_server_sync (ECalComponent *comp, - ECalClient *client, - GCancellable *cancellable, - GError **error); -gboolean cal_comp_is_icalcomp_on_server_sync - (icalcomponent *icalcomp, - ECalClient *client, - GCancellable *cancellable, - GError **error); +gboolean cal_comp_is_on_server (ECalComponent *comp, + ECalClient *client); +gboolean is_icalcomp_on_the_server (icalcomponent *icalcomp, ECalClient *client); -ECalComponent * cal_comp_event_new_with_defaults_sync +ECalComponent * cal_comp_event_new_with_defaults (ECalClient *client, gboolean all_day, gboolean use_default_reminder, gint default_reminder_interval, - EDurationType default_reminder_units, - GCancellable *cancellable, - GError **error); -ECalComponent * cal_comp_event_new_with_current_time_sync + EDurationType default_reminder_units); +ECalComponent * cal_comp_event_new_with_current_time (ECalClient *client, gboolean all_day, gboolean use_default_reminder, gint default_reminder_interval, - EDurationType default_reminder_units, - GCancellable *cancellable, - GError **error); -ECalComponent * cal_comp_task_new_with_defaults_sync - (ECalClient *client, - GCancellable *cancellable, - GError **error); -ECalComponent * cal_comp_memo_new_with_defaults_sync - (ECalClient *client, - GCancellable *cancellable, - GError **error); + EDurationType default_reminder_units); +ECalComponent *cal_comp_task_new_with_defaults (ECalClient *client); +ECalComponent *cal_comp_memo_new_with_defaults (ECalClient *client); void cal_comp_update_time_by_active_window (ECalComponent *comp, struct _EShell *shell); @@ -87,25 +70,10 @@ void cal_comp_set_dtstart_with_oldzone (ECalClient *client, ECalComponent *comp, const ECalComponentDateTime *pdate); void cal_comp_set_dtend_with_oldzone (ECalClient *client, ECalComponent *comp, const ECalComponentDateTime *pdate); -gboolean comp_util_sanitize_recurrence_master_sync - (ECalComponent *comp, - ECalClient *client, - GCancellable *cancellable, - GError **error); +void comp_util_sanitize_recurrence_master (ECalComponent *comp, ECalClient *client); gchar *icalcomp_suggest_filename (icalcomponent *icalcomp, const gchar *default_name); -void cal_comp_get_instance_times (ECalClient *client, - icalcomponent *icalcomp, - const icaltimezone *default_zone, - time_t *instance_start, - gboolean *start_is_date, - time_t *instance_end, - gboolean *end_is_date, - GCancellable *cancellable); -time_t cal_comp_gdate_to_timet (const GDate *date, - const icaltimezone *with_zone); - void cal_comp_transfer_item_to (ECalClient *src_client, ECalClient *dest_client, icalcomponent *icalcomp_vcal, diff -Nru evolution-3.16.0/calendar/gui/dialogs/comp-editor.c evolution-3.12.11/calendar/gui/dialogs/comp-editor.c --- evolution-3.16.0/calendar/gui/dialogs/comp-editor.c 2015-02-24 08:13:37.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/comp-editor.c 2014-04-23 12:36:23.000000000 +0000 @@ -119,7 +119,7 @@ gboolean saved; - ECalObjModType mod; + CalObjModType mod; gboolean existing_org; gboolean user_org; @@ -551,7 +551,7 @@ priv->comp, get_attachment_list (editor)); icalcomp = e_cal_component_get_icalcomponent (priv->comp); /* send the component to the server */ - if (!cal_comp_is_on_server_sync (priv->comp, priv->cal_client, NULL, NULL)) { + if (!cal_comp_is_on_server (priv->comp, priv->cal_client)) { gchar *uid = NULL; result = e_cal_client_create_object_sync ( priv->cal_client, icalcomp, &uid, NULL, &error); @@ -566,10 +566,11 @@ has_recurrences = e_cal_component_has_recurrences (priv->comp); - if (has_recurrences && priv->mod == E_CAL_OBJ_MOD_ALL) - comp_util_sanitize_recurrence_master_sync (priv->comp, priv->cal_client, NULL, NULL); + if (has_recurrences && priv->mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master ( + priv->comp, priv->cal_client); - if (priv->mod == E_CAL_OBJ_MOD_THIS) { + if (priv->mod == CALOBJ_MOD_THIS) { e_cal_component_set_rdate_list (priv->comp, NULL); e_cal_component_set_rrule_list (priv->comp, NULL); e_cal_component_set_exdate_list (priv->comp, NULL); @@ -578,7 +579,7 @@ result = e_cal_client_modify_object_sync ( priv->cal_client, icalcomp, priv->mod, NULL, &error); - if (priv->mod == E_CAL_OBJ_MOD_THIS) { + if (priv->mod == CALOBJ_MOD_THIS) { if (result && ((flags & COMP_EDITOR_DELEGATE) || !e_cal_component_has_organizer (clone) || itip_organizer_is_user (registry, clone, priv->cal_client) || @@ -636,7 +637,7 @@ if (priv->source_client && !e_source_equal (e_client_get_source (E_CLIENT (priv->cal_client)), e_client_get_source (E_CLIENT (priv->source_client))) && - cal_comp_is_on_server_sync (priv->comp, priv->source_client, NULL, NULL)) { + cal_comp_is_on_server (priv->comp, priv->source_client)) { /* Comp found a new home. Remove it from old one. */ GError *error = NULL; @@ -644,11 +645,11 @@ e_cal_component_has_recurrences (priv->comp)) e_cal_client_remove_object_sync ( priv->source_client, orig_uid_copy, - NULL, E_CAL_OBJ_MOD_ALL, NULL, &error); + NULL, CALOBJ_MOD_ALL, NULL, &error); else e_cal_client_remove_object_sync ( priv->source_client, - orig_uid_copy, NULL, E_CAL_OBJ_MOD_THIS, NULL, &error); + orig_uid_copy, NULL, CALOBJ_MOD_THIS, NULL, &error); if (error != NULL) { g_warning ( @@ -987,7 +988,7 @@ GTK_WINDOW (editor), delegated)) return; } else if (e_cal_component_is_instance (priv->comp)) - priv->mod = E_CAL_OBJ_MOD_THIS; + priv->mod = CALOBJ_MOD_THIS; comp = comp_editor_get_current_comp (editor, &correct); e_cal_component_get_summary (comp, &text); @@ -1027,7 +1028,7 @@ } else e_cal_client_remove_object_sync ( priv->cal_client, uid, NULL, - E_CAL_OBJ_MOD_THIS, NULL, &error); + CALOBJ_MOD_THIS, NULL, &error); g_clear_error (&error); } @@ -1086,8 +1087,8 @@ has_recurrences = e_cal_component_has_recurrences (comp); - if (has_recurrences && priv->mod == E_CAL_OBJ_MOD_ALL) - comp_util_sanitize_recurrence_master_sync (comp, priv->cal_client, NULL, NULL); + if (has_recurrences && priv->mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, priv->cal_client); comp_editor_edit_comp (editor, comp); } else { @@ -1295,14 +1296,14 @@ { "undo", "edit-undo", - N_("_Undo"), + N_("Undo"), "z", N_("Undo"), NULL }, /* Handled by EFocusTracker */ { "redo", "edit-redo", - N_("_Redo"), + N_("Redo"), "y", N_("Redo"), NULL }, /* Handled by EFocusTracker */ @@ -2102,7 +2103,7 @@ active_editors = g_list_prepend (active_editors, editor); - priv->calendar_settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + priv->calendar_settings = g_settings_new ("org.gnome.evolution.calendar"); /* Each editor window gets its own window group. */ window = GTK_WINDOW (editor); @@ -2112,7 +2113,7 @@ priv->pages = NULL; priv->changed = FALSE; priv->needs_send = FALSE; - priv->mod = E_CAL_OBJ_MOD_ALL; + priv->mod = CALOBJ_MOD_ALL; priv->existing_org = FALSE; priv->user_org = FALSE; priv->warned = FALSE; @@ -2161,7 +2162,7 @@ g_object_unref (emblemed_icon); save_action = gtk_action_group_get_action (action_group, "save"); - e_binding_bind_property ( + g_object_bind_property ( save_action, "sensitive", action, "sensitive", G_BINDING_SYNC_CREATE); @@ -2307,7 +2308,7 @@ action_group = comp_editor_get_action_group (editor, "individual"); action_group_2 = e_attachment_view_get_action_group (view, "editable"); - e_binding_bind_property ( + g_object_bind_property ( action_group, "sensitive", action_group_2, "sensitive", G_BINDING_SYNC_CREATE); @@ -3444,7 +3445,7 @@ registry = e_shell_get_registry (shell); - if (priv->mod == E_CAL_OBJ_MOD_ALL && e_cal_component_is_instance (priv->comp)) { + if (priv->mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (priv->comp)) { /* Ensure we send the master object, not the instance only */ icalcomponent *icalcomp = NULL; const gchar *uid = NULL; @@ -3484,10 +3485,10 @@ e_client_check_capability ( E_CLIENT (priv->cal_client), CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) { - if (itip_send_comp_sync ( + if (itip_send_comp ( registry, method, send_comp, priv->cal_client, NULL, NULL, users, strip_alarms, - priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY, NULL, NULL)) { + priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) { g_object_unref (send_comp); return TRUE; } @@ -3496,7 +3497,7 @@ GSList *attach_list = NULL; GSList *mime_attach_list, *attach; - /* mime_attach_list is freed by itip_send_comp_sync */ + /* mime_attach_list is freed by itip_send_comp */ mime_attach_list = comp_editor_get_mime_attach_list (editor); for (attach = mime_attach_list; attach; attach = attach->next) { @@ -3514,10 +3515,10 @@ g_slist_free (attach_list); } - if (itip_send_comp_sync ( + if (itip_send_comp ( registry, method, send_comp, priv->cal_client, NULL, mime_attach_list, users, strip_alarms, - priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY, NULL, NULL)) { + priv->flags & COMP_EDITOR_SEND_TO_NEW_ATTENDEES_ONLY)) { gboolean saved = save_comp (editor); g_object_unref (send_comp); @@ -3637,11 +3638,11 @@ e_cal_component_has_recurrences (priv->comp)) e_cal_client_remove_object_sync ( priv->cal_client, uid, NULL, - E_CAL_OBJ_MOD_ALL, NULL, NULL); + CALOBJ_MOD_ALL, NULL, NULL); else e_cal_client_remove_object_sync ( priv->cal_client, uid, NULL, - E_CAL_OBJ_MOD_THIS, NULL, NULL); + CALOBJ_MOD_THIS, NULL, NULL); close_dialog (editor); } diff -Nru evolution-3.16.0/calendar/gui/dialogs/copy-source-dialog.c evolution-3.12.11/calendar/gui/dialogs/copy-source-dialog.c --- evolution-3.16.0/calendar/gui/dialogs/copy-source-dialog.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/copy-source-dialog.c 2014-06-17 14:21:27.000000000 +0000 @@ -25,7 +25,7 @@ #include #endif -#include +#include #include "e-util/e-util.h" @@ -33,37 +33,31 @@ #include "select-source-dialog.h" typedef struct { - ECalModel *model; - ESource *from_source; - ESource *to_source; - ECalClient *to_client; - const gchar *extension_name; -} CopySourceData; - -static void -copy_source_data_free (gpointer ptr) -{ - CopySourceData *csd = ptr; - - if (csd) { - if (csd->to_client) - e_cal_model_emit_object_created (csd->model, csd->to_client); - - g_clear_object (&csd->model); - g_clear_object (&csd->from_source); - g_clear_object (&csd->to_source); - g_clear_object (&csd->to_client); - g_free (csd); - } + GtkWindow *parent; + ESource *orig_source; + ECalClientSourceType obj_type; + ESource *selected_source; + ECalClient *source_client, *dest_client; +} CopySourceDialogData; + +static void +show_error (CopySourceDialogData *csdd, + const gchar *msg, + const GError *error) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new ( + csdd->parent, 0, GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, error ? "%s\n%s" : "%s", msg, error ? error->message : ""); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); } struct ForeachTzidData { - ECalClient *from_client; - ECalClient *to_client; - gboolean success; - GCancellable *cancellable; - GError **error; + ECalClient *source_client; + ECalClient *dest_client; }; static void @@ -75,111 +69,169 @@ const gchar *tzid; g_return_if_fail (ftd != NULL); - g_return_if_fail (ftd->from_client != NULL); - g_return_if_fail (ftd->to_client != NULL); - - if (!ftd->success) - return; + g_return_if_fail (ftd->source_client != NULL); + g_return_if_fail (ftd->dest_client != NULL); tzid = icalparameter_get_tzid (param); if (!tzid || !*tzid) return; - if (g_cancellable_set_error_if_cancelled (ftd->cancellable, ftd->error)) { - ftd->success = FALSE; + e_cal_client_get_timezone_sync ( + ftd->source_client, tzid, &tz, NULL, NULL); + if (tz != NULL) + e_cal_client_add_timezone_sync ( + ftd->dest_client, tz, NULL, NULL); +} + +static void +free_copy_data (CopySourceDialogData *csdd) +{ + if (!csdd) return; - } - ftd->success = e_cal_client_get_timezone_sync (ftd->from_client, tzid, &tz, ftd->cancellable, ftd->error); - if (ftd->success && tz != NULL) - ftd->success = e_cal_client_add_timezone_sync (ftd->to_client, tz, ftd->cancellable, ftd->error); + if (csdd->orig_source) + g_object_unref (csdd->orig_source); + if (csdd->selected_source) + g_object_unref (csdd->selected_source); + if (csdd->source_client) + g_object_unref (csdd->source_client); + if (csdd->dest_client) + g_object_unref (csdd->dest_client); + g_free (csdd); } static void -copy_source_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) +dest_source_connected_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) { - CopySourceData *csd = user_data; + CopySourceDialogData *csdd = user_data; EClient *client; - ECalClient *from_client = NULL, *to_client = NULL; - GSList *objects = NULL, *link; - struct ForeachTzidData ftd; - gint n_objects, ii, last_percent = 0; - - if (!csd) - goto out; - - client = e_util_open_client_sync (job_data, e_cal_model_get_client_cache (csd->model), csd->extension_name, csd->from_source, 30, cancellable, error); - if (client) - from_client = E_CAL_CLIENT (client); - - if (!from_client) - goto out; - - client = e_util_open_client_sync (job_data, e_cal_model_get_client_cache (csd->model), csd->extension_name, csd->to_source, 30, cancellable, error); - if (client) - to_client = E_CAL_CLIENT (client); - - if (!to_client) - goto out; - - if (e_client_is_readonly (E_CLIENT (to_client))) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_READ_ONLY, _("Destination is read only")); - goto out; - } + GError *error = NULL; - if (!e_cal_client_get_object_list_sync (from_client, "#t", &objects, cancellable, error)) - goto out; + client = e_cal_client_connect_finish (result, &error); - ftd.from_client = from_client; - ftd.to_client = to_client; - ftd.success = TRUE; - ftd.cancellable = cancellable; - ftd.error = error; - - n_objects = g_slist_length (objects); - - for (link = objects, ii = 0; link && ftd.success && !g_cancellable_is_cancelled (cancellable); link = g_slist_next (link), ii++) { - icalcomponent *icalcomp = link->data; - icalcomponent *existing_icalcomp = NULL; - gint percent = 100 * (ii + 1) / n_objects; - GError *local_error = NULL; - - if (e_cal_client_get_object_sync (to_client, icalcomponent_get_uid (icalcomp), NULL, &existing_icalcomp, cancellable, &local_error) && - icalcomp != NULL) { - if (!e_cal_client_modify_object_sync (to_client, icalcomp, E_CAL_OBJ_MOD_ALL, cancellable, error)) - break; - - icalcomponent_free (existing_icalcomp); - } else if (local_error && !g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) { - g_propagate_error (error, local_error); - break; - } else { - icalcomponent_foreach_tzid (icalcomp, add_timezone_to_cal_cb, &ftd); + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + show_error (csdd, _("Could not open destination"), error); + g_error_free (error); + free_copy_data (csdd); + return; + } - g_clear_error (&local_error); + csdd->dest_client = E_CAL_CLIENT (client); - if (!ftd.success) - break; + /* check if the destination is read only */ + if (e_client_is_readonly (E_CLIENT (csdd->dest_client))) { + show_error (csdd, _("Destination is read only"), NULL); + } else { + GSList *obj_list = NULL; + + e_cal_client_get_object_list_sync ( + csdd->source_client, "#t", &obj_list, NULL, NULL); + if (obj_list != NULL) { + GSList *l; + icalcomponent *icalcomp; + struct ForeachTzidData ftd; + + ftd.source_client = csdd->source_client; + ftd.dest_client = csdd->dest_client; + + for (l = obj_list; l != NULL; l = l->next) { + icalcomp = NULL; + + /* FIXME: process recurrences */ + /* FIXME: process errors */ + if (e_cal_client_get_object_sync ( + csdd->dest_client, + icalcomponent_get_uid (l->data), + NULL, &icalcomp, NULL, NULL) && + icalcomp != NULL) { + e_cal_client_modify_object_sync ( + csdd->dest_client, l->data, + CALOBJ_MOD_ALL, NULL, NULL); + icalcomponent_free (icalcomp); + } else { + GError *error = NULL; + + icalcomp = l->data; + + /* Add timezone information from source + * ECal to the destination ECal. */ + icalcomponent_foreach_tzid ( + icalcomp, + add_timezone_to_cal_cb, &ftd); + + e_cal_client_create_object_sync ( + csdd->dest_client, + icalcomp, NULL, NULL, &error); + + if (error != NULL) { + show_error (csdd, _("Cannot create object"), error); + g_error_free (error); + break; + } + } + } - if (!e_cal_client_create_object_sync (to_client, icalcomp, NULL, cancellable, error)) - break; + e_cal_client_free_icalcomp_slist (obj_list); } + } - if (percent != last_percent) { - camel_operation_progress (cancellable, percent); - last_percent = percent; - } + free_copy_data (csdd); +} + +static void +orig_source_connected_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + CopySourceDialogData *csdd = user_data; + EClient *client; + GError *error = NULL; + + client = e_cal_client_connect_finish (result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + show_error (csdd, _("Could not open source"), error); + g_error_free (error); + free_copy_data (csdd); + return; } - if (ii > 0 && ftd.success) - csd->to_client = g_object_ref (to_client); - out: - e_cal_client_free_icalcomp_slist (objects); - g_clear_object (&from_client); - g_clear_object (&to_client); + csdd->source_client = E_CAL_CLIENT (client); + + e_cal_client_connect ( + csdd->selected_source, csdd->obj_type, NULL, + dest_source_connected_cb, csdd); +} + +static void +copy_source (const CopySourceDialogData *const_csdd) +{ + CopySourceDialogData *csdd; + + if (!const_csdd->selected_source) + return; + + csdd = g_new0 (CopySourceDialogData, 1); + csdd->parent = const_csdd->parent; + csdd->orig_source = g_object_ref (const_csdd->orig_source); + csdd->obj_type = const_csdd->obj_type; + csdd->selected_source = g_object_ref (const_csdd->selected_source); + + e_cal_client_connect ( + csdd->orig_source, csdd->obj_type, NULL, + orig_source_connected_cb, csdd); } /** @@ -190,67 +242,29 @@ */ void copy_source_dialog (GtkWindow *parent, - ECalModel *model, - ESource *from_source) + ESourceRegistry *registry, + ESource *source, + ECalClientSourceType obj_type) { - ECalClientSourceType obj_type; - ESource *to_source; - const gchar *extension_name; - const gchar *format; - const gchar *alert_ident; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_SOURCE (from_source)); - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - obj_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS; - extension_name = E_SOURCE_EXTENSION_CALENDAR; - format = _("Copying events to the calendar '%s'"); - alert_ident = "calendar:failed-copy-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - obj_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS; - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - format = _("Copying memos to the memo list '%s'"); - alert_ident = "calendar:failed-copy-memo"; - break; - case ICAL_VTODO_COMPONENT: - obj_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS; - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - format = _("Copying tasks to the task list '%s'"); - alert_ident = "calendar:failed-copy-task"; - break; - default: - g_warn_if_reached (); - return; - } + CopySourceDialogData csdd; - to_source = select_source_dialog (parent, e_cal_model_get_registry (model), obj_type, from_source); - if (to_source) { - CopySourceData *csd; - GCancellable *cancellable; - ECalDataModel *data_model; - const gchar *alert_arg_0; - gchar *description; - - csd = g_new0 (CopySourceData, 1); - csd->model = g_object_ref (model); - csd->from_source = g_object_ref (from_source); - csd->to_source = g_object_ref (to_source); - csd->to_client = NULL; - csd->extension_name = extension_name; - - alert_arg_0 = e_source_get_display_name (to_source); - description = g_strdup_printf (format, alert_arg_0); - data_model = e_cal_model_get_data_model (model); + g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); + g_return_if_fail (E_IS_SOURCE (source)); + g_return_if_fail (obj_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS || + obj_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS || + obj_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS); + + csdd.parent = parent; + csdd.orig_source = source; + csdd.selected_source = NULL; + csdd.obj_type = obj_type; + + csdd.selected_source = select_source_dialog ( + parent, registry, obj_type, source); + if (csdd.selected_source) { + copy_source (&csdd); - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, alert_arg_0, - copy_source_thread, csd, copy_source_data_free); - - g_clear_object (&cancellable); - g_free (description); + /* free memory */ + g_object_unref (csdd.selected_source); } - - g_clear_object (&to_source); } diff -Nru evolution-3.16.0/calendar/gui/dialogs/copy-source-dialog.h evolution-3.12.11/calendar/gui/dialogs/copy-source-dialog.h --- evolution-3.16.0/calendar/gui/dialogs/copy-source-dialog.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/copy-source-dialog.h 2014-03-24 09:25:23.000000000 +0000 @@ -27,10 +27,10 @@ #include #include -#include void copy_source_dialog (GtkWindow *parent, - ECalModel *model, - ESource *from_source); + ESourceRegistry *registry, + ESource *source, + ECalClientSourceType type); #endif /* COPY_SOURCE_DIALOG_H */ diff -Nru evolution-3.16.0/calendar/gui/dialogs/delete-error.c evolution-3.12.11/calendar/gui/dialogs/delete-error.c --- evolution-3.16.0/calendar/gui/dialogs/delete-error.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/delete-error.c 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,125 @@ +/* + * Evolution calendar - Send calendar component dialog + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include "delete-error.h" + +/** + * delete_error_dialog: + * + * Shows any applicable error messages as the result of deleting and object + * + **/ +void +delete_error_dialog (const GError *error, + ECalComponentVType vtype) +{ + GtkWidget *dialog; + const gchar *str; + const gchar *icon_name = NULL; + + if (!error || error->domain != E_CLIENT_ERROR) + return; + + switch (error->code) { + case E_CLIENT_ERROR_DBUS_ERROR: + switch (vtype) { + case E_CAL_COMPONENT_EVENT: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The event could not be deleted due to a dbus error: %s"); + break; + case E_CAL_COMPONENT_TODO: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The task could not be deleted due to a dbus error: %s"); + break; + case E_CAL_COMPONENT_JOURNAL: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The memo could not be deleted due to a dbus error: %s"); + break; + default: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The item could not be deleted due to a dbus error: %s"); + break; + } + break; + case E_CLIENT_ERROR_PERMISSION_DENIED: + switch (vtype) { + case E_CAL_COMPONENT_EVENT: + str = _("The event could not be deleted because permission was denied"); + break; + case E_CAL_COMPONENT_TODO: + str = _("The task could not be deleted because permission was denied"); + break; + case E_CAL_COMPONENT_JOURNAL: + str = _("The memo could not be deleted because permission was denied"); + break; + default: + str = _("The item could not be deleted because permission was denied"); + break; + } + break; + case E_CLIENT_ERROR_OTHER_ERROR: + switch (vtype) { + case E_CAL_COMPONENT_EVENT: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The event could not be deleted due to an error: %s"); + break; + case E_CAL_COMPONENT_TODO: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The task could not be deleted due to an error: %s"); + break; + case E_CAL_COMPONENT_JOURNAL: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The memo could not be deleted due to an error: %s"); + break; + default: + /* Translators: The '%s' is replaced with a detailed error message */ + str = _("The item could not be deleted due to an error: %s"); + break; + } + break; + default: + /* If not found, we don't care - its gone anyhow */ + return; + } + + dialog = gtk_message_dialog_new ( + NULL, GTK_DIALOG_MODAL, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, str, error->message); + if (vtype == E_CAL_COMPONENT_EVENT) + icon_name = "x-office-calendar"; + else if (vtype == E_CAL_COMPONENT_TODO) + icon_name = "stock_todo"; + + if (icon_name) + gtk_window_set_icon_name (GTK_WINDOW (dialog), icon_name); + + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} diff -Nru evolution-3.16.0/calendar/gui/dialogs/delete-error.h evolution-3.12.11/calendar/gui/dialogs/delete-error.h --- evolution-3.16.0/calendar/gui/dialogs/delete-error.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/delete-error.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,32 @@ +/* + * + * Evolution calendar - Send calendar component dialog + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * JP Rosevear + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef DELETE_ERROR_H +#define DELETE_ERROR_H + +#include + +void delete_error_dialog (const GError *error, ECalComponentVType vtype); + +#endif diff -Nru evolution-3.16.0/calendar/gui/dialogs/event-editor.c evolution-3.12.11/calendar/gui/dialogs/event-editor.c --- evolution-3.16.0/calendar/gui/dialogs/event-editor.c 2015-02-24 08:13:42.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/event-editor.c 2014-03-24 09:25:23.000000000 +0000 @@ -342,7 +342,7 @@ comp_editor_append_page (editor, page, _("Free/Busy"), TRUE); schedule_page_update_free_busy (priv->sched_page); - e_binding_bind_property ( + g_object_bind_property ( action_group, "visible", comp_editor_page_get_widget (page), "visible", G_BINDING_SYNC_CREATE); @@ -421,7 +421,7 @@ priv = EVENT_EDITOR_GET_PRIVATE (object); - e_binding_bind_property ( + g_object_bind_property ( object, "client", priv->model, "client", G_BINDING_SYNC_CREATE); @@ -734,9 +734,9 @@ gboolean result; client = e_meeting_store_get_client (priv->model); - result = itip_send_comp_sync ( + result = itip_send_comp ( registry, E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL, strip_alarms, FALSE, NULL, NULL); + client, NULL, NULL, NULL, strip_alarms, FALSE); g_object_unref (comp); if (!result) diff -Nru evolution-3.16.0/calendar/gui/dialogs/event-page.c evolution-3.12.11/calendar/gui/dialogs/event-page.c --- evolution-3.16.0/calendar/gui/dialogs/event-page.c 2014-08-28 07:26:03.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/event-page.c 2014-06-06 10:03:31.000000000 +0000 @@ -3488,7 +3488,7 @@ gtk_list_store_append (store, &iter); gtk_list_store_set ( store, &iter, - 0, _("Custom"), + 0, _("Customize"), -1); gtk_list_store_insert (store, &iter, 0); diff -Nru evolution-3.16.0/calendar/gui/dialogs/event-page.ui evolution-3.12.11/calendar/gui/dialogs/event-page.ui --- evolution-3.16.0/calendar/gui/dialogs/event-page.ui 2014-03-24 15:06:54.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/event-page.ui 2014-03-24 09:25:23.000000000 +0000 @@ -1036,6 +1036,29 @@ True False 0 + + + True + Custom Reminder: + False + False + GTK_JUSTIFY_LEFT + False + False + 0.5 + 0.5 + 0 + 0 + PANGO_ELLIPSIZE_NONE + False + 0 + + + 0 + False + False + +
0 diff -Nru evolution-3.16.0/calendar/gui/dialogs/goto-dialog.c evolution-3.12.11/calendar/gui/dialogs/goto-dialog.c --- evolution-3.16.0/calendar/gui/dialogs/goto-dialog.c 2014-11-13 07:24:17.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/goto-dialog.c 2014-03-24 09:25:23.000000000 +0000 @@ -46,15 +46,12 @@ ECalendar *ecal; GtkWidget *vbox; + GnomeCalendar *gcal; gint year_val; gint month_val; gint day_val; - ETagCalendar *tag_calendar; - - ECalDataModel *data_model; - ECalendarViewMoveType *out_move_type; - time_t *out_exact_date; + GCancellable *cancellable; } GoToDialog; static GoToDialog *dlg = NULL; @@ -89,6 +86,23 @@ dlg->ecal->calitem, dlg->year_val, dlg->month_val); } +static void +ecal_date_range_changed (ECalendarItem *calitem, + gpointer user_data) +{ + GoToDialog *dlg = user_data; + ECalModel *model; + ECalClient *client; + + model = gnome_calendar_get_model (dlg->gcal); + client = e_cal_model_ref_default_client (model); + + if (client != NULL) { + tag_calendar_by_client (dlg->ecal, client, dlg->cancellable); + g_object_unref (client); + } +} + /* Event handler for day groups in the month item. A button press makes * the calendar jump to the selected day and destroys the Go-to dialog box. */ static void @@ -97,12 +111,14 @@ { GoToDialog *dlg = user_data; GDate start_date, end_date; + ECalModel *model; struct icaltimetype tt = icaltime_null_time (); icaltimezone *timezone; time_t et; + model = gnome_calendar_get_model (dlg->gcal); e_calendar_item_get_selection (calitem, &start_date, &end_date); - timezone = e_cal_data_model_get_timezone (dlg->data_model); + timezone = e_cal_model_get_timezone (model); tt.year = g_date_get_year (&start_date); tt.month = g_date_get_month (&start_date); @@ -110,10 +126,9 @@ et = icaltime_as_timet_with_zone (tt, timezone); - *(dlg->out_move_type) = E_CALENDAR_VIEW_MOVE_TO_EXACT_DAY; - *(dlg->out_exact_date) = et; + gnome_calendar_goto (dlg->gcal, et); - gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_APPLY); + gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_NONE); } /* Returns the current time, for the ECalendarItem. */ @@ -149,8 +164,6 @@ ECalendarItem *calitem; dlg->ecal = E_CALENDAR (e_calendar_new ()); - dlg->tag_calendar = e_tag_calendar_new (dlg->ecal); - calitem = dlg->ecal->calitem; gnome_canvas_item_set ( @@ -166,6 +179,14 @@ calitem, get_current_time, dlg, NULL); + + ecal_date_range_changed (calitem, dlg); +} + +static void +goto_today (GoToDialog *dlg) +{ + gnome_calendar_goto_today (dlg->gcal); } /* Gets the widgets from the XML file and returns if they are all available. */ @@ -203,30 +224,28 @@ G_CALLBACK (year_changed), dlg); g_signal_connect ( + dlg->ecal->calitem, "date_range_changed", + G_CALLBACK (ecal_date_range_changed), dlg); + g_signal_connect ( dlg->ecal->calitem, "selection_changed", G_CALLBACK (ecal_event), dlg); } -/* Create a copy, thus a move to a distant date will not cause large event lookups */ - /* Creates a "goto date" dialog and runs it */ -gboolean -goto_dialog_run (GtkWindow *parent, - ECalDataModel *data_model, - const GDate *from_date, - ECalendarViewMoveType *out_move_type, - time_t *out_exact_date) +void +goto_dialog (GtkWindow *parent, + GnomeCalendar *gcal) { - gint response; + ECalModel *model; + time_t start_time; + struct icaltimetype tt; + icaltimezone *timezone; + gint b; if (dlg) { - return FALSE; + return; } - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - g_return_val_if_fail (out_move_type != NULL, FALSE); - g_return_val_if_fail (out_exact_date != NULL, FALSE); - dlg = g_new0 (GoToDialog, 1); /* Load the content widgets */ @@ -234,31 +253,20 @@ e_load_ui_builder_definition (dlg->builder, "goto-dialog.ui"); if (!get_widgets (dlg)) { - g_message ("goto_dialog_run(): Could not find all widgets in the XML file!"); + g_message ("goto_dialog(): Could not find all widgets in the XML file!"); g_free (dlg); - dlg = NULL; - return FALSE; + return; } + dlg->gcal = gcal; + dlg->cancellable = g_cancellable_new (); - dlg->data_model = e_cal_data_model_new_clone (data_model); - dlg->out_move_type = out_move_type; - dlg->out_exact_date = out_exact_date; - - if (from_date) { - dlg->year_val = g_date_get_year (from_date); - dlg->month_val = g_date_get_month (from_date) - 1; - dlg->day_val = g_date_get_day (from_date); - } else { - struct icaltimetype tt; - icaltimezone *timezone; - - timezone = e_cal_data_model_get_timezone (dlg->data_model); - tt = icaltime_current_time_with_zone (timezone); - - dlg->year_val = tt.year; - dlg->month_val = tt.month - 1; - dlg->day_val = tt.day; - } + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + e_cal_model_get_time_range (model, &start_time, NULL); + tt = icaltime_from_timet_with_zone (start_time, FALSE, timezone); + dlg->year_val = tt.year; + dlg->month_val = tt.month - 1; + dlg->day_val = tt.day; gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->month_combobox), dlg->month_val); gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->year), dlg->year_val); @@ -273,29 +281,21 @@ dlg->ecal->calitem->selection_set = TRUE; dlg->ecal->calitem->selection_start_month_offset = 0; - dlg->ecal->calitem->selection_start_day = dlg->day_val; + dlg->ecal->calitem->selection_start_day = tt.day; dlg->ecal->calitem->selection_end_month_offset = 0; - dlg->ecal->calitem->selection_end_day = dlg->day_val; + dlg->ecal->calitem->selection_end_day = tt.day; gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (dlg->ecal->calitem)); - e_tag_calendar_subscribe (dlg->tag_calendar, dlg->data_model); - - response = gtk_dialog_run (GTK_DIALOG (dlg->dialog)); - - e_tag_calendar_unsubscribe (dlg->tag_calendar, dlg->data_model); - + b = gtk_dialog_run (GTK_DIALOG (dlg->dialog)); gtk_widget_destroy (dlg->dialog); - if (response == GTK_RESPONSE_ACCEPT) - *(dlg->out_move_type) = E_CALENDAR_VIEW_MOVE_TO_TODAY; + if (b == 0) + goto_today (dlg); g_object_unref (dlg->builder); - g_clear_object (&dlg->tag_calendar); - g_clear_object (&dlg->data_model); - + g_cancellable_cancel (dlg->cancellable); + g_object_unref (dlg->cancellable); g_free (dlg); dlg = NULL; - - return response == GTK_RESPONSE_ACCEPT || response == GTK_RESPONSE_APPLY; } diff -Nru evolution-3.16.0/calendar/gui/dialogs/goto-dialog.h evolution-3.12.11/calendar/gui/dialogs/goto-dialog.h --- evolution-3.16.0/calendar/gui/dialogs/goto-dialog.h 2014-11-13 07:24:17.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/goto-dialog.h 2014-03-24 09:25:23.000000000 +0000 @@ -26,13 +26,8 @@ #ifndef GOTO_DIALOG_H #define GOTO_DIALOG_H -#include "calendar/gui/e-cal-data-model.h" -#include "calendar/gui/e-calendar-view.h" +#include "calendar/gui/gnome-cal.h" -gboolean goto_dialog_run (GtkWindow *parent, - ECalDataModel *data_model, - const GDate *from_date, - ECalendarViewMoveType *out_move_type, - time_t *out_exact_date); +void goto_dialog (GtkWindow *parent, GnomeCalendar *gcal); #endif diff -Nru evolution-3.16.0/calendar/gui/dialogs/goto-dialog.ui evolution-3.12.11/calendar/gui/dialogs/goto-dialog.ui --- evolution-3.16.0/calendar/gui/dialogs/goto-dialog.ui 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/goto-dialog.ui 2014-03-24 09:25:23.000000000 +0000 @@ -174,7 +174,7 @@
- button4 + button4 button5
diff -Nru evolution-3.16.0/calendar/gui/dialogs/Makefile.am evolution-3.12.11/calendar/gui/dialogs/Makefile.am --- evolution-3.16.0/calendar/gui/dialogs/Makefile.am 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -1,21 +1,20 @@ noinst_LTLIBRARIES = libcal-dialogs.la -libcal_dialogs_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DG_LOG_DOMAIN=\"calendar-gui\" \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -DEVOLUTION_UIDIR=\""$(uidir)"\" \ - -DEVOLUTION_ICONDIR=\""$(icondir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DPREFIX=\""$(prefix)"\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) +libcal_dialogs_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -DG_LOG_DOMAIN=\"calendar-gui\" \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + -I$(top_srcdir)/calendar \ + -I$(top_builddir)/shell \ + -I$(top_srcdir)/shell \ + -DEVOLUTION_UIDIR=\""$(uidir)"\" \ + -DEVOLUTION_ICONDIR=\""$(icondir)"\" \ + -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) ecalendarincludedir = $(privincludedir)/calendar/gui/dialogs @@ -29,6 +28,7 @@ comp-editor-util.h \ copy-source-dialog.h \ delete-comp.h \ + delete-error.h \ e-delegate-dialog.h \ e-send-options-utils.h \ event-editor.h \ @@ -45,13 +45,11 @@ task-editor.h \ task-page.h -libcal_dialogs_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) - libcal_dialogs_la_LIBADD = \ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) libcal_dialogs_la_SOURCES = \ alarm-dialog.c \ @@ -72,6 +70,8 @@ copy-source-dialog.h \ delete-comp.c \ delete-comp.h \ + delete-error.c \ + delete-error.h \ e-delegate-dialog.c \ e-delegate-dialog.h \ e-send-options-utils.c \ diff -Nru evolution-3.16.0/calendar/gui/dialogs/Makefile.in evolution-3.12.11/calendar/gui/dialogs/Makefile.in --- evolution-3.16.0/calendar/gui/dialogs/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/Makefile.in 2015-02-09 08:21:54.000000000 +0000 @@ -86,7 +86,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -105,7 +104,8 @@ am__DEPENDENCIES_1 = libcal_dialogs_la_DEPENDENCIES = \ $(top_builddir)/addressbook/util/libeabutil.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libcal_dialogs_la_OBJECTS = libcal_dialogs_la-alarm-dialog.lo \ libcal_dialogs_la-alarm-list-dialog.lo \ libcal_dialogs_la-cancel-comp.lo \ @@ -115,6 +115,7 @@ libcal_dialogs_la-comp-editor-util.lo \ libcal_dialogs_la-copy-source-dialog.lo \ libcal_dialogs_la-delete-comp.lo \ + libcal_dialogs_la-delete-error.lo \ libcal_dialogs_la-e-delegate-dialog.lo \ libcal_dialogs_la-e-send-options-utils.lo \ libcal_dialogs_la-event-editor.lo \ @@ -134,10 +135,6 @@ am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libcal_dialogs_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \ - $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \ - $(AM_CFLAGS) $(CFLAGS) $(libcal_dialogs_la_LDFLAGS) $(LDFLAGS) \ - -o $@ AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -239,14 +236,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -259,9 +253,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -275,8 +266,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -287,7 +276,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -314,6 +302,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -337,13 +329,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -481,21 +470,20 @@ viewsdir = @viewsdir@ noinst_LTLIBRARIES = libcal-dialogs.la libcal_dialogs_la_CPPFLAGS = \ - $(AM_CPPFLAGS) \ - -DG_LOG_DOMAIN=\"calendar-gui\" \ - -I$(top_srcdir) \ - -I$(top_builddir) \ - -I$(top_srcdir)/calendar \ - -I$(top_builddir)/shell \ - -I$(top_srcdir)/shell \ - -DEVOLUTION_UIDIR=\""$(uidir)"\" \ - -DEVOLUTION_ICONDIR=\""$(icondir)"\" \ - -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ - -DPREFIX=\""$(prefix)"\" \ - $(EVOLUTION_DATA_SERVER_CFLAGS) \ - $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(AM_CPPFLAGS) \ + -DG_LOG_DOMAIN=\"calendar-gui\" \ + -I$(top_srcdir) \ + -I$(top_builddir) \ + -I$(top_srcdir)/calendar \ + -I$(top_builddir)/shell \ + -I$(top_srcdir)/shell \ + -DEVOLUTION_UIDIR=\""$(uidir)"\" \ + -DEVOLUTION_ICONDIR=\""$(icondir)"\" \ + -DEVOLUTION_IMAGESDIR=\""$(imagesdir)"\" \ + -DPREFIX=\""$(prefix)"\" \ + $(EVOLUTION_DATA_SERVER_CFLAGS) \ + $(GNOME_PLATFORM_CFLAGS) \ + $(GTKHTML_CFLAGS) ecalendarincludedir = $(privincludedir)/calendar/gui/dialogs ecalendarinclude_HEADERS = \ @@ -508,6 +496,7 @@ comp-editor-util.h \ copy-source-dialog.h \ delete-comp.h \ + delete-error.h \ e-delegate-dialog.h \ e-send-options-utils.h \ event-editor.h \ @@ -524,12 +513,11 @@ task-editor.h \ task-page.h -libcal_dialogs_la_LDFLAGS = $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) libcal_dialogs_la_LIBADD = \ $(top_builddir)/addressbook/util/libeabutil.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) libcal_dialogs_la_SOURCES = \ alarm-dialog.c \ @@ -550,6 +538,8 @@ copy-source-dialog.h \ delete-comp.c \ delete-comp.h \ + delete-error.c \ + delete-error.h \ e-delegate-dialog.c \ e-delegate-dialog.h \ e-send-options-utils.c \ @@ -643,7 +633,7 @@ } libcal-dialogs.la: $(libcal_dialogs_la_OBJECTS) $(libcal_dialogs_la_DEPENDENCIES) $(EXTRA_libcal_dialogs_la_DEPENDENCIES) - $(AM_V_CCLD)$(libcal_dialogs_la_LINK) $(libcal_dialogs_la_OBJECTS) $(libcal_dialogs_la_LIBADD) $(LIBS) + $(AM_V_CCLD)$(LINK) $(libcal_dialogs_la_OBJECTS) $(libcal_dialogs_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -660,6 +650,7 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-comp-editor.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-copy-source-dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-delete-comp.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-delete-error.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-e-delegate-dialog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-e-send-options-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-event-editor.Plo@am__quote@ @@ -677,25 +668,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcal_dialogs_la-task-page.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @@ -763,6 +751,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcal_dialogs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcal_dialogs_la-delete-comp.lo `test -f 'delete-comp.c' || echo '$(srcdir)/'`delete-comp.c +libcal_dialogs_la-delete-error.lo: delete-error.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcal_dialogs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcal_dialogs_la-delete-error.lo -MD -MP -MF $(DEPDIR)/libcal_dialogs_la-delete-error.Tpo -c -o libcal_dialogs_la-delete-error.lo `test -f 'delete-error.c' || echo '$(srcdir)/'`delete-error.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcal_dialogs_la-delete-error.Tpo $(DEPDIR)/libcal_dialogs_la-delete-error.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='delete-error.c' object='libcal_dialogs_la-delete-error.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcal_dialogs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libcal_dialogs_la-delete-error.lo `test -f 'delete-error.c' || echo '$(srcdir)/'`delete-error.c + libcal_dialogs_la-e-delegate-dialog.lo: e-delegate-dialog.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcal_dialogs_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libcal_dialogs_la-e-delegate-dialog.lo -MD -MP -MF $(DEPDIR)/libcal_dialogs_la-e-delegate-dialog.Tpo -c -o libcal_dialogs_la-e-delegate-dialog.lo `test -f 'e-delegate-dialog.c' || echo '$(srcdir)/'`e-delegate-dialog.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcal_dialogs_la-e-delegate-dialog.Tpo $(DEPDIR)/libcal_dialogs_la-e-delegate-dialog.Plo diff -Nru evolution-3.16.0/calendar/gui/dialogs/recur-comp.c evolution-3.12.11/calendar/gui/dialogs/recur-comp.c --- evolution-3.16.0/calendar/gui/dialogs/recur-comp.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/recur-comp.c 2014-03-24 09:25:23.000000000 +0000 @@ -31,7 +31,7 @@ gboolean recur_component_dialog (ECalClient *client, ECalComponent *comp, - ECalObjModType *mod, + CalObjModType *mod, GtkWindow *parent, gboolean delegated) { @@ -112,46 +112,17 @@ ret = gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK; if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_this))) - *mod = E_CAL_OBJ_MOD_THIS; + *mod = CALOBJ_MOD_THIS; else if (rb_prior && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_prior))) - *mod = E_CAL_OBJ_MOD_THIS_AND_PRIOR; + *mod = CALOBJ_MOD_THISANDPRIOR; else if (rb_future && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_future))) - *mod = E_CAL_OBJ_MOD_THIS_AND_FUTURE; + *mod = CALOBJ_MOD_THISANDFUTURE; else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (rb_all))) { - *mod = E_CAL_OBJ_MOD_ALL; + *mod = CALOBJ_MOD_ALL; + } gtk_widget_destroy (dialog); return ret; } - -gboolean -recur_icalcomp_dialog (ECalClient *client, - icalcomponent *icalcomp, - ECalObjModType *mod, - GtkWindow *parent, - gboolean delegated) -{ - ECalComponent *comp; - gboolean res; - - g_return_val_if_fail (icalcomp != NULL, FALSE); - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icalcomp)); - if (!comp) - return FALSE; - - if (!e_cal_component_is_instance (comp)) { - *mod = E_CAL_OBJ_MOD_ALL; - g_object_unref (comp); - - return TRUE; - } - - res = recur_component_dialog (client, comp, mod, parent, delegated); - - g_object_unref (comp); - - return res; -} diff -Nru evolution-3.16.0/calendar/gui/dialogs/recur-comp.h evolution-3.12.11/calendar/gui/dialogs/recur-comp.h --- evolution-3.16.0/calendar/gui/dialogs/recur-comp.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/recur-comp.h 2014-03-24 09:25:23.000000000 +0000 @@ -29,13 +29,7 @@ gboolean recur_component_dialog (ECalClient *client, ECalComponent *comp, - ECalObjModType *mod, - GtkWindow *parent, - gboolean delegated); - -gboolean recur_icalcomp_dialog (ECalClient *client, - icalcomponent *icalcomp, - ECalObjModType *mod, + CalObjModType *mod, GtkWindow *parent, gboolean delegated); diff -Nru evolution-3.16.0/calendar/gui/dialogs/recurrence-page.c evolution-3.12.11/calendar/gui/dialogs/recurrence-page.c --- evolution-3.16.0/calendar/gui/dialogs/recurrence-page.c 2015-02-24 08:13:51.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/recurrence-page.c 2014-06-04 18:27:43.000000000 +0000 @@ -2567,7 +2567,7 @@ GTK_TREE_VIEW (priv->exception_list), GTK_TREE_MODEL (priv->exception_list_store)); - e_binding_bind_property ( + g_object_bind_property ( editor, "use-24-hour-format", priv->exception_list_store, "use-24-hour-format", G_BINDING_SYNC_CREATE); diff -Nru evolution-3.16.0/calendar/gui/dialogs/task-editor.c evolution-3.12.11/calendar/gui/dialogs/task-editor.c --- evolution-3.16.0/calendar/gui/dialogs/task-editor.c 2015-02-24 08:13:59.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/task-editor.c 2014-03-24 09:25:23.000000000 +0000 @@ -162,7 +162,7 @@ comp_editor_set_group_item (editor, TRUE); } - e_binding_bind_property ( + g_object_bind_property ( object, "client", priv->model, "client", G_BINDING_SYNC_CREATE); @@ -403,9 +403,9 @@ gboolean result; client = e_meeting_store_get_client (priv->model); - result = itip_send_comp_sync ( + result = itip_send_comp ( registry, E_CAL_COMPONENT_METHOD_CANCEL, comp, - client, NULL, NULL, NULL, strip_alarms, FALSE, NULL, NULL); + client, NULL, NULL, NULL, strip_alarms, FALSE); g_object_unref (comp); if (!result) diff -Nru evolution-3.16.0/calendar/gui/dialogs/task-page.c evolution-3.12.11/calendar/gui/dialogs/task-page.c --- evolution-3.16.0/calendar/gui/dialogs/task-page.c 2015-02-24 08:14:05.000000000 +0000 +++ evolution-3.12.11/calendar/gui/dialogs/task-page.c 2014-06-06 10:03:31.000000000 +0000 @@ -528,7 +528,6 @@ g_strfreev (priv->address_strings); g_free (priv->fallback_address); - g_free (priv->user_add); g_ptr_array_foreach ( priv->deleted_attendees, (GFunc) g_object_unref, NULL); @@ -746,7 +745,6 @@ gchar *name = NULL; gchar *mailto = NULL; - g_free (priv->user_add); priv->user_add = itip_get_comp_attendee ( registry, comp, client); @@ -2594,7 +2592,7 @@ /* Classification */ action = comp_editor_get_action (editor, "classify-public"); - e_binding_bind_property_full ( + g_object_bind_property_full ( action, "current-value", priv->classification_combo, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE, diff -Nru evolution-3.16.0/calendar/gui/ea-calendar.c evolution-3.12.11/calendar/gui/ea-calendar.c --- evolution-3.16.0/calendar/gui/ea-calendar.c 2015-01-05 13:56:08.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-calendar.c 2014-03-24 09:25:23.000000000 +0000 @@ -34,6 +34,7 @@ #include "calendar/gui/ea-day-view-main-item.h" #include "calendar/gui/ea-week-view.h" #include "calendar/gui/ea-week-view-main-item.h" +#include "calendar/gui/ea-gnome-calendar.h" EA_FACTORY_GOBJECT ( EA_TYPE_DAY_VIEW_MAIN_ITEM, @@ -41,6 +42,7 @@ EA_FACTORY_GOBJECT ( EA_TYPE_WEEK_VIEW_MAIN_ITEM, ea_week_view_main_item, ea_week_view_main_item_new) +EA_FACTORY (EA_TYPE_GNOME_CALENDAR, ea_gnome_calendar, ea_gnome_calendar_new) static gboolean ea_calendar_focus_watcher (GSignalInvocationHint *ihint, guint n_param_values, @@ -51,7 +53,7 @@ static gpointer e_day_view_main_item_type, e_week_view_main_item_type; void -e_calendar_a11y_init (void) +gnome_calendar_a11y_init (void) { /* we only add focus watcher when accessibility is enabled */ @@ -62,6 +64,8 @@ gnome_canvas = gnome_canvas_new (); gtk_widget_destroy (gnome_canvas); + EA_SET_FACTORY (gnome_calendar_get_type (), ea_gnome_calendar); + /* force loading some types */ e_text_type = g_type_class_ref (E_TYPE_TEXT); pixbuf_type = g_type_class_ref (GNOME_TYPE_CANVAS_PIXBUF); @@ -131,12 +135,15 @@ canvas_item = GNOME_CANVAS_ITEM (object); if (event->type == GDK_FOCUS_CHANGE) { - ea_event = - ea_calendar_helpers_get_accessible_for (canvas_item); - if (!ea_event) - /* not canvas item we want */ - return TRUE; - atk_object_notify_state_change (ea_event, ATK_STATE_FOCUSED, event->focus_change.in); + if (event->focus_change.in) { + ea_event = + ea_calendar_helpers_get_accessible_for (canvas_item); + if (!ea_event) + /* not canvas item we want */ + return TRUE; + + } + atk_focus_tracker_notify (ea_event); } } else if (E_IS_DAY_VIEW (object)) { @@ -150,12 +157,17 @@ } else if (E_IS_DAY_VIEW_MAIN_ITEM (object)) { if (event->type == GDK_FOCUS_CHANGE) { - /* we should emit focus on main item */ - ea_event = atk_gobject_accessible_for_object (object); + if (event->focus_change.in) { + /* we should emit focus on main item */ + ea_event = atk_gobject_accessible_for_object (object); + } + else + /* focus out */ + ea_event = NULL; #ifdef ACC_DEBUG printf ("EvoAcc: focus notify on day main item %p\n", (gpointer) object); #endif - atk_object_notify_state_change (ea_event, ATK_STATE_FOCUSED, event->focus_change.in); + atk_focus_tracker_notify (ea_event); } } else if (E_IS_WEEK_VIEW (object)) { EWeekView *week_view = E_WEEK_VIEW (object); @@ -168,9 +180,14 @@ } else if (E_IS_WEEK_VIEW_MAIN_ITEM (object)) { if (event->type == GDK_FOCUS_CHANGE) { - /* we should emit focus on main item */ - ea_event = atk_gobject_accessible_for_object (object); - atk_object_notify_state_change (ea_event, ATK_STATE_FOCUSED, event->focus_change.in); + if (event->focus_change.in) { + /* we should emit focus on main item */ + ea_event = atk_gobject_accessible_for_object (object); + } + else + /* focus out */ + ea_event = NULL; + atk_focus_tracker_notify (ea_event); } } return TRUE; diff -Nru evolution-3.16.0/calendar/gui/ea-calendar.h evolution-3.12.11/calendar/gui/ea-calendar.h --- evolution-3.16.0/calendar/gui/ea-calendar.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-calendar.h 2014-03-24 09:25:23.000000000 +0000 @@ -26,7 +26,7 @@ #ifndef _EA_CALENDAR_H__ #define _EA_CALENDAR_H__ -void e_calendar_a11y_init (void); +void gnome_calendar_a11y_init (void); void e_day_view_main_item_a11y_init (void); void e_week_view_main_item_a11y_init (void); diff -Nru evolution-3.16.0/calendar/gui/ea-cal-view.c evolution-3.12.11/calendar/gui/ea-cal-view.c --- evolution-3.16.0/calendar/gui/ea-cal-view.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-cal-view.c 2014-03-24 09:25:23.000000000 +0000 @@ -27,7 +27,6 @@ #include "ea-calendar-helpers.h" #include "e-day-view.h" #include "e-week-view.h" -#include "e-cal-ops.h" #include "dialogs/goto-dialog.h" #include @@ -42,7 +41,7 @@ gpointer data); static gboolean idle_dates_changed (gpointer data); -static void ea_cal_model_time_range_changed_cb (ECalModel *model, time_t start, time_t end, gpointer data); +static void ea_cal_view_dates_change_cb (GnomeCalendar *gcal, gpointer data); static void atk_action_interface_init (AtkActionIface *iface); static gboolean action_interface_do_action (AtkAction *action, gint i); @@ -103,7 +102,7 @@ gpointer data) { ECalendarView *cal_view; - ECalModel *model; + GnomeCalendar *gcal; static AtkRole role = ATK_ROLE_INVALID; g_return_if_fail (EA_IS_CAL_VIEW (accessible)); @@ -127,13 +126,13 @@ cal_view, "event_added", G_CALLBACK (ea_cal_view_event_added_cb), NULL); - /* listen for date changes */ - model = e_calendar_view_get_model (cal_view); + /* listen for date changes of calendar */ + gcal = e_calendar_view_get_calendar (cal_view); - if (model) - g_signal_connect_after ( - model, "time-range-changed", - G_CALLBACK (ea_cal_model_time_range_changed_cb), accessible); + if (gcal) + g_signal_connect ( + gcal, "dates_shown_changed", + G_CALLBACK (ea_cal_view_dates_change_cb), accessible); } static AtkObject * @@ -268,10 +267,8 @@ } static void -ea_cal_model_time_range_changed_cb (ECalModel *model, - time_t start, - time_t end, - gpointer data) +ea_cal_view_dates_change_cb (GnomeCalendar *gcal, + gpointer data) { g_idle_add (idle_dates_changed, data); } @@ -320,25 +317,35 @@ return FALSE; cal_view = E_CALENDAR_VIEW (widget); - switch (index) { - case 0: - /* New Appointment */ - e_calendar_view_new_appointment (cal_view); - break; - case 1: - /* New All Day Event */ - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_cal_ops_new_component_editor_from_model ( - e_calendar_view_get_model (cal_view), NULL, - dtstart, dtend, FALSE, TRUE); - break; - case 2: - /* New Meeting */ - e_calendar_view_get_selected_time_range (cal_view, &dtstart, &dtend); - e_cal_ops_new_component_editor_from_model ( - e_calendar_view_get_model (cal_view), NULL, - dtstart, dtend, TRUE, FALSE); - break; + switch (index) { + case 0: + /* New Appointment */ + e_calendar_view_new_appointment (cal_view); + break; + case 1: + /* New All Day Event */ + e_calendar_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_calendar_view_new_appointment_for (cal_view, + dtstart, dtend, TRUE, FALSE); + break; + case 2: + /* New Meeting */ + e_calendar_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_calendar_view_new_appointment_for (cal_view, + dtstart, dtend, FALSE, TRUE); + break; +#if 0 /* FIXME Have to go through GnomeCalendar */ + case 3: + /* Go to today */ + break; + calendar_goto_today (e_calendar_view_get_calendar (cal_view)); + case 4: + /* Go to date */ + goto_dialog (e_calendar_view_get_calendar (cal_view)); + break; +#endif default: return_value = FALSE; break; diff -Nru evolution-3.16.0/calendar/gui/ea-day-view.c evolution-3.12.11/calendar/gui/ea-day-view.c --- evolution-3.16.0/calendar/gui/ea-day-view.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-day-view.c 2014-03-24 09:25:23.000000000 +0000 @@ -27,6 +27,7 @@ #include "ea-cal-view-event.h" #include "ea-calendar-helpers.h" +#include "ea-gnome-calendar.h" #include static const gchar * ea_day_view_get_name (AtkObject *accessible); @@ -81,7 +82,9 @@ ea_day_view_get_name (AtkObject *accessible) { EDayView *day_view; - gchar *label_text; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; GtkWidget *widget; gint n_events; gchar *event_str, *name_str; @@ -93,8 +96,9 @@ return NULL; day_view = E_DAY_VIEW (widget); + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); - label_text = e_calendar_view_get_description_text (E_CALENDAR_VIEW (day_view)); + label_text = ea_gnome_calendar_get_label_description (gcal); n_events = atk_object_get_n_accessible_children (accessible); /* the child main item is always there */ @@ -113,7 +117,8 @@ 10th - July 14th, 2006." or "Day View: Thursday July 13th, 2006." */ event_str = g_strdup (_("It has no events.")); - if (e_day_view_get_work_week_view (day_view)) + view_type = gnome_calendar_get_view (gcal); + if (view_type == GNOME_CAL_WORK_WEEK_VIEW) /* To translators: First %s is the week, for example "July 10th - July 14th, 2006". Second %s is the number of events in this work week, for example "It has %d event/events." or "It has no events." */ @@ -131,7 +136,6 @@ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); g_free (name_str); g_free (event_str); - g_free (label_text); return accessible->name; } @@ -153,7 +157,13 @@ if (accessible->description) return accessible->description; else { - if (e_day_view_get_work_week_view (day_view)) + GnomeCalendar *gcal; + GnomeCalendarViewType view_type; + + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_WORK_WEEK_VIEW) return _("calendar view for a work week"); else return _("calendar view for one or more days"); diff -Nru evolution-3.16.0/calendar/gui/ea-day-view-main-item.c evolution-3.12.11/calendar/gui/ea-day-view-main-item.c --- evolution-3.16.0/calendar/gui/ea-day-view-main-item.c 2015-01-05 13:56:08.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-day-view-main-item.c 2014-10-07 05:37:46.000000000 +0000 @@ -46,7 +46,7 @@ static gint ea_day_view_main_item_get_index_in_parent (AtkObject *accessible); /* callbacks */ -static void ea_day_view_main_item_time_range_changed_cb (ECalModel *model, time_t start, time_t end, gpointer data); +static void ea_day_view_main_item_dates_change_cb (GnomeCalendar *gcal, gpointer data); static void ea_day_view_main_item_time_change_cb (EDayView *day_view, gpointer data); /* component interface */ @@ -187,7 +187,7 @@ ea_day_view_main_item_new (GObject *obj) { AtkObject *accessible; - ECalModel *model; + GnomeCalendar *gcal; EDayViewMainItem *main_item; EDayView *day_view; @@ -216,11 +216,11 @@ accessible); /* listen for date changes of calendar */ - model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); - if (model) - g_signal_connect_after ( - model, "time-range-changed", - G_CALLBACK (ea_day_view_main_item_time_range_changed_cb), + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); + if (gcal) + g_signal_connect ( + gcal, "dates_shown_changed", + G_CALLBACK (ea_day_view_main_item_dates_change_cb), accessible); return accessible; @@ -373,14 +373,12 @@ /* callbacks */ static void -ea_day_view_main_item_time_range_changed_cb (ECalModel *model, - time_t start, - time_t end, - gpointer data) +ea_day_view_main_item_dates_change_cb (GnomeCalendar *gcal, + gpointer data) { EaDayViewMainItem *ea_main_item; - g_return_if_fail (E_IS_CAL_MODEL (model)); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); g_return_if_fail (data); g_return_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (data)); @@ -424,6 +422,7 @@ item_cell); g_signal_emit_by_name (data, "selection_changed"); + atk_focus_tracker_notify (item_cell); g_object_unref (item_cell); } @@ -768,9 +767,8 @@ ATK_OBJECT (ea_main_item), index); if (child) - atk_component_get_extents ( - ATK_COMPONENT (child), NULL, NULL, &width, &height, - ATK_XY_SCREEN); + atk_component_get_size ( + ATK_COMPONENT (child), &width, &height); return width; } @@ -792,9 +790,8 @@ ATK_OBJECT (ea_main_item), index); if (child) - atk_component_get_extents ( - ATK_COMPONENT (child), NULL, NULL, &width, &height, - ATK_XY_SCREEN); + atk_component_get_size ( + ATK_COMPONENT (child), &width, &height); return height; } diff -Nru evolution-3.16.0/calendar/gui/ea-gnome-calendar.c evolution-3.12.11/calendar/gui/ea-gnome-calendar.c --- evolution-3.16.0/calendar/gui/ea-gnome-calendar.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-gnome-calendar.c 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,344 @@ +/* + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "ea-gnome-calendar.h" +#include "e-calendar-view.h" +#include +#include +#include + +static void ea_gnome_calendar_class_init (EaGnomeCalendarClass *klass); + +static gint ea_gnome_calendar_get_n_children (AtkObject * obj); +static AtkObject * ea_gnome_calendar_ref_child (AtkObject *obj, gint i); + +static void ea_gcal_dates_change_cb (GnomeCalendar *gcal, gpointer data); + +static gpointer parent_class = NULL; + +static const gchar * +ea_gnome_calendar_get_name (AtkObject *accessible) +{ + if (accessible->name) + return accessible->name; + return _("Gnome Calendar"); +} + +static const gchar * +ea_gnome_calendar_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + return _("Gnome Calendar"); +} + +GType +ea_gnome_calendar_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaGnomeCalendarClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_gnome_calendar_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaGnomeCalendar), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (GailWidget, in this case) + */ + + factory = atk_registry_get_factory ( + atk_get_default_registry (), + GTK_TYPE_WIDGET); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + g_type_query (derived_atk_type, &query); + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + + type = g_type_register_static ( + derived_atk_type, + "EaGnomeCalendar", &tinfo, 0); + + } + + return type; +} + +static void +ea_gnome_calendar_class_init (EaGnomeCalendarClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_gnome_calendar_get_name; + class->get_description = ea_gnome_calendar_get_description; + + class->get_n_children = ea_gnome_calendar_get_n_children; + class->ref_child = ea_gnome_calendar_ref_child; +} + +AtkObject * +ea_gnome_calendar_new (GtkWidget *widget) +{ + GObject *object; + AtkObject *accessible; + + g_return_val_if_fail (GNOME_IS_CALENDAR (widget), NULL); + + object = g_object_new (EA_TYPE_GNOME_CALENDAR, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, widget); + + accessible->role = ATK_ROLE_FILLER; + + /* listen on view type change + */ + g_signal_connect ( + widget, "dates_shown_changed", + G_CALLBACK (ea_gcal_dates_change_cb), accessible); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea-gnome-calendar created: %p\n", (gpointer) accessible); +#endif + + return accessible; +} + +const gchar * +ea_gnome_calendar_get_label_description (GnomeCalendar *gcal) +{ + GnomeCalendarViewType view_type; + ECalendarView *calendar_view; + ECalModel *model; + icaltimezone *zone; + struct icaltimetype start_tt, end_tt; + time_t start_time, end_time; + struct tm start_tm, end_tm; + static gchar buffer[512]; + gchar end_buffer[256]; + GnomeCalendarViewType view; + + model = gnome_calendar_get_model (gcal); + zone = e_cal_model_get_timezone (model); + + view_type = gnome_calendar_get_view (gcal); + calendar_view = gnome_calendar_get_calendar_view (gcal, view_type); + + if (!e_calendar_view_get_visible_time_range ( + calendar_view, &start_time, &end_time)) { + g_warn_if_reached (); + return NULL; + } + + start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone); + start_tm.tm_year = start_tt.year - 1900; + start_tm.tm_mon = start_tt.month - 1; + start_tm.tm_mday = start_tt.day; + start_tm.tm_hour = start_tt.hour; + start_tm.tm_min = start_tt.minute; + start_tm.tm_sec = start_tt.second; + start_tm.tm_isdst = -1; + start_tm.tm_wday = time_day_of_week ( + start_tt.day, start_tt.month - 1, + start_tt.year); + + /* Take one off end_time so we don't get an extra day. */ + end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone); + end_tm.tm_year = end_tt.year - 1900; + end_tm.tm_mon = end_tt.month - 1; + end_tm.tm_mday = end_tt.day; + end_tm.tm_hour = end_tt.hour; + end_tm.tm_min = end_tt.minute; + end_tm.tm_sec = end_tt.second; + end_tm.tm_isdst = -1; + end_tm.tm_wday = time_day_of_week ( + end_tt.day, end_tt.month - 1, + end_tt.year); + + view = gnome_calendar_get_view (gcal); + + switch (view) { + case GNOME_CAL_DAY_VIEW: + case GNOME_CAL_WORK_WEEK_VIEW: + case GNOME_CAL_WEEK_VIEW: + if (start_tm.tm_year == end_tm.tm_year + && start_tm.tm_mon == end_tm.tm_mon + && start_tm.tm_mday == end_tm.tm_mday) { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%A %d %b %Y"), &start_tm); + } else if (start_tm.tm_year == end_tm.tm_year) { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%a %d %b"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%a %d %b %Y"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + case GNOME_CAL_MONTH_VIEW: + case GNOME_CAL_LIST_VIEW: + if (start_tm.tm_year == end_tm.tm_year) { + if (start_tm.tm_mon == end_tm.tm_mon) { + if (start_tm.tm_mday == end_tm.tm_mday) { + buffer[0] = '\0'; + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + "%d", &start_tm); + strcat (buffer, " - "); + } + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%d %b"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + } else { + e_utf8_strftime ( + buffer, sizeof (buffer), + _("%d %b %Y"), &start_tm); + e_utf8_strftime ( + end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + default: + g_return_val_if_reached (NULL); + } + return buffer; +} + +static gint +ea_gnome_calendar_get_n_children (AtkObject *obj) +{ + g_return_val_if_fail (EA_IS_GNOME_CALENDAR (obj), 0); + + if (gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)) == NULL) + return -1; + + return 2; +} + +static AtkObject * +ea_gnome_calendar_ref_child (AtkObject *obj, + gint i) +{ + AtkObject * child = NULL; + GnomeCalendar * calendarWidget; + GnomeCalendarViewType view_type; + ECalendarView *view; + ECalendar *date_navigator; + GtkWidget *childWidget; + GtkWidget *widget; + + g_return_val_if_fail (EA_IS_GNOME_CALENDAR (obj), NULL); + /* valid child index range is [0-3] */ + if (i < 0 || i >3) + return NULL; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (obj)); + if (widget == NULL) + return NULL; + + calendarWidget = GNOME_CALENDAR (widget); + + switch (i) { + case 0: + /* for the day/week view */ + view_type = gnome_calendar_get_view (calendarWidget); + view = gnome_calendar_get_calendar_view (calendarWidget, view_type); + childWidget = GTK_WIDGET (view); + child = gtk_widget_get_accessible (childWidget); + atk_object_set_parent (child, obj); + break; + case 1: + /* for calendar */ + date_navigator = gnome_calendar_get_date_navigator (calendarWidget); + childWidget = GTK_WIDGET (date_navigator); + child = gtk_widget_get_accessible (childWidget); + break; + default: + break; + } + if (child) + g_object_ref (child); + return child; +} + +static void +ea_gcal_dates_change_cb (GnomeCalendar *gcal, + gpointer data) +{ + const gchar *new_name; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_GNOME_CALENDAR (data)); + + new_name = ea_gnome_calendar_get_label_description (gcal); + atk_object_set_name (ATK_OBJECT (data), new_name); + g_signal_emit_by_name (data, "visible_data_changed"); + +#ifdef ACC_DEBUG + printf ("AccDebug: calendar dates changed, label=%s\n", new_name); +#endif +} diff -Nru evolution-3.16.0/calendar/gui/ea-gnome-calendar.h evolution-3.12.11/calendar/gui/ea-gnome-calendar.h --- evolution-3.16.0/calendar/gui/ea-gnome-calendar.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-gnome-calendar.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,58 @@ +/* + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * Bolian Yin + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_GNOME_CALENDAR_H__ +#define __EA_GNOME_CALENDAR_H__ + +#include +#include "gnome-cal.h" + +G_BEGIN_DECLS + +#define EA_TYPE_GNOME_CALENDAR (ea_gnome_calendar_get_type ()) +#define EA_GNOME_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendar)) +#define EA_GNOME_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendarClass)) +#define EA_IS_GNOME_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_GNOME_CALENDAR)) +#define EA_IS_GNOME_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_GNOME_CALENDAR)) +#define EA_GNOME_CALENDAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendarClass)) + +typedef struct _EaGnomeCalendar EaGnomeCalendar; +typedef struct _EaGnomeCalendarClass EaGnomeCalendarClass; + +struct _EaGnomeCalendar +{ + GtkAccessible parent; +}; + +GType ea_gnome_calendar_get_type (void); + +struct _EaGnomeCalendarClass +{ + GtkAccessibleClass parent_class; +}; + +AtkObject * ea_gnome_calendar_new (GtkWidget *widget); + +const gchar * ea_gnome_calendar_get_label_description (GnomeCalendar *gcal); + +G_END_DECLS + +#endif /* __EA_GNOME_CALENDAR_H__ */ diff -Nru evolution-3.16.0/calendar/gui/ea-week-view.c evolution-3.12.11/calendar/gui/ea-week-view.c --- evolution-3.16.0/calendar/gui/ea-week-view.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-week-view.c 2014-03-24 09:25:23.000000000 +0000 @@ -29,7 +29,7 @@ #include "ea-cal-view-event.h" #include "ea-calendar-helpers.h" -#include "e-month-view.h" +#include "ea-gnome-calendar.h" static const gchar * ea_week_view_get_name (AtkObject *accessible); static const gchar * ea_week_view_get_description (AtkObject *accessible); @@ -84,7 +84,9 @@ ea_week_view_get_name (AtkObject *accessible) { EWeekView *week_view; - gchar *label_text; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; GtkWidget *widget; gint n_events; gchar *event_str, *name_str; @@ -96,8 +98,9 @@ return NULL; week_view = E_WEEK_VIEW (widget); + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); - label_text = e_calendar_view_get_description_text (E_CALENDAR_VIEW (week_view)); + label_text = ea_gnome_calendar_get_label_description (gcal); n_events = atk_object_get_n_accessible_children (accessible); /* the child main item is always there */ @@ -109,7 +112,9 @@ else event_str = g_strdup (_("It has no events.")); - if (E_IS_MONTH_VIEW (week_view)) + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_MONTH_VIEW) name_str = g_strdup_printf ( _("Month View: %s. %s"), label_text, event_str); @@ -122,7 +127,6 @@ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); g_free (name_str); g_free (event_str); - g_free (label_text); return accessible->name; } @@ -144,7 +148,13 @@ if (accessible->description) return accessible->description; else { - if (E_IS_MONTH_VIEW (week_view)) + GnomeCalendar *gcal; + GnomeCalendarViewType view_type; + + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_MONTH_VIEW) return _("calendar view for a month"); else return _("calendar view for one or more weeks"); @@ -178,14 +188,12 @@ event = &g_array_index (week_view->events, EWeekViewEvent, event_index); - if (event->spans_index >= 0 && event->spans_index < week_view->spans->len) { - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + 0); - - /* at least one of the event spans is visible, count it */ - if (span->text_item) - ++count; - } + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + event->spans_index + 0); + + /* at least one of the event spans is visible, count it */ + if (span->text_item) + ++count; } /* add the number of visible jump buttons */ @@ -242,10 +250,6 @@ event = &g_array_index (week_view->events, EWeekViewEvent, event_index); - - if (event->spans_index < 0 || !week_view->spans || event->spans_index >= week_view->spans->len) - continue; - span = &g_array_index (week_view->spans, EWeekViewEventSpan, event->spans_index + span_num); diff -Nru evolution-3.16.0/calendar/gui/ea-week-view-main-item.c evolution-3.12.11/calendar/gui/ea-week-view-main-item.c --- evolution-3.16.0/calendar/gui/ea-week-view-main-item.c 2015-01-05 13:56:08.000000000 +0000 +++ evolution-3.12.11/calendar/gui/ea-week-view-main-item.c 2014-10-07 05:37:46.000000000 +0000 @@ -50,10 +50,8 @@ (AtkObject *accessible); /* callbacks */ -static void ea_week_view_main_item_time_range_changed_cb - (ECalModel *model, - time_t start, - time_t end, +static void ea_week_view_main_item_dates_change_cb + (GnomeCalendar *gcal, gpointer data); static void ea_week_view_main_item_time_change_cb (EWeekView *week_view, @@ -219,7 +217,7 @@ ea_week_view_main_item_new (GObject *obj) { AtkObject *accessible; - ECalModel *model; + GnomeCalendar *gcal; EWeekViewMainItem *main_item; EWeekView *week_view; @@ -248,11 +246,11 @@ accessible); /* listen for date changes of calendar */ - model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); - if (model) + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); + if (gcal) g_signal_connect ( - model, "time-range-changed", - G_CALLBACK (ea_week_view_main_item_time_range_changed_cb), + gcal, "dates_shown_changed", + G_CALLBACK (ea_week_view_main_item_dates_change_cb), accessible); return accessible; @@ -402,14 +400,12 @@ /* callbacks */ static void -ea_week_view_main_item_time_range_changed_cb (ECalModel *model, - time_t start, - time_t end, - gpointer data) +ea_week_view_main_item_dates_change_cb (GnomeCalendar *gcal, + gpointer data) { EaWeekViewMainItem *ea_main_item; - g_return_if_fail (E_IS_CAL_MODEL (model)); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); g_return_if_fail (data); g_return_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (data)); @@ -453,6 +449,7 @@ "active-descendant-changed", item_cell); g_signal_emit_by_name (data, "selection_changed"); + atk_focus_tracker_notify (item_cell); g_object_unref (item_cell); } } @@ -761,9 +758,8 @@ child = atk_object_ref_accessible_child ( ATK_OBJECT (ea_main_item), index); if (child) - atk_component_get_extents ( - ATK_COMPONENT (child), NULL, NULL, &width, &height, - ATK_XY_SCREEN); + atk_component_get_size ( + ATK_COMPONENT (child), &width, &height); return width; } @@ -783,9 +779,8 @@ child = atk_object_ref_accessible_child ( ATK_OBJECT (ea_main_item), index); if (child) - atk_component_get_extents ( - ATK_COMPONENT (child), NULL, NULL, &width, &height, - ATK_XY_SCREEN); + atk_component_get_size ( + ATK_COMPONENT (child), &width, &height); return height; } diff -Nru evolution-3.16.0/calendar/gui/e-cal-component-preview.c evolution-3.12.11/calendar/gui/e-cal-component-preview.c --- evolution-3.16.0/calendar/gui/e-cal-component-preview.c 2014-07-07 08:08:19.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-component-preview.c 2014-07-07 10:56:09.000000000 +0000 @@ -230,9 +230,9 @@ g_string_append_printf (buffer, "%s", _("Categories:")); for (iter = list; iter != NULL; iter = iter->next) { const gchar *category = iter->data; - gchar *icon_file; + const gchar *icon_file; - icon_file = e_categories_dup_icon_file_for (category); + icon_file = e_categories_get_icon_file_for (category); if (icon_file && g_file_test (icon_file, G_FILE_TEST_EXISTS)) { gchar *uri; @@ -246,8 +246,6 @@ g_string_append_len (string, ", ", 2); g_string_append (string, category); } - - g_free (icon_file); } if (string->len > 0) g_string_append_printf (buffer, "%s", string->str); diff -Nru evolution-3.16.0/calendar/gui/e-cal-config.c evolution-3.12.11/calendar/gui/e-cal-config.c --- evolution-3.16.0/calendar/gui/e-cal-config.c 2014-11-13 07:32:18.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-config.c 2014-03-24 09:25:23.000000000 +0000 @@ -154,7 +154,7 @@ t = e_config_target_new ( &ecp->config, EC_CONFIG_TARGET_PREFS, sizeof (*t)); - t->settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + t->settings = g_settings_new ("org.gnome.evolution.calendar"); return t; } diff -Nru evolution-3.16.0/calendar/gui/e-cal-data-model.c evolution-3.12.11/calendar/gui/e-cal-data-model.c --- evolution-3.16.0/calendar/gui/e-cal-data-model.c 2015-02-24 09:04:48.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-data-model.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2902 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include "comp-util.h" -#include "e-cal-data-model.h" - -#define LOCK_PROPS() g_rec_mutex_lock (&data_model->priv->props_lock) -#define UNLOCK_PROPS() g_rec_mutex_unlock (&data_model->priv->props_lock) - -struct _ECalDataModelPrivate { - GThread *main_thread; - ECalDataModelSubmitThreadJobFunc submit_thread_job_func; - GWeakRef *submit_thread_job_responder; - GThreadPool *thread_pool; - - GRecMutex props_lock; /* to guard all the below members */ - - gboolean disposing; - gboolean expand_recurrences; - gchar *filter; - gchar *full_filter; /* to be used with views */ - icaltimezone *zone; - time_t range_start; - time_t range_end; - - GHashTable *clients; /* ESource::uid ~> ECalClient */ - GHashTable *views; /* ECalClient ~> ViewData */ - GSList *subscribers; /* ~> SubscriberData */ - - guint32 views_update_freeze; - gboolean views_update_required; -}; - -enum { - PROP_0, - PROP_EXPAND_RECURRENCES, - PROP_TIMEZONE -}; - -enum { - VIEW_STATE_CHANGED, - LAST_SIGNAL -}; - -static guint signals[LAST_SIGNAL]; - -G_DEFINE_TYPE (ECalDataModel, e_cal_data_model, G_TYPE_OBJECT) - -typedef struct _ComponentData { - ECalComponent *component; - time_t instance_start; - time_t instance_end; - gboolean is_detached; -} ComponentData; - -typedef struct _ViewData { - gint ref_count; - GRecMutex lock; - gboolean is_used; - - ECalClient *client; - ECalClientView *view; - gulong objects_added_id; - gulong objects_modified_id; - gulong objects_removed_id; - gulong progress_id; - gulong complete_id; - - GHashTable *components; /* ECalComponentId ~> ComponentData */ - GHashTable *lost_components; /* ECalComponentId ~> ComponentData; when re-running view, valid till 'complete' is received */ - gboolean received_complete; - GSList *to_expand_recurrences; /* icalcomponent */ - GSList *expanded_recurrences; /* ComponentData */ - gint pending_expand_recurrences; /* how many is waiting to be processed */ - - GCancellable *cancellable; -} ViewData; - -typedef struct _SubscriberData { - ECalDataModelSubscriber *subscriber; - time_t range_start; - time_t range_end; -} SubscriberData; - -static ComponentData * -component_data_new (ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gboolean is_detached) -{ - ComponentData *comp_data; - - g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), NULL); - - comp_data = g_new0 (ComponentData, 1); - comp_data->component = g_object_ref (comp); - comp_data->instance_start = instance_start; - comp_data->instance_end = instance_end; - comp_data->is_detached = is_detached; - - return comp_data; -} - -static void -component_data_free (gpointer ptr) -{ - ComponentData *comp_data = ptr; - - if (comp_data) { - g_object_unref (comp_data->component); - g_free (comp_data); - } -} - -static gboolean -component_data_equal (ComponentData *comp_data1, - ComponentData *comp_data2) -{ - icalcomponent *icomp1, *icomp2; - struct icaltimetype tt1, tt2; - gchar *as_str1, *as_str2; - gboolean equal; - - if (comp_data1 == comp_data2) - return TRUE; - - if (!comp_data1 || !comp_data2 || !comp_data1->component || !comp_data2->component) - return FALSE; - - if (comp_data1->instance_start != comp_data2->instance_start || - comp_data1->instance_end != comp_data2->instance_end) - return FALSE; - - icomp1 = e_cal_component_get_icalcomponent (comp_data1->component); - icomp2 = e_cal_component_get_icalcomponent (comp_data2->component); - - if (!icomp1 || !icomp2 || - icalcomponent_get_sequence (icomp1) != icalcomponent_get_sequence (icomp2) || - g_strcmp0 (icalcomponent_get_uid (icomp1), icalcomponent_get_uid (icomp2)) != 0) - return FALSE; - - tt1 = icalcomponent_get_recurrenceid (icomp1); - tt2 = icalcomponent_get_recurrenceid (icomp2); - if ((icaltime_is_valid_time (tt1) ? 1 : 0) != (icaltime_is_valid_time (tt2) ? 1 : 0) || - (icaltime_is_null_time (tt1) ? 1 : 0) != (icaltime_is_null_time (tt2) ? 1 : 0) || - icaltime_compare (tt1, tt2) != 0) - return FALSE; - - tt1 = icalcomponent_get_dtstamp (icomp1); - tt2 = icalcomponent_get_dtstamp (icomp2); - if ((icaltime_is_valid_time (tt1) ? 1 : 0) != (icaltime_is_valid_time (tt2) ? 1 : 0) || - (icaltime_is_null_time (tt1) ? 1 : 0) != (icaltime_is_null_time (tt2) ? 1 : 0) || - icaltime_compare (tt1, tt2) != 0) - return FALSE; - - /* Maybe not so effective compare, but might be still more effective - than updating whole UI with false notifications */ - as_str1 = icalcomponent_as_ical_string_r (icomp1); - as_str2 = icalcomponent_as_ical_string_r (icomp2); - - equal = g_strcmp0 (as_str1, as_str2) == 0; - - g_free (as_str1); - g_free (as_str2); - - return equal; -} - -static ViewData * -view_data_new (ECalClient *client) -{ - ViewData *view_data; - - g_return_val_if_fail (E_IS_CAL_CLIENT (client), NULL); - - view_data = g_new0 (ViewData, 1); - view_data->ref_count = 1; - g_rec_mutex_init (&view_data->lock); - view_data->is_used = TRUE; - view_data->client = g_object_ref (client); - view_data->components = g_hash_table_new_full ( - (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal, - (GDestroyNotify) e_cal_component_free_id, component_data_free); - - return view_data; -} - -static void -view_data_disconnect_view (ViewData *view_data) -{ - if (view_data && view_data->view) { - #define disconnect(x) G_STMT_START { \ - if (view_data->x) { \ - g_signal_handler_disconnect (view_data->view, view_data->x); \ - view_data->x = 0; \ - } \ - } G_STMT_END - - disconnect (objects_added_id); - disconnect (objects_modified_id); - disconnect (objects_removed_id); - disconnect (progress_id); - disconnect (complete_id); - - #undef disconnect - } -} - -static ViewData * -view_data_ref (ViewData *view_data) -{ - g_return_val_if_fail (view_data != NULL, NULL); - - g_atomic_int_inc (&view_data->ref_count); - - return view_data; -} - -static void -view_data_unref (gpointer ptr) -{ - ViewData *view_data = ptr; - - if (view_data) { - if (g_atomic_int_dec_and_test (&view_data->ref_count)) { - view_data_disconnect_view (view_data); - if (view_data->cancellable) - g_cancellable_cancel (view_data->cancellable); - g_clear_object (&view_data->cancellable); - g_clear_object (&view_data->client); - g_clear_object (&view_data->view); - g_hash_table_destroy (view_data->components); - if (view_data->lost_components) - g_hash_table_destroy (view_data->lost_components); - g_slist_free_full (view_data->to_expand_recurrences, (GDestroyNotify) icalcomponent_free); - g_slist_free_full (view_data->expanded_recurrences, component_data_free); - g_rec_mutex_clear (&view_data->lock); - g_free (view_data); - } - } -} - -static void -view_data_lock (ViewData *view_data) -{ - g_return_if_fail (view_data != NULL); - - g_rec_mutex_lock (&view_data->lock); -} - -static void -view_data_unlock (ViewData *view_data) -{ - g_return_if_fail (view_data != NULL); - - g_rec_mutex_unlock (&view_data->lock); -} - -static SubscriberData * -subscriber_data_new (ECalDataModelSubscriber *subscriber, - time_t range_start, - time_t range_end) -{ - SubscriberData *subs_data; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber), NULL); - - subs_data = g_new0 (SubscriberData, 1); - subs_data->subscriber = g_object_ref (subscriber); - subs_data->range_start = range_start; - subs_data->range_end = range_end; - - return subs_data; -} - -static void -subscriber_data_free (gpointer ptr) -{ - SubscriberData *subs_data = ptr; - - if (subs_data) { - g_clear_object (&subs_data->subscriber); - g_free (subs_data); - } -} - -typedef struct _ViewStateChangedData { - ECalDataModel *data_model; - ECalClientView *view; - ECalDataModelViewState state; - guint percent; - gchar *message; - GError *error; -} ViewStateChangedData; - -static void -view_state_changed_data_free (gpointer ptr) -{ - ViewStateChangedData *vscd = ptr; - - if (vscd) { - g_clear_object (&vscd->data_model); - g_clear_object (&vscd->view); - g_clear_error (&vscd->error); - g_free (vscd->message); - g_free (vscd); - } -} - -static gboolean -cal_data_model_emit_view_state_changed_timeout_cb (gpointer user_data) -{ - ViewStateChangedData *vscd = user_data; - - g_return_val_if_fail (vscd != NULL, FALSE); - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (vscd->data_model), FALSE); - g_return_val_if_fail (E_IS_CAL_CLIENT_VIEW (vscd->view), FALSE); - - g_signal_emit (vscd->data_model, signals[VIEW_STATE_CHANGED], 0, - vscd->view, vscd->state, vscd->percent, vscd->message, vscd->error); - - return FALSE; -} - -static void -cal_data_model_emit_view_state_changed (ECalDataModel *data_model, - ECalClientView *view, - ECalDataModelViewState state, - guint percent, - const gchar *message, - const GError *error) -{ - ViewStateChangedData *vscd; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (E_IS_CAL_CLIENT_VIEW (view)); - - if (e_cal_data_model_get_disposing (data_model)) - return; - - vscd = g_new0 (ViewStateChangedData, 1); - vscd->data_model = g_object_ref (data_model); - vscd->view = g_object_ref (view); - vscd->state = state; - vscd->percent = percent; - vscd->message = g_strdup (message); - vscd->error = error ? g_error_copy (error) : NULL; - - g_timeout_add_full (G_PRIORITY_DEFAULT, 1, - cal_data_model_emit_view_state_changed_timeout_cb, - vscd, view_state_changed_data_free); -} - -typedef void (* InternalThreadJobFunc) (ECalDataModel *data_model, gpointer user_data); - -typedef struct _InternalThreadJobData { - InternalThreadJobFunc func; - gpointer user_data; -} InternalThreadJobData; - -static void -cal_data_model_internal_thread_job_func (gpointer data, - gpointer user_data) -{ - ECalDataModel *data_model = user_data; - InternalThreadJobData *job_data = data; - - g_return_if_fail (job_data != NULL); - g_return_if_fail (job_data->func != NULL); - - job_data->func (data_model, job_data->user_data); - - g_free (job_data); -} - -static void -cal_data_model_submit_internal_thread_job (ECalDataModel *data_model, - InternalThreadJobFunc func, - gpointer user_data) -{ - InternalThreadJobData *job_data; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (func != NULL); - - job_data = g_new0 (InternalThreadJobData, 1); - job_data->func = func; - job_data->user_data = user_data; - - g_thread_pool_push (data_model->priv->thread_pool, job_data, NULL); -} - -typedef struct _SubmitThreadJobData { - ECalDataModel *data_model; - const gchar *description; - const gchar *alert_ident; - const gchar *alert_arg_0; - EAlertSinkThreadJobFunc func; - gpointer user_data; - GDestroyNotify free_user_data; - - GCancellable *cancellable; - gboolean finished; - GMutex mutex; - GCond cond; -} SubmitThreadJobData; - -static gboolean -cal_data_model_call_submit_thread_job (gpointer user_data) -{ - SubmitThreadJobData *stj_data = user_data; - GObject *responder; - - g_return_val_if_fail (stj_data != NULL, FALSE); - - g_mutex_lock (&stj_data->mutex); - responder = g_weak_ref_get (stj_data->data_model->priv->submit_thread_job_responder); - - stj_data->cancellable = stj_data->data_model->priv->submit_thread_job_func ( - responder, stj_data->description, stj_data->alert_ident, stj_data->alert_arg_0, - stj_data->func, stj_data->user_data, stj_data->free_user_data); - - g_clear_object (&responder); - - stj_data->finished = TRUE; - g_cond_signal (&stj_data->cond); - g_mutex_unlock (&stj_data->mutex); - - return FALSE; -} - -/** - * e_cal_data_model_submit_thread_job: - * @data_model: an #ECalDataModel - * @description: user-friendly description of the job, to be shown in UI - * @alert_ident: in case of an error, this alert identificator is used - * for EAlert construction - * @alert_arg_0: (allow-none): in case of an error, use this string as - * the first argument to the EAlert construction; the second argument - * is the actual error message; can be #NULL, in which case only - * the error message is passed to the EAlert construction - * @func: function to be run in a dedicated thread - * @user_data: (allow-none): custom data passed into @func; can be #NULL - * @free_user_data: (allow-none): function to be called on @user_data, - * when the job is over; can be #NULL - * - * Runs the @func in a dedicated thread. Any error is propagated to UI. - * The cancellable passed into the @func is a #CamelOperation, thus - * the caller can overwrite progress and description message on it. - * - * Returns: (transfer full): Newly created #GCancellable on success. - * The caller is responsible to g_object_unref() it when done with it. - * - * Note: The @free_user_data, if set, is called in the main thread. - * - * Note: This is a blocking call, it waits until the thread job is submitted. - * - * Since: 3.16 - **/ -GCancellable * -e_cal_data_model_submit_thread_job (ECalDataModel *data_model, - const gchar *description, - const gchar *alert_ident, - const gchar *alert_arg_0, - EAlertSinkThreadJobFunc func, - gpointer user_data, - GDestroyNotify free_user_data) -{ - SubmitThreadJobData stj_data; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - g_return_val_if_fail (data_model->priv->submit_thread_job_func != NULL, NULL); - - if (g_thread_self () == data_model->priv->main_thread) { - GCancellable *cancellable; - GObject *responder; - - responder = g_weak_ref_get (data_model->priv->submit_thread_job_responder); - cancellable = data_model->priv->submit_thread_job_func ( - responder, description, alert_ident, alert_arg_0, - func, user_data, free_user_data); - g_clear_object (&responder); - - return cancellable; - } - - stj_data.data_model = data_model; - stj_data.description = description; - stj_data.alert_ident = alert_ident; - stj_data.alert_arg_0 = alert_arg_0; - stj_data.func = func; - stj_data.user_data = user_data; - stj_data.free_user_data = free_user_data; - stj_data.cancellable = NULL; - stj_data.finished = FALSE; - g_mutex_init (&stj_data.mutex); - g_cond_init (&stj_data.cond); - - g_timeout_add (1, cal_data_model_call_submit_thread_job, &stj_data); - - g_mutex_lock (&stj_data.mutex); - while (!stj_data.finished) { - g_cond_wait (&stj_data.cond, &stj_data.mutex); - } - g_mutex_unlock (&stj_data.mutex); - - g_cond_clear (&stj_data.cond); - g_mutex_clear (&stj_data.mutex); - - return stj_data.cancellable; -} - -typedef void (* ECalDataModelForeachSubscriberFunc) (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data); - -static void -cal_data_model_foreach_subscriber_in_range (ECalDataModel *data_model, - ECalClient *client, - time_t in_range_start, - time_t in_range_end, - ECalDataModelForeachSubscriberFunc func, - gpointer user_data) -{ - GSList *link; - - g_return_if_fail (func != NULL); - - LOCK_PROPS (); - - if (in_range_end == (time_t) 0) { - in_range_end = in_range_start; - } - - for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) { - SubscriberData *subs_data = link->data; - - if ((in_range_start == (time_t) 0 && in_range_end == (time_t) 0) || - (subs_data->range_start == (time_t) 0 && subs_data->range_end == (time_t) 0) || - (subs_data->range_start <= in_range_end && subs_data->range_end >= in_range_start)) - func (data_model, client, subs_data->subscriber, user_data); - } - - UNLOCK_PROPS (); -} - -static void -cal_data_model_foreach_subscriber (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelForeachSubscriberFunc func, - gpointer user_data) -{ - g_return_if_fail (func != NULL); - - cal_data_model_foreach_subscriber_in_range (data_model, client, (time_t) 0, (time_t) 0, func, user_data); -} - -static void -cal_data_model_freeze_subscriber_cb (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data) -{ - e_cal_data_model_subscriber_freeze (subscriber); -} - -static void -cal_data_model_thaw_subscriber_cb (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data) -{ - e_cal_data_model_subscriber_thaw (subscriber); -} - -static void -cal_data_model_freeze_all_subscribers (ECalDataModel *data_model) -{ - cal_data_model_foreach_subscriber (data_model, NULL, cal_data_model_freeze_subscriber_cb, NULL); -} - -static void -cal_data_model_thaw_all_subscribers (ECalDataModel *data_model) -{ - cal_data_model_foreach_subscriber (data_model, NULL, cal_data_model_thaw_subscriber_cb, NULL); -} - -static void -cal_data_model_add_component_cb (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data) -{ - ECalComponent *comp = user_data; - - g_return_if_fail (comp != NULL); - - e_cal_data_model_subscriber_component_added (subscriber, client, comp); -} - -static void -cal_data_model_modify_component_cb (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data) -{ - ECalComponent *comp = user_data; - - g_return_if_fail (comp != NULL); - - e_cal_data_model_subscriber_component_modified (subscriber, client, comp); -} - -static void -cal_data_model_remove_one_view_component_cb (ECalDataModel *data_model, - ECalClient *client, - ECalDataModelSubscriber *subscriber, - gpointer user_data) -{ - const ECalComponentId *id = user_data; - - g_return_if_fail (id != NULL); - - e_cal_data_model_subscriber_component_removed (subscriber, client, id->uid, id->rid); -} - -static void -cal_data_model_remove_components (ECalDataModel *data_model, - ECalClient *client, - GHashTable *components, - GHashTable *also_remove_from) -{ - GList *ids, *ilink; - - g_return_if_fail (data_model != NULL); - g_return_if_fail (components != NULL); - - cal_data_model_freeze_all_subscribers (data_model); - - ids = g_hash_table_get_keys (components); - - for (ilink = ids; ilink; ilink = g_list_next (ilink)) { - ECalComponentId *id = ilink->data; - ComponentData *comp_data; - time_t instance_start = (time_t) 0, instance_end = (time_t) 0; - - if (!id) - continue; - - /* Try to limit which subscribers will be notified about removal */ - comp_data = g_hash_table_lookup (components, id); - if (comp_data) { - instance_start = comp_data->instance_start; - instance_end = comp_data->instance_end; - } - - cal_data_model_foreach_subscriber_in_range (data_model, client, - instance_start, instance_end, - cal_data_model_remove_one_view_component_cb, id); - - if (also_remove_from) - g_hash_table_remove (also_remove_from, id); - } - - g_list_free (ids); - - cal_data_model_thaw_all_subscribers (data_model); -} - -static void -cal_data_model_calc_range (ECalDataModel *data_model, - time_t *range_start, - time_t *range_end) -{ - GSList *link; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (range_start != NULL); - g_return_if_fail (range_end != NULL); - - *range_start = (time_t) 0; - *range_end = (time_t) 0; - - LOCK_PROPS (); - - for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) { - SubscriberData *subs_data = link->data; - - if (!subs_data) - continue; - - if (subs_data->range_start == (time_t) 0 && subs_data->range_end == (time_t) 0) { - *range_start = (time_t) 0; - *range_end = (time_t) 0; - break; - } - - if (link == data_model->priv->subscribers) { - *range_start = subs_data->range_start; - *range_end = subs_data->range_end; - } else { - if (*range_start > subs_data->range_start) - *range_start = subs_data->range_start; - if (*range_end < subs_data->range_end) - *range_end = subs_data->range_end; - } - } - - UNLOCK_PROPS (); -} - -static gboolean -cal_data_model_update_full_filter (ECalDataModel *data_model) -{ - gchar *filter; - time_t range_start, range_end; - gboolean changed; - - LOCK_PROPS (); - - cal_data_model_calc_range (data_model, &range_start, &range_end); - - if (range_start != (time_t) 0 || range_end != (time_t) 0) { - gchar *iso_start, *iso_end; - const gchar *default_tzloc = NULL; - - iso_start = isodate_from_time_t (range_start); - iso_end = isodate_from_time_t (range_end); - - if (data_model->priv->zone && data_model->priv->zone != icaltimezone_get_utc_timezone ()) - default_tzloc = icaltimezone_get_location (data_model->priv->zone); - if (!default_tzloc) - default_tzloc = ""; - - if (data_model->priv->filter) { - filter = g_strdup_printf ( - "(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\") %s)", - iso_start, iso_end, default_tzloc, data_model->priv->filter); - } else { - filter = g_strdup_printf ( - "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\")", - iso_start, iso_end, default_tzloc); - } - - g_free (iso_start); - g_free (iso_end); - } else if (data_model->priv->filter) { - filter = g_strdup (data_model->priv->filter); - } else { - filter = g_strdup ("#t"); - } - - changed = g_strcmp0 (data_model->priv->full_filter, filter) != 0; - - if (changed) { - g_free (data_model->priv->full_filter); - data_model->priv->full_filter = filter; - } else { - g_free (filter); - } - - UNLOCK_PROPS (); - - return changed; -} - -/* This consumes the comp_data - not so nice, but simpler - than adding reference counter for the structure */ -static void -cal_data_model_process_added_component (ECalDataModel *data_model, - ViewData *view_data, - ComponentData *comp_data, - GHashTable *known_instances) -{ - ECalComponentId *id; - ComponentData *old_comp_data = NULL; - gboolean comp_data_equal; - - g_return_if_fail (data_model != NULL); - g_return_if_fail (view_data != NULL); - g_return_if_fail (comp_data != NULL); - - id = e_cal_component_get_id (comp_data->component); - g_return_if_fail (id != NULL); - - view_data_lock (view_data); - - if (!old_comp_data && view_data->lost_components) - old_comp_data = g_hash_table_lookup (view_data->lost_components, id); - - if (!old_comp_data && known_instances) - old_comp_data = g_hash_table_lookup (known_instances, id); - - if (!old_comp_data) - old_comp_data = g_hash_table_lookup (view_data->components, id); - - if (old_comp_data) { - /* It can be a previously added detached instance received - during recurrences expand */ - if (!comp_data->is_detached) - comp_data->is_detached = old_comp_data->is_detached; - } - - comp_data_equal = component_data_equal (comp_data, old_comp_data); - - if (view_data->lost_components) - g_hash_table_remove (view_data->lost_components, id); - - if (known_instances) - g_hash_table_remove (known_instances, id); - - /* Note: old_comp_data is freed or NULL now */ - - /* 'id' is stolen by view_data->components */ - g_hash_table_insert (view_data->components, id, comp_data); - - if (!comp_data_equal) { - if (!old_comp_data) - cal_data_model_foreach_subscriber_in_range (data_model, view_data->client, - comp_data->instance_start, comp_data->instance_end, - cal_data_model_add_component_cb, comp_data->component); - else - cal_data_model_foreach_subscriber_in_range (data_model, view_data->client, - comp_data->instance_start, comp_data->instance_end, - cal_data_model_modify_component_cb, comp_data->component); - } - - view_data_unlock (view_data); -} - -typedef struct _GatherComponentsData { - const gchar *uid; - GList **pcomponent_ids; /* ECalComponentId, can be owned by the hash table */ - GHashTable *component_ids_hash; - gboolean copy_ids; - gboolean all_instances; /* FALSE to get only nondetached component instances */ -} GatherComponentsData; - -static void -cal_data_model_gather_components (gpointer key, - gpointer value, - gpointer user_data) -{ - ECalComponentId *id = key; - ComponentData *comp_data = value; - GatherComponentsData *gather_data = user_data; - - g_return_if_fail (id != NULL); - g_return_if_fail (comp_data != NULL); - g_return_if_fail (gather_data != NULL); - g_return_if_fail (gather_data->pcomponent_ids != NULL || gather_data->component_ids_hash != NULL); - g_return_if_fail (gather_data->pcomponent_ids == NULL || gather_data->component_ids_hash == NULL); - - if ((gather_data->all_instances || !comp_data->is_detached) && g_strcmp0 (id->uid, gather_data->uid) == 0) { - if (gather_data->component_ids_hash) { - ComponentData *comp_data_copy; - - comp_data_copy = component_data_new (comp_data->component, - comp_data->instance_start, comp_data->instance_end, - comp_data->is_detached); - - if (gather_data->copy_ids) { - g_hash_table_insert (gather_data->component_ids_hash, - e_cal_component_id_copy (id), comp_data_copy); - } else { - g_hash_table_insert (gather_data->component_ids_hash, id, comp_data_copy); - } - } else if (gather_data->copy_ids) { - *gather_data->pcomponent_ids = g_list_prepend (*gather_data->pcomponent_ids, - e_cal_component_id_copy (id)); - } else { - *gather_data->pcomponent_ids = g_list_prepend (*gather_data->pcomponent_ids, id); - } - } -} - -typedef struct _NotifyRecurrencesData { - ECalDataModel *data_model; - ECalClient *client; -} NotifyRecurrencesData; - -static gboolean -cal_data_model_notify_recurrences_cb (gpointer user_data) -{ - NotifyRecurrencesData *notif_data = user_data; - ECalDataModel *data_model; - ViewData *view_data; - - g_return_val_if_fail (notif_data != NULL, FALSE); - - data_model = notif_data->data_model; - - LOCK_PROPS (); - - view_data = g_hash_table_lookup (data_model->priv->views, notif_data->client); - if (view_data) - view_data_ref (view_data); - - UNLOCK_PROPS (); - - if (view_data) { - GHashTable *gathered_uids; - GHashTable *known_instances; - GSList *expanded_recurrences, *link; - - view_data_lock (view_data); - expanded_recurrences = view_data->expanded_recurrences; - view_data->expanded_recurrences = NULL; - - cal_data_model_freeze_all_subscribers (data_model); - - gathered_uids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - known_instances = g_hash_table_new_full ( - (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal, - (GDestroyNotify) e_cal_component_free_id, component_data_free); - - for (link = expanded_recurrences; link && view_data->is_used; link = g_slist_next (link)) { - ComponentData *comp_data = link->data; - icalcomponent *icomp; - const gchar *uid; - - if (!comp_data) - continue; - - icomp = e_cal_component_get_icalcomponent (comp_data->component); - if (!icomp || !icalcomponent_get_uid (icomp)) - continue; - - uid = icalcomponent_get_uid (icomp); - - if (!g_hash_table_contains (gathered_uids, uid)) { - GatherComponentsData gather_data; - - gather_data.uid = uid; - gather_data.pcomponent_ids = NULL; - gather_data.component_ids_hash = known_instances; - gather_data.copy_ids = TRUE; - gather_data.all_instances = FALSE; - - g_hash_table_foreach (view_data->components, - cal_data_model_gather_components, &gather_data); - - g_hash_table_insert (gathered_uids, g_strdup (uid), GINT_TO_POINTER (1)); - } - - /* Steal the comp_data */ - link->data = NULL; - - cal_data_model_process_added_component (data_model, view_data, comp_data, known_instances); - } - - if (view_data->is_used && g_hash_table_size (known_instances) > 0) { - cal_data_model_remove_components (data_model, view_data->client, known_instances, view_data->components); - g_hash_table_remove_all (known_instances); - } - - if (g_atomic_int_dec_and_test (&view_data->pending_expand_recurrences) && - view_data->is_used && view_data->lost_components && view_data->received_complete) { - cal_data_model_remove_components (data_model, view_data->client, view_data->lost_components, NULL); - g_hash_table_destroy (view_data->lost_components); - view_data->lost_components = NULL; - } - - g_hash_table_destroy (gathered_uids); - g_hash_table_destroy (known_instances); - - view_data_unlock (view_data); - - cal_data_model_thaw_all_subscribers (data_model); - - view_data_unref (view_data); - - g_slist_free_full (expanded_recurrences, component_data_free); - } - - g_clear_object (¬if_data->client); - g_clear_object (¬if_data->data_model); - g_free (notif_data); - - return FALSE; -} - -typedef struct -{ - ECalClient *client; - icaltimezone *zone; - GSList **pexpanded_recurrences; -} GenerateInstancesData; - -static gboolean -cal_data_model_instance_generated (ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - GenerateInstancesData *gid = data; - ComponentData *comp_data; - - g_return_val_if_fail (gid != NULL, FALSE); - - cal_comp_get_instance_times (gid->client, e_cal_component_get_icalcomponent (comp), - gid->zone, &instance_start, NULL, &instance_end, NULL, NULL); - - if (instance_end > instance_start) - instance_end--; - - comp_data = component_data_new (comp, instance_start, instance_end, FALSE); - *gid->pexpanded_recurrences = g_slist_prepend (*gid->pexpanded_recurrences, comp_data); - - return TRUE; -} - -static void -cal_data_model_expand_recurrences_thread (ECalDataModel *data_model, - gpointer user_data) -{ - ECalClient *client = user_data; - GSList *to_expand_recurrences, *link; - GSList *expanded_recurrences = NULL; - time_t range_start, range_end; - ViewData *view_data; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - view_data = g_hash_table_lookup (data_model->priv->views, client); - if (view_data) - view_data_ref (view_data); - - range_start = data_model->priv->range_start; - range_end = data_model->priv->range_end; - - UNLOCK_PROPS (); - - if (!view_data) { - g_object_unref (client); - return; - } - - view_data_lock (view_data); - - if (!view_data->is_used) { - view_data_unlock (view_data); - view_data_unref (view_data); - g_object_unref (client); - return; - } - - to_expand_recurrences = view_data->to_expand_recurrences; - view_data->to_expand_recurrences = NULL; - - view_data_unlock (view_data); - - for (link = to_expand_recurrences; link && view_data->is_used; link = g_slist_next (link)) { - icalcomponent *icomp = link->data; - GenerateInstancesData gid; - - if (!icomp) - continue; - - gid.client = client; - gid.pexpanded_recurrences = &expanded_recurrences; - gid.zone = data_model->priv->zone; - - e_cal_client_generate_instances_for_object_sync (client, icomp, range_start, range_end, - cal_data_model_instance_generated, &gid); - } - - g_slist_free_full (to_expand_recurrences, (GDestroyNotify) icalcomponent_free); - - view_data_lock (view_data); - if (expanded_recurrences) - view_data->expanded_recurrences = g_slist_concat (view_data->expanded_recurrences, expanded_recurrences); - if (view_data->is_used) { - NotifyRecurrencesData *notif_data; - - notif_data = g_new0 (NotifyRecurrencesData, 1); - notif_data->data_model = g_object_ref (data_model); - notif_data->client = g_object_ref (client); - - g_timeout_add (1, cal_data_model_notify_recurrences_cb, notif_data); - } - - view_data_unlock (view_data); - view_data_unref (view_data); - g_object_unref (client); -} - -static void -cal_data_model_process_modified_or_added_objects (ECalClientView *view, - const GSList *objects, - ECalDataModel *data_model, - gboolean is_add) -{ - ViewData *view_data; - ECalClient *client; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - client = e_cal_client_view_ref_client (view); - if (!client) { - UNLOCK_PROPS (); - return; - } - - view_data = g_hash_table_lookup (data_model->priv->views, client); - if (view_data) { - view_data_ref (view_data); - g_warn_if_fail (view_data->view == view); - } - - UNLOCK_PROPS (); - - if (!view_data) { - g_clear_object (&client); - return; - } - - view_data_lock (view_data); - - if (view_data->is_used) { - const GSList *link; - GSList *to_expand_recurrences = NULL; - - if (!is_add) { - /* Received a modify before the view was claimed as being complete, - aka fully populated, thus drop any previously known components, - because there is no hope for a merge. */ - if (view_data->lost_components) { - cal_data_model_remove_components (data_model, client, view_data->lost_components, NULL); - g_hash_table_destroy (view_data->lost_components); - view_data->lost_components = NULL; - } - } - - cal_data_model_freeze_all_subscribers (data_model); - - for (link = objects; link; link = g_slist_next (link)) { - icalcomponent *icomp = link->data; - - if (!icomp || !icalcomponent_get_uid (icomp)) - continue; - - if (data_model->priv->expand_recurrences && - !e_cal_util_component_is_instance (icomp) && - e_cal_util_component_has_recurrences (icomp)) { - /* This component requires an expand of recurrences, which - will be done in a dedicated thread, thus remember it */ - to_expand_recurrences = g_slist_prepend (to_expand_recurrences, - icalcomponent_new_clone (icomp)); - } else { - /* Single or detached instance, the simple case */ - ECalComponent *comp; - ComponentData *comp_data; - time_t instance_start, instance_end; - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icomp)); - if (!comp) - continue; - - cal_comp_get_instance_times (client, icomp, data_model->priv->zone, &instance_start, NULL, &instance_end, NULL, NULL); - - if (instance_end > instance_start) - instance_end--; - - comp_data = component_data_new (comp, instance_start, instance_end, - e_cal_util_component_is_instance (icomp)); - - cal_data_model_process_added_component (data_model, view_data, comp_data, NULL); - - g_object_unref (comp); - } - } - - cal_data_model_thaw_all_subscribers (data_model); - - if (to_expand_recurrences) { - view_data_lock (view_data); - view_data->to_expand_recurrences = g_slist_concat ( - view_data->to_expand_recurrences, to_expand_recurrences); - g_atomic_int_inc (&view_data->pending_expand_recurrences); - view_data_unlock (view_data); - - cal_data_model_submit_internal_thread_job (data_model, - cal_data_model_expand_recurrences_thread, g_object_ref (client)); - } - } - - view_data_unlock (view_data); - view_data_unref (view_data); - - g_clear_object (&client); -} - -static void -cal_data_model_view_objects_added (ECalClientView *view, - const GSList *objects, - ECalDataModel *data_model) -{ - cal_data_model_process_modified_or_added_objects (view, objects, data_model, TRUE); -} - -static void -cal_data_model_view_objects_modified (ECalClientView *view, - const GSList *objects, - ECalDataModel *data_model) -{ - cal_data_model_process_modified_or_added_objects (view, objects, data_model, FALSE); -} - -static void -cal_data_model_view_objects_removed (ECalClientView *view, - const GSList *uids, - ECalDataModel *data_model) -{ - ViewData *view_data; - ECalClient *client; - const GSList *link; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - client = e_cal_client_view_ref_client (view); - if (!client) { - UNLOCK_PROPS (); - return; - } - - view_data = g_hash_table_lookup (data_model->priv->views, client); - - g_clear_object (&client); - - if (view_data) { - view_data_ref (view_data); - g_warn_if_fail (view_data->view == view); - } - - UNLOCK_PROPS (); - - if (!view_data) - return; - - view_data_lock (view_data); - if (view_data->is_used) { - GHashTable *gathered_uids; - GList *removed = NULL, *rlink; - - gathered_uids = g_hash_table_new (g_str_hash, g_str_equal); - - for (link = uids; link; link = g_slist_next (link)) { - const ECalComponentId *id = link->data; - - if (id) { - if (!id->rid || !*id->rid) { - if (!g_hash_table_contains (gathered_uids, id->uid)) { - GatherComponentsData gather_data; - - gather_data.uid = id->uid; - gather_data.pcomponent_ids = &removed; - gather_data.component_ids_hash = NULL; - gather_data.copy_ids = TRUE; - gather_data.all_instances = TRUE; - - g_hash_table_foreach (view_data->components, - cal_data_model_gather_components, &gather_data); - if (view_data->lost_components) - g_hash_table_foreach (view_data->lost_components, - cal_data_model_gather_components, &gather_data); - - g_hash_table_insert (gathered_uids, id->uid, GINT_TO_POINTER (1)); - } - } else { - removed = g_list_prepend (removed, e_cal_component_id_copy (id)); - } - } - } - - cal_data_model_freeze_all_subscribers (data_model); - - for (rlink = removed; rlink; rlink = g_list_next (rlink)) { - ECalComponentId *id = rlink->data; - - if (id) { - ComponentData *comp_data; - time_t instance_start = (time_t) 0, instance_end = (time_t) 0; - - /* Try to limit which subscribers will be notified about removal */ - comp_data = g_hash_table_lookup (view_data->components, id); - if (comp_data) { - instance_start = comp_data->instance_start; - instance_end = comp_data->instance_end; - } else if (view_data->lost_components) { - comp_data = g_hash_table_lookup (view_data->lost_components, id); - if (comp_data) { - instance_start = comp_data->instance_start; - instance_end = comp_data->instance_end; - } - } - - g_hash_table_remove (view_data->components, id); - if (view_data->lost_components) - g_hash_table_remove (view_data->lost_components, id); - - cal_data_model_foreach_subscriber_in_range (data_model, view_data->client, - instance_start, instance_end, - cal_data_model_remove_one_view_component_cb, id); - } - } - - cal_data_model_thaw_all_subscribers (data_model); - - g_list_free_full (removed, (GDestroyNotify) e_cal_component_free_id); - g_hash_table_destroy (gathered_uids); - } - view_data_unlock (view_data); - view_data_unref (view_data); -} - -static void -cal_data_model_view_progress (ECalClientView *view, - guint percent, - const gchar *message, - ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - cal_data_model_emit_view_state_changed (data_model, view, E_CAL_DATA_MODEL_VIEW_STATE_PROGRESS, percent, message, NULL); -} - -static void -cal_data_model_view_complete (ECalClientView *view, - const GError *error, - ECalDataModel *data_model) -{ - ViewData *view_data; - ECalClient *client; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - client = e_cal_client_view_ref_client (view); - if (!client) { - UNLOCK_PROPS (); - return; - } - - view_data = g_hash_table_lookup (data_model->priv->views, client); - - g_clear_object (&client); - - if (view_data) { - view_data_ref (view_data); - g_warn_if_fail (view_data->view == view); - } - - UNLOCK_PROPS (); - - if (!view_data) - return; - - view_data_lock (view_data); - - view_data->received_complete = TRUE; - if (view_data->is_used && - view_data->lost_components && - !view_data->pending_expand_recurrences) { - cal_data_model_remove_components (data_model, view_data->client, view_data->lost_components, NULL); - g_hash_table_destroy (view_data->lost_components); - view_data->lost_components = NULL; - } - - cal_data_model_emit_view_state_changed (data_model, view, E_CAL_DATA_MODEL_VIEW_STATE_COMPLETE, 0, NULL, error); - - view_data_unlock (view_data); - view_data_unref (view_data); -} - -typedef struct _CreateViewData { - ECalDataModel *data_model; - ECalClient *client; -} CreateViewData; - -static void -create_view_data_free (gpointer ptr) -{ - CreateViewData *cv_data = ptr; - - if (cv_data) { - g_clear_object (&cv_data->data_model); - g_clear_object (&cv_data->client); - g_free (cv_data); - } -} - -static void -cal_data_model_create_view_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - CreateViewData *cv_data = user_data; - ViewData *view_data; - ECalDataModel *data_model; - ECalClient *client; - ECalClientView *view; - gchar *filter; - - g_return_if_fail (cv_data != NULL); - - data_model = cv_data->data_model; - client = cv_data->client; - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - - LOCK_PROPS (); - - if (g_cancellable_set_error_if_cancelled (cancellable, error)) { - UNLOCK_PROPS (); - return; - } - - view_data = g_hash_table_lookup (data_model->priv->views, client); - if (!view_data) { - UNLOCK_PROPS (); - g_warn_if_reached (); - return; - } - - filter = g_strdup (data_model->priv->full_filter); - - view_data_ref (view_data); - UNLOCK_PROPS (); - - view_data_lock (view_data); - g_warn_if_fail (view_data->view == NULL); - - if (!e_cal_client_get_view_sync (client, filter, &view_data->view, cancellable, error)) { - view_data_unlock (view_data); - view_data_unref (view_data); - g_free (filter); - return; - } - - g_warn_if_fail (view_data->view != NULL); - - view_data->objects_added_id = g_signal_connect (view_data->view, "objects-added", - G_CALLBACK (cal_data_model_view_objects_added), data_model); - view_data->objects_modified_id = g_signal_connect (view_data->view, "objects-modified", - G_CALLBACK (cal_data_model_view_objects_modified), data_model); - view_data->objects_removed_id = g_signal_connect (view_data->view, "objects-removed", - G_CALLBACK (cal_data_model_view_objects_removed), data_model); - view_data->progress_id = g_signal_connect (view_data->view, "progress", - G_CALLBACK (cal_data_model_view_progress), data_model); - view_data->complete_id = g_signal_connect (view_data->view, "complete", - G_CALLBACK (cal_data_model_view_complete), data_model); - - view = g_object_ref (view_data->view); - - view_data_unlock (view_data); - view_data_unref (view_data); - - g_free (filter); - - if (!g_cancellable_is_cancelled (cancellable)) { - cal_data_model_emit_view_state_changed (data_model, view, E_CAL_DATA_MODEL_VIEW_STATE_START, 0, NULL, NULL); - e_cal_client_view_start (view, error); - } - - g_clear_object (&view); -} - -typedef struct _NotifyRemoveComponentsData { - ECalDataModel *data_model; - ECalClient *client; -} NotifyRemoveComponentsData; - -static void -cal_data_model_notify_remove_components_cb (gpointer key, - gpointer value, - gpointer user_data) -{ - ECalComponentId *id = key; - ComponentData *comp_data = value; - NotifyRemoveComponentsData *nrc_data = user_data; - - g_return_if_fail (id != NULL); - g_return_if_fail (comp_data != NULL); - g_return_if_fail (nrc_data != NULL); - - cal_data_model_foreach_subscriber_in_range (nrc_data->data_model, nrc_data->client, - comp_data->instance_start, comp_data->instance_end, - cal_data_model_remove_one_view_component_cb, id); -} - -static void -cal_data_model_update_client_view (ECalDataModel *data_model, - ECalClient *client) -{ - ESource *source; - ViewData *view_data; - CreateViewData *cv_data; - const gchar *alert_ident; - gchar *description; - - LOCK_PROPS (); - - view_data = g_hash_table_lookup (data_model->priv->views, client); - if (!view_data) { - view_data = view_data_new (client); - g_hash_table_insert (data_model->priv->views, client, view_data); - } - - view_data_lock (view_data); - - if (view_data->cancellable) - g_cancellable_cancel (view_data->cancellable); - g_clear_object (&view_data->cancellable); - - if (view_data->view) { - view_data_disconnect_view (view_data); - cal_data_model_emit_view_state_changed (data_model, view_data->view, E_CAL_DATA_MODEL_VIEW_STATE_STOP, 0, NULL, NULL); - g_clear_object (&view_data->view); - } - - if (!view_data->received_complete) { - NotifyRemoveComponentsData nrc_data; - - nrc_data.data_model = data_model; - nrc_data.client = client; - - cal_data_model_freeze_all_subscribers (data_model); - - g_hash_table_foreach (view_data->components, - cal_data_model_notify_remove_components_cb, &nrc_data); - - g_hash_table_remove_all (view_data->components); - if (view_data->lost_components) { - g_hash_table_foreach (view_data->lost_components, - cal_data_model_notify_remove_components_cb, &nrc_data); - - g_hash_table_destroy (view_data->lost_components); - view_data->lost_components = NULL; - } - - cal_data_model_thaw_all_subscribers (data_model); - } else { - if (view_data->lost_components) { - NotifyRemoveComponentsData nrc_data; - - nrc_data.data_model = data_model; - nrc_data.client = client; - - cal_data_model_freeze_all_subscribers (data_model); - g_hash_table_foreach (view_data->lost_components, - cal_data_model_notify_remove_components_cb, &nrc_data); - cal_data_model_thaw_all_subscribers (data_model); - - g_hash_table_destroy (view_data->lost_components); - view_data->lost_components = NULL; - } - - view_data->lost_components = view_data->components; - view_data->components = g_hash_table_new_full ( - (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal, - (GDestroyNotify) e_cal_component_free_id, component_data_free); - } - - view_data_unlock (view_data); - - if (!data_model->priv->full_filter) { - UNLOCK_PROPS (); - return; - } - - source = e_client_get_source (E_CLIENT (client)); - - switch (e_cal_client_get_source_type (client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - alert_ident = "calendar:failed-create-view-calendar"; - description = g_strdup_printf (_("Creating view for calendar '%s'"), e_source_get_display_name (source)); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - alert_ident = "calendar:failed-create-view-tasks"; - description = g_strdup_printf (_("Creating view for task list '%s'"), e_source_get_display_name (source)); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - alert_ident = "calendar:failed-create-view-memos"; - description = g_strdup_printf (_("Creating view for memo list '%s'"), e_source_get_display_name (source)); - break; - case E_CAL_CLIENT_SOURCE_TYPE_LAST: - g_warn_if_reached (); - UNLOCK_PROPS (); - return; - } - - cv_data = g_new0 (CreateViewData, 1); - cv_data->data_model = g_object_ref (data_model); - cv_data->client = g_object_ref (client); - - view_data->received_complete = FALSE; - view_data->cancellable = e_cal_data_model_submit_thread_job (data_model, - description, alert_ident, e_source_get_display_name (source), - cal_data_model_create_view_thread, cv_data, create_view_data_free); - - g_free (description); - - UNLOCK_PROPS (); -} - -static void -cal_data_model_remove_client_view (ECalDataModel *data_model, - ECalClient *client) -{ - ViewData *view_data; - - LOCK_PROPS (); - - view_data = g_hash_table_lookup (data_model->priv->views, client); - - if (view_data) { - NotifyRemoveComponentsData nrc_data; - - view_data_lock (view_data); - - nrc_data.data_model = data_model; - nrc_data.client = client; - - cal_data_model_freeze_all_subscribers (data_model); - - g_hash_table_foreach (view_data->components, - cal_data_model_notify_remove_components_cb, &nrc_data); - g_hash_table_remove_all (view_data->components); - - cal_data_model_thaw_all_subscribers (data_model); - - if (view_data->view) - cal_data_model_emit_view_state_changed (data_model, view_data->view, E_CAL_DATA_MODEL_VIEW_STATE_STOP, 0, NULL, NULL); - - view_data->is_used = FALSE; - view_data_unlock (view_data); - - g_hash_table_remove (data_model->priv->views, client); - } - - UNLOCK_PROPS (); -} - -static gboolean -cal_data_model_add_to_subscriber (ECalDataModel *data_model, - ECalClient *client, - const ECalComponentId *id, - ECalComponent *component, - time_t instance_start, - time_t instance_end, - gpointer user_data) -{ - ECalDataModelSubscriber *subscriber = user_data; - - g_return_val_if_fail (subscriber != NULL, FALSE); - g_return_val_if_fail (id != NULL, FALSE); - - e_cal_data_model_subscriber_component_added (subscriber, client, component); - - return TRUE; -} - -static gboolean -cal_data_model_add_to_subscriber_except_its_range (ECalDataModel *data_model, - ECalClient *client, - const ECalComponentId *id, - ECalComponent *component, - time_t instance_start, - time_t instance_end, - gpointer user_data) -{ - SubscriberData *subs_data = user_data; - - g_return_val_if_fail (subs_data != NULL, FALSE); - g_return_val_if_fail (id != NULL, FALSE); - - /* subs_data should have set the old time range, which - means only components which didn't fit into the old - time range will be added */ - if (!(instance_start <= subs_data->range_end && - instance_end >= subs_data->range_start)) - e_cal_data_model_subscriber_component_added (subs_data->subscriber, client, component); - - return TRUE; -} - -static gboolean -cal_data_model_remove_from_subscriber_except_its_range (ECalDataModel *data_model, - ECalClient *client, - const ECalComponentId *id, - ECalComponent *component, - time_t instance_start, - time_t instance_end, - gpointer user_data) -{ - SubscriberData *subs_data = user_data; - - g_return_val_if_fail (subs_data != NULL, FALSE); - g_return_val_if_fail (id != NULL, FALSE); - - /* subs_data should have set the new time range, which - means only components which don't fit into this new - time range will be removed */ - if (!(instance_start <= subs_data->range_end && - instance_end >= subs_data->range_start)) - e_cal_data_model_subscriber_component_removed (subs_data->subscriber, client, id->uid, id->rid); - - return TRUE; -} - -static void -cal_data_model_set_client_default_zone_cb (gpointer key, - gpointer value, - gpointer user_data) -{ - ECalClient *client = value; - icaltimezone *zone = user_data; - - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (zone != NULL); - - e_cal_client_set_default_timezone (client, zone); -} - -static void -cal_data_model_rebuild_everything (ECalDataModel *data_model, - gboolean complete_rebuild) -{ - GHashTableIter iter; - gpointer key, value; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - if (data_model->priv->views_update_freeze > 0) { - data_model->priv->views_update_required = TRUE; - UNLOCK_PROPS (); - return; - } - - data_model->priv->views_update_required = FALSE; - - g_hash_table_iter_init (&iter, data_model->priv->clients); - while (g_hash_table_iter_next (&iter, &key, &value)) { - ECalClient *client = value; - - if (complete_rebuild) - cal_data_model_remove_client_view (data_model, client); - cal_data_model_update_client_view (data_model, client); - } - - UNLOCK_PROPS (); -} - -static void -cal_data_model_update_time_range (ECalDataModel *data_model) -{ - time_t range_start, range_end; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - if (data_model->priv->disposing) { - UNLOCK_PROPS (); - - return; - } - - range_start = data_model->priv->range_start; - range_end = data_model->priv->range_end; - - cal_data_model_calc_range (data_model, &range_start, &range_end); - - if (data_model->priv->range_start != range_start || - data_model->priv->range_end != range_end) { - data_model->priv->range_start = range_start; - data_model->priv->range_end = range_end; - - if (cal_data_model_update_full_filter (data_model)) - cal_data_model_rebuild_everything (data_model, FALSE); - } - - UNLOCK_PROPS (); -} - -static void -cal_data_model_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EXPAND_RECURRENCES: - e_cal_data_model_set_expand_recurrences ( - E_CAL_DATA_MODEL (object), - g_value_get_boolean (value)); - return; - - case PROP_TIMEZONE: - e_cal_data_model_set_timezone ( - E_CAL_DATA_MODEL (object), - g_value_get_pointer (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cal_data_model_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_EXPAND_RECURRENCES: - g_value_set_boolean ( - value, - e_cal_data_model_get_expand_recurrences ( - E_CAL_DATA_MODEL (object))); - return; - - case PROP_TIMEZONE: - g_value_set_pointer ( - value, - e_cal_data_model_get_timezone ( - E_CAL_DATA_MODEL (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -cal_data_model_dispose (GObject *object) -{ - ECalDataModel *data_model = E_CAL_DATA_MODEL (object); - - data_model->priv->disposing = TRUE; - - /* Chain up to parent's method. */ - G_OBJECT_CLASS (e_cal_data_model_parent_class)->dispose (object); -} - -static void -cal_data_model_finalize (GObject *object) -{ - ECalDataModel *data_model = E_CAL_DATA_MODEL (object); - - g_thread_pool_free (data_model->priv->thread_pool, TRUE, FALSE); - g_hash_table_destroy (data_model->priv->clients); - g_hash_table_destroy (data_model->priv->views); - g_slist_free_full (data_model->priv->subscribers, subscriber_data_free); - g_free (data_model->priv->filter); - g_free (data_model->priv->full_filter); - - e_weak_ref_free (data_model->priv->submit_thread_job_responder); - g_rec_mutex_clear (&data_model->priv->props_lock); - - /* Chain up to parent's method. */ - G_OBJECT_CLASS (e_cal_data_model_parent_class)->finalize (object); -} - -static void -e_cal_data_model_class_init (ECalDataModelClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ECalDataModelPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = cal_data_model_set_property; - object_class->get_property = cal_data_model_get_property; - object_class->dispose = cal_data_model_dispose; - object_class->finalize = cal_data_model_finalize; - - g_object_class_install_property ( - object_class, - PROP_EXPAND_RECURRENCES, - g_param_spec_boolean ( - "expand-recurrences", - "Expand Recurrences", - NULL, - FALSE, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, - PROP_TIMEZONE, - g_param_spec_pointer ( - "timezone", - "Time Zone", - NULL, - G_PARAM_READWRITE)); - - signals[VIEW_STATE_CHANGED] = g_signal_new ( - "view-state-changed", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalDataModelClass, view_state_changed), - NULL, NULL, - NULL, - G_TYPE_NONE, 5, E_TYPE_CAL_CLIENT_VIEW, G_TYPE_UINT, G_TYPE_UINT, G_TYPE_STRING, G_TYPE_ERROR); -} - -static void -e_cal_data_model_init (ECalDataModel *data_model) -{ - data_model->priv = G_TYPE_INSTANCE_GET_PRIVATE (data_model, E_TYPE_CAL_DATA_MODEL, ECalDataModelPrivate); - - /* Suppose the data_model is always created in the main/UI thread */ - data_model->priv->main_thread = g_thread_self (); - data_model->priv->thread_pool = g_thread_pool_new ( - cal_data_model_internal_thread_job_func, data_model, 5, FALSE, NULL); - - data_model->priv->clients = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref); - data_model->priv->views = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, view_data_unref); - data_model->priv->subscribers = NULL; - - data_model->priv->disposing = FALSE; - data_model->priv->expand_recurrences = FALSE; - data_model->priv->zone = icaltimezone_get_utc_timezone (); - - data_model->priv->views_update_freeze = 0; - data_model->priv->views_update_required = FALSE; - - g_rec_mutex_init (&data_model->priv->props_lock); -} - -/** - * e_cal_data_model_new: - * @func: a function to be called when the data model needs to create - * a thread job within UI - * @func_responder: (allow none): a responder for @func, which is passed - * as the first paramter; can be #NULL - * - * Creates a new instance of #ECalDataModel. The @func is mandatory, because - * it is used to create new thread jobs with UI feedback. - * - * Returns: (transfer full): A new #ECalDataModel instance - * - * Since: 3.16 - **/ -ECalDataModel * -e_cal_data_model_new (ECalDataModelSubmitThreadJobFunc func, - GObject *func_responder) -{ - ECalDataModel *data_model; - - g_return_val_if_fail (func != NULL, NULL); - - data_model = g_object_new (E_TYPE_CAL_DATA_MODEL, NULL); - data_model->priv->submit_thread_job_func = func; - data_model->priv->submit_thread_job_responder = e_weak_ref_new (func_responder); - - return data_model; -} - -/** - * e_cal_data_model_new_clone: - * @src_data_model: an #ECalDataModel to clone - * - * Creates a clone of @src_data_model, which means a copy with the same clients, filter and - * other properties set (not the subscribers). - * - * Returns: (transfer full): A new #ECalDataModel instance deriving settings from @src_data_model - * - * Since: 3.16 - **/ -ECalDataModel * -e_cal_data_model_new_clone (ECalDataModel *src_data_model) -{ - ECalDataModel *clone; - GObject *func_responder; - GList *clients, *link; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (src_data_model), NULL); - - func_responder = g_weak_ref_get (src_data_model->priv->submit_thread_job_responder); - g_return_val_if_fail (func_responder != NULL, NULL); - - clone = e_cal_data_model_new (src_data_model->priv->submit_thread_job_func, func_responder); - - g_clear_object (&func_responder); - - e_cal_data_model_set_expand_recurrences (clone, e_cal_data_model_get_expand_recurrences (src_data_model)); - e_cal_data_model_set_timezone (clone, e_cal_data_model_get_timezone (src_data_model)); - e_cal_data_model_set_filter (clone, src_data_model->priv->filter); - - clients = e_cal_data_model_get_clients (src_data_model); - for (link = clients; link; link = g_list_next (link)) { - ECalClient *client = link->data; - - e_cal_data_model_add_client (clone, client); - } - - g_list_free_full (clients, g_object_unref); - - return clone; -} - -/** - * e_cal_data_model_get_disposing: - * @data_model: an #EDataModel instance - * - * Obtains whether the @data_model is disposing and will be freed (soon). - * - * Returns: Whether the @data_model is disposing. - * - * Since: 3.16 - **/ -gboolean -e_cal_data_model_get_disposing (ECalDataModel *data_model) -{ - gboolean disposing; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - - LOCK_PROPS (); - - disposing = data_model->priv->disposing; - - UNLOCK_PROPS (); - - return disposing; -} - -/** - * e_cal_data_model_set_disposing: - * @data_model: an #EDataModel instance - * @disposing: whether the object is disposing - * - * Sets whether the @data_model is disposing itself (soon). - * If set to %TRUE, then no updates are done on changes - * which would otherwise trigger view and subscriber updates. - * - * Since: 3.16 - **/ -void -e_cal_data_model_set_disposing (ECalDataModel *data_model, - gboolean disposing) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - if ((data_model->priv->disposing ? 1 : 0) == (disposing ? 1 : 0)) { - UNLOCK_PROPS (); - return; - } - - data_model->priv->disposing = disposing; - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_get_expand_recurrences: - * @data_model: an #EDataModel instance - * - * Obtains whether the @data_model expands recurrences of recurring - * components by default. The default value is #FALSE, to not expand - * recurrences. - * - * Returns: Whether the @data_model expands recurrences of recurring - * components. - * - * Since: 3.16 - **/ -gboolean -e_cal_data_model_get_expand_recurrences (ECalDataModel *data_model) -{ - gboolean expand_recurrences; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - - LOCK_PROPS (); - - expand_recurrences = data_model->priv->expand_recurrences; - - UNLOCK_PROPS (); - - return expand_recurrences; -} - -/** - * e_cal_data_model_set_expand_recurrences: - * @data_model: an #EDataModel instance - * @expand_recurrences: whether to expand recurrences - * - * Sets whether the @data_model should expand recurrences of recurring - * components by default. - * - * Since: 3.16 - **/ -void -e_cal_data_model_set_expand_recurrences (ECalDataModel *data_model, - gboolean expand_recurrences) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - if ((data_model->priv->expand_recurrences ? 1 : 0) == (expand_recurrences ? 1 : 0)) { - UNLOCK_PROPS (); - return; - } - - data_model->priv->expand_recurrences = expand_recurrences; - - cal_data_model_rebuild_everything (data_model, TRUE); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_get_timezone: - * @data_model: an #EDataModel instance - * - * Obtains a timezone being used for calendar views. The returned - * timezone is owned by the @data_model. - * - * Returns: (transfer none): An #icaltimezone being used for calendar views. - * - * Since: 3.16 - **/ -icaltimezone * -e_cal_data_model_get_timezone (ECalDataModel *data_model) -{ - icaltimezone *zone; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - - LOCK_PROPS (); - - zone = data_model->priv->zone; - - UNLOCK_PROPS (); - - return zone; -} -/** - * e_cal_data_model_set_timezone: - * @data_model: an #EDataModel instance - * @zone: an #icaltimezone - * - * Sets a trimezone to be used for calendar views. This change - * regenerates all views. - * - * Since: 3.16 - **/ -void -e_cal_data_model_set_timezone (ECalDataModel *data_model, - icaltimezone *zone) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (zone != NULL); - - LOCK_PROPS (); - - if (data_model->priv->zone != zone) { - data_model->priv->zone = zone; - - g_hash_table_foreach (data_model->priv->clients, cal_data_model_set_client_default_zone_cb, zone); - - if (cal_data_model_update_full_filter (data_model)) - cal_data_model_rebuild_everything (data_model, TRUE); - } - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_set_filter: - * @data_model: an #EDataModel instance - * @sexp: an expression defining a filter - * - * Sets an additional filter for the views. The filter should not - * contain time constraints, these are meant to be defined by - * subscribers. - * - * Since: 3.16 - **/ -void -e_cal_data_model_set_filter (ECalDataModel *data_model, - const gchar *sexp) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (sexp != NULL); - - LOCK_PROPS (); - - if (sexp && !*sexp) - sexp = NULL; - - if (g_strcmp0 (data_model->priv->filter, sexp) != 0) { - g_free (data_model->priv->filter); - data_model->priv->filter = g_strdup (sexp); - - if (cal_data_model_update_full_filter (data_model)) - cal_data_model_rebuild_everything (data_model, TRUE); - } - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_dup_filter: - * @data_model: an #EDataModel instance - * - * Obtains currently used filter (an expression) for the views. - * - * Returns: (transfer full): A copy of the currently used - * filter for views. Free it with g_free() when done with it. - * Returns #NULL when there is no extra filter set. - * - * Since: 3.16 - **/ -gchar * -e_cal_data_model_dup_filter (ECalDataModel *data_model) -{ - gchar *filter; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - - LOCK_PROPS (); - - filter = g_strdup (data_model->priv->filter); - - UNLOCK_PROPS (); - - return filter; -} - -/** - * e_cal_data_model_add_client: - * @data_model: an #EDataModel instance - * @client: an #ECalClient - * - * Adds a new @client into the set of clients which should be used - * to populate data for subscribers. Adding the same client multiple - * times does nothing. - * - * Since: 3.16 - **/ -void -e_cal_data_model_add_client (ECalDataModel *data_model, - ECalClient *client) -{ - ESource *source; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - - source = e_client_get_source (E_CLIENT (client)); - g_return_if_fail (E_IS_SOURCE (source)); - g_return_if_fail (e_source_get_uid (source) != NULL); - - LOCK_PROPS (); - - if (g_hash_table_contains (data_model->priv->clients, e_source_get_uid (source))) { - UNLOCK_PROPS (); - return; - } - - g_hash_table_insert (data_model->priv->clients, e_source_dup_uid (source), g_object_ref (client)); - - e_cal_client_set_default_timezone (client, data_model->priv->zone); - - cal_data_model_update_client_view (data_model, client); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_remove_client: - * @uid: a UID of a client to remove - * - * Removes a client identified by @uid from a set of clients - * which populate the data for subscribers. Removing the client - * which is not used in the @data_model does nothing. - * - * Since: 3.16 - **/ -void -e_cal_data_model_remove_client (ECalDataModel *data_model, - const gchar *uid) -{ - ECalClient *client; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (uid != NULL); - - LOCK_PROPS (); - - client = g_hash_table_lookup (data_model->priv->clients, uid); - if (!client) { - UNLOCK_PROPS (); - return; - } - - cal_data_model_remove_client_view (data_model, client); - g_hash_table_remove (data_model->priv->clients, uid); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_ref_client: - * @data_model: an #EDataModel instance - * @uid: a UID of a client to return - * - * Obtains an #ECalClient with given @uid from the set of clients - * being used by the @data_modal. Returns #NULL, if no such client - * is used by the @data_model. - * - * Returns: (tranfer full): An #ECalClient with given @uid being - * used by @data_model, or NULL, when no such is used by - * the @data_model. Unref returned (non-NULL) client with - * g_object_unref() when done with it. - * - * Since: 3.16 - **/ -ECalClient * -e_cal_data_model_ref_client (ECalDataModel *data_model, - const gchar *uid) -{ - ECalClient *client; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - - LOCK_PROPS (); - - client = g_hash_table_lookup (data_model->priv->clients, uid); - if (client) - g_object_ref (client); - - UNLOCK_PROPS (); - - return client; -} - -/** - * e_cal_data_model_get_clients: - * @data_model: an #EDataModel instance - * - * Obtains a list of all clients being used by the @data_model. - * Each client in the returned list is referenced and the list - * itself is also newly allocated, thus free it with - * g_list_free_full (list, g_object_unref); when done with it. - * - * Returns: (transfer full): A list of currently used #ECalClient-s. - * - * Since: 3.16 - **/ -GList * -e_cal_data_model_get_clients (ECalDataModel *data_model) -{ - GList *clients; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - - LOCK_PROPS (); - - clients = g_hash_table_get_values (data_model->priv->clients); - g_list_foreach (clients, (GFunc) g_object_ref, NULL); - - UNLOCK_PROPS (); - - return clients; -} - -static gboolean -cal_data_model_prepend_component (ECalDataModel *data_model, - ECalClient *client, - const ECalComponentId *id, - ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer user_data) -{ - GSList **components = user_data; - - g_return_val_if_fail (components != NULL, FALSE); - g_return_val_if_fail (comp != NULL, FALSE); - - *components = g_slist_prepend (*components, g_object_ref (comp)); - - return TRUE; -} - -/** - * e_cal_data_model_get_components: - * @data_model: an #EDataModel instance - * @in_range_start: Start of the time range - * @in_range_end: End of the time range - * - * Obtains a list of components from the given time range. The time range is - * clamp by the actual time range defined by subscribers (if there is no - * subscriber, or all subscribers define times out of the given time range, - * then no components are returned). - * - * Returns: (transfer full): A #GSList of #ECalComponent-s known for the given - * time range in the time of the call. The #GSList, togher with the components, - * is owned by the caller, which should free it with - * g_slist_free_full (list, g_object_unref); when done with it. - * - * Note: A special case when both @in_range_start and @in_range_end are zero - * is treated as a request for all known components. - * - * Since: 3.16 - **/ -GSList * -e_cal_data_model_get_components (ECalDataModel *data_model, - time_t in_range_start, - time_t in_range_end) -{ - GSList *components = NULL; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); - - e_cal_data_model_foreach_component (data_model, in_range_start, in_range_end, - cal_data_model_prepend_component, &components); - - return g_slist_reverse (components); -} - -static gboolean -cal_data_model_foreach_component (ECalDataModel *data_model, - time_t in_range_start, - time_t in_range_end, - ECalDataModelForeachFunc func, - gpointer user_data, - gboolean include_lost_components) -{ - GHashTableIter viter; - gpointer key, value; - gboolean checked_all = TRUE; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - LOCK_PROPS (); - - /* Is the given time range in the currently used time range? */ - if (!(in_range_start == in_range_end && in_range_start == (time_t) 0) && - (in_range_start >= data_model->priv->range_end || - in_range_end <= data_model->priv->range_start)) { - UNLOCK_PROPS (); - return checked_all; - } - - g_hash_table_iter_init (&viter, data_model->priv->views); - while (checked_all && g_hash_table_iter_next (&viter, &key, &value)) { - ViewData *view_data = value; - GHashTableIter citer; - - if (!view_data) - continue; - - view_data_lock (view_data); - - g_hash_table_iter_init (&citer, view_data->components); - while (checked_all && g_hash_table_iter_next (&citer, &key, &value)) { - ECalComponentId *id = key; - ComponentData *comp_data = value; - - if (!comp_data) - continue; - - if ((in_range_start == in_range_end && in_range_start == (time_t) 0) || - (comp_data->instance_start < in_range_end && - comp_data->instance_end > in_range_start)) { - if (!func (data_model, view_data->client, id, comp_data->component, - comp_data->instance_start, comp_data->instance_end, user_data)) - checked_all = FALSE; - } - } - - if (include_lost_components && view_data->lost_components) { - g_hash_table_iter_init (&citer, view_data->lost_components); - while (checked_all && g_hash_table_iter_next (&citer, &key, &value)) { - ECalComponentId *id = key; - ComponentData *comp_data = value; - - if (!comp_data) - continue; - - if ((in_range_start == in_range_end && in_range_start == (time_t) 0) || - (comp_data->instance_start < in_range_end && - comp_data->instance_end > in_range_start)) { - if (!func (data_model, view_data->client, id, comp_data->component, - comp_data->instance_start, comp_data->instance_end, user_data)) - checked_all = FALSE; - } - } - } - - view_data_unlock (view_data); - } - - UNLOCK_PROPS (); - - return checked_all; -} - -/** - * e_cal_data_model_foreach_component: - * @data_model: an #EDataModel instance - * @in_range_start: Start of the time range - * @in_range_end: End of the time range - * @func: a function to be called for each component in the given time range - * @user_data: user data being passed into the @func - * - * Calls @func for each component in the given time range. The time range is - * clamp by the actual time range defined by subscribers (if there is no - * subscriber, or all subscribers define times out of the given time range, - * then the function is not called at all and a #FALSE is returned). - * - * The @func returns #TRUE to continue the traversal. If it wants to stop - * the traversal earlier, then it returns #FALSE. - * - * Returns: Whether all the components were checked. The returned value is - * usually #TRUE, unless the @func stops traversal earlier. - * - * Note: A special case when both @in_range_start and @in_range_end are zero - * is treated as a request for all known components. - * - * Since: 3.16 - **/ -gboolean -e_cal_data_model_foreach_component (ECalDataModel *data_model, - time_t in_range_start, - time_t in_range_end, - ECalDataModelForeachFunc func, - gpointer user_data) -{ - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - g_return_val_if_fail (func != NULL, FALSE); - - return cal_data_model_foreach_component (data_model, in_range_start, in_range_end, func, user_data, FALSE); -} - -/** - * e_cal_data_model_subscribe: - * @data_model: an #EDataModel instance - * @subscriber: an #ECalDataModelSubscriber instance - * @range_start: Start of the time range used by the @subscriber - * @range_end: End of the time range used by the @subscriber - * - * Either adds a new @subscriber to the set of subscribers for this - * @data_model, or changes a time range used by the @subscriber, - * in case it was added to the @data_model earlier. - * - * Reference count of the @subscriber is increased by one, in case - * it is newly added. The reference count is decreased by one - * when e_cal_data_model_unsubscribe() is called. - * - * Note: A special case when both @range_start and @range_end are zero - * is treated as a request with no time constraint. This limits - * the result only to those components which satisfy given filter. - * - * Since: 3.16 - **/ -void -e_cal_data_model_subscribe (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber, - time_t range_start, - time_t range_end) -{ - SubscriberData *subs_data = NULL; - GSList *link; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - - LOCK_PROPS (); - - for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) { - SubscriberData *subs_data = link->data; - - if (!subs_data) - continue; - - if (subs_data->subscriber == subscriber) - break; - } - - if (link != NULL) { - time_t new_range_start = range_start, new_range_end = range_end; - time_t old_range_start, old_range_end; - - /* The subscriber updates its time range (it is already known) */ - subs_data = link->data; - - /* No range change */ - if (range_start == subs_data->range_start && - range_end == subs_data->range_end) { - UNLOCK_PROPS (); - return; - } - - old_range_start = subs_data->range_start; - old_range_end = subs_data->range_end; - - if (new_range_start == (time_t) 0 && new_range_end == (time_t) 0) { - new_range_start = data_model->priv->range_start; - new_range_end = data_model->priv->range_end; - } - - if (new_range_start == (time_t) 0 && new_range_end == (time_t) 0) { - /* The subscriber is looking for everything and the data_model has everything too */ - e_cal_data_model_subscriber_freeze (subs_data->subscriber); - cal_data_model_foreach_component (data_model, - new_range_start, old_range_start, - cal_data_model_add_to_subscriber_except_its_range, subs_data, TRUE); - e_cal_data_model_subscriber_thaw (subs_data->subscriber); - } else { - e_cal_data_model_subscriber_freeze (subs_data->subscriber); - - if (new_range_start >= old_range_end || - new_range_end <= old_range_start) { - subs_data->range_start = range_start; - subs_data->range_end = range_end; - - /* Completely new range, not overlapping with the former range, - everything previously added can be removed... */ - cal_data_model_foreach_component (data_model, - old_range_start, old_range_end, - cal_data_model_remove_from_subscriber_except_its_range, subs_data, TRUE); - - subs_data->range_start = old_range_start; - subs_data->range_end = old_range_end; - - /* ...and components from the new range can be added */ - cal_data_model_foreach_component (data_model, - new_range_start, new_range_end, - cal_data_model_add_to_subscriber_except_its_range, subs_data, TRUE); - } else { - if (new_range_start < old_range_start) { - /* Add those known in the new extended range from the start */ - cal_data_model_foreach_component (data_model, - new_range_start, old_range_start, - cal_data_model_add_to_subscriber_except_its_range, subs_data, TRUE); - } else if (new_range_start > old_range_start) { - subs_data->range_start = range_start; - subs_data->range_end = range_end; - - /* Remove those out of the new range from the start */ - cal_data_model_foreach_component (data_model, - old_range_start, new_range_start, - cal_data_model_remove_from_subscriber_except_its_range, subs_data, TRUE); - - subs_data->range_start = old_range_start; - subs_data->range_end = old_range_end; - } - - if (new_range_end > old_range_end) { - /* Add those known in the new extended range from the end */ - cal_data_model_foreach_component (data_model, - old_range_end, new_range_end, - cal_data_model_add_to_subscriber_except_its_range, subs_data, TRUE); - } else if (new_range_end < old_range_end) { - subs_data->range_start = range_start; - subs_data->range_end = range_end; - - /* Remove those out of the new range from the end */ - cal_data_model_foreach_component (data_model, - new_range_end, old_range_end, - cal_data_model_remove_from_subscriber_except_its_range, subs_data, TRUE); - - subs_data->range_start = old_range_start; - subs_data->range_end = old_range_end; - } - } - - e_cal_data_model_subscriber_thaw (subs_data->subscriber); - } - - subs_data->range_start = range_start; - subs_data->range_end = range_end; - } else { - subs_data = subscriber_data_new (subscriber, range_start, range_end); - - data_model->priv->subscribers = g_slist_prepend (data_model->priv->subscribers, subs_data); - - e_cal_data_model_subscriber_freeze (subscriber); - cal_data_model_foreach_component (data_model, range_start, range_end, - cal_data_model_add_to_subscriber, subscriber, TRUE); - e_cal_data_model_subscriber_thaw (subscriber); - } - - cal_data_model_update_time_range (data_model); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_unsubscribe: - * @data_model: an #EDataModel instance - * @subscriber: an #ECalDataModelSubscriber instance - * - * Removes the @subscriber from the set of subscribers for the @data_model. - * Remove of the @subscriber, which is not in the set of subscribers for - * the @data_model does nothing. - * - * Note: The @subscriber is not notified about a removal of the components - * which could be added previously, while it was subscribed for the change - * notifications. - * - * Since: 3.16 - **/ -void -e_cal_data_model_unsubscribe (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber) -{ - GSList *link; - - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - - LOCK_PROPS (); - - for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) { - SubscriberData *subs_data = link->data; - - if (!subs_data) - continue; - - if (subs_data->subscriber == subscriber) { - data_model->priv->subscribers = g_slist_remove (data_model->priv->subscribers, subs_data); - subscriber_data_free (subs_data); - break; - } - } - - cal_data_model_update_time_range (data_model); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_get_subscriber_range: - * @data_model: an #EDataModel instance - * @subscriber: an #ECalDataModelSubscriber instance - * @range_start: (out): time range start for the @subscriber - * @range_end: (out): time range end for the @subscriber - * - * Obtains currently set time range for the @subscriber. In case - * the subscriber is not found returns #FALSE and both @range_start - * and @range_end are left untouched. - * - * Returns: Whether the @subscriber was found and the @range_start with - * the @range_end were set to its current time range it uses. - * - * Since: 3.16 - **/ -gboolean -e_cal_data_model_get_subscriber_range (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber, - time_t *range_start, - time_t *range_end) -{ - GSList *link; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - g_return_val_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber), FALSE); - g_return_val_if_fail (range_start, FALSE); - g_return_val_if_fail (range_end, FALSE); - - LOCK_PROPS (); - - for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) { - SubscriberData *subs_data = link->data; - - if (!subs_data) - continue; - - if (subs_data->subscriber == subscriber) { - *range_start = subs_data->range_start; - *range_end = subs_data->range_end; - break; - } - } - - UNLOCK_PROPS (); - - return link != NULL; -} - -/** - * e_cal_data_model_freeze_views_update: - * @data_model: an #EDataModel instance - * - * Freezes any views updates until e_cal_data_model_thaw_views_update() is - * called. This can be called nested, then the same count of the calls of - * e_cal_data_model_thaw_views_update() is expected to unlock the views update. - * - * Since: 3.16 - **/ -void -e_cal_data_model_freeze_views_update (ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - data_model->priv->views_update_freeze++; - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_thaw_views_update: - * @data_model: an #EDataModel instance - * - * A pair function for e_cal_data_model_freeze_views_update(), to unlock - * views update. - * - * Since: 3.16 - **/ -void -e_cal_data_model_thaw_views_update (ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - - LOCK_PROPS (); - - if (!data_model->priv->views_update_freeze) { - UNLOCK_PROPS (); - g_warn_if_reached (); - return; - } - - data_model->priv->views_update_freeze--; - if (data_model->priv->views_update_freeze == 0 && - data_model->priv->views_update_required) - cal_data_model_rebuild_everything (data_model, TRUE); - - UNLOCK_PROPS (); -} - -/** - * e_cal_data_model_is_views_update_frozen: - * @data_model: an #EDataModel instance - * - * Check whether any views updates are currently frozen. This is influenced by - * e_cal_data_model_freeze_views_update() and e_cal_data_model_thaw_views_update(). - * - * Returns: Whether any views updates are currently frozen. - * - * Since: 3.16 - **/ -gboolean -e_cal_data_model_is_views_update_frozen (ECalDataModel *data_model) -{ - gboolean is_frozen; - - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE); - - LOCK_PROPS (); - - is_frozen = data_model->priv->views_update_freeze > 0; - - UNLOCK_PROPS (); - - return is_frozen; -} diff -Nru evolution-3.16.0/calendar/gui/e-cal-data-model.h evolution-3.12.11/calendar/gui/e-cal-data-model.h --- evolution-3.16.0/calendar/gui/e-cal-data-model.h 2014-10-14 15:03:53.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-data-model.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,157 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifndef E_CAL_DATA_MODEL_H -#define E_CAL_DATA_MODEL_H - -#include -#include - -#include "e-cal-data-model-subscriber.h" - -/* Standard GObject macros */ -#define E_TYPE_CAL_DATA_MODEL \ - (e_cal_data_model_get_type ()) -#define E_CAL_DATA_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CAL_DATA_MODEL, ECalDataModel)) -#define E_CAL_DATA_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CAL_DATA_MODEL, ECalDataModelClass)) -#define E_IS_CAL_DATA_MODEL(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CAL_DATA_MODEL)) -#define E_IS_CAL_DATA_MODEL_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CAL_DATA_MODEL)) -#define E_CAL_DATA_MODEL_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_CAL_DATA_MODEL, ECalDataModelClass)) - -G_BEGIN_DECLS - -typedef enum { - E_CAL_DATA_MODEL_VIEW_STATE_START, - E_CAL_DATA_MODEL_VIEW_STATE_PROGRESS, - E_CAL_DATA_MODEL_VIEW_STATE_COMPLETE, - E_CAL_DATA_MODEL_VIEW_STATE_STOP -} ECalDataModelViewState; - -typedef struct _ECalDataModel ECalDataModel; -typedef struct _ECalDataModelClass ECalDataModelClass; -typedef struct _ECalDataModelPrivate ECalDataModelPrivate; - -struct _ECalDataModel { - GObject parent; - ECalDataModelPrivate *priv; -}; - -struct _ECalDataModelClass { - GObjectClass parent_class; - - /* Signals */ - void (* view_state_changed) (ECalDataModel *data_model, - ECalClientView *view, - ECalDataModelViewState state, - guint percent, - const gchar *message, - const GError *error); -}; - -typedef GCancellable * (* ECalDataModelSubmitThreadJobFunc) - (GObject *responder, - const gchar *description, - const gchar *alert_ident, - const gchar *alert_arg_0, - EAlertSinkThreadJobFunc func, - gpointer user_data, - GDestroyNotify free_user_data); - -GType e_cal_data_model_get_type (void); -ECalDataModel * e_cal_data_model_new (ECalDataModelSubmitThreadJobFunc func, - GObject *func_responder); -ECalDataModel * e_cal_data_model_new_clone (ECalDataModel *src_data_model); -GCancellable * e_cal_data_model_submit_thread_job - (ECalDataModel *data_model, - const gchar *description, - const gchar *alert_ident, - const gchar *alert_arg_0, - EAlertSinkThreadJobFunc func, - gpointer user_data, - GDestroyNotify free_user_data); -gboolean e_cal_data_model_get_disposing (ECalDataModel *data_model); -void e_cal_data_model_set_disposing (ECalDataModel *data_model, - gboolean disposing); -gboolean e_cal_data_model_get_expand_recurrences - (ECalDataModel *data_model); -void e_cal_data_model_set_expand_recurrences - (ECalDataModel *data_model, - gboolean expand_recurrences); -icaltimezone * e_cal_data_model_get_timezone (ECalDataModel *data_model); -void e_cal_data_model_set_timezone (ECalDataModel *data_model, - icaltimezone *zone); -void e_cal_data_model_set_filter (ECalDataModel *data_model, - const gchar *sexp); -gchar * e_cal_data_model_dup_filter (ECalDataModel *data_model); -void e_cal_data_model_add_client (ECalDataModel *data_model, - ECalClient *client); -void e_cal_data_model_remove_client (ECalDataModel *data_model, - const gchar *uid); -ECalClient * e_cal_data_model_ref_client (ECalDataModel *data_model, - const gchar *uid); -GList * e_cal_data_model_get_clients (ECalDataModel *data_model); -GSList * e_cal_data_model_get_components (ECalDataModel *data_model, - time_t in_range_start, - time_t in_range_end); - -typedef gboolean (* ECalDataModelForeachFunc) (ECalDataModel *data_model, - ECalClient *client, - const ECalComponentId *id, - ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer user_data); - -gboolean e_cal_data_model_foreach_component - (ECalDataModel *data_model, - time_t in_range_start, - time_t in_range_end, - ECalDataModelForeachFunc func, - gpointer user_data); - -void e_cal_data_model_subscribe (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber, - time_t range_start, - time_t range_end); -void e_cal_data_model_unsubscribe (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber); -gboolean e_cal_data_model_get_subscriber_range - (ECalDataModel *data_model, - ECalDataModelSubscriber *subscriber, - time_t *range_start, - time_t *range_end); -void e_cal_data_model_freeze_views_update - (ECalDataModel *data_model); -void e_cal_data_model_thaw_views_update - (ECalDataModel *data_model); -gboolean e_cal_data_model_is_views_update_frozen - (ECalDataModel *data_model); - -G_END_DECLS - -#endif /* E_CAL_DATA_MODEL_H */ diff -Nru evolution-3.16.0/calendar/gui/e-cal-data-model-subscriber.c evolution-3.12.11/calendar/gui/e-cal-data-model-subscriber.c --- evolution-3.16.0/calendar/gui/e-cal-data-model-subscriber.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-data-model-subscriber.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "e-cal-data-model-subscriber.h" - -G_DEFINE_INTERFACE (ECalDataModelSubscriber, e_cal_data_model_subscriber, G_TYPE_OBJECT) - -static void -e_cal_data_model_subscriber_default_init (ECalDataModelSubscriberInterface *iface) -{ -} - -/** - * e_cal_data_model_subscriber_component_added: - * @subscriber: an #ECalDataModelSubscriber - * @client: an #ECalClient, which notifies about the component addition - * @icalcomp: an #ECalComponent which was added - * - * Notifies the @subscriber about an added component which belongs - * to the time range used by the @subscriber. - * - * Note: The @subscriber can be frozen during these calls, to be able - * to cumulate multiple changes and propagate them at once. - **/ -void -e_cal_data_model_subscriber_component_added (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - ECalDataModelSubscriberInterface *iface; - - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - iface = E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE (subscriber); - g_return_if_fail (iface->component_added != NULL); - - iface->component_added (subscriber, client, comp); -} - -/** - * e_cal_data_model_subscriber_component_modified: - * @subscriber: an #ECalDataModelSubscriber - * @client: an #ECalClient, which notifies about the component modification - * @comp: an #ECalComponent which was modified - * - * Notifies the @subscriber about a modified component which belongs - * to the time range used by the @subscriber. - * - * Note: The @subscriber can be frozen during these calls, to be able - * to cumulate multiple changes and propagate them at once. - **/ -void -e_cal_data_model_subscriber_component_modified (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - ECalDataModelSubscriberInterface *iface; - - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - g_return_if_fail (E_IS_CAL_COMPONENT (comp)); - - iface = E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE (subscriber); - g_return_if_fail (iface->component_modified != NULL); - - iface->component_modified (subscriber, client, comp); -} - -/** - * e_cal_data_model_subscriber_component_removed: - * @subscriber: an #ECalDataModelSubscriber - * @client: an #ECalClient, which notifies about the component removal - * @uid: UID of a removed component - * @rid: RID of a removed component - * - * Notifies the @subscriber about a removed component identified - * by @uid and @rid. This component may or may not be within - * the time range specified by the @subscriber. - * - * Note: The @subscriber can be frozen during these calls, to be able - * to cumulate multiple changes and propagate them at once. - **/ -void -e_cal_data_model_subscriber_component_removed (ECalDataModelSubscriber *subscriber, - ECalClient *client, - const gchar *uid, - const gchar *rid) -{ - ECalDataModelSubscriberInterface *iface; - - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - - iface = E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE (subscriber); - g_return_if_fail (iface->component_removed != NULL); - - iface->component_removed (subscriber, client, uid, rid); -} - -/** - * e_cal_data_model_subscriber_freeze: - * @subscriber: an #ECalDataModelSubscriber - * - * Tells the @subscriber that it'll be notified about multiple - * changes. Once all the notifications are done, - * a e_cal_data_model_subscriber_thaw() is called. - * - * Note: This function can be called multiple times/recursively, with - * the same count of the e_cal_data_model_subscriber_thaw(), thus - * count with it. - **/ -void -e_cal_data_model_subscriber_freeze (ECalDataModelSubscriber *subscriber) -{ - ECalDataModelSubscriberInterface *iface; - - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - - iface = E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE (subscriber); - g_return_if_fail (iface->freeze != NULL); - - iface->freeze (subscriber); -} - -/** - * e_cal_data_model_subscriber_thaw: - * @subscriber: an #ECalDataModelSubscriber - * - * A pair function for e_cal_data_model_subscriber_freeze(), which notifies - * about the end of a content update. - **/ -void -e_cal_data_model_subscriber_thaw (ECalDataModelSubscriber *subscriber) -{ - ECalDataModelSubscriberInterface *iface; - - g_return_if_fail (E_IS_CAL_DATA_MODEL_SUBSCRIBER (subscriber)); - - iface = E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE (subscriber); - g_return_if_fail (iface->thaw != NULL); - - iface->thaw (subscriber); -} diff -Nru evolution-3.16.0/calendar/gui/e-cal-data-model-subscriber.h evolution-3.12.11/calendar/gui/e-cal-data-model-subscriber.h --- evolution-3.16.0/calendar/gui/e-cal-data-model-subscriber.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-data-model-subscriber.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifndef E_CAL_DATA_MODEL_SUBSCRIBER_H -#define E_CAL_DATA_MODEL_SUBSCRIBER_H - -#include - -/* Standard GObject macros */ -#define E_TYPE_CAL_DATA_MODEL_SUBSCRIBER \ - (e_cal_data_model_subscriber_get_type ()) -#define E_CAL_DATA_MODEL_SUBSCRIBER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, ECalDataModelSubscriber)) -#define E_CAL_DATA_MODEL_SUBSCRIBER_INTERFACE(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, ECalDataModelSubscriberInterface)) -#define E_IS_CAL_DATA_MODEL_SUBSCRIBER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_CAL_DATA_MODEL_SUBSCRIBER)) -#define E_IS_CAL_DATA_MODEL_SUBSCRIBER_INTERFACE(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_CAL_DATA_MODEL_SUBSCRIBER)) -#define E_CAL_DATA_MODEL_SUBSCRIBER_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE \ - ((obj), E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, ECalDataModelSubscriberInterface)) - -G_BEGIN_DECLS - -typedef struct _ECalDataModelSubscriber ECalDataModelSubscriber; -typedef struct _ECalDataModelSubscriberInterface ECalDataModelSubscriberInterface; - -struct _ECalDataModelSubscriberInterface { - GTypeInterface parent_interface; - - void (*component_added) (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp); - void (*component_modified) (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp); - void (*component_removed) (ECalDataModelSubscriber *subscriber, - ECalClient *client, - const gchar *uid, - const gchar *rid); - void (*freeze) (ECalDataModelSubscriber *subscriber); - void (*thaw) (ECalDataModelSubscriber *subscriber); -}; - -GType e_cal_data_model_subscriber_get_type (void) G_GNUC_CONST; -void e_cal_data_model_subscriber_component_added (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp); -void e_cal_data_model_subscriber_component_modified (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp); -void e_cal_data_model_subscriber_component_removed (ECalDataModelSubscriber *subscriber, - ECalClient *client, - const gchar *uid, - const gchar *rid); -void e_cal_data_model_subscriber_freeze (ECalDataModelSubscriber *subscriber); -void e_cal_data_model_subscriber_thaw (ECalDataModelSubscriber *subscriber); - -G_END_DECLS - -#endif /* E_CAL_DATA_MODEL_SUBSCRIBER_H */ diff -Nru evolution-3.16.0/calendar/gui/e-calendar-selector.c evolution-3.12.11/calendar/gui/e-calendar-selector.c --- evolution-3.16.0/calendar/gui/e-calendar-selector.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-calendar-selector.c 2014-07-17 10:48:07.000000000 +0000 @@ -0,0 +1,467 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-calendar-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include + +#include + +#include "e-calendar-selector.h" +#include "comp-util.h" + +#include + +#define E_CALENDAR_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorPrivate)) + +struct _ECalendarSelectorPrivate { + EShellView *shell_view; + + gpointer transfer_alert; /* weak pointer to EAlert */ +}; + +G_DEFINE_TYPE ( + ECalendarSelector, + e_calendar_selector, + E_TYPE_CLIENT_SELECTOR) + +enum { + PROP_0, + PROP_SHELL_VIEW, +}; + +static void +cal_transferring_update_alert (ECalendarSelector *calendar_selector, + EShellView *shell_view, + const gchar *domain, + const gchar *calendar, + const gchar *message) +{ + ECalendarSelectorPrivate *priv; + EShellContent *shell_content; + EAlert *alert; + + g_return_if_fail (calendar_selector != NULL); + g_return_if_fail (calendar_selector->priv != NULL); + + priv = calendar_selector->priv; + + if (priv->transfer_alert) { + e_alert_response ( + priv->transfer_alert, + e_alert_get_default_response (priv->transfer_alert)); + priv->transfer_alert = NULL; + } + + if (!message) + return; + + alert = e_alert_new (domain, calendar, message, NULL); + g_return_if_fail (alert != NULL); + + priv->transfer_alert = alert; + g_object_add_weak_pointer (G_OBJECT (alert), &priv->transfer_alert); + e_alert_start_timer (priv->transfer_alert, 300); + + shell_content = e_shell_view_get_shell_content (shell_view); + e_alert_sink_submit_alert (E_ALERT_SINK (shell_content), priv->transfer_alert); + g_object_unref (priv->transfer_alert); +} + +typedef struct _TransferItemToData { + ESource *destination; + ESourceSelector *selector; + EClient *src_client; + EShellView *shell_view; + EActivity *activity; + icalcomponent *icalcomp; + const gchar *display_name; + gboolean do_copy; +} TransferItemToData; + +static void +transfer_item_to_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + TransferItemToData *titd = user_data; + GError *error = NULL; + GCancellable *cancellable; + gboolean success; + + success = cal_comp_transfer_item_to_finish (E_CAL_CLIENT (source_object), result, &error); + + if (!success) { + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); + } + + cancellable = e_activity_get_cancellable (titd->activity); + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); + + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); +} + +static void +destination_client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EClient *client; + TransferItemToData *titd = user_data; + GCancellable *cancellable; + GError *error = NULL; + + client = e_client_selector_get_client_finish (E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + cancellable = e_activity_get_cancellable (titd->activity); + + if (error != NULL) { + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); + + goto exit; + } + + if (g_cancellable_is_cancelled (cancellable)) + goto exit; + + cal_comp_transfer_item_to ( + E_CAL_CLIENT (titd->src_client), E_CAL_CLIENT (client), + titd->icalcomp, titd->do_copy, cancellable, transfer_item_to_cb, titd); + + return; + +exit: + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); + + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); + +} + +static void +source_client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EClient *client; + TransferItemToData *titd = user_data; + GCancellable *cancellable; + GError *error = NULL; + + client = e_client_selector_get_client_finish (E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + cancellable = e_activity_get_cancellable (titd->activity); + + if (error != NULL) { + cal_transferring_update_alert ( + E_CALENDAR_SELECTOR (titd->selector), + titd->shell_view, + titd->do_copy ? "calendar:failed-copy-event" : "calendar:failed-move-event", + titd->display_name, + error->message); + g_clear_error (&error); + + goto exit; + } + + if (g_cancellable_is_cancelled (cancellable)) + goto exit; + + titd->src_client = client; + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (titd->selector), titd->destination, cancellable, + destination_client_connect_cb, titd); + + return; + +exit: + e_activity_set_state ( + titd->activity, + g_cancellable_is_cancelled (cancellable) ? E_ACTIVITY_CANCELLED : E_ACTIVITY_COMPLETED); + + g_object_unref (titd->activity); + icalcomponent_free (titd->icalcomp); + g_free (titd); +} + +static void +calendar_selector_set_shell_view (ECalendarSelector *selector, + EShellView *shell_view) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + g_return_if_fail (selector->priv->shell_view == NULL); + + selector->priv->shell_view = g_object_ref (shell_view); +} + +static void +calendar_selector_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + calendar_selector_set_shell_view ( + E_CALENDAR_SELECTOR (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +calendar_selector_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + g_value_set_object ( + value, + e_calendar_selector_get_shell_view ( + E_CALENDAR_SELECTOR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +calendar_selector_dispose (GObject *object) +{ + ECalendarSelectorPrivate *priv; + + priv = E_CALENDAR_SELECTOR_GET_PRIVATE (object); + + g_clear_object (&priv->shell_view); + + /* Chain up to the parent' s dispose() method. */ + G_OBJECT_CLASS (e_calendar_selector_parent_class)->dispose (object); +} + +static void +calendar_selector_constructed (GObject *object) +{ + ESourceSelector *selector; + ESourceRegistry *registry; + ESource *source; + + selector = E_SOURCE_SELECTOR (object); + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_default_calendar (registry); + e_source_selector_set_primary_selection (selector, source); + g_object_unref (source); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_calendar_selector_parent_class)->constructed (object); +} + +static gboolean +calendar_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + icalcomponent *icalcomp = NULL; + EActivity *activity; + EShellBackend *shell_backend; + EShellView *shell_view; + ESource *source = NULL; + ESourceRegistry *registry; + GCancellable *cancellable; + gchar **segments; + gchar *source_uid = NULL; + gchar *message; + const gchar *display_name; + const guchar *data; + gboolean do_copy; + TransferItemToData *titd; + + data = gtk_selection_data_get_data (selection_data); + g_return_val_if_fail (data != NULL, FALSE); + + segments = g_strsplit ((const gchar *) data, "\n", 2); + if (g_strv_length (segments) != 2) + goto exit; + + source_uid = g_strdup (segments[0]); + icalcomp = icalparser_parse_string (segments[1]); + + if (!icalcomp) + goto exit; + + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_source (registry, source_uid); + if (!source) + goto exit; + + shell_view = e_calendar_selector_get_shell_view (E_CALENDAR_SELECTOR (selector)); + shell_backend = e_shell_view_get_shell_backend (shell_view); + + display_name = e_source_get_display_name (destination); + + do_copy = action == GDK_ACTION_COPY ? TRUE : FALSE; + + message = do_copy ? + g_strdup_printf (_("Copying an event into the calendar %s"), display_name) : + g_strdup_printf (_("Moving an event into the calendar %s"), display_name); + + cancellable = g_cancellable_new (); + activity = e_activity_new (); + e_activity_set_cancellable (activity, cancellable); + e_activity_set_state (activity, E_ACTIVITY_RUNNING); + e_activity_set_text (activity, message); + g_free (message); + + e_shell_backend_add_activity (shell_backend, activity); + + titd = g_new0 (TransferItemToData, 1); + + titd->destination = destination; + titd->icalcomp = icalcomponent_new_clone (icalcomp); + titd->selector = selector; + titd->shell_view = shell_view; + titd->activity = activity; + titd->display_name = display_name; + titd->do_copy = do_copy; + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), source, cancellable, + source_client_connect_cb, titd); + +exit: + if (source) + g_object_unref (source); + + if (icalcomp) + icalcomponent_free (icalcomp); + + g_free (source_uid); + g_strfreev (segments); + return TRUE; +} + +static void +e_calendar_selector_class_init (ECalendarSelectorClass *class) +{ + GObjectClass *object_class; + ESourceSelectorClass *source_selector_class; + + g_type_class_add_private (class, sizeof (ECalendarSelectorPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = calendar_selector_constructed; + object_class->set_property = calendar_selector_set_property; + object_class->get_property = calendar_selector_get_property; + object_class->dispose = calendar_selector_dispose; + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = calendar_selector_data_dropped; + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + NULL, + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_calendar_selector_init (ECalendarSelector *selector) +{ + selector->priv = E_CALENDAR_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + NULL, 0, GDK_ACTION_COPY | GDK_ACTION_MOVE); + + e_drag_dest_add_calendar_targets (GTK_WIDGET (selector)); +} + +GtkWidget * +e_calendar_selector_new (EClientCache *client_cache, + EShellView *shell_view) +{ + ESourceRegistry *registry; + GtkWidget *widget; + + g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + registry = e_client_cache_ref_registry (client_cache); + + widget = g_object_new ( + E_TYPE_CALENDAR_SELECTOR, + "client-cache", client_cache, + "extension-name", E_SOURCE_EXTENSION_CALENDAR, + "registry", registry, + "shell-view", shell_view, + NULL); + + g_object_unref (registry); + + return widget; +} + +EShellView * +e_calendar_selector_get_shell_view (ECalendarSelector *selector) +{ + g_return_val_if_fail (E_IS_CALENDAR_SELECTOR (selector), NULL); + + return selector->priv->shell_view; +} + diff -Nru evolution-3.16.0/calendar/gui/e-calendar-selector.h evolution-3.12.11/calendar/gui/e-calendar-selector.h --- evolution-3.16.0/calendar/gui/e-calendar-selector.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-calendar-selector.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,67 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-calendar-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#ifndef E_CALENDAR_SELECTOR_H +#define E_CALENDAR_SELECTOR_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_CALENDAR_SELECTOR \ + (e_calendar_selector_get_type ()) +#define E_CALENDAR_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelector)) +#define E_CALENDAR_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass)) +#define E_IS_CALENDAR_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_CALENDAR_SELECTOR)) +#define E_IS_CALENDAR_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_CALENDAR_SELECTOR)) +#define E_CALENDAR_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_CALENDAR_SELECTOR, ECalendarSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _ECalendarSelector ECalendarSelector; +typedef struct _ECalendarSelectorClass ECalendarSelectorClass; +typedef struct _ECalendarSelectorPrivate ECalendarSelectorPrivate; + +struct _ECalendarSelector { + EClientSelector parent; + ECalendarSelectorPrivate *priv; +}; + +struct _ECalendarSelectorClass { + EClientSelectorClass parent_class; +}; + +GType e_calendar_selector_get_type (void); +GtkWidget * e_calendar_selector_new (EClientCache *client_cache, + EShellView *shell_backend); +EShellView * e_calendar_selector_get_shell_view + (ECalendarSelector *selector); + +G_END_DECLS + +#endif /* E_CALENDAR_SELECTOR_H */ diff -Nru evolution-3.16.0/calendar/gui/e-calendar-view.c evolution-3.12.11/calendar/gui/e-calendar-view.c --- evolution-3.16.0/calendar/gui/e-calendar-view.c 2015-02-24 14:55:48.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-calendar-view.c 2014-12-09 15:01:59.000000000 +0000 @@ -35,16 +35,13 @@ #include "comp-util.h" #include "ea-calendar.h" -#include "e-cal-ops.h" #include "e-cal-model-calendar.h" #include "e-calendar-view.h" -#include "e-day-view.h" -#include "e-month-view.h" -#include "e-cal-list-view.h" #include "ea-cal-view.h" #include "itip-utils.h" #include "dialogs/comp-editor-util.h" #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/event-editor.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" @@ -59,9 +56,13 @@ ((obj), E_TYPE_CALENDAR_VIEW, ECalendarViewPrivate)) struct _ECalendarViewPrivate { + /* The GnomeCalendar we are associated to */ + GnomeCalendar *calendar; + /* The calendar model we are monitoring */ ECalModel *model; + gchar *default_category; gint time_divisions; GSList *selected_cut_list; @@ -91,8 +92,8 @@ TIMEZONE_CHANGED, EVENT_CHANGED, EVENT_ADDED, + USER_CREATED, OPEN_EVENT, - MOVE_VIEW_RANGE, LAST_SIGNAL }; @@ -108,7 +109,7 @@ static void calendar_view_add_retract_data (ECalComponent *comp, const gchar *retract_comment, - ECalObjModType mod) + CalObjModType mod) { icalcomponent *icalcomp = NULL; icalproperty *icalprop = NULL; @@ -121,7 +122,7 @@ icalproperty_set_x_name (icalprop, "X-EVOLUTION-RETRACT-COMMENT"); icalcomponent_add_property (icalcomp, icalprop); - if (mod == E_CAL_OBJ_MOD_ALL) + if (mod == CALOBJ_MOD_ALL) icalprop = icalproperty_new_x ("All"); else icalprop = icalproperty_new_x ("This"); @@ -165,6 +166,7 @@ ECalComponentVType vtype; ESourceRegistry *registry; gboolean delete = TRUE; + GError *error = NULL; if (!is_comp_data_valid (event)) return; @@ -187,13 +189,29 @@ delete = prompt_retract_dialog (comp, &retract_comment, GTK_WIDGET (cal_view), &retract); if (retract) { - icalcomponent *icalcomp; + GSList *users = NULL; + icalcomponent *icalcomp = NULL, *mod_comp = NULL; - calendar_view_add_retract_data (comp, retract_comment, E_CAL_OBJ_MOD_ALL); + calendar_view_add_retract_data ( + comp, retract_comment, CALOBJ_MOD_ALL); icalcomp = e_cal_component_get_icalcomponent (comp); icalcomponent_set_method (icalcomp, ICAL_METHOD_CANCEL); + e_cal_client_send_objects_sync ( + event->comp_data->client, icalcomp, + &users, &mod_comp, NULL, &error); + if (error != NULL) { + delete_error_dialog (error, E_CAL_COMPONENT_EVENT); + g_clear_error (&error); + } else { + + if (mod_comp) + icalcomponent_free (mod_comp); - e_cal_ops_send_component (model, event->comp_data->client, icalcomp); + if (users) { + g_slist_foreach (users, (GFunc) g_free, NULL); + g_slist_free (users); + } + } } } else if (e_cal_model_get_confirm_delete (model)) delete = delete_component_dialog ( @@ -208,9 +226,10 @@ && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), event->comp_data->client, comp, TRUE)) - itip_send_component (model, E_CAL_COMPONENT_METHOD_CANCEL, + itip_send_comp ( + registry, E_CAL_COMPONENT_METHOD_CANCEL, comp, event->comp_data->client, NULL, NULL, - NULL, TRUE, FALSE, FALSE); + NULL, TRUE, FALSE); e_cal_component_get_uid (comp, &uid); if (!uid || !*uid) { @@ -218,12 +237,15 @@ return; } rid = e_cal_component_get_recurid_as_string (comp); - if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || - e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) - e_cal_ops_remove_component (model, event->comp_data->client, uid, rid, E_CAL_OBJ_MOD_ALL, FALSE); + if (e_cal_util_component_is_instance (event->comp_data->icalcomp) || e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) + e_cal_client_remove_object_sync ( + event->comp_data->client, uid, + rid, CALOBJ_MOD_ALL, NULL, &error); else - e_cal_ops_remove_component (model, event->comp_data->client, uid, NULL, E_CAL_OBJ_MOD_THIS, FALSE); + e_cal_client_remove_object_sync (event->comp_data->client, uid, NULL, CALOBJ_MOD_THIS, NULL, &error); + delete_error_dialog (error, E_CAL_COMPONENT_EVENT); + g_clear_error (&error); g_free (rid); } @@ -340,11 +362,26 @@ g_object_unref (keyboard); } + g_clear_object (&priv->calendar); + /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_calendar_view_parent_class)->dispose (object); } static void +calendar_view_finalize (GObject *object) +{ + ECalendarViewPrivate *priv; + + priv = E_CALENDAR_VIEW_GET_PRIVATE (object); + + g_free (priv->default_category); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_calendar_view_parent_class)->finalize (object); +} + +static void calendar_view_constructed (GObject *object) { /* Do this after calendar_view_init() so extensions can query @@ -445,6 +482,10 @@ if (!selected) return; +#if 0 /* KILL-BONOBO */ + e_calendar_view_set_status_message (cal_view, _("Deleting selected objects"), -1); +#endif + e_selectable_copy_clipboard (selectable); for (l = selected; l != NULL; l = g_list_next (l)) { @@ -453,6 +494,10 @@ priv->selected_cut_list = g_slist_prepend (priv->selected_cut_list, g_object_ref (event->comp_data)); } +#if 0 /* KILL-BONOBO */ + e_calendar_view_set_status_message (cal_view, NULL, -1); +#endif + g_list_free (selected); } @@ -569,301 +614,45 @@ g_list_free (selected); } -static void -calendar_view_component_created_cb (ECalModel *model, - ECalClient *client, - icalcomponent *original_icalcomp, - const gchar *new_uid, - gpointer user_data) -{ - gboolean strip_alarms = TRUE; - ECalComponent *comp; - ESourceRegistry *registry; - GtkWidget *toplevel = user_data; - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (original_icalcomp)); - g_return_if_fail (comp != NULL); - - registry = e_cal_model_get_registry (model); - - if (new_uid) - e_cal_component_set_uid (comp, new_uid); - - if ((itip_organizer_is_user (registry, comp, client) || - itip_sentby_is_user (registry, comp, client)) && - send_component_dialog ((GtkWindow *) toplevel, client, comp, TRUE, &strip_alarms, NULL)) { - itip_send_component (model, E_CAL_COMPONENT_METHOD_REQUEST, - comp, client, NULL, NULL, NULL, strip_alarms, FALSE, FALSE); - } - - g_object_unref (comp); -} - -static void -e_calendar_view_add_event_sync (ECalModel *model, - ECalClient *client, - time_t dtstart, - icaltimezone *default_zone, - icalcomponent *icalcomp, - gboolean all_day, - gboolean is_day_view, - gint time_division, - GtkWidget *top_level) -{ - ECalComponent *comp; - struct icaltimetype itime, old_dtstart, old_dtend; - time_t tt_start, tt_end, new_dtstart = 0; - struct icaldurationtype ic_dur, ic_oneday; - gchar *uid; - gint start_offset, end_offset; - gboolean all_day_event = FALSE; - - start_offset = 0; - end_offset = 0; - - old_dtstart = icalcomponent_get_dtstart (icalcomp); - tt_start = icaltime_as_timet (old_dtstart); - old_dtend = icalcomponent_get_dtend (icalcomp); - tt_end = icaltime_as_timet (old_dtend); - ic_dur = icaldurationtype_from_int (tt_end - tt_start); - - if (icaldurationtype_as_int (ic_dur) > 60 *60 *24) { - /* This is a long event */ - start_offset = old_dtstart.hour * 60 + old_dtstart.minute; - end_offset = old_dtstart.hour * 60 + old_dtend.minute; - } - - ic_oneday = icaldurationtype_null_duration (); - ic_oneday.days = 1; - - if (is_day_view) { - if (start_offset == 0 && end_offset == 0 && all_day) - all_day_event = TRUE; - - if (all_day_event) { - ic_dur = ic_oneday; - } else if (icaldurationtype_as_int (ic_dur) >= 60 *60 *24 && !all_day) { - /* copy & paste from top canvas to main canvas */ - ic_dur = icaldurationtype_from_int (time_division * 60); - } - - if (all_day) - new_dtstart = dtstart + start_offset * 60; - else - new_dtstart = dtstart; - } else { - if (old_dtstart.is_date && old_dtend.is_date - && memcmp (&ic_dur, &ic_oneday, sizeof (ic_dur)) == 0) { - all_day_event = TRUE; - new_dtstart = dtstart; - } else { - icaltimetype new_time = icaltime_from_timet_with_zone (dtstart, FALSE, default_zone); - - new_time.hour = old_dtstart.hour; - new_time.minute = old_dtstart.minute; - new_time.second = old_dtstart.second; - - new_dtstart = icaltime_as_timet_with_zone (new_time, old_dtstart.zone ? old_dtstart.zone : default_zone); - } - } - - itime = icaltime_from_timet_with_zone (new_dtstart, FALSE, old_dtstart.zone ? old_dtstart.zone : default_zone); - /* set the timezone properly */ - itime.zone = old_dtstart.zone ? old_dtstart.zone : default_zone; - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtstart (icalcomp, itime); - - itime.is_date = FALSE; - itime = icaltime_add (itime, ic_dur); - if (all_day_event) - itime.is_date = TRUE; - icalcomponent_set_dtend (icalcomp, itime); - - /* The new uid stuff can go away once we actually set it in the backend */ - uid = e_cal_component_gen_uid (); - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent ( - comp, icalcomponent_new_clone (icalcomp)); - e_cal_component_set_uid (comp, uid); - g_free (uid); - - e_cal_component_commit_sequence (comp); - - e_cal_ops_create_component (model, client, e_cal_component_get_icalcomponent (comp), - calendar_view_component_created_cb, g_object_ref (top_level), g_object_unref); - - g_object_unref (comp); -} - -typedef struct { - ECalendarView *cal_view; - GSList *selected_cut_list; /* ECalModelComponent * */ - GSList *copied_uids; /* gchar * */ - gchar *ical_str; - time_t selection_start; - time_t selection_end; - gboolean is_day_view; - gint time_division; - GtkWidget *top_level; - gboolean success; - ECalClient *client; -} PasteClipboardData; - -static void -paste_clipboard_data_free (gpointer ptr) -{ - PasteClipboardData *pcd = ptr; - - if (pcd) { - if (pcd->success && pcd->copied_uids && pcd->selected_cut_list) { - ECalModel *model; - ESourceRegistry *registry; - GSList *link; - - model = e_calendar_view_get_model (pcd->cal_view); - registry = e_cal_model_get_registry (model); - - for (link = pcd->selected_cut_list; link != NULL; link = g_slist_next (link)) { - ECalModelComponent *comp_data = (ECalModelComponent *) link->data; - ECalComponent *comp; - const gchar *uid; - GSList *found = NULL; - - /* Remove them one by one after ensuring it has been copied to the destination successfully */ - found = g_slist_find_custom (pcd->copied_uids, icalcomponent_get_uid (comp_data->icalcomp), (GCompareFunc) strcmp); - if (!found) - continue; - - g_free (found->data); - pcd->copied_uids = g_slist_delete_link (pcd->copied_uids, found); - - comp = e_cal_component_new (); - e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); - - if ((itip_organizer_is_user (registry, comp, comp_data->client) || - itip_sentby_is_user (registry, comp, comp_data->client)) - && cancel_component_dialog ((GtkWindow *) pcd->top_level, comp_data->client, comp, TRUE)) - itip_send_component (model, E_CAL_COMPONENT_METHOD_CANCEL, - comp, comp_data->client, NULL, NULL, NULL, TRUE, FALSE, TRUE); - - e_cal_component_get_uid (comp, &uid); - if (e_cal_component_is_instance (comp)) { - gchar *rid = NULL; - - /* when cutting detached instances, only cut that instance */ - rid = e_cal_component_get_recurid_as_string (comp); - e_cal_ops_remove_component (model, comp_data->client, uid, rid, E_CAL_OBJ_MOD_THIS, TRUE); - g_free (rid); - } else { - e_cal_ops_remove_component (model, comp_data->client, uid, NULL, E_CAL_OBJ_MOD_ALL, FALSE); - } - - g_object_unref (comp); - } - } - - if (pcd->success && pcd->client) { - ECalModel *model; - - model = e_calendar_view_get_model (pcd->cal_view); - e_cal_model_emit_object_created (model, pcd->client); - } - - g_clear_object (&pcd->cal_view); - g_clear_object (&pcd->top_level); - g_clear_object (&pcd->client); - g_slist_free_full (pcd->selected_cut_list, g_object_unref); - g_slist_free_full (pcd->copied_uids, g_free); - g_free (pcd->ical_str); - g_free (pcd); - } -} - -static void -cal_view_paste_clipboard_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) +static gboolean +clipboard_get_calendar_data (ECalendarView *cal_view, + const gchar *text, + GSList **copied_list) { - PasteClipboardData *pcd = user_data; icalcomponent *icalcomp; icalcomponent_kind kind; + time_t selected_time_start, selected_time_end; icaltimezone *default_zone; - ECalModel *model; - ESourceRegistry *registry; - ESource *source, *default_source; - EClientCache *client_cache; - EClient *e_client; - ECalClient *client = NULL; - const gchar *message; - const gchar *extension_name; - guint copied_components = 1; - gboolean all_day; - GError *local_error = NULL; - - g_return_if_fail (pcd != NULL); - - icalcomp = icalparser_parse_string (pcd->ical_str); - if (!icalcomp) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, - _("Pasted text doesn't contain valid iCalendar data")); - return; - } - - model = e_calendar_view_get_model (pcd->cal_view); - registry = e_cal_model_get_registry (model); + ECalClient *client; + gboolean in_top_canvas, ret = FALSE; - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - default_source = e_source_registry_ref_default_calendar (registry); - extension_name = E_SOURCE_EXTENSION_CALENDAR; - message = _("Default calendar not found"); - break; - case ICAL_VJOURNAL_COMPONENT: - default_source = e_source_registry_ref_default_memo_list (registry); - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - message = _("Default memo list not found"); - break; - case ICAL_VTODO_COMPONENT: - default_source = e_source_registry_ref_default_task_list (registry); - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - message = _("Default task list not found"); - break; - default: - g_warn_if_reached (); - goto out; - } - - source = e_source_registry_ref_source (registry, e_cal_model_get_default_source_uid (model)); - if (!source) { - source = default_source; - default_source = NULL; - } + g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); - if (!source) { - const gchar *default_source_uid = e_cal_model_get_default_source_uid (model); + if (!text || !*text) + return FALSE; - e_alert_sink_thread_job_set_alert_arg_0 (job_data, default_source_uid ? default_source_uid : ""); - g_set_error_literal (&local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, message); + icalcomp = icalparser_parse_string (text); + if (!icalcomp) + return FALSE; - return; - } + /* check the type of the component */ + /* FIXME An error dialog if we return? */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) + return FALSE; - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); - client_cache = e_cal_model_get_client_cache (model); + default_zone = e_cal_model_get_timezone (cal_view->priv->model); + client = e_cal_model_ref_default_client (cal_view->priv->model); - e_client = e_client_cache_get_client_sync (client_cache, source, extension_name, 30, cancellable, &local_error); - if (!e_client) { - e_util_propagate_open_source_job_error (job_data, extension_name, local_error, error); - goto out; - } +#if 0 /* KILL-BONOBO */ + e_calendar_view_set_status_message (cal_view, _("Updating objects"), -1); +#endif + e_calendar_view_get_selected_time_range (cal_view, &selected_time_start, &selected_time_end); - client = E_CAL_CLIENT (e_client); - kind = icalcomponent_isa (icalcomp); - default_zone = e_cal_model_get_timezone (model); - all_day = pcd->selection_end - pcd->selection_start == 60 * 60 * 24; - copied_components = 0; + if ((selected_time_end - selected_time_start) == 60 * 60 * 24) + in_top_canvas = TRUE; + else + in_top_canvas = FALSE; if (kind == ICAL_VCALENDAR_COMPONENT) { icalcomponent *subcomp; @@ -873,13 +662,28 @@ subcomp; subcomp = icalcomponent_get_next_component (icalcomp, ICAL_VTIMEZONE_COMPONENT)) { icaltimezone *zone; + GError *error = NULL; zone = icaltimezone_new (); icaltimezone_set_component (zone, subcomp); + e_cal_client_add_timezone_sync ( + client, zone, NULL, &error); + if (error != NULL) { + icalproperty *tzidprop; + const gchar *tzid; + + tzidprop = icalcomponent_get_first_property ( + subcomp, ICAL_TZID_PROPERTY); + if (tzidprop != NULL) + tzid = icalproperty_get_tzid (tzidprop); + else + tzid = "???"; + + g_warning ( + "%s: Add zone '%s' failed. %s", + G_STRFUNC, tzid, error->message); - if (!e_cal_client_add_timezone_sync (client, zone, cancellable, error)) { - icaltimezone_free (zone, 1); - goto out; + g_error_free (error); } icaltimezone_free (zone, 1); @@ -894,33 +698,28 @@ icalproperty_remove_parameter_by_name (icalprop, "X-EVOLUTION-ENDDATE"); } - e_calendar_view_add_event_sync (model, client, pcd->selection_start, default_zone, subcomp, all_day, - pcd->is_day_view, pcd->time_division, pcd->top_level); + ret = e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, subcomp, in_top_canvas); + if (!ret) + break; - copied_components++; - if (pcd->selected_cut_list) - pcd->copied_uids = g_slist_prepend (pcd->copied_uids, g_strdup (icalcomponent_get_uid (subcomp))); + if (copied_list) + *copied_list = g_slist_prepend (*copied_list, g_strdup (icalcomponent_get_uid (subcomp))); } - } else if (kind == e_cal_model_get_component_kind (model)) { - e_calendar_view_add_event_sync (model, client, pcd->selection_start, default_zone, icalcomp, all_day, - pcd->is_day_view, pcd->time_division, pcd->top_level); - copied_components++; - if (pcd->selected_cut_list) - pcd->copied_uids = g_slist_prepend (pcd->copied_uids, g_strdup (icalcomponent_get_uid (icalcomp))); + icalcomponent_free (icalcomp); + } else { + ret = e_calendar_view_add_event (cal_view, client, selected_time_start, default_zone, icalcomp, in_top_canvas); + if (ret && copied_list) + *copied_list = g_slist_prepend (*copied_list, g_strdup (icalcomponent_get_uid (icalcomp))); } - pcd->success = !g_cancellable_is_cancelled (cancellable); - pcd->client = g_object_ref (client); + g_object_unref (client); - out: - if (!copied_components && !g_cancellable_is_cancelled (cancellable) && error && !*error) - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, _("No suitable component found")); + return ret; - icalcomponent_free (icalcomp); - g_clear_object (&source); - g_clear_object (&default_source); - g_clear_object (&client); +#if 0 /* KILL-BONOBO */ + e_calendar_view_set_status_message (cal_view, NULL, -1); +#endif } static void @@ -928,11 +727,15 @@ { ECalModel *model; ECalendarView *cal_view; + ECalendarViewPrivate *priv; + ESourceRegistry *registry; GtkClipboard *clipboard; cal_view = E_CALENDAR_VIEW (selectable); + priv = cal_view->priv; model = e_calendar_view_get_model (cal_view); + registry = e_cal_model_get_registry (model); clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); @@ -947,48 +750,86 @@ /* Paste iCalendar data into the view. */ } else if (e_clipboard_wait_is_calendar_available (clipboard)) { - PasteClipboardData *pcd; - ECalDataModel *data_model; - GCancellable *cancellable; - const gchar *alert_ident = NULL; - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - alert_ident = "calendar:failed-create-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - alert_ident = "calendar:failed-create-memo"; - break; - case ICAL_VTODO_COMPONENT: - alert_ident = "calendar:failed-create-task"; - break; - default: - g_warn_if_reached (); - return; - } - - pcd = g_new0 (PasteClipboardData, 1); - pcd->cal_view = g_object_ref (cal_view); - pcd->selected_cut_list = cal_view->priv->selected_cut_list; - cal_view->priv->selected_cut_list = NULL; - pcd->copied_uids = NULL; /* gchar * */ - pcd->ical_str = e_clipboard_wait_for_calendar (clipboard); - g_warn_if_fail (e_calendar_view_get_selected_time_range (cal_view, &pcd->selection_start, &pcd->selection_end)); - pcd->is_day_view = E_IS_DAY_VIEW (cal_view); - if (pcd->is_day_view) - pcd->time_division = e_calendar_view_get_time_divisions (cal_view); - pcd->top_level = gtk_widget_get_toplevel (GTK_WIDGET (cal_view)); - if (pcd->top_level) - g_object_ref (pcd->top_level); - pcd->success = FALSE; - pcd->client = NULL; + gchar *calendar_source; + GSList *copied_list = NULL, *l; + + calendar_source = e_clipboard_wait_for_calendar (clipboard); + + if (priv->selected_cut_list) + clipboard_get_calendar_data (cal_view, calendar_source, &copied_list); + else + clipboard_get_calendar_data (cal_view, calendar_source, NULL); + + if (copied_list && priv->selected_cut_list) { + for (l = priv->selected_cut_list; l != NULL; l = l->next) { + ECalComponent *comp; + ECalModelComponent *comp_data = (ECalModelComponent *) l->data; + const gchar *uid; + GError *error = NULL; + GSList *found = NULL; + + /* Remove them one by one after ensuring it has been copied to the destination successfully */ + found = g_slist_find_custom (copied_list, icalcomponent_get_uid (comp_data->icalcomp), (GCompareFunc) strcmp); + if (!found) + continue; + + g_free (found->data); + copied_list = g_slist_delete_link (copied_list, found); + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp)); + + if ((itip_organizer_is_user (registry, comp, comp_data->client) || + itip_sentby_is_user (registry, comp, comp_data->client)) + && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), + comp_data->client, comp, TRUE)) + itip_send_comp ( + registry, + E_CAL_COMPONENT_METHOD_CANCEL, + comp, comp_data->client, + NULL, NULL, NULL, TRUE, FALSE); + + e_cal_component_get_uid (comp, &uid); + if (e_cal_component_is_instance (comp)) { + gchar *rid = NULL; + icalcomponent *icalcomp; - data_model = e_cal_model_get_data_model (model); + /* when cutting detached instances, only cut that instance */ + rid = e_cal_component_get_recurid_as_string (comp); + e_cal_client_get_object_sync ( + comp_data->client, uid, rid, + &icalcomp, NULL, NULL); + if (icalcomp != NULL) { + e_cal_client_remove_object_sync ( + comp_data->client, uid, rid, + CALOBJ_MOD_THIS, NULL, &error); + icalcomponent_free (icalcomp); + } else { + e_cal_client_remove_object_sync ( + comp_data->client, uid, NULL, + CALOBJ_MOD_ALL, NULL, &error); + } + g_free (rid); + } else { + e_cal_client_remove_object_sync ( + comp_data->client, uid, NULL, + CALOBJ_MOD_ALL, NULL, &error); + } + delete_error_dialog (error, E_CAL_COMPONENT_EVENT); - cancellable = e_cal_data_model_submit_thread_job (data_model, _("Pasting iCalendar data"), alert_ident, - NULL, cal_view_paste_clipboard_thread, pcd, paste_clipboard_data_free); + g_clear_error (&error); + g_object_unref (comp); + } + } + + if (priv->selected_cut_list) { + g_slist_foreach (priv->selected_cut_list, (GFunc) g_object_unref, NULL); + g_slist_free (priv->selected_cut_list); + } + priv->selected_cut_list = NULL; + + g_free (calendar_source); - g_clear_object (&cancellable); } } @@ -1028,18 +869,19 @@ object_class->set_property = calendar_view_set_property; object_class->get_property = calendar_view_get_property; object_class->dispose = calendar_view_dispose; + object_class->finalize = calendar_view_finalize; object_class->constructed = calendar_view_constructed; class->selection_changed = NULL; class->selected_time_changed = NULL; class->event_changed = NULL; class->event_added = NULL; + class->user_created = NULL; class->get_selected_events = NULL; class->get_selected_time_range = NULL; class->set_selected_time_range = NULL; class->get_visible_time_range = NULL; - class->precalc_visible_time_range = NULL; class->update_query = NULL; class->open_event = e_calendar_view_open_event; class->paste_text = NULL; @@ -1148,6 +990,15 @@ G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[USER_CREATED] = g_signal_new ( + "user-created", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalendarViewClass, user_created), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + signals[OPEN_EVENT] = g_signal_new ( "open-event", G_TYPE_FROM_CLASS (class), @@ -1157,64 +1008,223 @@ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - signals[MOVE_VIEW_RANGE] = g_signal_new ( - "move-view-range", - G_TYPE_FROM_CLASS (object_class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalendarViewClass, move_view_range), - NULL, NULL, - NULL, /* default marshal */ - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT64); + /* Key bindings */ + + binding_set = gtk_binding_set_by_class (class); + + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_o, GDK_CONTROL_MASK, "open-event", 0); + + /* init the accessibility support for e_day_view */ + widget_class = GTK_WIDGET_CLASS (class); + gtk_widget_class_set_accessible_type (widget_class, EA_TYPE_CAL_VIEW); +} + +static void +e_calendar_view_init (ECalendarView *calendar_view) +{ + GtkTargetList *target_list; + + calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view); + + /* Set this early to avoid a divide-by-zero during init. */ + calendar_view->priv->time_divisions = 30; + + target_list = gtk_target_list_new (NULL, 0); + e_target_list_add_calendar_targets (target_list, 0); + calendar_view->priv->copy_target_list = target_list; + + target_list = gtk_target_list_new (NULL, 0); + e_target_list_add_calendar_targets (target_list, 0); + calendar_view->priv->paste_target_list = target_list; +} + +static void +calendar_view_selectable_init (ESelectableInterface *iface) +{ + iface->update_actions = calendar_view_update_actions; + iface->cut_clipboard = calendar_view_cut_clipboard; + iface->copy_clipboard = calendar_view_copy_clipboard; + iface->paste_clipboard = calendar_view_paste_clipboard; + iface->delete_selection = calendar_view_delete_selection; +} + +void +e_calendar_view_popup_event (ECalendarView *calendar_view, + GdkEvent *button_event) +{ + g_return_if_fail (E_IS_CALENDAR_VIEW (calendar_view)); + g_return_if_fail (button_event != NULL); + + g_signal_emit (calendar_view, signals[POPUP_EVENT], 0, button_event); +} + +gboolean +e_calendar_view_add_event (ECalendarView *cal_view, + ECalClient *client, + time_t dtstart, + icaltimezone *default_zone, + icalcomponent *icalcomp, + gboolean in_top_canvas) +{ + ECalModel *model; + ECalComponent *comp; + ESourceRegistry *registry; + struct icaltimetype itime, old_dtstart, old_dtend; + time_t tt_start, tt_end, new_dtstart = 0; + struct icaldurationtype ic_dur, ic_oneday; + gchar *uid; + gint start_offset, end_offset; + gboolean all_day_event = FALSE; + GnomeCalendarViewType view_type; + gboolean ret = TRUE; + GError *error = NULL; + + model = e_calendar_view_get_model (cal_view); + registry = e_cal_model_get_registry (model); + + start_offset = 0; + end_offset = 0; + + old_dtstart = icalcomponent_get_dtstart (icalcomp); + tt_start = icaltime_as_timet (old_dtstart); + old_dtend = icalcomponent_get_dtend (icalcomp); + tt_end = icaltime_as_timet (old_dtend); + ic_dur = icaldurationtype_from_int (tt_end - tt_start); + + if (icaldurationtype_as_int (ic_dur) > 60 *60 *24) { + /* This is a long event */ + start_offset = old_dtstart.hour * 60 + old_dtstart.minute; + end_offset = old_dtstart.hour * 60 + old_dtend.minute; + } + + ic_oneday = icaldurationtype_null_duration (); + ic_oneday.days = 1; + + view_type = gnome_calendar_get_view (cal_view->priv->calendar); + + switch (view_type) { + case GNOME_CAL_DAY_VIEW: + case GNOME_CAL_WORK_WEEK_VIEW: + if (start_offset == 0 && end_offset == 0 && in_top_canvas) + all_day_event = TRUE; + + if (all_day_event) { + ic_dur = ic_oneday; + } else if (icaldurationtype_as_int (ic_dur) >= 60 *60 *24 + && !in_top_canvas) { + /* copy & paste from top canvas to main canvas */ + gint time_divisions; + + time_divisions = e_calendar_view_get_time_divisions (cal_view); + ic_dur = icaldurationtype_from_int (time_divisions * 60); + } + + if (in_top_canvas) + new_dtstart = dtstart + start_offset * 60; + else + new_dtstart = dtstart; + break; + case GNOME_CAL_WEEK_VIEW: + case GNOME_CAL_MONTH_VIEW: + case GNOME_CAL_LIST_VIEW: + if (old_dtstart.is_date && old_dtend.is_date + && memcmp (&ic_dur, &ic_oneday, sizeof (ic_dur)) == 0) { + all_day_event = TRUE; + new_dtstart = dtstart; + } else { + icaltimetype new_time = icaltime_from_timet_with_zone (dtstart, FALSE, default_zone); - /* Key bindings */ + new_time.hour = old_dtstart.hour; + new_time.minute = old_dtstart.minute; + new_time.second = old_dtstart.second; - binding_set = gtk_binding_set_by_class (class); + new_dtstart = icaltime_as_timet_with_zone (new_time, old_dtstart.zone ? old_dtstart.zone : default_zone); + } + break; + default: + g_return_val_if_reached (FALSE); + } - gtk_binding_entry_add_signal ( - binding_set, GDK_KEY_o, GDK_CONTROL_MASK, "open-event", 0); + itime = icaltime_from_timet_with_zone (new_dtstart, FALSE, old_dtstart.zone ? old_dtstart.zone : default_zone); + /* set the timezone properly */ + itime.zone = old_dtstart.zone ? old_dtstart.zone : default_zone; + if (all_day_event) + itime.is_date = TRUE; + icalcomponent_set_dtstart (icalcomp, itime); - /* init the accessibility support for e_day_view */ - widget_class = GTK_WIDGET_CLASS (class); - gtk_widget_class_set_accessible_type (widget_class, EA_TYPE_CAL_VIEW); -} + itime.is_date = FALSE; + itime = icaltime_add (itime, ic_dur); + if (all_day_event) + itime.is_date = TRUE; + icalcomponent_set_dtend (icalcomp, itime); -static void -e_calendar_view_init (ECalendarView *calendar_view) -{ - GtkTargetList *target_list; + /* FIXME The new uid stuff can go away once we actually set it in the backend */ + uid = e_cal_component_gen_uid (); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent ( + comp, icalcomponent_new_clone (icalcomp)); + e_cal_component_set_uid (comp, uid); + g_free (uid); - calendar_view->priv = E_CALENDAR_VIEW_GET_PRIVATE (calendar_view); + e_cal_component_commit_sequence (comp); - /* Set this early to avoid a divide-by-zero during init. */ - calendar_view->priv->time_divisions = 30; + uid = NULL; + e_cal_client_create_object_sync ( + client, e_cal_component_get_icalcomponent (comp), + &uid, NULL, &error); + if (error == NULL) { + gboolean strip_alarms = TRUE; + + if (uid) { + e_cal_component_set_uid (comp, uid); + g_free (uid); + } - target_list = gtk_target_list_new (NULL, 0); - e_target_list_add_calendar_targets (target_list, 0); - calendar_view->priv->copy_target_list = target_list; + if ((itip_organizer_is_user (registry, comp, client) || + itip_sentby_is_user (registry, comp, client)) && + send_component_dialog ( + (GtkWindow *) gtk_widget_get_toplevel ( + GTK_WIDGET (cal_view)), + client, comp, TRUE, &strip_alarms, NULL)) { + itip_send_comp ( + registry, E_CAL_COMPONENT_METHOD_REQUEST, + comp, client, NULL, NULL, NULL, strip_alarms, + FALSE); + } + } else { + g_message ( + "%s: Could not create the object! %s", + G_STRFUNC, error->message); + g_error_free (error); + ret = FALSE; + } - target_list = gtk_target_list_new (NULL, 0); - e_target_list_add_calendar_targets (target_list, 0); - calendar_view->priv->paste_target_list = target_list; + g_object_unref (comp); + return ret; } -static void -calendar_view_selectable_init (ESelectableInterface *iface) +GnomeCalendar * +e_calendar_view_get_calendar (ECalendarView *cal_view) { - iface->update_actions = calendar_view_update_actions; - iface->cut_clipboard = calendar_view_cut_clipboard; - iface->copy_clipboard = calendar_view_copy_clipboard; - iface->paste_clipboard = calendar_view_paste_clipboard; - iface->delete_selection = calendar_view_delete_selection; + g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); + + return cal_view->priv->calendar; } void -e_calendar_view_popup_event (ECalendarView *calendar_view, - GdkEvent *button_event) +e_calendar_view_set_calendar (ECalendarView *cal_view, + GnomeCalendar *calendar) { - g_return_if_fail (E_IS_CALENDAR_VIEW (calendar_view)); - g_return_if_fail (button_event != NULL); + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - g_signal_emit (calendar_view, signals[POPUP_EVENT], 0, button_event); + if (calendar) + g_object_ref (calendar); + + if (cal_view->priv->calendar) + g_object_unref (cal_view->priv->calendar); + + cal_view->priv->calendar = calendar; } ECalModel * @@ -1250,6 +1260,32 @@ old_zone, zone); } +const gchar * +e_calendar_view_get_default_category (ECalendarView *cal_view) +{ + g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); + + return cal_view->priv->default_category; +} + +/** + * e_calendar_view_set_default_category + * @cal_view: A calendar view. + * @category: Default category name or NULL for no category. + * + * Sets the default category that will be used when creating new calendar + * components from the given calendar view. + */ +void +e_calendar_view_set_default_category (ECalendarView *cal_view, + const gchar *category) +{ + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + + g_free (cal_view->priv->default_category); + cal_view->priv->default_category = g_strdup (category); +} + GtkTargetList * e_calendar_view_get_copy_target_list (ECalendarView *cal_view) { @@ -1349,25 +1385,6 @@ } void -e_calendar_view_precalc_visible_time_range (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time) -{ - ECalendarViewClass *class; - - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - /* Not all views implement this, so return silently. */ - class = E_CALENDAR_VIEW_GET_CLASS (cal_view); - if (class->precalc_visible_time_range == NULL) - return; - - class->precalc_visible_time_range (cal_view, in_start_time, in_end_time, out_start_time, out_end_time); -} - -void e_calendar_view_update_query (ECalendarView *cal_view) { ECalendarViewClass *class; @@ -1383,19 +1400,132 @@ void e_calendar_view_delete_selected_occurrence (ECalendarView *cal_view) { - ECalendarViewEvent *event; GList *selected; + ECalModel *model; + ECalComponent *comp; + ECalendarViewEvent *event; + ECalComponentVType vtype; + ESourceRegistry *registry; + gboolean delete = TRUE; + GError *error = NULL; + + model = e_calendar_view_get_model (cal_view); + registry = e_cal_model_get_registry (model); selected = e_calendar_view_get_selected_events (cal_view); if (!selected) return; - event = (ECalendarViewEvent *) selected->data; - if (is_comp_data_valid (event)) { - calendar_view_delete_event (cal_view, event); + if (!is_comp_data_valid (event)) + return; + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + vtype = e_cal_component_get_vtype (comp); + + /*FIXME Retract should be moved to Groupwise features plugin */ + if (calendar_view_check_for_retract (comp, event->comp_data->client)) { + gchar *retract_comment = NULL; + gboolean retract = FALSE; + + delete = prompt_retract_dialog (comp, &retract_comment, GTK_WIDGET (cal_view), &retract); + if (retract) { + GSList *users = NULL; + icalcomponent *icalcomp = NULL, *mod_comp = NULL; + + calendar_view_add_retract_data ( + comp, retract_comment, CALOBJ_MOD_THIS); + icalcomp = e_cal_component_get_icalcomponent (comp); + icalcomponent_set_method (icalcomp, ICAL_METHOD_CANCEL); + e_cal_client_send_objects_sync ( + event->comp_data->client, icalcomp, + &users, &mod_comp, NULL, &error); + if (error != NULL) { + delete_error_dialog (error, E_CAL_COMPONENT_EVENT); + g_clear_error (&error); + } else { + if (mod_comp) + icalcomponent_free (mod_comp); + if (users) { + g_slist_foreach (users, (GFunc) g_free, NULL); + g_slist_free (users); + } + } + } + } else if (e_cal_model_get_confirm_delete (model)) + delete = delete_component_dialog ( + comp, FALSE, 1, vtype, GTK_WIDGET (cal_view)); + + if (delete) { + const gchar *uid; + gchar *rid = NULL; + ECalComponentDateTime dt; + icaltimezone *zone = NULL; + gboolean is_instance = FALSE; + + e_cal_component_get_uid (comp, &uid); + e_cal_component_get_dtstart (comp, &dt); + is_instance = e_cal_component_is_instance (comp); + + if (dt.tzid) { + GError *error = NULL; + + e_cal_client_get_timezone_sync (event->comp_data->client, dt.tzid, &zone, NULL, &error); + if (error != NULL) { + zone = e_calendar_view_get_timezone (cal_view); + g_clear_error (&error); + } + } else + zone = e_calendar_view_get_timezone (cal_view); + + if (is_instance) + rid = e_cal_component_get_recurid_as_string (comp); + + e_cal_component_free_datetime (&dt); + + if ((itip_organizer_is_user (registry, comp, event->comp_data->client) || + itip_sentby_is_user (registry, comp, event->comp_data->client)) + && cancel_component_dialog ((GtkWindow *) gtk_widget_get_toplevel (GTK_WIDGET (cal_view)), + event->comp_data->client, + comp, TRUE) && !e_cal_client_check_save_schedules (event->comp_data->client)) { + if (!e_cal_component_is_instance (comp)) { + ECalComponentRange range; + + /* set the recurrence ID of the object we send */ + range.type = E_CAL_COMPONENT_RANGE_SINGLE; + e_cal_component_get_dtstart (comp, &range.datetime); + range.datetime.value->is_date = 1; + e_cal_component_set_recurid (comp, &range); + + e_cal_component_free_datetime (&range.datetime); + } + + itip_send_comp ( + registry, E_CAL_COMPONENT_METHOD_CANCEL, + comp, event->comp_data->client, NULL, NULL, + NULL, TRUE, FALSE); + } + + if (is_instance) + e_cal_client_remove_object_sync (event->comp_data->client, uid, rid, CALOBJ_MOD_THIS, NULL, &error); + else { + struct icaltimetype instance_rid; + + instance_rid = icaltime_from_timet_with_zone ( + event->comp_data->instance_start, + TRUE, zone ? zone : icaltimezone_get_utc_timezone ()); + e_cal_util_remove_instances (event->comp_data->icalcomp, instance_rid, CALOBJ_MOD_THIS); + e_cal_client_modify_object_sync (event->comp_data->client, event->comp_data->icalcomp, CALOBJ_MOD_THIS, NULL, &error); + } + + delete_error_dialog (error, E_CAL_COMPONENT_EVENT); + g_clear_error (&error); + g_free (rid); } + /* free memory */ g_list_free (selected); + g_object_unref (comp); } void @@ -1414,6 +1544,99 @@ } /** + * e_calendar_view_new_appointment_for + * @cal_view: A calendar view. + * @dtstart: A Unix time_t that marks the beginning of the appointment. + * @dtend: A Unix time_t that marks the end of the appointment. + * @all_day: If TRUE, the dtstart and dtend are expanded to cover + * the entire day, and the event is set to TRANSPARENT. + * @meeting: Whether the appointment is a meeting or not. + * + * Opens an event editor dialog for a new appointment. + */ +void +e_calendar_view_new_appointment_for (ECalendarView *cal_view, + time_t dtstart, + time_t dtend, + gboolean all_day, + gboolean meeting) +{ + ECalendarViewPrivate *priv; + struct icaltimetype itt; + ECalComponentDateTime dt; + ECalComponent *comp; + icalcomponent *icalcomp; + ECalComponentTransparency transparency; + ECalClient *default_client = NULL; + gpointer parent; + guint32 flags = 0; + + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + + parent = gtk_widget_get_toplevel (GTK_WIDGET (cal_view)); + parent = gtk_widget_is_toplevel (parent) ? parent : NULL; + + priv = cal_view->priv; + + default_client = e_cal_model_ref_default_client (priv->model); + g_return_if_fail (default_client != NULL); + + dt.value = &itt; + if (all_day) + dt.tzid = NULL; + else + dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (cal_view->priv->model)); + + icalcomp = e_cal_model_create_component_with_defaults (priv->model, all_day); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + /* DTSTART, DTEND */ + itt = icaltime_from_timet_with_zone (dtstart, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); + if (all_day) { + itt.hour = itt.minute = itt.second = 0; + itt.is_date = TRUE; + } + e_cal_component_set_dtstart (comp, &dt); + + itt = icaltime_from_timet_with_zone (dtend, FALSE, e_cal_model_get_timezone (cal_view->priv->model)); + if (all_day) { + /* We round it up to the end of the day, unless it is + * already set to midnight */ + if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) { + icaltime_adjust (&itt, 1, 0, 0, 0); + } + itt.hour = itt.minute = itt.second = 0; + itt.is_date = TRUE; + } + e_cal_component_set_dtend (comp, &dt); + + /* TRANSPARENCY */ + transparency = all_day ? E_CAL_COMPONENT_TRANSP_TRANSPARENT + : E_CAL_COMPONENT_TRANSP_OPAQUE; + e_cal_component_set_transparency (comp, transparency); + + /* CATEGORY */ + e_cal_component_set_categories (comp, priv->default_category); + + /* edit the object */ + e_cal_component_commit_sequence (comp); + + flags |= COMP_EDITOR_NEW_ITEM; + if (meeting) { + flags |= COMP_EDITOR_MEETING; + flags |= COMP_EDITOR_USER_ORG; + } + + e_calendar_view_open_event_with_flags ( + cal_view, default_client, icalcomp, flags); + + g_object_unref (comp); + + g_object_unref (default_client); +} + +/** * e_calendar_view_new_appointment_full * @cal_view: an #ECalendarView * @all_day: Whether create all day event or not. @@ -1485,9 +1708,7 @@ dtend = dtstart + (time_div * 60); } - e_cal_ops_new_component_editor_from_model ( - e_calendar_view_get_model (cal_view), NULL, - dtstart, dtend, meeting, all_day); + e_calendar_view_new_appointment_for (cal_view, dtstart, dtend, all_day, meeting); } void @@ -1503,7 +1724,7 @@ object_created_cb (CompEditor *ce, ECalendarView *cal_view) { - e_cal_model_emit_object_created (e_calendar_view_get_model (cal_view), comp_editor_get_client (ce)); + e_calendar_view_emit_user_created (cal_view, comp_editor_get_client (ce)); } CompEditor * @@ -1586,6 +1807,106 @@ e_calendar_view_open_event_with_flags (cal_view, client, icalcomp, flags); } +void +e_calendar_view_modify_and_send (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new) +{ + ECalModel *model; + ESourceRegistry *registry; + gboolean only_new_attendees = FALSE; + gboolean strip_alarms = TRUE; + + if (e_calendar_view_modify (cal_view, comp, client, mod)) { + model = e_calendar_view_get_model (cal_view); + registry = e_cal_model_get_registry (model); + + if ((itip_organizer_is_user (registry, comp, client) || + itip_sentby_is_user (registry, comp, client)) && + send_component_dialog (toplevel, client, comp, new, &strip_alarms, &only_new_attendees)) + e_calendar_view_send (cal_view, comp, client, mod, toplevel, strip_alarms, only_new_attendees); + } +} + +gboolean +e_calendar_view_modify (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod) +{ + GError *error = NULL; + gboolean ret; + + g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), FALSE); + + e_cal_component_commit_sequence (comp); + + ret = e_cal_client_modify_object_sync ( + client, e_cal_component_get_icalcomponent (comp), + mod, NULL, &error); + + if (error != NULL) { + g_message ( + G_STRLOC ": Could not update the object! %s", + error->message); + + g_error_free (error); + } + + return ret; +} + +void +e_calendar_view_send (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean strip_alarms, + gboolean only_new_attendees) +{ + ESourceRegistry *registry; + ECalModel *model; + ECalComponent *send_comp = NULL; + + if (!itip_component_has_recipients (comp)) + return; + + if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { + /* Ensure we send the master object, not the instance only */ + icalcomponent *icalcomp = NULL; + const gchar *uid = NULL; + + e_cal_component_get_uid (comp, &uid); + e_cal_client_get_object_sync ( + client, uid, NULL, &icalcomp, NULL, NULL); + if (icalcomp != NULL) { + send_comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (send_comp, icalcomp)) { + icalcomponent_free (icalcomp); + g_object_unref (send_comp); + send_comp = NULL; + } else if (only_new_attendees) { + /* copy new-attendees information too if required for later use */ + comp_editor_copy_new_attendees (send_comp, comp); + } + } + } + + model = e_calendar_view_get_model (cal_view); + registry = e_cal_model_get_registry (model); + itip_send_comp ( + registry, E_CAL_COMPONENT_METHOD_REQUEST, + send_comp ? send_comp : comp, client, NULL, + NULL, NULL, strip_alarms, only_new_attendees); + + if (send_comp) + g_object_unref (send_comp); +} + static void tooltip_ungrab (ECalendarView *view, guint32 event_time) @@ -2025,22 +2346,15 @@ return summary; } -/* A callback for e_cal_ops_create_component(), whose @user_data is an ECalendarView instance */ void -e_calendar_view_component_created_cb (ECalModel *model, - ECalClient *client, - icalcomponent *original_icalcomp, - const gchar *new_uid, - gpointer user_data) +e_calendar_view_emit_user_created (ECalendarView *cal_view, + ECalClient *where_was_created) { - ECalendarView *cal_view = user_data; - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - e_cal_model_emit_object_created (model, client); + g_signal_emit (cal_view, signals[USER_CREATED], 0, where_was_created); } - void draw_curved_rectangle (cairo_t *cr, gdouble x0, @@ -2179,110 +2493,3 @@ return is_editing; } - -/* Returns text description of the current view. */ -gchar * -e_calendar_view_get_description_text (ECalendarView *cal_view) -{ - time_t start_time, end_time; - struct tm start_tm, end_tm; - struct icaltimetype start_tt, end_tt; - icaltimezone *zone; - gchar buffer[1024] = { 0 }; - gchar end_buffer[512] = { 0 }; - - g_return_val_if_fail (E_IS_CALENDAR_VIEW (cal_view), NULL); - - if (!e_calendar_view_get_visible_time_range (cal_view, &start_time, &end_time)) - return NULL; - - zone = e_cal_model_get_timezone (cal_view->priv->model); - - start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone); - start_tm.tm_year = start_tt.year - 1900; - start_tm.tm_mon = start_tt.month - 1; - start_tm.tm_mday = start_tt.day; - start_tm.tm_hour = start_tt.hour; - start_tm.tm_min = start_tt.minute; - start_tm.tm_sec = start_tt.second; - start_tm.tm_isdst = -1; - start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1, start_tt.year); - - /* Subtract one from end_time so we don't get an extra day. */ - end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone); - end_tm.tm_year = end_tt.year - 1900; - end_tm.tm_mon = end_tt.month - 1; - end_tm.tm_mday = end_tt.day; - end_tm.tm_hour = end_tt.hour; - end_tm.tm_min = end_tt.minute; - end_tm.tm_sec = end_tt.second; - end_tm.tm_isdst = -1; - end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1, end_tt.year); - - if (E_IS_MONTH_VIEW (cal_view) || E_IS_CAL_LIST_VIEW (cal_view)) { - if (start_tm.tm_year == end_tm.tm_year) { - if (start_tm.tm_mon == end_tm.tm_mon) { - e_utf8_strftime (buffer, sizeof (buffer), - "%d", &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime (buffer, sizeof (buffer), - _("%d %b"), &start_tm); - e_utf8_strftime (end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } else { - e_utf8_strftime ( - buffer, sizeof (buffer), - _("%d %b %Y"), &start_tm); - e_utf8_strftime ( - end_buffer, sizeof (end_buffer), - _("%d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } else { - if (start_tm.tm_year == end_tm.tm_year && - start_tm.tm_mon == end_tm.tm_mon && - start_tm.tm_mday == end_tm.tm_mday) { - e_utf8_strftime ( - buffer, sizeof (buffer), - _("%A %d %b %Y"), &start_tm); - } else if (start_tm.tm_year == end_tm.tm_year) { - e_utf8_strftime ( - buffer, sizeof (buffer), - _("%a %d %b"), &start_tm); - e_utf8_strftime ( - end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } else { - e_utf8_strftime ( - buffer, sizeof (buffer), - _("%a %d %b %Y"), &start_tm); - e_utf8_strftime ( - end_buffer, sizeof (end_buffer), - _("%a %d %b %Y"), &end_tm); - strcat (buffer, " - "); - strcat (buffer, end_buffer); - } - } - - return g_strdup (buffer); -} - -void -e_calendar_view_move_view_range (ECalendarView *cal_view, - ECalendarViewMoveType mode_type, - time_t exact_date) -{ - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); - - g_signal_emit (cal_view, signals[MOVE_VIEW_RANGE], 0, mode_type, (gint64) exact_date); -} diff -Nru evolution-3.16.0/calendar/gui/e-calendar-view.h evolution-3.12.11/calendar/gui/e-calendar-view.h --- evolution-3.16.0/calendar/gui/e-calendar-view.h 2015-02-24 14:55:48.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-calendar-view.h 2014-03-24 09:25:23.000000000 +0000 @@ -26,6 +26,7 @@ #include #include "e-cal-model.h" +#include "gnome-cal.h" #include "dialogs/comp-editor.h" /* Standard GObject macros */ @@ -126,13 +127,6 @@ EDIT_EVENT_FORCE_APPOINTMENT } EEditEventMode; -typedef enum { - E_CALENDAR_VIEW_MOVE_PREVIOUS, - E_CALENDAR_VIEW_MOVE_NEXT, - E_CALENDAR_VIEW_MOVE_TO_TODAY, - E_CALENDAR_VIEW_MOVE_TO_EXACT_DAY -} ECalendarViewMoveType; - struct _ECalendarViewClass { GtkTableClass parent_class; @@ -148,9 +142,8 @@ ECalendarViewEvent *event); void (*event_added) (ECalendarView *day_view, ECalendarViewEvent *event); - void (*move_view_range) (ECalendarView *cal_view, - ECalendarViewMoveType move_type, - gint64 exact_date); + void (*user_created) (ECalendarView *cal_view, + ECalClient *where_was_created); /* Virtual methods */ GList * (*get_selected_events) (ECalendarView *cal_view); @@ -166,27 +159,33 @@ (ECalendarView *cal_view, time_t *start_time, time_t *end_time); - void (*precalc_visible_time_range) - (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time); void (*update_query) (ECalendarView *cal_view); void (*open_event) (ECalendarView *cal_view); void (*paste_text) (ECalendarView *cal_view); }; GType e_calendar_view_get_type (void); +GnomeCalendar * e_calendar_view_get_calendar (ECalendarView *cal_view); +void e_calendar_view_set_calendar (ECalendarView *cal_view, + GnomeCalendar *calendar); ECalModel * e_calendar_view_get_model (ECalendarView *cal_view); icaltimezone * e_calendar_view_get_timezone (ECalendarView *cal_view); void e_calendar_view_set_timezone (ECalendarView *cal_view, icaltimezone *zone); +const gchar * e_calendar_view_get_default_category + (ECalendarView *cal_view); +void e_calendar_view_set_default_category + (ECalendarView *cal_view, + const gchar *category); gint e_calendar_view_get_time_divisions (ECalendarView *cal_view); void e_calendar_view_set_time_divisions (ECalendarView *cal_view, gint time_divisions); +void e_calendar_view_set_status_message + (ECalendarView *cal_view, + const gchar *message, + gint percent); GtkTargetList * e_calendar_view_get_copy_target_list (ECalendarView *cal_view); GtkTargetList * e_calendar_view_get_paste_target_list @@ -206,12 +205,6 @@ (ECalendarView *cal_view, time_t *start_time, time_t *end_time); -void e_calendar_view_precalc_visible_time_range - (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time); void e_calendar_view_update_query (ECalendarView *cal_view); void e_calendar_view_delete_selected_occurrence @@ -225,12 +218,18 @@ void e_calendar_view_popup_event (ECalendarView *cal_view, GdkEvent *button_event); -void e_calendar_view_add_event (ECalendarView *cal_view, +gboolean e_calendar_view_add_event (ECalendarView *cal_view, ECalClient *client, time_t dtstart, icaltimezone *default_zone, icalcomponent *icalcomp, gboolean in_top_canvas); +void e_calendar_view_new_appointment_for + (ECalendarView *cal_view, + time_t dtstart, + time_t dtend, + gboolean all_day, + gboolean meeting); void e_calendar_view_new_appointment_full (ECalendarView *cal_view, gboolean all_day, @@ -243,11 +242,23 @@ icalcomponent *icalcomp, EEditEventMode mode); void e_calendar_view_open_event (ECalendarView *cal_view); -gchar * e_calendar_view_get_description_text - (ECalendarView *cal_view); -void e_calendar_view_move_view_range (ECalendarView *cal_view, - ECalendarViewMoveType mode_type, - time_t exact_date); +void e_calendar_view_modify_and_send (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean new); +gboolean e_calendar_view_modify (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod); +void e_calendar_view_send (ECalendarView *cal_view, + ECalComponent *comp, + ECalClient *client, + CalObjModType mod, + GtkWindow *toplevel, + gboolean strip_alarms, + gboolean only_new_attendees); gboolean e_calendar_view_get_tooltips (const ECalendarViewEventData *data); void e_calendar_view_move_tip (GtkWidget *widget, @@ -259,12 +270,9 @@ icalcomponent *icalcomp, gboolean *free_text); -void e_calendar_view_component_created_cb - (ECalModel *model, - ECalClient *client, - icalcomponent *original_icalcomp, - const gchar *new_uid, - gpointer user_data); +void e_calendar_view_emit_user_created + (ECalendarView *cal_view, + ECalClient *where_was_created); void draw_curved_rectangle (cairo_t *cr, gdouble x0, diff -Nru evolution-3.16.0/calendar/gui/e-cal-list-view.c evolution-3.12.11/calendar/gui/e-cal-list-view.c --- evolution-3.16.0/calendar/gui/e-cal-list-view.c 2015-02-24 14:57:11.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-list-view.c 2014-07-07 10:56:09.000000000 +0000 @@ -37,6 +37,7 @@ #include "e-cal-model-calendar.h" #include "e-cell-date-edit-text.h" #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/goto-dialog.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" @@ -196,13 +197,13 @@ "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL); - e_binding_bind_property ( + g_object_bind_property ( model, "timezone", cell, "timezone", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | @@ -212,7 +213,7 @@ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); g_object_unref (cell); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", popup_cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | diff -Nru evolution-3.16.0/calendar/gui/e-cal-list-view.h evolution-3.12.11/calendar/gui/e-cal-list-view.h --- evolution-3.16.0/calendar/gui/e-cal-list-view.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-list-view.h 2014-03-24 09:25:23.000000000 +0000 @@ -29,6 +29,7 @@ #include #include "e-calendar-view.h" +#include "gnome-cal.h" /* * ECalListView - displays calendar events in an ETable. diff -Nru evolution-3.16.0/calendar/gui/e-cal-model.c evolution-3.12.11/calendar/gui/e-cal-model.c --- evolution-3.16.0/calendar/gui/e-cal-model.c 2015-02-02 12:58:06.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model.c 2014-12-09 15:01:10.000000000 +0000 @@ -33,15 +33,12 @@ #include #include -#include "dialogs/recur-comp.h" -#include "dialogs/send-comp.h" #include "comp-util.h" -#include "e-cal-data-model-subscriber.h" -#include "e-cal-ops.h" +#include "e-cal-model.h" #include "itip-utils.h" #include "misc.h" -#include "e-cal-model.h" +typedef struct _ClientData ClientData; struct _ECalModelComponentPrivate { GString *categories_str; @@ -55,19 +52,39 @@ (G_TYPE_INSTANCE_GET_PRIVATE \ ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentPrivate)) +struct _ClientData { + volatile gint ref_count; + GWeakRef model; + ECalClient *client; + + GMutex view_lock; + gboolean do_query; + ECalClientView *view; + GCancellable *cancellable; + + gulong backend_died_handler_id; + gulong objects_added_handler_id; + gulong objects_modified_handler_id; + gulong objects_removed_handler_id; + gulong progress_handler_id; + gulong complete_handler_id; +}; + struct _ECalModelPrivate { - ECalDataModel *data_model; ESourceRegistry *registry; - EShell *shell; - EClientCache *client_cache; - /* The default source uid of an ECalClient */ - gchar *default_source_uid; + /* Queue of ClientData structs */ + GQueue clients; + GMutex clients_lock; + + /* The default client in the list */ + ECalClient *default_client; /* Array for storing the objects. Each element is of type ECalModelComponent */ GPtrArray *objects; icalcomponent_kind kind; + ECalModelFlags flags; icaltimezone *zone; /* The time range to display */ @@ -77,6 +94,9 @@ /* The search regular expression */ gchar *search_sexp; + /* The full regular expression, including time range */ + gchar *full_sexp; + /* The default category */ gchar *default_category; @@ -110,6 +130,18 @@ /* Ask user to confirm before deleting components. */ gboolean confirm_delete; + + gboolean in_added; + gboolean in_modified; + gboolean in_removed; + + GHashTable *notify_added; + GHashTable *notify_modified; + GHashTable *notify_removed; + + GMutex notify_lock; + + GCancellable *loading_clients; }; typedef struct { @@ -119,17 +151,19 @@ static const gchar *cal_model_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data); +static gboolean add_new_client (ECalModel *model, ECalClient *client, gboolean do_query); +static void remove_client_objects (ECalModel *model, ClientData *client_data); +static void remove_client (ECalModel *model, ClientData *client_data); +static void redo_queries (ECalModel *model); + enum { PROP_0, - PROP_CLIENT_CACHE, PROP_COMPRESS_WEEKEND, PROP_CONFIRM_DELETE, - PROP_DATA_MODEL, + PROP_DEFAULT_CLIENT, PROP_DEFAULT_REMINDER_INTERVAL, PROP_DEFAULT_REMINDER_UNITS, - PROP_DEFAULT_SOURCE_UID, PROP_REGISTRY, - PROP_SHELL, PROP_TIMEZONE, PROP_USE_24_HOUR_FORMAT, PROP_USE_DEFAULT_REMINDER, @@ -151,95 +185,236 @@ TIME_RANGE_CHANGED, ROW_APPENDED, COMPS_DELETED, + CAL_VIEW_PROGRESS, + CAL_VIEW_COMPLETE, + STATUS_MESSAGE, TIMEZONE_CHANGED, - OBJECT_CREATED, LAST_SIGNAL }; /* Forward Declarations */ -static void e_cal_model_table_model_init (ETableModelInterface *iface); -static void e_cal_model_cal_data_model_subscriber_init (ECalDataModelSubscriberInterface *iface); +static void e_cal_model_table_model_init + (ETableModelInterface *iface); static guint signals[LAST_SIGNAL]; -G_DEFINE_ABSTRACT_TYPE_WITH_CODE (ECalModel, e_cal_model, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL) - G_IMPLEMENT_INTERFACE (E_TYPE_TABLE_MODEL, e_cal_model_table_model_init) - G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, e_cal_model_cal_data_model_subscriber_init)) - -G_DEFINE_TYPE (ECalModelComponent, e_cal_model_component, G_TYPE_OBJECT) +G_DEFINE_TYPE_WITH_CODE ( + ECalModel, + e_cal_model, + G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE ( + E_TYPE_EXTENSIBLE, NULL) + G_IMPLEMENT_INTERFACE ( + E_TYPE_TABLE_MODEL, + e_cal_model_table_model_init)) + +G_DEFINE_TYPE ( + ECalModelComponent, + e_cal_model_component, + G_TYPE_OBJECT) static void -e_cal_model_component_set_icalcomponent (ECalModelComponent *comp_data, - ECalModel *model, - icalcomponent *icalcomp) +client_data_backend_died_cb (ECalClient *client, + ClientData *client_data) { - if (model != NULL) - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (comp_data != NULL); + ECalModel *model; - #define free_ptr(x) { \ - if (x) { \ - g_free (x); \ - x = NULL; \ - } \ + model = g_weak_ref_get (&client_data->model); + if (model != NULL) { + e_cal_model_remove_client (model, client); + g_object_unref (model); } +} - if (comp_data->icalcomp) - icalcomponent_free (comp_data->icalcomp); - comp_data->icalcomp = icalcomp; +static ClientData * +client_data_new (ECalModel *model, + ECalClient *client, + gboolean do_query) +{ + ClientData *client_data; + gulong handler_id; - if (comp_data->priv->categories_str) - g_string_free (comp_data->priv->categories_str, TRUE); - comp_data->priv->categories_str = NULL; + client_data = g_slice_new0 (ClientData); + client_data->ref_count = 1; + g_weak_ref_set (&client_data->model, model); + client_data->client = g_object_ref (client); + client_data->do_query = do_query; - free_ptr (comp_data->dtstart); - free_ptr (comp_data->dtend); - free_ptr (comp_data->due); - free_ptr (comp_data->completed); - free_ptr (comp_data->created); - free_ptr (comp_data->lastmodified); - free_ptr (comp_data->color); + g_mutex_init (&client_data->view_lock); - #undef free_ptr + handler_id = g_signal_connect ( + client_data->client, "backend-died", + G_CALLBACK (client_data_backend_died_cb), client_data); + client_data->backend_died_handler_id = handler_id; - if (comp_data->icalcomp && model) - e_cal_model_set_instance_times (comp_data, model->priv->zone); + return client_data; } static void -e_cal_model_component_finalize (GObject *object) +client_data_disconnect_view_handlers (ClientData *client_data) { - ECalModelComponent *comp_data = E_CAL_MODEL_COMPONENT (object); + /* This MUST be called with the view_lock acquired. */ - if (comp_data->client) { - g_object_unref (comp_data->client); - comp_data->client = NULL; + g_return_if_fail (client_data->view != NULL); + + if (client_data->objects_added_handler_id > 0) { + g_signal_handler_disconnect ( + client_data->view, + client_data->objects_added_handler_id); + client_data->objects_added_handler_id = 0; } - e_cal_model_component_set_icalcomponent (comp_data, NULL, NULL); + if (client_data->objects_modified_handler_id > 0) { + g_signal_handler_disconnect ( + client_data->view, + client_data->objects_modified_handler_id); + client_data->objects_modified_handler_id = 0; + } - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_cal_model_component_parent_class)->finalize (object); + if (client_data->objects_removed_handler_id > 0) { + g_signal_handler_disconnect ( + client_data->view, + client_data->objects_removed_handler_id); + client_data->objects_removed_handler_id = 0; + } + + if (client_data->progress_handler_id > 0) { + g_signal_handler_disconnect ( + client_data->view, + client_data->progress_handler_id); + client_data->progress_handler_id = 0; + } + + if (client_data->complete_handler_id > 0) { + g_signal_handler_disconnect ( + client_data->view, + client_data->complete_handler_id); + client_data->complete_handler_id = 0; + } } -/* Class initialization function for the calendar component object */ -static void -e_cal_model_component_class_init (ECalModelComponentClass *class) +static ClientData * +client_data_ref (ClientData *client_data) { - GObjectClass *object_class; + g_return_val_if_fail (client_data != NULL, NULL); + g_return_val_if_fail (client_data->ref_count > 0, NULL); - object_class = (GObjectClass *) class; - g_type_class_add_private (class, sizeof (ECalModelComponentPrivate)); + g_atomic_int_inc (&client_data->ref_count); - object_class->finalize = e_cal_model_component_finalize; + return client_data; } static void -e_cal_model_component_init (ECalModelComponent *comp) +client_data_unref (ClientData *client_data) { - comp->priv = E_CAL_MODEL_COMPONENT_GET_PRIVATE (comp); - comp->is_new_component = FALSE; + g_return_if_fail (client_data != NULL); + g_return_if_fail (client_data->ref_count > 0); + + if (g_atomic_int_dec_and_test (&client_data->ref_count)) { + + g_signal_handler_disconnect ( + client_data->client, + client_data->backend_died_handler_id); + + if (client_data->view != NULL) + client_data_disconnect_view_handlers (client_data); + + g_weak_ref_set (&client_data->model, NULL); + + g_clear_object (&client_data->client); + g_clear_object (&client_data->view); + g_clear_object (&client_data->cancellable); + + g_mutex_clear (&client_data->view_lock); + + g_slice_free (ClientData, client_data); + } +} + +static GList * +cal_model_clients_list (ECalModel *model) +{ + GList *list, *head; + + g_mutex_lock (&model->priv->clients_lock); + + head = g_queue_peek_head_link (&model->priv->clients); + list = g_list_copy_deep (head, (GCopyFunc) client_data_ref, NULL); + + g_mutex_unlock (&model->priv->clients_lock); + + return list; +} + +static ClientData * +cal_model_clients_lookup (ECalModel *model, + ECalClient *client) +{ + ClientData *client_data = NULL; + GList *list, *link; + + list = cal_model_clients_list (model); + + for (link = list; link != NULL; link = g_list_next (link)) { + ClientData *candidate = link->data; + + if (candidate->client == client) { + client_data = client_data_ref (candidate); + break; + } + } + + g_list_free_full (list, (GDestroyNotify) client_data_unref); + + return client_data; +} + +static ClientData * +cal_model_clients_peek (ECalModel *model) +{ + ClientData *client_data; + + g_mutex_lock (&model->priv->clients_lock); + + client_data = g_queue_peek_head (&model->priv->clients); + if (client_data != NULL) + client_data_ref (client_data); + + g_mutex_unlock (&model->priv->clients_lock); + + return client_data; +} + +static ClientData * +cal_model_clients_pop (ECalModel *model) +{ + ClientData *client_data; + + g_mutex_lock (&model->priv->clients_lock); + + client_data = g_queue_pop_head (&model->priv->clients); + + g_mutex_unlock (&model->priv->clients_lock); + + return client_data; +} + +static gboolean +cal_model_clients_remove (ECalModel *model, + ClientData *client_data) +{ + gboolean removed = FALSE; + + g_mutex_lock (&model->priv->clients_lock); + + if (g_queue_remove (&model->priv->clients, client_data)) { + client_data_unref (client_data); + removed = TRUE; + } + + g_mutex_unlock (&model->priv->clients_lock); + + return removed; } static gpointer @@ -343,7 +518,7 @@ && e_cal_client_get_timezone_sync (comp_data->client, icaltime_get_tzid (tt_start), &zone, NULL, NULL)) got_zone = TRUE; - if (e_cal_data_model_get_expand_recurrences (priv->data_model)) { + if (e_cal_model_get_flags (model) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) { if (got_zone) { tt_start = icaltime_from_timet_with_zone (comp_data->instance_start, tt_start.is_date, zone); if (priv->zone) @@ -579,20 +754,6 @@ } static void -cal_model_set_data_model (ECalModel *model, - ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (model->priv->data_model == NULL); - - /* Be aware of a circular dependency, once this @model is subscribed to - the @data_model, then the @data_model increases reference count - of the @model. - */ - model->priv->data_model = g_object_ref (data_model); -} - -static void cal_model_set_registry (ECalModel *model, ESourceRegistry *registry) { @@ -603,25 +764,6 @@ } static void -cal_model_set_shell (ECalModel *model, - EShell *shell) -{ - EClientCache *client_cache; - - g_return_if_fail (E_IS_SHELL (shell)); - g_return_if_fail (model->priv->shell == NULL); - - model->priv->shell = g_object_ref (shell); - - client_cache = e_shell_get_client_cache (shell); - - g_return_if_fail (E_IS_CLIENT_CACHE (client_cache)); - g_return_if_fail (model->priv->client_cache == NULL); - - model->priv->client_cache = g_object_ref (client_cache); -} - -static void cal_model_set_property (GObject *object, guint property_id, const GValue *value, @@ -640,18 +782,12 @@ g_value_get_boolean (value)); return; - case PROP_DATA_MODEL: - cal_model_set_data_model ( + case PROP_DEFAULT_CLIENT: + e_cal_model_set_default_client ( E_CAL_MODEL (object), g_value_get_object (value)); return; - case PROP_DEFAULT_SOURCE_UID: - e_cal_model_set_default_source_uid ( - E_CAL_MODEL (object), - g_value_get_string (value)); - return; - case PROP_DEFAULT_REMINDER_INTERVAL: e_cal_model_set_default_reminder_interval ( E_CAL_MODEL (object), @@ -670,12 +806,6 @@ g_value_get_object (value)); return; - case PROP_SHELL: - cal_model_set_shell ( - E_CAL_MODEL (object), - g_value_get_object (value)); - return; - case PROP_TIMEZONE: e_cal_model_set_timezone ( E_CAL_MODEL (object), @@ -784,13 +914,6 @@ GParamSpec *pspec) { switch (property_id) { - case PROP_CLIENT_CACHE: - g_value_set_object ( - value, - e_cal_model_get_client_cache ( - E_CAL_MODEL (object))); - return; - case PROP_COMPRESS_WEEKEND: g_value_set_boolean ( value, @@ -805,17 +928,10 @@ E_CAL_MODEL (object))); return; - case PROP_DATA_MODEL: - g_value_set_object ( - value, - e_cal_model_get_data_model ( - E_CAL_MODEL (object))); - return; - - case PROP_DEFAULT_SOURCE_UID: - g_value_set_string ( + case PROP_DEFAULT_CLIENT: + g_value_take_object ( value, - e_cal_model_get_default_source_uid ( + e_cal_model_ref_default_client ( E_CAL_MODEL (object))); return; @@ -840,13 +956,6 @@ E_CAL_MODEL (object))); return; - case PROP_SHELL: - g_value_set_object ( - value, - e_cal_model_get_shell ( - E_CAL_MODEL (object))); - return; - case PROP_TIMEZONE: g_value_set_pointer ( value, @@ -972,13 +1081,21 @@ priv = E_CAL_MODEL_GET_PRIVATE (object); - g_clear_object (&priv->data_model); - g_clear_object (&priv->registry); - g_clear_object (&priv->shell); - g_clear_object (&priv->client_cache); + if (priv->registry != NULL) { + g_object_unref (priv->registry); + priv->registry = NULL; + } + + if (priv->loading_clients) { + g_cancellable_cancel (priv->loading_clients); + g_object_unref (priv->loading_clients); + priv->loading_clients = NULL; + } + + while (!g_queue_is_empty (&priv->clients)) + client_data_unref (g_queue_pop_head (&priv->clients)); - g_free (priv->default_source_uid); - priv->default_source_uid = NULL; + priv->default_client = NULL; /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_cal_model_parent_class)->dispose (object); @@ -992,6 +1109,11 @@ priv = E_CAL_MODEL_GET_PRIVATE (object); + g_mutex_clear (&priv->clients_lock); + + g_free (priv->search_sexp); + g_free (priv->full_sexp); + g_free (priv->default_category); for (ii = 0; ii < priv->objects->len; ii++) { @@ -1006,6 +1128,12 @@ } g_ptr_array_free (priv->objects, TRUE); + g_mutex_clear (&priv->notify_lock); + + g_hash_table_destroy (priv->notify_added); + g_hash_table_destroy (priv->notify_modified); + g_hash_table_destroy (priv->notify_removed); + /* Chain up to parent's finalize() method. */ G_OBJECT_CLASS (e_cal_model_parent_class)->finalize (object); } @@ -1101,211 +1229,80 @@ return priv->objects->len; } -static const gchar * -cal_model_kind_to_extension_name (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - switch (model->priv->kind) { - case ICAL_VEVENT_COMPONENT: - return E_SOURCE_EXTENSION_CALENDAR; - case ICAL_VJOURNAL_COMPONENT: - return E_SOURCE_EXTENSION_MEMO_LIST; - case ICAL_VTODO_COMPONENT: - return E_SOURCE_EXTENSION_TASK_LIST; - default: - g_warn_if_reached (); - break; - } - - return NULL; -} - -typedef struct { - ECalModel *model; - ETableModel *table_model; - GHashTable *values; - gboolean success; -} CreateComponentData; - -static void -create_component_data_free (gpointer ptr) -{ - CreateComponentData *ccd = ptr; - - if (ccd) { - GHashTableIter iter; - gpointer key, value; - - g_hash_table_iter_init (&iter, ccd->values); - while (g_hash_table_iter_next (&iter, &key, &value)) { - gint column = GPOINTER_TO_INT (key); - - e_table_model_free_value (ccd->table_model, column, value); - } - - if (ccd->success) - g_signal_emit (ccd->model, signals[ROW_APPENDED], 0); - - g_clear_object (&ccd->model); - g_clear_object (&ccd->table_model); - g_hash_table_destroy (ccd->values); - g_free (ccd); - } -} - static void -cal_model_create_component_from_values_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) +cal_model_append_row (ETableModel *etm, + ETableModel *source, + gint row) { - CreateComponentData *ccd = user_data; - EClientCache *client_cache; - ESourceRegistry *registry; - ESource *source; - EClient *client; + ECalModelClass *model_class; ECalModelComponent *comp_data; - const gchar *source_uid; - GError *local_error = NULL; - - g_return_if_fail (ccd != NULL); - - source_uid = e_cal_model_get_default_source_uid (ccd->model); - g_return_if_fail (source_uid != NULL); - - client_cache = e_cal_model_get_client_cache (ccd->model); - registry = e_cal_model_get_registry (ccd->model); + ECalModel *model = (ECalModel *) etm; + gchar *uid = NULL; + GError *error = NULL; - source = e_source_registry_ref_source (registry, source_uid); - if (!source) { - g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - _("Source with UID '%s' not found"), source_uid); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, source_uid); - return; - } + g_return_if_fail (E_IS_CAL_MODEL (model)); + g_return_if_fail (E_IS_TABLE_MODEL (source)); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); + comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); - client = e_client_cache_get_client_sync (client_cache, source, - cal_model_kind_to_extension_name (ccd->model), (guint32) -1, cancellable, &local_error); - g_clear_object (&source); + comp_data->client = e_cal_model_ref_default_client (model); - if (!client) { - e_util_propagate_open_source_job_error (job_data, - cal_model_kind_to_extension_name (ccd->model), local_error, error); + if (comp_data->client == NULL) { + g_object_unref (comp_data); return; } - comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); - comp_data->client = g_object_ref (client); - comp_data->icalcomp = e_cal_model_create_component_with_defaults_sync (ccd->model, comp_data->client, FALSE, cancellable, error); + comp_data->icalcomp = e_cal_model_create_component_with_defaults (model, FALSE); - if (comp_data->icalcomp) { - ECalModelClass *model_class; - gchar *uid = NULL; - gpointer dtstart; - - /* set values for our fields */ - set_categories (comp_data, e_cal_model_util_get_value (ccd->values, E_CAL_MODEL_FIELD_CATEGORIES)); - set_classification (comp_data, e_cal_model_util_get_value (ccd->values, E_CAL_MODEL_FIELD_CLASSIFICATION)); - set_description (comp_data, e_cal_model_util_get_value (ccd->values, E_CAL_MODEL_FIELD_DESCRIPTION)); - set_summary (comp_data, e_cal_model_util_get_value (ccd->values, E_CAL_MODEL_FIELD_SUMMARY)); - - dtstart = e_cal_model_util_get_value (ccd->values, E_CAL_MODEL_FIELD_DTSTART); - if (dtstart) { - set_dtstart (ccd->model, comp_data, dtstart); - } else if (ccd->model->priv->get_default_time) { - time_t tt = ccd->model->priv->get_default_time (ccd->model, ccd->model->priv->get_default_time_user_data); - - if (tt > 0) { - struct icaltimetype itt = icaltime_from_timet_with_zone (tt, FALSE, e_cal_model_get_timezone (ccd->model)); - icalproperty *prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); - - if (prop) { - icalproperty_set_dtstart (prop, itt); - } else { - prop = icalproperty_new_dtstart (itt); - icalcomponent_add_property (comp_data->icalcomp, prop); - } + /* set values for our fields */ + set_categories (comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CATEGORIES, row)); + set_classification (comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_CLASSIFICATION, row)); + set_description (comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DESCRIPTION, row)); + set_summary (comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_SUMMARY, row)); + + if (e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)) { + set_dtstart (model, comp_data, e_table_model_value_at (source, E_CAL_MODEL_FIELD_DTSTART, row)); + } else if (model->priv->get_default_time) { + time_t tt = model->priv->get_default_time (model, model->priv->get_default_time_user_data); + + if (tt > 0) { + struct icaltimetype itt = icaltime_from_timet_with_zone (tt, FALSE, e_cal_model_get_timezone (model)); + icalproperty *prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); + + if (prop) { + icalproperty_set_dtstart (prop, itt); + } else { + prop = icalproperty_new_dtstart (itt); + icalcomponent_add_property (comp_data->icalcomp, prop); } } + } - /* call the class' method for filling the component */ - model_class = E_CAL_MODEL_GET_CLASS (ccd->model); - if (model_class->fill_component_from_values != NULL) { - model_class->fill_component_from_values (ccd->model, comp_data, ccd->values); - } - - ccd->success = e_cal_client_create_object_sync (comp_data->client, comp_data->icalcomp, &uid, cancellable, error); - - g_free (uid); + /* call the class' method for filling the component */ + model_class = (ECalModelClass *) G_OBJECT_GET_CLASS (model); + if (model_class->fill_component_from_model != NULL) { + model_class->fill_component_from_model (model, comp_data, source, row); } - g_object_unref (comp_data); - g_object_unref (client); -} + e_cal_client_create_object_sync ( + comp_data->client, comp_data->icalcomp, &uid, NULL, &error); -static void -cal_model_append_row (ETableModel *etm, - ETableModel *source, - gint row) -{ - ECalModelClass *model_class; - ECalModel *model = (ECalModel *) etm; - GHashTable *values; - GCancellable *cancellable; - CreateComponentData *ccd; - const gchar *description; - const gchar *alert_ident; + if (error != NULL) { + g_warning ( + G_STRLOC ": Could not create the object! %s", + error->message); - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_TABLE_MODEL (source)); + /* FIXME: show error dialog */ + g_error_free (error); + } else { + if (uid) + icalcomponent_set_uid (comp_data->icalcomp, uid); - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - description = _("Creating an event"); - alert_ident = "calendar:failed-create-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - description = _("Creating a memo"); - alert_ident = "calendar:failed-create-memo"; - break; - case ICAL_VTODO_COMPONENT: - description = _("Creating a task"); - alert_ident = "calendar:failed-create-task"; - break; - default: - g_warn_if_reached (); - return; + g_signal_emit (model, signals[ROW_APPENDED], 0); } - values = g_hash_table_new (g_direct_hash, g_direct_equal); - - /* store values for our fields */ - e_cal_model_util_set_value (values, source, E_CAL_MODEL_FIELD_CATEGORIES, row); - e_cal_model_util_set_value (values, source, E_CAL_MODEL_FIELD_CLASSIFICATION, row); - e_cal_model_util_set_value (values, source, E_CAL_MODEL_FIELD_DESCRIPTION, row); - e_cal_model_util_set_value (values, source, E_CAL_MODEL_FIELD_SUMMARY, row); - e_cal_model_util_set_value (values, source, E_CAL_MODEL_FIELD_DTSTART, row); - - /* call the class' method to store other values */ - model_class = E_CAL_MODEL_GET_CLASS (model); - if (model_class->store_values_from_model != NULL) { - model_class->store_values_from_model (model, source, row, values); - } - - ccd = g_new0 (CreateComponentData, 1); - ccd->model = g_object_ref (model); - ccd->table_model = g_object_ref (source); - ccd->values = values; - ccd->success = FALSE; - - cancellable = e_cal_data_model_submit_thread_job (model->priv->data_model, description, - alert_ident, NULL, cal_model_create_component_from_values_thread, - ccd, create_component_data_free); - - g_clear_object (&cancellable); + g_free (uid); + g_object_unref (comp_data); } static gpointer @@ -1420,7 +1417,7 @@ ECalModelPrivate *priv; ECalModelComponent *comp_data; ECalModel *model = (ECalModel *) etm; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + GError *error = NULL; g_return_if_fail (E_IS_CAL_MODEL (model)); @@ -1450,10 +1447,19 @@ break; } - if (!recur_icalcomp_dialog (comp_data->client, comp_data->icalcomp, &mod, NULL, FALSE)) - return; + /* FIXME ask about mod type */ + e_cal_client_modify_object_sync ( + comp_data->client, comp_data->icalcomp, + CALOBJ_MOD_ALL, NULL, &error); + + if (error != NULL) { + g_warning ( + G_STRLOC ": Could not modify the object! %s", + error->message); - e_cal_ops_modify_component (model, comp_data->client, comp_data->icalcomp, mod, E_CAL_OPS_SEND_FLAG_DONT_SEND); + /* FIXME Show error dialog */ + g_error_free (error); + } } static gboolean @@ -1655,252 +1661,51 @@ return g_strdup (""); } -static gint -e_cal_model_get_component_index (ECalModel *model, - ECalClient *client, - const ECalComponentId *id) +static void +e_cal_model_class_init (ECalModelClass *class) { - gint ii; + GObjectClass *object_class; - for (ii = 0; ii < model->priv->objects->len; ii++) { - ECalModelComponent *comp_data = g_ptr_array_index (model->priv->objects, ii); + g_type_class_add_private (class, sizeof (ECalModelPrivate)); - if (comp_data) { - const gchar *uid; - gchar *rid = NULL; - struct icaltimetype icalrid; - gboolean has_rid = (id->rid && *id->rid); + object_class = G_OBJECT_CLASS (class); + object_class->set_property = cal_model_set_property; + object_class->get_property = cal_model_get_property; + object_class->constructed = cal_model_constructed; + object_class->dispose = cal_model_dispose; + object_class->finalize = cal_model_finalize; - uid = icalcomponent_get_uid (comp_data->icalcomp); - icalrid = icalcomponent_get_recurrenceid (comp_data->icalcomp); - if (!icaltime_is_null_time (icalrid)) - rid = icaltime_as_ical_string_r (icalrid); + class->get_color_for_component = cal_model_get_color_for_component; + class->fill_component_from_model = NULL; - if (uid && *uid) { - if ((!client || comp_data->client == client) && strcmp (id->uid, uid) == 0) { - if (has_rid) { - if (!(rid && *rid && strcmp (rid, id->rid) == 0)) { - g_free (rid); - continue; - } - } - g_free (rid); - return ii; - } - } - - g_free (rid); - } - } - - return -1; -} - -/* We do this check since the calendar items are downloaded from the server - * in the open_method, since the default timezone might not be set there. */ -static void -ensure_dates_are_in_default_zone (ECalModel *model, - icalcomponent *icalcomp) -{ - icaltimetype dt; - icaltimezone *zone; - - zone = e_cal_model_get_timezone (model); - if (!zone) - return; - - dt = icalcomponent_get_dtstart (icalcomp); - if (dt.is_utc) { - dt = icaltime_convert_to_zone (dt, zone); - icalcomponent_set_dtstart (icalcomp, dt); - } - - dt = icalcomponent_get_dtend (icalcomp); - if (dt.is_utc) { - dt = icaltime_convert_to_zone (dt, zone); - icalcomponent_set_dtend (icalcomp, dt); - } -} - -static void -cal_model_data_subscriber_component_added_or_modified (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp, - gboolean is_added) -{ - ECalModel *model; - ECalModelComponent *comp_data; - ETableModel *table_model; - ECalComponentId *id; - icalcomponent *icalcomp; - gint index; - - model = E_CAL_MODEL (subscriber); - - id = e_cal_component_get_id (comp); - - index = e_cal_model_get_component_index (model, client, id); - - e_cal_component_free_id (id); - - if (index < 0 && !is_added) - return; - - table_model = E_TABLE_MODEL (model); - icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); - ensure_dates_are_in_default_zone (model, icalcomp); - - if (index < 0) { - e_table_model_pre_change (table_model); - - comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); - comp_data->is_new_component = FALSE; - comp_data->client = g_object_ref (client); - comp_data->icalcomp = icalcomp; - e_cal_model_set_instance_times (comp_data, model->priv->zone); - g_ptr_array_add (model->priv->objects, comp_data); - - e_table_model_row_inserted (table_model, model->priv->objects->len - 1); - } else { - e_table_model_pre_change (table_model); - - comp_data = g_ptr_array_index (model->priv->objects, index); - e_cal_model_component_set_icalcomponent (comp_data, model, icalcomp); - - e_table_model_row_changed (table_model, index); - } -} - -static void -e_cal_model_data_subscriber_component_added (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - cal_model_data_subscriber_component_added_or_modified (subscriber, client, comp, TRUE); -} - -static void -e_cal_model_data_subscriber_component_modified (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - cal_model_data_subscriber_component_added_or_modified (subscriber, client, comp, FALSE); -} - -static void -e_cal_model_data_subscriber_component_removed (ECalDataModelSubscriber *subscriber, - ECalClient *client, - const gchar *uid, - const gchar *rid) -{ - ECalModel *model; - ECalModelComponent *comp_data; - ETableModel *table_model; - ECalComponentId id; - GSList *link; - gint index; - - model = E_CAL_MODEL (subscriber); - - id.uid = (gchar *) uid; - id.rid = (gchar *) rid; - - index = e_cal_model_get_component_index (model, client, &id); - - if (index < 0) - return; - - table_model = E_TABLE_MODEL (model); - e_table_model_pre_change (table_model); - - comp_data = g_ptr_array_remove_index (model->priv->objects, index); - if (!comp_data) { - e_table_model_no_change (table_model); - return; - } - - link = g_slist_append (NULL, comp_data); - g_signal_emit (model, signals[COMPS_DELETED], 0, link); - - g_slist_free (link); - g_object_unref (comp_data); - - e_table_model_row_deleted (table_model, index); -} - -static void -e_cal_model_data_subscriber_freeze (ECalDataModelSubscriber *subscriber) -{ - /* No freeze/thaw, the ETableModel doesn't notify about changes when frozen */ - - /* ETableModel *table_model = E_TABLE_MODEL (subscriber); - e_table_model_freeze (table_model); */ -} - -static void -e_cal_model_data_subscriber_thaw (ECalDataModelSubscriber *subscriber) -{ - /* No freeze/thaw, the ETableModel doesn't notify about changes when frozen */ - - /* ETableModel *table_model = E_TABLE_MODEL (subscriber); - e_table_model_thaw (table_model); */ -} - -static void -e_cal_model_class_init (ECalModelClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ECalModelPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = cal_model_set_property; - object_class->get_property = cal_model_get_property; - object_class->constructed = cal_model_constructed; - object_class->dispose = cal_model_dispose; - object_class->finalize = cal_model_finalize; - - class->get_color_for_component = cal_model_get_color_for_component; - - g_object_class_install_property ( - object_class, - PROP_DATA_MODEL, - g_param_spec_object ( - "data-model", - "Calendar Data Model", - NULL, - E_TYPE_CAL_DATA_MODEL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property ( - object_class, - PROP_CLIENT_CACHE, - g_param_spec_object ( - "client-cache", - "Client Cache", - NULL, - E_TYPE_CLIENT_CACHE, - G_PARAM_READABLE)); + g_object_class_install_property ( + object_class, + PROP_COMPRESS_WEEKEND, + g_param_spec_boolean ( + "compress-weekend", + "Compress Weekend", + NULL, + FALSE, + G_PARAM_READWRITE)); g_object_class_install_property ( object_class, - PROP_COMPRESS_WEEKEND, + PROP_CONFIRM_DELETE, g_param_spec_boolean ( - "compress-weekend", - "Compress Weekend", + "confirm-delete", + "Confirm Delete", NULL, - FALSE, + TRUE, G_PARAM_READWRITE)); g_object_class_install_property ( object_class, - PROP_CONFIRM_DELETE, - g_param_spec_boolean ( - "confirm-delete", - "Confirm Delete", + PROP_DEFAULT_CLIENT, + g_param_spec_object ( + "default-client", + "Default ECalClient", NULL, - TRUE, + E_TYPE_CAL_CLIENT, G_PARAM_READWRITE)); g_object_class_install_property ( @@ -1928,16 +1733,6 @@ g_object_class_install_property ( object_class, - PROP_DEFAULT_SOURCE_UID, - g_param_spec_string ( - "default-source-uid", - "Default source UID of an ECalClient", - NULL, - NULL, - G_PARAM_READWRITE)); - - g_object_class_install_property ( - object_class, PROP_REGISTRY, g_param_spec_object ( "registry", @@ -1949,17 +1744,6 @@ g_object_class_install_property ( object_class, - PROP_SHELL, - g_param_spec_object ( - "shell", - "Shell", - "EShell", - E_TYPE_SHELL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property ( - object_class, PROP_TIMEZONE, g_param_spec_pointer ( "timezone", @@ -2161,6 +1945,40 @@ G_TYPE_NONE, 1, G_TYPE_POINTER); + signals[CAL_VIEW_PROGRESS] = g_signal_new ( + "cal_view_progress", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalModelClass, cal_view_progress), + NULL, NULL, + e_marshal_VOID__STRING_INT_INT, + G_TYPE_NONE, 3, + G_TYPE_STRING, + G_TYPE_INT, + G_TYPE_INT); + + signals[CAL_VIEW_COMPLETE] = g_signal_new ( + "cal_view_complete", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (ECalModelClass, cal_view_complete), + NULL, NULL, + e_marshal_VOID__BOXED_INT, + G_TYPE_NONE, 2, + G_TYPE_ERROR, + G_TYPE_INT); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ECalModelClass, status_message), + NULL, NULL, + e_marshal_VOID__STRING_DOUBLE, + G_TYPE_NONE, 2, + G_TYPE_STRING, + G_TYPE_DOUBLE); + signals[TIMEZONE_CHANGED] = g_signal_new ( "timezone-changed", G_TYPE_FROM_CLASS (class), @@ -2171,15 +1989,6 @@ G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_POINTER); - - signals[OBJECT_CREATED] = g_signal_new ( - "object-created", - G_TYPE_FROM_CLASS (class), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (ECalModelClass, object_created), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, E_TYPE_CAL_CLIENT); } static void @@ -2201,28 +2010,33 @@ } static void -e_cal_model_cal_data_model_subscriber_init (ECalDataModelSubscriberInterface *iface) -{ - iface->component_added = e_cal_model_data_subscriber_component_added; - iface->component_modified = e_cal_model_data_subscriber_component_modified; - iface->component_removed = e_cal_model_data_subscriber_component_removed; - iface->freeze = e_cal_model_data_subscriber_freeze; - iface->thaw = e_cal_model_data_subscriber_thaw; -} - -static void e_cal_model_init (ECalModel *model) { model->priv = E_CAL_MODEL_GET_PRIVATE (model); + g_mutex_init (&model->priv->clients_lock); + /* match none by default */ - model->priv->start = (time_t) -1; - model->priv->end = (time_t) -1; + model->priv->start = -1; + model->priv->end = -1; + model->priv->search_sexp = NULL; + model->priv->full_sexp = g_strdup ("#f"); model->priv->objects = g_ptr_array_new (); model->priv->kind = ICAL_NO_COMPONENT; + model->priv->flags = 0; model->priv->use_24_hour_format = TRUE; + + model->priv->in_added = FALSE; + model->priv->in_modified = FALSE; + model->priv->in_removed = FALSE; + model->priv->notify_added = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + model->priv->notify_modified = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + model->priv->notify_removed = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, NULL); + g_mutex_init (&model->priv->notify_lock); + + model->priv->loading_clients = g_cancellable_new (); } /* updates time in a component, and keeps the timezone used in it, if exists */ @@ -2299,7 +2113,7 @@ e_cal_model_test_row_editable (ECalModel *model, gint row) { - gboolean readonly = FALSE; + gboolean readonly; ECalClient *client = NULL; if (row != -1) { @@ -2310,44 +2124,13 @@ if (comp_data != NULL && comp_data->client != NULL) client = g_object_ref (comp_data->client); - readonly = (client == NULL); } else { - const gchar *source_uid; - - source_uid = e_cal_model_get_default_source_uid (model); - - /* if the source cannot be opened, then expect the client being writable; - there will be shown an error if not, when saving changes anyway */ - readonly = source_uid == NULL; - - if (source_uid != NULL) { - ESourceRegistry *registry = e_cal_model_get_registry (model); - EClientCache *client_cache = e_cal_model_get_client_cache (model); - ESource *source; - - source = e_source_registry_ref_source (registry, source_uid); - if (source) { - EClient *e_client; - - e_client = e_client_cache_ref_cached_client (client_cache, source, - cal_model_kind_to_extension_name (model)); - if (e_client) { - client = E_CAL_CLIENT (e_client); - } else { - const gchar *parent_uid = e_source_get_parent (source); - - /* There are couple known to be always read-only */ - readonly = g_strcmp0 (parent_uid, "webcal-stub") == 0 || - g_strcmp0 (parent_uid, "weather-stub") == 0 || - g_strcmp0 (parent_uid, "contacts-stub") == 0; - } - } - - g_clear_object (&source); - } + client = e_cal_model_ref_default_client (model); } - if (!readonly && client) + readonly = (client == NULL); + + if (!readonly) readonly = e_client_is_readonly (E_CLIENT (client)); g_clear_object (&client); @@ -2355,38 +2138,6 @@ return !readonly; } -ESourceRegistry * -e_cal_model_get_registry (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - return model->priv->registry; -} - -EShell * -e_cal_model_get_shell (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - return model->priv->shell; -} - -ECalDataModel * -e_cal_model_get_data_model (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - return model->priv->data_model; -} - -EClientCache * -e_cal_model_get_client_cache (ECalModel *model) -{ - g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - - return model->priv->client_cache; -} - gboolean e_cal_model_get_confirm_delete (ECalModel *model) { @@ -2426,6 +2177,31 @@ model->priv->kind = kind; } +ECalModelFlags +e_cal_model_get_flags (ECalModel *model) +{ + g_return_val_if_fail (E_IS_CAL_MODEL (model), 0); + + return model->priv->flags; +} + +void +e_cal_model_set_flags (ECalModel *model, + ECalModelFlags flags) +{ + g_return_if_fail (E_IS_CAL_MODEL (model)); + + model->priv->flags = flags; +} + +ESourceRegistry * +e_cal_model_get_registry (ECalModel *model) +{ + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); + + return model->priv->registry; +} + icaltimezone * e_cal_model_get_timezone (ECalModel *model) { @@ -2451,6 +2227,7 @@ /* the timezone affects the times shown for date fields, * so we need to redisplay everything */ e_table_model_changed (E_TABLE_MODEL (model)); + redo_queries (model); g_object_notify (G_OBJECT (model), "timezone"); g_signal_emit ( @@ -2803,31 +2580,99 @@ g_object_notify (G_OBJECT (model), "work-day-start-minute"); } -const gchar * -e_cal_model_get_default_source_uid (ECalModel *model) +ECalClient * +e_cal_model_ref_default_client (ECalModel *model) { + ClientData *client_data; + ECalClient *default_client = NULL; + g_return_val_if_fail (model != NULL, NULL); g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - if (model->priv->default_source_uid && !model->priv->default_source_uid) - return NULL; + if (model->priv->default_client != NULL) + return g_object_ref (model->priv->default_client); - return model->priv->default_source_uid; + client_data = cal_model_clients_peek (model); + if (client_data != NULL) { + default_client = g_object_ref (client_data->client); + client_data_unref (client_data); + } + + return default_client; } void -e_cal_model_set_default_source_uid (ECalModel *model, - const gchar *source_uid) +e_cal_model_set_default_client (ECalModel *model, + ECalClient *client) { + ECalModelPrivate *priv; + g_return_if_fail (E_IS_CAL_MODEL (model)); - if (g_strcmp0 (model->priv->default_source_uid, source_uid) == 0) + if (client != NULL) + g_return_if_fail (E_IS_CAL_CLIENT (client)); + + priv = model->priv; + + if (priv->default_client == client) return; - g_free (model->priv->default_source_uid); - model->priv->default_source_uid = g_strdup (source_uid); + if (priv->default_client == NULL) { + ClientData *client_data; + + client_data = cal_model_clients_lookup ( + model, priv->default_client); + if (client_data != NULL) { + if (!client_data->do_query) + remove_client (model, client_data); + client_data_unref (client_data); + } + } + + if (client != NULL) { + /* Make sure its in the model */ + add_new_client (model, client, FALSE); + + /* Store the default client */ + priv->default_client = client; + } else { + priv->default_client = NULL; + } + + g_object_notify (G_OBJECT (model), "default-client"); +} + +GList * +e_cal_model_list_clients (ECalModel *model) +{ + GQueue results = G_QUEUE_INIT; + GList *list, *link; + ECalClient *default_client; + + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); + + default_client = model->priv->default_client; + + list = cal_model_clients_list (model); + + for (link = list; link != NULL; link = g_list_next (link)) { + ClientData *client_data = link->data; + ECalClient *client; + + client = client_data->client; - g_object_notify (G_OBJECT (model), "default-source-uid"); + /* Exclude the default client if we're not querying it. */ + if (client == default_client) { + if (!client_data->do_query) + continue; + } + + g_queue_push_tail (&results, g_object_ref (client)); + } + + g_list_free_full (list, (GDestroyNotify) client_data_unref); + + return g_queue_peek_head_link (&results); } static ECalModelComponent * @@ -2871,32 +2716,1022 @@ return NULL; } -void -e_cal_model_remove_all_objects (ECalModel *model) +static void +remove_all_for_id_and_client (ECalModel *model, + ECalClient *client, + const ECalComponentId *id) { ECalModelComponent *comp_data; - ETableModel *table_model; - GSList *link; - gint index; - - table_model = E_TABLE_MODEL (model); - for (index = model->priv->objects->len - 1; index >= 0; index--) { - e_table_model_pre_change (table_model); - - comp_data = g_ptr_array_remove_index (model->priv->objects, index); - if (!comp_data) { - e_table_model_no_change (table_model); + + while ((comp_data = search_by_id_and_client (model->priv, client, id))) { + gint pos; + GSList *list = NULL; + + pos = get_position_in_array (model->priv->objects, comp_data); + + if (!g_ptr_array_remove (model->priv->objects, comp_data)) + continue; + + list = g_slist_append (list, comp_data); + g_signal_emit (model, signals[COMPS_DELETED], 0, list); + + g_slist_free (list); + g_object_unref (comp_data); + + e_table_model_pre_change (E_TABLE_MODEL (model)); + e_table_model_row_deleted (E_TABLE_MODEL (model), pos); + } +} + +typedef struct { + ECalClient *client; + ECalClientView *view; + ECalModel *model; + icalcomponent *icalcomp; +} RecurrenceExpansionData; + +static void +free_rdata (gpointer data) +{ + RecurrenceExpansionData *rdata = data; + + if (!rdata) + return; + + g_object_unref (rdata->client); + g_object_unref (rdata->view); + g_object_unref (rdata->model); + g_free (rdata); +} + +static gboolean +add_instance_cb (ECalComponent *comp, + time_t instance_start, + time_t instance_end, + gpointer user_data) +{ + ECalModelComponent *comp_data; + ECalModelPrivate *priv; + RecurrenceExpansionData *rdata = user_data; + icaltimetype time; + ECalComponentDateTime datetime, to_set; + icaltimezone *zone = NULL; + ECalComponentId *id; + + g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), TRUE); + + priv = rdata->model->priv; + + id = e_cal_component_get_id (comp); + remove_all_for_id_and_client (rdata->model, rdata->client, id); + e_cal_component_free_id (id); + + e_table_model_pre_change (E_TABLE_MODEL (rdata->model)); + + /* set the right instance start date to component */ + e_cal_component_get_dtstart (comp, &datetime); + if (datetime.tzid) + e_cal_client_get_timezone_sync (rdata->client, datetime.tzid, &zone, NULL, NULL); + time = icaltime_from_timet_with_zone (instance_start, FALSE, zone ? zone : priv->zone); + to_set.value = &time; + to_set.tzid = datetime.tzid; + e_cal_component_set_dtstart (comp, &to_set); + e_cal_component_free_datetime (&datetime); + + /* set the right instance end date to component*/ + e_cal_component_get_dtend (comp, &datetime); + zone = NULL; + if (datetime.tzid) + e_cal_client_get_timezone_sync (rdata->client, datetime.tzid, &zone, NULL, NULL); + time = icaltime_from_timet_with_zone (instance_end, FALSE, zone ? zone : priv->zone); + to_set.value = &time; + to_set.tzid = datetime.tzid; + e_cal_component_set_dtend (comp, &to_set); + e_cal_component_free_datetime (&datetime); + + comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); + comp_data->client = g_object_ref (rdata->client); + comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); + comp_data->instance_start = instance_start; + comp_data->instance_end = instance_end; + + g_ptr_array_add (priv->objects, comp_data); + e_table_model_row_inserted (E_TABLE_MODEL (rdata->model), priv->objects->len - 1); + + return TRUE; +} + +/* We do this check since the calendar items are downloaded from the server + * in the open_method, since the default timezone might not be set there. */ +static void +ensure_dates_are_in_default_zone (ECalModel *model, + icalcomponent *icalcomp) +{ + icaltimetype dt; + icaltimezone *zone; + + zone = e_cal_model_get_timezone (model); + if (!zone) + return; + + dt = icalcomponent_get_dtstart (icalcomp); + if (dt.is_utc) { + dt = icaltime_convert_to_zone (dt, zone); + icalcomponent_set_dtstart (icalcomp, dt); + } + + dt = icalcomponent_get_dtend (icalcomp); + if (dt.is_utc) { + dt = icaltime_convert_to_zone (dt, zone); + icalcomponent_set_dtend (icalcomp, dt); + } +} + +static gint +place_master_object_first_cb (gconstpointer p1, + gconstpointer p2) +{ + icalcomponent *c1 = (icalcomponent *) p1, *c2 = (icalcomponent *) p2; + const gchar *uid1, *uid2; + gint res; + + g_return_val_if_fail (c1 != NULL, 0); + g_return_val_if_fail (c2 != NULL, 0); + + uid1 = icalcomponent_get_uid (c1); + uid2 = icalcomponent_get_uid (c2); + + res = g_strcmp0 (uid1, uid2); + if (res == 0) { + struct icaltimetype rid1, rid2; + + rid1 = icalcomponent_get_recurrenceid (c1); + rid2 = icalcomponent_get_recurrenceid (c2); + + if (icaltime_is_null_time (rid1)) { + if (!icaltime_is_null_time (rid2)) + res = -1; + } else if (icaltime_is_null_time (rid2)) { + res = 1; + } else { + res = icaltime_compare (rid1, rid2); + } + } + + return res; +} + +static void +process_event (ECalClientView *view, + const GSList *objects, + ECalModel *model, + void (*process_fn) (ECalClientView *view, + const GSList *objects, + ECalModel *model), + gboolean *in, + GHashTable *save_hash, + gpointer (*copy_fn) (gpointer data), + void (*free_fn) (gpointer data)) +{ + gboolean skip = FALSE; + const GSList *l; + + g_return_if_fail (save_hash != NULL); + + g_mutex_lock (&model->priv->notify_lock); + if (*in) { + GSList *save_list = g_hash_table_lookup (save_hash, view); + + skip = TRUE; + for (l = objects; l; l = l->next) { + if (l->data) + save_list = g_slist_append (save_list, copy_fn (l->data)); + } + + g_hash_table_insert (save_hash, g_object_ref (view), save_list); + } else { + *in = TRUE; + } + + g_mutex_unlock (&model->priv->notify_lock); + + if (skip) + return; + + /* do it */ + process_fn (view, objects, model); + + g_mutex_lock (&model->priv->notify_lock); + while (g_hash_table_size (save_hash)) { + gpointer key = NULL, value = NULL; + GHashTableIter iter; + GSList *save_list; + + g_hash_table_iter_init (&iter, save_hash); + if (!g_hash_table_iter_next (&iter, &key, &value)) { + g_debug ("%s: Failed to get first item of the save_hash", G_STRFUNC); + break; + } + + save_list = value; + view = g_object_ref (key); + + g_hash_table_remove (save_hash, view); + + g_mutex_unlock (&model->priv->notify_lock); + + /* do it */ + process_fn (view, save_list, model); + + for (l = save_list; l; l = l->next) { + if (l->data) { + free_fn (l->data); + } + } + g_slist_free (save_list); + g_object_unref (view); + + g_mutex_lock (&model->priv->notify_lock); + } + + *in = FALSE; + g_mutex_unlock (&model->priv->notify_lock); +} + +static void +process_added (ECalClientView *view, + const GSList *objects, + ECalModel *model) +{ + ECalModelPrivate *priv; + const GSList *l; + GSList *copy; + + priv = model->priv; + + /* order matters, process master object first, then detached instances */ + copy = g_slist_sort (g_slist_copy ((GSList *) objects), place_master_object_first_cb); + + for (l = copy; l; l = l->next) { + ECalModelComponent *comp_data; + ECalComponentId *id; + ECalComponent *comp = e_cal_component_new (); + ECalClient *client = e_cal_client_view_get_client (view); + + /* This will fail for alarm or VCalendar component */ + if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) { + g_object_unref (comp); + continue; + } + + id = e_cal_component_get_id (comp); + + /* remove the components if they are already present and re-add them */ + remove_all_for_id_and_client (model, client, id); + + e_cal_component_free_id (id); + g_object_unref (comp); + ensure_dates_are_in_default_zone (model, l->data); + + if (e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) { + ClientData *client_data; + + client_data = cal_model_clients_lookup (model, client); + + if (client_data != NULL) { + RecurrenceExpansionData *rdata = g_new0 (RecurrenceExpansionData, 1); + rdata->client = g_object_ref (client); + rdata->view = g_object_ref (view); + rdata->model = g_object_ref (model); + + e_cal_client_generate_instances_for_object (rdata->client, l->data, priv->start, priv->end, client_data->cancellable, + (ECalRecurInstanceFn) add_instance_cb, rdata, free_rdata); + + client_data_unref (client_data); + } + } else { + e_table_model_pre_change (E_TABLE_MODEL (model)); + + comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); + comp_data->client = g_object_ref (client); + comp_data->icalcomp = icalcomponent_new_clone (l->data); + e_cal_model_set_instance_times (comp_data, priv->zone); + + g_ptr_array_add (priv->objects, comp_data); + e_table_model_row_inserted (E_TABLE_MODEL (model), priv->objects->len - 1); + } + } + + g_slist_free (copy); +} + +static void +process_modified (ECalClientView *view, + const GSList *objects, + ECalModel *model) +{ + ECalModelPrivate *priv; + const GSList *l; + GSList *list = NULL; + + priv = model->priv; + + /* re-add only the recurrence objects */ + for (l = objects; l != NULL; l = g_slist_next (l)) { + if (!e_cal_util_component_is_instance (l->data) && e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) + list = g_slist_prepend (list, l->data); + else { + gint pos; + ECalModelComponent *comp_data; + ECalComponentId *id; + ECalComponent *comp = e_cal_component_new (); + ECalClient *client = e_cal_client_view_get_client (view); + + if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) { + g_object_unref (comp); + continue; + } + + e_table_model_pre_change (E_TABLE_MODEL (model)); + + id = e_cal_component_get_id (comp); + + comp_data = search_by_id_and_client (priv, client, id); + + e_cal_component_free_id (id); + g_object_unref (comp); + + if (!comp_data) { + /* the modified component is not in the model yet, just skip it */ + continue; + } + + if (comp_data->icalcomp) + icalcomponent_free (comp_data->icalcomp); + if (comp_data->dtstart) { + g_free (comp_data->dtstart); + comp_data->dtstart = NULL; + } + if (comp_data->dtend) { + g_free (comp_data->dtend); + comp_data->dtend = NULL; + } + if (comp_data->due) { + g_free (comp_data->due); + comp_data->due = NULL; + } + if (comp_data->completed) { + g_free (comp_data->completed); + comp_data->completed = NULL; + } + if (comp_data->created) { + g_free (comp_data->created); + comp_data->created = NULL; + } + if (comp_data->lastmodified) { + g_free (comp_data->lastmodified); + comp_data->lastmodified = NULL; + } + if (comp_data->color) { + g_free (comp_data->color); + comp_data->color = NULL; + } + + comp_data->icalcomp = icalcomponent_new_clone (l->data); + e_cal_model_set_instance_times (comp_data, priv->zone); + + pos = get_position_in_array (priv->objects, comp_data); + + e_table_model_row_changed (E_TABLE_MODEL (model), pos); + } + } + + process_event ( + view, list, model, process_added, + &model->priv->in_added, + model->priv->notify_added, + (gpointer (*)(gpointer)) icalcomponent_new_clone, + (void (*)(gpointer)) icalcomponent_free); + + g_slist_free (list); +} + +static void +process_removed (ECalClientView *view, + const GSList *ids, + ECalModel *model) +{ + ECalModelPrivate *priv; + const GSList *l; + + priv = model->priv; + + for (l = ids; l; l = l->next) { + ECalModelComponent *comp_data = NULL; + ECalComponentId *id = l->data; + gint pos; + + /* make sure we remove all objects with this UID */ + while ((comp_data = search_by_id_and_client (priv, e_cal_client_view_get_client (view), id))) { + GSList *l = NULL; + + pos = get_position_in_array (priv->objects, comp_data); + + if (!g_ptr_array_remove (priv->objects, comp_data)) + continue; + + l = g_slist_append (l, comp_data); + g_signal_emit (model, signals[COMPS_DELETED], 0, l); + + g_slist_free (l); + g_object_unref (comp_data); + + e_table_model_pre_change (E_TABLE_MODEL (model)); + e_table_model_row_deleted (E_TABLE_MODEL (model), pos); + } + } + + /* to notify about changes, because in call of row_deleted there are still all events */ + e_table_model_changed (E_TABLE_MODEL (model)); +} + +static gpointer +copy_comp_id (gpointer id) +{ + ECalComponentId *comp_id = (ECalComponentId *) id, *copy; + + g_return_val_if_fail (comp_id != NULL, NULL); + + copy = g_new0 (ECalComponentId, 1); + copy->uid = g_strdup (comp_id->uid); + copy->rid = g_strdup (comp_id->rid); + + return copy; +} + +static void +free_comp_id (gpointer id) +{ + ECalComponentId *comp_id = (ECalComponentId *) id; + + g_return_if_fail (comp_id != NULL); + + g_free (comp_id->uid); + g_free (comp_id->rid); + g_free (comp_id); +} + +static void +client_view_objects_added_cb (ECalClientView *view, + const GSList *objects, + GWeakRef *weak_ref_model) +{ + ECalModel *model; + + model = g_weak_ref_get (weak_ref_model); + + if (model != NULL) { + process_event ( + view, objects, model, process_added, + &model->priv->in_added, + model->priv->notify_added, + (gpointer (*)(gpointer)) icalcomponent_new_clone, + (void (*)(gpointer)) icalcomponent_free); + g_object_unref (model); + } +} + +static void +client_view_objects_modified_cb (ECalClientView *view, + const GSList *objects, + GWeakRef *weak_ref_model) +{ + ECalModel *model; + + model = g_weak_ref_get (weak_ref_model); + + if (model != NULL) { + process_event ( + view, objects, model, process_modified, + &model->priv->in_modified, + model->priv->notify_modified, + (gpointer (*)(gpointer)) icalcomponent_new_clone, + (void (*)(gpointer)) icalcomponent_free); + g_object_unref (model); + } +} + +static void +client_view_objects_removed_cb (ECalClientView *view, + const GSList *ids, + GWeakRef *weak_ref_model) +{ + ECalModel *model; + + model = g_weak_ref_get (weak_ref_model); + + if (model != NULL) { + process_event ( + view, ids, model, process_removed, + &model->priv->in_removed, + model->priv->notify_removed, + copy_comp_id, free_comp_id); + g_object_unref (model); + } +} + +static void +client_view_progress_cb (ECalClientView *view, + gint percent, + const gchar *message, + GWeakRef *weak_ref_model) +{ + ECalModel *model; + + model = g_weak_ref_get (weak_ref_model); + + if (model != NULL) { + ECalClient *client; + ECalClientSourceType source_type; + + client = e_cal_client_view_get_client (view); + source_type = e_cal_client_get_source_type (client); + + g_signal_emit ( + model, signals[CAL_VIEW_PROGRESS], 0, + message, percent, source_type); + + g_object_unref (model); + } +} + +static void +client_view_complete_cb (ECalClientView *view, + const GError *error, + GWeakRef *weak_ref_model) +{ + ECalModel *model; + + model = g_weak_ref_get (weak_ref_model); + + if (model != NULL) { + ECalClient *client; + ECalClientSourceType source_type; + + client = e_cal_client_view_get_client (view); + source_type = e_cal_client_get_source_type (client); + + g_signal_emit ( + model, signals[CAL_VIEW_COMPLETE], 0, + error, source_type); + + g_object_unref (model); + } +} + +static void +cal_model_get_view_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + ClientData *client_data = user_data; + ECalClientView *view = NULL; + ECalModel *model = NULL; + GError *error = NULL; + + e_cal_client_get_view_finish ( + E_CAL_CLIENT (source_object), result, &view, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((view != NULL) && (error == NULL)) || + ((view == NULL) && (error != NULL))); + + /* Ignore cancellations. */ + if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (error); + goto exit; + } + + model = g_weak_ref_get (&client_data->model); + + if (view != NULL && model != NULL) { + gulong handler_id; + + g_mutex_lock (&client_data->view_lock); + + client_data->view = g_object_ref (view); + + handler_id = g_signal_connect_data ( + view, "objects-added", + G_CALLBACK (client_view_objects_added_cb), + e_weak_ref_new (model), + (GClosureNotify) e_weak_ref_free, 0); + client_data->objects_added_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + view, "objects-modified", + G_CALLBACK (client_view_objects_modified_cb), + e_weak_ref_new (model), + (GClosureNotify) e_weak_ref_free, 0); + client_data->objects_modified_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + view, "objects-removed", + G_CALLBACK (client_view_objects_removed_cb), + e_weak_ref_new (model), + (GClosureNotify) e_weak_ref_free, 0); + client_data->objects_removed_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + view, "progress", + G_CALLBACK (client_view_progress_cb), + e_weak_ref_new (model), + (GClosureNotify) e_weak_ref_free, 0); + client_data->progress_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + view, "complete", + G_CALLBACK (client_view_complete_cb), + e_weak_ref_new (model), + (GClosureNotify) e_weak_ref_free, 0); + client_data->complete_handler_id = handler_id; + + g_mutex_unlock (&client_data->view_lock); + + e_cal_client_view_start (view, &error); + + if (error != NULL) { + g_warning ( + "%s: Failed to start view: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + + } else if (error != NULL) { + g_warning ( + "%s: Failed to get view: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + +exit: + g_clear_object (&model); + g_clear_object (&view); + + client_data_unref (client_data); +} + +static void +update_e_cal_view_for_client (ECalModel *model, + ClientData *client_data) +{ + ECalModelPrivate *priv; + GCancellable *cancellable; + + priv = model->priv; + + g_return_if_fail (model->priv->full_sexp != NULL); + + /* free the previous view, if any */ + g_mutex_lock (&client_data->view_lock); + if (client_data->view != NULL) { + client_data_disconnect_view_handlers (client_data); + g_clear_object (&client_data->view); + } + g_mutex_unlock (&client_data->view_lock); + + /* Don't create the new query if we won't use it */ + if (!client_data->do_query) + return; + + /* prepare the view */ + + cancellable = g_cancellable_new (); + + g_mutex_lock (&client_data->view_lock); + + if (client_data->cancellable != NULL) { + g_cancellable_cancel (client_data->cancellable); + g_clear_object (&client_data->cancellable); + } + + client_data->cancellable = g_object_ref (cancellable); + + g_mutex_unlock (&client_data->view_lock); + + e_cal_client_get_view ( + client_data->client, priv->full_sexp, + cancellable, cal_model_get_view_cb, + client_data_ref (client_data)); + + g_object_unref (cancellable); +} + +void +e_cal_model_update_status_message (ECalModel *model, + const gchar *message, + gdouble percent) +{ + g_return_if_fail (model != NULL); + + g_signal_emit (model, signals[STATUS_MESSAGE], 0, message, percent); +} + +static gboolean +add_new_client (ECalModel *model, + ECalClient *client, + gboolean do_query) +{ + ClientData *client_data; + gboolean update_view = TRUE; + + /* Look to see if we already have this client */ + client_data = cal_model_clients_lookup (model, client); + if (client_data != NULL) { + if (client_data->do_query) + update_view = FALSE; + else + client_data->do_query = do_query; + + } else { + client_data = client_data_new (model, client, do_query); + + g_mutex_lock (&model->priv->clients_lock); + g_queue_push_tail ( + &model->priv->clients, + client_data_ref (client_data)); + g_mutex_unlock (&model->priv->clients_lock); + } + + if (update_view) + update_e_cal_view_for_client (model, client_data); + + client_data_unref (client_data); + + return update_view; +} + +/** + * e_cal_model_add_client: + * @model: an #ECalModel + * @client: an #ECalClient + * + * Adds @client to @model and creates an internal #ECalClientView for it. + * + * If @model already has @client from a previous e_cal_model_add_client() + * call (in other words, excluding e_cal_model_set_default_client()), then + * the function does nothing and returns %FALSE. + * + * Returns: %TRUE if @client was added, %FALSE if @model already had it + */ +gboolean +e_cal_model_add_client (ECalModel *model, + ECalClient *client) +{ + g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE); + g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE); + + return add_new_client (model, client, TRUE); +} + +static void +remove_client_objects (ECalModel *model, + ClientData *client_data) +{ + gint i; + + /* remove all objects belonging to this client */ + for (i = model->priv->objects->len; i > 0; i--) { + ECalModelComponent *comp_data = (ECalModelComponent *) g_ptr_array_index (model->priv->objects, i - 1); + + g_return_if_fail (comp_data != NULL); + + if (comp_data->client == client_data->client) { + GSList *l = NULL; + + g_ptr_array_remove (model->priv->objects, comp_data); + + l = g_slist_append (l, comp_data); + g_signal_emit (model, signals[COMPS_DELETED], 0, l); + + g_slist_free (l); + g_object_unref (comp_data); + + e_table_model_pre_change (E_TABLE_MODEL (model)); + e_table_model_row_deleted (E_TABLE_MODEL (model), i - 1); + } + } + + /* to notify about changes, because in call of row_deleted there are still all events */ + e_table_model_changed (E_TABLE_MODEL (model)); +} + +static void +remove_client (ECalModel *model, + ClientData *client_data) +{ + g_mutex_lock (&client_data->view_lock); + if (client_data->view != NULL) + client_data_disconnect_view_handlers (client_data); + g_mutex_unlock (&client_data->view_lock); + + remove_client_objects (model, client_data); + + /* If this is the default client and we were querying (so it + * was also a source), keep it around but don't query it */ + if (model->priv->default_client == client_data->client && client_data->do_query) { + client_data->do_query = FALSE; + + return; + } + + if (model->priv->default_client == client_data->client) + model->priv->default_client = NULL; + + cal_model_clients_remove (model, client_data); +} + +/** + * e_cal_model_remove_client + * @model: an #ECalModel + * @client: an #ECalClient + * + * Removes @client from @model along with its internal #ECalClientView. + * + * If @model does not have @client then the function does nothing and + * returns %FALSE. + * + * Returns: %TRUE is @client was remove, %FALSE if @model did not have it + */ +gboolean +e_cal_model_remove_client (ECalModel *model, + ECalClient *client) +{ + ClientData *client_data; + gboolean removed = FALSE; + + g_return_val_if_fail (E_IS_CAL_MODEL (model), FALSE); + g_return_val_if_fail (E_IS_CAL_CLIENT (client), FALSE); + + client_data = cal_model_clients_lookup (model, client); + if (client_data != NULL) { + remove_client (model, client_data); + client_data_unref (client_data); + removed = TRUE; + } + + return removed; +} + +/** + * e_cal_model_remove_all_clients + */ +void +e_cal_model_remove_all_clients (ECalModel *model) +{ + ClientData *client_data; + + g_return_if_fail (E_IS_CAL_MODEL (model)); + + while ((client_data = cal_model_clients_pop (model)) != NULL) { + remove_client (model, client_data); + client_data_unref (client_data); + } +} + +static GSList * +get_objects_as_list (ECalModel *model) +{ + gint i; + GSList *l = NULL; + ECalModelPrivate *priv = model->priv; + + for (i = 0; i < priv->objects->len; i++) { + ECalModelComponent *comp_data; + + comp_data = g_ptr_array_index (priv->objects, i); + if (comp_data == NULL) { + g_warning ("comp_data is null\n"); continue; } - link = g_slist_append (NULL, comp_data); - g_signal_emit (model, signals[COMPS_DELETED], 0, link); + l = g_slist_prepend (l, comp_data); + } - g_slist_free (link); - g_object_unref (comp_data); + return l; +} + +struct cc_data +{ + ECalModel *model; + EFlag *eflag; +}; + +static gboolean +cleanup_content_cb (gpointer user_data) +{ + ECalModel *model; + ECalModelPrivate *priv; + GSList *slist; + gint len; + struct cc_data *data = user_data; + + g_return_val_if_fail (data != NULL, FALSE); + g_return_val_if_fail (data->model != NULL, FALSE); + g_return_val_if_fail (data->eflag != NULL, FALSE); - e_table_model_row_deleted (table_model, index); + model = data->model; + priv = model->priv; + + g_return_val_if_fail (priv != NULL, FALSE); + + e_table_model_pre_change (E_TABLE_MODEL (model)); + len = priv->objects->len; + + slist = get_objects_as_list (model); + g_ptr_array_set_size (priv->objects, 0); + g_signal_emit (model, signals[COMPS_DELETED], 0, slist); + + e_table_model_rows_deleted (E_TABLE_MODEL (model), 0, len); + + g_slist_foreach (slist, (GFunc) g_object_unref, NULL); + g_slist_free (slist); + + e_flag_set (data->eflag); + + return FALSE; +} + +static void +redo_queries (ECalModel *model) +{ + ECalModelPrivate *priv; + GList *list, *link; + struct cc_data data; + + priv = model->priv; + + if (priv->full_sexp) + g_free (priv->full_sexp); + + if (priv->start != -1 && priv->end != -1) { + gchar *iso_start, *iso_end; + const gchar *default_tzloc = NULL; + + iso_start = isodate_from_time_t (priv->start); + iso_end = isodate_from_time_t (priv->end); + + if (priv->zone && priv->zone != icaltimezone_get_utc_timezone ()) + default_tzloc = icaltimezone_get_location (priv->zone); + if (!default_tzloc) + default_tzloc = ""; + + if (priv->search_sexp) { + priv->full_sexp = g_strdup_printf ( + "(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\") %s)", + iso_start, iso_end, default_tzloc, + priv->search_sexp ? priv->search_sexp : ""); + } else { + priv->full_sexp = g_strdup_printf ( + "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\")", + iso_start, iso_end, default_tzloc); + } + + g_free (iso_start); + g_free (iso_end); + } else if (priv->search_sexp) { + priv->full_sexp = g_strdup (priv->search_sexp); + } else { + priv->full_sexp = g_strdup ("#f"); + } + + /* clean up the current contents, which should be done + * always from the main thread, because of gtk calls during removal */ + data.model = model; + data.eflag = e_flag_new (); + + if (!g_main_context_is_owner (g_main_context_default ())) { + /* function called from other than main thread */ + e_named_timeout_add (10, cleanup_content_cb, &data); + e_flag_wait (data.eflag); + } else { + cleanup_content_cb (&data); + } + + e_flag_free (data.eflag); + + /* update the view for all clients */ + + list = cal_model_clients_list (model); + + for (link = list; link != NULL; link = g_list_next (link)) { + ClientData *client_data = link->data; + + update_e_cal_view_for_client (model, client_data); } + + g_list_free_full (list, (GDestroyNotify) client_data_unref); } void @@ -2924,7 +3759,6 @@ time_t end) { ECalModelPrivate *priv; - ECalDataModelSubscriber *subscriber; g_return_if_fail (model != NULL); g_return_if_fail (E_IS_CAL_MODEL (model)); @@ -2933,69 +3767,142 @@ priv = model->priv; - if (start != (time_t) 0 && end != (time_t) 0) { - end = time_day_end_with_zone (end, priv->zone) - 1; - } - if (priv->start == start && priv->end == end) return; - subscriber = E_CAL_DATA_MODEL_SUBSCRIBER (model); priv->start = start; priv->end = end; g_signal_emit (model, signals[TIME_RANGE_CHANGED], 0, start, end); + redo_queries (model); +} + +const gchar * +e_cal_model_get_search_query (ECalModel *model) +{ + ECalModelPrivate *priv; + + g_return_val_if_fail (model != NULL, NULL); + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); + + priv = model->priv; + + return priv->search_sexp; +} + +/** + * e_cal_model_set_query + */ +void +e_cal_model_set_search_query (ECalModel *model, + const gchar *sexp) +{ + ECalModelPrivate *priv; + + g_return_if_fail (E_IS_CAL_MODEL (model)); + + priv = model->priv; + + if (!strcmp (sexp ? sexp : "", priv->search_sexp ? priv->search_sexp : "")) + return; + + if (priv->search_sexp) + g_free (priv->search_sexp); + + if (!sexp || !*sexp) + priv->search_sexp = NULL; + else + priv->search_sexp = g_strdup (sexp); + + redo_queries (model); +} - e_cal_data_model_unsubscribe (model->priv->data_model, subscriber); - e_cal_model_remove_all_objects (model); - e_cal_data_model_subscribe (model->priv->data_model, subscriber, start, end); +/** + * e_cal_model_set_query + */ +void +e_cal_model_set_search_query_with_time_range (ECalModel *model, + const gchar *sexp, + time_t start, + time_t end) +{ + ECalModelPrivate *priv; + gboolean do_query = FALSE; + + g_return_if_fail (E_IS_CAL_MODEL (model)); + + priv = model->priv; + + if (strcmp (sexp ? sexp : "", priv->search_sexp ? priv->search_sexp : "")) { + if (priv->search_sexp) + g_free (priv->search_sexp); + + if (!sexp || !*sexp) + priv->search_sexp = NULL; + else + priv->search_sexp = g_strdup (sexp); + do_query = TRUE; + } + + if (!(priv->start == start && priv->end == end)) { + priv->start = start; + priv->end = end; + do_query = TRUE; + + g_signal_emit (model, signals[TIME_RANGE_CHANGED], 0, start, end); + } + + if (do_query) + redo_queries (model); } /** - * e_cal_model_create_component_with_defaults_sync + * e_cal_model_create_component_with_defaults */ icalcomponent * -e_cal_model_create_component_with_defaults_sync (ECalModel *model, - ECalClient *client, - gboolean all_day, - GCancellable *cancellable, - GError **error) +e_cal_model_create_component_with_defaults (ECalModel *model, + gboolean all_day) { + ECalModelPrivate *priv; ECalComponent *comp; icalcomponent *icalcomp; + ECalClient *client; g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); - if (client) { - switch (model->priv->kind) { - case ICAL_VEVENT_COMPONENT : - comp = cal_comp_event_new_with_defaults_sync ( - client, all_day, - e_cal_model_get_use_default_reminder (model), - e_cal_model_get_default_reminder_interval (model), - e_cal_model_get_default_reminder_units (model), - cancellable, error); - break; - case ICAL_VTODO_COMPONENT : - comp = cal_comp_task_new_with_defaults_sync (client, cancellable, error); - break; - case ICAL_VJOURNAL_COMPONENT : - comp = cal_comp_memo_new_with_defaults_sync (client, cancellable, error); - break; - default: - g_warn_if_reached (); - return NULL; - } - } + priv = model->priv; - if (comp) { - icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); - g_object_unref (comp); - } else { - icalcomp = icalcomponent_new (model->priv->kind); + client = e_cal_model_ref_default_client (model); + if (client == NULL) + return icalcomponent_new (priv->kind); + + switch (priv->kind) { + case ICAL_VEVENT_COMPONENT : + comp = cal_comp_event_new_with_defaults ( + client, all_day, + e_cal_model_get_use_default_reminder (model), + e_cal_model_get_default_reminder_interval (model), + e_cal_model_get_default_reminder_units (model)); + break; + case ICAL_VTODO_COMPONENT : + comp = cal_comp_task_new_with_defaults (client); + break; + case ICAL_VJOURNAL_COMPONENT : + comp = cal_comp_memo_new_with_defaults (client); + break; + default: + return NULL; } - /* make sure the component has a UID */ + g_object_unref (client); + + if (!comp) + return icalcomponent_new (priv->kind); + + icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); + g_object_unref (comp); + + /* make sure the component has an UID */ if (!icalcomponent_get_uid (icalcomp)) { gchar *uid; @@ -3167,9 +4074,8 @@ } ECalModelComponent * -e_cal_model_get_component_for_client_and_uid (ECalModel *model, - ECalClient *client, - const ECalComponentId *id) +e_cal_model_get_component_for_uid (ECalModel *model, + const ECalComponentId *id) { ECalModelPrivate *priv; @@ -3177,7 +4083,7 @@ priv = model->priv; - return search_by_id_and_client (priv, client, id); + return search_by_id_and_client (priv, NULL, id); } /** @@ -3221,6 +4127,89 @@ return g_strdup (buffer); } +/* FIXME is it still needed ? +static ECellDateEditValue * +copy_ecdv (ECellDateEditValue *ecdv) +{ + ECellDateEditValue *new_ecdv; + * + new_ecdv = g_new0 (ECellDateEditValue, 1); + new_ecdv->tt = ecdv ? ecdv->tt : icaltime_null_time (); + new_ecdv->zone = ecdv ? ecdv->zone : NULL; + * + return new_ecdv; +} */ + +static void e_cal_model_component_finalize (GObject *object); + +/* Class initialization function for the calendar component object */ +static void +e_cal_model_component_class_init (ECalModelComponentClass *class) +{ + GObjectClass *object_class; + + object_class = (GObjectClass *) class; + g_type_class_add_private (class, sizeof (ECalModelComponentPrivate)); + + object_class->finalize = e_cal_model_component_finalize; +} + +static void +e_cal_model_component_finalize (GObject *object) +{ + ECalModelComponent *comp_data = E_CAL_MODEL_COMPONENT (object); + + if (comp_data->client) { + g_object_unref (comp_data->client); + comp_data->client = NULL; + } + if (comp_data->icalcomp) { + icalcomponent_free (comp_data->icalcomp); + comp_data->icalcomp = NULL; + } + if (comp_data->dtstart) { + g_free (comp_data->dtstart); + comp_data->dtstart = NULL; + } + if (comp_data->dtend) { + g_free (comp_data->dtend); + comp_data->dtend = NULL; + } + if (comp_data->due) { + g_free (comp_data->due); + comp_data->due = NULL; + } + if (comp_data->completed) { + g_free (comp_data->completed); + comp_data->completed = NULL; + } + if (comp_data->created) { + g_free (comp_data->created); + comp_data->created = NULL; + } + if (comp_data->lastmodified) { + g_free (comp_data->lastmodified); + comp_data->lastmodified = NULL; + } + if (comp_data->color) { + g_free (comp_data->color); + comp_data->color = NULL; + } + + if (comp_data->priv->categories_str) + g_string_free (comp_data->priv->categories_str, TRUE); + comp_data->priv->categories_str = NULL; + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (e_cal_model_component_parent_class)->finalize (object); +} + +static void +e_cal_model_component_init (ECalModelComponent *comp) +{ + comp->priv = E_CAL_MODEL_COMPONENT_GET_PRIVATE (comp); +} + /** * e_cal_model_generate_instances_sync * @@ -3265,12 +4254,14 @@ e_cal_model_set_instance_times (ECalModelComponent *comp_data, const icaltimezone *zone) { - if (icalcomponent_isa (comp_data->icalcomp) == ICAL_VEVENT_COMPONENT) { - struct icaltimetype start_time, end_time; + struct icaltimetype start_time, end_time; + icalcomponent_kind kind; - start_time = icalcomponent_get_dtstart (comp_data->icalcomp); - end_time = icalcomponent_get_dtend (comp_data->icalcomp); + kind = icalcomponent_isa (comp_data->icalcomp); + start_time = icalcomponent_get_dtstart (comp_data->icalcomp); + end_time = icalcomponent_get_dtend (comp_data->icalcomp); + if (kind == ICAL_VEVENT_COMPONENT) { if (start_time.is_date && icaltime_is_null_time (end_time)) { /* If end_time is null and it's an all day event, * just make start_time = end_time so that end_time @@ -3290,8 +4281,59 @@ } } - cal_comp_get_instance_times (comp_data->client, comp_data->icalcomp, zone, - &comp_data->instance_start, NULL, &comp_data->instance_end, NULL, NULL); + /* Some events can have missing DTEND, then use the start_time for them */ + if (icaltime_is_null_time (end_time)) + end_time = start_time; + + if (start_time.zone) + zone = start_time.zone; + else { + icalparameter *param = NULL; + icalproperty *prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); + + if (prop) { + param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); + + if (param) { + const gchar *tzid = NULL; + icaltimezone *st_zone = NULL; + + tzid = icalparameter_get_tzid (param); + if (tzid) + e_cal_client_get_timezone_sync (comp_data->client, tzid, &st_zone, NULL, NULL); + + if (st_zone) + zone = st_zone; + } + } + } + + comp_data->instance_start = icaltime_as_timet_with_zone (start_time, zone); + + if (end_time.zone) + zone = end_time.zone; + else { + icalparameter *param = NULL; + icalproperty *prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTSTART_PROPERTY); + + if (prop) { + param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER); + + if (param) { + const gchar *tzid = NULL; + icaltimezone *end_zone = NULL; + + tzid = icalparameter_get_tzid (param); + if (tzid) + e_cal_client_get_timezone_sync (comp_data->client, tzid, &end_zone, NULL, NULL); + + if (end_zone) + zone = end_zone; + } + } + + } + comp_data->instance_end = icaltime_as_timet_with_zone (end_time, zone); } /** @@ -3310,52 +4352,6 @@ model->priv->get_default_time_user_data = user_data; } -void -e_cal_model_modify_component (ECalModel *model, - ECalModelComponent *comp_data, - ECalObjModType mod) -{ - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_MODEL_COMPONENT (comp_data)); - - e_cal_ops_modify_component (model, comp_data->client, comp_data->icalcomp, mod, E_CAL_OPS_SEND_FLAG_ASK); -} - -void -e_cal_model_util_set_value (GHashTable *values, - ETableModel *table_model, - gint column, - gint row) -{ - gpointer value; - - g_return_if_fail (values != NULL); - - value = e_table_model_value_at (table_model, column, row); - - g_hash_table_insert (values, GINT_TO_POINTER (column), - e_table_model_duplicate_value (table_model, column, value)); -} - -gpointer -e_cal_model_util_get_value (GHashTable *values, - gint column) -{ - g_return_val_if_fail (values != NULL, NULL); - - return g_hash_table_lookup (values, GINT_TO_POINTER (column)); -} - -void -e_cal_model_emit_object_created (ECalModel *model, - ECalClient *where) -{ - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (where)); - - g_signal_emit (model, signals[OBJECT_CREATED], 0, where); -} - ECellDateEditValue * e_cal_model_copy_cell_date_value (const ECellDateEditValue *value) diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-calendar.c evolution-3.12.11/calendar/gui/e-cal-model-calendar.c --- evolution-3.16.0/calendar/gui/e-cal-model-calendar.c 2014-11-04 14:36:08.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-calendar.c 2014-11-04 14:37:29.000000000 +0000 @@ -71,14 +71,15 @@ model_zone = e_cal_model_get_timezone (E_CAL_MODEL (model)); - if (got_zone) { - tt_end = icaltime_from_timet_with_zone (comp_data->instance_end, tt_end.is_date, zone); - if (model_zone) - icaltimezone_convert_time (&tt_end, zone, model_zone); - } else { - tt_end = icaltime_from_timet_with_zone ( - comp_data->instance_end, - tt_end.is_date, model_zone); + if (e_cal_model_get_flags (E_CAL_MODEL (model)) & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES) { + if (got_zone) { + tt_end = icaltime_from_timet_with_zone (comp_data->instance_end, tt_end.is_date, zone); + if (model_zone) + icaltimezone_convert_time (&tt_end, zone, model_zone); + } else + tt_end = icaltime_from_timet_with_zone ( + comp_data->instance_end, + tt_end.is_date, model_zone); } if (!icaltime_is_valid_time (tt_end) || icaltime_is_null_time (tt_end)) @@ -199,32 +200,24 @@ } static void -cal_model_calendar_store_values_from_model (ECalModel *model, - ETableModel *source_model, - gint row, - GHashTable *values) -{ - g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); - g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - g_return_if_fail (values != NULL); - - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row); -} - -static void -cal_model_calendar_fill_component_from_values (ECalModel *model, - ECalModelComponent *comp_data, - GHashTable *values) +cal_model_calendar_fill_component_from_model (ECalModel *model, + ECalModelComponent *comp_data, + ETableModel *source_model, + gint row) { g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); g_return_if_fail (comp_data != NULL); - g_return_if_fail (values != NULL); + g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - set_dtend (model, comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_DTEND)); - set_location (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_LOCATION)); - set_transparency (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY)); + set_dtend ( + model, comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_DTEND, row)); + set_location ( + comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row)); + set_transparency ( + comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row)); } static gint @@ -272,14 +265,18 @@ gconstpointer value) { ECalModelComponent *comp_data; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; ECalComponent *comp; ECalModelCalendar *model = (ECalModelCalendar *) etm; + ESourceRegistry *registry; + GError *error = NULL; g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model)); g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST); g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm)); + registry = e_cal_model_get_registry (E_CAL_MODEL (model)); + if (col < E_CAL_MODEL_FIELD_LAST) { table_model_parent_interface->set_value_at (etm, col, row, value); return; @@ -289,8 +286,9 @@ if (!comp_data) return; - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (comp_data->icalcomp)); - if (!comp) { + comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) { + g_object_unref (comp); return; } @@ -314,7 +312,51 @@ break; } - e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, mod); + e_cal_client_modify_object_sync ( + comp_data->client, comp_data->icalcomp, mod, NULL, &error); + + if (error == NULL) { + gboolean strip_alarms = TRUE; + + if (itip_organizer_is_user (registry, comp, comp_data->client) && + send_component_dialog (NULL, comp_data->client, comp, FALSE, &strip_alarms, NULL)) { + ECalComponent *send_comp = NULL; + + if (mod == CALOBJ_MOD_ALL && e_cal_component_is_instance (comp)) { + /* Ensure we send the master object, not the instance only */ + icalcomponent *icalcomp = NULL; + const gchar *uid = NULL; + + e_cal_component_get_uid (comp, &uid); + e_cal_client_get_object_sync ( + comp_data->client, uid, NULL, + &icalcomp, NULL, NULL); + if (icalcomp != NULL) { + send_comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent (send_comp, icalcomp)) { + icalcomponent_free (icalcomp); + g_object_unref (send_comp); + send_comp = NULL; + } + } + } + + itip_send_comp ( + registry, E_CAL_COMPONENT_METHOD_REQUEST, + send_comp ? send_comp : comp, comp_data->client, + NULL, NULL, NULL, strip_alarms, FALSE); + + if (send_comp) + g_object_unref (send_comp); + } + } else { + g_warning ( + G_STRLOC ": Could not modify the object! %s", + error->message); + + /* FIXME Show error dialog */ + g_error_free (error); + } g_object_unref (comp); } @@ -458,8 +500,7 @@ ECalModelClass *model_class; model_class = E_CAL_MODEL_CLASS (class); - model_class->store_values_from_model = cal_model_calendar_store_values_from_model; - model_class->fill_component_from_values = cal_model_calendar_fill_component_from_values; + model_class->fill_component_from_model = cal_model_calendar_fill_component_from_model; } static void @@ -487,19 +528,12 @@ } ECalModel * -e_cal_model_calendar_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell) +e_cal_model_calendar_new (ESourceRegistry *registry) { - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - g_return_val_if_fail (E_IS_SHELL (shell), NULL); return g_object_new ( E_TYPE_CAL_MODEL_CALENDAR, - "data-model", data_model, - "registry", registry, - "shell", shell, - NULL); + "registry", registry, NULL); } diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-calendar.h evolution-3.12.11/calendar/gui/e-cal-model-calendar.h --- evolution-3.16.0/calendar/gui/e-cal-model-calendar.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-calendar.h 2014-03-24 09:25:23.000000000 +0000 @@ -71,9 +71,7 @@ }; GType e_cal_model_calendar_get_type (void); -ECalModel * e_cal_model_calendar_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell); +ECalModel * e_cal_model_calendar_new (ESourceRegistry *registry); G_END_DECLS diff -Nru evolution-3.16.0/calendar/gui/e-cal-model.h evolution-3.12.11/calendar/gui/e-cal-model.h --- evolution-3.16.0/calendar/gui/e-cal-model.h 2015-02-19 15:30:15.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model.h 2014-11-04 14:37:29.000000000 +0000 @@ -28,8 +28,6 @@ #include #include -#include -#include #include "e-cell-date-edit-text.h" @@ -91,6 +89,11 @@ E_CAL_MODEL_FIELD_LAST } ECalModelField; +typedef enum { + E_CAL_MODEL_FLAGS_INVALID = -1, + E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES = 0x01 +} ECalModelFlags; + typedef struct _ECalModel ECalModel; typedef struct _ECalModelClass ECalModelClass; typedef struct _ECalModelPrivate ECalModelPrivate; @@ -106,7 +109,6 @@ icalcomponent *icalcomp; time_t instance_start; time_t instance_end; - gboolean is_new_component; /* Private data used by ECalModelCalendar and ECalModelTasks */ /* keep these public to avoid many accessor functions */ @@ -142,15 +144,11 @@ const gchar * (*get_color_for_component) (ECalModel *model, ECalModelComponent *comp_data); - void (*store_values_from_model) - (ECalModel *model, - ETableModel *source_model, - gint row, - GHashTable *values); /* column ID ~> value */ - void (*fill_component_from_values) + void (*fill_component_from_model) (ECalModel *model, ECalModelComponent *comp_data, - GHashTable *values); /* column ID ~> value, populated by store_values_from_model() */ + ETableModel *source_model, + gint row); /* Signals */ void (*time_range_changed) (ECalModel *model, @@ -159,22 +157,25 @@ void (*row_appended) (ECalModel *model); void (*comps_deleted) (ECalModel *model, gpointer list); + void (*cal_view_progress) (ECalModel *model, + const gchar *message, + gint progress, + ECalClientSourceType type); + void (*cal_view_complete) (ECalModel *model, + const GError *error, + ECalClientSourceType type); + void (*status_message) (ECalModel *model, + const gchar *message, + gdouble percent); void (*timezone_changed) (ECalModel *model, icaltimezone *old_zone, icaltimezone *new_zone); - void (*object_created) (ECalModel *model, - ECalClient *where); }; typedef time_t (*ECalModelDefaultTimeFunc) (ECalModel *model, gpointer user_data); GType e_cal_model_get_type (void); GType e_cal_model_component_get_type (void); -ECalDataModel * e_cal_model_get_data_model (ECalModel *model); -ESourceRegistry * - e_cal_model_get_registry (ECalModel *model); -EShell * e_cal_model_get_shell (ECalModel *model); -EClientCache * e_cal_model_get_client_cache (ECalModel *model); icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model); void e_cal_model_set_component_kind (ECalModel *model, @@ -182,6 +183,11 @@ gboolean e_cal_model_get_confirm_delete (ECalModel *model); void e_cal_model_set_confirm_delete (ECalModel *model, gboolean confirm_delete); +ECalModelFlags e_cal_model_get_flags (ECalModel *model); +void e_cal_model_set_flags (ECalModel *model, + ECalModelFlags flags); +ESourceRegistry * + e_cal_model_get_registry (ECalModel *model); icaltimezone * e_cal_model_get_timezone (ECalModel *model); void e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone); @@ -243,24 +249,27 @@ void e_cal_model_set_work_day_start_minute (ECalModel *model, gint work_day_start_minute); -const gchar * e_cal_model_get_default_source_uid - (ECalModel *model); -void e_cal_model_set_default_source_uid - (ECalModel *model, - const gchar *source_uid); -void e_cal_model_remove_all_objects (ECalModel *model); +ECalClient * e_cal_model_ref_default_client (ECalModel *model); +void e_cal_model_set_default_client (ECalModel *model, + ECalClient *client); +GList * e_cal_model_list_clients (ECalModel *model); +gboolean e_cal_model_add_client (ECalModel *model, + ECalClient *cal_client); +gboolean e_cal_model_remove_client (ECalModel *model, + ECalClient *cal_client); +void e_cal_model_remove_all_clients (ECalModel *model); void e_cal_model_get_time_range (ECalModel *model, time_t *start, time_t *end); void e_cal_model_set_time_range (ECalModel *model, time_t start, time_t end); -icalcomponent * e_cal_model_create_component_with_defaults_sync +const gchar * e_cal_model_get_search_query (ECalModel *model); +void e_cal_model_set_search_query (ECalModel *model, + const gchar *sexp); +icalcomponent * e_cal_model_create_component_with_defaults (ECalModel *model, - ECalClient *client, - gboolean all_day, - GCancellable *cancellable, - GError **error); + gboolean all_day); gchar * e_cal_model_get_attendees_status_info (ECalModel *model, ECalComponent *comp, @@ -278,9 +287,8 @@ e_cal_model_get_component_at (ECalModel *model, gint row); ECalModelComponent * - e_cal_model_get_component_for_client_and_uid + e_cal_model_get_component_for_uid (ECalModel *model, - ECalClient *client, const ECalComponentId *id); gchar * e_cal_model_date_value_to_string (ECalModel *model, gconstpointer value); @@ -293,6 +301,11 @@ GPtrArray * e_cal_model_get_object_array (ECalModel *model); void e_cal_model_set_instance_times (ECalModelComponent *comp_data, const icaltimezone *zone); +void e_cal_model_set_search_query_with_time_range + (ECalModel *model, + const gchar *sexp, + time_t start, + time_t end); gboolean e_cal_model_test_row_editable (ECalModel *model, gint row); void e_cal_model_set_default_time_func @@ -308,19 +321,10 @@ struct icaltimetype v), icalproperty * (*new_func) (struct icaltimetype v)); -void e_cal_model_emit_object_created (ECalModel *model, - ECalClient *where); - -void e_cal_model_modify_component (ECalModel *model, - ECalModelComponent *comp_data, - ECalObjModType mod); - -void e_cal_model_util_set_value (GHashTable *values, - ETableModel *table_model, - gint column, - gint row); -gpointer e_cal_model_util_get_value (GHashTable *values, - gint column); +void e_cal_model_update_status_message + (ECalModel *model, + const gchar *message, + gdouble percent); ECellDateEditValue * e_cal_model_copy_cell_date_value diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-memos.c evolution-3.12.11/calendar/gui/e-cal-model-memos.c --- evolution-3.16.0/calendar/gui/e-cal-model-memos.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-memos.c 2014-03-24 09:25:23.000000000 +0000 @@ -49,28 +49,15 @@ e_cal_model_memos_table_model_init)) static void -cal_model_memos_store_values_from_model (ECalModel *model, - ETableModel *source_model, - gint row, - GHashTable *values) -{ - g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model)); - g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - g_return_if_fail (values != NULL); - - /* nothing is stored from UI currently */ -} - -static void -cal_model_memos_fill_component_from_values (ECalModel *model, - ECalModelComponent *comp_data, - GHashTable *values) +cal_model_memos_fill_component_from_model (ECalModel *model, + ECalModelComponent *comp_data, + ETableModel *source_model, + gint row) { icaltimetype start; - g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model)); g_return_if_fail (comp_data != NULL); - g_return_if_fail (values != NULL); + g_return_if_fail (E_IS_TABLE_MODEL (source_model)); start = icalcomponent_get_dtstart (comp_data->icalcomp); if (icaltime_compare_date_only (start, icaltime_null_time ()) == 0) { @@ -116,6 +103,7 @@ { ECalModelComponent *comp_data; ECalModelMemos *model = (ECalModelMemos *) etm; + GError *error = NULL; g_return_if_fail (E_IS_CAL_MODEL_MEMOS (model)); g_return_if_fail (col >= 0 && col < E_CAL_MODEL_MEMOS_FIELD_LAST); @@ -132,7 +120,19 @@ return; } - e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL); + /* TODO ask about mod type */ + e_cal_client_modify_object_sync ( + comp_data->client, comp_data->icalcomp, + CALOBJ_MOD_ALL, NULL, &error); + + if (error != NULL) { + g_warning ( + G_STRLOC ": Could not modify the object! %s", + error->message); + + /* TODO Show error dialog */ + g_error_free (error); + } } static gboolean @@ -226,8 +226,7 @@ ECalModelClass *model_class; model_class = E_CAL_MODEL_CLASS (class); - model_class->store_values_from_model = cal_model_memos_store_values_from_model; - model_class->fill_component_from_values = cal_model_memos_fill_component_from_values; + model_class->fill_component_from_model = cal_model_memos_fill_component_from_model; } static void @@ -257,19 +256,12 @@ } ECalModel * -e_cal_model_memos_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell) +e_cal_model_memos_new (ESourceRegistry *registry) { - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - g_return_val_if_fail (E_IS_SHELL (shell), NULL); return g_object_new ( E_TYPE_CAL_MODEL_MEMOS, - "data-model", data_model, - "registry", registry, - "shell", shell, - NULL); + "registry", registry, NULL); } diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-memos.h evolution-3.12.11/calendar/gui/e-cal-model-memos.h --- evolution-3.16.0/calendar/gui/e-cal-model-memos.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-memos.h 2014-03-24 09:25:23.000000000 +0000 @@ -70,9 +70,7 @@ }; GType e_cal_model_memos_get_type (void); -ECalModel * e_cal_model_memos_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell); +ECalModel * e_cal_model_memos_new (ESourceRegistry *registry); G_END_DECLS diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-tasks.c evolution-3.12.11/calendar/gui/e-cal-model-tasks.c --- evolution-3.16.0/calendar/gui/e-cal-model-tasks.c 2014-11-04 14:36:08.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-tasks.c 2014-11-04 14:37:29.000000000 +0000 @@ -684,6 +684,34 @@ } } +/** + * commit_component_changes + * @comp_data: Component of our interest, which has been changed. + * + * Commits changes to the backend calendar of the component. + **/ +static void +commit_component_changes (ECalModelComponent *comp_data) +{ + GError *error = NULL; + + g_return_if_fail (comp_data != NULL); + + /* FIXME ask about mod type */ + e_cal_client_modify_object_sync ( + comp_data->client, comp_data->icalcomp, + CALOBJ_MOD_ALL, NULL, &error); + + if (error != NULL) { + g_warning ( + G_STRLOC ": Could not modify the object! %s", + error->message); + + /* FIXME Show error dialog */ + g_error_free (error); + } +} + static void cal_model_tasks_set_property (GObject *object, guint property_id, @@ -806,51 +834,41 @@ } static void -cal_model_tasks_store_values_from_model (ECalModel *model, - ETableModel *source_model, - gint row, - GHashTable *values) -{ - g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); - g_return_if_fail (E_IS_TABLE_MODEL (source_model)); - g_return_if_fail (values != NULL); - - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_COMPLETED, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_PERCENT, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_STATUS, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_DUE, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_GEO, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_PRIORITY, row); - e_cal_model_util_set_value (values, source_model, E_CAL_MODEL_TASKS_FIELD_URL, row); -} - -static void -cal_model_tasks_fill_component_from_values (ECalModel *model, - ECalModelComponent *comp_data, - GHashTable *values) +cal_model_tasks_fill_component_from_model (ECalModel *model, + ECalModelComponent *comp_data, + ETableModel *source_model, + gint row) { gpointer value; g_return_if_fail (E_IS_CAL_MODEL_TASKS (model)); g_return_if_fail (comp_data != NULL); - g_return_if_fail (values != NULL); + g_return_if_fail (E_IS_TABLE_MODEL (source_model)); /* This just makes sure if anything indicates completion, all * three fields do or if percent is 0, status is sane */ - value = e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_COMPLETED); + value = e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_COMPLETED, row); set_completed ((ECalModelTasks *) model, comp_data, value); if (!value) { - value = e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_PERCENT); + value = e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_PERCENT, row); set_percent (comp_data, value); if (GPOINTER_TO_INT (value) != 100 && GPOINTER_TO_INT (value) != 0) - set_status (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_STATUS)); + set_status (comp_data, e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_STATUS, row)); } - set_due (model, comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_DUE)); - set_geo (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_GEO)); - set_priority (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_PRIORITY)); - set_url (comp_data, e_cal_model_util_get_value (values, E_CAL_MODEL_TASKS_FIELD_URL)); + set_due ( + model, comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_DUE, row)); + set_geo ( + comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_GEO, row)); + set_priority ( + comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_PRIORITY, row)); + set_url ( + comp_data, + e_table_model_value_at (source_model, E_CAL_MODEL_TASKS_FIELD_URL, row)); } static gint @@ -955,7 +973,7 @@ break; } - e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL); + commit_component_changes (comp_data); } static gboolean @@ -1162,8 +1180,7 @@ cal_model_class = E_CAL_MODEL_CLASS (class); cal_model_class->get_color_for_component = cal_model_tasks_get_color_for_component; - cal_model_class->store_values_from_model = cal_model_tasks_store_values_from_model; - cal_model_class->fill_component_from_values = cal_model_tasks_fill_component_from_values; + cal_model_class->fill_component_from_model = cal_model_tasks_fill_component_from_model; g_object_class_install_property ( object_class, @@ -1238,20 +1255,13 @@ } ECalModel * -e_cal_model_tasks_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell) +e_cal_model_tasks_new (ESourceRegistry *registry) { - g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL); g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); - g_return_val_if_fail (E_IS_SHELL (shell), NULL); return g_object_new ( E_TYPE_CAL_MODEL_TASKS, - "data-model", data_model, - "registry", registry, - "shell", shell, - NULL); + "registry", registry, NULL); } gboolean @@ -1367,7 +1377,7 @@ /*e_table_model_row_changed (E_TABLE_MODEL (model), model_row);*/ - e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL); + commit_component_changes (comp_data); } /** @@ -1412,7 +1422,7 @@ /*e_table_model_row_changed (E_TABLE_MODEL (model), model_row);*/ - e_cal_model_modify_component (E_CAL_MODEL (model), comp_data, E_CAL_OBJ_MOD_ALL); + commit_component_changes (comp_data); } void diff -Nru evolution-3.16.0/calendar/gui/e-cal-model-tasks.h evolution-3.12.11/calendar/gui/e-cal-model-tasks.h --- evolution-3.16.0/calendar/gui/e-cal-model-tasks.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-model-tasks.h 2014-03-24 09:25:23.000000000 +0000 @@ -78,9 +78,7 @@ }; GType e_cal_model_tasks_get_type (void); -ECalModel * e_cal_model_tasks_new (ECalDataModel *data_model, - ESourceRegistry *registry, - EShell *shell); +ECalModel * e_cal_model_tasks_new (ESourceRegistry *registry); gboolean e_cal_model_tasks_get_highlight_due_today (ECalModelTasks *model); void e_cal_model_tasks_set_highlight_due_today diff -Nru evolution-3.16.0/calendar/gui/e-cal-ops.c evolution-3.12.11/calendar/gui/e-cal-ops.c --- evolution-3.16.0/calendar/gui/e-cal-ops.c 2015-03-03 17:40:39.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-ops.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,2092 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include - -#include "dialogs/comp-editor.h" -#include "dialogs/event-editor.h" -#include "dialogs/memo-editor.h" -#include "dialogs/task-editor.h" -#include "dialogs/send-comp.h" -#include "comp-util.h" - -#include "e-cal-data-model.h" - -#include "e-cal-ops.h" - -static void -cal_ops_manage_send_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp, - ECalObjModType mod, - ECalOpsSendFlags send_flags) -{ - ECalComponent *comp; - ESourceRegistry *registry; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - if ((send_flags & E_CAL_OPS_SEND_FLAG_DONT_SEND) != 0) - return; - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icalcomp)); - if (!comp) - return; - - registry = e_cal_model_get_registry (model); - - if (itip_organizer_is_user (registry, comp, client)) { - gboolean strip_alarms = (send_flags & E_CAL_OPS_SEND_FLAG_STRIP_ALARMS) != 0; - gboolean only_new_attendees = (send_flags & E_CAL_OPS_SEND_FLAG_ONLY_NEW_ATTENDEES) != 0; - gboolean can_send = (send_flags & E_CAL_OPS_SEND_FLAG_SEND) != 0; - - if (!can_send) /* E_CAL_OPS_SEND_FLAG_ASK */ - can_send = send_component_dialog (NULL, client, comp, - (send_flags & E_CAL_OPS_SEND_FLAG_IS_NEW_COMPONENT) != 0, - &strip_alarms, &only_new_attendees); - - if (can_send) - itip_send_component (model, E_CAL_COMPONENT_METHOD_REQUEST, comp, client, - NULL, NULL, NULL, strip_alarms, only_new_attendees, mod == E_CAL_OBJ_MOD_ALL); - } - - g_clear_object (&comp); -} - -typedef struct { - ECalModel *model; - ECalClient *client; - icalcomponent *icalcomp; - ECalObjModType mod; - gchar *uid; - gchar *rid; - gboolean check_detached_instance; - ECalOpsCreateComponentFunc create_cb; - ECalOpsGetDefaultComponentFunc get_default_comp_cb; - gboolean all_day_default_comp; - gchar *for_client_uid; - gboolean is_modify; - ECalOpsSendFlags send_flags; - gpointer user_data; - GDestroyNotify user_data_free; - gboolean success; -} BasicOperationData; - -static void -basic_operation_data_free (gpointer ptr) -{ - BasicOperationData *bod = ptr; - - if (bod) { - if (bod->success) { - if (bod->create_cb && bod->uid && bod->icalcomp) { - bod->create_cb (bod->model, bod->client, bod->icalcomp, bod->uid, bod->user_data); - if (bod->user_data_free) - bod->user_data_free (bod->user_data); - } - - if (bod->is_modify && bod->icalcomp && (bod->send_flags & E_CAL_OPS_SEND_FLAG_DONT_SEND) == 0) { - cal_ops_manage_send_component (bod->model, bod->client, bod->icalcomp, bod->mod, bod->send_flags); - } - - if (bod->get_default_comp_cb && bod->icalcomp) { - bod->get_default_comp_cb (bod->model, bod->client, bod->icalcomp, bod->user_data); - if (bod->user_data_free) - bod->user_data_free (bod->user_data); - } - } - - g_clear_object (&bod->model); - g_clear_object (&bod->client); - if (bod->icalcomp) - icalcomponent_free (bod->icalcomp); - g_free (bod->for_client_uid); - g_free (bod->uid); - g_free (bod->rid); - g_free (bod); - } -} - -static void -cal_ops_create_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - BasicOperationData *bod = user_data; - - g_return_if_fail (bod != NULL); - - bod->success = e_cal_client_create_object_sync (bod->client, bod->icalcomp, &bod->uid, cancellable, error); -} - -/** - * e_cal_ops_create_component: - * @model: an #ECalModel - * @client: an #ECalClient - * @icalcomp: an #icalcomponent - * @callback: (allow none): a callback to be called on success - * @user_data: user data to be passed to @callback; ignored when @callback is #NULL - * @user_data_free: a function to free @user_data; ignored when @callback is #NULL - * - * Creates a new @icalcomp in the @client. The @callback, if not #NULL, - * is called with a new uid of the @icalcomp on sucessful component save. - * The @callback is called in the main thread. - * - * Since: 3.16 - **/ -void -e_cal_ops_create_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp, - ECalOpsCreateComponentFunc callback, - gpointer user_data, - GDestroyNotify user_data_free) -{ - ECalDataModel *data_model; - ESource *source; - const gchar *description; - const gchar *alert_ident; - BasicOperationData *bod; - GCancellable *cancellable; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - switch (e_cal_client_get_source_type (client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = _("Creating an event"); - alert_ident = "calendar:failed-create-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = _("Creating a memo"); - alert_ident = "calendar:failed-create-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = _("Creating a task"); - alert_ident = "calendar:failed-create-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - source = e_client_get_source (E_CLIENT (client)); - - bod = g_new0 (BasicOperationData, 1); - bod->model = g_object_ref (model); - bod->client = g_object_ref (client); - bod->icalcomp = icalcomponent_new_clone (icalcomp); - bod->create_cb = callback; - bod->user_data = user_data; - bod->user_data_free = user_data_free; - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - e_source_get_display_name (source), cal_ops_create_component_thread, - bod, basic_operation_data_free); - - g_clear_object (&cancellable); -} - -static void -cal_ops_modify_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - BasicOperationData *bod = user_data; - - g_return_if_fail (bod != NULL); - - if (bod->mod == E_CAL_OBJ_MOD_ALL) { - ECalComponent *comp; - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (bod->icalcomp)); - if (comp && e_cal_component_has_recurrences (comp)) { - if (!comp_util_sanitize_recurrence_master_sync (comp, bod->client, cancellable, error)) { - g_object_unref (comp); - return; - } - - icalcomponent_free (bod->icalcomp); - bod->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); - } - - g_clear_object (&comp); - } - - bod->success = e_cal_client_modify_object_sync (bod->client, bod->icalcomp, bod->mod, cancellable, error); -} - -/** - * e_cal_ops_modify_component: - * @model: an #ECalModel - * @client: an #ECalClient - * @icalcomp: an #icalcomponent - * @mod: a mode to use for modification of the component - * @send_flags: what to do when the modify succeeded and the component has attendees - * - * Saves changes of the @icalcomp into the @client using the @mod. The @send_flags influences - * what to do when the @icalcomp has attendees and the organizer is user. Only one of - * #E_CAL_OPS_SEND_FLAG_ASK, #E_CAL_OPS_SEND_FLAG_SEND, #E_CAL_OPS_SEND_FLAG_DONT_SEND - * can be used, while the ASK flag is the default. - * - * Since: 3.16 - **/ -void -e_cal_ops_modify_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp, - ECalObjModType mod, - ECalOpsSendFlags send_flags) -{ - ECalDataModel *data_model; - ESource *source; - const gchar *description; - const gchar *alert_ident; - BasicOperationData *bod; - GCancellable *cancellable; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - switch (e_cal_client_get_source_type (client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = _("Modifying an event"); - alert_ident = "calendar:failed-modify-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = _("Modifying a memo"); - alert_ident = "calendar:failed-modify-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = _("Modifying a task"); - alert_ident = "calendar:failed-modify-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - source = e_client_get_source (E_CLIENT (client)); - - bod = g_new0 (BasicOperationData, 1); - bod->model = g_object_ref (model); - bod->client = g_object_ref (client); - bod->icalcomp = icalcomponent_new_clone (icalcomp); - bod->mod = mod; - bod->send_flags = send_flags; - bod->is_modify = TRUE; - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - e_source_get_display_name (source), cal_ops_modify_component_thread, - bod, basic_operation_data_free); - - g_clear_object (&cancellable); -} - -static void -cal_ops_remove_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - BasicOperationData *bod = user_data; - - g_return_if_fail (bod != NULL); - - /* The check_detached_instance means to test whether the event is a detached instance, - then only that one is deleted, otherwise the master object is deleted */ - if (bod->check_detached_instance && bod->mod == E_CAL_OBJ_MOD_THIS && bod->rid && *bod->rid) { - icalcomponent *icalcomp = NULL; - GError *local_error = NULL; - - if (!e_cal_client_get_object_sync (bod->client, bod->uid, bod->rid, &icalcomp, cancellable, &local_error) && - g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) { - g_free (bod->rid); - bod->rid = NULL; - bod->mod = E_CAL_OBJ_MOD_ALL; - } - - g_clear_error (&local_error); - if (icalcomp) - icalcomponent_free (icalcomp); - } - - bod->success = e_cal_client_remove_object_sync (bod->client, bod->uid, bod->rid, bod->mod, cancellable, error); -} - -/** - * e_cal_ops_remove_component: - * @model: an #ECalModel - * @client: an #ECalClient - * @uid: a UID of the component to remove - * @rid: (allow none): a recurrence ID of the component; can be #NULL - * @mod: a mode to use for the component removal - * @check_detached_instance: whether to test whether a detached instance is to be removed - * - * Removes component identified by @uid and @rid from the @client using mode @mod. - * The @check_detached_instance influences behaviour when removing only one instance. - * If set to #TRUE, then it is checked first whether the component to be removed is - * a detached instance. If it is, then only that one is removed (as requested), otherwise - * the master objects is removed. If the @check_detached_instance is set to #FALSE, then - * the removal is done exactly with the given values. - * - * Since: 3.16 - **/ -void -e_cal_ops_remove_component (ECalModel *model, - ECalClient *client, - const gchar *uid, - const gchar *rid, - ECalObjModType mod, - gboolean check_detached_instance) -{ - ECalDataModel *data_model; - ESource *source; - const gchar *description; - const gchar *alert_ident; - BasicOperationData *bod; - GCancellable *cancellable; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (uid != NULL); - - switch (e_cal_client_get_source_type (client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = _("Removing an event"); - alert_ident = "calendar:failed-remove-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = _("Removing a memo"); - alert_ident = "calendar:failed-remove-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = _("Removing a task"); - alert_ident = "calendar:failed-remove-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - source = e_client_get_source (E_CLIENT (client)); - - bod = g_new0 (BasicOperationData, 1); - bod->model = g_object_ref (model); - bod->client = g_object_ref (client); - bod->uid = g_strdup (uid); - bod->rid = g_strdup (rid); - bod->mod = mod; - bod->check_detached_instance = check_detached_instance; - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - e_source_get_display_name (source), cal_ops_remove_component_thread, - bod, basic_operation_data_free); - - g_clear_object (&cancellable); -} - -static void -cal_ops_delete_components_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - GSList *objects = user_data, *link; - - for (link = objects; link && !g_cancellable_is_cancelled (cancellable); link = g_slist_next (link)) { - ECalModelComponent *comp_data = (ECalModelComponent *) link->data; - struct icaltimetype tt; - gchar *rid = NULL; - - tt = icalcomponent_get_recurrenceid (comp_data->icalcomp); - if (icaltime_is_valid_time (tt) && !icaltime_is_null_time (tt)) - rid = icaltime_as_ical_string_r (tt); - - if (!e_cal_client_remove_object_sync ( - comp_data->client, icalcomponent_get_uid (comp_data->icalcomp), - rid, E_CAL_OBJ_MOD_THIS, cancellable, error)) { - ESource *source = e_client_get_source (E_CLIENT (comp_data->client)); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); - /* Stop on the first error */ - g_free (rid); - break; - } - - g_free (rid); - } -} - -/** - * e_cal_ops_delete_ecalmodel_components: - * @model: an #ECalModel - * @objects: a #GSList of an #ECalModelComponent objects to delete - * - * Deletes all components from their sources. The @objects should - * be part of @model. - * - * Since: 3.16 - **/ -void -e_cal_ops_delete_ecalmodel_components (ECalModel *model, - const GSList *objects) -{ - ECalDataModel *data_model; - GCancellable *cancellable; - const gchar *alert_ident; - gchar *description; - GSList *objects_copy; - gint nobjects; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - if (!objects) - return; - - objects_copy = g_slist_copy ((GSList *) objects); - g_slist_foreach (objects_copy, (GFunc) g_object_ref, NULL); - nobjects = g_slist_length (objects_copy); - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - description = g_strdup_printf (ngettext ("Deleting an event", "Deleting %d events", nobjects), nobjects); - alert_ident = "calendar:failed-remove-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - description = g_strdup_printf (ngettext ("Deleting a memo", "Deleting %d memos", nobjects), nobjects); - alert_ident = "calendar:failed-remove-memo"; - break; - case ICAL_VTODO_COMPONENT: - description = g_strdup_printf (ngettext ("Deleting a task", "Deleting %d tasks", nobjects), nobjects); - alert_ident = "calendar:failed-remove-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - NULL, cal_ops_delete_components_thread, objects_copy, (GDestroyNotify) e_util_free_nullable_object_slist); - - g_clear_object (&cancellable); - g_free (description); -} - -static gboolean -cal_ops_create_comp_with_new_uid_sync (ECalClient *cal_client, - icalcomponent *icalcomp, - GCancellable *cancellable, - GError **error) -{ - icalcomponent *clone; - gchar *uid; - gboolean success; - - g_return_val_if_fail (E_IS_CAL_CLIENT (cal_client), FALSE); - g_return_val_if_fail (icalcomp != NULL, FALSE); - - - clone = icalcomponent_new_clone (icalcomp); - - uid = e_cal_component_gen_uid (); - icalcomponent_set_uid (clone, uid); - g_free (uid); - - success = e_cal_client_create_object_sync (cal_client, clone, NULL, cancellable, error); - - icalcomponent_free (clone); - - return success; -} - -typedef struct { - ECalModel *model; - icalcomponent *icalcomp; - icalcomponent_kind kind; - const gchar *extension_name; - gboolean success; -} PasteComponentsData; - -static void -paste_components_data_free (gpointer ptr) -{ - PasteComponentsData *pcd = ptr; - - if (pcd) { - if (pcd->model && pcd->success) - g_signal_emit_by_name (pcd->model, "row-appended", 0); - - g_clear_object (&pcd->model); - icalcomponent_free (pcd->icalcomp); - g_free (pcd); - } -} - -static void -cal_ops_update_components_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - PasteComponentsData *pcd = user_data; - EClient *client; - EClientCache *client_cache; - ECalClient *cal_client; - ESourceRegistry *registry; - ESource *source; - const gchar *uid; - gboolean success = TRUE, any_copied = FALSE; - GError *local_error = NULL; - - g_return_if_fail (pcd != NULL); - - uid = e_cal_model_get_default_source_uid (pcd->model); - g_return_if_fail (uid != NULL); - - client_cache = e_cal_model_get_client_cache (pcd->model); - registry = e_cal_model_get_registry (pcd->model); - - source = e_source_registry_ref_source (registry, uid); - if (!source) { - g_set_error (&local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - _("Source with UID '%s' not found"), uid); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, uid); - return; - } - - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); - - client = e_client_cache_get_client_sync (client_cache, source, pcd->extension_name, 30, cancellable, &local_error); - g_clear_object (&source); - - if (!client) { - e_util_propagate_open_source_job_error (job_data, pcd->extension_name, local_error, error); - return; - } - - cal_client = E_CAL_CLIENT (client); - - if (icalcomponent_isa (pcd->icalcomp) == ICAL_VCALENDAR_COMPONENT && - icalcomponent_get_first_component (pcd->icalcomp, pcd->kind) != NULL) { - icalcomponent *subcomp; - - for (subcomp = icalcomponent_get_first_component (pcd->icalcomp, ICAL_VTIMEZONE_COMPONENT); - subcomp && !g_cancellable_is_cancelled (cancellable); - subcomp = icalcomponent_get_next_component (pcd->icalcomp, ICAL_VTIMEZONE_COMPONENT)) { - icaltimezone *zone; - - zone = icaltimezone_new (); - icaltimezone_set_component (zone, subcomp); - if (!e_cal_client_add_timezone_sync (cal_client, zone, cancellable, error)) { - icaltimezone_free (zone, 1); - success = FALSE; - break; - } - - icaltimezone_free (zone, 1); - } - - for (subcomp = icalcomponent_get_first_component (pcd->icalcomp, pcd->kind); - subcomp && !g_cancellable_is_cancelled (cancellable) && success; - subcomp = icalcomponent_get_next_component (pcd->icalcomp, pcd->kind)) { - if (!cal_ops_create_comp_with_new_uid_sync (cal_client, subcomp, cancellable, error)) { - success = FALSE; - break; - } - - any_copied = TRUE; - } - } else if (icalcomponent_isa (pcd->icalcomp) == pcd->kind) { - success = cal_ops_create_comp_with_new_uid_sync (cal_client, pcd->icalcomp, cancellable, error); - any_copied = success; - } - - pcd->success = success && any_copied; - - g_object_unref (client); -} - -/** - * e_cal_ops_paste_components: - * @model: an #ECalModel - * @icalcompstr: a string representation of an iCalendar component - * - * Pastes components into the default source of the @model. - * - * Since: 3.16 - **/ -void -e_cal_ops_paste_components (ECalModel *model, - const gchar *icalcompstr) -{ - ECalDataModel *data_model; - icalcomponent *icalcomp; - icalcomponent_kind kind; - gint ncomponents = 0; - GCancellable *cancellable; - const gchar *alert_ident; - const gchar *extension_name; - gchar *description; - PasteComponentsData *pcd; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (icalcompstr != NULL); - - icalcomp = icalparser_parse_string (icalcompstr); - if (!icalcomp) - return; - - kind = icalcomponent_isa (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && - kind != e_cal_model_get_component_kind (model)) { - icalcomponent_free (icalcomp); - return; - } - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - if (kind == ICAL_VCALENDAR_COMPONENT) { - kind = ICAL_VEVENT_COMPONENT; - ncomponents = icalcomponent_count_components (icalcomp, kind); - } else if (kind == ICAL_VEVENT_COMPONENT) { - ncomponents = 1; - } - - if (ncomponents == 0) - break; - - description = g_strdup_printf (ngettext ("Pasting an event", "Pasting %d events", ncomponents), ncomponents); - alert_ident = "calendar:failed-create-event"; - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case ICAL_VJOURNAL_COMPONENT: - if (kind == ICAL_VCALENDAR_COMPONENT) { - kind = ICAL_VJOURNAL_COMPONENT; - ncomponents = icalcomponent_count_components (icalcomp, kind); - } else if (kind == ICAL_VJOURNAL_COMPONENT) { - ncomponents = 1; - } - - if (ncomponents == 0) - break; - - description = g_strdup_printf (ngettext ("Pasting a memo", "Pasting %d memos", ncomponents), ncomponents); - alert_ident = "calendar:failed-create-memo"; - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - case ICAL_VTODO_COMPONENT: - if (kind == ICAL_VCALENDAR_COMPONENT) { - kind = ICAL_VTODO_COMPONENT; - ncomponents = icalcomponent_count_components (icalcomp, kind); - } else if (kind == ICAL_VTODO_COMPONENT) { - ncomponents = 1; - } - - if (ncomponents == 0) - break; - - description = g_strdup_printf (ngettext ("Pasting a task", "Pasting %d tasks", ncomponents), ncomponents); - alert_ident = "calendar:failed-create-task"; - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - default: - g_warn_if_reached (); - break; - } - - if (ncomponents == 0) { - icalcomponent_free (icalcomp); - return; - } - - pcd = g_new0 (PasteComponentsData, 1); - pcd->model = g_object_ref (model); - pcd->icalcomp = icalcomp; - pcd->kind = kind; - pcd->extension_name = extension_name; - pcd->success = FALSE; - - data_model = e_cal_model_get_data_model (model); - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - NULL, cal_ops_update_components_thread, pcd, paste_components_data_free); - - g_clear_object (&cancellable); - g_free (description); -} - -typedef struct -{ - ECalClient *client; - icalcomponent *icalcomp; -} SendComponentData; - -static void -send_component_data_free (gpointer ptr) -{ - SendComponentData *scd = ptr; - - if (scd) { - g_clear_object (&scd->client); - icalcomponent_free (scd->icalcomp); - g_free (scd); - } -} - -static void -cal_ops_send_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - SendComponentData *scd = user_data; - icalcomponent *mod_comp = NULL; - GSList *users = NULL; - - g_return_if_fail (scd != NULL); - - e_cal_client_send_objects_sync (scd->client, scd->icalcomp, - &users, &mod_comp, cancellable, error); - - if (mod_comp) - icalcomponent_free (mod_comp); - - g_slist_free_full (users, g_free); -} - -/** - * e_cal_ops_send_component: - * @model: an #ECalModel - * @client: an #ECalClient - * @icalcomp: an #icalcomponent - * - * Sends (calls e_cal_client_send_objects_sync()) on the given @client - * with the given @icalcomp in a dedicated thread. - * - * Since: 3.16 - **/ -void -e_cal_ops_send_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp) -{ - ECalDataModel *data_model; - ESource *source; - GCancellable *cancellable; - const gchar *alert_ident; - const gchar *description; - SendComponentData *scd; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - switch (e_cal_client_get_source_type (client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = _("Updating an event"); - alert_ident = "calendar:failed-update-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = _("Updating a memo"); - alert_ident = "calendar:failed-update-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = _("Updating a task"); - alert_ident = "calendar:failed-update-task"; - break; - default: - g_warn_if_reached (); - return; - } - - scd = g_new0 (SendComponentData, 1); - scd->client = g_object_ref (client); - scd->icalcomp = icalcomponent_new_clone (icalcomp); - - source = e_client_get_source (E_CLIENT (client)); - data_model = e_cal_model_get_data_model (model); - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - e_source_get_display_name (source), cal_ops_send_component_thread, - scd, send_component_data_free); - - g_clear_object (&cancellable); -} - -typedef struct { - ECalModel *model; - GList *clients; - icalcomponent_kind kind; - time_t older_than; -} PurgeComponentsData; - -static void -purge_components_data_free (gpointer ptr) -{ - PurgeComponentsData *pcd = ptr; - - if (pcd) { - g_clear_object (&pcd->model); - g_list_free_full (pcd->clients, g_object_unref); - g_free (pcd); - } -} - -struct purge_data { - GList *clients; - gboolean remove; - time_t older_than; -}; - -static gboolean -ca_ops_purge_check_instance_cb (ECalComponent *comp, - time_t instance_start, - time_t instance_end, - gpointer data) -{ - struct purge_data *pd = data; - - if (instance_end >= pd->older_than) - pd->remove = FALSE; - - return pd->remove; -} - -static void -cal_ops_purge_components_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - PurgeComponentsData *pcd = user_data; - GList *clink; - gchar *sexp, *start, *end; - gboolean pushed_message = FALSE; - const gchar *display_name, *tzloc = NULL; - icaltimezone *zone; - icalcomponent_kind model_kind; - - g_return_if_fail (pcd != NULL); - - model_kind = e_cal_model_get_component_kind (pcd->model); - zone = e_cal_model_get_timezone (pcd->model); - if (zone && zone != icaltimezone_get_utc_timezone ()) - tzloc = icaltimezone_get_location (zone); - - start = isodate_from_time_t (0); - end = isodate_from_time_t (pcd->older_than); - sexp = g_strdup_printf ( - "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\")", - start, end, tzloc ? tzloc : ""); - g_free (start); - g_free (end); - - for (clink = pcd->clients; clink && !g_cancellable_is_cancelled (cancellable); clink = g_list_next (clink)) { - ECalClient *client = clink->data; - GSList *objects, *olink; - gint nobjects, ii, last_percent = 0; - gboolean success = TRUE; - - if (!client || e_client_is_readonly (E_CLIENT (client))) - continue; - - display_name = e_source_get_display_name (e_client_get_source (E_CLIENT (client))); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, display_name); - - switch (model_kind) { - case ICAL_VEVENT_COMPONENT: - camel_operation_push_message (cancellable, - _("Getting events to purge in the calendar '%s'"), display_name); - break; - case ICAL_VJOURNAL_COMPONENT: - camel_operation_push_message (cancellable, - _("Getting memos to purge in the memo list '%s'"), display_name); - break; - case ICAL_VTODO_COMPONENT: - camel_operation_push_message (cancellable, - _("Getting tasks to purge in the task list '%s'"), display_name); - break; - default: - g_warn_if_reached (); - return; - } - - pushed_message = TRUE; - - if (!e_cal_client_get_object_list_sync (client, sexp, &objects, cancellable, error)) - break; - - camel_operation_pop_message (cancellable); - pushed_message = FALSE; - - if (!objects) - continue; - - switch (model_kind) { - case ICAL_VEVENT_COMPONENT: - camel_operation_push_message (cancellable, - _("Purging events in the calendar '%s'"), display_name); - break; - case ICAL_VJOURNAL_COMPONENT: - camel_operation_push_message (cancellable, - _("Purging memos in the memo list '%s'"), display_name); - break; - case ICAL_VTODO_COMPONENT: - camel_operation_push_message (cancellable, - _("Purging tasks in the task list '%s'"), display_name); - break; - default: - g_warn_if_reached (); - return; - } - - pushed_message = TRUE; - nobjects = g_slist_length (objects); - - for (olink = objects, ii = 0; olink; olink = g_slist_next (olink), ii++) { - icalcomponent *icalcomp = olink->data; - gboolean remove = TRUE; - gint percent = 100 * (ii + 1) / nobjects; - - if (!e_cal_client_check_recurrences_no_master (client)) { - struct purge_data pd; - - pd.remove = TRUE; - pd.older_than = pcd->older_than; - - e_cal_client_generate_instances_for_object_sync (client, icalcomp, - pcd->older_than, G_MAXINT32, ca_ops_purge_check_instance_cb, &pd); - - remove = pd.remove; - } - - if (remove) { - const gchar *uid = icalcomponent_get_uid (icalcomp); - - if (e_cal_util_component_is_instance (icalcomp) || - e_cal_util_component_has_recurrences (icalcomp)) { - gchar *rid = NULL; - struct icaltimetype recur_id; - - recur_id = icalcomponent_get_recurrenceid (icalcomp); - - if (!icaltime_is_null_time (recur_id)) - rid = icaltime_as_ical_string_r (recur_id); - - success = e_cal_client_remove_object_sync (client, uid, rid, E_CAL_OBJ_MOD_ALL, cancellable, error); - - g_free (rid); - } else { - success = e_cal_client_remove_object_sync (client, uid, NULL, E_CAL_OBJ_MOD_THIS, cancellable, error); - } - - if (!success) - break; - } - - if (percent != last_percent) { - camel_operation_progress (cancellable, percent); - last_percent = percent; - } - } - - g_slist_foreach (objects, (GFunc) icalcomponent_free, NULL); - g_slist_free (objects); - - camel_operation_progress (cancellable, 0); - camel_operation_pop_message (cancellable); - pushed_message = FALSE; - - if (!success) - break; - } - - if (pushed_message) - camel_operation_pop_message (cancellable); - - g_free (sexp); -} - -/** - * e_cal_ops_purge_components: - * @model: an #ECalModel instance - * @older_than: threshold for the purge operation - * - * Purges (removed) all components older than @older_than from all - * currently active clients in @model. - * - * Since: 3.16 - **/ -void -e_cal_ops_purge_components (ECalModel *model, - time_t older_than) -{ - ECalDataModel *data_model; - GCancellable *cancellable; - const gchar *alert_ident; - const gchar *description; - PurgeComponentsData *pcd; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - description = _("Purging events"); - alert_ident = "calendar:failed-remove-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - description = _("Purging memos"); - alert_ident = "calendar:failed-remove-memo"; - break; - case ICAL_VTODO_COMPONENT: - description = _("Purging tasks"); - alert_ident = "calendar:failed-remove-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - - pcd = g_new0 (PurgeComponentsData, 1); - pcd->model = g_object_ref (model); - pcd->clients = e_cal_data_model_get_clients (data_model); - pcd->kind = e_cal_model_get_component_kind (model); - pcd->older_than = older_than; - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - NULL, cal_ops_purge_components_thread, - pcd, purge_components_data_free); - - g_clear_object (&cancellable); -} - -static void -clients_list_free (gpointer ptr) -{ - g_list_free_full (ptr, g_object_unref); -} - -static void -cal_ops_delete_completed_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - GList *clients = user_data, *link; - - for (link = clients; link; link = g_list_next (link)) { - ECalClient *client = link->data; - GSList *objects = NULL, *olink; - - if (!client || - e_client_is_readonly (E_CLIENT (client))) - continue; - - if (!e_cal_client_get_object_list_sync (client, "(is-completed?)", &objects, cancellable, error)) { - ESource *source = e_client_get_source (E_CLIENT (client)); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); - break; - } - - for (olink = objects; olink != NULL; olink = g_slist_next (olink)) { - icalcomponent *icalcomp = olink->data; - const gchar *uid; - - uid = icalcomponent_get_uid (icalcomp); - - if (!e_cal_client_remove_object_sync (client, uid, NULL, E_CAL_OBJ_MOD_THIS, cancellable, error)) { - ESource *source = e_client_get_source (E_CLIENT (client)); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, e_source_get_display_name (source)); - break; - } - } - - e_cal_client_free_icalcomp_slist (objects); - - /* did not process all objects => an error occurred */ - if (olink != NULL) - break; - } -} - -/** - * e_cal_ops_delete_completed_tasks: - * @model: an #ECalModel - * - * Deletes all completed tasks from all currently opened - * clients in @model. - * - * Since: 3.16 - **/ -void -e_cal_ops_delete_completed_tasks (ECalModel *model) -{ - ECalDataModel *data_model; - GCancellable *cancellable; - GList *clients; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - data_model = e_cal_model_get_data_model (model); - clients = e_cal_data_model_get_clients (data_model); - - if (!clients) - return; - - if (e_cal_client_get_source_type (clients->data) != E_CAL_CLIENT_SOURCE_TYPE_TASKS) { - g_list_free_full (clients, g_object_unref); - g_warn_if_reached (); - return; - } - - cancellable = e_cal_data_model_submit_thread_job (data_model, _("Expunging completed tasks"), - "calendar:failed-remove-task", NULL, cal_ops_delete_completed_thread, - clients, clients_list_free); - - g_clear_object (&cancellable); -} - -static ECalClient * -cal_ops_open_client_sync (EAlertSinkThreadJobData *job_data, - EShell *shell, - const gchar *client_uid, - const gchar *extension_name, - GCancellable *cancellable, - GError **error) -{ - ECalClient *cal_client = NULL; - ESourceRegistry *registry; - EClientCache *client_cache; - ESource *source; - EClient *client; - - g_return_val_if_fail (E_IS_SHELL (shell), NULL); - g_return_val_if_fail (client_uid != NULL, NULL); - g_return_val_if_fail (extension_name != NULL, NULL); - - registry = e_shell_get_registry (shell); - client_cache = e_shell_get_client_cache (shell); - - source = e_source_registry_ref_source (registry, client_uid); - if (!source) { - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - _("Source with UID '%s' not found"), client_uid); - e_alert_sink_thread_job_set_alert_arg_0 (job_data, client_uid); - } else { - client = e_client_cache_get_client_sync (client_cache, source, extension_name, 30, cancellable, error); - if (client) - cal_client = E_CAL_CLIENT (client); - } - - g_clear_object (&source); - - return cal_client; -} - -static void -cal_ops_get_default_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - BasicOperationData *bod = user_data; - - g_return_if_fail (bod != NULL); - - if (!bod->for_client_uid) { - ESourceRegistry *registry; - ESource *default_source = NULL; - - registry = e_cal_model_get_registry (bod->model); - - switch (e_cal_model_get_component_kind (bod->model)) { - case ICAL_VEVENT_COMPONENT: - default_source = e_source_registry_ref_default_calendar (registry); - break; - case ICAL_VJOURNAL_COMPONENT: - default_source = e_source_registry_ref_default_memo_list (registry); - break; - case ICAL_VTODO_COMPONENT: - default_source = e_source_registry_ref_default_task_list (registry); - break; - default: - g_warn_if_reached (); - return; - } - - if (default_source) - bod->for_client_uid = g_strdup (e_source_get_uid (default_source)); - - g_clear_object (&default_source); - } - - if (bod->for_client_uid) { - const gchar *extension_name = NULL; - - switch (e_cal_model_get_component_kind (bod->model)) { - case ICAL_VEVENT_COMPONENT: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case ICAL_VJOURNAL_COMPONENT: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - case ICAL_VTODO_COMPONENT: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - default: - g_warn_if_reached (); - return; - } - - bod->client = cal_ops_open_client_sync (job_data, - e_cal_model_get_shell (bod->model), - bod->for_client_uid, - extension_name, - cancellable, - error); - } - - bod->icalcomp = e_cal_model_create_component_with_defaults_sync (bod->model, bod->client, bod->all_day_default_comp, cancellable, error); - bod->success = bod->icalcomp != NULL && !g_cancellable_is_cancelled (cancellable); -} - -/** - * e_cal_ops_get_default_component: - * @model: an #ECalModel - * @for_client_uid: (allow none): a client UID to use for the new component; can be #NULL - * @all_day: whether the default event should be an all day event; this argument - * is ignored for other than event @model-s - * @callback: a callback to be called when the operation succeeded - * @user_data: user data passed to @callback - * @user_data_free: (allow none): a function to free @user_data, or #NULL - * - * Creates a new component with default values as defined by the @client, - * or by the @model, if @client is #NULL. The @callback is called on success. - * The @callback is called in the main thread. - * - * Since: 3.16 - **/ -void -e_cal_ops_get_default_component (ECalModel *model, - const gchar *for_client_uid, - gboolean all_day, - ECalOpsGetDefaultComponentFunc callback, - gpointer user_data, - GDestroyNotify user_data_free) -{ - ECalDataModel *data_model; - ESource *source = NULL; - const gchar *description; - const gchar *alert_ident; - BasicOperationData *bod; - GCancellable *cancellable; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (callback != NULL); - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - description = _("Creating an event"); - alert_ident = "calendar:failed-create-event"; - break; - case ICAL_VJOURNAL_COMPONENT: - description = _("Creating a memo"); - alert_ident = "calendar:failed-create-memo"; - break; - case ICAL_VTODO_COMPONENT: - description = _("Creating a task"); - alert_ident = "calendar:failed-create-task"; - break; - default: - g_warn_if_reached (); - return; - } - - data_model = e_cal_model_get_data_model (model); - if (for_client_uid) { - ESourceRegistry *registry; - - registry = e_cal_model_get_registry (model); - source = e_source_registry_ref_source (registry, for_client_uid); - } - - bod = g_new0 (BasicOperationData, 1); - bod->model = g_object_ref (model); - bod->client = NULL; - bod->icalcomp = NULL; - bod->for_client_uid = g_strdup (for_client_uid); - bod->all_day_default_comp = all_day; - bod->get_default_comp_cb = callback; - bod->user_data = user_data; - bod->user_data_free = user_data_free; - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - source ? e_source_get_display_name (source) : "", cal_ops_get_default_component_thread, - bod, basic_operation_data_free); - - g_clear_object (&cancellable); - g_clear_object (&source); -} - -static void -cal_ops_emit_model_object_created (CompEditor *editor, - ECalModel *model) -{ - g_return_if_fail (IS_COMP_EDITOR (editor)); - g_return_if_fail (E_IS_CAL_MODEL (model)); - - e_cal_model_emit_object_created (model, comp_editor_get_client (editor)); -} - -typedef struct -{ - gboolean is_new_component; - EShell *shell; - ECalModel *model; - ECalClientSourceType source_type; - gboolean is_assigned; - gchar *extension_name; - gchar *for_client_uid; - ESource *default_source; - ECalClient *client; - ECalComponent *comp; - - /* for events only */ - time_t dtstart; - time_t dtend; - gboolean all_day; - gboolean use_default_reminder; - gint default_reminder_interval; - EDurationType default_reminder_units; -} NewComponentData; - -static void -new_component_data_free (gpointer ptr) -{ - NewComponentData *ncd = ptr; - - if (ncd) { - /* successfully opened the default client */ - if (ncd->client && ncd->comp) { - CompEditor *editor = NULL; - CompEditorFlags flags = 0; - - if (ncd->is_new_component) { - flags |= COMP_EDITOR_NEW_ITEM; - - if (ncd->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) - flags |= COMP_EDITOR_USER_ORG; - } else { - if (e_cal_component_has_attendees (ncd->comp)) - ncd->is_assigned = TRUE; - - if (ncd->is_assigned && e_cal_component_has_organizer (ncd->comp)) { - ESourceRegistry *registry; - - registry = e_cal_model_get_registry (ncd->model); - if (itip_organizer_is_user (registry, ncd->comp, ncd->client)) - flags |= COMP_EDITOR_USER_ORG; - - if (ncd->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS && - (flags & COMP_EDITOR_USER_ORG) == 0 && - itip_sentby_is_user (registry, ncd->comp, ncd->client)) - flags |= COMP_EDITOR_USER_ORG; - } else { - flags |= COMP_EDITOR_USER_ORG; - } - } - - if (ncd->is_assigned) { - if (ncd->is_new_component) - flags |= COMP_EDITOR_USER_ORG; - - if (ncd->source_type == E_CAL_CLIENT_SOURCE_TYPE_EVENTS) - flags |= COMP_EDITOR_MEETING; - else if (ncd->source_type == E_CAL_CLIENT_SOURCE_TYPE_MEMOS) - flags |= COMP_EDITOR_IS_SHARED; - else if (ncd->source_type == E_CAL_CLIENT_SOURCE_TYPE_TASKS) - flags |= COMP_EDITOR_IS_ASSIGNED; - } - - switch (ncd->source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - editor = event_editor_new (ncd->client, ncd->shell, flags); - if (ncd->is_new_component && ncd->model && ncd->dtstart > 0 && ncd->dtend > 0) { - ECalComponentDateTime dt; - struct icaltimetype itt; - icaltimezone *zone; - - zone = e_cal_model_get_timezone (ncd->model); - - dt.value = &itt; - if (ncd->all_day) - dt.tzid = NULL; - else - dt.tzid = icaltimezone_get_tzid (zone); - - itt = icaltime_from_timet_with_zone (ncd->dtstart, FALSE, zone); - if (ncd->all_day) { - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - e_cal_component_set_dtstart (ncd->comp, &dt); - - itt = icaltime_from_timet_with_zone (ncd->dtend, FALSE, zone); - if (ncd->all_day) { - /* We round it up to the end of the day, unless it is - * already set to midnight */ - if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) { - icaltime_adjust (&itt, 1, 0, 0, 0); - } - itt.hour = itt.minute = itt.second = 0; - itt.is_date = TRUE; - } - e_cal_component_set_dtend (ncd->comp, &dt); - } - e_cal_component_commit_sequence (ncd->comp); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - editor = memo_editor_new (ncd->client, ncd->shell, flags); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - editor = task_editor_new (ncd->client, ncd->shell, flags); - break; - default: - g_warn_if_reached (); - break; - } - - if (editor) { - if (ncd->model) { - g_signal_connect (editor, "object-created", - G_CALLBACK (cal_ops_emit_model_object_created), ncd->model); - - g_object_set_data_full (G_OBJECT (editor), "e-cal-ops-model", g_object_ref (ncd->model), g_object_unref); - } - - comp_editor_edit_comp (editor, ncd->comp); - gtk_window_present (GTK_WINDOW (editor)); - } - } - - g_clear_object (&ncd->shell); - g_clear_object (&ncd->model); - g_clear_object (&ncd->default_source); - g_clear_object (&ncd->client); - g_clear_object (&ncd->comp); - g_free (ncd->extension_name); - g_free (ncd->for_client_uid); - g_free (ncd); - } -} - -static void -cal_ops_new_component_editor_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - NewComponentData *ncd = user_data; - GError *local_error = NULL; - - g_return_if_fail (ncd != NULL); - - if (ncd->for_client_uid) { - ncd->client = cal_ops_open_client_sync (job_data, ncd->shell, ncd->for_client_uid, - ncd->extension_name, cancellable, &local_error); - } - - if (!ncd->default_source && !ncd->client && !ncd->for_client_uid) { - const gchar *message; - - switch (ncd->source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - message = _("Default calendar not found"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - message = _("Default memo list not found"); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - message = _("Default task list not found"); - break; - default: - g_warn_if_reached (); - return; - } - - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, message); - return; - } - - if (!ncd->client && !ncd->for_client_uid) { - EClient *client; - EClientCache *client_cache; - - client_cache = e_shell_get_client_cache (ncd->shell); - - client = e_client_cache_get_client_sync (client_cache, ncd->default_source, ncd->extension_name, 30, cancellable, &local_error); - if (client) - ncd->client = E_CAL_CLIENT (client); - } - - if (ncd->client) { - switch (ncd->source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - ncd->comp = cal_comp_event_new_with_current_time_sync (ncd->client, - ncd->all_day, ncd->use_default_reminder, ncd->default_reminder_interval, - ncd->default_reminder_units, cancellable, &local_error); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - ncd->comp = cal_comp_memo_new_with_defaults_sync (ncd->client, cancellable, &local_error); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - ncd->comp = cal_comp_task_new_with_defaults_sync (ncd->client, cancellable, &local_error); - break; - default: - g_warn_if_reached (); - return; - } - } - - e_util_propagate_open_source_job_error (job_data, ncd->extension_name, local_error, error); -} - -static void -e_cal_ops_new_component_ex (EShellWindow *shell_window, - ECalModel *model, - ECalClientSourceType source_type, - const gchar *for_client_uid, - gboolean is_assigned, - gboolean all_day, - time_t dtstart, - time_t dtend, - gboolean use_default_reminder, - gint default_reminder_interval, - EDurationType default_reminder_units) -{ - ESourceRegistry *registry; - ESource *default_source, *for_client_source = NULL; - EShell *shell; - gchar *description = NULL, *alert_ident = NULL, *alert_arg_0 = NULL; - const gchar *source_display_name = ""; /* not NULL intentionally */ - const gchar *extension_name; - NewComponentData *ncd; - - if (shell_window) { - g_return_if_fail (E_IS_SHELL_WINDOW (shell_window)); - - shell = e_shell_window_get_shell (shell_window); - } else { - g_return_if_fail (E_IS_CAL_MODEL (model)); - - shell = e_cal_model_get_shell (model); - } - - registry = e_shell_get_registry (shell); - - switch (source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - default_source = e_source_registry_ref_default_calendar (registry); - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - default_source = e_source_registry_ref_default_memo_list (registry); - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - default_source = e_source_registry_ref_default_task_list (registry); - break; - default: - g_warn_if_reached (); - return; - } - - if (for_client_uid) - for_client_source = e_source_registry_ref_source (registry, for_client_uid); - - ncd = g_new0 (NewComponentData, 1); - ncd->is_new_component = TRUE; - ncd->shell = g_object_ref (shell); - ncd->model = model ? g_object_ref (model) : NULL; - ncd->source_type = source_type; - ncd->for_client_uid = g_strdup (for_client_uid); - ncd->is_assigned = is_assigned; - ncd->extension_name = g_strdup (extension_name); - ncd->default_source = default_source ? g_object_ref (default_source) : NULL; - ncd->client = NULL; - ncd->comp = NULL; - ncd->dtstart = dtstart; - ncd->dtend = dtend; - ncd->all_day = all_day; - ncd->use_default_reminder = use_default_reminder; - ncd->default_reminder_interval = default_reminder_interval; - ncd->default_reminder_units = default_reminder_units; - - if (for_client_source) - source_display_name = e_source_get_display_name (for_client_source); - else if (default_source) - source_display_name = e_source_get_display_name (default_source); - - g_warn_if_fail (e_util_get_open_source_job_info (extension_name, - source_display_name, &description, &alert_ident, &alert_arg_0)); - - if (shell_window) { - EShellView *shell_view; - EActivity *activity; - - shell_view = e_shell_window_get_shell_view (shell_window, - e_shell_window_get_active_view (shell_window)); - - activity = e_shell_view_submit_thread_job ( - shell_view, description, alert_ident, alert_arg_0, - cal_ops_new_component_editor_thread, ncd, new_component_data_free); - - g_clear_object (&activity); - } else { - GCancellable *cancellable; - ECalDataModel *data_model; - - data_model = e_cal_model_get_data_model (model); - - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, alert_arg_0, - cal_ops_new_component_editor_thread, ncd, new_component_data_free); - - g_clear_object (&cancellable); - } - - g_clear_object (&default_source); - g_clear_object (&for_client_source); - g_free (description); - g_free (alert_ident); - g_free (alert_arg_0); -} - -/** - * e_cal_ops_new_component_editor: - * @shell_window: an #EShellWindow - * @source_type: a source type of the new component - * @for_client_uid: (allow none): a client UID to use for the new component; can be #NULL - * @is_assigned: whether the new component should be assigned - * - * Creates a new component either for an #ECalClient with UID @for_client_uid, or - * for a default source of the @source_type, with prefilled values as provided - * by the #ECalClient. Use e_cal_ops_new_event_editor() for events with - * predefined alarms. - * - * Since: 3.16 - **/ -void -e_cal_ops_new_component_editor (EShellWindow *shell_window, - ECalClientSourceType source_type, - const gchar *for_client_uid, - gboolean is_assigned) -{ - e_cal_ops_new_component_ex (shell_window, NULL, source_type, for_client_uid, is_assigned, FALSE, 0, 0, FALSE, 0, E_DURATION_MINUTES); -} - -/** - * e_cal_ops_new_event_editor: - * @shell_window: an #EShellWindow - * @source_type: a source type of the new component - * @for_client_uid: (allow none): a client UID to use for the new component; can be #NULL - * @is_meeting: whether the new event should be a meeting - * @all_day: whether the new event should be an all day event - * @use_default_reminder: whether a default reminder should be added, - * if #FALSE, then the next two reminded arguments are ignored - * @default_reminder_interval: reminder interval for the default reminder - * @default_reminder_units: reminder uints for the default reminder - * - * This is a fine-grained version of e_cal_ops_new_component_editor(), suitable - * for events with predefined alarms. The e_cal_ops_new_component_editor() - * accepts events as well. - * - * Since: 3.16 - **/ -void -e_cal_ops_new_event_editor (EShellWindow *shell_window, - const gchar *for_client_uid, - gboolean is_meeting, - gboolean all_day, - gboolean use_default_reminder, - gint default_reminder_interval, - EDurationType default_reminder_units) -{ - e_cal_ops_new_component_ex (shell_window, NULL, E_CAL_CLIENT_SOURCE_TYPE_EVENTS, for_client_uid, is_meeting, - all_day, 0, 0, use_default_reminder, default_reminder_interval, default_reminder_units); -} - -/** - * e_cal_ops_new_component_editor_from_model: - * @model: an #ECalModel - * @for_client_uid: (allow none): a client UID to use for the new component; can be #NULL - * @dtstart: a DTSTART to use, for events; less than or equal to 0 to ignore - * @dtend: a DTEND to use, for events; less than or equal to 0 to ignore - * @is_assigned: whether the new component should be assigned - * @all_day: whether the new component should be an all day event - * - * Creates a new component either for an #ECalClient with UID @for_client_uid, or - * for a default source of the source type as defined by @model, with prefilled - * values as provided by the #ECalClient. The @all_day is used only for events - * source type. - * - * Since: 3.16 - **/ -void -e_cal_ops_new_component_editor_from_model (ECalModel *model, - const gchar *for_client_uid, - time_t dtstart, - time_t dtend, - gboolean is_assigned, - gboolean all_day) -{ - ECalClientSourceType source_type; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - switch (e_cal_model_get_component_kind (model)) { - case ICAL_VEVENT_COMPONENT: - source_type = E_CAL_CLIENT_SOURCE_TYPE_EVENTS; - break; - case ICAL_VJOURNAL_COMPONENT: - source_type = E_CAL_CLIENT_SOURCE_TYPE_MEMOS; - break; - case ICAL_VTODO_COMPONENT: - source_type = E_CAL_CLIENT_SOURCE_TYPE_TASKS; - break; - default: - g_warn_if_reached (); - return; - } - - if (!for_client_uid) - for_client_uid = e_cal_model_get_default_source_uid (model); - - if (for_client_uid && !for_client_uid) - for_client_uid = NULL; - - e_cal_ops_new_component_ex (NULL, model, source_type, for_client_uid, is_assigned, all_day, dtstart, dtend, - e_cal_model_get_use_default_reminder (model), - e_cal_model_get_default_reminder_interval (model), - e_cal_model_get_default_reminder_units (model)); -} - -/** - * e_cal_ops_open_component_in_editor_sync: - * @model: an #ECalModel instance - * @client: an #ECalClient, to which the component belongs - * @icalcomp: an #icalcomponent to open in an editor - * - * Opens a component @icalcomp, which belongs to a @client, in - * a component editor. This is done synchronously. - * - * Since: 3.16 - **/ -void -e_cal_ops_open_component_in_editor_sync (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp) -{ - NewComponentData *ncd; - ECalComponent *comp; - CompEditor *editor; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (icalcomp != NULL); - - editor = comp_editor_find_instance (icalcomponent_get_uid (icalcomp)); - if (editor) { - gtk_window_present (GTK_WINDOW (editor)); - return; - } - - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (icalcomp)); - g_return_if_fail (comp != NULL); - - ncd = g_new0 (NewComponentData, 1); - ncd->is_new_component = FALSE; - ncd->shell = g_object_ref (e_cal_model_get_shell (model)); - ncd->model = g_object_ref (model); - ncd->source_type = e_cal_client_get_source_type (client); - ncd->is_assigned = FALSE; /* will be figured out later */ - ncd->extension_name = NULL; - ncd->for_client_uid = NULL; - ncd->default_source = NULL; - ncd->client = g_object_ref (client); - ncd->comp = comp; - - /* This opens the editor */ - new_component_data_free (ncd); -} - -typedef struct -{ - EShell *shell; - ECalModel *model; - ESource *destination; - ECalClient *destination_client; - ECalClientSourceType source_type; - GHashTable *icalcomps_by_source; - gboolean is_move; - gint nobjects; -} TransferComponentsData; - -static void -transfer_components_free_icalcomps_slist (gpointer ptr) -{ - GSList *icalcomps = ptr; - - g_slist_free_full (icalcomps, (GDestroyNotify) icalcomponent_free); -} - -static void -transfer_components_data_free (gpointer ptr) -{ - TransferComponentsData *tcd = ptr; - - if (tcd) { - if (tcd->destination_client) - e_cal_model_emit_object_created (tcd->model, tcd->destination_client); - - g_clear_object (&tcd->shell); - g_clear_object (&tcd->model); - g_clear_object (&tcd->destination); - g_clear_object (&tcd->destination_client); - g_hash_table_destroy (tcd->icalcomps_by_source); - g_free (tcd); - } -} - -static void -transfer_components_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - TransferComponentsData *tcd = user_data; - const gchar *extension_name; - EClient *from_client = NULL, *to_client = NULL; - ECalClient *from_cal_client = NULL, *to_cal_client = NULL; - EClientCache *client_cache; - GHashTableIter iter; - gpointer key, value; - gint nobjects, ii = 0, last_percent = 0; - GSList *link; - gboolean success = TRUE; - - g_return_if_fail (tcd != NULL); - - switch (tcd->source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - extension_name = E_SOURCE_EXTENSION_CALENDAR; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - extension_name = E_SOURCE_EXTENSION_MEMO_LIST; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - extension_name = E_SOURCE_EXTENSION_TASK_LIST; - break; - default: - g_warn_if_reached (); - return; - } - - client_cache = e_shell_get_client_cache (tcd->shell); - - to_client = e_util_open_client_sync (job_data, client_cache, extension_name, tcd->destination, 30, cancellable, error); - if (!to_client) - goto out; - - to_cal_client = E_CAL_CLIENT (to_client); - - if (e_client_is_readonly (E_CLIENT (to_client))) { - g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_READ_ONLY, _("Destination is read only")); - goto out; - } - - nobjects = tcd->nobjects; - - g_hash_table_iter_init (&iter, tcd->icalcomps_by_source); - while (g_hash_table_iter_next (&iter, &key, &value)) { - ESource *source = key; - GSList *icalcomps = value; - - from_client = e_util_open_client_sync (job_data, client_cache, extension_name, source, 30, cancellable, error); - if (!from_client) { - success = FALSE; - goto out; - } - - from_cal_client = E_CAL_CLIENT (from_client); - - for (link = icalcomps; link && !g_cancellable_is_cancelled (cancellable); link = g_slist_next (link), ii++) { - gint percent = 100 * (ii + 1) / nobjects; - icalcomponent *icalcomp = link->data; - - if (!cal_comp_transfer_item_to_sync (from_cal_client, to_cal_client, icalcomp, !tcd->is_move, cancellable, error)) { - success = FALSE; - break; - } - - if (percent != last_percent) { - camel_operation_progress (cancellable, percent); - last_percent = percent; - } - } - - g_clear_object (&from_client); - } - - if (success && ii > 0) - tcd->destination_client = g_object_ref (to_client); - - out: - g_clear_object (&from_client); - g_clear_object (&to_client); -} - -/** - * e_cal_ops_transfer_components: - * @shell_view: an #EShellView - * @model: an #ECalModel, where to notify about created objects - * @source_type: a source type of the @destination and the sources - * @icalcomps_by_source: a hash table of #ESource to #GSList of icalcomponent to transfer - * @destination: a destination #ESource - * @icalcomps: a #GSList of icalcomponent-s to transfer - * @is_move: whether the transfer is move (%TRUE) or copy (%FALSE) - * - * Transfers (copies or moves, as set by @is_move) all @icalcomps from the @source - * to the @destination of type @source type (calendar/memo list/task list). - * - * Since: 3.16 - **/ -void -e_cal_ops_transfer_components (EShellView *shell_view, - ECalModel *model, - ECalClientSourceType source_type, - GHashTable *icalcomps_by_source, - ESource *destination, - gboolean is_move) -{ - gint nobjects; - gchar *description; - const gchar *alert_ident; - TransferComponentsData *tcd; - GHashTableIter iter; - gpointer key, value; - EActivity *activity; - - g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (icalcomps_by_source != NULL); - g_return_if_fail (E_IS_SOURCE (destination)); - - nobjects = 0; - g_hash_table_iter_init (&iter, icalcomps_by_source); - while (g_hash_table_iter_next (&iter, &key, &value)) { - ESource *source = key; - GSList *icalcomps = value; - - if (!e_source_equal (source, destination)) - nobjects += g_slist_length (icalcomps); - } - - switch (source_type) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = g_strdup_printf (is_move ? - ngettext ("Moving an event", "Moving %d events", nobjects) : - ngettext ("Copying an event", "Copying %d events", nobjects), - nobjects); - alert_ident = is_move ? "calendar:failed-move-event" : "calendar:failed-copy-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = g_strdup_printf (is_move ? - ngettext ("Moving a memo", "Moving %d memos", nobjects) : - ngettext ("Copying a memo", "Copying %d memos", nobjects), - nobjects); - alert_ident = is_move ? "calendar:failed-move-memo" : "calendar:failed-copy-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = g_strdup_printf (is_move ? - ngettext ("Moving a task", "Moving %d tasks", nobjects) : - ngettext ("Copying a task", "Copying %d tasks", nobjects), - nobjects); - alert_ident = is_move ? "calendar:failed-move-task" : "calendar:failed-copy-task"; - break; - default: - g_warn_if_reached (); - return; - } - - tcd = g_new0 (TransferComponentsData, 1); - tcd->shell = g_object_ref (e_shell_window_get_shell (e_shell_view_get_shell_window (shell_view))); - tcd->model = g_object_ref (model); - tcd->icalcomps_by_source = g_hash_table_new_full ((GHashFunc) e_source_hash, (GEqualFunc) e_source_equal, - g_object_unref, transfer_components_free_icalcomps_slist); - tcd->destination = g_object_ref (destination); - tcd->source_type = source_type; - tcd->is_move = is_move; - tcd->nobjects = nobjects; - tcd->destination_client = NULL; - - g_hash_table_iter_init (&iter, icalcomps_by_source); - while (g_hash_table_iter_next (&iter, &key, &value)) { - ESource *source = key; - GSList *icalcomps = value; - - if (!e_source_equal (source, destination)) { - GSList *link; - - icalcomps = g_slist_copy (icalcomps); - for (link = icalcomps; link; link = g_slist_next (link)) { - link->data = icalcomponent_new_clone (link->data); - } - - g_hash_table_insert (tcd->icalcomps_by_source, g_object_ref (source), icalcomps); - } - } - - activity = e_shell_view_submit_thread_job (shell_view, description, alert_ident, - e_source_get_display_name (destination), transfer_components_thread, tcd, - transfer_components_data_free); - - g_clear_object (&activity); - g_free (description); -} diff -Nru evolution-3.16.0/calendar/gui/e-cal-ops.h evolution-3.12.11/calendar/gui/e-cal-ops.h --- evolution-3.16.0/calendar/gui/e-cal-ops.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-cal-ops.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, see . - * - * Authors: Milan Crha - */ - -#ifndef E_CAL_OPS_H -#define E_CAL_OPS_H - -#include -#include -#include -#include - -typedef void (* ECalOpsCreateComponentFunc) (ECalModel *model, - ECalClient *client, - icalcomponent *original_icalcomp, - const gchar *new_uid, - gpointer user_data); -typedef void (* ECalOpsGetDefaultComponentFunc) (ECalModel *model, - ECalClient *client, - icalcomponent *default_component, - gpointer user_data); - -typedef enum { - E_CAL_OPS_SEND_FLAG_ASK = 0, - E_CAL_OPS_SEND_FLAG_SEND = 1 << 0, - E_CAL_OPS_SEND_FLAG_DONT_SEND = 1 << 1, - E_CAL_OPS_SEND_FLAG_IS_NEW_COMPONENT = 1 << 2, - E_CAL_OPS_SEND_FLAG_ONLY_NEW_ATTENDEES = 1 << 3, - E_CAL_OPS_SEND_FLAG_STRIP_ALARMS = 1 << 4 -} ECalOpsSendFlags; - -void e_cal_ops_create_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp, - ECalOpsCreateComponentFunc callback, - gpointer user_data, - GDestroyNotify user_data_free); -void e_cal_ops_modify_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp, - ECalObjModType mod, - ECalOpsSendFlags send_flags); -void e_cal_ops_remove_component (ECalModel *model, - ECalClient *client, - const gchar *uid, - const gchar *rid, - ECalObjModType mod, - gboolean check_detached_instance); -void e_cal_ops_delete_ecalmodel_components (ECalModel *model, - const GSList *objects); /* data is 'ECalModelComponent *' */ -void e_cal_ops_paste_components (ECalModel *model, - const gchar *icalcompstr); -void e_cal_ops_send_component (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp); -void e_cal_ops_purge_components (ECalModel *model, - time_t older_than); -void e_cal_ops_delete_completed_tasks (ECalModel *model); -void e_cal_ops_get_default_component (ECalModel *model, - const gchar *for_client_uid, - gboolean all_day, - ECalOpsGetDefaultComponentFunc callback, - gpointer user_data, - GDestroyNotify user_data_free); - -void e_cal_ops_new_component_editor (EShellWindow *shell_window, - ECalClientSourceType source_type, - const gchar *for_client_uid, - gboolean is_assigned); -void e_cal_ops_new_event_editor (EShellWindow *shell_window, - const gchar *for_client_uid, - gboolean is_meeting, - gboolean all_day, - gboolean use_default_reminder, - gint default_reminder_interval, - EDurationType default_reminder_units); -void e_cal_ops_new_component_editor_from_model - (ECalModel *model, - const gchar *for_client_uid, - time_t dtstart, - time_t dtend, - gboolean is_assigned, - gboolean all_day); -void e_cal_ops_open_component_in_editor_sync (ECalModel *model, - ECalClient *client, - icalcomponent *icalcomp); - -void e_cal_ops_transfer_components (EShellView *shell_view, - ECalModel *model, - ECalClientSourceType source_type, - GHashTable *icalcomps_by_source, /* ESource ~> GSList{icalcomponent} */ - ESource *destination, - gboolean is_move); - -#endif /* E_CAL_OPS_H */ diff -Nru evolution-3.16.0/calendar/gui/e-day-view.c evolution-3.12.11/calendar/gui/e-day-view.c --- evolution-3.16.0/calendar/gui/e-day-view.c 2015-02-24 17:29:24.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-day-view.c 2014-12-22 15:05:29.000000000 +0000 @@ -36,6 +36,7 @@ #include "libgnomecanvas/libgnomecanvas.h" #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" #include "dialogs/recur-comp.h" @@ -45,7 +46,6 @@ #include "calendar-config.h" #include "comp-util.h" -#include "e-cal-ops.h" #include "e-cal-model-calendar.h" #include "e-day-view-layout.h" #include "e-day-view-main-item.h" @@ -339,8 +339,7 @@ static void e_day_view_free_events (EDayView *day_view); static void e_day_view_free_event_array (EDayView *day_view, GArray *array); -static void e_day_view_add_event (ESourceRegistry *registry, - ECalClient *client, +static gint e_day_view_add_event (ESourceRegistry *registry, ECalComponent *comp, time_t start, time_t end, @@ -463,11 +462,6 @@ static void e_day_view_recalc_work_week (EDayView *day_view); static void e_day_view_recalc_work_week_days_shown (EDayView *day_view); -static void e_day_view_precalc_visible_time_range (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time); static void e_day_view_queue_layout (EDayView *day_view); static void e_day_view_cancel_layout (EDayView *day_view); static gboolean e_day_view_layout_timeout_cb (gpointer data); @@ -654,62 +648,52 @@ return TRUE; } -typedef struct { - EDayView *day_view; - GdkEventKey *key_event; - time_t dtstart, dtend; - gboolean in_top_canvas; - gboolean paste_clipboard; -} NewEventInRangeData; - -static void -new_event_in_rage_data_free (gpointer ptr) -{ - NewEventInRangeData *ned = ptr; - - if (ned) { - g_clear_object (&ned->day_view); - g_free (ned->key_event); - g_free (ned); - } -} - -static void -day_view_new_event_in_selected_range_cb (ECalModel *model, - ECalClient *client, - icalcomponent *default_component, - gpointer user_data) +static gboolean +e_day_view_add_new_event_in_selected_range (EDayView *day_view, + GdkEventKey *key_event) { - NewEventInRangeData *ned = user_data; + icalcomponent *icalcomp; + ECalClient *client; + ECalModel *model; ECalComponent *comp = NULL; gint day, event_num; + time_t dtstart, dtend; ECalComponentDateTime start_dt, end_dt; struct icaltimetype start_tt, end_tt; const gchar *uid; AddEventData add_event_data; ESourceRegistry *registry; - icaltimezone *zone; + gboolean success = FALSE; - g_return_if_fail (ned != NULL); - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (client)); - g_return_if_fail (default_component != NULL); + model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); + + registry = e_cal_model_get_registry (model); + client = e_cal_model_ref_default_client (model); /* Check if the client is read only */ if (e_client_is_readonly (E_CLIENT (client))) - return; + goto exit; - registry = e_cal_model_get_registry (model); - zone = e_cal_model_get_timezone (model); - uid = icalcomponent_get_uid (default_component); + icalcomp = e_cal_model_create_component_with_defaults (model, day_view->selection_in_top_canvas); + if (!icalcomp) + goto exit; + + uid = icalcomponent_get_uid (icalcomp); - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (default_component)); - g_return_if_fail (comp != NULL); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend); + + start_tt = icaltime_from_timet_with_zone ( + dtstart, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - start_tt = icaltime_from_timet_with_zone (ned->dtstart, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (ned->dtend, FALSE, zone); + end_tt = icaltime_from_timet_with_zone ( + dtend, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); - if (ned->in_top_canvas) { + if (day_view->selection_in_top_canvas) { start_dt.tzid = NULL; start_tt.is_date = 1; end_tt.is_date = 1; @@ -717,7 +701,7 @@ /* Editor default in day/work-week view - top canvas */ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT); } else { - start_dt.tzid = icaltimezone_get_tzid (zone); + start_dt.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); /* Editor default in day/work-week view - main canvas */ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE); @@ -729,77 +713,32 @@ e_cal_component_set_dtstart (comp, &start_dt); e_cal_component_set_dtend (comp, &end_dt); + e_cal_component_set_categories ( + comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (day_view))); + /* We add the event locally and start editing it. We don't send it * to the server until the user finishes editing it. */ - add_event_data.day_view = ned->day_view; + add_event_data.day_view = day_view; add_event_data.comp_data = NULL; - e_day_view_add_event (registry, client, comp, ned->dtstart, ned->dtend, &add_event_data); - e_day_view_check_layout (ned->day_view); - gtk_widget_queue_draw (ned->day_view->top_canvas); - gtk_widget_queue_draw (ned->day_view->main_canvas); + e_day_view_add_event (registry, comp, dtstart, dtend, &add_event_data); + e_day_view_check_layout (day_view); + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); - if (!e_day_view_find_event_from_uid (ned->day_view, client, uid, NULL, &day, &event_num)) { + if (!e_day_view_find_event_from_uid (day_view, client, uid, NULL, &day, &event_num)) { g_warning ("Couldn't find event to start editing.\n"); - } else { - e_day_view_start_editing_event (ned->day_view, day, event_num, ned->key_event); - - if (ned->paste_clipboard) { - EDayViewEvent *event; - - g_clear_object (&comp); - - if (ned->day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) { - if (!is_array_index_in_bounds (ned->day_view->long_events, ned->day_view->editing_event_num)) - goto out; - - event = &g_array_index (ned->day_view->long_events, - EDayViewEvent, - ned->day_view->editing_event_num); - } else { - if (!is_array_index_in_bounds (ned->day_view->events[ned->day_view->editing_event_day], ned->day_view->editing_event_num)) - goto out; - - event = &g_array_index (ned->day_view->events[ned->day_view->editing_event_day], - EDayViewEvent, - ned->day_view->editing_event_num); - } - - if (event->canvas_item && - E_IS_TEXT (event->canvas_item) && - E_TEXT (event->canvas_item)->editing) { - e_text_paste_clipboard (E_TEXT (event->canvas_item)); - } - } + goto exit; } - out: - g_clear_object (&comp); -} - -static void -e_day_view_add_new_event_in_selected_range (EDayView *day_view, - GdkEventKey *key_event, - gboolean paste_clipboard) -{ - NewEventInRangeData *ned; - ECalModel *model; - const gchar *source_uid; + e_day_view_start_editing_event (day_view, day, event_num, key_event); - ned = g_new0 (NewEventInRangeData, 1); - ned->day_view = g_object_ref (day_view); - if (key_event) { - ned->key_event = g_new0 (GdkEventKey, 1); - *ned->key_event = *key_event; - } - day_view_get_selected_time_range (E_CALENDAR_VIEW (day_view), &ned->dtstart, &ned->dtend); - ned->in_top_canvas = day_view->selection_in_top_canvas; - ned->paste_clipboard = paste_clipboard; + success = TRUE; - model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); - source_uid = e_cal_model_get_default_source_uid (model); +exit: + g_clear_object (&comp); + g_clear_object (&client); - e_cal_ops_get_default_component (model, source_uid, ned->in_top_canvas, - day_view_new_event_in_selected_range_cb, ned, new_event_in_rage_data_free); + return success; } static void @@ -1826,8 +1765,6 @@ gtk_widget_queue_draw (day_view->top_canvas); gtk_widget_queue_draw (day_view->top_dates_canvas); gtk_widget_queue_draw (day_view->main_canvas); - - e_day_view_ensure_rows_visible (day_view, day_view->selection_start_row, day_view->selection_end_row); } } @@ -1864,10 +1801,9 @@ day_view = E_DAY_VIEW (cal_view); - if (day_view->editing_event_num == -1) { - e_day_view_add_new_event_in_selected_range (day_view, NULL, TRUE); + if (day_view->editing_event_num == -1 && + !e_day_view_add_new_event_in_selected_range (day_view, NULL)) return; - } if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) { if (!is_array_index_in_bounds (day_view->long_events, day_view->editing_event_num)) @@ -1924,7 +1860,6 @@ view_class->get_selected_time_range = day_view_get_selected_time_range; view_class->set_selected_time_range = day_view_set_selected_time_range; view_class->get_visible_time_range = day_view_get_visible_time_range; - view_class->precalc_visible_time_range = e_day_view_precalc_visible_time_range; view_class->paste_text = day_view_paste_text; /* XXX Should these be constructor properties? */ @@ -2378,52 +2313,6 @@ } static void -e_day_view_precalc_visible_time_range (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time) -{ - EDayView *day_view; - gint days_shown; - time_t lower; - icaltimezone *zone; - - g_return_if_fail (E_IS_DAY_VIEW (cal_view)); - g_return_if_fail (out_start_time != NULL); - g_return_if_fail (out_end_time != NULL); - - day_view = E_DAY_VIEW (cal_view); - days_shown = e_day_view_get_days_shown (day_view); - zone = e_calendar_view_get_timezone (cal_view); - - /* Calculate the first day that should be shown, based on start_time - * and the days_shown setting. If we are showing 1 day it is just the - * start of the day given by start_time, otherwise it is the previous - * work-week start day. */ - if (!e_day_view_get_work_week_view (day_view)) { - lower = time_day_begin_with_zone (in_start_time, zone); - } else { - lower = e_day_view_find_work_week_start (day_view, in_start_time); - } - - /* See if we need to change the days shown. */ - if (lower == day_view->lower) { - *out_start_time = day_view->lower; - *out_end_time = day_view->upper; - } else { - gint day; - - *out_start_time = lower; - *out_end_time = lower; - - for (day = 1; day <= days_shown; day++) { - *out_end_time = time_add_day_with_zone (*out_end_time, 1, zone); - } - } -} - -static void time_range_changed_cb (ECalModel *model, time_t start_time, time_t end_time, @@ -2508,7 +2397,7 @@ add_event_data.day_view = day_view; add_event_data.comp_data = comp_data; e_day_view_add_event ( - registry, comp_data->client, comp, comp_data->instance_start, + registry, comp, comp_data->instance_start, comp_data->instance_end, &add_event_data); g_object_unref (comp); @@ -3982,9 +3871,10 @@ day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend); } - e_cal_ops_new_component_editor_from_model ( - e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), NULL, - dtstart, dtend, calendar_config_get_prefer_meeting (), TRUE); + e_calendar_view_new_appointment_for ( + E_CALENDAR_VIEW (day_view), + dtstart, dtend, TRUE, + calendar_config_get_prefer_meeting ()); return TRUE; } @@ -4145,9 +4035,10 @@ dtend = day_view->before_click_dtend; day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend); } - e_cal_ops_new_component_editor_from_model ( - e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), NULL, - dtstart, dtend, calendar_config_get_prefer_meeting (), FALSE); + e_calendar_view_new_appointment_for ( + E_CALENDAR_VIEW (day_view), + dtstart, dtend, FALSE, + calendar_config_get_prefer_meeting ()); return TRUE; } @@ -5162,7 +5053,8 @@ ECalModel *model; ECalClient *client; ESourceRegistry *registry; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; gint is_date; model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); @@ -5232,7 +5124,10 @@ goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { /* set the correct DTSTART/DTEND on the individual recurrence */ if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { *date.value = icaltime_from_timet_with_zone ( @@ -5250,14 +5145,17 @@ e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); + + e_cal_component_commit_sequence (comp); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; - e_cal_component_commit_sequence (comp); + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); - e_cal_ops_modify_component (model, client, e_cal_component_get_icalcomponent (comp), - mod, E_CAL_OPS_SEND_FLAG_ASK | E_CAL_OPS_SEND_FLAG_IS_NEW_COMPONENT); + e_calendar_view_modify_and_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, TRUE); out: day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; @@ -5279,9 +5177,10 @@ ECalModel *model; ECalClient *client; ESourceRegistry *registry; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; GtkWindow *toplevel; GtkResponseType send = GTK_RESPONSE_NO; + gboolean modified; gboolean only_new_attendees = FALSE; gboolean strip_alarms = TRUE; @@ -5366,7 +5265,10 @@ goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { /* set the correct DTSTART/DTEND on the individual recurrence */ if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { *date.value = icaltime_from_timet_with_zone ( @@ -5386,14 +5288,16 @@ e_cal_component_set_exrule_list (comp, NULL); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; e_cal_component_commit_sequence (comp); - e_cal_ops_modify_component (model, client, e_cal_component_get_icalcomponent (comp), mod, - (send == GTK_RESPONSE_YES ? E_CAL_OPS_SEND_FLAG_SEND : E_CAL_OPS_SEND_FLAG_DONT_SEND) | - (strip_alarms ? E_CAL_OPS_SEND_FLAG_STRIP_ALARMS : 0) | - (only_new_attendees ? E_CAL_OPS_SEND_FLAG_ONLY_NEW_ATTENDEES : 0)); + modified = e_calendar_view_modify (E_CALENDAR_VIEW (day_view), comp, client, mod); + + if (modified && send == GTK_RESPONSE_YES) + e_calendar_view_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, strip_alarms, only_new_attendees); out: g_object_unref (comp); @@ -5481,9 +5385,8 @@ } /* This adds one event to the view, adding it to the appropriate array. */ -static void +static gboolean e_day_view_add_event (ESourceRegistry *registry, - ECalClient *client, ECalComponent *comp, time_t start, time_t end, @@ -5495,7 +5398,6 @@ gint days_shown; struct icaltimetype start_tt, end_tt; AddEventData *add_event_data; - icaltimezone *zone; add_event_data = data; @@ -5508,20 +5410,23 @@ }*/ /* Check that the event times are valid. */ - g_return_if_fail (start <= end); - g_return_if_fail (start < add_event_data->day_view->upper); - g_return_if_fail (end > add_event_data->day_view->lower); - - zone = e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view)); - start_tt = icaltime_from_timet_with_zone (start, FALSE, zone); - end_tt = icaltime_from_timet_with_zone (end, FALSE, zone); + g_return_val_if_fail (start <= end, TRUE); + g_return_val_if_fail (start < add_event_data->day_view->upper, TRUE); + g_return_val_if_fail (end > add_event_data->day_view->lower, TRUE); + + start_tt = icaltime_from_timet_with_zone ( + start, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view))); + end_tt = icaltime_from_timet_with_zone ( + end, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view))); if (add_event_data->comp_data) { event.comp_data = g_object_ref (add_event_data->comp_data); } else { event.comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); - event.comp_data->is_new_component = TRUE; - event.comp_data->client = g_object_ref (client); + + event.comp_data->client = e_cal_model_ref_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->day_view))); e_cal_component_abort_sequence (comp); event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); } @@ -5546,7 +5451,9 @@ event.num_columns = 0; event.different_timezone = FALSE; - if (!cal_comp_util_compare_event_timezones (comp, event.comp_data->client, zone)) + if (!cal_comp_util_compare_event_timezones (comp, + event.comp_data->client, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (add_event_data->day_view)))) event.different_timezone = TRUE; if (!e_cal_component_has_attendees (comp) || @@ -5579,7 +5486,7 @@ g_array_append_val (add_event_data->day_view->events[day], event); add_event_data->day_view->events_sorted[day] = FALSE; add_event_data->day_view->need_layout[day] = TRUE; - return; + return TRUE; } } @@ -5588,7 +5495,7 @@ g_array_append_val (add_event_data->day_view->long_events, event); add_event_data->day_view->long_events_sorted = FALSE; add_event_data->day_view->long_events_need_layout = TRUE; - return; + return TRUE; } /* This lays out the short (less than 1 day) events in the columns. @@ -6225,9 +6132,7 @@ return FALSE; } - e_day_view_add_new_event_in_selected_range (day_view, event, FALSE); - - return TRUE; + return e_day_view_add_new_event_in_selected_range (day_view, event); } /* Select the time that begins a work day*/ @@ -6787,7 +6692,7 @@ GdkEventKey *event) { if (day_view->selection_start_day == 0) { - e_calendar_view_move_view_range (E_CALENDAR_VIEW (day_view), E_CALENDAR_VIEW_MOVE_PREVIOUS, 0); + gnome_calendar_previous (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); } else { day_view->selection_start_day--; day_view->selection_end_day--; @@ -6810,7 +6715,7 @@ days_shown = e_day_view_get_days_shown (day_view); if (day_view->selection_end_day == days_shown - 1) { - e_calendar_view_move_view_range (E_CALENDAR_VIEW (day_view), E_CALENDAR_VIEW_MOVE_NEXT, 0); + gnome_calendar_next (e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view))); } else { day_view->selection_start_day++; day_view->selection_end_day++; @@ -7374,7 +7279,8 @@ ECalModel *model; ECalClient *client; ESourceRegistry *registry; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; day = day_view->editing_event_day; event_num = day_view->editing_event_num; @@ -7434,19 +7340,25 @@ goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { e_cal_component_set_rdate_list (comp, NULL); e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); e_cal_component_commit_sequence (comp); - e_cal_ops_modify_component (model, client, e_cal_component_get_icalcomponent (comp), - mod, E_CAL_OPS_SEND_FLAG_ASK | E_CAL_OPS_SEND_FLAG_IS_NEW_COMPONENT); + e_calendar_view_modify_and_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, TRUE); out: g_object_unref (comp); @@ -7646,7 +7558,7 @@ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); client = event->comp_data->client; - on_server = !event->comp_data->is_new_component; + on_server = cal_comp_is_on_server (comp, client); if (string_is_empty (text) && !on_server) { const gchar *uid; @@ -7679,20 +7591,40 @@ e_cal_component_commit_sequence (comp); if (!on_server) { - e_cal_ops_create_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), client, icalcomp, - e_calendar_view_component_created_cb, g_object_ref (day_view), g_object_unref); + gchar *uid = NULL; + GError *error = NULL; + + e_cal_client_create_object_sync ( + client, icalcomp, &uid, NULL, &error); + + if (error != NULL) { + uid = NULL; + g_warning ( + "%s: Could not create the object! %s", + G_STRFUNC, error->message); + g_error_free (error); + } else { + icalcomponent_set_uid (icalcomp, uid); + e_calendar_view_emit_user_created ( + E_CALENDAR_VIEW (day_view), client); + } + + g_free (uid); /* we remove the object since we either got the update from the server or failed */ e_day_view_remove_event_cb (day_view, day, event_num, NULL); } else { - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; - + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; if (e_cal_component_has_recurrences (comp)) { if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { ECalComponentDateTime olddt, dt; icaltimetype itt; @@ -7740,10 +7672,14 @@ e_cal_component_commit_sequence (comp); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; - e_cal_ops_modify_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), - client, e_cal_component_get_icalcomponent (comp), mod, E_CAL_OPS_SEND_FLAG_ASK); + /* FIXME When sending here, what exactly should we send? */ + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + + e_calendar_view_modify_and_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, FALSE); } } @@ -8829,6 +8765,7 @@ gint format, length; gint days_shown; GtkResponseType send = GTK_RESPONSE_NO; + gboolean modified; gboolean only_new_attendees = FALSE; gboolean strip_alarms = TRUE; @@ -8857,7 +8794,7 @@ x, y, &day, NULL); if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; ECalClient *client; GtkWindow *toplevel; @@ -8987,21 +8924,24 @@ return; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { e_cal_component_set_rdate_list (comp, NULL); e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; - e_cal_component_commit_sequence (comp); + modified = e_calendar_view_modify (E_CALENDAR_VIEW (day_view), comp, client, mod); - e_cal_ops_modify_component (model, client, e_cal_component_get_icalcomponent (comp), mod, - (send == GTK_RESPONSE_YES ? E_CAL_OPS_SEND_FLAG_SEND : E_CAL_OPS_SEND_FLAG_DONT_SEND) | - (strip_alarms ? E_CAL_OPS_SEND_FLAG_STRIP_ALARMS : 0) | - (only_new_attendees ? E_CAL_OPS_SEND_FLAG_ONLY_NEW_ATTENDEES : 0)); + if (modified && send == GTK_RESPONSE_YES) + e_calendar_view_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, strip_alarms, only_new_attendees); g_object_unref (comp); @@ -9010,9 +8950,14 @@ } if (length >= 0 && format == 8 && !drag_from_same_window) { + ECalClient *client; + /* We are dragging between different window */ + icalcomponent *icalcomp; icalcomponent_kind kind; + time_t dtstart; + icaltimezone *default_zone; pos = e_day_view_convert_position_in_top_canvas ( day_view, @@ -9025,14 +8970,49 @@ if (!icalcomp) goto error; + default_zone = e_cal_model_get_timezone (model); + /* check the type of the component */ kind = icalcomponent_isa (icalcomp); - icalcomponent_free (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) goto error; - e_cal_ops_paste_components (model, (const gchar *) data); + dtstart = day_view->day_starts[day]; + + client = e_cal_model_ref_default_client (model); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + + subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT) + e_calendar_view_add_event ( + E_CALENDAR_VIEW (day_view), client, dtstart, + default_zone, subcomp, TRUE); + else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + e_cal_client_add_timezone_sync (client, zone, NULL, NULL); + + icaltimezone_free (zone, 1); + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + icalcomponent_free (icalcomp); + + } else { + e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, default_zone, icalcomp, TRUE); + } + + g_object_unref (client); gtk_drag_finish (context, TRUE, TRUE, time); return; @@ -9068,6 +9048,7 @@ const guchar *data; gint format, length; GtkResponseType send = GTK_RESPONSE_NO; + gboolean modified; gboolean only_new_attendees = FALSE; gboolean strip_alarms = TRUE; @@ -9101,7 +9082,7 @@ x, y, &day, &row, NULL); if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; ECalClient *client; GtkWindow *toplevel; @@ -9204,21 +9185,24 @@ return; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { e_cal_component_set_rdate_list (comp, NULL); e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; - e_cal_component_commit_sequence (comp); + modified = e_calendar_view_modify (E_CALENDAR_VIEW (day_view), comp, client, mod); - e_cal_ops_modify_component (model, client, e_cal_component_get_icalcomponent (comp), mod, - (send == GTK_RESPONSE_YES ? E_CAL_OPS_SEND_FLAG_SEND : E_CAL_OPS_SEND_FLAG_DONT_SEND) | - (strip_alarms ? E_CAL_OPS_SEND_FLAG_STRIP_ALARMS : 0) | - (only_new_attendees ? E_CAL_OPS_SEND_FLAG_ONLY_NEW_ATTENDEES : 0)); + if (modified && send == GTK_RESPONSE_YES) + e_calendar_view_send ( + E_CALENDAR_VIEW (day_view), + comp, client, mod, toplevel, strip_alarms, only_new_attendees); g_object_unref (comp); @@ -9227,9 +9211,14 @@ } if (length >= 0 && format == 8 && !drag_from_same_window) { + ECalClient *client; + /* We are dragging between different window */ + icalcomponent *icalcomp; icalcomponent_kind kind; + time_t dtstart; + icaltimezone *default_zone; pos = e_day_view_convert_position_in_main_canvas ( day_view, @@ -9242,14 +9231,49 @@ if (!icalcomp) goto error; + default_zone = e_cal_model_get_timezone (model); + /* check the type of the component */ kind = icalcomponent_isa (icalcomp); - icalcomponent_free (icalcomp); - if (kind != ICAL_VCALENDAR_COMPONENT && kind != ICAL_VEVENT_COMPONENT) goto error; - e_cal_ops_paste_components (model, (const gchar *) data); + dtstart = e_day_view_convert_grid_position_to_time (day_view, day, row); + + client = e_cal_model_ref_default_client (model); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + + subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT) + e_calendar_view_add_event ( + E_CALENDAR_VIEW (day_view), client, dtstart, + default_zone, subcomp, FALSE); + else if (child_kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + e_cal_client_add_timezone_sync (client, zone, NULL, NULL); + + icaltimezone_free (zone, 1); + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + icalcomponent_free (icalcomp); + + } else { + e_calendar_view_add_event (E_CALENDAR_VIEW (day_view), client, dtstart, default_zone, icalcomp, FALSE); + } + + g_object_unref (client); gtk_drag_finish (context, TRUE, TRUE, time); return; diff -Nru evolution-3.16.0/calendar/gui/e-day-view.h evolution-3.12.11/calendar/gui/e-day-view.h --- evolution-3.16.0/calendar/gui/e-day-view.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-day-view.h 2014-03-24 09:25:23.000000000 +0000 @@ -28,6 +28,7 @@ #include #include "e-calendar-view.h" +#include "gnome-cal.h" /* * EDayView - displays the Day & Work-Week views of the calendar. diff -Nru evolution-3.16.0/calendar/gui/e-day-view-top-item.c evolution-3.12.11/calendar/gui/e-day-view-top-item.c --- evolution-3.16.0/calendar/gui/e-day-view-top-item.c 2014-07-10 15:38:37.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-day-view-top-item.c 2014-07-10 15:43:11.000000000 +0000 @@ -450,16 +450,15 @@ e_cal_component_get_categories_list (comp, &categories_list); for (elem = categories_list; elem; elem = elem->next) { gchar *category; - gchar *file; + const gchar *file; GdkPixbuf *pixbuf; category = (gchar *) elem->data; - file = e_categories_dup_icon_file_for (category); + file = e_categories_get_icon_file_for (category); if (!file) continue; pixbuf = gdk_pixbuf_new_from_file (file, NULL); - g_free (file); if (pixbuf == NULL) continue; diff -Nru evolution-3.16.0/calendar/gui/e-memo-list-selector.c evolution-3.12.11/calendar/gui/e-memo-list-selector.c --- evolution-3.16.0/calendar/gui/e-memo-list-selector.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-memo-list-selector.c 2014-07-17 10:48:07.000000000 +0000 @@ -0,0 +1,469 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-memo-list-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include + +#include "e-memo-list-selector.h" + +#include +#include + +#include "calendar/gui/comp-util.h" + +#define E_MEMO_LIST_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorPrivate)) + +struct _EMemoListSelectorPrivate { + EShellView *shell_view; +}; + +G_DEFINE_TYPE ( + EMemoListSelector, + e_memo_list_selector, + E_TYPE_CLIENT_SELECTOR) + +enum { + PROP_0, + PROP_SHELL_VIEW +}; + +static gboolean +memo_list_selector_update_single_object (ECalClient *client, + icalcomponent *icalcomp) +{ + gchar *uid; + icalcomponent *tmp_icalcomp = NULL; + gboolean success; + + uid = (gchar *) icalcomponent_get_uid (icalcomp); + + e_cal_client_get_object_sync ( + client, uid, NULL, &tmp_icalcomp, NULL, NULL); + + if (tmp_icalcomp != NULL) { + icalcomponent_free (tmp_icalcomp); + + return e_cal_client_modify_object_sync ( + client, icalcomp, CALOBJ_MOD_ALL, NULL, NULL); + } + + success = e_cal_client_create_object_sync ( + client, icalcomp, &uid, NULL, NULL); + + if (uid != NULL) { + icalcomponent_set_uid (icalcomp, uid); + g_free (uid); + } + + return success; +} + +static gboolean +memo_list_selector_update_objects (ECalClient *client, + icalcomponent *icalcomp) +{ + icalcomponent *subcomp; + icalcomponent_kind kind; + + kind = icalcomponent_isa (icalcomp); + if (kind == ICAL_VJOURNAL_COMPONENT) + return memo_list_selector_update_single_object ( + client, icalcomp); + else if (kind != ICAL_VCALENDAR_COMPONENT) + return FALSE; + + subcomp = icalcomponent_get_first_component ( + icalcomp, ICAL_ANY_COMPONENT); + while (subcomp != NULL) { + gboolean success; + + kind = icalcomponent_isa (subcomp); + if (kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + GError *error = NULL; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + + e_cal_client_add_timezone_sync (client, zone, NULL, &error); + icaltimezone_free (zone, 1); + if (error != NULL) { + g_warning ( + "%s: Failed to add timezone: %s", + G_STRFUNC, error->message); + g_error_free (error); + return FALSE; + } + } else if (kind == ICAL_VJOURNAL_COMPONENT) { + success = memo_list_selector_update_single_object ( + client, subcomp); + if (!success) + return FALSE; + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + return TRUE; +} + +static void +client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EClient *client; + gchar *uid = user_data; + GError *error = NULL; + + g_return_if_fail (uid != NULL); + + client = e_client_selector_get_client_finish ( + E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + if (!e_client_is_readonly (client)) + e_cal_client_remove_object_sync ( + E_CAL_CLIENT (client), uid, NULL, + CALOBJ_MOD_THIS, NULL, NULL); + + g_object_unref (client); + +exit: + g_free (uid); +} + +static gboolean +memo_list_selector_process_data (ESourceSelector *selector, + ECalClient *client, + const gchar *source_uid, + icalcomponent *icalcomp, + GdkDragAction action) +{ + ESource *source; + ESourceRegistry *registry; + icalcomponent *tmp_icalcomp = NULL; + const gchar *uid; + gchar *old_uid = NULL; + gboolean success = FALSE; + GError *error = NULL; + + /* FIXME Deal with GDK_ACTION_ASK. */ + if (action == GDK_ACTION_COPY) { + old_uid = g_strdup (icalcomponent_get_uid (icalcomp)); + uid = e_cal_component_gen_uid (); + icalcomponent_set_uid (icalcomp, uid); + } + + uid = icalcomponent_get_uid (icalcomp); + if (old_uid == NULL) + old_uid = g_strdup (uid); + + success = e_cal_client_get_object_sync ( + client, uid, NULL, &tmp_icalcomp, NULL, &error); + + /* Sanity check. */ + g_return_val_if_fail ( + (success && (error == NULL)) || + (!success && (error != NULL)), FALSE); + + if (success) { + icalcomponent_free (tmp_icalcomp); + goto exit; + } + + if (g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) + g_clear_error (&error); + + if (error != NULL) { + g_message ( + "Failed to search the object in destination " + "task list: %s", error->message); + g_error_free (error); + goto exit; + } + + success = memo_list_selector_update_objects (client, icalcomp); + + if (!success || action != GDK_ACTION_MOVE) + goto exit; + + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_source (registry, source_uid); + + if (source != NULL) { + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), source, NULL, + client_connect_cb, g_strdup (old_uid)); + g_object_unref (source); + } + +exit: + g_free (old_uid); + + return success; +} + +struct DropData { + ESourceSelector *selector; + GdkDragAction action; + GSList *list; +}; + +static void +client_connect_for_drop_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + struct DropData *dd = user_data; + EClient *client; + ECalClient *cal_client; + GSList *iter; + GError *error = NULL; + + g_return_if_fail (dd != NULL); + + client = e_client_selector_get_client_finish ( + E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + cal_client = E_CAL_CLIENT (client); + + for (iter = dd->list; iter != NULL; iter = iter->next) { + gchar *source_uid = iter->data; + icalcomponent *icalcomp; + gchar *component_string; + + /* Each string is "source_uid\ncomponent_string". */ + component_string = strchr (source_uid, '\n'); + if (component_string == NULL) + continue; + + *component_string++ = '\0'; + icalcomp = icalparser_parse_string (component_string); + if (icalcomp == NULL) + continue; + + memo_list_selector_process_data ( + dd->selector, cal_client, source_uid, + icalcomp, dd->action); + + icalcomponent_free (icalcomp); + } + + g_object_unref (client); + +exit: + g_slist_foreach (dd->list, (GFunc) g_free, NULL); + g_slist_free (dd->list); + g_object_unref (dd->selector); + g_free (dd); +} + +static void +memo_list_selector_set_shell_view (EMemoListSelector *selector, + EShellView *shell_view) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + g_return_if_fail (selector->priv->shell_view == NULL); + + selector->priv->shell_view = g_object_ref (shell_view); +} + +static void +memo_list_selector_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + memo_list_selector_set_shell_view ( + E_MEMO_LIST_SELECTOR (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_list_selector_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + g_value_set_object ( + value, + e_memo_list_selector_get_shell_view ( + E_MEMO_LIST_SELECTOR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +memo_list_selector_dispose (GObject *object) +{ + EMemoListSelectorPrivate *priv; + + priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (object); + + g_clear_object (&priv->shell_view); + + /* Chain up to the parent's dispose() method. */ + G_OBJECT_CLASS (e_memo_list_selector_parent_class)->dispose (object); +} + +static void +memo_list_selector_constructed (GObject *object) +{ + ESourceSelector *selector; + ESourceRegistry *registry; + ESource *source; + + selector = E_SOURCE_SELECTOR (object); + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_default_memo_list (registry); + e_source_selector_set_primary_selection (selector, source); + g_object_unref (source); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_memo_list_selector_parent_class)->constructed (object); +} + +static gboolean +memo_list_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + struct DropData *dd; + + dd = g_new0 (struct DropData, 1); + dd->selector = g_object_ref (selector); + dd->action = action; + dd->list = cal_comp_selection_get_string_list (selection_data); + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), destination, NULL, + client_connect_for_drop_cb, dd); + + return TRUE; +} + +static void +e_memo_list_selector_class_init (EMemoListSelectorClass *class) +{ + GObjectClass *object_class; + ESourceSelectorClass *source_selector_class; + + g_type_class_add_private (class, sizeof (EMemoListSelectorPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = memo_list_selector_constructed; + object_class->set_property = memo_list_selector_set_property; + object_class->get_property = memo_list_selector_get_property; + object_class->dispose = memo_list_selector_dispose; + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = memo_list_selector_data_dropped; + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + NULL, + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_memo_list_selector_init (EMemoListSelector *selector) +{ + selector->priv = E_MEMO_LIST_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + NULL, 0, GDK_ACTION_COPY | GDK_ACTION_MOVE); + + e_drag_dest_add_calendar_targets (GTK_WIDGET (selector)); +} + +GtkWidget * +e_memo_list_selector_new (EClientCache *client_cache, + EShellView *shell_view) +{ + ESourceRegistry *registry; + GtkWidget *widget; + + g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + registry = e_client_cache_ref_registry (client_cache); + + widget = g_object_new ( + E_TYPE_MEMO_LIST_SELECTOR, + "client-cache", client_cache, + "extension-name", E_SOURCE_EXTENSION_MEMO_LIST, + "shell-view", shell_view, + "registry", registry, NULL); + + g_object_unref (registry); + + return widget; +} + +EShellView * +e_memo_list_selector_get_shell_view (EMemoListSelector *selector) +{ + g_return_val_if_fail (E_IS_MEMO_LIST_SELECTOR (selector), NULL); + + return selector->priv->shell_view; +} + diff -Nru evolution-3.16.0/calendar/gui/e-memo-list-selector.h evolution-3.12.11/calendar/gui/e-memo-list-selector.h --- evolution-3.16.0/calendar/gui/e-memo-list-selector.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-memo-list-selector.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-memo-list-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +/* XXX This widget is nearly identical to ETaskListSelector. If + * ECalendarSelector ever learns how to move selections from + * one source to another, perhaps these ESourceSelector sub- + * classes could someday be combined. */ + +#ifndef E_MEMO_LIST_SELECTOR_H +#define E_MEMO_LIST_SELECTOR_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_MEMO_LIST_SELECTOR \ + (e_memo_list_selector_get_type ()) +#define E_MEMO_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelector)) +#define E_MEMO_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass)) +#define E_IS_MEMO_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR)) +#define E_IS_MEMO_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_MEMO_LIST_SELECTOR)) +#define E_MEMO_LIST_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_MEMO_LIST_SELECTOR, EMemoListSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _EMemoListSelector EMemoListSelector; +typedef struct _EMemoListSelectorClass EMemoListSelectorClass; +typedef struct _EMemoListSelectorPrivate EMemoListSelectorPrivate; + +struct _EMemoListSelector { + EClientSelector parent; + EMemoListSelectorPrivate *priv; +}; + +struct _EMemoListSelectorClass { + EClientSelectorClass parent_class; +}; + +GType e_memo_list_selector_get_type (void); +GtkWidget * e_memo_list_selector_new (EClientCache *client_cache, + EShellView *shell_view); +EShellView * e_memo_list_selector_get_shell_view + (EMemoListSelector *selector); + +G_END_DECLS + +#endif /* E_MEMO_LIST_SELECTOR_H */ diff -Nru evolution-3.16.0/calendar/gui/e-memo-table.c evolution-3.12.11/calendar/gui/e-memo-table.c --- evolution-3.16.0/calendar/gui/e-memo-table.c 2015-02-24 08:13:24.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-memo-table.c 2014-10-09 09:05:48.000000000 +0000 @@ -37,9 +37,9 @@ #include #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/memo-editor.h" #include "e-cal-model-memos.h" -#include "e-cal-ops.h" #include "e-calendar-view.h" #include "e-cell-date-edit-text.h" #include "print.h" @@ -68,6 +68,7 @@ enum { OPEN_COMPONENT, POPUP_EVENT, + STATUS_MESSAGE, LAST_SIGNAL }; @@ -109,6 +110,16 @@ g_signal_emit (memo_table, signal_id, 0, event); } +static void +memo_table_emit_status_message (EMemoTable *memo_table, + const gchar *message, + gdouble percent) +{ + guint signal_id = signals[STATUS_MESSAGE]; + + g_signal_emit (memo_table, signal_id, 0, message, percent); +} + /* Returns the current time, for the ECellDateEdit items. * FIXME: Should probably use the timezone of the item rather than the * current timezone, though that may be difficult to get from here. */ @@ -140,14 +151,51 @@ return tmp_tm; } +static void +memo_table_model_cal_view_progress_cb (EMemoTable *memo_table, + const gchar *message, + gint progress, + ECalClientSourceType type) +{ + gdouble percent = (gdouble) progress; + + memo_table_emit_status_message (memo_table, message, percent); +} + +static void +memo_table_model_cal_view_complete_cb (EMemoTable *memo_table, + const GError *error, + ECalClientSourceType type) +{ + memo_table_emit_status_message (memo_table, NULL, -1.0); +} + /* Deletes all of the selected components in the table */ static void delete_selected_components (EMemoTable *memo_table) { - GSList *objs; + GSList *objs, *l; + const gchar *status_message; objs = e_memo_table_get_selected (memo_table); - e_cal_ops_delete_ecalmodel_components (memo_table->priv->model, objs); + + status_message = _("Deleting selected objects"); + memo_table_emit_status_message (memo_table, status_message, -1.0); + + for (l = objs; l; l = l->next) { + ECalModelComponent *comp_data = (ECalModelComponent *) l->data; + GError *error = NULL; + + e_cal_client_remove_object_sync ( + comp_data->client, + icalcomponent_get_uid (comp_data->icalcomp), + NULL, CALOBJ_MOD_THIS, NULL, &error); + delete_error_dialog (error, E_CAL_COMPONENT_JOURNAL); + g_clear_error (&error); + } + + memo_table_emit_status_message (memo_table, NULL, -1.0); + g_slist_free (objs); } @@ -158,6 +206,16 @@ g_return_if_fail (memo_table->priv->model == NULL); memo_table->priv->model = g_object_ref (model); + + g_signal_connect_swapped ( + model, "cal-view-progress", + G_CALLBACK (memo_table_model_cal_view_progress_cb), + memo_table); + + g_signal_connect_swapped ( + model, "cal-view-complete", + G_CALLBACK (memo_table_model_cal_view_complete_cb), + memo_table); } static void @@ -296,13 +354,13 @@ cell = e_cell_date_edit_text_new (NULL, GTK_JUSTIFY_LEFT); g_object_set (cell, "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL); - e_binding_bind_property ( + g_object_bind_property ( model, "timezone", cell, "timezone", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | @@ -312,7 +370,7 @@ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); g_object_unref (cell); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", popup_cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | @@ -783,6 +841,117 @@ memo_table->tmp_vcal = NULL; } +/* Helper for memo_table_paste_clipboard() */ +static void +clipboard_get_calendar_data (EMemoTable *memo_table, + const gchar *text) +{ + icalcomponent *icalcomp; + gchar *uid; + ECalComponent *comp; + ECalClient *client; + ECalModel *model; + icalcomponent_kind kind; + const gchar *status_message; + + g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); + + if (!text || !*text) + return; + + icalcomp = icalparser_parse_string (text); + if (!icalcomp) + return; + + /* check the type of the component */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && + kind != ICAL_VEVENT_COMPONENT && + kind != ICAL_VTODO_COMPONENT && + kind != ICAL_VJOURNAL_COMPONENT) { + return; + } + + model = e_memo_table_get_model (memo_table); + client = e_cal_model_ref_default_client (model); + + status_message = _("Updating objects"); + memo_table_emit_status_message (memo_table, status_message, -1.0); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + icalcomponent *vcal_comp; + + vcal_comp = icalcomp; + subcomp = icalcomponent_get_first_component ( + vcal_comp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT || + child_kind == ICAL_VTODO_COMPONENT || + child_kind == ICAL_VJOURNAL_COMPONENT) { + ECalComponent *tmp_comp; + GError *error = NULL; + + uid = e_cal_component_gen_uid (); + tmp_comp = e_cal_component_new (); + e_cal_component_set_icalcomponent ( + tmp_comp, + icalcomponent_new_clone (subcomp)); + e_cal_component_set_uid (tmp_comp, uid); + g_free (uid); + uid = NULL; + + /* FIXME Should we convert start/due/complete + * times? Also, need error handling.*/ + e_cal_client_create_object_sync ( + client, + e_cal_component_get_icalcomponent (tmp_comp), + NULL, NULL, &error); + + g_object_unref (tmp_comp); + + if (error != NULL) { + g_warning ( + "%s: Failed to create object: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + } + subcomp = icalcomponent_get_next_component ( + vcal_comp, ICAL_ANY_COMPONENT); + } + } else { + GError *error = NULL; + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + uid = e_cal_component_gen_uid (); + e_cal_component_set_uid (comp, (const gchar *) uid); + g_free (uid); + uid = NULL; + + e_cal_client_create_object_sync ( + client, + e_cal_component_get_icalcomponent (comp), + NULL, NULL, &error); + + g_object_unref (comp); + + if (error != NULL) { + g_warning ( + "%s: Failed to create object: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + } + + memo_table_emit_status_message (memo_table, NULL, -1.0); + + g_object_unref (client); +} + static void memo_table_paste_clipboard (ESelectable *selectable) { @@ -816,14 +985,11 @@ /* Paste iCalendar data into the table. */ } else if (e_clipboard_wait_is_calendar_available (clipboard)) { - ECalModel *model; - gchar *ical_str; - - model = e_memo_table_get_model (memo_table); + gchar *calendar_source; - ical_str = e_clipboard_wait_for_calendar (clipboard); - e_cal_ops_paste_components (model, ical_str); - g_free (ical_str); + calendar_source = e_clipboard_wait_for_calendar (clipboard); + clipboard_get_calendar_data (memo_table, calendar_source); + g_free (calendar_source); } } @@ -988,6 +1154,16 @@ g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EMemoTableClass, status_message), + NULL, NULL, + e_marshal_VOID__STRING_DOUBLE, + G_TYPE_NONE, 2, + G_TYPE_STRING, G_TYPE_DOUBLE); } static void diff -Nru evolution-3.16.0/calendar/gui/e-memo-table.h evolution-3.12.11/calendar/gui/e-memo-table.h --- evolution-3.16.0/calendar/gui/e-memo-table.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-memo-table.h 2014-03-24 09:25:23.000000000 +0000 @@ -81,6 +81,9 @@ ECalModelComponent *comp_data); void (*popup_event) (EMemoTable *memo_table, GdkEvent *event); + void (*status_message) (EMemoTable *memo_table, + const gchar *message, + gdouble percent); }; GType e_memo_table_get_type (void); diff -Nru evolution-3.16.0/calendar/gui/e-task-list-selector.c evolution-3.12.11/calendar/gui/e-task-list-selector.c --- evolution-3.16.0/calendar/gui/e-task-list-selector.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-task-list-selector.c 2014-07-17 10:48:07.000000000 +0000 @@ -0,0 +1,466 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-task-list-selector.c + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +#include + +#include "e-task-list-selector.h" + +#include +#include + +#include "calendar/gui/comp-util.h" + +#define E_TASK_LIST_SELECTOR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorPrivate)) + +struct _ETaskListSelectorPrivate { + EShellView *shell_view; +}; + +G_DEFINE_TYPE ( + ETaskListSelector, + e_task_list_selector, + E_TYPE_CLIENT_SELECTOR) + +enum { + PROP_0, + PROP_SHELL_VIEW +}; + +static gboolean +task_list_selector_update_single_object (ECalClient *client, + icalcomponent *icalcomp) +{ + gchar *uid; + icalcomponent *tmp_icalcomp = NULL; + gboolean success; + + uid = (gchar *) icalcomponent_get_uid (icalcomp); + + e_cal_client_get_object_sync ( + client, uid, NULL, &tmp_icalcomp, NULL, NULL); + + if (tmp_icalcomp != NULL) { + icalcomponent_free (tmp_icalcomp); + + return e_cal_client_modify_object_sync ( + client, icalcomp, CALOBJ_MOD_ALL, NULL, NULL); + } + + success = e_cal_client_create_object_sync ( + client, icalcomp, &uid, NULL, NULL); + + if (uid != NULL) { + icalcomponent_set_uid (icalcomp, uid); + g_free (uid); + } + + return success; +} + +static gboolean +task_list_selector_update_objects (ECalClient *client, + icalcomponent *icalcomp) +{ + icalcomponent *subcomp; + icalcomponent_kind kind; + + kind = icalcomponent_isa (icalcomp); + if (kind == ICAL_VTODO_COMPONENT || kind == ICAL_VEVENT_COMPONENT) + return task_list_selector_update_single_object ( + client, icalcomp); + else if (kind != ICAL_VCALENDAR_COMPONENT) + return FALSE; + + subcomp = icalcomponent_get_first_component ( + icalcomp, ICAL_ANY_COMPONENT); + while (subcomp != NULL) { + gboolean success; + + kind = icalcomponent_isa (subcomp); + if (kind == ICAL_VTIMEZONE_COMPONENT) { + icaltimezone *zone; + GError *error = NULL; + + zone = icaltimezone_new (); + icaltimezone_set_component (zone, subcomp); + + e_cal_client_add_timezone_sync (client, zone, NULL, &error); + icaltimezone_free (zone, 1); + if (error != NULL) { + g_warning ( + "%s: Failed to add timezone: %s", + G_STRFUNC, error->message); + g_error_free (error); + return FALSE; + } + } else if (kind == ICAL_VTODO_COMPONENT || + kind == ICAL_VEVENT_COMPONENT) { + success = task_list_selector_update_single_object ( + client, subcomp); + if (!success) + return FALSE; + } + + subcomp = icalcomponent_get_next_component ( + icalcomp, ICAL_ANY_COMPONENT); + } + + return TRUE; +} + +static void +client_connect_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + EClient *client; + gchar *uid = user_data; + GError *error = NULL; + + g_return_if_fail (uid != NULL); + + client = e_client_selector_get_client_finish ( + E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + if (!e_client_is_readonly (client)) + e_cal_client_remove_object_sync ( + E_CAL_CLIENT (client), uid, NULL, + CALOBJ_MOD_THIS, NULL, NULL); + + g_object_unref (client); + +exit: + g_free (uid); +} + +static gboolean +task_list_selector_process_data (ESourceSelector *selector, + ECalClient *client, + const gchar *source_uid, + icalcomponent *icalcomp, + GdkDragAction action) +{ + ESource *source; + ESourceRegistry *registry; + icalcomponent *tmp_icalcomp = NULL; + const gchar *uid; + gchar *old_uid = NULL; + gboolean success = FALSE; + GError *error = NULL; + + /* FIXME Deal with GDK_ACTION_ASK. */ + if (action == GDK_ACTION_COPY) { + old_uid = g_strdup (icalcomponent_get_uid (icalcomp)); + uid = e_cal_component_gen_uid (); + icalcomponent_set_uid (icalcomp, uid); + } + + uid = icalcomponent_get_uid (icalcomp); + if (old_uid == NULL) + old_uid = g_strdup (uid); + + e_cal_client_get_object_sync ( + client, uid, NULL, &tmp_icalcomp, NULL, &error); + + if (tmp_icalcomp != NULL) { + icalcomponent_free (tmp_icalcomp); + success = TRUE; + goto exit; + } + + if (g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_NOT_FOUND)) { + g_clear_error (&error); + + } else if (error != NULL) { + g_message ( + "Failed to search the object in destination " + "task list: %s", error->message); + g_error_free (error); + goto exit; + } + + success = task_list_selector_update_objects (client, icalcomp); + + if (!success || action != GDK_ACTION_MOVE) + goto exit; + + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_source (registry, source_uid); + + if (source != NULL) { + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), source, NULL, + client_connect_cb, g_strdup (old_uid)); + g_object_unref (source); + } + +exit: + g_free (old_uid); + + return success; +} + +struct DropData { + ESourceSelector *selector; + GdkDragAction action; + GSList *list; +}; + +static void +client_connect_for_drop_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + struct DropData *dd = user_data; + EClient *client; + ECalClient *cal_client; + GSList *iter; + GError *error = NULL; + + g_return_if_fail (dd != NULL); + + client = e_client_selector_get_client_finish ( + E_CLIENT_SELECTOR (source_object), result, &error); + + /* Sanity check. */ + g_return_if_fail ( + ((client != NULL) && (error == NULL)) || + ((client == NULL) && (error != NULL))); + + if (error != NULL) { + g_warning ("%s: %s", G_STRFUNC, error->message); + g_error_free (error); + goto exit; + } + + cal_client = E_CAL_CLIENT (client); + + for (iter = dd->list; iter != NULL; iter = iter->next) { + gchar *source_uid = iter->data; + icalcomponent *icalcomp; + gchar *component_string; + + /* Each string is "source_uid\ncomponent_string". */ + component_string = strchr (source_uid, '\n'); + if (component_string == NULL) + continue; + + *component_string++ = '\0'; + icalcomp = icalparser_parse_string (component_string); + if (icalcomp == NULL) + continue; + + task_list_selector_process_data ( + dd->selector, cal_client, source_uid, + icalcomp, dd->action); + + icalcomponent_free (icalcomp); + } + + g_object_unref (client); + +exit: + g_slist_foreach (dd->list, (GFunc) g_free, NULL); + g_slist_free (dd->list); + g_object_unref (dd->selector); + g_free (dd); +} + +static void +task_list_selector_set_shell_view (ETaskListSelector *selector, + EShellView *shell_view) +{ + g_return_if_fail (E_IS_SHELL_VIEW (shell_view)); + g_return_if_fail (selector->priv->shell_view == NULL); + + selector->priv->shell_view = g_object_ref (shell_view); +} + +static void +task_list_selector_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + task_list_selector_set_shell_view ( + E_TASK_LIST_SELECTOR (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_list_selector_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_VIEW: + g_value_set_object ( + value, + e_task_list_selector_get_shell_view ( + E_TASK_LIST_SELECTOR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +task_list_selector_constructed (GObject *object) +{ + ESourceSelector *selector; + ESourceRegistry *registry; + ESource *source; + + selector = E_SOURCE_SELECTOR (object); + registry = e_source_selector_get_registry (selector); + source = e_source_registry_ref_default_task_list (registry); + e_source_selector_set_primary_selection (selector, source); + g_object_unref (source); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (e_task_list_selector_parent_class)->constructed (object); +} + +static gboolean +task_list_selector_data_dropped (ESourceSelector *selector, + GtkSelectionData *selection_data, + ESource *destination, + GdkDragAction action, + guint info) +{ + struct DropData *dd; + + dd = g_new0 (struct DropData, 1); + dd->selector = g_object_ref (selector); + dd->action = action; + dd->list = cal_comp_selection_get_string_list (selection_data); + + e_client_selector_get_client ( + E_CLIENT_SELECTOR (selector), destination, NULL, + client_connect_for_drop_cb, dd); + + return TRUE; +} + +static void +task_list_selector_dispose (GObject *object) +{ + ETaskListSelectorPrivate *priv; + + priv = E_TASK_LIST_SELECTOR_GET_PRIVATE (object); + + g_clear_object (&priv->shell_view); + + /* Chain up to the parent' s dispose() method. */ + G_OBJECT_CLASS (e_task_list_selector_parent_class)->dispose (object); +} + +static void +e_task_list_selector_class_init (ETaskListSelectorClass *class) +{ + GObjectClass *object_class; + ESourceSelectorClass *source_selector_class; + + g_type_class_add_private (class, sizeof (ETaskListSelectorPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = task_list_selector_constructed; + object_class->set_property = task_list_selector_set_property; + object_class->get_property = task_list_selector_get_property; + object_class->dispose = task_list_selector_dispose; + + source_selector_class = E_SOURCE_SELECTOR_CLASS (class); + source_selector_class->data_dropped = task_list_selector_data_dropped; + + g_object_class_install_property ( + object_class, + PROP_SHELL_VIEW, + g_param_spec_object ( + "shell-view", + NULL, + NULL, + E_TYPE_SHELL_VIEW, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); +} + +static void +e_task_list_selector_init (ETaskListSelector *selector) +{ + selector->priv = E_TASK_LIST_SELECTOR_GET_PRIVATE (selector); + + gtk_drag_dest_set ( + GTK_WIDGET (selector), GTK_DEST_DEFAULT_ALL, + NULL, 0, GDK_ACTION_COPY | GDK_ACTION_MOVE); + + e_drag_dest_add_calendar_targets (GTK_WIDGET (selector)); +} + +GtkWidget * +e_task_list_selector_new (EClientCache *client_cache, + EShellView *shell_view) +{ + ESourceRegistry *registry; + GtkWidget *widget; + + g_return_val_if_fail (E_IS_CLIENT_CACHE (client_cache), NULL); + g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL); + + registry = e_client_cache_ref_registry (client_cache); + + widget = g_object_new ( + E_TYPE_TASK_LIST_SELECTOR, + "client-cache", client_cache, + "extension-name", E_SOURCE_EXTENSION_TASK_LIST, + "shell-view", shell_view, + "registry", registry, NULL); + + g_object_unref (registry); + + return widget; +} + +EShellView * +e_task_list_selector_get_shell_view (ETaskListSelector *selector) +{ + g_return_val_if_fail (E_IS_TASK_LIST_SELECTOR (selector), NULL); + + return selector->priv->shell_view; +} + diff -Nru evolution-3.16.0/calendar/gui/e-task-list-selector.h evolution-3.12.11/calendar/gui/e-task-list-selector.h --- evolution-3.16.0/calendar/gui/e-task-list-selector.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-task-list-selector.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,72 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-task-list-selector.h + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + */ + +/* XXX This widget is nearly identical to EMemoListSelector. If + * ECalendarSelector ever learns how to move selections from + * one source to another, perhaps these ESourceSelector sub- + * classes could someday be combined. */ + +#ifndef E_TASK_LIST_SELECTOR_H +#define E_TASK_LIST_SELECTOR_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_TASK_LIST_SELECTOR \ + (e_task_list_selector_get_type ()) +#define E_TASK_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelector)) +#define E_TASK_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass)) +#define E_IS_TASK_LIST_SELECTOR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_TASK_LIST_SELECTOR)) +#define E_IS_TASK_LIST_SELECTOR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_TASK_LIST_SELECTOR)) +#define E_TASK_LIST_SELECTOR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_TASK_LIST_SELECTOR, ETaskListSelectorClass)) + +G_BEGIN_DECLS + +typedef struct _ETaskListSelector ETaskListSelector; +typedef struct _ETaskListSelectorClass ETaskListSelectorClass; +typedef struct _ETaskListSelectorPrivate ETaskListSelectorPrivate; + +struct _ETaskListSelector { + EClientSelector parent; + ETaskListSelectorPrivate *priv; +}; + +struct _ETaskListSelectorClass { + EClientSelectorClass parent_class; +}; + +GType e_task_list_selector_get_type (void); +GtkWidget * e_task_list_selector_new (EClientCache *client_cache, + EShellView *shell_view); +EShellView * e_task_list_selector_get_shell_view + (ETaskListSelector *selector); + +G_END_DECLS + +#endif /* E_TASK_LIST_SELECTOR_H */ diff -Nru evolution-3.16.0/calendar/gui/e-task-table.c evolution-3.12.11/calendar/gui/e-task-table.c --- evolution-3.16.0/calendar/gui/e-task-table.c 2015-02-24 08:13:30.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-task-table.c 2014-10-09 09:05:52.000000000 +0000 @@ -39,9 +39,9 @@ #include "calendar-config.h" #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/task-editor.h" #include "e-cal-model-tasks.h" -#include "e-cal-ops.h" #include "e-calendar-view.h" #include "e-cell-date-edit-text.h" #include "print.h" @@ -76,6 +76,7 @@ enum { OPEN_COMPONENT, POPUP_EVENT, + STATUS_MESSAGE, LAST_SIGNAL }; @@ -121,6 +122,16 @@ g_signal_emit (task_table, signal_id, 0, event); } +static void +task_table_emit_status_message (ETaskTable *task_table, + const gchar *message, + gdouble percent) +{ + guint signal_id = signals[STATUS_MESSAGE]; + + g_signal_emit (task_table, signal_id, 0, message, percent); +} + static gint task_table_percent_compare_cb (gconstpointer a, gconstpointer b, @@ -232,14 +243,51 @@ return (status_a < status_b) ? -1 : (status_a > status_b); } +static void +task_table_model_cal_view_progress_cb (ETaskTable *task_table, + const gchar *message, + gint progress, + ECalClientSourceType type) +{ + gdouble percent = (gdouble) progress; + + task_table_emit_status_message (task_table, message, percent); +} + +static void +task_table_model_cal_view_complete_cb (ETaskTable *task_table, + const GError *error, + ECalClientSourceType type) +{ + task_table_emit_status_message (task_table, NULL, -1.0); +} + /* Deletes all of the selected components in the table */ static void delete_selected_components (ETaskTable *task_table) { - GSList *objs; + GSList *objs, *l; + const gchar *status_message; objs = e_task_table_get_selected (task_table); - e_cal_ops_delete_ecalmodel_components (task_table->priv->model, objs); + + status_message = _("Deleting selected objects"); + task_table_emit_status_message (task_table, status_message, -1.0); + + for (l = objs; l; l = l->next) { + ECalModelComponent *comp_data = (ECalModelComponent *) l->data; + GError *error = NULL; + + e_cal_client_remove_object_sync ( + comp_data->client, + icalcomponent_get_uid (comp_data->icalcomp), + NULL, CALOBJ_MOD_THIS, NULL, &error); + delete_error_dialog (error, E_CAL_COMPONENT_TODO); + g_clear_error (&error); + } + + task_table_emit_status_message (task_table, NULL, -1.0); + g_slist_free (objs); } @@ -261,6 +309,16 @@ task_table->priv->model = g_object_ref (model); + g_signal_connect_swapped ( + model, "cal-view-progress", + G_CALLBACK (task_table_model_cal_view_progress_cb), + task_table); + + g_signal_connect_swapped ( + model, "cal-view-complete", + G_CALLBACK (task_table_model_cal_view_complete_cb), + task_table); + /* redraw on drawing options change */ task_table->priv->notify_highlight_due_today_id = e_signal_connect_notify ( model, "notify::highlight-due-today", @@ -445,13 +503,13 @@ "bg_color_column", E_CAL_MODEL_FIELD_COLOR, NULL); - e_binding_bind_property ( + g_object_bind_property ( model, "timezone", cell, "timezone", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | @@ -461,7 +519,7 @@ e_cell_popup_set_child (E_CELL_POPUP (popup_cell), cell); g_object_unref (cell); - e_binding_bind_property ( + g_object_bind_property ( model, "use-24-hour-format", popup_cell, "use-24-hour-format", G_BINDING_BIDIRECTIONAL | @@ -981,9 +1039,6 @@ for (iter = list; iter != NULL && sources_are_editable; iter = iter->next) { ECalModelComponent *comp_data = iter->data; - if (!comp_data) - continue; - sources_are_editable = sources_are_editable && !e_client_is_readonly (E_CLIENT (comp_data->client)); } @@ -1103,12 +1158,110 @@ clipboard_get_calendar_data (ETaskTable *task_table, const gchar *text) { + icalcomponent *icalcomp; + gchar *uid; + ECalComponent *comp; + ECalModel *model; + ECalClient *client; + icalcomponent_kind kind; + const gchar *status_message; + g_return_if_fail (E_IS_TASK_TABLE (task_table)); if (!text || !*text) return; - e_cal_ops_paste_components (e_task_table_get_model (task_table), text); + icalcomp = icalparser_parse_string (text); + if (!icalcomp) + return; + + /* check the type of the component */ + kind = icalcomponent_isa (icalcomp); + if (kind != ICAL_VCALENDAR_COMPONENT && + kind != ICAL_VEVENT_COMPONENT && + kind != ICAL_VTODO_COMPONENT && + kind != ICAL_VJOURNAL_COMPONENT) { + return; + } + + model = e_task_table_get_model (task_table); + client = e_cal_model_ref_default_client (model); + + status_message = _("Updating objects"); + task_table_emit_status_message (task_table, status_message, -1.0); + + if (kind == ICAL_VCALENDAR_COMPONENT) { + icalcomponent_kind child_kind; + icalcomponent *subcomp; + icalcomponent *vcal_comp; + + vcal_comp = icalcomp; + subcomp = icalcomponent_get_first_component ( + vcal_comp, ICAL_ANY_COMPONENT); + while (subcomp) { + child_kind = icalcomponent_isa (subcomp); + if (child_kind == ICAL_VEVENT_COMPONENT || + child_kind == ICAL_VTODO_COMPONENT || + child_kind == ICAL_VJOURNAL_COMPONENT) { + ECalComponent *tmp_comp; + GError *error = NULL; + + uid = e_cal_component_gen_uid (); + tmp_comp = e_cal_component_new (); + e_cal_component_set_icalcomponent ( + tmp_comp, + icalcomponent_new_clone (subcomp)); + e_cal_component_set_uid (tmp_comp, uid); + g_free (uid); + uid = NULL; + + /* FIXME should we convert start/due/complete + * times? Also, need error handling. */ + e_cal_client_create_object_sync ( + client, + e_cal_component_get_icalcomponent (tmp_comp), + NULL, NULL, &error); + + if (error != NULL) { + g_warning ( + "%s: Failed to create object: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + + g_object_unref (tmp_comp); + } + subcomp = icalcomponent_get_next_component ( + vcal_comp, ICAL_ANY_COMPONENT); + } + } else { + GError *error = NULL; + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + uid = e_cal_component_gen_uid (); + e_cal_component_set_uid (comp, (const gchar *) uid); + g_free (uid); + uid = NULL; + + e_cal_client_create_object_sync ( + client, + e_cal_component_get_icalcomponent (comp), + NULL, NULL, &error); + + if (error != NULL) { + g_warning ( + "%s: Failed to create object: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + + g_object_unref (comp); + } + + task_table_emit_status_message (task_table, NULL, -1.0); + + g_object_unref (client); } static void @@ -1241,6 +1394,7 @@ ECalComponent *comp = NULL; gboolean delete = TRUE; gint n_selected; + GError *error = NULL; task_table = E_TASK_TABLE (selectable); model = e_task_table_get_model (task_table); @@ -1270,16 +1424,30 @@ comp, &retract_comment, GTK_WIDGET (task_table), &retract); if (retract) { - icalcomponent *icalcomp = NULL; + GSList *users = NULL; + icalcomponent *icalcomp = NULL, *mod_comp = NULL; add_retract_data (comp, retract_comment); icalcomp = e_cal_component_get_icalcomponent (comp); icalcomponent_set_method (icalcomp, ICAL_METHOD_CANCEL); + e_cal_client_send_objects_sync ( + comp_data->client, icalcomp, + &users, &mod_comp, NULL, &error); + if (error != NULL) { + delete_error_dialog (error, E_CAL_COMPONENT_TODO); + g_clear_error (&error); + } else { + + if (mod_comp) + icalcomponent_free (mod_comp); + + if (users) { + g_slist_foreach (users, (GFunc) g_free, NULL); + g_slist_free (users); + } + } - e_cal_ops_send_component (model, comp_data->client, icalcomp); } - - g_free (retract_comment); } else if (e_cal_model_get_confirm_delete (model)) delete = delete_component_dialog ( comp, FALSE, n_selected, @@ -1376,6 +1544,16 @@ g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_EVENT | G_SIGNAL_TYPE_STATIC_SCOPE); + + signals[STATUS_MESSAGE] = g_signal_new ( + "status-message", + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (ETaskTableClass, status_message), + NULL, NULL, + e_marshal_VOID__STRING_DOUBLE, + G_TYPE_NONE, 2, + G_TYPE_STRING, G_TYPE_DOUBLE); } static void @@ -1535,16 +1713,14 @@ gpointer user_data) { ECalModel *model = user_data; - ECalClient *cal_client; GSList *m, *objects; gboolean changed = FALSE; gint pos; GPtrArray *comp_objects; GError *error = NULL; - cal_client = E_CAL_CLIENT (source_object); - - e_cal_client_get_object_list_finish (cal_client, result, &objects, &error); + e_cal_client_get_object_list_finish ( + E_CAL_CLIENT (source_object), result, &objects, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); @@ -1577,16 +1753,17 @@ comp, icalcomponent_new_clone (m->data)); id = e_cal_component_get_id (comp); - comp_data = e_cal_model_get_component_for_client_and_uid (model, cal_client, id); + comp_data = e_cal_model_get_component_for_uid (model, id); if (comp_data != NULL) { e_table_model_pre_change (E_TABLE_MODEL (model)); pos = get_position_in_array ( comp_objects, comp_data); - if (g_ptr_array_remove (comp_objects, comp_data)) - g_object_unref (comp_data); e_table_model_row_deleted ( E_TABLE_MODEL (model), pos); changed = TRUE; + + if (g_ptr_array_remove (comp_objects, comp_data)) + g_object_unref (comp_data); } e_cal_component_free_id (id); g_object_unref (comp); @@ -1606,16 +1783,14 @@ GAsyncResult *result, gpointer user_data) { - ECalClient *cal_client; + ECalClient *client; ECalModel *model = user_data; GSList *m, *objects; GPtrArray *comp_objects; GError *error = NULL; - cal_client = E_CAL_CLIENT (source_object); - g_return_if_fail (cal_client != NULL); - - e_cal_client_get_object_list_finish (cal_client, result, &objects, &error); + e_cal_client_get_object_list_finish ( + E_CAL_CLIENT (source_object), result, &objects, &error); if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { g_error_free (error); @@ -1636,6 +1811,9 @@ return; } + client = E_CAL_CLIENT (source_object); + g_return_if_fail (client != NULL); + comp_objects = e_cal_model_get_object_array (model); g_return_if_fail (comp_objects != NULL); @@ -1648,11 +1826,11 @@ comp, icalcomponent_new_clone (m->data)); id = e_cal_component_get_id (comp); - if (!(e_cal_model_get_component_for_client_and_uid (model, cal_client, id))) { + if (!(e_cal_model_get_component_for_uid (model, id))) { e_table_model_pre_change (E_TABLE_MODEL (model)); comp_data = g_object_new ( E_TYPE_CAL_MODEL_COMPONENT, NULL); - comp_data->client = g_object_ref (cal_client); + comp_data->client = g_object_ref (client); comp_data->icalcomp = icalcomponent_new_clone (m->data); e_cal_model_set_instance_times ( @@ -1718,7 +1896,6 @@ gboolean config_changed) { ECalModel *model; - ECalDataModel *data_model; GList *client_list; GCancellable *cancellable; gchar *hide_sexp, *show_sexp; @@ -1732,7 +1909,6 @@ cancellable = task_table->priv->completed_cancellable; model = e_task_table_get_model (task_table); - data_model = e_cal_model_get_data_model (model); hide_sexp = calendar_config_get_hide_completed_tasks_sexp (TRUE); show_sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE); @@ -1740,7 +1916,7 @@ if (!(hide_sexp && show_sexp)) show_sexp = g_strdup ("(is-completed?)"); - client_list = e_cal_data_model_get_clients (data_model); + client_list = e_cal_model_list_clients (model); /* Delete rows from model */ if (hide_sexp) { diff -Nru evolution-3.16.0/calendar/gui/e-task-table.h evolution-3.12.11/calendar/gui/e-task-table.h --- evolution-3.16.0/calendar/gui/e-task-table.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-task-table.h 2014-03-24 09:25:23.000000000 +0000 @@ -79,6 +79,9 @@ ECalModelComponent *comp_data); void (*popup_event) (ETaskTable *task_table, GdkEvent *event); + void (*status_message) (ETaskTable *task_table, + const gchar *message, + gdouble percent); }; GType e_task_table_get_type (void); diff -Nru evolution-3.16.0/calendar/gui/e-week-view.c evolution-3.12.11/calendar/gui/e-week-view.c --- evolution-3.16.0/calendar/gui/e-week-view.c 2015-02-24 14:50:34.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-week-view.c 2014-12-22 15:05:29.000000000 +0000 @@ -36,6 +36,7 @@ #include #include "dialogs/delete-comp.h" +#include "dialogs/delete-error.h" #include "dialogs/send-comp.h" #include "dialogs/cancel-comp.h" #include "dialogs/recur-comp.h" @@ -44,7 +45,6 @@ #include "calendar-config.h" #include "comp-util.h" #include "e-cal-model-calendar.h" -#include "e-cal-ops.h" #include "e-week-view-event-item.h" #include "e-week-view-layout.h" #include "e-week-view-main-item.h" @@ -140,12 +140,11 @@ gint day); static void e_week_view_free_events (EWeekView *week_view); -static void e_week_view_add_event (ECalClient *client, - ECalComponent *comp, - time_t start, - time_t end, - gboolean prepend, - gpointer data); +static gboolean e_week_view_add_event (ECalComponent *comp, + time_t start, + time_t end, + gboolean prepend, + gpointer data); static void e_week_view_check_layout (EWeekView *week_view); static void e_week_view_ensure_events_sorted (EWeekView *week_view); static void e_week_view_reshape_events (EWeekView *week_view); @@ -239,7 +238,7 @@ /* Add the object */ add_event_data.week_view = week_view; add_event_data.comp_data = comp_data; - e_week_view_add_event (comp_data->client, comp, comp_data->instance_start, comp_data->instance_end, FALSE, &add_event_data); + e_week_view_add_event (comp, comp_data->instance_start, comp_data->instance_end, FALSE, &add_event_data); g_object_unref (comp); g_free (rid); @@ -375,67 +374,6 @@ } static void -e_week_view_precalc_visible_time_range (ECalendarView *cal_view, - time_t in_start_time, - time_t in_end_time, - time_t *out_start_time, - time_t *out_end_time) -{ - EWeekView *week_view; - GDate date, base_date; - GDateWeekday weekday; - GDateWeekday display_start_day; - guint day_offset, week_start_offset; - gint num_days; - icaltimezone *zone; - - g_return_if_fail (E_IS_WEEK_VIEW (cal_view)); - g_return_if_fail (out_start_time != NULL); - g_return_if_fail (out_end_time != NULL); - - week_view = E_WEEK_VIEW (cal_view); - zone = e_calendar_view_get_timezone (cal_view); - - time_to_gdate_with_zone (&date, in_start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); - - weekday = g_date_get_weekday (&date); - display_start_day = e_week_view_get_display_start_day (week_view); - - /* Convert it to an offset from the start of the display. */ - week_start_offset = e_weekday_get_days_between (display_start_day, weekday); - - /* Set the day_offset to the result, so we move back to the - * start of the week. */ - day_offset = week_start_offset; - - /* Calculate the base date, i.e. the first day shown when the - * scrollbar adjustment value is 0. */ - base_date = date; - g_date_subtract_days (&base_date, day_offset); - - num_days = e_week_view_get_weeks_shown (week_view) * 7; - - /* See if we need to update the first day shown. */ - if (!g_date_valid (&week_view->priv->first_day_shown) - || g_date_compare (&week_view->priv->first_day_shown, &base_date)) { - gint day; - - in_start_time = time_add_day_with_zone (in_start_time, -((gint) day_offset), zone); - in_start_time = time_day_begin_with_zone (in_start_time, zone); - - *out_start_time = in_start_time; - *out_end_time = in_start_time; - - for (day = 1; day <= num_days; day++) { - *out_end_time = time_add_day_with_zone (*out_end_time, 1, zone); - } - } else { - *out_start_time = week_view->day_starts[0]; - *out_end_time = week_view->day_starts[num_days]; - } -} - -static void week_view_time_range_changed_cb (EWeekView *week_view, time_t start_time, time_t end_time, @@ -624,140 +562,105 @@ return width; } -typedef struct { - EWeekView *week_view; - time_t dtstart, dtend; - gchar *initial_text; - gboolean paste_clipboard; -} NewEventInRangeData; - -static void -new_event_in_rage_data_free (gpointer ptr) -{ - NewEventInRangeData *ned = ptr; - - if (ned) { - g_clear_object (&ned->week_view); - g_free (ned->initial_text); - g_free (ned); - } -} - -static void -week_view_new_event_in_selected_range_cb (ECalModel *model, - ECalClient *client, - icalcomponent *default_component, - gpointer user_data) +static gboolean +e_week_view_add_new_event_in_selected_range (EWeekView *week_view, + const gchar *initial_text) { - NewEventInRangeData *ned = user_data; + ECalClient *client; + ECalModel *model; ECalComponent *comp = NULL; + icalcomponent *icalcomp; gint event_num; ECalComponentDateTime date; struct icaltimetype itt; + time_t dtstart, dtend; const gchar *uid; AddEventData add_event_data; EWeekViewEvent *wvevent; EWeekViewEventSpan *span; - icaltimezone *zone; + gboolean success = FALSE; + + model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); + client = e_cal_model_ref_default_client (model); /* Check if the client is read only */ if (e_client_is_readonly (E_CLIENT (client))) goto exit; /* Add a new event covering the selected range. */ - comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone (default_component)); - g_return_if_fail (comp != NULL); + icalcomp = e_cal_model_create_component_with_defaults (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), TRUE); + if (!icalcomp) + goto exit; + uid = icalcomponent_get_uid (icalcomp); - uid = icalcomponent_get_uid (default_component); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + dtstart = week_view->day_starts[week_view->selection_start_day]; + dtend = week_view->day_starts[week_view->selection_end_day + 1]; date.value = &itt; date.tzid = NULL; - zone = e_cal_model_get_timezone (model); - /* We use DATE values now, so we don't need the timezone. */ /*date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view)));*/ - *date.value = icaltime_from_timet_with_zone (ned->dtstart, TRUE, zone); + *date.value = icaltime_from_timet_with_zone (dtstart, TRUE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); e_cal_component_set_dtstart (comp, &date); - *date.value = icaltime_from_timet_with_zone (ned->dtend, TRUE, zone); + *date.value = icaltime_from_timet_with_zone (dtend, TRUE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (week_view))); e_cal_component_set_dtend (comp, &date); /* Editor default in week/month view */ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT); + e_cal_component_set_categories ( + comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (week_view))); + /* We add the event locally and start editing it. We don't send it * to the server until the user finishes editing it. */ - add_event_data.week_view = ned->week_view; + add_event_data.week_view = week_view; add_event_data.comp_data = NULL; - e_week_view_add_event (client, comp, ned->dtstart, ned->dtend, TRUE, &add_event_data); - e_week_view_check_layout (ned->week_view); - gtk_widget_queue_draw (ned->week_view->main_canvas); + e_week_view_add_event (comp, dtstart, dtend, TRUE, &add_event_data); + e_week_view_check_layout (week_view); + gtk_widget_queue_draw (week_view->main_canvas); - if (!e_week_view_find_event_from_uid (ned->week_view, client, uid, NULL, &event_num)) { + if (!e_week_view_find_event_from_uid (week_view, client, uid, NULL, &event_num)) { g_warning ("Couldn't find event to start editing.\n"); goto exit; } - if (!is_array_index_in_bounds (ned->week_view->events, event_num)) + if (!is_array_index_in_bounds (week_view->events, event_num)) goto exit; - wvevent = &g_array_index (ned->week_view->events, EWeekViewEvent, event_num); + wvevent = &g_array_index (week_view->events, EWeekViewEvent, + event_num); - if (!is_array_index_in_bounds (ned->week_view->spans, wvevent->spans_index + 0)) + if (!is_array_index_in_bounds (week_view->spans, wvevent->spans_index + 0)) goto exit; - span = &g_array_index (ned->week_view->spans, EWeekViewEventSpan, wvevent->spans_index + 0); + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + wvevent->spans_index + 0); /* If the event can't be fit on the screen, don't try to edit it. */ if (!span->text_item) { - e_week_view_foreach_event_with_uid (ned->week_view, uid, e_week_view_remove_event_cb, NULL); + e_week_view_foreach_event_with_uid (week_view, uid, + e_week_view_remove_event_cb, NULL); goto exit; } - e_week_view_start_editing_event (ned->week_view, event_num, 0, ned->initial_text); - - if (ned->paste_clipboard) { - wvevent = &g_array_index (ned->week_view->events, EWeekViewEvent, ned->week_view->editing_event_num); + e_week_view_start_editing_event ( + week_view, event_num, 0, (gchar *) initial_text); - if (!is_array_index_in_bounds (ned->week_view->spans, wvevent->spans_index + ned->week_view->editing_span_num)) - return; + success = TRUE; - span = &g_array_index (ned->week_view->spans, EWeekViewEventSpan, wvevent->spans_index + ned->week_view->editing_span_num); - - if (span->text_item && - E_IS_TEXT (span->text_item) && - E_TEXT (span->text_item)->editing) { - e_text_paste_clipboard (E_TEXT (span->text_item)); - } - } - - exit: +exit: g_clear_object (&comp); -} - -static void -e_week_view_add_new_event_in_selected_range (EWeekView *week_view, - const gchar *initial_text, - gboolean paste_clipboard) -{ - NewEventInRangeData *ned; - ECalModel *model; - const gchar *source_uid; - - ned = g_new0 (NewEventInRangeData, 1); - ned->week_view = g_object_ref (week_view); - ned->initial_text = g_strdup (initial_text); - ned->dtstart = week_view->day_starts[week_view->selection_start_day]; - ned->dtend = week_view->day_starts[week_view->selection_end_day + 1]; - ned->paste_clipboard = paste_clipboard; - - model = e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)); - source_uid = e_cal_model_get_default_source_uid (model); + g_clear_object (&client); - e_cal_ops_get_default_component (model, source_uid, TRUE, - week_view_new_event_in_selected_range_cb, ned, new_event_in_rage_data_free); + return success; } static void @@ -1480,10 +1383,9 @@ week_view = E_WEEK_VIEW (cal_view); - if (week_view->editing_event_num == -1) { - e_week_view_add_new_event_in_selected_range (week_view, NULL, TRUE); + if (week_view->editing_event_num == -1 && + !e_week_view_add_new_event_in_selected_range (week_view, NULL)) return; - } if (!is_array_index_in_bounds (week_view->events, week_view->editing_event_num)) return; @@ -1595,7 +1497,6 @@ view_class->get_selected_time_range = week_view_get_selected_time_range; view_class->set_selected_time_range = week_view_set_selected_time_range; view_class->get_visible_time_range = week_view_get_visible_time_range; - view_class->precalc_visible_time_range = e_week_view_precalc_visible_time_range; view_class->paste_text = week_view_paste_text; class->cursor_key_up = week_view_cursor_key_up; @@ -2797,7 +2698,7 @@ week_view->before_click_dtstart, week_view->before_click_dtend); } - e_calendar_view_new_appointment_full (E_CALENDAR_VIEW (week_view), FALSE, calendar_config_get_prefer_meeting (), FALSE); + e_calendar_view_new_appointment_full (E_CALENDAR_VIEW (week_view), FALSE, FALSE, calendar_config_get_prefer_meeting ()); return TRUE; } @@ -3129,9 +3030,8 @@ } /* This adds one event to the view, adding it to the appropriate array. */ -static void -e_week_view_add_event (ECalClient *client, - ECalComponent *comp, +static gboolean +e_week_view_add_event (ECalComponent *comp, time_t start, time_t end, gboolean prepend, @@ -3148,9 +3048,9 @@ /* Check that the event times are valid. */ num_days = e_week_view_get_weeks_shown (add_event_data->week_view) * 7; - g_return_if_fail (start <= end); - g_return_if_fail (start < add_event_data->week_view->day_starts[num_days]); - g_return_if_fail (end > add_event_data->week_view->day_starts[0]); + g_return_val_if_fail (start <= end, TRUE); + g_return_val_if_fail (start < add_event_data->week_view->day_starts[num_days], TRUE); + g_return_val_if_fail (end > add_event_data->week_view->day_starts[0], TRUE); start_tt = icaltime_from_timet_with_zone ( start, FALSE, @@ -3163,8 +3063,8 @@ event.comp_data = g_object_ref (add_event_data->comp_data); } else { event.comp_data = g_object_new (E_TYPE_CAL_MODEL_COMPONENT, NULL); - event.comp_data->is_new_component = TRUE; - event.comp_data->client = g_object_ref (client); + + event.comp_data->client = e_cal_model_ref_default_client (e_calendar_view_get_model (E_CALENDAR_VIEW (add_event_data->week_view))); e_cal_component_abort_sequence (comp); event.comp_data->icalcomp = icalcomponent_new_clone (e_cal_component_get_icalcomponent (comp)); } @@ -3196,6 +3096,8 @@ g_array_append_val (add_event_data->week_view->events, event); add_event_data->week_view->events_sorted = FALSE; add_event_data->week_view->events_need_layout = TRUE; + + return TRUE; } /* This lays out the events, or reshapes them, as necessary. */ @@ -3996,7 +3898,7 @@ /* if we started to editing new item on the canvas, then do not open editing dialog until it's saved, * because the save of the event recalculates event numbers and you can edit different one */ - if (event->comp_data->is_new_component) + if (!is_icalcomp_on_the_server (event->comp_data->icalcomp, event->comp_data->client)) return TRUE; e_calendar_view_edit_appointment ( @@ -4303,7 +4205,8 @@ ECalComponentDateTime date; struct icaltimetype itt; ECalClient *client; - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; event_num = week_view->editing_event_num; @@ -4353,20 +4256,25 @@ goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { e_cal_component_set_rdate_list (comp, NULL); e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view))); e_cal_component_commit_sequence (comp); - e_cal_ops_modify_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - client, e_cal_component_get_icalcomponent (comp), - mod, E_CAL_OPS_SEND_FLAG_ASK | E_CAL_OPS_SEND_FLAG_IS_NEW_COMPONENT); + e_calendar_view_modify_and_send ( + E_CALENDAR_VIEW (week_view), + comp, client, mod, toplevel, TRUE); out: g_object_unref (comp); @@ -4453,7 +4361,7 @@ e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); client = event->comp_data->client; - on_server = !event->comp_data->is_new_component; + on_server = cal_comp_is_on_server (comp, client); if (string_is_empty (text) && !on_server) { e_cal_component_get_uid (comp, &uid); @@ -4489,20 +4397,45 @@ e_cal_component_commit_sequence (comp); if (!on_server) { - e_cal_ops_create_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), client, icalcomp, - e_calendar_view_component_created_cb, g_object_ref (week_view), g_object_unref); + gchar *uid = NULL; + GError *error = NULL; + + e_cal_client_create_object_sync ( + client, icalcomp, &uid, NULL, &error); + + if (error != NULL) { + g_warning ( + G_STRLOC ": Could not create the object! %s", + error->message); + uid = NULL; + } else { + if (uid) + icalcomponent_set_uid (icalcomp, uid); + + e_calendar_view_emit_user_created ( + E_CALENDAR_VIEW (week_view), client); + } + + g_free (uid); + + if (error != NULL) + g_error_free (error); /* we remove the object since we either got the update from the server or failed */ e_week_view_remove_event_cb (week_view, event_num, NULL); } else { - ECalObjModType mod = E_CAL_OBJ_MOD_ALL; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; if (e_cal_component_has_recurrences (comp)) { if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { goto out; } - if (mod == E_CAL_OBJ_MOD_THIS) { + if (mod == CALOBJ_MOD_ALL) + comp_util_sanitize_recurrence_master (comp, client); + + if (mod == CALOBJ_MOD_THIS) { ECalComponentDateTime dt; struct icaltimetype tt; gchar *tzid; @@ -4549,13 +4482,18 @@ e_cal_component_set_rrule_list (comp, NULL); e_cal_component_set_exdate_list (comp, NULL); e_cal_component_set_exrule_list (comp, NULL); + + e_cal_component_commit_sequence (comp); } } else if (e_cal_component_is_instance (comp)) - mod = E_CAL_OBJ_MOD_THIS; + mod = CALOBJ_MOD_THIS; + + /* FIXME When sending here, what exactly should we send? */ + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (week_view))); - e_cal_component_commit_sequence (comp); - e_cal_ops_modify_component (e_calendar_view_get_model (E_CALENDAR_VIEW (week_view)), - client, e_cal_component_get_icalcomponent (comp), mod, E_CAL_OPS_SEND_FLAG_ASK); + e_calendar_view_modify_and_send ( + E_CALENDAR_VIEW (week_view), + comp, client, mod, toplevel, FALSE); } } @@ -4740,6 +4678,7 @@ gchar *initial_text; guint keyval; gboolean stop_emission; + gboolean ret_val; g_return_val_if_fail (widget != NULL, FALSE); g_return_val_if_fail (E_IS_WEEK_VIEW (widget), FALSE); @@ -4825,12 +4764,12 @@ } else initial_text = e_utf8_from_gtk_event_key (widget, event->keyval, event->string); - e_week_view_add_new_event_in_selected_range (week_view, initial_text, FALSE); + ret_val = e_week_view_add_new_event_in_selected_range (week_view, initial_text); if (initial_text) g_free (initial_text); - return TRUE; + return ret_val; } static gint @@ -4884,10 +4823,17 @@ GnomeCanvasItem *item) { gint day; + GnomeCalendar *calendar; for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; ++day) { if (item == week_view->jump_buttons[day]) { - e_calendar_view_move_view_range (E_CALENDAR_VIEW (week_view), E_CALENDAR_VIEW_MOVE_TO_EXACT_DAY, week_view->day_starts[day]); + calendar = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); + if (calendar) + gnome_calendar_dayjump + (calendar, + week_view->day_starts[day]); + else + g_warning ("Calendar not set"); return; } } diff -Nru evolution-3.16.0/calendar/gui/e-week-view-event-item.c evolution-3.12.11/calendar/gui/e-week-view-event-item.c --- evolution-3.16.0/calendar/gui/e-week-view-event-item.c 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-week-view-event-item.c 2014-07-07 10:56:09.000000000 +0000 @@ -157,7 +157,10 @@ if (editing && event && editing->comp_data == event->comp_data && is_comp_data_valid (editing) && - (!event->comp_data || event->comp_data->is_new_component)) + (!event->comp_data || + !is_icalcomp_on_the_server ( + event->comp_data->icalcomp, + event->comp_data->client))) return TRUE; } diff -Nru evolution-3.16.0/calendar/gui/e-week-view.h evolution-3.12.11/calendar/gui/e-week-view.h --- evolution-3.16.0/calendar/gui/e-week-view.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-week-view.h 2014-07-07 10:56:09.000000000 +0000 @@ -26,6 +26,7 @@ #include #include "e-calendar-view.h" +#include "gnome-cal.h" /* * EWeekView - displays the Week & Month views of the calendar. diff -Nru evolution-3.16.0/calendar/gui/e-week-view-layout.c evolution-3.12.11/calendar/gui/e-week-view-layout.c --- evolution-3.16.0/calendar/gui/e-week-view-layout.c 2014-11-13 07:32:25.000000000 +0000 +++ evolution-3.12.11/calendar/gui/e-week-view-layout.c 2014-03-24 09:25:23.000000000 +0000 @@ -351,7 +351,7 @@ g_return_if_fail (day < 7); - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); if (g_settings_get_boolean (settings, "work-day-monday")) work_days[0] = 1, n_work_days_mon_wed++; diff -Nru evolution-3.16.0/calendar/gui/gnome-cal.c evolution-3.12.11/calendar/gui/gnome-cal.c --- evolution-3.16.0/calendar/gui/gnome-cal.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/gnome-cal.c 2014-06-05 09:52:08.000000000 +0000 @@ -0,0 +1,2464 @@ +/* + * Evolution calendar - Main calendar view widget + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * Miguel de Icaza + * Federico Mena-Quintero + * Seth Alves + * Rodrigo Moya + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "gnome-cal.h" + +#include +#include +#include +#include + +#include +#include + +#include "shell/e-shell.h" + +#include "dialogs/delete-error.h" +#include "dialogs/event-editor.h" + +#include "calendar-config.h" +#include "calendar-view.h" +#include "comp-util.h" +#include "e-cal-list-view.h" +#include "e-cal-model-calendar.h" +#include "e-day-view-time-item.h" +#include "e-day-view.h" +#include "e-memo-table.h" +#include "e-month-view.h" +#include "e-task-table.h" +#include "e-week-view.h" +#include "ea-calendar.h" +#include "misc.h" +#include "tag-calendar.h" + +#define d(x) + +#define GNOME_CALENDAR_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), GNOME_TYPE_CALENDAR, GnomeCalendarPrivate)) + +typedef struct _ViewData ViewData; + +/* Private part of the GnomeCalendar structure */ +struct _GnomeCalendarPrivate { + ESourceRegistry *registry; + ECalModel *model; + + /* + * Fields for the calendar view + */ + + /* This is the last time explicitly selected by the user */ + time_t base_view_time; + + /* Widgets */ + + GtkWidget *hpane; + + ECalendar *date_navigator; + GtkWidget *memo_table; /* EMemoTable, but can be NULL */ + GtkWidget *task_table; /* ETaskTable, but can be NULL */ + + GHashTable *date_nav_view_data; /* set of ViewData */ + GMutex date_nav_view_data_lock; + + gchar *sexp; + guint update_timeout; + guint update_marcus_bains_line_timeout; + + /* This is the view currently shown. We use it to keep track of the + * positions of the panes. range_selected is TRUE if a range of dates + * was selected in the date navigator to show the view. */ + ECalendarView *views[GNOME_CAL_LAST_VIEW]; + GnomeCalendarViewType current_view_type; + + gboolean range_selected; + + /* These are the saved positions of the panes. They are multiples of + * calendar month widths & heights in the date navigator, so that they + * will work OK after theme changes. */ + gint hpane_pos; + gint hpane_pos_month_view; + + /* The signal handler id for our GtkCalendar "day_selected" handler. */ + guint day_selected_id; + + /* The dates currently shown. If they are -1 then we have no dates + * shown. We only use these to check if we need to emit a + * 'dates-shown-changed' signal.*/ + time_t visible_start; + time_t visible_end; + gboolean updating; + + /* If this is true, list view uses range of showing the events + * as the dates selected in date navigator which is one month, + * else it uses the date range set in search bar. */ + gboolean lview_select_daten_range; + + GCancellable *cancellable; + + gulong notify_week_start_day_id; +}; + +struct _ViewData { + volatile gint ref_count; + GWeakRef gcal_weak_ref; + GCancellable *cancellable; + ECalClientView *client_view; + gulong objects_added_handler_id; + gulong objects_modified_handler_id; + gulong objects_removed_handler_id; + gulong complete_handler_id; +}; + +enum { + PROP_0, + PROP_DATE_NAVIGATOR, + PROP_MEMO_TABLE, + PROP_REGISTRY, + PROP_TASK_TABLE, + PROP_VIEW +}; + +enum { + DATES_SHOWN_CHANGED, + CALENDAR_SELECTION_CHANGED, + GOTO_DATE, + SOURCE_ADDED, + SOURCE_REMOVED, + CHANGE_VIEW, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL]; + +static void gnome_calendar_do_dispose (GObject *object); +static void gnome_calendar_finalize (GObject *object); +static void gnome_calendar_goto_date (GnomeCalendar *gcal, + GnomeCalendarGotoDateType goto_date); + +static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal); + +static void update_task_and_memo_views (GnomeCalendar *gcal); + +G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, G_TYPE_OBJECT) + +static ViewData * +view_data_new (GnomeCalendar *gcal) +{ + ViewData *view_data; + + view_data = g_slice_new0 (ViewData); + view_data->ref_count = 1; + view_data->cancellable = g_cancellable_new (); + + g_weak_ref_set (&view_data->gcal_weak_ref, gcal); + + return view_data; +} + +static ViewData * +view_data_ref (ViewData *view_data) +{ + g_return_val_if_fail (view_data != NULL, NULL); + g_return_val_if_fail (view_data->ref_count > 0, NULL); + + g_atomic_int_inc (&view_data->ref_count); + + return view_data; +} + +static void +view_data_unref (ViewData *view_data) +{ + g_return_if_fail (view_data != NULL); + g_return_if_fail (view_data->ref_count > 0); + + if (g_atomic_int_dec_and_test (&view_data->ref_count)) { + + if (view_data->objects_added_handler_id > 0) + g_signal_handler_disconnect ( + view_data->client_view, + view_data->objects_added_handler_id); + + if (view_data->objects_modified_handler_id > 0) + g_signal_handler_disconnect ( + view_data->client_view, + view_data->objects_modified_handler_id); + + if (view_data->objects_removed_handler_id > 0) + g_signal_handler_disconnect ( + view_data->client_view, + view_data->objects_removed_handler_id); + + if (view_data->complete_handler_id > 0) + g_signal_handler_disconnect ( + view_data->client_view, + view_data->complete_handler_id); + + g_weak_ref_set (&view_data->gcal_weak_ref, NULL); + + g_cancellable_cancel (view_data->cancellable); + + g_clear_object (&view_data->cancellable); + g_clear_object (&view_data->client_view); + + g_slice_free (ViewData, view_data); + } +} + +static void +date_nav_view_data_insert (GnomeCalendar *gcal, + ViewData *view_data) +{ + g_return_if_fail (view_data != NULL); + + g_mutex_lock (&gcal->priv->date_nav_view_data_lock); + + g_hash_table_add ( + gcal->priv->date_nav_view_data, + view_data_ref (view_data)); + + g_mutex_unlock (&gcal->priv->date_nav_view_data_lock); +} + +static void +date_nav_view_data_remove_all (GnomeCalendar *gcal) +{ + g_mutex_lock (&gcal->priv->date_nav_view_data_lock); + + g_hash_table_remove_all (gcal->priv->date_nav_view_data); + + g_mutex_unlock (&gcal->priv->date_nav_view_data_lock); +} + +static void +gcal_update_status_message (GnomeCalendar *gcal, + const gchar *message, + gdouble percent) +{ + ECalModel *model; + + g_return_if_fail (gcal != NULL); + + model = gnome_calendar_get_model (gcal); + g_return_if_fail (model != NULL); + + e_cal_model_update_status_message (model, message, percent); +} + +static void +update_adjustment (GnomeCalendar *gcal, + GtkAdjustment *adjustment, + EWeekView *week_view) +{ + GDate date; + GDate first_day_shown; + ECalModel *model; + gint week_offset; + struct icaltimetype start_tt = icaltime_null_time (); + time_t lower; + guint32 old_first_day_julian, new_first_day_julian; + icaltimezone *timezone; + gdouble value; + + e_week_view_get_first_day_shown (week_view, &first_day_shown); + + /* If we don't have a valid date set yet, just return. */ + if (!g_date_valid (&first_day_shown)) + return; + + value = gtk_adjustment_get_value (adjustment); + + /* Determine the first date shown. */ + date = week_view->base_date; + week_offset = floor (value + 0.5); + g_date_add_days (&date, week_offset * 7); + + /* Convert the old & new first days shown to julian values. */ + old_first_day_julian = g_date_get_julian (&first_day_shown); + new_first_day_julian = g_date_get_julian (&date); + + /* If we are already showing the date, just return. */ + if (old_first_day_julian == new_first_day_julian) + return; + + /* Convert it to a time_t. */ + start_tt.year = g_date_get_year (&date); + start_tt.month = g_date_get_month (&date); + start_tt.day = g_date_get_day (&date); + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + lower = icaltime_as_timet_with_zone (start_tt, timezone); + + e_week_view_set_update_base_date (week_view, FALSE); + gnome_calendar_set_selected_time_range (gcal, lower); + e_week_view_set_update_base_date (week_view, TRUE); +} + +static void +week_view_adjustment_changed_cb (GtkAdjustment *adjustment, + GnomeCalendar *gcal) +{ + ECalendarView *view; + + view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_WEEK_VIEW); + update_adjustment (gcal, adjustment, E_WEEK_VIEW (view)); +} + +static void +month_view_adjustment_changed_cb (GtkAdjustment *adjustment, + GnomeCalendar *gcal) +{ + ECalendarView *view; + + view = gnome_calendar_get_calendar_view (gcal, GNOME_CAL_MONTH_VIEW); + update_adjustment (gcal, adjustment, E_WEEK_VIEW (view)); +} + +static void +view_selection_changed_cb (GnomeCalendar *gcal) +{ + g_signal_emit (gcal, signals[CALENDAR_SELECTION_CHANGED], 0); +} + +static void +view_progress_cb (ECalModel *model, + const gchar *message, + gint percent, + ECalClientSourceType type, + GnomeCalendar *gcal) +{ + gcal_update_status_message (gcal, message, percent); +} + +static void +view_complete_cb (ECalModel *model, + const GError *error, + ECalClientSourceType type, + GnomeCalendar *gcal) +{ + gcal_update_status_message (gcal, NULL, -1); +} + +static void +gnome_calendar_notify_week_start_day_cb (GnomeCalendar *gcal) +{ + time_t start_time; + + start_time = gcal->priv->base_view_time; + gnome_calendar_set_selected_time_range (gcal, start_time); +} + +static void +gnome_calendar_update_time_range (GnomeCalendar *gcal) +{ + time_t start_time; + + start_time = gcal->priv->base_view_time; + gnome_calendar_set_selected_time_range (gcal, start_time); +} + +static void +gnome_calendar_set_registry (GnomeCalendar *gcal, + ESourceRegistry *registry) +{ + g_return_if_fail (E_IS_SOURCE_REGISTRY (registry)); + g_return_if_fail (gcal->priv->registry == NULL); + + gcal->priv->registry = g_object_ref (registry); +} + +static void +gnome_calendar_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DATE_NAVIGATOR: + gnome_calendar_set_date_navigator ( + GNOME_CALENDAR (object), + g_value_get_object (value)); + return; + + case PROP_MEMO_TABLE: + gnome_calendar_set_memo_table ( + GNOME_CALENDAR (object), + g_value_get_object (value)); + return; + + case PROP_REGISTRY: + gnome_calendar_set_registry ( + GNOME_CALENDAR (object), + g_value_get_object (value)); + return; + + case PROP_TASK_TABLE: + gnome_calendar_set_task_table ( + GNOME_CALENDAR (object), + g_value_get_object (value)); + return; + + case PROP_VIEW: + gnome_calendar_set_view ( + GNOME_CALENDAR (object), + g_value_get_int (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +gnome_calendar_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_DATE_NAVIGATOR: + g_value_set_object ( + value, gnome_calendar_get_date_navigator ( + GNOME_CALENDAR (object))); + return; + + case PROP_MEMO_TABLE: + g_value_set_object ( + value, gnome_calendar_get_memo_table ( + GNOME_CALENDAR (object))); + return; + + case PROP_REGISTRY: + g_value_set_object ( + value, gnome_calendar_get_registry ( + GNOME_CALENDAR (object))); + return; + + case PROP_TASK_TABLE: + g_value_set_object ( + value, gnome_calendar_get_task_table ( + GNOME_CALENDAR (object))); + return; + + case PROP_VIEW: + g_value_set_int ( + value, gnome_calendar_get_view ( + GNOME_CALENDAR (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +gnome_calendar_constructed (GObject *object) +{ + GnomeCalendar *gcal = GNOME_CALENDAR (object); + ECalendarView *calendar_view; + ESourceRegistry *registry; + ECalModel *model; + GtkAdjustment *adjustment; + + registry = gnome_calendar_get_registry (gcal); + + /* Create the model for the views. */ + model = e_cal_model_calendar_new (registry); + e_cal_model_set_flags (model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES); + gcal->priv->model = model; + + g_signal_connect ( + model, "cal-view-progress", + G_CALLBACK (view_progress_cb), gcal); + + g_signal_connect ( + model, "cal-view-complete", + G_CALLBACK (view_complete_cb), gcal); + + /* Day View */ + calendar_view = e_day_view_new (model); + e_calendar_view_set_calendar (calendar_view, gcal); + gcal->priv->views[GNOME_CAL_DAY_VIEW] = calendar_view; + g_object_ref_sink (calendar_view); + + g_signal_connect_swapped ( + calendar_view, "selection-changed", + G_CALLBACK (view_selection_changed_cb), gcal); + + /* Work Week View */ + calendar_view = e_day_view_new (model); + e_day_view_set_work_week_view (E_DAY_VIEW (calendar_view), TRUE); + e_day_view_set_days_shown (E_DAY_VIEW (calendar_view), 5); + e_calendar_view_set_calendar (calendar_view, gcal); + gcal->priv->views[GNOME_CAL_WORK_WEEK_VIEW] = calendar_view; + g_object_ref_sink (calendar_view); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-monday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-tuesday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-wednesday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-thursday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-friday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-saturday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + e_signal_connect_notify_swapped ( + calendar_view, "notify::working-day-sunday", + G_CALLBACK (gnome_calendar_update_time_range), gcal); + + /* Week View */ + calendar_view = e_week_view_new (model); + e_calendar_view_set_calendar (calendar_view, gcal); + gcal->priv->views[GNOME_CAL_WEEK_VIEW] = calendar_view; + g_object_ref_sink (calendar_view); + + g_signal_connect_swapped ( + calendar_view, "selection-changed", + G_CALLBACK (view_selection_changed_cb), gcal); + + adjustment = gtk_range_get_adjustment ( + GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar)); + g_signal_connect ( + adjustment, "value-changed", + G_CALLBACK (week_view_adjustment_changed_cb), gcal); + + /* Month View */ + calendar_view = e_month_view_new (model); + e_week_view_set_multi_week_view (E_WEEK_VIEW (calendar_view), TRUE); + e_week_view_set_weeks_shown (E_WEEK_VIEW (calendar_view), 6); + e_calendar_view_set_calendar (calendar_view, gcal); + gcal->priv->views[GNOME_CAL_MONTH_VIEW] = calendar_view; + g_object_ref_sink (calendar_view); + + g_signal_connect_swapped ( + calendar_view, "selection-changed", + G_CALLBACK (view_selection_changed_cb), gcal); + + adjustment = gtk_range_get_adjustment ( + GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar)); + g_signal_connect ( + adjustment, "value-changed", + G_CALLBACK (month_view_adjustment_changed_cb), gcal); + + /* List View */ + calendar_view = e_cal_list_view_new (model); + e_calendar_view_set_calendar (calendar_view, gcal); + gcal->priv->views[GNOME_CAL_LIST_VIEW] = calendar_view; + g_object_ref_sink (calendar_view); + + g_signal_connect_swapped ( + calendar_view, "selection-changed", + G_CALLBACK (view_selection_changed_cb), gcal); + + gcal->priv->notify_week_start_day_id = e_signal_connect_notify_swapped ( + model, "notify::week-start-day", + G_CALLBACK (gnome_calendar_notify_week_start_day_cb), gcal); + + gnome_calendar_goto_today (gcal); + + /* Chain up to parent's constructed() method. */ + G_OBJECT_CLASS (gnome_calendar_parent_class)->constructed (object); +} + +/* Class initialization function for the gnome calendar */ +static void +gnome_calendar_class_init (GnomeCalendarClass *class) +{ + GObjectClass *object_class; + GtkBindingSet *binding_set; + + g_type_class_add_private (class, sizeof (GnomeCalendarPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = gnome_calendar_set_property; + object_class->get_property = gnome_calendar_get_property; + object_class->constructed = gnome_calendar_constructed; + object_class->dispose = gnome_calendar_do_dispose; + object_class->finalize = gnome_calendar_finalize; + + class->dates_shown_changed = NULL; + class->calendar_selection_changed = NULL; + class->source_added = NULL; + class->source_removed = NULL; + class->goto_date = gnome_calendar_goto_date; + class->change_view = gnome_calendar_set_view; + + g_object_class_install_property ( + object_class, + PROP_DATE_NAVIGATOR, + g_param_spec_object ( + "date-navigator", + "Date Navigator", + NULL, + E_TYPE_CALENDAR, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_MEMO_TABLE, + g_param_spec_object ( + "memo-table", + "Memo table", + NULL, + E_TYPE_MEMO_TABLE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_REGISTRY, + g_param_spec_object ( + "registry", + "Registry", + "Data source registry", + E_TYPE_SOURCE_REGISTRY, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS)); + + g_object_class_install_property ( + object_class, + PROP_TASK_TABLE, + g_param_spec_object ( + "task-table", + "Task table", + NULL, + E_TYPE_TASK_TABLE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_VIEW, + g_param_spec_int ( + "view", + "View", + NULL, + GNOME_CAL_DAY_VIEW, + GNOME_CAL_LIST_VIEW, + GNOME_CAL_DAY_VIEW, + G_PARAM_READWRITE)); + + signals[DATES_SHOWN_CHANGED] = g_signal_new ( + "dates_shown_changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GnomeCalendarClass, dates_shown_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[CALENDAR_SELECTION_CHANGED] = g_signal_new ( + "calendar_selection_changed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GnomeCalendarClass, calendar_selection_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + signals[SOURCE_ADDED] = g_signal_new ( + "source_added", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GnomeCalendarClass, source_added), + NULL, NULL, + e_marshal_VOID__INT_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_INT, + G_TYPE_OBJECT); + + signals[SOURCE_REMOVED] = g_signal_new ( + "source_removed", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GnomeCalendarClass, source_removed), + NULL, NULL, + e_marshal_VOID__INT_OBJECT, + G_TYPE_NONE, 2, + G_TYPE_INT, + G_TYPE_OBJECT); + + signals[GOTO_DATE] = g_signal_new ( + "goto_date", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GnomeCalendarClass, goto_date), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); + + signals[CHANGE_VIEW] = g_signal_new ( + "change_view", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (GnomeCalendarClass, change_view), + NULL, NULL, + g_cclosure_marshal_VOID__INT, + G_TYPE_NONE, 1, + G_TYPE_INT); + + /* + * Key bindings + */ + + binding_set = gtk_binding_set_new (G_OBJECT_CLASS_NAME (class)); + + /* Alt+PageUp/PageDown, go to the first/last day of the month */ + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_Page_Up, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_KP_Page_Up, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_Page_Down, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_LAST_DAY_OF_MONTH); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_KP_Page_Down, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_LAST_DAY_OF_MONTH); + + /* Alt+Home/End, go to the first/last day of the week */ + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_Home, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_End, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_LAST_DAY_OF_WEEK); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_KP_Home, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_KP_End, + GDK_MOD1_MASK, + "goto_date", 1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_LAST_DAY_OF_WEEK); + + /*Alt+Left/Right, go to the same day of the previous/next week*/ + gtk_binding_entry_add_signal ( + binding_set,GDK_KEY_Left, + GDK_MOD1_MASK, + "goto_date",1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK); + gtk_binding_entry_add_signal ( + binding_set,GDK_KEY_KP_Left, + GDK_MOD1_MASK, + "goto_date",1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK); + gtk_binding_entry_add_signal ( + binding_set,GDK_KEY_Right, + GDK_MOD1_MASK, + "goto_date",1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK); + gtk_binding_entry_add_signal ( + binding_set,GDK_KEY_KP_Right, + GDK_MOD1_MASK, + "goto_date",1, + G_TYPE_ENUM, + GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK); + + /* Ctrl+Y/J/K/M/L to switch between + * DayView/WorkWeekView/WeekView/MonthView/ListView */ + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_y, + GDK_CONTROL_MASK, + "change_view", 1, + G_TYPE_ENUM, + GNOME_CAL_DAY_VIEW); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_j, + GDK_CONTROL_MASK, + "change_view", 1, + G_TYPE_ENUM, + GNOME_CAL_WORK_WEEK_VIEW); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_k, + GDK_CONTROL_MASK, + "change_view", 1, + G_TYPE_ENUM, + GNOME_CAL_WEEK_VIEW); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_m, + GDK_CONTROL_MASK, + "change_view", 1, + G_TYPE_ENUM, + GNOME_CAL_MONTH_VIEW); + gtk_binding_entry_add_signal ( + binding_set, GDK_KEY_l, + GDK_CONTROL_MASK, + "change_view", 1, + G_TYPE_ENUM, + GNOME_CAL_LIST_VIEW); + + /* init the accessibility support for gnome_calendar */ + gnome_calendar_a11y_init (); + +} + +/* We do this check since the calendar items are downloaded from the server + * in the open_method, since the default timezone might not be set there. */ +static void +ensure_dates_are_in_default_zone (GnomeCalendar *gcal, + icalcomponent *icalcomp) +{ + ECalModel *model; + icaltimezone *timezone; + icaltimetype dt; + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + + if (timezone == NULL) + return; + + dt = icalcomponent_get_dtstart (icalcomp); + if (dt.is_utc) { + dt = icaltime_convert_to_zone (dt, timezone); + icalcomponent_set_dtstart (icalcomp, dt); + } + + dt = icalcomponent_get_dtend (icalcomp); + if (dt.is_utc) { + dt = icaltime_convert_to_zone (dt, timezone); + icalcomponent_set_dtend (icalcomp, dt); + } +} + +/* Callback used when the calendar query reports of an updated object */ +static void +gnome_cal_objects_added_cb (ECalClientView *view, + const GSList *list, + GWeakRef *weak_ref) +{ + GnomeCalendar *gcal; + + gcal = g_weak_ref_get (weak_ref); + + if (gcal != NULL) { + const GSList *link; + + for (link = list; link != NULL; link = g_slist_next (link)) { + ECalComponent *comp = NULL; + icalcomponent *icalcomp = link->data; + + ensure_dates_are_in_default_zone (gcal, icalcomp); + comp = e_cal_component_new (); + if (!e_cal_component_set_icalcomponent ( + comp, icalcomponent_new_clone (icalcomp))) { + g_object_unref (comp); + continue; + } + + tag_calendar_by_comp ( + gcal->priv->date_navigator, comp, + e_cal_client_view_get_client (view), + NULL, FALSE, TRUE, TRUE, + gcal->priv->cancellable); + g_object_unref (comp); + } + + g_object_unref (gcal); + } +} + +static void +gnome_cal_objects_modified_cb (ECalClientView *view, + const GSList *objects, + GWeakRef *weak_ref) +{ + GnomeCalendar *gcal; + + gcal = g_weak_ref_get (weak_ref); + + if (gcal != NULL) { + /* We have to retag the whole thing: an event may change dates + * and the tag_calendar_by_comp() below would not know how to + * untag the old dates. */ + gnome_calendar_update_query (gcal); + g_object_unref (gcal); + } +} + +/* Callback used when the calendar query reports of a removed object */ +static void +gnome_cal_objects_removed_cb (ECalClientView *view, + const GSList *ids, + GWeakRef *weak_ref) +{ + GnomeCalendar *gcal; + + gcal = g_weak_ref_get (weak_ref); + + if (gcal != NULL) { + /* Just retag the whole thing */ + gnome_calendar_update_query (gcal); + g_object_unref (gcal); + } +} + +/* Callback used when the calendar query is done */ +static void +gnome_cal_view_complete_cb (ECalClientView *query, + const GError *error, + GWeakRef *weak_ref) +{ + /* FIXME Better error reporting */ + if (error != NULL) + g_warning ( + "%s: Query did not complete successfully: %s", + G_STRFUNC, error->message); +} + +ECalendarView * +gnome_calendar_get_calendar_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + g_return_val_if_fail (view_type < GNOME_CAL_LAST_VIEW, NULL); + + return gcal->priv->views[view_type]; +} + +static void +get_times_for_views (GnomeCalendar *gcal, + GnomeCalendarViewType view_type, + time_t *start_time, + time_t *end_time, + time_t *select_time) +{ + GnomeCalendarPrivate *priv; + ECalModel *model; + EDayView *day_view; + EWeekView *week_view; + gint shown; + GDate date; + gint days_shown; + GDateWeekday week_start_day; + GDateWeekday first_work_day; + GDateWeekday last_work_day; + GDateWeekday start_day; + GDateWeekday weekday; + guint offset; + struct icaltimetype tt = icaltime_null_time (); + icaltimezone *timezone; + gboolean range_selected; + + model = gnome_calendar_get_model (gcal); + range_selected = gnome_calendar_get_range_selected (gcal); + + timezone = e_cal_model_get_timezone (model); + week_start_day = e_cal_model_get_week_start_day (model); + + priv = gcal->priv; + + switch (view_type) { + case GNOME_CAL_DAY_VIEW: + day_view = E_DAY_VIEW (priv->views[view_type]); + shown = e_day_view_get_days_shown (day_view); + *start_time = time_day_begin_with_zone (*start_time, timezone); + *end_time = time_add_day_with_zone (*start_time, shown, timezone); + break; + case GNOME_CAL_WORK_WEEK_VIEW: + /* FIXME Kind of gross, but it works */ + day_view = E_DAY_VIEW (priv->views[view_type]); + time_to_gdate_with_zone (&date, *start_time, timezone); + + /* The start of the work-week is the first working day after the + * week start day. */ + + /* Get the weekday corresponding to start_time. */ + weekday = g_date_get_weekday (&date); + + /* Find the first working day of the week. */ + first_work_day = e_cal_model_get_work_day_first (model); + + if (first_work_day != G_DATE_BAD_WEEKDAY) { + last_work_day = e_cal_model_get_work_day_last (model); + + /* Now calculate the days we need to show to include + * all the working days in the week. Add 1 to make it + * inclusive. */ + days_shown = e_weekday_get_days_between ( + first_work_day, last_work_day) + 1; + } else { + /* If no working days are set, just use 7. */ + days_shown = 7; + } + + if (first_work_day == G_DATE_BAD_WEEKDAY) + first_work_day = week_start_day; + + /* Calculate how many days we need to go back to the first workday. */ + if (weekday < first_work_day) + offset = (weekday + 7) - first_work_day; + else + offset = weekday - first_work_day; + + if (offset > 0) + g_date_subtract_days (&date, offset); + + tt.year = g_date_get_year (&date); + tt.month = g_date_get_month (&date); + tt.day = g_date_get_day (&date); + + *start_time = icaltime_as_timet_with_zone (tt, timezone); + *end_time = time_add_day_with_zone (*start_time, days_shown, timezone); + + if (select_time && day_view->selection_start_day == -1) + time (select_time); + break; + case GNOME_CAL_WEEK_VIEW: + week_view = E_WEEK_VIEW (priv->views[view_type]); + start_day = e_week_view_get_display_start_day (week_view); + + *start_time = time_week_begin_with_zone ( + *start_time, + e_weekday_to_tm_wday (start_day), + timezone); + *end_time = time_add_week_with_zone ( + *start_time, 1, timezone); + + if (select_time && week_view->selection_start_day == -1) + time (select_time); + break; + case GNOME_CAL_MONTH_VIEW: + week_view = E_WEEK_VIEW (priv->views[view_type]); + shown = e_week_view_get_weeks_shown (week_view); + start_day = e_week_view_get_display_start_day (week_view); + + if (!range_selected && ( + !e_week_view_get_multi_week_view (week_view) || + !week_view->month_scroll_by_week)) + *start_time = time_month_begin_with_zone ( + *start_time, timezone); + + *start_time = time_week_begin_with_zone ( + *start_time, + e_weekday_to_tm_wday (start_day), + timezone); + *end_time = time_add_week_with_zone ( + *start_time, shown, timezone); + + if (select_time && week_view->selection_start_day == -1) + time (select_time); + break; + case GNOME_CAL_LIST_VIEW: + /* FIXME What to do here? */ + *start_time = time_month_begin_with_zone (*start_time, timezone); + *end_time = time_add_month_with_zone (*start_time, 1, timezone); + break; + default: + g_return_if_reached (); + } +} + +/* Computes the range of time that the date navigator is showing */ +static void +get_date_navigator_range (GnomeCalendar *gcal, + time_t *start_time, + time_t *end_time) +{ + ECalModel *model; + gint start_year, start_month, start_day; + gint end_year, end_month, end_day; + struct icaltimetype start_tt; + struct icaltimetype end_tt; + icaltimezone *timezone; + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + + start_tt = icaltime_null_time (); + end_tt = icaltime_null_time (); + + if (!e_calendar_item_get_date_range ( + gcal->priv->date_navigator->calitem, + &start_year, &start_month, &start_day, + &end_year, &end_month, &end_day)) { + *start_time = -1; + *end_time = -1; + return; + } + + start_tt.year = start_year; + start_tt.month = start_month + 1; + start_tt.day = start_day; + + end_tt.year = end_year; + end_tt.month = end_month + 1; + end_tt.day = end_day; + + icaltime_adjust (&end_tt, 1, 0, 0, 0); + + *start_time = icaltime_as_timet_with_zone (start_tt, timezone); + *end_time = icaltime_as_timet_with_zone (end_tt, timezone); +} + +static const gchar * +gcal_get_default_tzloc (GnomeCalendar *gcal) +{ + ECalModel *model; + icaltimezone *timezone; + const gchar *tzloc = NULL; + + g_return_val_if_fail (gcal != NULL, ""); + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + + if (timezone && timezone != icaltimezone_get_utc_timezone ()) + tzloc = icaltimezone_get_location (timezone); + + return tzloc ? tzloc : ""; +} + +/* Adjusts a given query sexp with the time range of the date navigator */ +static gchar * +adjust_client_view_sexp (GnomeCalendar *gcal, + const gchar *sexp) +{ + time_t start_time, end_time; + gchar *start, *end; + gchar *new_sexp; + + get_date_navigator_range (gcal, &start_time, &end_time); + if (start_time == -1 || end_time == -1) + return NULL; + + start = isodate_from_time_t (start_time); + end = isodate_from_time_t (end_time); + + if (sexp) { + new_sexp = g_strdup_printf ( + "(and (occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\") %s)", + start, end, gcal_get_default_tzloc (gcal), sexp); + } else { + new_sexp = g_strdup_printf ( + "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\")", + start, end, gcal_get_default_tzloc (gcal)); + } + + g_free (start); + g_free (end); + + return new_sexp; +} + +static void +gnome_cal_get_client_view_cb (GObject *source_object, + GAsyncResult *result, + gpointer user_data) +{ + ECalClient *client; + ECalClientView *client_view = NULL; + GnomeCalendar *gcal; + ViewData *view_data; + GError *local_error = NULL; + + client = E_CAL_CLIENT (source_object); + view_data = (ViewData *) user_data; + + e_cal_client_get_view_finish ( + client, result, &client_view, &local_error); + + /* Sanity check. */ + g_return_if_fail ( + ((client_view != NULL) && (local_error == NULL)) || + ((client_view == NULL) && (local_error != NULL))); + + gcal = g_weak_ref_get (&view_data->gcal_weak_ref); + + if (g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { + g_error_free (local_error); + + } else if (local_error != NULL) { + /* FIXME This should be displayed as an EAlert. */ + g_warning ("%s: %s", G_STRFUNC, local_error->message); + g_error_free (local_error); + + } else if (gcal != NULL) { + gulong handler_id; + + /* The ViewData struct is only modified from a single + * thread, so no locking is necessary when populating + * the struct members. */ + + view_data->client_view = g_object_ref (client_view); + + handler_id = g_signal_connect_data ( + client_view, "objects-added", + G_CALLBACK (gnome_cal_objects_added_cb), + e_weak_ref_new (gcal), + (GClosureNotify) e_weak_ref_free, 0); + view_data->objects_added_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + client_view, "objects-modified", + G_CALLBACK (gnome_cal_objects_modified_cb), + e_weak_ref_new (gcal), + (GClosureNotify) e_weak_ref_free, 0); + view_data->objects_modified_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + client_view, "objects-removed", + G_CALLBACK (gnome_cal_objects_removed_cb), + e_weak_ref_new (gcal), + (GClosureNotify) e_weak_ref_free, 0); + view_data->objects_removed_handler_id = handler_id; + + handler_id = g_signal_connect_data ( + client_view, "complete", + G_CALLBACK (gnome_cal_view_complete_cb), + e_weak_ref_new (gcal), + (GClosureNotify) e_weak_ref_free, 0); + view_data->complete_handler_id = handler_id; + + /* XXX This call blocks with no way to cancel. But the + * ECalClientView API does not provide a proper way. */ + e_cal_client_view_start (client_view, &local_error); + + if (local_error != NULL) { + g_warning ("%s: %s", G_STRFUNC, local_error->message); + g_error_free (local_error); + } + } + + g_clear_object (&gcal); + g_clear_object (&client_view); + + view_data_unref (view_data); +} + +/* Restarts a query for the date navigator in the calendar */ +void +gnome_calendar_update_query (GnomeCalendar *gcal) +{ + GList *list, *link; + gchar *real_sexp; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem); + + /* This cancels any previous view requests still in progress. */ + date_nav_view_data_remove_all (gcal); + + g_return_if_fail (gcal->priv->sexp != NULL); + + /* Don't start a query unless a time range is set. */ + real_sexp = adjust_client_view_sexp (gcal, gcal->priv->sexp); + if (real_sexp == NULL) + return; + + list = e_cal_model_list_clients (gcal->priv->model); + + /* create queries for each loaded client */ + for (link = list; link != NULL; link = g_list_next (link)) { + ECalClient *client = E_CAL_CLIENT (link->data); + ViewData *view_data; + + view_data = view_data_new (gcal); + date_nav_view_data_insert (gcal, view_data); + + e_cal_client_get_view ( + client, real_sexp, + view_data->cancellable, + gnome_cal_get_client_view_cb, + view_data_ref (view_data)); + + view_data_unref (view_data); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + g_free (real_sexp); + + update_task_and_memo_views (gcal); +} + +void +gnome_calendar_set_search_query (GnomeCalendar *gcal, + const gchar *sexp, + gboolean range_search, + time_t start_range, + time_t end_range) +{ + GnomeCalendarPrivate *priv; + ECalModel *model; + gint i; + time_t start, end; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (sexp != NULL); + + priv = gcal->priv; + + model = gnome_calendar_get_model (gcal); + + /* Set the query on the date navigator */ + + g_free (priv->sexp); + priv->sexp = g_strdup (sexp); + + priv->lview_select_daten_range = !range_search; + start = start_range; + end = end_range; + + d (g_print ("Changing the queries %s \n", sexp)); + + gnome_calendar_update_query (gcal); + + i = priv->current_view_type; + + /* Set the query on the views */ + if (i == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range) { + start = priv->base_view_time; + get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end, NULL); + + e_cal_model_set_search_query_with_time_range ( + model, sexp, start, end); + + if (priv->current_view_type == GNOME_CAL_LIST_VIEW) + gnome_calendar_update_date_navigator (gcal); + } else + e_cal_model_set_search_query (model, sexp); +} + +static void +update_task_and_memo_views (GnomeCalendar *gcal) +{ + if (gcal->priv->task_table != NULL) { + ECalModel *task_model; + ETaskTable *task_table; + gchar *hide_completed_tasks_sexp; + + /* Set the query on the task pad. */ + + task_table = E_TASK_TABLE (gcal->priv->task_table); + task_model = e_task_table_get_model (task_table); + + hide_completed_tasks_sexp = + calendar_config_get_hide_completed_tasks_sexp (FALSE); + + if (hide_completed_tasks_sexp != NULL) { + if (gcal->priv->sexp != NULL) { + gchar *search_query; + + search_query = g_strdup_printf ( + "(and %s %s)", + hide_completed_tasks_sexp, + gcal->priv->sexp); + e_cal_model_set_search_query ( + task_model, search_query); + g_free (search_query); + } else { + e_cal_model_set_search_query ( + task_model, hide_completed_tasks_sexp); + } + } else { + e_cal_model_set_search_query ( + task_model, gcal->priv->sexp); + } + + g_free (hide_completed_tasks_sexp); + } + + if (gcal->priv->memo_table != NULL) { + ECalModel *memo_model; + ECalModel *view_model; + EMemoTable *memo_table; + time_t start = -1, end = -1; + + /* Set the query on the memo pad. */ + + memo_table = E_MEMO_TABLE (gcal->priv->memo_table); + memo_model = e_memo_table_get_model (memo_table); + + view_model = gnome_calendar_get_model (gcal); + e_cal_model_get_time_range (view_model, &start, &end); + + if (start != -1 && end != -1) { + gchar *search_query; + gchar *iso_start; + gchar *iso_end; + + iso_start = isodate_from_time_t (start); + iso_end = isodate_from_time_t (end); + + search_query = g_strdup_printf ( + "(and (or (not (has-start?)) " + "(occur-in-time-range? (make-time \"%s\") " + "(make-time \"%s\") \"%s\")) %s)", + iso_start, iso_end, + gcal_get_default_tzloc (gcal), + gcal->priv->sexp ? gcal->priv->sexp : ""); + + e_cal_model_set_search_query ( + memo_model, search_query); + + g_free (search_query); + g_free (iso_start); + g_free (iso_end); + } + } +} + +static gboolean +update_marcus_bains_line_cb (gpointer user_data) +{ + GnomeCalendar *gcal; + GnomeCalendarViewType view_type; + ECalendarView *view; + time_t now, day_begin; + + gcal = GNOME_CALENDAR (user_data); + view_type = gnome_calendar_get_view (gcal); + view = gnome_calendar_get_calendar_view (gcal, view_type); + + if (E_IS_DAY_VIEW (view)) + e_day_view_marcus_bains_update (E_DAY_VIEW (view)); + + time (&now); + day_begin = time_day_begin (now); + + /* check in the first two minutes */ + if (now >= day_begin && now <= day_begin + 120) { + time_t start_time = 0, end_time = 0; + + g_return_val_if_fail (view != NULL, TRUE); + + e_calendar_view_get_selected_time_range (view, &start_time, &end_time); + + if (end_time >= time_add_day (day_begin, -1) && start_time <= day_begin) { + gnome_calendar_goto (gcal, now); + } + } + + return TRUE; +} + +static void +setup_widgets (GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + + priv = gcal->priv; + + /* update_task_and_memo_views (gcal); */ + + /* Timeout check to hide completed items */ +#if 0 /* KILL-BONOBO */ + priv->update_timeout = g_timeout_add_full ( + G_PRIORITY_LOW, 60000, (GSourceFunc) + update_task_and_memo_views_cb, gcal, NULL); +#endif + + /* The Marcus Bains line */ + priv->update_marcus_bains_line_timeout = + e_named_timeout_add_seconds_full ( + G_PRIORITY_LOW, 60, + update_marcus_bains_line_cb, gcal, NULL); + + /* update_memo_view (gcal); */ +} + +/* Object initialization function for the gnome calendar */ +static void +gnome_calendar_init (GnomeCalendar *gcal) +{ + GHashTable *date_nav_view_data; + + date_nav_view_data = g_hash_table_new_full ( + (GHashFunc) g_direct_hash, + (GEqualFunc) g_direct_equal, + (GDestroyNotify) view_data_unref, + (GDestroyNotify) NULL); + + gcal->priv = GNOME_CALENDAR_GET_PRIVATE (gcal); + + g_mutex_init (&gcal->priv->date_nav_view_data_lock); + + gcal->priv->current_view_type = GNOME_CAL_WORK_WEEK_VIEW; + gcal->priv->range_selected = FALSE; + gcal->priv->lview_select_daten_range = TRUE; + + setup_widgets (gcal); + + gcal->priv->date_nav_view_data = date_nav_view_data; + + gcal->priv->sexp = g_strdup ("#t"); /* Match all */ + + gcal->priv->visible_start = -1; + gcal->priv->visible_end = -1; + gcal->priv->updating = FALSE; + + gcal->priv->cancellable = g_cancellable_new (); +} + +static void +gnome_calendar_do_dispose (GObject *object) +{ + GnomeCalendarPrivate *priv; + gint ii; + + priv = GNOME_CALENDAR_GET_PRIVATE (object); + + if (priv->registry != NULL) { + g_object_unref (priv->registry); + priv->registry = NULL; + } + + if (priv->model != NULL) { + g_signal_handlers_disconnect_by_data (priv->model, object); + e_signal_disconnect_notify_handler (priv->model, &priv->notify_week_start_day_id); + g_object_unref (priv->model); + priv->model = NULL; + } + + for (ii = 0; ii < GNOME_CAL_LAST_VIEW; ii++) { + if (priv->views[ii] != NULL) { + g_object_unref (priv->views[ii]); + priv->views[ii] = NULL; + } + } + + g_hash_table_remove_all (priv->date_nav_view_data); + + if (priv->sexp) { + g_free (priv->sexp); + priv->sexp = NULL; + } + + if (priv->update_timeout) { + g_source_remove (priv->update_timeout); + priv->update_timeout = 0; + } + + if (priv->update_marcus_bains_line_timeout) { + g_source_remove (priv->update_marcus_bains_line_timeout); + priv->update_marcus_bains_line_timeout = 0; + } + + if (priv->cancellable) { + g_cancellable_cancel (priv->cancellable); + g_object_unref (priv->cancellable); + priv->cancellable = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (gnome_calendar_parent_class)->dispose (object); +} + +static void +gnome_calendar_finalize (GObject *object) +{ + GnomeCalendarPrivate *priv; + + priv = GNOME_CALENDAR_GET_PRIVATE (object); + + g_mutex_clear (&priv->date_nav_view_data_lock); + + g_hash_table_destroy (priv->date_nav_view_data); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (gnome_calendar_parent_class)->finalize (object); +} + +static void +notify_selected_time_changed (GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + gint i; + + priv = gcal->priv; + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) { + g_signal_emit_by_name (priv->views[i], "selected_time_changed"); + } +} + +static void +gnome_calendar_goto_date (GnomeCalendar *gcal, + GnomeCalendarGotoDateType goto_date) +{ + ECalModel *model; + time_t new_time = 0; + GDateWeekday week_start_day; + gboolean need_updating = FALSE; + icaltimezone *timezone; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + model = gnome_calendar_get_model (gcal); + week_start_day = e_cal_model_get_week_start_day (model); + timezone = e_cal_model_get_timezone (model); + + switch (goto_date) { + /* GNOME_CAL_GOTO_TODAY and GNOME_CAL_GOTO_DATE are + * currently not used + */ + case GNOME_CAL_GOTO_TODAY: + break; + case GNOME_CAL_GOTO_DATE: + break; + case GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH: + new_time = time_month_begin_with_zone ( + gcal->priv->base_view_time, timezone); + need_updating = TRUE; + break; + case GNOME_CAL_GOTO_LAST_DAY_OF_MONTH: + new_time = time_add_month_with_zone ( + gcal->priv->base_view_time, 1, timezone); + new_time = time_month_begin_with_zone (new_time, timezone); + new_time = time_add_day_with_zone (new_time, -1, timezone); + need_updating = TRUE; + break; + case GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK: + new_time = time_week_begin_with_zone ( + gcal->priv->base_view_time, + e_weekday_to_tm_wday (week_start_day), + timezone); + need_updating = TRUE; + break; + case GNOME_CAL_GOTO_LAST_DAY_OF_WEEK: + new_time = time_week_begin_with_zone ( + gcal->priv->base_view_time, + e_weekday_to_tm_wday (week_start_day), + timezone); + if (gcal->priv->current_view_type == GNOME_CAL_DAY_VIEW || + gcal->priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) { + /* FIXME Shouldn't hard code work week end */ + /* goto Friday of this week */ + new_time = time_add_day_with_zone (new_time, 4, timezone); + } else { + /* goto Sunday of this week */ + /* FIXME Shouldn't hard code week end */ + new_time = time_add_day_with_zone (new_time, 6, timezone); + } + need_updating = TRUE; + break; + case GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK: + new_time = time_add_week_with_zone ( + gcal->priv->base_view_time, -1, timezone); + need_updating = TRUE; + break; + case GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK: + new_time = time_add_week_with_zone ( + gcal->priv->base_view_time, 1, timezone); + need_updating = TRUE; + break; + default: + break; + } + + if (need_updating) { + gnome_calendar_set_selected_time_range (gcal, new_time); + notify_selected_time_changed (gcal); + } +} + +void +gnome_calendar_goto (GnomeCalendar *gcal, + time_t new_time) +{ + GnomeCalendarPrivate *priv; + gint i; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (new_time != -1); + + priv = gcal->priv; + + gnome_calendar_set_selected_time_range (gcal, new_time); + + for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) + e_calendar_view_set_selected_time_range ( + priv->views[i], new_time, new_time); +} + +void +gnome_calendar_update_view_times (GnomeCalendar *gcal, + time_t start_time) +{ + GnomeCalendarPrivate *priv; + ECalModel *model; + time_t real_start_time = start_time; + time_t end_time, select_time = 0; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + priv = gcal->priv; + + priv->base_view_time = start_time; + + model = gnome_calendar_get_model (gcal); + + get_times_for_views ( + gcal, priv->current_view_type, + &real_start_time, &end_time, &select_time); + + if (priv->current_view_type == GNOME_CAL_LIST_VIEW && + !priv->lview_select_daten_range) + return; + + e_cal_model_set_time_range (model, real_start_time, end_time); + + if (select_time != 0 && select_time >= real_start_time && select_time <= end_time) + e_calendar_view_set_selected_time_range ( + priv->views[priv->current_view_type], + select_time, select_time); +} + +static void +gnome_calendar_direction (GnomeCalendar *gcal, + gint direction) +{ + ECalModel *model; + icaltimezone *timezone; + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + + switch (gnome_calendar_get_view (gcal)) { + case GNOME_CAL_DAY_VIEW: + gcal->priv->base_view_time = time_add_day_with_zone ( + gcal->priv->base_view_time, direction, timezone); + break; + case GNOME_CAL_WORK_WEEK_VIEW: + case GNOME_CAL_WEEK_VIEW: + gcal->priv->base_view_time = time_add_week_with_zone ( + gcal->priv->base_view_time, direction, timezone); + break; + case GNOME_CAL_MONTH_VIEW: + case GNOME_CAL_LIST_VIEW: + gcal->priv->base_view_time = time_add_month_with_zone ( + gcal->priv->base_view_time, direction, timezone); + break; + default: + g_return_if_reached (); + } + + gnome_calendar_set_selected_time_range ( + gcal, gcal->priv->base_view_time); +} + +void +gnome_calendar_next (GnomeCalendar *gcal) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + gnome_calendar_direction (gcal, 1); +} + +void +gnome_calendar_previous (GnomeCalendar *gcal) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + gnome_calendar_direction (gcal, -1); +} + +void +gnome_calendar_dayjump (GnomeCalendar *gcal, + time_t time) +{ + ECalModel *model; + icaltimezone *timezone; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + + gcal->priv->base_view_time = + time_day_begin_with_zone (time, timezone); + + gnome_calendar_update_view_times (gcal, gcal->priv->base_view_time); + gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW); +} + +void +gnome_calendar_goto_today (GnomeCalendar *gcal) +{ + GnomeCalendarViewType view_type; + ECalendarView *view; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + view_type = gnome_calendar_get_view (gcal); + view = gnome_calendar_get_calendar_view (gcal, view_type); + + gnome_calendar_goto (gcal, time (NULL)); + gtk_widget_grab_focus (GTK_WIDGET (view)); +} + +/** + * gnome_calendar_get_view: + * @gcal: A calendar. + * + * Queries the type of the view that is being shown in a calendar. + * + * Return value: Type of the view that is currently shown. + **/ +GnomeCalendarViewType +gnome_calendar_get_view (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), GNOME_CAL_DAY_VIEW); + + return gcal->priv->current_view_type; +} + +/** + * gnome_calendar_set_view: + * @gcal: A calendar. + * @view_type: Type of view to show. + * + * Sets the view that should be shown in a calendar. If @reset_range is true, + * this function will automatically set the number of days or weeks shown in + * the view; otherwise the last configuration will be kept. + **/ +void +gnome_calendar_set_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type) +{ + ECalendarView *calendar_view; + gint ii; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + if (gcal->priv->current_view_type == view_type && + E_CALENDAR_VIEW (gcal->priv->views[view_type])->in_focus) + return; + + gcal->priv->current_view_type = view_type; + gnome_calendar_set_range_selected (gcal, FALSE); + + E_CALENDAR_VIEW (gcal->priv->views[view_type])->in_focus = TRUE; + for (ii = 0; ii < GNOME_CAL_LAST_VIEW; ii++) { + if (ii == view_type) + continue; + E_CALENDAR_VIEW (gcal->priv->views[ii])->in_focus = FALSE; + } + + calendar_view = gnome_calendar_get_calendar_view (gcal, view_type); + gtk_widget_grab_focus (GTK_WIDGET (calendar_view)); + + g_object_notify (G_OBJECT (gcal), "view"); +} + +void +gnome_calendar_display_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type) +{ + ECalendarView *view; + gboolean preserve_day; + gboolean range_selected; + time_t start_time; + + view = gnome_calendar_get_calendar_view (gcal, view_type); + + /* Set the view without changing the selection or updating the date + * navigator. If a range of dates isn't selected, also reset the + * number of days/weeks shown to the default (i.e. 1 day for the + * day view or 6 weeks for the month view). */ + + preserve_day = FALSE; + + switch (view_type) { + case GNOME_CAL_DAY_VIEW: + if (!gnome_calendar_get_range_selected (gcal)) + e_day_view_set_days_shown (E_DAY_VIEW (view), 1); + + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + break; + + case GNOME_CAL_WORK_WEEK_VIEW: + preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + break; + + case GNOME_CAL_WEEK_VIEW: + preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + break; + + case GNOME_CAL_MONTH_VIEW: + if (!gnome_calendar_get_range_selected (gcal)) + e_week_view_set_weeks_shown (E_WEEK_VIEW (view), 6); + + preserve_day = TRUE; + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + break; + + case GNOME_CAL_LIST_VIEW: + if (!gcal->priv->lview_select_daten_range) + gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator)); + else + gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator)); + break; + + default: + g_return_if_reached (); + } + + range_selected = gnome_calendar_get_range_selected (gcal); + gnome_calendar_set_view (gcal, view_type); + gnome_calendar_set_range_selected (gcal, range_selected); + + /* For the week & month views we want the selection in the date + * navigator to be rounded to the nearest week when the arrow buttons + * are pressed to move to the previous/next month. */ + g_object_set ( + gcal->priv->date_navigator->calitem, + "preserve_day_when_moving", preserve_day, NULL); + + /* keep week days selected as before for a work week view */ + g_object_set ( + gcal->priv->date_navigator->calitem, + "keep_wdays_on_weeknum_click", + view_type == GNOME_CAL_WORK_WEEK_VIEW, + NULL); + + if (!gcal->priv->base_view_time) + start_time = time (NULL); + else + start_time = gcal->priv->base_view_time; + + gnome_calendar_set_selected_time_range (gcal, start_time); + +} + +GtkWidget * +gnome_calendar_new (ESourceRegistry *registry) +{ + g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL); + + return g_object_new ( + GNOME_TYPE_CALENDAR, + "registry", registry, NULL); +} + +ESourceRegistry * +gnome_calendar_get_registry (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->registry; +} + +ECalendar * +gnome_calendar_get_date_navigator (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->date_navigator; +} + +void +gnome_calendar_set_date_navigator (GnomeCalendar *gcal, + ECalendar *date_navigator) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + if (gcal->priv->date_navigator == date_navigator) + return; + + if (date_navigator != NULL) { + g_return_if_fail (E_IS_CALENDAR (date_navigator)); + g_object_ref (date_navigator); + } + + if (gcal->priv->date_navigator != NULL) + g_object_unref (gcal->priv->date_navigator); + + gcal->priv->date_navigator = date_navigator; + + /* Update the new date navigator */ + gnome_calendar_update_date_navigator (gcal); + + g_object_notify (G_OBJECT (gcal), "date-navigator"); +} + +GtkWidget * +gnome_calendar_get_memo_table (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->memo_table; +} + +void +gnome_calendar_set_memo_table (GnomeCalendar *gcal, + GtkWidget *memo_table) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + if (gcal->priv->memo_table == memo_table) + return; + + if (memo_table != NULL) { + g_return_if_fail (E_IS_MEMO_TABLE (memo_table)); + g_object_ref (memo_table); + } + + if (gcal->priv->memo_table != NULL) + g_object_unref (gcal->priv->memo_table); + + gcal->priv->memo_table = memo_table; + + g_object_notify (G_OBJECT (gcal), "memo-table"); +} + +GtkWidget * +gnome_calendar_get_task_table (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->task_table; +} + +void +gnome_calendar_set_task_table (GnomeCalendar *gcal, + GtkWidget *task_table) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + if (gcal->priv->task_table == task_table) + return; + + if (task_table != NULL) { + g_return_if_fail (E_IS_TASK_TABLE (task_table)); + g_object_ref (task_table); + } + + if (gcal->priv->task_table != NULL) + g_object_unref (gcal->priv->task_table); + + gcal->priv->task_table = task_table; + + g_object_notify (G_OBJECT (gcal), "task-table"); +} + +/** + * gnome_calendar_get_model: + * @gcal: A calendar view. + * + * Queries the calendar model object that a calendar view is using. + * + * Return value: A calendar client interface object. + **/ +ECalModel * +gnome_calendar_get_model (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL); + + return gcal->priv->model; +} + +gboolean +gnome_calendar_get_range_selected (GnomeCalendar *gcal) +{ + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE); + + return gcal->priv->range_selected; +} + +void +gnome_calendar_set_range_selected (GnomeCalendar *gcal, + gboolean range_selected) +{ + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + gcal->priv->range_selected = range_selected; +} + +void +gnome_calendar_set_selected_time_range (GnomeCalendar *gcal, + time_t start_time) +{ + gnome_calendar_update_view_times (gcal, start_time); + gnome_calendar_update_date_navigator (gcal); + gnome_calendar_notify_dates_shown_changed (gcal); +} + +/** + * gnome_calendar_new_task: + * @gcal: An Evolution calendar. + * @dtstart: Start time of the task, in same timezone as model. + * @dtend: End time of the task, in same timezone as model. + * + * Opens a task editor dialog for a new task. dtstart or dtend can be NULL. + **/ +#if 0 /* KILL-BONOBO */ +void +gnome_calendar_new_task (GnomeCalendar *gcal, + time_t *dtstart, + time_t *dtend) +{ + GnomeCalendarPrivate *priv; + ECal *ecal; + ECalModel *model; + CompEditor *editor; + ECalComponent *comp; + icalcomponent *icalcomp; + const gchar *category; + guint32 flags = 0; + ECalComponentDateTime dt; + struct icaltimetype itt; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + priv = gcal->priv; + model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)); + ecal = e_cal_model_get_default_client (model); + if (!ecal) + return; + + flags |= COMP_EDITOR_NEW_ITEM; + editor = task_editor_new (ecal, flags); + + icalcomp = e_cal_model_create_component_with_defaults (model, FALSE); + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomp); + + dt.value = &itt; + dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (model)); + + if (dtstart) { + itt = icaltime_from_timet_with_zone ( + *dtstart, FALSE, e_cal_model_get_timezone (model)); + e_cal_component_set_dtstart (comp, &dt); + } + + if (dtend) { + itt = icaltime_from_timet_with_zone ( + *dtend, FALSE, e_cal_model_get_timezone (model)); + e_cal_component_set_due (comp, &dt); /* task uses 'due' not 'dtend' */ + } + + if (dtstart || dtend) + e_cal_component_commit_sequence (comp); + + comp_editor_edit_comp (editor, comp); + g_object_unref (comp); + + gtk_window_present (GTK_WINDOW (editor)); +} +#endif + +/* Returns the selected time range for the current view. Note that this may be + * different from the fields in the GnomeCalendar, since the view may clip + * this or choose a more appropriate time. */ +void +gnome_calendar_get_current_time_range (GnomeCalendar *gcal, + time_t *start_time, + time_t *end_time) +{ + GnomeCalendarViewType view_type; + ECalendarView *view; + + view_type = gnome_calendar_get_view (gcal); + view = gnome_calendar_get_calendar_view (gcal, view_type); + + e_calendar_view_get_selected_time_range (view, start_time, end_time); +} + +/* This updates the month shown and the days selected in the calendar, if + * necessary. */ +static void +gnome_calendar_update_date_navigator (GnomeCalendar *gcal) +{ + GnomeCalendarPrivate *priv; + ECalModel *model; + time_t start, end; + GDateWeekday week_start_day; + GDate start_date, end_date; + icaltimezone *timezone; + + priv = gcal->priv; + + /* If the ECalendar is not yet set, we just return. */ + if (priv->date_navigator == NULL) + return; + + /* If the ECalendar isn't visible, we just return. */ + if (!gtk_widget_get_visible (GTK_WIDGET (priv->date_navigator))) + return; + + if (priv->current_view_type == GNOME_CAL_LIST_VIEW && + !priv->lview_select_daten_range) + return; + + model = gnome_calendar_get_model (gcal); + timezone = e_cal_model_get_timezone (model); + week_start_day = e_cal_model_get_week_start_day (model); + e_cal_model_get_time_range (model, &start, &end); + + time_to_gdate_with_zone (&start_date, start, timezone); + if (priv->current_view_type == GNOME_CAL_MONTH_VIEW) { + EWeekView *week_view = E_WEEK_VIEW (priv->views[priv->current_view_type]); + + if (week_start_day == G_DATE_MONDAY && + (!e_week_view_get_multi_week_view (week_view) || + e_week_view_get_compress_weekend (week_view))) + g_date_add_days (&start_date, 1); + } + time_to_gdate_with_zone (&end_date, end, timezone); + g_date_subtract_days (&end_date, 1); + + e_calendar_item_set_selection ( + priv->date_navigator->calitem, + &start_date, &end_date); +} + +void +gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal) +{ + GnomeCalendarViewType view_type; + ECalendarView *calendar_view; + GnomeCalendarPrivate *priv; + time_t start_time, end_time; + gboolean has_time_range; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + priv = gcal->priv; + + view_type = gnome_calendar_get_view (gcal); + calendar_view = gnome_calendar_get_calendar_view (gcal, view_type); + + /* If no time range is set yet, just return. */ + has_time_range = e_calendar_view_get_visible_time_range ( + calendar_view, &start_time, &end_time); + if (!has_time_range) + return; + + /* We check if the visible date range has changed, and only emit the + * signal if it has. (This makes sure we only change the folder title + * bar label in the shell when we need to.) */ + if (priv->visible_start != start_time + || priv->visible_end != end_time) { + priv->visible_start = start_time; + priv->visible_end = end_time; + + gtk_widget_queue_draw (GTK_WIDGET (calendar_view)); + g_signal_emit (gcal, signals[DATES_SHOWN_CHANGED], 0); + } + update_task_and_memo_views (gcal); +} + +/* Returns the number of selected events (0 or 1 at present). */ +gint +gnome_calendar_get_num_events_selected (GnomeCalendar *gcal) +{ + GnomeCalendarViewType view_type; + ECalendarView *view; + gint retval = 0; + + g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0); + + view_type = gnome_calendar_get_view (gcal); + view = gnome_calendar_get_calendar_view (gcal, view_type); + + if (E_IS_DAY_VIEW (view)) + retval = e_day_view_get_num_events_selected (E_DAY_VIEW (view)); + else + retval = e_week_view_get_num_events_selected (E_WEEK_VIEW (view)); + + return retval; +} + +struct purge_data { + gboolean remove; + time_t older_than; +}; + +static gboolean +check_instance_cb (ECalComponent *comp, + time_t instance_start, + time_t instance_end, + gpointer data) +{ + struct purge_data *pd = data; + + if (instance_end >= pd->older_than) + pd->remove = FALSE; + + return pd->remove; +} + +void +gnome_calendar_purge (GnomeCalendar *gcal, + time_t older_than) +{ + ECalModel *model; + gchar *sexp, *start, *end; + GList *list, *link; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + + model = gnome_calendar_get_model (gcal); + + start = isodate_from_time_t (0); + end = isodate_from_time_t (older_than); + sexp = g_strdup_printf ( + "(occur-in-time-range? (make-time \"%s\") (make-time \"%s\") \"%s\")", + start, end, gcal_get_default_tzloc (gcal)); + + gcal_update_status_message (gcal, _("Purging"), -1); + + /* FIXME Confirm expunge */ + list = e_cal_model_list_clients (model); + + for (link = list; link != NULL; link = g_list_next (link)) { + ECalClient *client = E_CAL_CLIENT (link->data); + GSList *objects, *m; + GError *error = NULL; + + if (e_client_is_readonly (E_CLIENT (client))) + continue; + + e_cal_client_get_object_list_sync ( + client, sexp, &objects, NULL, &error); + + if (error != NULL) { + g_warning ( + "%s: Could not get the objects: %s", + G_STRFUNC, error->message); + g_error_free (error); + continue; + } + + for (m = objects; m; m = m->next) { + gboolean remove = TRUE; + + /* FIXME write occur-before and occur-after + * sexp funcs so we don't have to use the max + * gint */ + if (!e_cal_client_check_recurrences_no_master (client)) { + struct purge_data pd; + + pd.remove = TRUE; + pd.older_than = older_than; + + e_cal_client_generate_instances_for_object_sync (client, m->data, + older_than, G_MAXINT32, + check_instance_cb, + &pd); + + remove = pd.remove; + } + + /* FIXME Better error handling */ + if (remove) { + const gchar *uid = icalcomponent_get_uid (m->data); + GError *error = NULL; + + if (e_cal_util_component_is_instance (m->data) || + e_cal_util_component_has_recurrences (m->data)) { + gchar *rid = NULL; + struct icaltimetype recur_id; + + recur_id = icalcomponent_get_recurrenceid (m->data); + + if (!icaltime_is_null_time (recur_id)) + rid = icaltime_as_ical_string_r (recur_id); + + e_cal_client_remove_object_sync ( + client, uid, rid, + CALOBJ_MOD_ALL, NULL, &error); + g_free (rid); + } else { + e_cal_client_remove_object_sync ( + client, uid, NULL, + CALOBJ_MOD_THIS, NULL, &error); + } + + if (error != NULL) { + g_warning ( + "%s: Unable to purge events: %s", + G_STRFUNC, error->message); + g_error_free (error); + } + } + } + + g_slist_foreach (objects, (GFunc) icalcomponent_free, NULL); + g_slist_free (objects); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + + gcal_update_status_message (gcal, NULL, -1); + + g_free (sexp); + g_free (start); + g_free (end); + +} diff -Nru evolution-3.16.0/calendar/gui/gnome-cal.h evolution-3.12.11/calendar/gui/gnome-cal.h --- evolution-3.16.0/calendar/gui/gnome-cal.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/calendar/gui/gnome-cal.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,190 @@ +/* + * Evolution calendar - Main calendar view widget + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + * + * Authors: + * Miguel de Icaza + * Federico Mena-Quintero + * Seth Alves + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef GNOME_CALENDAR_H +#define GNOME_CALENDAR_H + +#include +#include +#include + +#include + +#include "e-cal-model.h" + +/* Standard GObject macros */ +#define GNOME_TYPE_CALENDAR \ + (gnome_calendar_get_type ()) +#define GNOME_CALENDAR(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), GNOME_TYPE_CALENDAR, GnomeCalendar)) +#define GNOME_CALENDAR_CLASS(cls) \ + (G_TYPE_CHECK_INSTANCE_CAST_CLASS \ + ((cls), GNOME_TYPE_CALENDAR, GnomeCalendarClass)) +#define GNOME_IS_CALENDAR(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), GNOME_TYPE_CALENDAR)) +#define GNOME_IS_CALENDAR_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), GNOME_TYPE_CALENDAR)) +#define GNOME_CALENDAR_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), GNOME_TYPE_CALENDAR, GnomeCalendarClass)) + +G_BEGIN_DECLS + +/* Avoid circular inclusion. */ +struct _ECalendarView; + +typedef struct _GnomeCalendar GnomeCalendar; +typedef struct _GnomeCalendarClass GnomeCalendarClass; +typedef struct _GnomeCalendarPrivate GnomeCalendarPrivate; + +/* View types */ +typedef enum { + GNOME_CAL_DAY_VIEW, + GNOME_CAL_WORK_WEEK_VIEW, + GNOME_CAL_WEEK_VIEW, + GNOME_CAL_MONTH_VIEW, + GNOME_CAL_LIST_VIEW, + GNOME_CAL_LAST_VIEW +} GnomeCalendarViewType; + +typedef enum { + GNOME_CAL_GOTO_TODAY, + GNOME_CAL_GOTO_DATE, + GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH, + GNOME_CAL_GOTO_LAST_DAY_OF_MONTH, + GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK, + GNOME_CAL_GOTO_LAST_DAY_OF_WEEK, + GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK, + GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK +} GnomeCalendarGotoDateType; + +struct _GnomeCalendar { + GObject parent; + GnomeCalendarPrivate *priv; +}; + +struct _GnomeCalendarClass { + GObjectClass parent_class; + + /* Notification signals */ + void (*dates_shown_changed) (GnomeCalendar *gcal); + + void (*calendar_selection_changed) (GnomeCalendar *gcal); + + void (*calendar_focus_change) (GnomeCalendar *gcal, + gboolean in); + void (*change_view) (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); + + void (*source_added) (GnomeCalendar *gcal, + ESource *source); + void (*source_removed) (GnomeCalendar *gcal, + ESource *source); + + /* Action signals */ + void (*goto_date) (GnomeCalendar *gcal, + GnomeCalendarGotoDateType date); +}; + +GType gnome_calendar_get_type (void); +GtkWidget * gnome_calendar_new (ESourceRegistry *registry); +ESourceRegistry * + gnome_calendar_get_registry (GnomeCalendar *gcal); +ECalendar * gnome_calendar_get_date_navigator + (GnomeCalendar *gcal); +void gnome_calendar_set_date_navigator + (GnomeCalendar *gcal, + ECalendar *date_navigator); +GtkWidget * gnome_calendar_get_memo_table (GnomeCalendar *gcal); +void gnome_calendar_set_memo_table (GnomeCalendar *gcal, + GtkWidget *memo_table); +GtkWidget * gnome_calendar_get_task_table (GnomeCalendar *gcal); +void gnome_calendar_set_task_table (GnomeCalendar *gcal, + GtkWidget *task_table); +ECalModel * gnome_calendar_get_model (GnomeCalendar *gcal); +void gnome_calendar_update_query (GnomeCalendar *gcal); +void gnome_calendar_set_search_query (GnomeCalendar *gcal, + const gchar *sexp, + gboolean range_search, + time_t start_range, + time_t end_range); + +void gnome_calendar_next (GnomeCalendar *gcal); +void gnome_calendar_previous (GnomeCalendar *gcal); +void gnome_calendar_goto (GnomeCalendar *gcal, + time_t new_time); +void gnome_calendar_update_view_times (GnomeCalendar *gcal, + time_t start_time); +void gnome_calendar_dayjump (GnomeCalendar *gcal, + time_t time); +void gnome_calendar_goto_today (GnomeCalendar *gcal); + +GnomeCalendarViewType + gnome_calendar_get_view (GnomeCalendar *gcal); +void gnome_calendar_set_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); +void gnome_calendar_display_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); + +struct _ECalendarView * + gnome_calendar_get_calendar_view (GnomeCalendar *gcal, + GnomeCalendarViewType view_type); + +gboolean gnome_calendar_get_range_selected + (GnomeCalendar *gcal); +void gnome_calendar_set_range_selected + (GnomeCalendar *gcal, + gboolean range_selected); +void gnome_calendar_set_selected_time_range + (GnomeCalendar *gcal, + time_t start_time); +void gnome_calendar_new_task (GnomeCalendar *gcal, + time_t *dtstart, + time_t *dtend); + +/* Returns the selected time range for the current view. Note that this may be + * different from the fields in the GnomeCalendar, since the view may clip + * this or choose a more appropriate time. */ +void gnome_calendar_get_current_time_range + (GnomeCalendar *gcal, + time_t *start_time, + time_t *end_time); + +void gnome_calendar_notify_dates_shown_changed + (GnomeCalendar *gcal); + +/* Returns the number of selected events (0 or 1 at present). */ +gint gnome_calendar_get_num_events_selected + (GnomeCalendar *gcal); + +void gnome_calendar_purge (GnomeCalendar *gcal, + time_t older_than); + +G_END_DECLS + +#endif diff -Nru evolution-3.16.0/calendar/gui/itip-utils.c evolution-3.12.11/calendar/gui/itip-utils.c --- evolution-3.16.0/calendar/gui/itip-utils.c 2015-02-26 07:16:47.000000000 +0000 +++ evolution-3.12.11/calendar/gui/itip-utils.c 2014-11-11 11:12:10.000000000 +0000 @@ -426,10 +426,10 @@ return user_email; } - } - g_free (address); - address = NULL; + g_free (address); + address = NULL; + } extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; list = e_source_registry_list_enabled (registry, extension_name); @@ -1124,34 +1124,37 @@ } static gboolean -comp_server_send_sync (ECalComponentItipMethod method, - ECalComponent *comp, - ECalClient *cal_client, - icalcomponent *zones, - GSList **users, - GCancellable *cancellable, - GError **error) +comp_server_send (ECalComponentItipMethod method, + ECalComponent *comp, + ECalClient *cal_client, + icalcomponent *zones, + GSList **users) { icalcomponent *top_level, *returned_icalcomp = NULL; gboolean retval = TRUE; - GError *local_error = NULL; + GError *error = NULL; top_level = comp_toplevel_with_zones (method, comp, cal_client, zones); - d (printf ("itip-utils.c: comp_server_send_sync: calling e_cal_send_objects... \n")); + d (printf ("itip-utils.c: comp_server_send: calling e_cal_send_objects... \n")); e_cal_client_send_objects_sync ( cal_client, top_level, users, - &returned_icalcomp, cancellable, &local_error); + &returned_icalcomp, NULL, &error); - if (g_error_matches (local_error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_ID_ALREADY_EXISTS)) { - g_propagate_error (error, g_error_new (local_error->domain, local_error->code, - _("Unable to book a resource, the new event collides with some other."))); - g_clear_error (&local_error); + if (g_error_matches (error, E_CAL_CLIENT_ERROR, E_CAL_CLIENT_ERROR_OBJECT_ID_ALREADY_EXISTS)) { + e_notice ( + NULL, GTK_MESSAGE_ERROR, + _("Unable to book a resource, the " + "new event collides with some other.")); + g_error_free (error); retval = FALSE; - } else if (local_error != NULL) { - g_prefix_error (&local_error, "%s", _("Unable to book a resource, error: ")); - g_propagate_error (error, local_error); + } else if (error != NULL) { + e_notice ( + NULL, GTK_MESSAGE_ERROR, + _("Unable to book a resource, error: %s"), + error->message); + g_error_free (error); retval = FALSE; } @@ -1669,90 +1672,18 @@ g_object_unref (registry); } -typedef struct { - ESourceRegistry *registry; - ECalComponentItipMethod method; - ECalComponent *send_comp; - ECalClient *cal_client; - icalcomponent *zones; - GSList *attachments_list; - GSList *users; - gboolean strip_alarms; - gboolean only_new_attendees; - gboolean ensure_master_object; - - gboolean finished; - gboolean success; -} ItipSendComponentData; - -static void -itip_send_component_data_free (ItipSendComponentData *isc) -{ - if (isc) { - g_clear_object (&isc->registry); - g_clear_object (&isc->send_comp); - g_clear_object (&isc->cal_client); - if (isc->zones) - icalcomponent_free (isc->zones); - g_slist_free_full (isc->attachments_list, g_object_unref); /* CamelMimePart */ - g_slist_free_full (isc->users, g_free); - g_free (isc); - } -} - -static void -itip_send_component_begin (ItipSendComponentData *isc, - GCancellable *cancellable, - GError **error) -{ - g_return_if_fail (isc != NULL); - - isc->finished = FALSE; - - if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH && e_cal_client_check_save_schedules (isc->cal_client)) { - isc->success = TRUE; - isc->finished = TRUE; - return; - } - - if (isc->ensure_master_object && e_cal_component_is_instance (isc->send_comp)) { - /* Ensure we send the master object, not the instance only */ - icalcomponent *icalcomp = NULL; - const gchar *uid = NULL; - - e_cal_component_get_uid (isc->send_comp, &uid); - if (e_cal_client_get_object_sync (isc->cal_client, uid, NULL, &icalcomp, cancellable, NULL) && icalcomp) { - ECalComponent *send_comp; - - send_comp = e_cal_component_new_from_icalcomponent (icalcomp); - if (send_comp) { - g_object_unref (isc->send_comp); - isc->send_comp = send_comp; - } - } - } - - /* Give the server a chance to manipulate the comp */ - if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH) { - d (printf ("itip-utils.c: itip_send_component_begin: calling comp_server_send_sync... \n")); - if (!comp_server_send_sync (isc->method, isc->send_comp, isc->cal_client, isc->zones, &isc->users, cancellable, error)) { - isc->success = FALSE; - isc->finished = TRUE; - return; - } - } - - /* check whether backend could handle sending requests/updates */ - if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH && - e_client_check_capability (E_CLIENT (isc->cal_client), CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) { - isc->success = TRUE; - isc->finished = TRUE; - } -} - -static void -itip_send_component_finish (ItipSendComponentData *isc) +gboolean +itip_send_comp (ESourceRegistry *registry, + ECalComponentItipMethod method, + ECalComponent *send_comp, + ECalClient *cal_client, + icalcomponent *zones, + GSList *attachments_list, + GSList *users, + gboolean strip_alarms, + gboolean only_new_attendees) { + EShell *shell; GSettings *settings; EMsgComposer *composer; EComposerHeaderTable *table; @@ -1763,58 +1694,83 @@ gchar *ical_string = NULL; gchar *content_type = NULL; gchar *subject = NULL; - gboolean use_24hour_format; + gboolean use_24_hour_format; + gboolean retval = FALSE; - g_return_if_fail (isc != NULL); + g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE); - if (isc->finished) - return; + /* FIXME Pass this in. */ + shell = e_shell_get_default (); + + settings = g_settings_new ("org.gnome.evolution.calendar"); - isc->success = FALSE; + use_24_hour_format = + g_settings_get_boolean (settings, "use-24hour-format"); - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); - use_24hour_format = g_settings_get_boolean (settings, "use-24hour-format"); g_object_unref (settings); default_zone = calendar_config_get_icaltimezone (); + /* check whether backend could handle auto-saving requests/updates */ + if (method != E_CAL_COMPONENT_METHOD_PUBLISH && e_cal_client_check_save_schedules (cal_client)) + return TRUE; + + /* Give the server a chance to manipulate the comp */ + if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { + d (printf ("itip-utils.c: itip_send_comp: calling comp_server_send... \n")); + if (!comp_server_send (method, send_comp, cal_client, zones, &users)) + goto cleanup; + } + + /* check whether backend could handle sending requests/updates */ + if (method != E_CAL_COMPONENT_METHOD_PUBLISH && + e_client_check_capability ( + E_CLIENT (cal_client), + CAL_STATIC_CAPABILITY_CREATE_MESSAGES)) { + if (users) { + g_slist_foreach (users, (GFunc) g_free, NULL); + g_slist_free (users); + } + return TRUE; + } + /* Tidy up the comp */ comp = comp_compliant ( - isc->registry, isc->method, isc->send_comp, isc->cal_client, - isc->zones, default_zone, isc->strip_alarms); + registry, method, send_comp, cal_client, + zones, default_zone, strip_alarms); if (comp == NULL) goto cleanup; /* Recipients */ destinations = comp_to_list ( - isc->registry, isc->method, comp, isc->users, FALSE, - isc->only_new_attendees ? g_object_get_data ( - G_OBJECT (isc->send_comp), "new-attendees") : NULL); - if (isc->method != E_CAL_COMPONENT_METHOD_PUBLISH) { + registry, method, comp, users, FALSE, + only_new_attendees ? g_object_get_data ( + G_OBJECT (send_comp), "new-attendees") : NULL); + if (method != E_CAL_COMPONENT_METHOD_PUBLISH) { if (destinations == NULL) { /* We sent them all via the server */ - isc->success = TRUE; + retval = TRUE; goto cleanup; } } /* Subject information */ - subject = comp_subject (isc->registry, isc->method, comp); + subject = comp_subject (registry, method, comp); - composer = e_msg_composer_new (e_shell_get_default ()); + composer = e_msg_composer_new (shell); table = e_msg_composer_get_header_table (composer); - setup_from (isc->method, isc->send_comp, isc->cal_client, table); + setup_from (method, send_comp, cal_client, table); e_composer_header_table_set_subject (table, subject); e_composer_header_table_set_destinations_to (table, destinations); e_destination_freev (destinations); /* Content type */ - content_type = comp_content_type (comp, isc->method); + content_type = comp_content_type (comp, method); - top_level = comp_toplevel_with_zones (isc->method, comp, isc->cal_client, isc->zones); + top_level = comp_toplevel_with_zones (method, comp, cal_client, zones); ical_string = icalcomponent_as_ical_string_r (top_level); if (e_cal_component_get_vtype (comp) == E_CAL_COMPONENT_EVENT) { @@ -1826,9 +1782,10 @@ gchar *body; filename = comp_filename (comp); - description = comp_description (comp, use_24hour_format); + description = comp_description (comp, use_24_hour_format); - body = camel_text_to_html (description, CAMEL_MIME_FILTER_TOHTML_PRE, 0); + body = camel_text_to_html ( + description, CAMEL_MIME_FILTER_TOHTML_PRE, 0); e_msg_composer_set_body_text (composer, body, TRUE); g_free (body); @@ -1847,162 +1804,31 @@ g_free (description); } - append_cal_attachments (composer, comp, isc->attachments_list); + append_cal_attachments (composer, comp, attachments_list); - if (isc->method == E_CAL_COMPONENT_METHOD_PUBLISH && !isc->users) + if ((method == E_CAL_COMPONENT_METHOD_PUBLISH) && !users) gtk_widget_show (GTK_WIDGET (composer)); else e_msg_composer_send (composer); - isc->success = TRUE; + retval = TRUE; - cleanup: - g_clear_object (&comp); +cleanup: + if (comp != NULL) + g_object_unref (comp); if (top_level != NULL) icalcomponent_free (top_level); - g_free (content_type); - g_free (subject); - g_free (ical_string); -} - -static void -itip_send_component_finish_and_free (gpointer ptr) -{ - ItipSendComponentData *isc = ptr; - - if (isc) { - itip_send_component_finish (isc); - itip_send_component_data_free (isc); - } -} -static void -itip_send_component_thread (EAlertSinkThreadJobData *job_data, - gpointer user_data, - GCancellable *cancellable, - GError **error) -{ - ItipSendComponentData *isc = user_data; - - g_return_if_fail (isc != NULL); - - itip_send_component_begin (isc, cancellable, error); -} - -void -itip_send_component (ECalModel *model, - ECalComponentItipMethod method, - ECalComponent *send_comp, - ECalClient *cal_client, - icalcomponent *zones, - GSList *attachments_list, - GSList *users, - gboolean strip_alarms, - gboolean only_new_attendees, - gboolean ensure_master_object) -{ - ESourceRegistry *registry; - ECalDataModel *data_model; - ESource *source; - const gchar *alert_ident; - const gchar *description; - GCancellable *cancellable; - ItipSendComponentData *isc; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - g_return_if_fail (E_IS_CAL_CLIENT (cal_client)); - - switch (e_cal_client_get_source_type (cal_client)) { - case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: - description = _("Sending an event"); - alert_ident = "calendar:failed-send-event"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_MEMOS: - description = _("Sending a memo"); - alert_ident = "calendar:failed-send-memo"; - break; - case E_CAL_CLIENT_SOURCE_TYPE_TASKS: - description = _("Sending a task"); - alert_ident = "calendar:failed-send-task"; - break; - default: - g_warn_if_reached (); - break; - } - - registry = e_cal_model_get_registry (model); - data_model = e_cal_model_get_data_model (model); - source = e_client_get_source (E_CLIENT (cal_client)); - - isc = g_new0 (ItipSendComponentData, 1); - isc->registry = g_object_ref (registry); - isc->method = method; - isc->send_comp = g_object_ref (send_comp); - isc->cal_client = g_object_ref (cal_client); - if (zones) { - isc->zones = icalcomponent_new_clone (zones); - } - if (attachments_list) { - isc->attachments_list = g_slist_copy (attachments_list); - g_slist_foreach (isc->attachments_list, (GFunc) g_object_ref, NULL); - } if (users) { - GSList *link; - - isc->users = g_slist_copy (users); - for (link = isc->users; link; link = g_slist_next (link)) { - link->data = g_strdup (link->data); - } + g_slist_foreach (users, (GFunc) g_free, NULL); + g_slist_free (users); } - isc->strip_alarms = strip_alarms; - isc->only_new_attendees = only_new_attendees; - isc->ensure_master_object = ensure_master_object; - isc->success = FALSE; - isc->finished = FALSE; - cancellable = e_cal_data_model_submit_thread_job (data_model, description, alert_ident, - e_source_get_display_name (source), itip_send_component_thread, - isc, itip_send_component_finish_and_free); - - g_clear_object (&cancellable); -} - -gboolean -itip_send_comp_sync (ESourceRegistry *registry, - ECalComponentItipMethod method, - ECalComponent *send_comp, - ECalClient *cal_client, - icalcomponent *zones, - GSList *attachments_list, - GSList *users, - gboolean strip_alarms, - gboolean only_new_attendees, - GCancellable *cancellable, - GError **error) -{ - ItipSendComponentData isc; - - memset (&isc, 0, sizeof (ItipSendComponentData)); - - isc.registry = registry; - isc.method = method; - isc.send_comp = send_comp; - isc.cal_client = cal_client; - isc.zones = zones; - isc.attachments_list = attachments_list; - isc.users = users; - isc.strip_alarms = strip_alarms; - isc.only_new_attendees = only_new_attendees; - - isc.finished = FALSE; - isc.success = FALSE; - - itip_send_component_begin (&isc, cancellable, error); - itip_send_component_finish (&isc); - - g_slist_free_full (isc.users, g_free); + g_free (content_type); + g_free (subject); + g_free (ical_string); - return isc.success; + return retval; } gboolean diff -Nru evolution-3.16.0/calendar/gui/itip-utils.h evolution-3.12.11/calendar/gui/itip-utils.h --- evolution-3.16.0/calendar/gui/itip-utils.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/itip-utils.h 2014-03-24 09:25:23.000000000 +0000 @@ -22,7 +22,6 @@ #include #include #include -#include G_BEGIN_DECLS @@ -69,27 +68,15 @@ gchar * itip_get_comp_attendee (ESourceRegistry *registry, ECalComponent *comp, ECalClient *cal_client); -gboolean itip_send_comp_sync (ESourceRegistry *registry, +gboolean itip_send_comp (ESourceRegistry *registry, ECalComponentItipMethod method, - ECalComponent *send_comp, - ECalClient *cal_client, - icalcomponent *zones, - GSList *attachments_list, - GSList *users, - gboolean strip_alarms, - gboolean only_new_attendees, - GCancellable *cancellable, - GError **error); -void itip_send_component (ECalModel *model, - ECalComponentItipMethod method, - ECalComponent *send_comp, + ECalComponent *comp, ECalClient *cal_client, icalcomponent *zones, GSList *attachments_list, GSList *users, gboolean strip_alarms, - gboolean only_new_attendees, - gboolean ensure_master_object); + gboolean only_new_attendees); gboolean itip_publish_begin (ECalComponent *pub_comp, ECalClient *cal_client, gboolean cloned, diff -Nru evolution-3.16.0/calendar/gui/Makefile.am evolution-3.12.11/calendar/gui/Makefile.am --- evolution-3.16.0/calendar/gui/Makefile.am 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -11,13 +11,11 @@ comp-util.h \ e-alarm-list.h \ e-cal-config.h \ - e-cal-data-model.h \ - e-cal-data-model-subscriber.h \ e-cal-event.h \ e-cal-list-view.h \ e-cal-model-calendar.h \ e-cal-model.h \ - e-cal-ops.h \ + e-calendar-selector.h \ e-calendar-view.h \ e-cell-date-edit-text.h \ e-date-time-list.h \ @@ -42,6 +40,7 @@ e-week-view.h \ e-weekday-chooser.h \ e-timezone-entry.h \ + gnome-cal.h \ itip-utils.h \ misc.h \ tag-calendar.h @@ -68,9 +67,8 @@ -DPREFIX=\""$(prefix)"\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(LIBSOUP_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) \ + $(LIBSOUP_CFLAGS) etspec_DATA = \ e-calendar-table.etspec \ @@ -92,24 +90,20 @@ e-cal-component-preview.h \ e-cal-config.c \ e-cal-config.h \ - e-cal-data-model.c \ - e-cal-data-model.h \ - e-cal-data-model-subscriber.c \ - e-cal-data-model-subscriber.h \ e-cal-event.c \ e-cal-event.h \ - e-cal-list-view.c \ - e-cal-list-view.h \ e-cal-model-calendar.c \ e-cal-model-calendar.h \ e-cal-model.c \ e-cal-model.h \ + e-cal-list-view.c \ + e-cal-list-view.h \ e-cal-model-memos.c \ e-cal-model-memos.h \ e-cal-model-tasks.c \ e-cal-model-tasks.h \ - e-cal-ops.h \ - e-cal-ops.c \ + e-calendar-selector.c \ + e-calendar-selector.h \ e-calendar-view.c \ e-calendar-view.h \ e-cell-date-edit-text.h \ @@ -139,6 +133,8 @@ e-meeting-types.h \ e-meeting-utils.c \ e-meeting-utils.h \ + e-memo-list-selector.c \ + e-memo-list-selector.h \ e-memo-table.c \ e-memo-table.h \ e-month-view.c \ @@ -147,6 +143,8 @@ e-select-names-editable.h \ e-select-names-renderer.c \ e-select-names-renderer.h \ + e-task-list-selector.c \ + e-task-list-selector.h \ e-task-table.c \ e-task-table.h \ e-week-view-event-item.c \ @@ -163,6 +161,8 @@ e-weekday-chooser.h \ e-timezone-entry.c \ e-timezone-entry.h \ + gnome-cal.c \ + gnome-cal.h \ itip-utils.c \ itip-utils.h \ misc.c \ @@ -192,7 +192,9 @@ ea-week-view-cell.c \ ea-week-view-cell.h \ ea-jump-button.c \ - ea-jump-button.h + ea-jump-button.h \ + ea-gnome-calendar.c \ + ea-gnome-calendar.h libevolution_calendar_la_LIBADD = \ $(top_builddir)/composer/libevolution-mail-composer.la \ @@ -204,10 +206,10 @@ $(top_builddir)/e-util/libevolution-util.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(LIBSOUP_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(LIBSOUP_LIBS) -libevolution_calendar_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_calendar_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) EXTRA_DIST = \ $(ui_DATA) \ diff -Nru evolution-3.16.0/calendar/gui/Makefile.in evolution-3.12.11/calendar/gui/Makefile.in --- evolution-3.16.0/calendar/gui/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/calendar/gui/Makefile.in 2015-02-09 08:21:54.000000000 +0000 @@ -86,7 +86,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -141,7 +140,7 @@ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/e-util/libevolution-util.la \ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) am_libevolution_calendar_la_OBJECTS = \ libevolution_calendar_la-calendar-config.lo \ libevolution_calendar_la-calendar-view.lo \ @@ -149,15 +148,13 @@ libevolution_calendar_la-e-alarm-list.lo \ libevolution_calendar_la-e-cal-component-preview.lo \ libevolution_calendar_la-e-cal-config.lo \ - libevolution_calendar_la-e-cal-data-model.lo \ - libevolution_calendar_la-e-cal-data-model-subscriber.lo \ libevolution_calendar_la-e-cal-event.lo \ - libevolution_calendar_la-e-cal-list-view.lo \ libevolution_calendar_la-e-cal-model-calendar.lo \ libevolution_calendar_la-e-cal-model.lo \ + libevolution_calendar_la-e-cal-list-view.lo \ libevolution_calendar_la-e-cal-model-memos.lo \ libevolution_calendar_la-e-cal-model-tasks.lo \ - libevolution_calendar_la-e-cal-ops.lo \ + libevolution_calendar_la-e-calendar-selector.lo \ libevolution_calendar_la-e-calendar-view.lo \ libevolution_calendar_la-e-cell-date-edit-text.lo \ libevolution_calendar_la-e-date-time-list.lo \ @@ -172,10 +169,12 @@ libevolution_calendar_la-e-meeting-time-sel.lo \ libevolution_calendar_la-e-meeting-time-sel-item.lo \ libevolution_calendar_la-e-meeting-utils.lo \ + libevolution_calendar_la-e-memo-list-selector.lo \ libevolution_calendar_la-e-memo-table.lo \ libevolution_calendar_la-e-month-view.lo \ libevolution_calendar_la-e-select-names-editable.lo \ libevolution_calendar_la-e-select-names-renderer.lo \ + libevolution_calendar_la-e-task-list-selector.lo \ libevolution_calendar_la-e-task-table.lo \ libevolution_calendar_la-e-week-view-event-item.lo \ libevolution_calendar_la-e-week-view-layout.lo \ @@ -184,6 +183,7 @@ libevolution_calendar_la-e-week-view.lo \ libevolution_calendar_la-e-weekday-chooser.lo \ libevolution_calendar_la-e-timezone-entry.lo \ + libevolution_calendar_la-gnome-cal.lo \ libevolution_calendar_la-itip-utils.lo \ libevolution_calendar_la-misc.lo \ libevolution_calendar_la-print.lo \ @@ -198,7 +198,8 @@ libevolution_calendar_la-ea-week-view.lo \ libevolution_calendar_la-ea-week-view-main-item.lo \ libevolution_calendar_la-ea-week-view-cell.lo \ - libevolution_calendar_la-ea-jump-button.lo + libevolution_calendar_la-ea-jump-button.lo \ + libevolution_calendar_la-ea-gnome-calendar.lo libevolution_calendar_la_OBJECTS = \ $(am_libevolution_calendar_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -323,14 +324,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -343,9 +341,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -359,8 +354,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -371,7 +364,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -398,6 +390,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -421,13 +417,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -573,13 +566,11 @@ comp-util.h \ e-alarm-list.h \ e-cal-config.h \ - e-cal-data-model.h \ - e-cal-data-model-subscriber.h \ e-cal-event.h \ e-cal-list-view.h \ e-cal-model-calendar.h \ e-cal-model.h \ - e-cal-ops.h \ + e-calendar-selector.h \ e-calendar-view.h \ e-cell-date-edit-text.h \ e-date-time-list.h \ @@ -604,6 +595,7 @@ e-week-view.h \ e-weekday-chooser.h \ e-timezone-entry.h \ + gnome-cal.h \ itip-utils.h \ misc.h \ tag-calendar.h @@ -628,9 +620,8 @@ -DPREFIX=\""$(prefix)"\" \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(LIBSOUP_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) \ + $(LIBSOUP_CFLAGS) etspec_DATA = \ e-calendar-table.etspec \ @@ -652,24 +643,20 @@ e-cal-component-preview.h \ e-cal-config.c \ e-cal-config.h \ - e-cal-data-model.c \ - e-cal-data-model.h \ - e-cal-data-model-subscriber.c \ - e-cal-data-model-subscriber.h \ e-cal-event.c \ e-cal-event.h \ - e-cal-list-view.c \ - e-cal-list-view.h \ e-cal-model-calendar.c \ e-cal-model-calendar.h \ e-cal-model.c \ e-cal-model.h \ + e-cal-list-view.c \ + e-cal-list-view.h \ e-cal-model-memos.c \ e-cal-model-memos.h \ e-cal-model-tasks.c \ e-cal-model-tasks.h \ - e-cal-ops.h \ - e-cal-ops.c \ + e-calendar-selector.c \ + e-calendar-selector.h \ e-calendar-view.c \ e-calendar-view.h \ e-cell-date-edit-text.h \ @@ -699,6 +686,8 @@ e-meeting-types.h \ e-meeting-utils.c \ e-meeting-utils.h \ + e-memo-list-selector.c \ + e-memo-list-selector.h \ e-memo-table.c \ e-memo-table.h \ e-month-view.c \ @@ -707,6 +696,8 @@ e-select-names-editable.h \ e-select-names-renderer.c \ e-select-names-renderer.h \ + e-task-list-selector.c \ + e-task-list-selector.h \ e-task-table.c \ e-task-table.h \ e-week-view-event-item.c \ @@ -723,6 +714,8 @@ e-weekday-chooser.h \ e-timezone-entry.c \ e-timezone-entry.h \ + gnome-cal.c \ + gnome-cal.h \ itip-utils.c \ itip-utils.h \ misc.c \ @@ -752,7 +745,9 @@ ea-week-view-cell.c \ ea-week-view-cell.h \ ea-jump-button.c \ - ea-jump-button.h + ea-jump-button.h \ + ea-gnome-calendar.c \ + ea-gnome-calendar.h libevolution_calendar_la_LIBADD = \ $(top_builddir)/composer/libevolution-mail-composer.la \ @@ -764,10 +759,10 @@ $(top_builddir)/e-util/libevolution-util.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(LIBSOUP_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) \ + $(LIBSOUP_LIBS) -libevolution_calendar_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_calendar_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) EXTRA_DIST = \ $(ui_DATA) \ $(etspec_DATA) \ @@ -858,15 +853,13 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-alarm-list.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-component-preview.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-config.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-data-model-subscriber.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-data-model.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-event.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-model-calendar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-model-memos.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-model-tasks.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-model.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cal-ops.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-calendar-selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-calendar-view.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-cell-date-edit-text.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-date-time-list.Plo@am__quote@ @@ -881,10 +874,12 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-meeting-time-sel-item.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-meeting-time-sel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-meeting-utils.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-memo-list-selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-memo-table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-month-view.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-select-names-editable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-select-names-renderer.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-task-list-selector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-task-table.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-timezone-entry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-e-week-view-event-item.Plo@am__quote@ @@ -900,35 +895,34 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-day-view-cell.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-day-view-main-item.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-day-view.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-gnome-calendar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-jump-button.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-week-view-cell.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-week-view-main-item.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-ea-week-view.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-gnome-cal.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-itip-utils.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-misc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-print.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_la-tag-calendar.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< @@ -975,20 +969,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-config.lo `test -f 'e-cal-config.c' || echo '$(srcdir)/'`e-cal-config.c -libevolution_calendar_la-e-cal-data-model.lo: e-cal-data-model.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-data-model.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-data-model.Tpo -c -o libevolution_calendar_la-e-cal-data-model.lo `test -f 'e-cal-data-model.c' || echo '$(srcdir)/'`e-cal-data-model.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-data-model.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-data-model.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-cal-data-model.c' object='libevolution_calendar_la-e-cal-data-model.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-data-model.lo `test -f 'e-cal-data-model.c' || echo '$(srcdir)/'`e-cal-data-model.c - -libevolution_calendar_la-e-cal-data-model-subscriber.lo: e-cal-data-model-subscriber.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-data-model-subscriber.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-data-model-subscriber.Tpo -c -o libevolution_calendar_la-e-cal-data-model-subscriber.lo `test -f 'e-cal-data-model-subscriber.c' || echo '$(srcdir)/'`e-cal-data-model-subscriber.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-data-model-subscriber.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-data-model-subscriber.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-cal-data-model-subscriber.c' object='libevolution_calendar_la-e-cal-data-model-subscriber.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-data-model-subscriber.lo `test -f 'e-cal-data-model-subscriber.c' || echo '$(srcdir)/'`e-cal-data-model-subscriber.c - libevolution_calendar_la-e-cal-event.lo: e-cal-event.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-event.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-event.Tpo -c -o libevolution_calendar_la-e-cal-event.lo `test -f 'e-cal-event.c' || echo '$(srcdir)/'`e-cal-event.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-event.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-event.Plo @@ -996,13 +976,6 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-event.lo `test -f 'e-cal-event.c' || echo '$(srcdir)/'`e-cal-event.c -libevolution_calendar_la-e-cal-list-view.lo: e-cal-list-view.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-list-view.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Tpo -c -o libevolution_calendar_la-e-cal-list-view.lo `test -f 'e-cal-list-view.c' || echo '$(srcdir)/'`e-cal-list-view.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-cal-list-view.c' object='libevolution_calendar_la-e-cal-list-view.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-list-view.lo `test -f 'e-cal-list-view.c' || echo '$(srcdir)/'`e-cal-list-view.c - libevolution_calendar_la-e-cal-model-calendar.lo: e-cal-model-calendar.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-model-calendar.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-model-calendar.Tpo -c -o libevolution_calendar_la-e-cal-model-calendar.lo `test -f 'e-cal-model-calendar.c' || echo '$(srcdir)/'`e-cal-model-calendar.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-model-calendar.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-model-calendar.Plo @@ -1017,6 +990,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-model.lo `test -f 'e-cal-model.c' || echo '$(srcdir)/'`e-cal-model.c +libevolution_calendar_la-e-cal-list-view.lo: e-cal-list-view.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-list-view.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Tpo -c -o libevolution_calendar_la-e-cal-list-view.lo `test -f 'e-cal-list-view.c' || echo '$(srcdir)/'`e-cal-list-view.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-list-view.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-cal-list-view.c' object='libevolution_calendar_la-e-cal-list-view.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-list-view.lo `test -f 'e-cal-list-view.c' || echo '$(srcdir)/'`e-cal-list-view.c + libevolution_calendar_la-e-cal-model-memos.lo: e-cal-model-memos.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-model-memos.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-model-memos.Tpo -c -o libevolution_calendar_la-e-cal-model-memos.lo `test -f 'e-cal-model-memos.c' || echo '$(srcdir)/'`e-cal-model-memos.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-model-memos.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-model-memos.Plo @@ -1031,12 +1011,12 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-model-tasks.lo `test -f 'e-cal-model-tasks.c' || echo '$(srcdir)/'`e-cal-model-tasks.c -libevolution_calendar_la-e-cal-ops.lo: e-cal-ops.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-cal-ops.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-cal-ops.Tpo -c -o libevolution_calendar_la-e-cal-ops.lo `test -f 'e-cal-ops.c' || echo '$(srcdir)/'`e-cal-ops.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-cal-ops.Tpo $(DEPDIR)/libevolution_calendar_la-e-cal-ops.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-cal-ops.c' object='libevolution_calendar_la-e-cal-ops.lo' libtool=yes @AMDEPBACKSLASH@ +libevolution_calendar_la-e-calendar-selector.lo: e-calendar-selector.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-calendar-selector.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-calendar-selector.Tpo -c -o libevolution_calendar_la-e-calendar-selector.lo `test -f 'e-calendar-selector.c' || echo '$(srcdir)/'`e-calendar-selector.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-calendar-selector.Tpo $(DEPDIR)/libevolution_calendar_la-e-calendar-selector.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-calendar-selector.c' object='libevolution_calendar_la-e-calendar-selector.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-cal-ops.lo `test -f 'e-cal-ops.c' || echo '$(srcdir)/'`e-cal-ops.c +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-calendar-selector.lo `test -f 'e-calendar-selector.c' || echo '$(srcdir)/'`e-calendar-selector.c libevolution_calendar_la-e-calendar-view.lo: e-calendar-view.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-calendar-view.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-calendar-view.Tpo -c -o libevolution_calendar_la-e-calendar-view.lo `test -f 'e-calendar-view.c' || echo '$(srcdir)/'`e-calendar-view.c @@ -1136,6 +1116,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-meeting-utils.lo `test -f 'e-meeting-utils.c' || echo '$(srcdir)/'`e-meeting-utils.c +libevolution_calendar_la-e-memo-list-selector.lo: e-memo-list-selector.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-memo-list-selector.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-memo-list-selector.Tpo -c -o libevolution_calendar_la-e-memo-list-selector.lo `test -f 'e-memo-list-selector.c' || echo '$(srcdir)/'`e-memo-list-selector.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-memo-list-selector.Tpo $(DEPDIR)/libevolution_calendar_la-e-memo-list-selector.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-memo-list-selector.c' object='libevolution_calendar_la-e-memo-list-selector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-memo-list-selector.lo `test -f 'e-memo-list-selector.c' || echo '$(srcdir)/'`e-memo-list-selector.c + libevolution_calendar_la-e-memo-table.lo: e-memo-table.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-memo-table.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-memo-table.Tpo -c -o libevolution_calendar_la-e-memo-table.lo `test -f 'e-memo-table.c' || echo '$(srcdir)/'`e-memo-table.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-memo-table.Tpo $(DEPDIR)/libevolution_calendar_la-e-memo-table.Plo @@ -1164,6 +1151,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-select-names-renderer.lo `test -f 'e-select-names-renderer.c' || echo '$(srcdir)/'`e-select-names-renderer.c +libevolution_calendar_la-e-task-list-selector.lo: e-task-list-selector.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-task-list-selector.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-task-list-selector.Tpo -c -o libevolution_calendar_la-e-task-list-selector.lo `test -f 'e-task-list-selector.c' || echo '$(srcdir)/'`e-task-list-selector.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-task-list-selector.Tpo $(DEPDIR)/libevolution_calendar_la-e-task-list-selector.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='e-task-list-selector.c' object='libevolution_calendar_la-e-task-list-selector.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-task-list-selector.lo `test -f 'e-task-list-selector.c' || echo '$(srcdir)/'`e-task-list-selector.c + libevolution_calendar_la-e-task-table.lo: e-task-table.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-e-task-table.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-e-task-table.Tpo -c -o libevolution_calendar_la-e-task-table.lo `test -f 'e-task-table.c' || echo '$(srcdir)/'`e-task-table.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-e-task-table.Tpo $(DEPDIR)/libevolution_calendar_la-e-task-table.Plo @@ -1220,6 +1214,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-e-timezone-entry.lo `test -f 'e-timezone-entry.c' || echo '$(srcdir)/'`e-timezone-entry.c +libevolution_calendar_la-gnome-cal.lo: gnome-cal.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-gnome-cal.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-gnome-cal.Tpo -c -o libevolution_calendar_la-gnome-cal.lo `test -f 'gnome-cal.c' || echo '$(srcdir)/'`gnome-cal.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-gnome-cal.Tpo $(DEPDIR)/libevolution_calendar_la-gnome-cal.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='gnome-cal.c' object='libevolution_calendar_la-gnome-cal.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-gnome-cal.lo `test -f 'gnome-cal.c' || echo '$(srcdir)/'`gnome-cal.c + libevolution_calendar_la-itip-utils.lo: itip-utils.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-itip-utils.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-itip-utils.Tpo -c -o libevolution_calendar_la-itip-utils.lo `test -f 'itip-utils.c' || echo '$(srcdir)/'`itip-utils.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-itip-utils.Tpo $(DEPDIR)/libevolution_calendar_la-itip-utils.Plo @@ -1325,6 +1326,13 @@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-ea-jump-button.lo `test -f 'ea-jump-button.c' || echo '$(srcdir)/'`ea-jump-button.c +libevolution_calendar_la-ea-gnome-calendar.lo: ea-gnome-calendar.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libevolution_calendar_la-ea-gnome-calendar.lo -MD -MP -MF $(DEPDIR)/libevolution_calendar_la-ea-gnome-calendar.Tpo -c -o libevolution_calendar_la-ea-gnome-calendar.lo `test -f 'ea-gnome-calendar.c' || echo '$(srcdir)/'`ea-gnome-calendar.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libevolution_calendar_la-ea-gnome-calendar.Tpo $(DEPDIR)/libevolution_calendar_la-ea-gnome-calendar.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ea-gnome-calendar.c' object='libevolution_calendar_la-ea-gnome-calendar.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libevolution_calendar_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libevolution_calendar_la-ea-gnome-calendar.lo `test -f 'ea-gnome-calendar.c' || echo '$(srcdir)/'`ea-gnome-calendar.c + mostlyclean-libtool: -rm -f *.lo diff -Nru evolution-3.16.0/calendar/gui/print.c evolution-3.12.11/calendar/gui/print.c --- evolution-3.16.0/calendar/gui/print.c 2014-11-13 07:32:34.000000000 +0000 +++ evolution-3.12.11/calendar/gui/print.c 2014-10-07 05:37:46.000000000 +0000 @@ -44,6 +44,7 @@ #include "e-week-view.h" #include "e-week-view-layout.h" #include "e-task-table.h" +#include "gnome-cal.h" #include "art/jump.xpm" @@ -58,9 +59,7 @@ }; struct PrintCalItem { - ECalendarView *cal_view; - ETable *tasks_table; - EPrintView print_view_type; + GnomeCalendar *gcal; time_t start; }; @@ -118,7 +117,7 @@ GSettings *settings; gint time_divisions; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); time_divisions = g_settings_get_int (settings, "time-divisions"); if (time_divisions < 5 || time_divisions > 30) @@ -643,7 +642,7 @@ GSettings *settings; gboolean show_week_numbers; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); show_week_numbers = g_settings_get_boolean (settings, "show-week-numbers"); @@ -770,7 +769,7 @@ */ static void print_month_small (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t month, gdouble x1, gdouble y1, @@ -783,6 +782,7 @@ { icaltimezone *zone; PangoFontDescription *font, *font_bold, *font_normal; + ECalModel *model; time_t now, next; gint x, y; gint day; @@ -797,6 +797,7 @@ gboolean week_numbers; cairo_t *cr; + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); week_numbers = get_show_week_numbers (); @@ -923,7 +924,7 @@ /* this is a slow messy way to do this ... but easy ... */ e_cal_model_generate_instances_sync ( - model, now, + gnome_calendar_get_model (gcal), now, time_day_end_with_zone (now, zone), instance_cb, &found); @@ -1016,7 +1017,7 @@ /* Draw the borders, lines, and times down the left of the day view. */ static void print_day_background (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t whence, struct pdinfo *pdi, gdouble left, @@ -1024,6 +1025,7 @@ gdouble top, gdouble bottom) { + ECalModel *model; PangoFontDescription *font_hour, *font_minute; gdouble yinc, y; gdouble width = DAY_VIEW_TIME_COLUMN_WIDTH; @@ -1035,6 +1037,7 @@ gdouble hour_minute_x, hour_minute_width; cairo_t *cr; + model = gnome_calendar_get_model (gcal); use_24_hour = e_cal_model_get_use_24_hour_format (model); /* Fill the time column in light-gray. */ @@ -1542,13 +1545,14 @@ static void print_day_details (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t whence, gdouble left, gdouble right, gdouble top, gdouble bottom) { + ECalModel *model; icaltimezone *zone; EDayViewEvent *event; PangoFontDescription *font; @@ -1561,6 +1565,7 @@ #define LONG_DAY_EVENTS_TOP_SPACING 4 #define LONG_DAY_EVENTS_BOTTOM_SPACING 2 + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); start = time_day_begin_with_zone (whence, zone); @@ -1694,7 +1699,7 @@ /* Draw the borders, lines, and times down the left. */ print_day_background ( - context, model, whence, &pdi, + context, gcal, whence, &pdi, left, right, top, bottom); /* Now adjust to get rid of the time column. */ left += DAY_VIEW_TIME_COLUMN_WIDTH; @@ -2146,7 +2151,7 @@ static void print_week_summary (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t whence, gboolean multi_week_view, gint weeks_shown, @@ -2166,7 +2171,9 @@ GArray *spans; PangoFontDescription *font, *font_background; gdouble cell_width, cell_height; + ECalModel *model; + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); psi.days_shown = weeks_shown * 7; @@ -2262,9 +2269,7 @@ static void print_month_summary (GtkPrintContext *context, - ECalModel *model, - ECalendarView *calendar_view, - EPrintView print_view_type, + GnomeCalendar *gcal, time_t whence, gdouble left, gdouble right, @@ -2276,6 +2281,7 @@ struct tm tm; struct icaltimetype tt; gchar buffer[100]; + ECalModel *model; PangoFontDescription *font; gboolean compress_weekend; gint columns, col, month, weeks; @@ -2283,18 +2289,23 @@ gint wday; gdouble font_size, cell_width, x1, x2, y1, y2; + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); weekday = e_cal_model_get_week_start_day (model); compress_weekend = e_cal_model_get_compress_weekend (model); date = 0; weeks = 6; - if (print_view_type == E_PRINT_VIEW_MONTH) { + if (gnome_calendar_get_view (gcal) == GNOME_CAL_MONTH_VIEW) { + GnomeCalendarViewType view_type; + ECalendarView *calendar_view; EWeekView *week_view; GDate first_day_shown; gboolean multi_week_view; gint weeks_shown; + view_type = gnome_calendar_get_view (gcal); + calendar_view = gnome_calendar_get_calendar_view (gcal, view_type); week_view = E_WEEK_VIEW (calendar_view); weeks_shown = e_week_view_get_weeks_shown (week_view); multi_week_view = e_week_view_get_multi_week_view (week_view); @@ -2365,14 +2376,14 @@ top = y2; print_week_summary ( - context, model, date, TRUE, weeks, month, + context, gcal, date, TRUE, weeks, month, MONTH_NORMAL_FONT_SIZE, MONTH_NORMAL_FONT_SIZE, left, right, top, bottom); } static void print_todo_details (GtkPrintContext *context, - ETable *tasks_table, + GnomeCalendar *gcal, time_t start, time_t end, gdouble left, @@ -2383,14 +2394,18 @@ PangoFontDescription *font_summary; gdouble y, yend, x, xend; struct icaltimetype *tt; + GtkWidget *task_table; + ETable *table; ECalModel *model; gint rows, row; cairo_t *cr; /* We get the tasks directly from the TaskPad ETable. This means we * get them filtered & sorted for free. */ - g_return_if_fail (tasks_table != NULL); - model = e_task_table_get_model (E_TASK_TABLE (tasks_table)); + task_table = gnome_calendar_get_task_table (gcal); + table = E_TABLE (task_table); + g_return_if_fail (table != NULL); + model = e_task_table_get_model (E_TASK_TABLE (task_table)); font_summary = get_font_for_size (12, PANGO_WEIGHT_NORMAL); @@ -2414,7 +2429,7 @@ ECalComponentText summary; gint model_row; - model_row = e_table_view_to_model_row (tasks_table, row); + model_row = e_table_view_to_model_row (table, row); comp_data = e_cal_model_get_component_at (model, model_row); if (!comp_data) continue; @@ -2472,8 +2487,7 @@ static void print_day_view (GtkPrintContext *context, - ECalendarView *cal_view, - ETable *tasks_table, + GnomeCalendar *gcal, time_t date) { ECalModel *model; @@ -2485,7 +2499,7 @@ gdouble width, height; struct tm tm; - model = e_calendar_view_get_model (cal_view); + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); setup = gtk_print_context_get_page_setup (context); @@ -2500,13 +2514,13 @@ /* Print the main view with all the events in. */ print_day_details ( - context, model, date, + context, gcal, date, 0.0, todo - 2.0, HEADER_HEIGHT + 4, height); /* Print the TaskPad down the right. */ print_todo_details ( - context, tasks_table, 0, INT_MAX, + context, gcal, 0, INT_MAX, todo, width, HEADER_HEIGHT + 4, height); @@ -2521,13 +2535,13 @@ SMALL_MONTH_SPACING; print_month_small ( - context, model, date, + context, gcal, date, l, 2, l + small_month_width + week_numbers_inc, HEADER_HEIGHT + 2, DATE_MONTH | DATE_YEAR, date, date, FALSE); l += SMALL_MONTH_SPACING + small_month_width + week_numbers_inc; print_month_small ( - context, model, + context, gcal, time_add_month_with_zone (date, 1, zone), l, 2, l + small_month_width + week_numbers_inc, HEADER_HEIGHT + 2, DATE_MONTH | DATE_YEAR, 0, 0, FALSE); @@ -2557,7 +2571,7 @@ static void print_work_week_background (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t whence, struct pdinfo *pdi, gdouble left, @@ -2565,6 +2579,7 @@ gdouble top, gdouble bottom) { + ECalModel *model; PangoFontDescription *font_hour, *font_minute; gdouble yinc, y; gdouble width = DAY_VIEW_TIME_COLUMN_WIDTH; @@ -2578,6 +2593,7 @@ gdouble hour_minute_xl, hour_minute_xr; cairo_t *cr; + model = gnome_calendar_get_model (gcal); use_24_hour = e_cal_model_get_use_24_hour_format (model); /* Fill the left time column in light-gray. */ @@ -2711,7 +2727,7 @@ static void print_work_week_day_details (GtkPrintContext *context, - ECalModel *model, + GnomeCalendar *gcal, time_t whence, gdouble left, gdouble right, @@ -2719,6 +2735,7 @@ gdouble bottom, struct pdinfo *_pdi) { + ECalModel *model; icaltimezone *zone; EDayViewEvent *event; PangoFontDescription *font; @@ -2731,6 +2748,7 @@ #define LONG_DAY_EVENTS_TOP_SPACING 4 #define LONG_DAY_EVENTS_BOTTOM_SPACING 2 + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); start = time_day_begin_with_zone (whence, zone); @@ -2917,7 +2935,7 @@ static void print_work_week_view (GtkPrintContext *context, - ECalendarView *cal_view, + GnomeCalendar *gcal, time_t date) { GtkPageSetup *setup; @@ -2934,7 +2952,7 @@ gdouble day_width, day_x; ECalModel *model; - model = e_calendar_view_get_model (cal_view); + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); setup = gtk_print_context_get_page_setup (context); @@ -2957,7 +2975,7 @@ e_cal_model_generate_instances_sync (model, start, end, print_work_week_view_cb, &pdi); print_work_week_background ( - context, model, date, &pdi, 0.0, width, + context, gcal, date, &pdi, 0.0, width, HEADER_HEIGHT + DAY_VIEW_ROW_HEIGHT + LONG_EVENT_OFFSET, height); @@ -2968,13 +2986,13 @@ SMALL_MONTH_SPACING; print_month_small ( - context, model, start, + context, gcal, start, l, 4, l + small_month_width + weeknum_inc, HEADER_HEIGHT + 4, DATE_MONTH | DATE_YEAR, start, end, FALSE); l += SMALL_MONTH_SPACING + small_month_width + weeknum_inc; print_month_small ( - context, model, + context, gcal, time_add_month_with_zone (start, 1, zone), l, 4, l + small_month_width + weeknum_inc, HEADER_HEIGHT + 4, DATE_MONTH | DATE_YEAR, 0, 0, FALSE); @@ -3013,7 +3031,7 @@ HEADER_HEIGHT + 4, HEADER_HEIGHT + 4 + 18); print_work_week_day_details ( - context, model, when, + context, gcal, when, day_x, day_x + day_width, HEADER_HEIGHT, height, &pdi); when = time_add_day_with_zone (when, 1, zone); @@ -3022,7 +3040,7 @@ static void print_week_view (GtkPrintContext *context, - ECalendarView *cal_view, + GnomeCalendar *gcal, time_t date) { GtkPageSetup *setup; @@ -3043,7 +3061,7 @@ small_month_width = calc_small_month_width (context, HEADER_HEIGHT); week_numbers_inc = get_show_week_numbers () ? small_month_width / 7.0 : 0; - model = e_calendar_view_get_model (cal_view); + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); convert_timet_to_struct_tm (date, zone, &tm); @@ -3063,7 +3081,7 @@ /* Print the main week view. */ print_week_summary ( - context, model, when, FALSE, 1, 0, + context, gcal, when, FALSE, 1, 0, WEEK_EVENT_FONT_SIZE, WEEK_SMALL_FONT_SIZE, 0.0, width, HEADER_HEIGHT + 20, height); @@ -3082,14 +3100,14 @@ l = width - SMALL_MONTH_PAD - (small_month_width + week_numbers_inc) * 2 - SMALL_MONTH_SPACING; print_month_small ( - context, model, when, + context, gcal, when, l, 4, l + small_month_width + week_numbers_inc, HEADER_HEIGHT + 10, DATE_MONTH | DATE_YEAR, when, time_add_week_with_zone (when, 1, zone), FALSE); l += SMALL_MONTH_SPACING + small_month_width + week_numbers_inc; print_month_small ( - context, model, + context, gcal, time_add_month_with_zone (when, 1, zone), l, 4, l + small_month_width + week_numbers_inc, HEADER_HEIGHT + 10, DATE_MONTH | DATE_YEAR, when, @@ -3113,8 +3131,7 @@ static void print_month_view (GtkPrintContext *context, - ECalendarView *cal_view, - EPrintView print_view_type, + GnomeCalendar *gcal, time_t date) { ECalModel *model; @@ -3125,7 +3142,7 @@ gdouble l, week_numbers_inc, small_month_width; struct tm tm; - model = e_calendar_view_get_model (cal_view); + model = gnome_calendar_get_model (gcal); zone = e_cal_model_get_timezone (model); setup = gtk_print_context_get_page_setup (context); @@ -3136,7 +3153,7 @@ week_numbers_inc = get_show_week_numbers () ? small_month_width / 7.0 : 0; /* Print the main month view. */ - print_month_summary (context, model, cal_view, print_view_type, date, 0.0, width, HEADER_HEIGHT, height); + print_month_summary (context, gcal, date, 0.0, width, HEADER_HEIGHT, height); /* Print the border around the header. */ print_border (context, 0.0, width, 0.0, HEADER_HEIGHT + 10, 1.0, 0.9); @@ -3145,13 +3162,13 @@ /* Print the 2 mini calendar-months. */ print_month_small ( - context, model, + context, gcal, time_add_month_with_zone (date, 1, zone), l, 4, l + small_month_width + week_numbers_inc, HEADER_HEIGHT + 4, DATE_MONTH | DATE_YEAR, 0, 0, FALSE); print_month_small ( - context, model, + context, gcal, time_add_month_with_zone (date, -1, zone), SMALL_MONTH_PAD, 4, SMALL_MONTH_PAD + small_month_width + week_numbers_inc, HEADER_HEIGHT + 4, DATE_MONTH | DATE_YEAR, 0, 0, FALSE); @@ -3354,18 +3371,18 @@ gint page_nr, PrintCalItem *pcali) { - switch (pcali->print_view_type) { - case E_PRINT_VIEW_DAY: - print_day_view (context, pcali->cal_view, pcali->tasks_table, pcali->start); + switch (gnome_calendar_get_view (pcali->gcal)) { + case GNOME_CAL_DAY_VIEW: + print_day_view (context, pcali->gcal, pcali->start); break; - case E_PRINT_VIEW_WORKWEEK: - print_work_week_view (context, pcali->cal_view, pcali->start); + case GNOME_CAL_WORK_WEEK_VIEW: + print_work_week_view (context, pcali->gcal, pcali->start); break; - case E_PRINT_VIEW_WEEK: - print_week_view (context, pcali->cal_view, pcali->start); + case GNOME_CAL_WEEK_VIEW: + print_week_view (context, pcali->gcal, pcali->start); break; - case E_PRINT_VIEW_MONTH: - print_month_view (context, pcali->cal_view, pcali->print_view_type, pcali->start); + case GNOME_CAL_MONTH_VIEW: + print_month_view (context, pcali->gcal, pcali->start); break; default: g_return_if_reached (); @@ -3373,25 +3390,27 @@ } void -print_calendar (ECalendarView *cal_view, - ETable *tasks_table, - EPrintView print_view_type, +print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action, time_t start) { GtkPrintOperation *operation; PrintCalItem pcali; - g_return_if_fail (cal_view != NULL); - g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + g_return_if_fail (gcal != NULL); + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - if (print_view_type == E_PRINT_VIEW_MONTH) { + if (gnome_calendar_get_view (gcal) == GNOME_CAL_MONTH_VIEW) { + GnomeCalendarViewType view_type; + ECalendarView *calendar_view; EWeekView *week_view; GDate date; gboolean multi_week_view; gint weeks_shown; - week_view = E_WEEK_VIEW (cal_view); + view_type = gnome_calendar_get_view (gcal); + calendar_view = gnome_calendar_get_calendar_view (gcal, view_type); + week_view = E_WEEK_VIEW (calendar_view); weeks_shown = e_week_view_get_weeks_shown (week_view); multi_week_view = e_week_view_get_multi_week_view (week_view); e_week_view_get_first_day_shown (week_view, &date); @@ -3416,9 +3435,7 @@ } } - pcali.cal_view = cal_view; - pcali.tasks_table = tasks_table; - pcali.print_view_type = print_view_type; + pcali.gcal = (GnomeCalendar *) gcal; pcali.start = start; operation = e_print_operation_new (); diff -Nru evolution-3.16.0/calendar/gui/print.h evolution-3.12.11/calendar/gui/print.h --- evolution-3.16.0/calendar/gui/print.h 2014-10-13 16:01:55.000000000 +0000 +++ evolution-3.12.11/calendar/gui/print.h 2014-03-24 09:25:23.000000000 +0000 @@ -26,19 +26,17 @@ #include -#include "calendar/gui/e-calendar-view.h" +#include "calendar/gui/gnome-cal.h" typedef enum { - E_PRINT_VIEW_DAY, - E_PRINT_VIEW_WORKWEEK, - E_PRINT_VIEW_WEEK, - E_PRINT_VIEW_MONTH, - E_PRINT_VIEW_LIST -} EPrintView; + PRINT_VIEW_DAY, + PRINT_VIEW_WEEK, + PRINT_VIEW_MONTH, + PRINT_VIEW_YEAR, + PRINT_VIEW_LIST +} PrintView; -void print_calendar (ECalendarView *cal_view, - ETable *tasks_table, - EPrintView print_view_type, +void print_calendar (GnomeCalendar *gcal, GtkPrintOperationAction action, time_t start); void print_comp (ECalComponent *comp, diff -Nru evolution-3.16.0/calendar/gui/tag-calendar.c evolution-3.12.11/calendar/gui/tag-calendar.c --- evolution-3.16.0/calendar/gui/tag-calendar.c 2014-11-13 07:32:41.000000000 +0000 +++ evolution-3.12.11/calendar/gui/tag-calendar.c 2014-03-24 09:25:23.000000000 +0000 @@ -29,842 +29,8 @@ #include "shell/e-shell.h" #include "calendar-config.h" -#include "comp-util.h" -#include "e-cal-data-model-subscriber.h" #include "tag-calendar.h" -struct _ETagCalendarPrivate -{ - ECalendar *calendar; /* weak-referenced */ - ECalendarItem *calitem; /* weak-referenced */ - ECalDataModel *data_model; /* not referenced, due to circular dependency */ - gboolean recur_events_italic; - - GHashTable *objects; /* ObjectInfo ~> 1 (unused) */ - GHashTable *dates; /* julian date ~> DateInfo */ - - guint32 range_start_julian; - guint32 range_end_julian; -}; - -enum { - PROP_0, - PROP_CALENDAR, - PROP_RECUR_EVENTS_ITALIC -}; - -static void e_tag_calendar_cal_data_model_subscriber_init (ECalDataModelSubscriberInterface *iface); - -G_DEFINE_TYPE_WITH_CODE (ETagCalendar, e_tag_calendar, G_TYPE_OBJECT, - G_IMPLEMENT_INTERFACE (E_TYPE_CAL_DATA_MODEL_SUBSCRIBER, e_tag_calendar_cal_data_model_subscriber_init)) - -typedef struct { - gconstpointer client; - ECalComponentId *id; - gboolean is_transparent; /* neither of the two means is_single */ - gboolean is_recurring; - guint32 start_julian; - guint32 end_julian; -} ObjectInfo; - -typedef struct { - guint n_transparent; - guint n_recurring; - guint n_single; -} DateInfo; - -static guint -object_info_hash (gconstpointer v) -{ - const ObjectInfo *oinfo = v; - - if (!v) - return 0; - - return g_direct_hash (oinfo->client) ^ e_cal_component_id_hash (oinfo->id); -} - -/* component-related equality, for hash tables */ -static gboolean -object_info_equal (gconstpointer v1, - gconstpointer v2) -{ - const ObjectInfo *oinfo1 = v1; - const ObjectInfo *oinfo2 = v2; - - if (oinfo1 == oinfo2) - return TRUE; - - if (!oinfo1 || !oinfo2) - return FALSE; - - return oinfo1->client == oinfo2->client && - e_cal_component_id_equal (oinfo1->id, oinfo2->id); -} - -/* date-related equality, for drawing changes */ -static gboolean -object_info_data_equal (ObjectInfo *o1, - ObjectInfo *o2) -{ - if (o1 == o2) - return TRUE; - - if (!o1 || !o2) - return FALSE; - - return (o1->is_transparent ? 1: 0) == (o2->is_transparent ? 1 : 0) && - (o1->start_julian ? 1: 0) == (o2->is_recurring ? 1 : 0) && - (o1->start_julian == o2->start_julian) && - (o1->end_julian == o2->end_julian); -} - -static ObjectInfo * -object_info_new (ECalClient *client, - ECalComponentId *id, /* will be consumed */ - gboolean is_transparent, - gboolean is_recurring, - guint32 start_julian, - guint32 end_julian) -{ - ObjectInfo *oinfo; - - g_return_val_if_fail (client != NULL, NULL); - g_return_val_if_fail (id != NULL, NULL); - - oinfo = g_new0 (ObjectInfo, 1); - oinfo->client = client; - oinfo->id = id; - oinfo->is_transparent = is_transparent; - oinfo->is_recurring = is_recurring; - oinfo->start_julian = start_julian; - oinfo->end_julian = end_julian; - - return oinfo; -} - -static void -object_info_free (gpointer ptr) -{ - ObjectInfo *oinfo = ptr; - - if (oinfo) { - e_cal_component_free_id (oinfo->id); - g_free (oinfo); - } -} - -static DateInfo * -date_info_new (void) -{ - return g_new0 (DateInfo, 1); -} - -static void -date_info_free (gpointer ptr) -{ - DateInfo *dinfo = ptr; - - if (dinfo) - g_free (dinfo); -} - -static gboolean -date_info_update (DateInfo *dinfo, - ObjectInfo *oinfo, - gboolean inc) -{ - gint nn = inc ? +1 : -1; - gboolean ui_changed = FALSE; - - g_return_val_if_fail (dinfo != NULL, FALSE); - g_return_val_if_fail (oinfo != NULL, FALSE); - - if (oinfo->is_transparent) { - dinfo->n_transparent += nn; - ui_changed = ui_changed || (inc && dinfo->n_transparent == 1) || (!inc && dinfo->n_transparent == 0); - } else if (oinfo->is_recurring) { - dinfo->n_recurring += nn; - ui_changed = ui_changed || (inc && dinfo->n_recurring == 1) || (!inc && dinfo->n_recurring == 0); - } else { - dinfo->n_single += nn; - ui_changed = ui_changed || (inc && dinfo->n_single == 1) || (!inc && dinfo->n_single == 0); - } - - return ui_changed; -} - -static guint8 -date_info_get_style (DateInfo *dinfo, - gboolean recur_events_italic) -{ - guint8 style = 0; - - g_return_val_if_fail (dinfo != NULL, 0); - - if (dinfo->n_transparent > 0 || - (recur_events_italic && dinfo->n_recurring > 0)) - style |= E_CALENDAR_ITEM_MARK_ITALIC; - - if (dinfo->n_single > 0 || - (!recur_events_italic && dinfo->n_recurring > 0)) - style |= E_CALENDAR_ITEM_MARK_BOLD; - - return style; -} - -static gint32 -encode_ymd_to_julian (gint year, - gint month, - gint day) -{ - GDate dt; - - g_date_clear (&dt, 1); - g_date_set_dmy (&dt, day, month, year); - - return g_date_get_julian (&dt); -} - -static guint32 -encode_timet_to_julian (time_t t, - gboolean is_date, - const icaltimezone *zone) -{ - struct icaltimetype tt; - - if (!t) - return 0; - - if (zone) - tt = icaltime_from_timet_with_zone (t, is_date, zone); - else - tt = icaltime_from_timet (t, is_date); - - if (!icaltime_is_valid_time (tt) || icaltime_is_null_time (tt)) - return 0; - - return encode_ymd_to_julian (tt.year, tt.month, tt.day); -} - -static void -decode_julian (guint32 julian, - gint *year, - gint *month, - gint *day) -{ - GDate dt; - - g_date_clear (&dt, 1); - g_date_set_julian (&dt, julian); - - *year = g_date_get_year (&dt); - *month = g_date_get_month (&dt); - *day = g_date_get_day (&dt); -} - -static void -tag_calendar_date_cb (gpointer key, - gpointer value, - gpointer user_data) -{ - ETagCalendar *tag_calendar = user_data; - DateInfo *dinfo = value; - gint year, month, day; - - decode_julian (GPOINTER_TO_UINT (key), &year, &month, &day); - - e_calendar_item_mark_day (tag_calendar->priv->calitem, year, month - 1, day, - date_info_get_style (dinfo, tag_calendar->priv->recur_events_italic), FALSE); -} - -static void -e_tag_calendar_remark_days (ETagCalendar *tag_calendar) -{ - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - g_return_if_fail (tag_calendar->priv->calitem != NULL); - - e_calendar_item_clear_marks (tag_calendar->priv->calitem); - - g_hash_table_foreach (tag_calendar->priv->dates, tag_calendar_date_cb, tag_calendar); -} - -static time_t -e_tag_calendar_date_to_timet (gint year, - gint month, - gint day, - const icaltimezone *with_zone) -{ - GDate *date; - time_t tt; - - date = g_date_new_dmy (day, month, year); - g_return_val_if_fail (date != NULL, (time_t) -1); - - tt = cal_comp_gdate_to_timet (date, with_zone); - - g_date_free (date); - - return tt; -} - -static void -e_tag_calendar_date_range_changed_cb (ETagCalendar *tag_calendar) -{ - gint start_year, start_month, start_day, end_year, end_month, end_day; - time_t range_start, range_end; - - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - - if (!tag_calendar->priv->data_model || - !tag_calendar->priv->calitem) - return; - - g_return_if_fail (E_IS_CALENDAR_ITEM (tag_calendar->priv->calitem)); - - /* This can fail on start, when the ECalendarItem wasn't updated (drawn) yet */ - if (!e_calendar_item_get_date_range (tag_calendar->priv->calitem, - &start_year, &start_month, &start_day, &end_year, &end_month, &end_day)) - return; - - start_month++; - end_month++; - - range_start = e_tag_calendar_date_to_timet (start_year, start_month, start_day, NULL); - range_end = e_tag_calendar_date_to_timet (end_year, end_month, end_day, NULL); - - tag_calendar->priv->range_start_julian = encode_ymd_to_julian (start_year, start_month, start_day); - tag_calendar->priv->range_end_julian = encode_ymd_to_julian (end_year, end_month, end_day); - - /* Range change causes removal of marks in the calendar */ - e_tag_calendar_remark_days (tag_calendar); - - e_cal_data_model_subscribe (tag_calendar->priv->data_model, - E_CAL_DATA_MODEL_SUBSCRIBER (tag_calendar), - range_start, range_end); -} - -static gboolean -e_tag_calendar_query_tooltip_cb (ECalendar *calendar, - gint x, - gint y, - gboolean keayboard_mode, - GtkTooltip *tooltip, - ETagCalendar *tag_calendar) -{ - GDate date; - gint32 julian, events; - DateInfo *date_info; - gchar *msg; - - g_return_val_if_fail (E_IS_CALENDAR (calendar), FALSE); - g_return_val_if_fail (E_IS_TAG_CALENDAR (tag_calendar), FALSE); - g_return_val_if_fail (GTK_IS_TOOLTIP (tooltip), FALSE); - - if (!e_calendar_item_convert_position_to_date (calendar->calitem, x, y, &date)) - return FALSE; - - julian = encode_ymd_to_julian (g_date_get_year (&date), g_date_get_month (&date), g_date_get_day (&date)); - date_info = g_hash_table_lookup (tag_calendar->priv->dates, GINT_TO_POINTER (julian)); - - if (!date_info) - return FALSE; - - events = date_info->n_transparent + date_info->n_recurring + date_info->n_single; - - if (events <= 0) - return FALSE; - - msg = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE, "%d event", "%d events", events), events); - - gtk_tooltip_set_text (tooltip, msg); - - g_free (msg); - - return TRUE; -} - -static void -get_component_julian_range (ECalClient *client, - ECalComponent *comp, - guint32 *start_julian, - guint32 *end_julian) -{ - time_t instance_start = 0, instance_end = 0; - gboolean start_is_date = FALSE, end_is_date = FALSE; - const icaltimezone *zone; - - g_return_if_fail (client != NULL); - g_return_if_fail (comp != NULL); - - zone = calendar_config_get_icaltimezone (); - - cal_comp_get_instance_times (client, e_cal_component_get_icalcomponent (comp), - zone, &instance_start, &start_is_date, &instance_end, &end_is_date, NULL); - - *start_julian = encode_timet_to_julian (instance_start, start_is_date, zone); - *end_julian = encode_timet_to_julian (instance_end - 1, end_is_date, zone); -} - -static void -e_tag_calendar_update_by_oinfo (ETagCalendar *tag_calendar, - ObjectInfo *oinfo, - gboolean inc) -{ - ECalendarItem *calitem; - guint32 dt, start_julian, end_julian; - DateInfo *dinfo; - - g_return_if_fail (tag_calendar->priv->calitem != NULL); - - calitem = tag_calendar->priv->calitem; - g_return_if_fail (calitem != NULL); - - if (!oinfo) - return; - - start_julian = oinfo->start_julian; - end_julian = oinfo->end_julian; - - if (inc) { - if (start_julian < tag_calendar->priv->range_start_julian) - start_julian = tag_calendar->priv->range_start_julian; - - if (end_julian > tag_calendar->priv->range_end_julian) - end_julian = tag_calendar->priv->range_end_julian; - } - - for (dt = start_julian; dt <= end_julian; dt++) { - dinfo = g_hash_table_lookup (tag_calendar->priv->dates, GUINT_TO_POINTER (dt)); - - if (!dinfo) { - if (!inc) - continue; - - dinfo = date_info_new (); - g_hash_table_insert (tag_calendar->priv->dates, GUINT_TO_POINTER (dt), dinfo); - } - - if (date_info_update (dinfo, oinfo, inc)) { - gint year, month, day; - guint8 style; - - decode_julian (dt, &year, &month, &day); - style = date_info_get_style (dinfo, tag_calendar->priv->recur_events_italic); - - e_calendar_item_mark_day (calitem, year, month - 1, day, style, FALSE); - - if (!style && !inc) - g_hash_table_remove (tag_calendar->priv->dates, GUINT_TO_POINTER (dt)); - } - } -} - -static void -e_tag_calendar_update_component_dates (ETagCalendar *tag_calendar, - ObjectInfo *old_oinfo, - ObjectInfo *new_oinfo) -{ - g_return_if_fail (tag_calendar->priv->calitem != NULL); - - e_tag_calendar_update_by_oinfo (tag_calendar, old_oinfo, FALSE); - e_tag_calendar_update_by_oinfo (tag_calendar, new_oinfo, TRUE); -} - -static void -e_tag_calendar_data_subscriber_component_added (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - ETagCalendar *tag_calendar; - ECalComponentTransparency transparency; - guint32 start_julian = 0, end_julian = 0; - ObjectInfo *oinfo; - - g_return_if_fail (E_IS_TAG_CALENDAR (subscriber)); - - tag_calendar = E_TAG_CALENDAR (subscriber); - - get_component_julian_range (client, comp, &start_julian, &end_julian); - if (start_julian == 0 || end_julian == 0) - return; - - e_cal_component_get_transparency (comp, &transparency); - - oinfo = object_info_new (client, e_cal_component_get_id (comp), - transparency == E_CAL_COMPONENT_TRANSP_TRANSPARENT, - e_cal_component_is_instance (comp), - start_julian, end_julian); - - e_tag_calendar_update_component_dates (tag_calendar, NULL, oinfo); - - g_hash_table_insert (tag_calendar->priv->objects, oinfo, GINT_TO_POINTER (0)); -} - -static void -e_tag_calendar_data_subscriber_component_modified (ECalDataModelSubscriber *subscriber, - ECalClient *client, - ECalComponent *comp) -{ - ETagCalendar *tag_calendar; - ECalComponentTransparency transparency; - guint32 start_julian = 0, end_julian = 0; - gpointer orig_key, orig_value; - ObjectInfo *old_oinfo = NULL, *new_oinfo; - - g_return_if_fail (E_IS_TAG_CALENDAR (subscriber)); - - tag_calendar = E_TAG_CALENDAR (subscriber); - - get_component_julian_range (client, comp, &start_julian, &end_julian); - if (start_julian == 0 || end_julian == 0) - return; - - e_cal_component_get_transparency (comp, &transparency); - - new_oinfo = object_info_new (client, e_cal_component_get_id (comp), - transparency == E_CAL_COMPONENT_TRANSP_TRANSPARENT, - e_cal_component_is_instance (comp), - start_julian, end_julian); - - if (!g_hash_table_lookup_extended (tag_calendar->priv->objects, new_oinfo, &orig_key, &orig_value)) { - object_info_free (new_oinfo); - return; - } - - old_oinfo = orig_key; - - if (object_info_data_equal (old_oinfo, new_oinfo)) { - object_info_free (new_oinfo); - return; - } - - e_tag_calendar_update_component_dates (tag_calendar, old_oinfo, new_oinfo); - - /* it also frees old_oinfo */ - g_hash_table_insert (tag_calendar->priv->objects, new_oinfo, GINT_TO_POINTER (0)); -} - -static void -e_tag_calendar_data_subscriber_component_removed (ECalDataModelSubscriber *subscriber, - ECalClient *client, - const gchar *uid, - const gchar *rid) -{ - ETagCalendar *tag_calendar; - ECalComponentId id; - gpointer orig_key, orig_value; - ObjectInfo fake_oinfo, *old_oinfo; - - g_return_if_fail (E_IS_TAG_CALENDAR (subscriber)); - - tag_calendar = E_TAG_CALENDAR (subscriber); - - id.uid = (gchar *) uid; - id.rid = (gchar *) rid; - - /* only these two values are used for GHashTable compare */ - fake_oinfo.client = client; - fake_oinfo.id = &id; - - if (!g_hash_table_lookup_extended (tag_calendar->priv->objects, &fake_oinfo, &orig_key, &orig_value)) - return; - - old_oinfo = orig_key; - - e_tag_calendar_update_component_dates (tag_calendar, old_oinfo, NULL); - - g_hash_table_remove (tag_calendar->priv->objects, old_oinfo); -} - -static void -e_tag_calendar_data_subscriber_freeze (ECalDataModelSubscriber *subscriber) -{ - /* Ignore freezes here */ -} - -static void -e_tag_calendar_data_subscriber_thaw (ECalDataModelSubscriber *subscriber) -{ - /* Ignore freezes here */ -} - -static void -e_tag_calendar_set_calendar (ETagCalendar *tag_calendar, - ECalendar *calendar) -{ - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - g_return_if_fail (E_IS_CALENDAR (calendar)); - g_return_if_fail (calendar->calitem != NULL); - g_return_if_fail (tag_calendar->priv->calendar == NULL); - - tag_calendar->priv->calendar = calendar; - tag_calendar->priv->calitem = calendar->calitem; - - g_object_weak_ref (G_OBJECT (tag_calendar->priv->calendar), - (GWeakNotify) g_nullify_pointer, &tag_calendar->priv->calendar); - g_object_weak_ref (G_OBJECT (tag_calendar->priv->calitem), - (GWeakNotify) g_nullify_pointer, &tag_calendar->priv->calitem); -} - -static void -e_tag_calendar_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CALENDAR: - e_tag_calendar_set_calendar ( - E_TAG_CALENDAR (object), - g_value_get_object (value)); - return; - - case PROP_RECUR_EVENTS_ITALIC: - e_tag_calendar_set_recur_events_italic ( - E_TAG_CALENDAR (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_tag_calendar_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_CALENDAR: - g_value_set_object (value, - e_tag_calendar_get_calendar (E_TAG_CALENDAR (object))); - return; - - case PROP_RECUR_EVENTS_ITALIC: - g_value_set_boolean (value, - e_tag_calendar_get_recur_events_italic (E_TAG_CALENDAR (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -e_tag_calendar_constructed (GObject *object) -{ - ETagCalendar *tag_calendar = E_TAG_CALENDAR (object); - GSettings *settings; - - /* Chain up to parent's constructed() method. */ - G_OBJECT_CLASS (e_tag_calendar_parent_class)->constructed (object); - - g_return_if_fail (tag_calendar->priv->calendar != NULL); - g_return_if_fail (tag_calendar->priv->calitem != NULL); - - g_signal_connect_swapped (tag_calendar->priv->calitem, "date-range-changed", - G_CALLBACK (e_tag_calendar_date_range_changed_cb), tag_calendar); - - g_signal_connect (tag_calendar->priv->calendar, "query-tooltip", - G_CALLBACK (e_tag_calendar_query_tooltip_cb), tag_calendar); - - gtk_widget_set_has_tooltip (GTK_WIDGET (tag_calendar->priv->calendar), TRUE); - - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); - - g_settings_bind ( - settings, "recur-events-italic", - tag_calendar, "recur-events-italic", - G_SETTINGS_BIND_DEFAULT | G_SETTINGS_BIND_NO_SENSITIVITY); - - g_object_unref (settings); -} - -static void -e_tag_calendar_dispose (GObject *object) -{ - ETagCalendar *tag_calendar = E_TAG_CALENDAR (object); - - if (tag_calendar->priv->calendar != NULL) { - g_signal_handlers_disconnect_by_func (tag_calendar->priv->calendar->calitem, - G_CALLBACK (e_tag_calendar_date_range_changed_cb), tag_calendar); - g_signal_handlers_disconnect_by_func (tag_calendar->priv->calendar, - G_CALLBACK (e_tag_calendar_query_tooltip_cb), tag_calendar); - g_object_weak_unref (G_OBJECT (tag_calendar->priv->calendar), - (GWeakNotify) g_nullify_pointer, &tag_calendar->priv->calendar); - tag_calendar->priv->calendar = NULL; - } - - if (tag_calendar->priv->calitem != NULL) { - g_object_weak_unref (G_OBJECT (tag_calendar->priv->calitem), - (GWeakNotify) g_nullify_pointer, &tag_calendar->priv->calitem); - tag_calendar->priv->calitem = NULL; - } - - if (tag_calendar->priv->data_model) - e_tag_calendar_unsubscribe (tag_calendar, tag_calendar->priv->data_model); - - /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (e_tag_calendar_parent_class)->dispose (object); -} - -static void -e_tag_calendar_finalize (GObject *object) -{ - ETagCalendar *tag_calendar = E_TAG_CALENDAR (object); - - g_warn_if_fail (tag_calendar->priv->data_model == NULL); - - g_hash_table_destroy (tag_calendar->priv->objects); - g_hash_table_destroy (tag_calendar->priv->dates); - - /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (e_tag_calendar_parent_class)->finalize (object); -} - -static void -e_tag_calendar_class_init (ETagCalendarClass *class) -{ - GObjectClass *object_class; - - g_type_class_add_private (class, sizeof (ETagCalendarPrivate)); - - object_class = G_OBJECT_CLASS (class); - object_class->set_property = e_tag_calendar_set_property; - object_class->get_property = e_tag_calendar_get_property; - object_class->constructed = e_tag_calendar_constructed; - object_class->dispose = e_tag_calendar_dispose; - object_class->finalize = e_tag_calendar_finalize; - - g_object_class_install_property ( - object_class, - PROP_CALENDAR, - g_param_spec_object ( - "calendar", - "Calendar", - NULL, - E_TYPE_CALENDAR, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - - g_object_class_install_property ( - object_class, - PROP_RECUR_EVENTS_ITALIC, - g_param_spec_boolean ( - "recur-events-italic", - "Recur Events Italic", - NULL, - FALSE, - G_PARAM_READWRITE)); -} - -static void -e_tag_calendar_cal_data_model_subscriber_init (ECalDataModelSubscriberInterface *iface) -{ - iface->component_added = e_tag_calendar_data_subscriber_component_added; - iface->component_modified = e_tag_calendar_data_subscriber_component_modified; - iface->component_removed = e_tag_calendar_data_subscriber_component_removed; - iface->freeze = e_tag_calendar_data_subscriber_freeze; - iface->thaw = e_tag_calendar_data_subscriber_thaw; -} - -static void -e_tag_calendar_init (ETagCalendar *tag_calendar) -{ - tag_calendar->priv = G_TYPE_INSTANCE_GET_PRIVATE (tag_calendar, E_TYPE_TAG_CALENDAR, ETagCalendarPrivate); - - tag_calendar->priv->objects = g_hash_table_new_full ( - object_info_hash, - object_info_equal, - object_info_free, - g_free); - - tag_calendar->priv->dates = g_hash_table_new_full ( - g_direct_hash, - g_direct_equal, - NULL, - date_info_free); -} - -ETagCalendar * -e_tag_calendar_new (ECalendar *calendar) -{ - return g_object_new (E_TYPE_TAG_CALENDAR, "calendar", calendar, NULL); -} - -ECalendar * -e_tag_calendar_get_calendar (ETagCalendar *tag_calendar) -{ - g_return_val_if_fail (E_IS_TAG_CALENDAR (tag_calendar), NULL); - - return tag_calendar->priv->calendar; -} - -gboolean -e_tag_calendar_get_recur_events_italic (ETagCalendar *tag_calendar) -{ - g_return_val_if_fail (E_IS_TAG_CALENDAR (tag_calendar), FALSE); - - return tag_calendar->priv->recur_events_italic; -} - -void -e_tag_calendar_set_recur_events_italic (ETagCalendar *tag_calendar, - gboolean recur_events_italic) -{ - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - - if ((tag_calendar->priv->recur_events_italic ? 1 : 0) == (recur_events_italic ? 1 : 0)) - return; - - tag_calendar->priv->recur_events_italic = recur_events_italic; - - g_object_notify (G_OBJECT (tag_calendar), "recur-events-italic"); - - e_tag_calendar_remark_days (tag_calendar); -} - -void -e_tag_calendar_subscribe (ETagCalendar *tag_calendar, - ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (tag_calendar->priv->data_model != data_model); - - /* if the reference is held by the priv->data_model, then - an unsubscribe may cause free of the tag_calendar */ - g_object_ref (tag_calendar); - - if (tag_calendar->priv->data_model) - e_tag_calendar_unsubscribe (tag_calendar, tag_calendar->priv->data_model); - - tag_calendar->priv->data_model = data_model; - e_tag_calendar_date_range_changed_cb (tag_calendar); - - g_object_unref (tag_calendar); -} - -void -e_tag_calendar_unsubscribe (ETagCalendar *tag_calendar, - ECalDataModel *data_model) -{ - g_return_if_fail (E_IS_TAG_CALENDAR (tag_calendar)); - g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model)); - g_return_if_fail (tag_calendar->priv->data_model == data_model); - - e_cal_data_model_unsubscribe (data_model, E_CAL_DATA_MODEL_SUBSCRIBER (tag_calendar)); - tag_calendar->priv->data_model = NULL; - - /* calitem can be NULL during dispose of an ECalBaseShellContents */ - if (tag_calendar->priv->calitem) - e_calendar_item_clear_marks (tag_calendar->priv->calitem); - - g_hash_table_remove_all (tag_calendar->priv->objects); - g_hash_table_remove_all (tag_calendar->priv->dates); -} - struct calendar_tag_closure { ECalendarItem *calitem; icaltimezone *zone; @@ -961,6 +127,51 @@ return TRUE; } +/** + * tag_calendar_by_client: + * @ecal: Calendar widget to tag. + * @client: A calendar client object. + * @cancellable: A #GCancellable; can be %NULL + * + * Tags an #ECalendar widget with the events that occur in its current time + * range. The occurrences are extracted from the specified calendar @client. + **/ +void +tag_calendar_by_client (ECalendar *ecal, + ECalClient *client, + GCancellable *cancellable) +{ + GSettings *settings; + struct calendar_tag_closure *closure; + + g_return_if_fail (E_IS_CALENDAR (ecal)); + g_return_if_fail (E_IS_CAL_CLIENT (client)); + + /* If the ECalendar isn't visible, we just return. */ + if (!gtk_widget_get_visible (GTK_WIDGET (ecal))) + return; + + closure = g_new0 (struct calendar_tag_closure, 1); + + if (!prepare_tag (ecal, closure, NULL, TRUE)) { + g_free (closure); + return; + } + + settings = g_settings_new ("org.gnome.evolution.calendar"); + + closure->skip_transparent_events = TRUE; + closure->recur_events_italic = + g_settings_get_boolean (settings, "recur-events-italic"); + + g_object_unref (settings); + + e_cal_client_generate_instances ( + client, closure->start_time, closure->end_time, cancellable, + (ECalRecurInstanceFn) tag_calendar_cb, + closure, (GDestroyNotify) g_free); +} + /* Resolves TZIDs for the recurrence generator, for when the comp is not on * the server. We need to try to use builtin timezones first, as they may not * be added to the server yet. */ @@ -1028,7 +239,7 @@ if (!prepare_tag (ecal, &closure, display_zone, clear_first)) return; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); closure.skip_transparent_events = FALSE; closure.recur_events_italic = diff -Nru evolution-3.16.0/calendar/gui/tag-calendar.h evolution-3.12.11/calendar/gui/tag-calendar.h --- evolution-3.16.0/calendar/gui/tag-calendar.h 2014-11-13 07:24:17.000000000 +0000 +++ evolution-3.12.11/calendar/gui/tag-calendar.h 2014-03-24 09:25:23.000000000 +0000 @@ -28,66 +28,11 @@ #include #include -#include -/* Standard GObject macros */ -#define E_TYPE_TAG_CALENDAR \ - (e_tag_calendar_get_type ()) -#define E_TAG_CALENDAR(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST \ - ((obj), E_TYPE_TAG_CALENDAR, ETagCalendar)) -#define E_TAG_CALENDAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_CAST \ - ((cls), E_TYPE_TAG_CALENDAR, ETagCalendarClass)) -#define E_IS_TAG_CALENDAR(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE \ - ((obj), E_TYPE_TAG_CALENDAR)) -#define E_IS_TAG_CALENDAR_CLASS(cls) \ - (G_TYPE_CHECK_CLASS_TYPE \ - ((cls), E_TYPE_TAG_CALENDAR)) -#define E_TAG_CALENDAR_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS \ - ((obj), E_TYPE_TAG_CALENDAR, ETagCalendarClass)) - -G_BEGIN_DECLS - -typedef struct _ETagCalendar ETagCalendar; -typedef struct _ETagCalendarClass ETagCalendarClass; -typedef struct _ETagCalendarPrivate ETagCalendarPrivate; - -struct _ETagCalendar { - GObject parent; - ETagCalendarPrivate *priv; -}; - -struct _ETagCalendarClass { - GObjectClass parent_class; -}; - -GType e_tag_calendar_get_type (void); - -ETagCalendar * e_tag_calendar_new (ECalendar *calendar); -ECalendar * e_tag_calendar_get_calendar (ETagCalendar *tag_calendar); -gboolean e_tag_calendar_get_recur_events_italic - (ETagCalendar *tag_calendar); -void e_tag_calendar_set_recur_events_italic - (ETagCalendar *tag_calendar, - gboolean recur_events_italic); -void e_tag_calendar_subscribe (ETagCalendar *tag_calendar, - ECalDataModel *data_model); -void e_tag_calendar_unsubscribe (ETagCalendar *tag_calendar, - ECalDataModel *data_model); - - -void tag_calendar_by_comp (ECalendar *ecal, - ECalComponent *comp, - ECalClient *client, - icaltimezone *display_zone, - gboolean clear_first, - gboolean comp_is_on_server, - gboolean can_recur_events_italic, - GCancellable *cancellable); - -G_END_DECLS +void tag_calendar_by_client (ECalendar *ecal, ECalClient *client, GCancellable *cancellable); +void tag_calendar_by_comp (ECalendar *ecal, ECalComponent *comp, + ECalClient *client, icaltimezone *display_zone, + gboolean clear_first, gboolean comp_is_on_server, + gboolean can_recur_events_italic, GCancellable *cancellable); #endif diff -Nru evolution-3.16.0/calendar/importers/icalendar-importer.c evolution-3.12.11/calendar/importers/icalendar-importer.c --- evolution-3.16.0/calendar/importers/icalendar-importer.c 2015-02-25 15:31:40.000000000 +0000 +++ evolution-3.12.11/calendar/importers/icalendar-importer.c 2014-04-23 12:36:24.000000000 +0000 @@ -309,9 +309,11 @@ /* Type of icalendar items */ for (i = 0; import_type_map[i] != -1; i++) { GtkWidget *selector, *rb; + ESource *source = NULL; GtkWidget *scrolled; struct _selector_data *sd; const gchar *extension_name; + GList *list; switch (import_type_map[i]) { case E_CAL_CLIENT_SOURCE_TYPE_EVENTS: @@ -333,6 +335,15 @@ gtk_container_add ((GtkContainer *) scrolled, selector); gtk_notebook_append_page (GTK_NOTEBOOK (nb), scrolled, NULL); + list = e_source_registry_list_sources (registry, extension_name); + if (list != NULL) { + source = E_SOURCE (list->data); + e_source_selector_set_primary_selection ( + E_SOURCE_SELECTOR (selector), source); + } + + g_list_free_full (list, (GDestroyNotify) g_object_unref); + g_signal_connect ( selector, "primary_selection_changed", G_CALLBACK (primary_selection_changed_cb), target); @@ -352,9 +363,8 @@ if (!group) group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (rb)); - if (first == NULL) { - /* Set primary-source */ - primary_selection_changed_cb (E_SOURCE_SELECTOR (selector), target); + if (first == NULL && source != NULL) { + g_datalist_set_data_full (&target->data, "primary-source", g_object_ref (source), g_object_unref); g_datalist_set_data (&target->data, "primary-type", GINT_TO_POINTER (import_type_map[i])); first = rb; } @@ -453,7 +463,7 @@ e_cal_client_connect ( g_datalist_get_data (&target->data, "primary-source"), - type, 30, ici->cancellable, ivcal_connect_cb, ici); + type, ici->cancellable, ivcal_connect_cb, ici); } static void @@ -891,7 +901,7 @@ e_import_status (ici->ei, ici->target, _("Opening calendar"), 0); e_cal_client_connect ( - source, source_type, 30, ici->cancellable, + source, source_type, ici->cancellable, default_client_connect_cb, odsd); g_object_unref (source); @@ -1042,7 +1052,7 @@ GSettings *settings; gboolean done_cal, done_tasks; - settings = e_util_ref_settings ("org.gnome.evolution.importer"); + settings = g_settings_new ("org.gnome.evolution.importer"); done_cal = g_settings_get_boolean (settings, "gnome-calendar-done-calendar"); done_tasks = g_settings_get_boolean (settings, "gnome-calendar-done-tasks"); g_object_unref (settings); @@ -1395,7 +1405,7 @@ icaltimezone *zone = NULL; gchar *location; - settings = e_util_ref_settings ("org.gnome.evolution.calendar"); + settings = g_settings_new ("org.gnome.evolution.calendar"); if (g_settings_get_boolean (settings, "use-system-timezone")) { location = e_cal_util_get_system_timezone_location (); diff -Nru evolution-3.16.0/calendar/importers/Makefile.am evolution-3.12.11/calendar/importers/Makefile.am --- evolution-3.16.0/calendar/importers/Makefile.am 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/calendar/importers/Makefile.am 2014-03-24 09:25:23.000000000 +0000 @@ -9,20 +9,19 @@ -I$(top_builddir)/calendar \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libevolution_calendar_importers_la_SOURCES = \ evolution-calendar-importer.h \ icalendar-importer.c -libevolution_calendar_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_calendar_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libevolution_calendar_importers_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) -include $(top_srcdir)/git.mk diff -Nru evolution-3.16.0/calendar/importers/Makefile.in evolution-3.12.11/calendar/importers/Makefile.in --- evolution-3.16.0/calendar/importers/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/calendar/importers/Makefile.in 2015-02-09 08:21:54.000000000 +0000 @@ -84,7 +84,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -132,7 +131,8 @@ libevolution_calendar_importers_la_DEPENDENCIES = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) am_libevolution_calendar_importers_la_OBJECTS = \ libevolution_calendar_importers_la-icalendar-importer.lo libevolution_calendar_importers_la_OBJECTS = \ @@ -215,14 +215,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -235,9 +232,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -251,8 +245,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -263,7 +255,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -290,6 +281,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -313,13 +308,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ @@ -465,20 +457,19 @@ -I$(top_builddir)/calendar \ $(EVOLUTION_DATA_SERVER_CFLAGS) \ $(GNOME_PLATFORM_CFLAGS) \ - $(CODE_COVERAGE_CFLAGS) \ - $(NULL) + $(GTKHTML_CFLAGS) libevolution_calendar_importers_la_SOURCES = \ evolution-calendar-importer.h \ icalendar-importer.c -libevolution_calendar_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) $(CODE_COVERAGE_LDFLAGS) +libevolution_calendar_importers_la_LDFLAGS = -avoid-version $(NO_UNDEFINED) libevolution_calendar_importers_la_LIBADD = \ $(top_builddir)/e-util/libevolution-util.la \ $(top_builddir)/shell/libevolution-shell.la \ $(EVOLUTION_DATA_SERVER_LIBS) \ $(GNOME_PLATFORM_LIBS) \ - $(NULL) + $(GTKHTML_LIBS) all: all-am @@ -562,25 +553,22 @@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libevolution_calendar_importers_la-icalendar-importer.Plo@am__quote@ .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< diff -Nru evolution-3.16.0/calendar/Makefile.in evolution-3.12.11/calendar/Makefile.in --- evolution-3.16.0/calendar/Makefile.in 2015-03-23 06:59:17.000000000 +0000 +++ evolution-3.12.11/calendar/Makefile.in 2015-02-09 08:21:54.000000000 +0000 @@ -83,7 +83,6 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/as-ac-expand.m4 \ $(top_srcdir)/m4/as-compiler-flag.m4 \ - $(top_srcdir)/m4/behave-installed-tests.m4 \ $(top_srcdir)/m4/evo_check_langinfo.m4 \ $(top_srcdir)/m4/evo_ldap_check.m4 \ $(top_srcdir)/m4/evo_purify_support.m4 \ @@ -217,14 +216,11 @@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ AR = @AR@ AS = @AS@ -AUTOAR_CFLAGS = @AUTOAR_CFLAGS@ -AUTOAR_LIBS = @AUTOAR_LIBS@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASE_VERSION = @BASE_VERSION@ -BEHAVE_INSTALLED_TESTS_ENABLED = @BEHAVE_INSTALLED_TESTS_ENABLED@ BOGOFILTER = @BOGOFILTER@ CANBERRA_CFLAGS = @CANBERRA_CFLAGS@ CANBERRA_LIBS = @CANBERRA_LIBS@ @@ -237,9 +233,6 @@ CHAMPLAIN_LIBS = @CHAMPLAIN_LIBS@ CLUTTER_GTK_CFLAGS = @CLUTTER_GTK_CFLAGS@ CLUTTER_GTK_LIBS = @CLUTTER_GTK_LIBS@ -CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ -CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ -CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CYGPATH_W = @CYGPATH_W@ @@ -253,8 +246,6 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ -ENCHANT_CFLAGS = @ENCHANT_CFLAGS@ -ENCHANT_LIBS = @ENCHANT_LIBS@ EVOLUTION_DATA_SERVER_CFLAGS = @EVOLUTION_DATA_SERVER_CFLAGS@ EVOLUTION_DATA_SERVER_LIBS = @EVOLUTION_DATA_SERVER_LIBS@ EVOLUTION_DIR = @EVOLUTION_DIR@ @@ -265,7 +256,6 @@ FGREP = @FGREP@ GDATA_CFLAGS = @GDATA_CFLAGS@ GDATA_LIBS = @GDATA_LIBS@ -GENHTML = @GENHTML@ GEO_CFLAGS = @GEO_CFLAGS@ GEO_LIBS = @GEO_LIBS@ GETTEXT_PACKAGE = @GETTEXT_PACKAGE@ @@ -292,6 +282,10 @@ GTKDOC_DEPS_LIBS = @GTKDOC_DEPS_LIBS@ GTKDOC_MKPDF = @GTKDOC_MKPDF@ GTKDOC_REBASE = @GTKDOC_REBASE@ +GTKHTML_CFLAGS = @GTKHTML_CFLAGS@ +GTKHTML_LIBS = @GTKHTML_LIBS@ +GTKIMAGEVIEW_CFLAGS = @GTKIMAGEVIEW_CFLAGS@ +GTKIMAGEVIEW_LIBS = @GTKIMAGEVIEW_LIBS@ GTKSPELL_CFLAGS = @GTKSPELL_CFLAGS@ GTKSPELL_LIBS = @GTKSPELL_LIBS@ GWEATHER_CFLAGS = @GWEATHER_CFLAGS@ @@ -315,13 +309,10 @@ INTLTOOL__v_MERGE_0 = @INTLTOOL__v_MERGE_0@ ITSTOOL = @ITSTOOL@ KILL_PROCESS_CMD = @KILL_PROCESS_CMD@ -LCOV = @LCOV@ LD = @LD@ LDAP_CFLAGS = @LDAP_CFLAGS@ LDAP_LIBS = @LDAP_LIBS@ LDFLAGS = @LDFLAGS@ -LIBCRYPTUI_CFLAGS = @LIBCRYPTUI_CFLAGS@ -LIBCRYPTUI_LIBS = @LIBCRYPTUI_LIBS@ LIBNOTIFY_CFLAGS = @LIBNOTIFY_CFLAGS@ LIBNOTIFY_LIBS = @LIBNOTIFY_LIBS@ LIBOBJS = @LIBOBJS@ diff -Nru evolution-3.16.0/ChangeLog evolution-3.12.11/ChangeLog --- evolution-3.16.0/ChangeLog 2015-03-23 06:48:33.000000000 +0000 +++ evolution-3.12.11/ChangeLog 2014-04-23 12:36:23.000000000 +0000 @@ -4,4 +4,4 @@ Get a clone of git repository and list changes with 'git log' there, $ git clone git://git.gnome.org/evolution or browse changes online at - http://git.gnome.org/browse/evolution/log/?h=gnome-3-16 + http://git.gnome.org/browse/evolution/log/?h=evolution-3-12 diff -Nru evolution-3.16.0/composer/e-composer-actions.c evolution-3.12.11/composer/e-composer-actions.c --- evolution-3.16.0/composer/e-composer-actions.c 2015-03-20 07:04:49.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-actions.c 2014-03-24 09:25:23.000000000 +0000 @@ -22,64 +22,9 @@ #include "e-composer-actions.h" #include "e-composer-private.h" -#include - #include #include -/* because 'composer' is compiled before 'mail' folder */ -static gboolean -composer_copy_em_utils_prompt_user (GtkWindow *parent, - const gchar *promptkey, - const gchar *tag, - ...) -{ - GtkWidget *dialog; - GtkWidget *check = NULL; - GtkWidget *container; - va_list ap; - gint button; - GSettings *settings; - EAlert *alert = NULL; - - settings = e_util_ref_settings ("org.gnome.evolution.mail"); - - if (promptkey && !g_settings_get_boolean (settings, promptkey)) { - g_object_unref (settings); - return TRUE; - } - - va_start (ap, tag); - alert = e_alert_new_valist (tag, ap); - va_end (ap); - - dialog = e_alert_dialog_new (parent, alert); - g_object_unref (alert); - - container = e_alert_dialog_get_content_area (E_ALERT_DIALOG (dialog)); - - if (promptkey) { - check = gtk_check_button_new_with_mnemonic ( - _("_Do not show this message again")); - gtk_box_pack_start ( - GTK_BOX (container), check, FALSE, FALSE, 0); - gtk_widget_show (check); - } - - button = gtk_dialog_run (GTK_DIALOG (dialog)); - if (promptkey) - g_settings_set_boolean ( - settings, promptkey, - !gtk_toggle_button_get_active ( - GTK_TOGGLE_BUTTON (check))); - - gtk_widget_destroy (dialog); - - g_object_unref (settings); - - return button == GTK_RESPONSE_YES; -} - static void action_attach_cb (GtkAction *action, EMsgComposer *composer) @@ -134,24 +79,20 @@ action_pgp_encrypt_cb (GtkToggleAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static void action_pgp_sign_cb (GtkToggleAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static void @@ -202,14 +143,12 @@ action_save_cb (GtkAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor = GTKHTML_EDITOR (composer); const gchar *filename; gint fd; GError *error = NULL; - editor = e_msg_composer_get_editor (composer); - filename = e_html_editor_get_filename (editor); + filename = gtkhtml_editor_get_filename (editor); if (filename == NULL) { gtk_action_activate (ACTION (SAVE_AS)); return; @@ -239,7 +178,7 @@ } else close (fd); - if (!e_html_editor_save (editor, filename, TRUE, &error)) { + if (!gtkhtml_editor_save (editor, filename, TRUE, &error)) { e_alert_submit ( E_ALERT_SINK (composer), E_ALERT_NO_SAVE_FILE, @@ -248,15 +187,13 @@ return; } - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + gtkhtml_editor_run_command (GTKHTML_EDITOR (composer), "saved"); } static void action_save_as_cb (GtkAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; GtkWidget *dialog; gchar *filename; gint response; @@ -280,9 +217,8 @@ if (response != GTK_RESPONSE_OK) goto exit; - editor = e_msg_composer_get_editor (composer); filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); - e_html_editor_set_filename (editor, filename); + gtkhtml_editor_set_filename (GTKHTML_EDITOR (composer), filename); g_free (filename); gtk_action_activate (ACTION (SAVE)); @@ -309,68 +245,20 @@ action_smime_encrypt_cb (GtkToggleAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static void action_smime_sign_cb (GtkToggleAction *action, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); -} - -static void -action_unicode_smileys_cb (GtkToggleAction *action, - EMsgComposer *composer) -{ - EHTMLEditor *editor; - EHTMLEditorView *view; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_unicode_smileys (view, - gtk_toggle_action_get_active (action)); -} - -static void -composer_actions_toolbar_option_toggled_cb (GtkToggleAction *toggle_action, - EMsgComposer *composer) -{ - GtkAction *action; - - action = GTK_ACTION (toggle_action); + GtkhtmlEditor *editor; - /* Show the action only after the first time the option is used */ - if (!gtk_action_get_visible (action) && - gtk_toggle_action_get_active (toggle_action)) - gtk_action_set_visible (action, TRUE); -} - -static gboolean -composer_actions_accel_activate_cb (GtkAccelGroup *accel_group, - GObject *acceleratable, - guint keyval, - GdkModifierType modifier, - gpointer user_data) -{ - EMsgComposer *composer = user_data; - - if (keyval == GDK_KEY_Return && (modifier & GDK_MODIFIER_MASK) == GDK_CONTROL_MASK && - !composer_copy_em_utils_prompt_user (GTK_WINDOW (composer), "prompt-on-accel-send", - "mail-composer:prompt-accel-send", NULL)) { - return TRUE; - } - return FALSE; + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static GtkActionEntry entries[] = { @@ -523,62 +411,6 @@ G_CALLBACK (action_smime_sign_cb), FALSE }, - { "toolbar-pgp-encrypt", - "security-high", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "toolbar-pgp-sign", - "stock_signature", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "toolbar-prioritize-message", - "emblem-important", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "toolbar-request-read-receipt", - "mail-forward", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "toolbar-smime-encrypt", - "security-high", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "toolbar-smime-sign", - "stock_signature", - NULL, - NULL, - NULL, - NULL, - FALSE }, - - { "unicode-smileys", - NULL, - N_("Unicode smileys"), - NULL, - N_("Use Unicode characters for smileys."), - G_CALLBACK (action_unicode_smileys_cb), - FALSE }, - { "view-bcc", NULL, N_("_Bcc Field"), @@ -595,39 +427,29 @@ NULL, /* Handled by property bindings */ FALSE }, - { "view-from-override", - NULL, - N_("_From Override Field"), - NULL, - N_("Toggles whether the From override field to change name or email address is displayed"), - NULL, /* Handled by property bindings */ - FALSE }, - { "view-reply-to", NULL, N_("_Reply-To Field"), NULL, N_("Toggles whether the Reply-To field is displayed"), NULL, /* Handled by property bindings */ - FALSE } + FALSE }, }; void e_composer_actions_init (EMsgComposer *composer) { GtkActionGroup *action_group; - GtkAccelGroup *accel_group; GtkUIManager *ui_manager; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; + EWebViewGtkHTML *web_view; gboolean visible; - GIcon *gcr_gnupg_icon; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - ui_manager = e_html_editor_get_ui_manager (editor); + editor = GTKHTML_EDITOR (composer); + web_view = e_msg_composer_get_web_view (composer); + ui_manager = gtkhtml_editor_get_ui_manager (editor); /* Composer Actions */ action_group = composer->priv->composer_actions; @@ -670,94 +492,24 @@ g_object_set ( ACTION (SAVE_DRAFT), "short-label", _("Save Draft"), NULL); - #define init_toolbar_option(x, always_visible) \ - gtk_action_set_visible (ACTION (TOOLBAR_ ## x), always_visible); \ - e_binding_bind_property ( \ - ACTION (x), "active", \ - ACTION (TOOLBAR_ ## x), "active", \ - G_BINDING_SYNC_CREATE | G_BINDING_BIDIRECTIONAL); \ - e_binding_bind_property ( \ - ACTION (x), "label", \ - ACTION (TOOLBAR_ ## x), "label", \ - G_BINDING_SYNC_CREATE); \ - e_binding_bind_property ( \ - ACTION (x), "tooltip", \ - ACTION (TOOLBAR_ ## x), "tooltip", \ - G_BINDING_SYNC_CREATE); \ - e_binding_bind_property ( \ - ACTION (x), "sensitive", \ - ACTION (TOOLBAR_ ## x), "sensitive", \ - G_BINDING_SYNC_CREATE); \ - g_signal_connect (ACTION (TOOLBAR_ ## x), "toggled", \ - G_CALLBACK (composer_actions_toolbar_option_toggled_cb), composer); - - init_toolbar_option (PGP_SIGN, FALSE); - init_toolbar_option (PGP_ENCRYPT, FALSE); - init_toolbar_option (PRIORITIZE_MESSAGE, TRUE); - init_toolbar_option (REQUEST_READ_RECEIPT, TRUE); - init_toolbar_option (SMIME_SIGN, FALSE); - init_toolbar_option (SMIME_ENCRYPT, FALSE); - - #undef init_toolbar_option - - /* Borrow a GnuPG icon from gcr to distinguish between GPG and S/MIME Sign/Encrypt actions */ - gcr_gnupg_icon = g_themed_icon_new ("gcr-gnupg"); - if (gcr_gnupg_icon) { - GIcon *temp_icon; - GIcon *action_icon; - GEmblem *emblem; - GtkAction *action; - - emblem = g_emblem_new (gcr_gnupg_icon); - - action = ACTION (TOOLBAR_PGP_SIGN); - action_icon = g_themed_icon_new (gtk_action_get_icon_name (action)); - temp_icon = g_emblemed_icon_new (action_icon, emblem); - g_object_unref (action_icon); - - gtk_action_set_gicon (action, temp_icon); - g_object_unref (temp_icon); - - action = ACTION (TOOLBAR_PGP_ENCRYPT); - action_icon = g_themed_icon_new (gtk_action_get_icon_name (action)); - temp_icon = g_emblemed_icon_new (action_icon, emblem); - g_object_unref (action_icon); - - gtk_action_set_gicon (action, temp_icon); - g_object_unref (temp_icon); - - g_object_unref (emblem); - g_object_unref (gcr_gnupg_icon); - } - - e_binding_bind_property ( - view, "html-mode", + g_object_bind_property ( + composer, "html-mode", ACTION (PICTURE_GALLERY), "sensitive", G_BINDING_SYNC_CREATE); - e_binding_bind_property ( - view, "editable", - e_html_editor_get_action (editor, "edit-menu"), "sensitive", + g_object_bind_property ( + web_view, "editable", + GTKHTML_EDITOR_ACTION_EDIT_MENU (editor), "sensitive", G_BINDING_SYNC_CREATE); - e_binding_bind_property ( - view, "editable", - e_html_editor_get_action (editor, "format-menu"), "sensitive", + g_object_bind_property ( + web_view, "editable", + GTKHTML_EDITOR_ACTION_FORMAT_MENU (editor), "sensitive", G_BINDING_SYNC_CREATE); - e_binding_bind_property ( - view, "editable", - e_html_editor_get_action (editor, "insert-menu"), "sensitive", - G_BINDING_SYNC_CREATE); - - e_binding_bind_property ( - view, "editable", - e_html_editor_get_action (editor, "options-menu"), "sensitive", - G_BINDING_SYNC_CREATE); - - e_binding_bind_property ( - view, "editable", - e_html_editor_get_action (editor, "picture-gallery"), "sensitive", + g_object_bind_property ( + web_view, "editable", + GTKHTML_EDITOR_ACTION_INSERT_MENU (editor), "sensitive", G_BINDING_SYNC_CREATE); #if defined (HAVE_NSS) @@ -768,8 +520,4 @@ gtk_action_set_visible (ACTION (SMIME_ENCRYPT), visible); gtk_action_set_visible (ACTION (SMIME_SIGN), visible); - - accel_group = gtk_ui_manager_get_accel_group (ui_manager); - g_signal_connect (accel_group, "accel-activate", - G_CALLBACK (composer_actions_accel_activate_cb), composer); } diff -Nru evolution-3.16.0/composer/e-composer-actions.h evolution-3.12.11/composer/e-composer-actions.h --- evolution-3.16.0/composer/e-composer-actions.h 2015-02-25 12:48:56.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-actions.h 2014-03-24 09:25:23.000000000 +0000 @@ -18,9 +18,7 @@ #define E_COMPOSER_ACTIONS_H #define E_COMPOSER_ACTION(composer, name) \ - (e_html_editor_get_action ( \ - e_msg_composer_get_editor ( \ - E_MSG_COMPOSER (composer)), (name))) + (gtkhtml_editor_get_action (GTKHTML_EDITOR (composer), (name))) #define E_COMPOSER_ACTION_ATTACH(composer) \ E_COMPOSER_ACTION ((composer), "attach") @@ -56,26 +54,10 @@ E_COMPOSER_ACTION ((composer), "smime-encrypt") #define E_COMPOSER_ACTION_SMIME_SIGN(composer) \ E_COMPOSER_ACTION ((composer), "smime-sign") -#define E_COMPOSER_ACTION_TOOLBAR_PGP_ENCRYPT(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-pgp-encrypt") -#define E_COMPOSER_ACTION_TOOLBAR_PGP_SIGN(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-pgp-sign") -#define E_COMPOSER_ACTION_TOOLBAR_PRIORITIZE_MESSAGE(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-prioritize-message") -#define E_COMPOSER_ACTION_TOOLBAR_REQUEST_READ_RECEIPT(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-request-read-receipt") -#define E_COMPOSER_ACTION_TOOLBAR_SMIME_ENCRYPT(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-smime-encrypt") -#define E_COMPOSER_ACTION_TOOLBAR_SMIME_SIGN(composer) \ - E_COMPOSER_ACTION ((composer), "toolbar-smime-sign") -#define E_COMPOSER_ACTION_UNICODE_SMILEYS(composer) \ - E_COMPOSER_ACTION ((composer), "unicode-smileys") #define E_COMPOSER_ACTION_VIEW_BCC(composer) \ E_COMPOSER_ACTION ((composer), "view-bcc") #define E_COMPOSER_ACTION_VIEW_CC(composer) \ E_COMPOSER_ACTION ((composer), "view-cc") -#define E_COMPOSER_ACTION_VIEW_FROM_OVERRIDE(composer) \ - E_COMPOSER_ACTION ((composer), "view-from-override") #define E_COMPOSER_ACTION_VIEW_REPLY_TO(composer) \ E_COMPOSER_ACTION ((composer), "view-reply-to") diff -Nru evolution-3.16.0/composer/e-composer-activity.c evolution-3.12.11/composer/e-composer-activity.c --- evolution-3.16.0/composer/e-composer-activity.c 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-activity.c 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,187 @@ +/* + * e-composer-activity.c + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "e-composer-private.h" + +#define E_COMPOSER_ACTIVITY_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_COMPOSER_ACTIVITY, EComposerActivityPrivate)) + +struct _EComposerActivityPrivate { + EMsgComposer *composer; + gboolean saved_editable; +}; + +enum { + PROP_0, + PROP_COMPOSER +}; + +G_DEFINE_TYPE ( + EComposerActivity, + e_composer_activity, + E_TYPE_ACTIVITY) + +static void +composer_activity_lock_interface (EComposerActivity *activity) +{ + GtkActionGroup *action_group; + EMsgComposer *composer; + EWebViewGtkHTML *web_view; + gboolean editable; + + composer = e_composer_activity_get_composer (activity); + + web_view = e_msg_composer_get_web_view (composer); + editable = e_web_view_gtkhtml_get_editable (web_view); + e_web_view_gtkhtml_set_editable (web_view, FALSE); + activity->priv->saved_editable = editable; + + action_group = composer->priv->async_actions; + gtk_action_group_set_sensitive (action_group, FALSE); +} + +static void +composer_activity_unlock_interface (EComposerActivity *activity) +{ + GtkActionGroup *action_group; + EMsgComposer *composer; + EWebViewGtkHTML *web_view; + gboolean editable; + + composer = e_composer_activity_get_composer (activity); + + editable = activity->priv->saved_editable; + web_view = e_msg_composer_get_web_view (composer); + e_web_view_gtkhtml_set_editable (web_view, editable); + + action_group = composer->priv->async_actions; + gtk_action_group_set_sensitive (action_group, TRUE); +} + +static void +composer_activity_set_composer (EComposerActivity *activity, + EMsgComposer *composer) +{ + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + g_return_if_fail (activity->priv->composer == NULL); + + activity->priv->composer = g_object_ref (composer); + + composer_activity_lock_interface (activity); +} + +static void +composer_activity_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_COMPOSER: + composer_activity_set_composer ( + E_COMPOSER_ACTIVITY (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +composer_activity_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_COMPOSER: + g_value_set_object ( + value, e_composer_activity_get_composer ( + E_COMPOSER_ACTIVITY (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +composer_activity_dispose (GObject *object) +{ + EComposerActivity *activity; + + activity = E_COMPOSER_ACTIVITY (object); + + if (activity->priv->composer != NULL) { + composer_activity_unlock_interface (activity); + g_object_unref (activity->priv->composer); + activity->priv->composer = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_composer_activity_parent_class)->dispose (object); +} + +static void +e_composer_activity_class_init (EComposerActivityClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EComposerActivityPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = composer_activity_set_property; + object_class->get_property = composer_activity_get_property; + object_class->dispose = composer_activity_dispose; + + g_object_class_install_property ( + object_class, + PROP_COMPOSER, + g_param_spec_object ( + "composer", + NULL, + NULL, + E_TYPE_MSG_COMPOSER, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +e_composer_activity_init (EComposerActivity *activity) +{ + activity->priv = E_COMPOSER_ACTIVITY_GET_PRIVATE (activity); +} + +EActivity * +e_composer_activity_new (EMsgComposer *composer) +{ + return g_object_new ( + E_TYPE_COMPOSER_ACTIVITY, + "composer", composer, NULL); +} + +EMsgComposer * +e_composer_activity_get_composer (EComposerActivity *activity) +{ + g_return_val_if_fail (E_IS_COMPOSER_ACTIVITY (activity), NULL); + + return activity->priv->composer; +} diff -Nru evolution-3.16.0/composer/e-composer-activity.h evolution-3.12.11/composer/e-composer-activity.h --- evolution-3.16.0/composer/e-composer-activity.h 1970-01-01 00:00:00.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-activity.h 2014-03-24 09:25:23.000000000 +0000 @@ -0,0 +1,64 @@ +/* + * e-composer-activity.h + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, see . + * + */ + +#ifndef E_COMPOSER_ACTIVITY_H +#define E_COMPOSER_ACTIVITY_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_COMPOSER_ACTIVITY \ + (e_composer_activity_get_type ()) +#define E_COMPOSER_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_COMPOSER_ACTIVITY, EComposerActivity)) +#define E_COMPOSER_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_COMPOSER_ACTIVITY, EComposerActivityClass)) +#define E_IS_COMPOSER_ACTIVITY(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_COMPOSER_ACTIVITY)) +#define E_IS_COMPOSER_ACTIVITY_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_COMPOSER_ACTIVITY)) +#define E_COMPOSER_ACTIVITY_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_COMPOSER_ACTIVITY, EComposerActivityClass)) + +G_BEGIN_DECLS + +typedef struct _EComposerActivity EComposerActivity; +typedef struct _EComposerActivityClass EComposerActivityClass; +typedef struct _EComposerActivityPrivate EComposerActivityPrivate; + +struct _EComposerActivity { + EActivity parent; + EComposerActivityPrivate *priv; +}; + +struct _EComposerActivityClass { + EActivityClass parent_class; +}; + +GType e_composer_activity_get_type (void); +EActivity * e_composer_activity_new (EMsgComposer *composer); +EMsgComposer * e_composer_activity_get_composer + (EComposerActivity *activity); + +G_END_DECLS + +#endif /* E_COMPOSER_ACTIVITY_H */ diff -Nru evolution-3.16.0/composer/e-composer-from-header.c evolution-3.12.11/composer/e-composer-from-header.c --- evolution-3.16.0/composer/e-composer-from-header.c 2015-02-25 12:48:56.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-from-header.c 2014-07-17 10:48:07.000000000 +0000 @@ -21,15 +21,8 @@ #include #endif -#include - #include "e-composer-from-header.h" -enum { - PROP_0, - PROP_OVERRIDE_VISIBLE -}; - G_DEFINE_TYPE ( EComposerFromHeader, e_composer_from_header, @@ -39,146 +32,38 @@ composer_from_header_changed_cb (EMailIdentityComboBox *combo_box, EComposerFromHeader *header) { - if (e_mail_identity_combo_box_get_refreshing (combo_box)) - return; - g_signal_emit_by_name (header, "changed"); } static void -composer_from_header_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_OVERRIDE_VISIBLE: - e_composer_from_header_set_override_visible ( - E_COMPOSER_FROM_HEADER (object), - g_value_get_boolean (value)); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void -composer_from_header_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec) -{ - switch (property_id) { - case PROP_OVERRIDE_VISIBLE: - g_value_set_boolean ( - value, e_composer_from_header_get_override_visible ( - E_COMPOSER_FROM_HEADER (object))); - return; - } - - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); -} - -static void composer_from_header_constructed (GObject *object) { ESourceRegistry *registry; EComposerHeader *header; - EComposerFromHeader *from_header; GtkWidget *widget; - GtkWidget *grid; - GtkWidget *label; - GtkWidget *name; - GtkWidget *address; header = E_COMPOSER_HEADER (object); - from_header = E_COMPOSER_FROM_HEADER (object); registry = e_composer_header_get_registry (header); /* Input widget must be set before chaining up. */ widget = e_mail_identity_combo_box_new (registry); - gtk_widget_show (widget); g_signal_connect ( widget, "changed", G_CALLBACK (composer_from_header_changed_cb), header); header->input_widget = g_object_ref_sink (widget); - grid = gtk_grid_new (); - gtk_grid_set_column_homogeneous (GTK_GRID (grid), FALSE); - label = gtk_label_new_with_mnemonic (_("_Name:")); - gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1); - name = gtk_entry_new (); - g_object_set (G_OBJECT (name), - "hexpand", TRUE, - "halign", GTK_ALIGN_FILL, - "margin-left", 2, - "margin-right", 2, - NULL); - gtk_grid_attach (GTK_GRID (grid), name, 1, 0, 1, 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), name); - gtk_widget_show (label); - gtk_widget_show (name); - - label = gtk_label_new_with_mnemonic (_("_Address:")); - gtk_grid_attach (GTK_GRID (grid), label, 2, 0, 1, 1); - address = gtk_entry_new (); - g_object_set (G_OBJECT (address), - "hexpand", TRUE, - "halign", GTK_ALIGN_FILL, - "margin-left", 2, - "margin-right", 0, - NULL); - gtk_grid_attach (GTK_GRID (grid), address, 3, 0, 1, 1); - gtk_label_set_mnemonic_widget (GTK_LABEL (label), address); - gtk_widget_show (label); - gtk_widget_show (address); - - if (from_header->override_visible) - gtk_widget_show (grid); - else - gtk_widget_hide (grid); - - from_header->override_widget = g_object_ref_sink (grid); - /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (e_composer_from_header_parent_class)->constructed (object); } static void -composer_from_header_dispose (GObject *object) -{ - EComposerFromHeader *from_header; - - from_header = E_COMPOSER_FROM_HEADER (object); - - g_clear_object (&from_header->override_widget); - - /* Chain up to parent's method. */ - G_OBJECT_CLASS (e_composer_from_header_parent_class)->dispose (object); -} - -static void e_composer_from_header_class_init (EComposerFromHeaderClass *class) { GObjectClass *object_class; object_class = G_OBJECT_CLASS (class); - object_class->set_property = composer_from_header_set_property; - object_class->get_property = composer_from_header_get_property; object_class->constructed = composer_from_header_constructed; - object_class->dispose = composer_from_header_dispose; - - g_object_class_install_property ( - object_class, - PROP_OVERRIDE_VISIBLE, - g_param_spec_boolean ( - "override-visible", - NULL, - NULL, - FALSE, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS)); } static void @@ -198,15 +83,6 @@ "registry", registry, NULL); } -static GtkComboBox * -e_composer_from_header_get_identities_widget (EComposerFromHeader *header) - -{ - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - - return GTK_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget); -} - const gchar * e_composer_from_header_get_active_id (EComposerFromHeader *header) { @@ -214,7 +90,7 @@ g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - combo_box = e_composer_from_header_get_identities_widget (header); + combo_box = GTK_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget); return gtk_combo_box_get_active_id (combo_box); } @@ -230,7 +106,7 @@ if (!active_id) return; - combo_box = e_composer_from_header_get_identities_widget (header); + combo_box = GTK_COMBO_BOX (E_COMPOSER_HEADER (header)->input_widget); if (!gtk_combo_box_set_active_id (combo_box, active_id) && active_id && *active_id) { ESourceRegistry *registry; @@ -268,109 +144,3 @@ } } } - -GtkEntry * -e_composer_from_header_get_name_entry (EComposerFromHeader *header) -{ - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - - return GTK_ENTRY (gtk_grid_get_child_at (GTK_GRID (header->override_widget), 1, 0)); -} - -const gchar * -e_composer_from_header_get_name (EComposerFromHeader *header) -{ - const gchar *text; - - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - - text = gtk_entry_get_text (e_composer_from_header_get_name_entry (header)); - if (text && !*text) - text = NULL; - - return text; -} - -void -e_composer_from_header_set_name (EComposerFromHeader *header, - const gchar *name) -{ - GtkEntry *widget; - - g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header)); - - if (!name) - name = ""; - - widget = e_composer_from_header_get_name_entry (header); - - gtk_entry_set_text (widget, name); -} - -GtkEntry * -e_composer_from_header_get_address_entry (EComposerFromHeader *header) -{ - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - - return GTK_ENTRY (gtk_grid_get_child_at (GTK_GRID (header->override_widget), 3, 0)); -} - -const gchar * -e_composer_from_header_get_address (EComposerFromHeader *header) -{ - const gchar *text; - - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), NULL); - - text = gtk_entry_get_text (e_composer_from_header_get_address_entry (header)); - if (text && !*text) - text = NULL; - - return text; -} - -void -e_composer_from_header_set_address (EComposerFromHeader *header, - const gchar *address) -{ - GtkEntry *widget; - - g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header)); - - if (!address) - address = ""; - - widget = e_composer_from_header_get_address_entry (header); - - gtk_entry_set_text (widget, address); -} - -gboolean -e_composer_from_header_get_override_visible (EComposerFromHeader *header) -{ - g_return_val_if_fail (E_IS_COMPOSER_FROM_HEADER (header), FALSE); - - return header->override_visible; -} - -void -e_composer_from_header_set_override_visible (EComposerFromHeader *header, - gboolean visible) -{ - g_return_if_fail (E_IS_COMPOSER_FROM_HEADER (header)); - - if (header->override_visible == visible) - return; - - header->override_visible = visible; - - /* Show/hide the override widgets accordingly. */ - if (header->override_widget) { - if (visible) - gtk_widget_show (header->override_widget); - else - gtk_widget_hide (header->override_widget); - } - - g_object_notify (G_OBJECT (header), "override-visible"); -} diff -Nru evolution-3.16.0/composer/e-composer-from-header.h evolution-3.12.11/composer/e-composer-from-header.h --- evolution-3.16.0/composer/e-composer-from-header.h 2015-02-25 12:48:56.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-from-header.h 2014-03-24 09:25:23.000000000 +0000 @@ -48,9 +48,6 @@ struct _EComposerFromHeader { EComposerHeader parent; - - GtkWidget *override_widget; - gboolean override_visible; }; struct _EComposerFromHeaderClass { @@ -66,23 +63,6 @@ void e_composer_from_header_set_active_id (EComposerFromHeader *header, const gchar *active_id); -GtkEntry * e_composer_from_header_get_name_entry - (EComposerFromHeader *header); -const gchar * e_composer_from_header_get_name (EComposerFromHeader *header); -void e_composer_from_header_set_name (EComposerFromHeader *header, - const gchar *name); -GtkEntry * e_composer_from_header_get_address_entry - (EComposerFromHeader *header); -const gchar * e_composer_from_header_get_address - (EComposerFromHeader *header); -void e_composer_from_header_set_address - (EComposerFromHeader *header, - const gchar *address); -gboolean e_composer_from_header_get_override_visible - (EComposerFromHeader *header); -void e_composer_from_header_set_override_visible - (EComposerFromHeader *header, - gboolean visible); G_END_DECLS diff -Nru evolution-3.16.0/composer/e-composer-header.c evolution-3.12.11/composer/e-composer-header.c --- evolution-3.16.0/composer/e-composer-header.c 2015-02-24 08:14:26.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-header.c 2014-07-17 10:48:07.000000000 +0000 @@ -242,12 +242,12 @@ header->title_widget = g_object_ref_sink (widget); - e_binding_bind_property ( + g_object_bind_property ( header, "visible", header->title_widget, "visible", G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( header, "visible", header->input_widget, "visible", G_BINDING_SYNC_CREATE); diff -Nru evolution-3.16.0/composer/e-composer-header-table.c evolution-3.12.11/composer/e-composer-header-table.c --- evolution-3.16.0/composer/e-composer-header-table.c 2015-03-12 18:10:06.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-header-table.c 2014-07-17 10:48:07.000000000 +0000 @@ -50,8 +50,6 @@ GtkWidget *signature_combo_box; ENameSelector *name_selector; EClientCache *client_cache; - - gchar *previous_from_uid; }; enum { @@ -272,7 +270,7 @@ GSettings *settings; gint ii; - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { EComposerHeader *header; @@ -283,10 +281,6 @@ header = e_composer_header_table_get_header (table, ii); switch (ii) { - case E_COMPOSER_HEADER_FROM: - key = "composer-show-from-override"; - break; - case E_COMPOSER_HEADER_BCC: key = "composer-show-bcc"; break; @@ -331,18 +325,11 @@ e_composer_header_set_sensitive (header, sensitive); e_composer_header_set_visible (header, visible); - if (key != NULL) { - if (ii == E_COMPOSER_HEADER_FROM) - g_settings_bind ( - settings, key, - header, "override-visible", - G_SETTINGS_BIND_DEFAULT); - else - g_settings_bind ( - settings, key, - header, "visible", - G_SETTINGS_BIND_DEFAULT); - } + if (key != NULL) + g_settings_bind ( + settings, key, + header, "visible", + G_SETTINGS_BIND_DEFAULT); } g_object_unref (settings); @@ -354,7 +341,7 @@ GSettings *settings; gint ii; - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); for (ii = 0; ii < E_COMPOSER_NUM_HEADERS; ii++) { EComposerHeader *header; @@ -468,13 +455,10 @@ ESource *mail_account = NULL; EComposerHeader *header; EComposerHeaderType type; - EComposerFromHeader *from_header; EComposerPostHeader *post_header; EComposerTextHeader *text_header; EDestination **old_destinations; EDestination **new_destinations; - const gchar *name = NULL; - const gchar *address = NULL; const gchar *reply_to = NULL; const gchar * const *bcc = NULL; const gchar * const *cc = NULL; @@ -508,52 +492,13 @@ extension_name = E_SOURCE_EXTENSION_MAIL_COMPOSITION; mc = e_source_get_extension (source, extension_name); - name = e_source_mail_identity_get_name (mi); - address = e_source_mail_identity_get_address (mi); reply_to = e_source_mail_identity_get_reply_to (mi); bcc = e_source_mail_composition_get_bcc (mc); cc = e_source_mail_composition_get_cc (mc); - if (table->priv->previous_from_uid) { - ESource *previous_source; - - previous_source = e_composer_header_table_ref_source (table, table->priv->previous_from_uid); - if (previous_source && e_source_has_extension (previous_source, E_SOURCE_EXTENSION_MAIL_IDENTITY)) { - const gchar *previous_reply_to; - const gchar *current_reply_to; - gboolean matches; - - mi = e_source_get_extension (previous_source, E_SOURCE_EXTENSION_MAIL_IDENTITY); - previous_reply_to = e_source_mail_identity_get_reply_to (mi); - - header = e_composer_header_table_get_header (table, E_COMPOSER_HEADER_REPLY_TO); - text_header = E_COMPOSER_TEXT_HEADER (header); - current_reply_to = e_composer_text_header_get_text (text_header); - - matches = ((!current_reply_to || !*current_reply_to) && (!previous_reply_to || !*previous_reply_to)) || - g_strcmp0 (current_reply_to, previous_reply_to) == 0; - - /* Do not change Reply-To, if the user changed it. */ - if (!matches) - reply_to = current_reply_to; - } - } - - g_free (table->priv->previous_from_uid); - table->priv->previous_from_uid = g_strdup (e_source_get_uid (source)); - g_object_unref (source); - } else { - g_free (table->priv->previous_from_uid); - table->priv->previous_from_uid = NULL; } - type = E_COMPOSER_HEADER_FROM; - header = e_composer_header_table_get_header (table, type); - from_header = E_COMPOSER_FROM_HEADER (header); - e_composer_from_header_set_name (from_header, name); - e_composer_from_header_set_address (from_header, address); - type = E_COMPOSER_HEADER_POST_TO; header = e_composer_header_table_get_header (table, type); post_header = E_COMPOSER_POST_HEADER (header); @@ -795,9 +740,6 @@ priv->client_cache = NULL; } - g_free (priv->previous_from_uid); - priv->previous_from_uid = NULL; - /* Chain up to parent's dispose() method. */ G_OBJECT_CLASS (e_composer_header_table_parent_class)->dispose (object); } @@ -806,7 +748,6 @@ composer_header_table_constructed (GObject *object) { EComposerHeaderTable *table; - EComposerFromHeader *from_header; ENameSelector *name_selector; EClientCache *client_cache; ESourceRegistry *registry; @@ -878,19 +819,14 @@ row_padding = 3; for (ii = 0; ii < G_N_ELEMENTS (table->priv->headers); ii++) { - gint row = ii; - - if (ii > E_COMPOSER_HEADER_FROM) - row++; - gtk_table_attach ( GTK_TABLE (object), table->priv->headers[ii]->title_widget, 0, 1, - row, row + 1, GTK_FILL, GTK_FILL, 0, row_padding); + ii, ii + 1, GTK_FILL, GTK_FILL, 0, row_padding); gtk_table_attach ( GTK_TABLE (object), table->priv->headers[ii]->input_widget, 1, 4, - row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, row_padding); + ii, ii + 1, GTK_FILL | GTK_EXPAND, 0, 0, row_padding); } ii = E_COMPOSER_HEADER_FROM; @@ -901,12 +837,12 @@ table->priv->headers[ii]->input_widget, "right-attach", 2, NULL); - e_binding_bind_property ( + g_object_bind_property ( table->priv->headers[ii]->input_widget, "visible", table->priv->signature_label, "visible", G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( table->priv->headers[ii]->input_widget, "visible", table->priv->signature_combo_box, "visible", G_BINDING_SYNC_CREATE); @@ -921,13 +857,6 @@ table->priv->signature_combo_box, 3, 4, ii, ii + 1, 0, 0, 0, row_padding); - from_header = E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header (table, E_COMPOSER_HEADER_FROM)); - - gtk_table_attach ( - GTK_TABLE (object), - from_header->override_widget, 1, 2, - ii + 1, ii + 2, GTK_FILL, GTK_FILL, 0, row_padding); - /* Initialize the headers. */ composer_header_table_from_changed_cb (table); @@ -1366,38 +1295,6 @@ e_composer_from_header_set_active_id (from_header, identity_uid); } -const gchar * -e_composer_header_table_get_from_name (EComposerHeaderTable *table) -{ - EComposerHeader *header; - EComposerHeaderType type; - EComposerFromHeader *from_header; - - g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - - type = E_COMPOSER_HEADER_FROM; - header = e_composer_header_table_get_header (table, type); - from_header = E_COMPOSER_FROM_HEADER (header); - - return e_composer_from_header_get_name (from_header); -} - -const gchar * -e_composer_header_table_get_from_address (EComposerHeaderTable *table) -{ - EComposerHeader *header; - EComposerHeaderType type; - EComposerFromHeader *from_header; - - g_return_val_if_fail (E_IS_COMPOSER_HEADER_TABLE (table), NULL); - - type = E_COMPOSER_HEADER_FROM; - header = e_composer_header_table_get_header (table, type); - from_header = E_COMPOSER_FROM_HEADER (header); - - return e_composer_from_header_get_address (from_header); -} - GList * e_composer_header_table_get_post_to (EComposerHeaderTable *table) { diff -Nru evolution-3.16.0/composer/e-composer-header-table.h evolution-3.12.11/composer/e-composer-header-table.h --- evolution-3.16.0/composer/e-composer-header-table.h 2015-02-25 12:48:56.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-header-table.h 2014-03-24 09:25:23.000000000 +0000 @@ -109,10 +109,6 @@ void e_composer_header_table_set_identity_uid (EComposerHeaderTable *table, const gchar *identity_uid); -const gchar * e_composer_header_table_get_from_name - (EComposerHeaderTable *table); -const gchar * e_composer_header_table_get_from_address - (EComposerHeaderTable *table); GList * e_composer_header_table_get_post_to (EComposerHeaderTable *table); void e_composer_header_table_set_post_to_base diff -Nru evolution-3.16.0/composer/e-composer-private.c evolution-3.12.11/composer/e-composer-private.c --- evolution-3.16.0/composer/e-composer-private.c 2015-03-20 07:04:49.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-private.c 2014-10-29 11:12:27.000000000 +0000 @@ -21,26 +21,21 @@ #endif #include "e-composer-private.h" -#include "e-composer-from-header.h" #include "e-composer-spell-header.h" #include "e-util/e-util-private.h" /* Initial height of the picture gallery. */ #define GALLERY_INITIAL_HEIGHT 150 -#define UNICODE_ZERO_WIDTH_SPACE "\xe2\x80\x8b" - static void composer_setup_charset_menu (EMsgComposer *composer) { - EHTMLEditor *editor; GtkUIManager *ui_manager; const gchar *path; GList *list; guint merge_id; - editor = e_msg_composer_get_editor (composer); - ui_manager = e_html_editor_get_ui_manager (editor); + ui_manager = gtkhtml_editor_get_ui_manager (GTKHTML_EDITOR (composer)); path = "/main-menu/options-menu/charset-menu"; merge_id = gtk_ui_manager_new_merge_id (ui_manager); @@ -63,22 +58,62 @@ } static void +msg_composer_url_requested_cb (GtkHTML *html, + const gchar *uri, + GtkHTMLStream *stream, + EMsgComposer *composer) +{ + GByteArray *array; + GHashTable *hash_table; + CamelDataWrapper *wrapper; + CamelStream *camel_stream; + CamelMimePart *mime_part; + + hash_table = composer->priv->inline_images_by_url; + mime_part = g_hash_table_lookup (hash_table, uri); + + if (mime_part == NULL) { + hash_table = composer->priv->inline_images; + mime_part = g_hash_table_lookup (hash_table, uri); + } + + /* If this is not an inline image request, + * allow the signal emission to continue. */ + if (mime_part == NULL) + return; + + array = g_byte_array_new (); + camel_stream = camel_stream_mem_new_with_byte_array (array); + wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); + camel_data_wrapper_decode_to_stream_sync ( + wrapper, camel_stream, NULL, NULL); + + gtk_html_write (html, stream, (gchar *) array->data, array->len); + + gtk_html_end (html, stream, GTK_HTML_STREAM_OK); + + g_object_unref (camel_stream); + + /* gtk_html_end() destroys the GtkHTMLStream, so we need to + * stop the signal emission so nothing else tries to use it. */ + g_signal_stop_emission_by_name (html, "url-requested"); +} + +static void composer_update_gallery_visibility (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GtkToggleAction *toggle_action; gboolean gallery_active; - gboolean is_html; + gboolean html_mode; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - is_html = e_html_editor_view_get_html_mode (view); + editor = GTKHTML_EDITOR (composer); + html_mode = gtkhtml_editor_get_html_mode (editor); toggle_action = GTK_TOGGLE_ACTION (ACTION (PICTURE_GALLERY)); gallery_active = gtk_toggle_action_get_active (toggle_action); - if (is_html && gallery_active) { + if (html_mode && gallery_active) { gtk_widget_show (composer->priv->gallery_scrolled_window); gtk_widget_show (composer->priv->gallery_icon_view); } else { @@ -87,16 +122,30 @@ } } +static void +composer_spell_languages_changed (EMsgComposer *composer, + GList *languages) +{ + EComposerHeader *header; + EComposerHeaderTable *table; + + table = e_msg_composer_get_header_table (composer); + header = e_composer_header_table_get_header ( + table, E_COMPOSER_HEADER_SUBJECT); + + e_composer_spell_header_set_languages ( + E_COMPOSER_SPELL_HEADER (header), languages); +} + void e_composer_private_constructed (EMsgComposer *composer) { EMsgComposerPrivate *priv = composer->priv; EFocusTracker *focus_tracker; - EComposerHeader *header; EShell *shell; + EWebViewGtkHTML *web_view; EClientCache *client_cache; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GtkUIManager *ui_manager; GtkAction *action; GtkWidget *container; @@ -109,14 +158,14 @@ gint ii; GError *error = NULL; - editor = e_msg_composer_get_editor (composer); - ui_manager = e_html_editor_get_ui_manager (editor); - view = e_html_editor_get_view (editor); + editor = GTKHTML_EDITOR (composer); + ui_manager = gtkhtml_editor_get_ui_manager (editor); - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); shell = e_msg_composer_get_shell (composer); client_cache = e_shell_get_client_cache (shell); + web_view = e_msg_composer_get_web_view (composer); /* Each composer window gets its own window group. */ window = GTK_WINDOW (composer); @@ -130,17 +179,20 @@ priv->extra_hdr_names = g_ptr_array_new (); priv->extra_hdr_values = g_ptr_array_new (); + priv->inline_images = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) NULL); + + priv->inline_images_by_url = g_hash_table_new_full ( + g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_object_unref); + priv->charset = e_composer_get_default_charset (); - priv->is_from_new_message = FALSE; - priv->set_signature_from_message = FALSE; + priv->is_from_message = FALSE; priv->disable_signature = FALSE; - priv->busy = FALSE; - priv->saved_editable = FALSE; - priv->drop_occured = FALSE; - priv->dnd_is_uri = FALSE; - - priv->focused_entry = NULL; e_composer_actions_init (composer); @@ -165,64 +217,48 @@ focus_tracker = e_focus_tracker_new (GTK_WINDOW (composer)); - action = e_html_editor_get_action (editor, "cut"); + action = gtkhtml_editor_get_action (editor, "cut"); e_focus_tracker_set_cut_clipboard_action (focus_tracker, action); - action = e_html_editor_get_action (editor, "copy"); + action = gtkhtml_editor_get_action (editor, "copy"); e_focus_tracker_set_copy_clipboard_action (focus_tracker, action); - action = e_html_editor_get_action (editor, "paste"); + action = gtkhtml_editor_get_action (editor, "paste"); e_focus_tracker_set_paste_clipboard_action (focus_tracker, action); - action = e_html_editor_get_action (editor, "select-all"); + action = gtkhtml_editor_get_action (editor, "select-all"); e_focus_tracker_set_select_all_action (focus_tracker, action); - action = e_html_editor_get_action (editor, "undo"); - e_focus_tracker_set_undo_action (focus_tracker, action); - - action = e_html_editor_get_action (editor, "redo"); - e_focus_tracker_set_redo_action (focus_tracker, action); - priv->focus_tracker = focus_tracker; - widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); - gtk_container_add (GTK_CONTAINER (composer), widget); - gtk_widget_show (widget); - - container = widget; + container = editor->vbox; - /* Construct the main menu and toolbar. */ + /* Construct the activity bar. */ - widget = e_html_editor_get_managed_widget (editor, "/main-menu"); + widget = e_activity_bar_new (); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); + priv->activity_bar = g_object_ref_sink (widget); + /* EActivityBar controls its own visibility. */ - widget = e_html_editor_get_managed_widget (editor, "/main-toolbar"); + /* Construct the alert bar for errors. */ + + widget = e_alert_bar_new (); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); + priv->alert_bar = g_object_ref_sink (widget); + /* EAlertBar controls its own visibility. */ /* Construct the header table. */ widget = e_composer_header_table_new (client_cache); gtk_container_set_border_width (GTK_CONTAINER (widget), 6); gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - priv->header_table = g_object_ref (widget); + gtk_box_reorder_child (GTK_BOX (container), widget, 2); + priv->header_table = g_object_ref_sink (widget); gtk_widget_show (widget); - header = e_composer_header_table_get_header ( - E_COMPOSER_HEADER_TABLE (widget), - E_COMPOSER_HEADER_SUBJECT); - e_binding_bind_property ( - view, "spell-checker", - header->input_widget, "spell-checker", - G_BINDING_SYNC_CREATE); - - /* Construct the editing toolbars. We'll have to reparent - * the embedded EHTMLEditorView a little further down. */ - - widget = GTK_WIDGET (editor); - gtk_box_pack_start (GTK_BOX (container), widget, FALSE, FALSE, 0); - gtk_widget_show (widget); + g_signal_connect ( + G_OBJECT (composer), "spell-languages-changed", + G_CALLBACK (composer_spell_languages_changed), NULL); /* Construct the attachment paned. */ @@ -231,9 +267,9 @@ priv->attachment_paned = g_object_ref_sink (widget); gtk_widget_show (widget); - e_binding_bind_property ( - view, "editable", - widget, "sensitive", + g_object_bind_property ( + web_view, "editable", + widget, "editable", G_BINDING_SYNC_CREATE); container = e_attachment_paned_get_content_area ( @@ -253,13 +289,13 @@ GTK_SCROLLED_WINDOW (widget), GTK_SHADOW_IN); gtk_widget_set_size_request (widget, -1, GALLERY_INITIAL_HEIGHT); gtk_paned_pack1 (GTK_PANED (container), widget, FALSE, FALSE); - priv->gallery_scrolled_window = g_object_ref (widget); + priv->gallery_scrolled_window = g_object_ref_sink (widget); gtk_widget_show (widget); - /* Reparent the scrolled window containing the web view - * widget into the content area of the top attachment pane. */ + /* Reparent the scrolled window containing the GtkHTML widget + * into the content area of the top attachment pane. */ - widget = GTK_WIDGET (view); + widget = GTK_WIDGET (web_view); widget = gtk_widget_get_parent (widget); gtk_widget_reparent (widget, container); @@ -275,16 +311,16 @@ priv->gallery_icon_view = g_object_ref_sink (widget); g_free (gallery_path); - e_signal_connect_notify_swapped ( - view, "notify::mode", - G_CALLBACK (composer_update_gallery_visibility), composer); + e_signal_connect_notify ( + composer, "notify::html-mode", + G_CALLBACK (composer_update_gallery_visibility), NULL); g_signal_connect_swapped ( ACTION (PICTURE_GALLERY), "toggled", G_CALLBACK (composer_update_gallery_visibility), composer); - /* Initial sync */ - composer_update_gallery_visibility (composer); + /* XXX What is this for? */ + g_object_set_data (G_OBJECT (composer), "vbox", editor->vbox); /* Bind headers to their corresponding actions. */ @@ -297,22 +333,6 @@ header = e_composer_header_table_get_header (table, ii); switch (ii) { - case E_COMPOSER_HEADER_FROM: - e_widget_undo_attach ( - GTK_WIDGET (e_composer_from_header_get_name_entry (E_COMPOSER_FROM_HEADER (header))), - focus_tracker); - e_widget_undo_attach ( - GTK_WIDGET (e_composer_from_header_get_address_entry (E_COMPOSER_FROM_HEADER (header))), - focus_tracker); - - action = ACTION (VIEW_FROM_OVERRIDE); - e_binding_bind_property ( - header, "override-visible", - action, "active", - G_BINDING_BIDIRECTIONAL | - G_BINDING_SYNC_CREATE); - continue; - case E_COMPOSER_HEADER_BCC: action = ACTION (VIEW_BCC); break; @@ -323,49 +343,39 @@ case E_COMPOSER_HEADER_REPLY_TO: action = ACTION (VIEW_REPLY_TO); - e_widget_undo_attach ( - GTK_WIDGET (header->input_widget), - focus_tracker); break; - case E_COMPOSER_HEADER_SUBJECT: - e_widget_undo_attach ( - GTK_WIDGET (header->input_widget), - focus_tracker); - continue; - default: continue; } - e_binding_bind_property ( + g_object_bind_property ( header, "sensitive", action, "sensitive", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); - e_binding_bind_property ( + g_object_bind_property ( header, "visible", action, "active", G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE); } - /* Disable actions that start asynchronous activities while an - * asynchronous activity is in progress. We enforce this with - * a simple inverted binding to EMsgComposer's "busy" property. */ - - e_binding_bind_property ( - composer, "busy", - priv->async_actions, "sensitive", - G_BINDING_SYNC_CREATE | - G_BINDING_INVERT_BOOLEAN); - - e_binding_bind_property ( - composer, "busy", - priv->header_table, "sensitive", - G_BINDING_SYNC_CREATE | - G_BINDING_INVERT_BOOLEAN); + /* Install a handler for inline images. */ + + /* XXX We no longer use GtkhtmlEditor::uri-requested because it + * conflicts with EWebView's url_requested() method, which + * unconditionally launches an async operation. I changed + * GtkHTML::url-requested to be a G_SIGNAL_RUN_LAST so that + * our handler runs first. If we can handle the request + * we'll stop the signal emission to prevent EWebView from + * launching an async operation. Messy, but works until we + * switch to WebKit. --mbarnes */ + + g_signal_connect ( + web_view, "url-requested", + G_CALLBACK (msg_composer_url_requested_cb), composer); g_object_unref (settings); } @@ -380,16 +390,21 @@ composer->priv->shell = NULL; } - if (composer->priv->editor != NULL) { - g_object_unref (composer->priv->editor); - composer->priv->editor = NULL; - } - if (composer->priv->header_table != NULL) { g_object_unref (composer->priv->header_table); composer->priv->header_table = NULL; } + if (composer->priv->activity_bar != NULL) { + g_object_unref (composer->priv->activity_bar); + composer->priv->activity_bar = NULL; + } + + if (composer->priv->alert_bar != NULL) { + g_object_unref (composer->priv->alert_bar); + composer->priv->alert_bar = NULL; + } + if (composer->priv->attachment_paned != NULL) { g_object_unref (composer->priv->attachment_paned); composer->priv->attachment_paned = NULL; @@ -420,10 +435,11 @@ composer->priv->composer_actions = NULL; } - if (composer->priv->gallery_scrolled_window != NULL) { - g_object_unref (composer->priv->gallery_scrolled_window); - composer->priv->gallery_scrolled_window = NULL; - } + g_clear_object (&composer->priv->gallery_icon_view); + g_clear_object (&composer->priv->gallery_scrolled_window); + + g_hash_table_remove_all (composer->priv->inline_images); + g_hash_table_remove_all (composer->priv->inline_images_by_url); if (composer->priv->redirect != NULL) { g_object_unref (composer->priv->redirect); @@ -447,6 +463,10 @@ g_free (composer->priv->charset); g_free (composer->priv->mime_type); g_free (composer->priv->mime_body); + g_free (composer->priv->selected_signature_uid); + + g_hash_table_destroy (composer->priv->inline_images); + g_hash_table_destroy (composer->priv->inline_images_by_url); } gchar * @@ -479,7 +499,7 @@ GSettings *settings; gchar *charset; - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); charset = g_settings_get_string (settings, "composer-charset"); @@ -506,13 +526,92 @@ return charset; } +gchar * +e_composer_decode_clue_value (const gchar *encoded_value) +{ + GString *buffer; + const gchar *cp; + + /* Decode a GtkHtml "ClueFlow" value. */ + + g_return_val_if_fail (encoded_value != NULL, NULL); + + buffer = g_string_sized_new (strlen (encoded_value)); + + /* Copy the value, decoding escaped characters as we go. */ + cp = encoded_value; + while (*cp != '\0') { + if (*cp == '.') { + cp++; + switch (*cp) { + case '.': + g_string_append_c (buffer, '.'); + break; + case '1': + g_string_append_c (buffer, '"'); + break; + case '2': + g_string_append_c (buffer, '='); + break; + default: + /* Invalid escape sequence. */ + g_string_free (buffer, TRUE); + return NULL; + } + } else + g_string_append_c (buffer, *cp); + cp++; + } + + return g_string_free (buffer, FALSE); +} + +gchar * +e_composer_encode_clue_value (const gchar *decoded_value) +{ + gchar *encoded_value; + gchar **strv; + + /* Encode a GtkHtml "ClueFlow" value. */ + + g_return_val_if_fail (decoded_value != NULL, NULL); + + /* XXX This is inefficient but easy to understand. */ + + encoded_value = g_strdup (decoded_value); + + /* Substitution: '.' --> '..' (do this first) */ + if (strchr (encoded_value, '.') != NULL) { + strv = g_strsplit (encoded_value, ".", 0); + g_free (encoded_value); + encoded_value = g_strjoinv ("..", strv); + g_strfreev (strv); + } + + /* Substitution: '"' --> '.1' */ + if (strchr (encoded_value, '"') != NULL) { + strv = g_strsplit (encoded_value, """", 0); + g_free (encoded_value); + encoded_value = g_strjoinv (".1", strv); + g_strfreev (strv); + } + + /* Substitution: '=' --> '.2' */ + if (strchr (encoded_value, '=') != NULL) { + strv = g_strsplit (encoded_value, "=", 0); + g_free (encoded_value); + encoded_value = g_strjoinv (".2", strv); + g_strfreev (strv); + } + + return encoded_value; +} + gboolean e_composer_paste_html (EMsgComposer *composer, GtkClipboard *clipboard) { - EHTMLEditor *editor; - EHTMLEditorView *view; - EHTMLEditorSelection *editor_selection; + GtkhtmlEditor *editor; gchar *html; g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); @@ -521,13 +620,8 @@ html = e_clipboard_wait_for_html (clipboard); g_return_val_if_fail (html != NULL, FALSE); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - editor_selection = e_html_editor_view_get_selection (view); - /* If Web View doesn't have focus, focus it */ - if (!gtk_widget_has_focus (GTK_WIDGET (view))) - gtk_widget_grab_focus (GTK_WIDGET (view)); - e_html_editor_selection_insert_html (editor_selection, html); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_insert_html (editor, html); g_free (html); @@ -538,8 +632,7 @@ e_composer_paste_image (EMsgComposer *composer, GtkClipboard *clipboard) { - EHTMLEditor *editor; - EHTMLEditorView *html_editor_view; + GtkhtmlEditor *editor; EAttachmentStore *store; EAttachmentView *view; GdkPixbuf *pixbuf = NULL; @@ -551,6 +644,7 @@ g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); g_return_val_if_fail (GTK_IS_CLIPBOARD (clipboard), FALSE); + editor = GTKHTML_EDITOR (composer); view = e_msg_composer_get_attachment_view (composer); store = e_attachment_view_get_store (view); @@ -580,15 +674,9 @@ /* In HTML mode, paste the image into the message body. * In text mode, add the image to the attachment store. */ - editor = e_msg_composer_get_editor (composer); - html_editor_view = e_html_editor_get_view (editor); - if (e_html_editor_view_get_html_mode (html_editor_view)) { - EHTMLEditorSelection *selection; - - selection = e_html_editor_view_get_selection (html_editor_view); - e_html_editor_selection_insert_image (selection, uri); - e_html_editor_selection_scroll_to_caret (selection); - } else { + if (gtkhtml_editor_get_html_mode (editor)) + gtkhtml_editor_insert_image (editor, uri); + else { EAttachment *attachment; attachment = e_attachment_new_for_uri (uri); @@ -618,9 +706,7 @@ e_composer_paste_text (EMsgComposer *composer, GtkClipboard *clipboard) { - EHTMLEditor *editor; - EHTMLEditorView *view; - EHTMLEditorSelection *editor_selection; + GtkhtmlEditor *editor; gchar *text; g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); @@ -629,14 +715,8 @@ text = gtk_clipboard_wait_for_text (clipboard); g_return_val_if_fail (text != NULL, FALSE); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - editor_selection = e_html_editor_view_get_selection (view); - /* If WebView doesn't have focus, focus it */ - if (!gtk_widget_has_focus (GTK_WIDGET (view))) - gtk_widget_grab_focus (GTK_WIDGET (view)); - - e_html_editor_selection_insert_text (editor_selection, text); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_insert_text (editor, text); g_free (text); @@ -678,35 +758,6 @@ } gboolean -e_composer_selection_is_base64_uris (EMsgComposer *composer, - GtkSelectionData *selection) -{ - gboolean all_base64_uris = TRUE; - gchar **uris; - guint ii; - - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); - g_return_val_if_fail (selection != NULL, FALSE); - - uris = gtk_selection_data_get_uris (selection); - - if (!uris) - return FALSE; - - for (ii = 0; uris[ii] != NULL; ii++) { - if (!((g_str_has_prefix (uris[ii], "data:") || strstr (uris[ii], ";data:")) - && strstr (uris[ii], ";base64,"))) { - all_base64_uris = FALSE; - break; - } - } - - g_strfreev (uris); - - return all_base64_uris; -} - -gboolean e_composer_selection_is_image_uris (EMsgComposer *composer, GtkSelectionData *selection) { @@ -719,7 +770,7 @@ uris = gtk_selection_data_get_uris (selection); - if (!uris) + if (uris == NULL) return FALSE; for (ii = 0; uris[ii] != NULL; ii++) { @@ -785,7 +836,7 @@ gboolean signature_delim; /* FIXME This should be an EMsgComposer property. */ - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); signature_delim = !g_settings_get_boolean ( settings, "composer-no-signature-delim"); g_object_unref (settings); @@ -800,7 +851,7 @@ gboolean top_signature; /* FIXME This should be an EMsgComposer property. */ - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); top_signature = g_settings_get_boolean ( settings, "composer-top-signature"); g_object_unref (settings); @@ -809,270 +860,19 @@ } static void -composer_size_allocate_cb (GtkWidget *widget, - gpointer user_data) -{ - GtkWidget *scrolled_window; - GtkAdjustment *adj; - - scrolled_window = gtk_widget_get_parent (GTK_WIDGET (widget)); - adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window)); - - /* Scroll only when there is some size allocated */ - if (gtk_adjustment_get_upper (adj) != 0.0) { - /* Scroll web view down to caret */ - gtk_adjustment_set_value (adj, gtk_adjustment_get_upper (adj) - gtk_adjustment_get_page_size (adj)); - gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (scrolled_window), adj); - /* Disconnect because we don't want to scroll down the view on every window size change */ - g_signal_handlers_disconnect_by_func ( - widget, G_CALLBACK (composer_size_allocate_cb), NULL); - } -} - -static WebKitDOMElement * -prepare_paragraph (EHTMLEditorSelection *selection, - WebKitDOMDocument *document) -{ - WebKitDOMElement *br, *paragraph; - - paragraph = e_html_editor_selection_get_paragraph_element ( - selection, document, -1, 0); - webkit_dom_element_set_id (paragraph, "-x-evo-input-start"); - br = webkit_dom_document_create_element (document, "BR", NULL); - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (paragraph), WEBKIT_DOM_NODE (br), NULL); - - return paragraph; -} - -static WebKitDOMElement * -prepare_top_signature_spacer (EHTMLEditorSelection *selection, - WebKitDOMDocument *document) -{ - WebKitDOMElement *element; - - element = prepare_paragraph (selection, document); - webkit_dom_element_remove_attribute (element, "id"); - element_add_class (element, "-x-evo-top-signature-spacer"); - - return element; -} - -static void -composer_move_caret (EMsgComposer *composer) -{ - EHTMLEditor *editor; - EHTMLEditorView *view; - EHTMLEditorSelection *editor_selection; - GSettings *settings; - gboolean start_bottom, top_signature; - gboolean is_message_from_draft; - gboolean is_message_from_edit_as_new; - gboolean has_paragraphs_in_body = TRUE; - WebKitDOMDocument *document; - WebKitDOMDOMWindow *window; - WebKitDOMDOMSelection *dom_selection; - WebKitDOMElement *element, *signature; - WebKitDOMHTMLElement *body; - WebKitDOMNodeList *list; - WebKitDOMRange *new_range; - - /* When there is an option composer-reply-start-bottom set we have - * to move the caret between reply and signature. */ - settings = e_util_ref_settings ("org.gnome.evolution.mail"); - start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom"); - g_object_unref (settings); - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - editor_selection = e_html_editor_view_get_selection (view); - is_message_from_draft = e_html_editor_view_is_message_from_draft (view); - is_message_from_edit_as_new = - e_html_editor_view_is_message_from_edit_as_new (view); - - top_signature = - use_top_signature (composer) && - !is_message_from_edit_as_new && - !composer->priv->is_from_new_message; - - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - window = webkit_dom_document_get_default_view (document); - dom_selection = webkit_dom_dom_window_get_selection (window); - - body = webkit_dom_document_get_body (document); - webkit_dom_element_set_attribute ( - WEBKIT_DOM_ELEMENT (body), "data-message", "", NULL); - new_range = webkit_dom_document_create_range (document); - - /* If editing message as new don't handle with caret */ - if (is_message_from_edit_as_new || is_message_from_draft) { - if (is_message_from_edit_as_new) - webkit_dom_element_set_attribute ( - WEBKIT_DOM_ELEMENT (body), - "data-edit-as-new", - "", - NULL); - - if (is_message_from_edit_as_new) { - element = WEBKIT_DOM_ELEMENT (body); - e_html_editor_selection_block_selection_changed (editor_selection); - goto move_caret; - } else - e_html_editor_selection_scroll_to_caret (editor_selection); - - return; - } - - e_html_editor_selection_block_selection_changed (editor_selection); - - /* When the new message is written from the beginning - note it into body */ - if (composer->priv->is_from_new_message) - webkit_dom_element_set_attribute ( - WEBKIT_DOM_ELEMENT (body), "data-new-message", "", NULL); - - list = webkit_dom_document_get_elements_by_class_name (document, "-x-evo-paragraph"); - signature = webkit_dom_document_query_selector (document, ".-x-evo-signature-wrapper", NULL); - /* Situation when wrapped paragraph is just in signature and not in message body */ - if (webkit_dom_node_list_get_length (list) == 1) - if (signature && webkit_dom_element_query_selector (signature, ".-x-evo-paragraph", NULL)) - has_paragraphs_in_body = FALSE; - - /* - * - * Keeping Signatures in the beginning of composer - * ------------------------------------------------ - * - * Purists are gonna blast me for this. - * But there are so many people (read Outlook users) who want this. - * And Evo is an exchange-client, Outlook-replacement etc. - * So Here it goes :( - * - * -- Sankar - * - */ - if (signature && top_signature) { - WebKitDOMElement *spacer; - - spacer = prepare_top_signature_spacer (editor_selection, document); - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (spacer), - webkit_dom_node_get_next_sibling (WEBKIT_DOM_NODE (signature)), - NULL); - } - - if (webkit_dom_node_list_get_length (list) == 0) - has_paragraphs_in_body = FALSE; - - element = webkit_dom_document_get_element_by_id (document, "-x-evo-input-start"); - if (!signature) { - if (start_bottom) { - if (!element) { - element = prepare_paragraph (editor_selection, document); - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - NULL); - } - } else - element = WEBKIT_DOM_ELEMENT (body); - - g_object_unref (list); - goto move_caret; - } - - if (!has_paragraphs_in_body) { - element = prepare_paragraph (editor_selection, document); - if (top_signature) { - if (start_bottom) { - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - NULL); - } else { - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - WEBKIT_DOM_NODE (signature), - NULL); - } - } else { - if (start_bottom) - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - WEBKIT_DOM_NODE (signature), - NULL); - else - element = WEBKIT_DOM_ELEMENT (body); - } - } else { - if (!element && top_signature) { - element = prepare_paragraph (editor_selection, document); - if (start_bottom) { - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - NULL); - } else { - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - WEBKIT_DOM_NODE (signature), - NULL); - } - } else if (element && top_signature && !start_bottom) { - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - WEBKIT_DOM_NODE (signature), - NULL); - } else if (element && start_bottom) { - /* Leave it how it is */ - } else - element = WEBKIT_DOM_ELEMENT (body); - } - - g_object_unref (list); - move_caret: - if (element) { - webkit_dom_range_select_node_contents ( - new_range, WEBKIT_DOM_NODE (element), NULL); - webkit_dom_range_collapse (new_range, TRUE, NULL); - webkit_dom_dom_selection_remove_all_ranges (dom_selection); - webkit_dom_dom_selection_add_range (dom_selection, new_range); - } - - if (start_bottom) - g_signal_connect ( - view, "size-allocate", - G_CALLBACK (composer_size_allocate_cb), NULL); - - e_html_editor_view_force_spell_check (view); - - e_html_editor_selection_unblock_selection_changed (editor_selection); -} - -static void composer_load_signature_cb (EMailSignatureComboBox *combo_box, GAsyncResult *result, EMsgComposer *composer) { GString *html_buffer = NULL; + GtkhtmlEditor *editor; gchar *contents = NULL; gsize length = 0; const gchar *active_id; + gchar *encoded_uid = NULL; gboolean top_signature; gboolean is_html; GError *error = NULL; - EHTMLEditor *editor; - EHTMLEditorView *view; - WebKitDOMDocument *document; - WebKitDOMNodeList *signatures; - gulong list_length, ii; - GSettings *settings; - gboolean start_bottom; - gboolean is_message_from_edit_as_new; e_mail_signature_combo_box_load_selected_finish ( combo_box, result, &contents, &length, &is_html, &error); @@ -1084,21 +884,14 @@ goto exit; } - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - is_message_from_edit_as_new = - e_html_editor_view_is_message_from_edit_as_new (view); + if (composer->priv->disable_signature) + goto exit; - /* "Edit as New Message" sets is_message_from_edit_as_new. + /* "Edit as New Message" sets "priv->is_from_message". * Always put the signature at the bottom for that case. */ top_signature = use_top_signature (composer) && - !is_message_from_edit_as_new && - !composer->priv->is_from_new_message; - - settings = e_util_ref_settings ("org.gnome.evolution.mail"); - start_bottom = g_settings_get_boolean (settings, "composer-reply-start-bottom"); - g_object_unref (settings); + !composer->priv->is_from_message; if (contents == NULL) goto insert; @@ -1122,13 +915,24 @@ /* The combo box active ID is the signature's ESource UID. */ active_id = gtk_combo_box_get_active_id (GTK_COMBO_BOX (combo_box)); + if (active_id != NULL && *active_id != '\0') + encoded_uid = e_composer_encode_clue_value (active_id); + g_string_append_printf ( html_buffer, - "", - (active_id != NULL) ? active_id : ""); + "" + "", + (encoded_uid != NULL) ? encoded_uid : ""); + + g_string_append ( + html_buffer, + "
"); if (!is_html) - g_string_append (html_buffer, "
");
+		g_string_append (html_buffer, "
\n");
 
 	/* The signature dash convention ("-- \n") is specified
 	 * in the "Son of RFC 1036", section 4.3.2.
@@ -1139,8 +943,8 @@
 		const gchar *delim_nl;
 
 		if (is_html) {
-			delim = "-- 
"; - delim_nl = "\n--
"; + delim = "-- \n
"; + delim_nl = "\n-- \n
"; } else { delim = "-- \n"; delim_nl = "\n-- \n"; @@ -1158,135 +962,73 @@ g_string_append_len (html_buffer, contents, length); if (!is_html) - g_string_append (html_buffer, "
"); + g_string_append (html_buffer, "
\n"); + + if (top_signature) + g_string_append (html_buffer, "
"); + + g_string_append (html_buffer, "
"); - g_string_append (html_buffer, "
"); + g_free (encoded_uid); g_free (contents); insert: /* Remove the old signature and insert the new one. */ - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - - signatures = webkit_dom_document_get_elements_by_class_name ( - document, "-x-evo-signature-wrapper"); - list_length = webkit_dom_node_list_get_length (signatures); - for (ii = 0; ii < list_length; ii++) { - WebKitDOMNode *wrapper, *signature; - gchar *id; - - wrapper = webkit_dom_node_list_item (signatures, ii); - signature = webkit_dom_node_get_first_child (wrapper); - id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (signature)); - - /* When we are editing a message with signature we need to set active - * signature id in signature combo box otherwise no signature will be - * added but we have to do it just once when the composer opens */ - if (is_message_from_edit_as_new && composer->priv->set_signature_from_message) { - gchar *name; - - composer->priv->set_signature_from_message = FALSE; - - name = webkit_dom_element_get_attribute (WEBKIT_DOM_ELEMENT (signature), "name"); - gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), name); - g_free (name); - } - - if (id && (strlen (id) == 1) && (*id == '1')) { - /* If the top signature was set we have to remove the NL - * that was inserted after it */ - if (top_signature) { - WebKitDOMElement *spacer; - - spacer = webkit_dom_document_query_selector ( - document, ".-x-evo-top-signature-spacer", NULL); - if (spacer) - remove_node_if_empty (WEBKIT_DOM_NODE (spacer)); - } - /* We have to remove the div containing the span with signature */ - remove_node (wrapper); - g_object_unref (wrapper); - - g_free (id); - break; - } + editor = GTKHTML_EDITOR (composer); - g_object_unref (wrapper); - g_free (id); + /* This prevents our command before/after callbacks from + * screwing around with the signature as we insert it. */ + composer->priv->in_signature_insert = TRUE; + + gtkhtml_editor_freeze (editor); + gtkhtml_editor_run_command (editor, "cursor-position-save"); + gtkhtml_editor_undo_begin (editor, "Set signature", "Reset signature"); + + gtkhtml_editor_run_command (editor, "block-selection"); + gtkhtml_editor_run_command (editor, "cursor-bod"); + if (gtkhtml_editor_search_by_data (editor, 1, "ClueFlow", "signature", "1")) { + gtkhtml_editor_run_command (editor, "select-paragraph"); + gtkhtml_editor_run_command (editor, "delete"); + gtkhtml_editor_set_paragraph_data (editor, "signature", "0"); + gtkhtml_editor_run_command (editor, "delete-back"); } - g_object_unref (signatures); + gtkhtml_editor_run_command (editor, "unblock-selection"); if (html_buffer != NULL) { - if (*html_buffer->str) { - WebKitDOMElement *element; - WebKitDOMHTMLElement *body; - - body = webkit_dom_document_get_body (document); - element = webkit_dom_document_create_element (document, "DIV", NULL); - webkit_dom_element_set_class_name (element, "-x-evo-signature-wrapper"); - - webkit_dom_html_element_set_inner_html ( - WEBKIT_DOM_HTML_ELEMENT (element), html_buffer->str, NULL); - - if (top_signature) { - WebKitDOMNode *child = - webkit_dom_node_get_first_child (WEBKIT_DOM_NODE (body)); - - if (start_bottom) { - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - child, - NULL); - } else { - /* When we are using signature on top the caret - * should be before the signature */ - webkit_dom_node_insert_before ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - child, - NULL); - } - } else { - webkit_dom_node_append_child ( - WEBKIT_DOM_NODE (body), - WEBKIT_DOM_NODE (element), - NULL); - } - } + gtkhtml_editor_run_command (editor, "insert-paragraph"); + if (!gtkhtml_editor_run_command (editor, "cursor-backward")) + gtkhtml_editor_run_command (editor, "insert-paragraph"); + else + gtkhtml_editor_run_command (editor, "cursor-forward"); + + gtkhtml_editor_set_paragraph_data (editor, "orig", "0"); + gtkhtml_editor_run_command (editor, "indent-zero"); + gtkhtml_editor_run_command (editor, "style-normal"); + gtkhtml_editor_insert_html (editor, html_buffer->str); g_string_free (html_buffer, TRUE); + + } else if (top_signature) { + /* Insert paragraph after the signature ClueFlow stuff. */ + if (gtkhtml_editor_run_command (editor, "cursor-forward")) + gtkhtml_editor_run_command (editor, "insert-paragraph"); } - composer_move_caret (composer); + gtkhtml_editor_undo_end (editor); + gtkhtml_editor_run_command (editor, "cursor-position-restore"); + gtkhtml_editor_thaw (editor); -exit: - /* Make sure the flag will be unset and won't influence user's choice */ - composer->priv->set_signature_from_message = FALSE; + composer->priv->in_signature_insert = FALSE; +exit: g_object_unref (composer); } -static void -composer_web_view_load_status_changed_cb (WebKitWebView *webkit_web_view, - GParamSpec *pspec, - EMsgComposer *composer) +static gboolean +is_null_or_none (const gchar *text) { - WebKitLoadStatus status; - - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - - status = webkit_web_view_get_load_status (webkit_web_view); - - if (status != WEBKIT_LOAD_FINISHED) - return; - - g_signal_handlers_disconnect_by_func ( - webkit_web_view, - G_CALLBACK (composer_web_view_load_status_changed_cb), - NULL); - - e_composer_update_signature (composer); + return !text || g_strcmp0 (text, "none") == 0; } void @@ -1294,9 +1036,7 @@ { EComposerHeaderTable *table; EMailSignatureComboBox *combo_box; - EHTMLEditor *editor; - EHTMLEditorView *view; - WebKitLoadStatus status; + const gchar *signature_uid; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); @@ -1306,24 +1046,20 @@ return; table = e_msg_composer_get_header_table (composer); - combo_box = e_composer_header_table_get_signature_combo_box (table); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); + signature_uid = e_composer_header_table_get_signature_uid (table); - status = webkit_web_view_get_load_status (WEBKIT_WEB_VIEW (view)); - /* If document is not loaded, we will wait for him */ - if (status != WEBKIT_LOAD_FINISHED) { - /* Disconnect previous handlers */ - g_signal_handlers_disconnect_by_func ( - WEBKIT_WEB_VIEW (view), - G_CALLBACK (composer_web_view_load_status_changed_cb), - composer); - g_signal_connect ( - WEBKIT_WEB_VIEW(view), "notify::load-status", - G_CALLBACK (composer_web_view_load_status_changed_cb), - composer); + /* this is a case when the signature combo cleared itself for a reload */ + if (!signature_uid) return; - } + + if (g_strcmp0 (signature_uid, composer->priv->selected_signature_uid) == 0 || + (is_null_or_none (signature_uid) && is_null_or_none (composer->priv->selected_signature_uid))) + return; + + g_free (composer->priv->selected_signature_uid); + composer->priv->selected_signature_uid = g_strdup (signature_uid); + + combo_box = e_composer_header_table_get_signature_combo_box (table); /* XXX Signature files should be local and therefore load quickly, * so while we do load them asynchronously we don't allow for diff -Nru evolution-3.16.0/composer/e-composer-private.h evolution-3.12.11/composer/e-composer-private.h --- evolution-3.16.0/composer/e-composer-private.h 2015-02-12 12:50:50.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-private.h 2014-10-29 10:58:24.000000000 +0000 @@ -32,6 +32,7 @@ #include #include "e-composer-actions.h" +#include "e-composer-activity.h" #include "e-composer-header-table.h" #ifdef HAVE_XFREE @@ -57,11 +58,11 @@ gpointer shell; /* weak pointer */ - EHTMLEditor *editor; - /*** UI Management ***/ GtkWidget *header_table; + GtkWidget *activity_bar; + GtkWidget *alert_bar; GtkWidget *attachment_paned; EFocusTracker *focus_tracker; @@ -81,6 +82,10 @@ GtkWidget *address_dialog; + GHashTable *inline_images; + GHashTable *inline_images_by_url; + GList *current_images; + gchar *mime_type; gchar *mime_body; gchar *charset; @@ -92,28 +97,10 @@ CamelMimeMessage *redirect; - gboolean busy; + gboolean is_from_message; gboolean disable_signature; - gboolean is_from_draft; - gboolean is_from_new_message; - /* The web view is uneditable while the editor is busy. - * This is used to restore the previous editable state. */ - gboolean saved_editable; - gboolean set_signature_from_message; - gboolean drop_occured; - gboolean dnd_is_uri; - - gint focused_entry_selection_start; - gint focused_entry_selection_end; - - gulong notify_destinations_bcc_handler; - gulong notify_destinations_cc_handler; - gulong notify_destinations_to_handler; - gulong notify_identity_uid_handler; - gulong notify_reply_to_handler; - gulong notify_signature_uid_handler; - gulong notify_subject_handler; - gulong notify_subject_changed_handler; + + gchar *selected_signature_uid; }; void e_composer_private_constructed (EMsgComposer *composer); @@ -135,9 +122,6 @@ GtkClipboard *clipboard); gboolean e_composer_paste_uris (EMsgComposer *composer, GtkClipboard *clipboard); -gboolean e_composer_selection_is_base64_uris - (EMsgComposer *composer, - GtkSelectionData *selection); gboolean e_composer_selection_is_image_uris (EMsgComposer *composer, GtkSelectionData *selection); diff -Nru evolution-3.16.0/composer/e-composer-spell-header.c evolution-3.12.11/composer/e-composer-spell-header.c --- evolution-3.16.0/composer/e-composer-spell-header.c 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-spell-header.c 2014-03-24 09:25:23.000000000 +0000 @@ -63,3 +63,16 @@ "registry", registry, NULL); } +void +e_composer_spell_header_set_languages (EComposerSpellHeader *header, + GList *languages) +{ + ESpellEntry *spell_entry; + + g_return_if_fail (header != NULL); + + spell_entry = E_SPELL_ENTRY (E_COMPOSER_HEADER (header)->input_widget); + g_return_if_fail (spell_entry != NULL); + + e_spell_entry_set_languages (spell_entry, languages); +} diff -Nru evolution-3.16.0/composer/e-composer-spell-header.h evolution-3.12.11/composer/e-composer-spell-header.h --- evolution-3.16.0/composer/e-composer-spell-header.h 2014-06-09 14:39:38.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-spell-header.h 2014-03-24 09:25:23.000000000 +0000 @@ -66,6 +66,9 @@ e_composer_spell_header_new_button (ESourceRegistry *registry, const gchar *label); +void e_composer_spell_header_set_languages + (EComposerSpellHeader *header, + GList *languages); G_END_DECLS diff -Nru evolution-3.16.0/composer/e-composer-text-header.c evolution-3.12.11/composer/e-composer-text-header.c --- evolution-3.16.0/composer/e-composer-text-header.c 2014-11-05 15:31:04.000000000 +0000 +++ evolution-3.12.11/composer/e-composer-text-header.c 2014-07-17 10:48:07.000000000 +0000 @@ -28,6 +28,11 @@ #define E_COMPOSER_TEXT_HEADER_GET_ENTRY(header) \ (GTK_ENTRY (E_COMPOSER_HEADER (header)->input_widget)) +struct _EComposerTextHeaderPrivate { + GtkLinkButton *linkbtn; + guint destination_index; +}; + G_DEFINE_TYPE ( EComposerTextHeader, e_composer_text_header, diff -Nru evolution-3.16.0/composer/e-msg-composer.c evolution-3.12.11/composer/e-msg-composer.c --- evolution-3.16.0/composer/e-msg-composer.c 2015-03-20 07:04:49.000000000 +0000 +++ evolution-3.12.11/composer/e-msg-composer.c 2014-10-29 11:11:43.000000000 +0000 @@ -35,9 +35,7 @@ #include #include #include -#include -#include "e-composer-from-header.h" #include "e-composer-private.h" #include @@ -46,8 +44,6 @@ #include -#include - typedef struct _AsyncContext AsyncContext; struct _AsyncContext { @@ -76,22 +72,19 @@ /* Flags for building a message. */ typedef enum { - COMPOSER_FLAG_HTML_CONTENT = 1 << 0, - COMPOSER_FLAG_SAVE_OBJECT_DATA = 1 << 1, - COMPOSER_FLAG_PRIORITIZE_MESSAGE = 1 << 2, - COMPOSER_FLAG_REQUEST_READ_RECEIPT = 1 << 3, - COMPOSER_FLAG_PGP_SIGN = 1 << 4, - COMPOSER_FLAG_PGP_ENCRYPT = 1 << 5, - COMPOSER_FLAG_SMIME_SIGN = 1 << 6, - COMPOSER_FLAG_SMIME_ENCRYPT = 1 << 7, - COMPOSER_FLAG_HTML_MODE = 1 << 8, - COMPOSER_FLAG_SAVE_DRAFT = 1 << 9 + COMPOSER_FLAG_HTML_CONTENT = 1 << 0, + COMPOSER_FLAG_SAVE_OBJECT_DATA = 1 << 1, + COMPOSER_FLAG_PRIORITIZE_MESSAGE = 1 << 2, + COMPOSER_FLAG_REQUEST_READ_RECEIPT = 1 << 3, + COMPOSER_FLAG_PGP_SIGN = 1 << 4, + COMPOSER_FLAG_PGP_ENCRYPT = 1 << 5, + COMPOSER_FLAG_SMIME_SIGN = 1 << 6, + COMPOSER_FLAG_SMIME_ENCRYPT = 1 << 7, + COMPOSER_FLAG_DRAFT = 1 << 8 } ComposerFlags; enum { PROP_0, - PROP_BUSY, - PROP_EDITOR, PROP_FOCUS_TRACKER, PROP_SHELL }; @@ -105,26 +98,6 @@ LAST_SIGNAL }; -enum DndTargetType { - DND_TARGET_TYPE_TEXT_URI_LIST, - DND_TARGET_TYPE_MOZILLA_URL, - DND_TARGET_TYPE_TEXT_HTML, - DND_TARGET_TYPE_UTF8_STRING, - DND_TARGET_TYPE_TEXT_PLAIN, - DND_TARGET_TYPE_STRING, - DND_TARGET_TYPE_TEXT_PLAIN_UTF8 -}; - -static GtkTargetEntry drag_dest_targets[] = { - { (gchar *) "text/uri-list", 0, DND_TARGET_TYPE_TEXT_URI_LIST }, - { (gchar *) "_NETSCAPE_URL", 0, DND_TARGET_TYPE_MOZILLA_URL }, - { (gchar *) "text/html", 0, DND_TARGET_TYPE_TEXT_HTML }, - { (gchar *) "UTF8_STRING", 0, DND_TARGET_TYPE_UTF8_STRING }, - { (gchar *) "text/plain", 0, DND_TARGET_TYPE_TEXT_PLAIN }, - { (gchar *) "STRING", 0, DND_TARGET_TYPE_STRING }, - { (gchar *) "text/plain;charset=utf-8", 0, DND_TARGET_TYPE_TEXT_PLAIN_UTF8 }, -}; - static guint signals[LAST_SIGNAL]; /* used by e_msg_composer_add_message_attachments () */ @@ -155,10 +128,14 @@ GCancellable *cancellable, gint depth); +static void e_msg_composer_alert_sink_init (EAlertSinkInterface *iface); + G_DEFINE_TYPE_WITH_CODE ( EMsgComposer, e_msg_composer, - GTK_TYPE_WINDOW, + GTKHTML_TYPE_EDITOR, + G_IMPLEMENT_INTERFACE ( + E_TYPE_ALERT_SINK, e_msg_composer_alert_sink_init) G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) static void @@ -218,7 +195,6 @@ GString *part_id; EShell *shell; GtkWindow *window; - gsize n_bytes_written = 0; GQueue queue = G_QUEUE_INIT; shell = e_shell_get_default (); @@ -265,7 +241,7 @@ g_object_unref (formatter); g_object_unref (part_list); - g_output_stream_write_all (stream, "", 1, &n_bytes_written, NULL, NULL); + g_output_stream_write (stream, "", 1, NULL, NULL); g_output_stream_close (stream, NULL, NULL); @@ -431,6 +407,45 @@ return g_strdup (charset); } +static void +clear_current_images (EMsgComposer *composer) +{ + EMsgComposerPrivate *p = composer->priv; + g_list_free (p->current_images); + p->current_images = NULL; +} + +void +e_msg_composer_clear_inlined_table (EMsgComposer *composer) +{ + EMsgComposerPrivate *p = composer->priv; + + g_hash_table_remove_all (p->inline_images); + g_hash_table_remove_all (p->inline_images_by_url); +} + +static void +add_inlined_images (EMsgComposer *composer, + CamelMultipart *multipart) +{ + EMsgComposerPrivate *p = composer->priv; + + GList *d = p->current_images; + GHashTable *added; + + added = g_hash_table_new (g_direct_hash, g_direct_equal); + while (d) { + CamelMimePart *part = d->data; + + if (!g_hash_table_lookup (added, part)) { + camel_multipart_add_part (multipart, part); + g_hash_table_insert (added, part, part); + } + d = d->next; + } + g_hash_table_destroy (added); +} + /* These functions builds a CamelMimeMessage for the message that the user has * composed in 'composer'. */ @@ -547,26 +562,19 @@ if (source != NULL) { CamelMedium *medium; CamelInternetAddress *addr; + ESourceMailIdentity *mi; ESourceMailSubmission *ms; - EComposerHeader *composer_header; const gchar *extension_name; const gchar *header_name; const gchar *name, *address; const gchar *transport_uid; const gchar *sent_folder; - composer_header = e_composer_header_table_get_header (table, E_COMPOSER_HEADER_FROM); - if (e_composer_from_header_get_override_visible (E_COMPOSER_FROM_HEADER (composer_header))) { - name = e_composer_header_table_get_from_name (table); - address = e_composer_header_table_get_from_address (table); - } else { - ESourceMailIdentity *mail_identity; - - mail_identity = e_source_get_extension (source, E_SOURCE_EXTENSION_MAIL_IDENTITY); + extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY; + mi = e_source_get_extension (source, extension_name); - name = e_source_mail_identity_get_name (mail_identity); - address = e_source_mail_identity_get_address (mail_identity); - } + name = e_source_mail_identity_get_name (mi); + address = e_source_mail_identity_get_address (mi); extension_name = E_SOURCE_EXTENSION_MAIL_SUBMISSION; ms = e_source_get_extension (source, extension_name); @@ -1033,24 +1041,6 @@ } static void -composer_add_evolution_composer_mode_header (CamelMedium *medium, - EMsgComposer *composer) -{ - gboolean html_mode; - EHTMLEditor *editor; - EHTMLEditorView *view; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - html_mode = e_html_editor_view_get_html_mode (view); - - camel_medium_add_header ( - medium, - "X-Evolution-Composer-Mode", - html_mode ? "text/html" : "text/plain"); -} - -static void composer_add_evolution_format_header (CamelMedium *medium, ComposerFlags flags) { @@ -1058,7 +1048,7 @@ string = g_string_sized_new (128); - if ((flags & COMPOSER_FLAG_HTML_CONTENT) || (flags & COMPOSER_FLAG_SAVE_DRAFT)) + if (flags & COMPOSER_FLAG_HTML_CONTENT) g_string_append (string, "text/html"); else g_string_append (string, "text/plain"); @@ -1081,6 +1071,45 @@ g_string_free (string, TRUE); } +static gchar * +msg_composer_generate_msg_id (EMsgComposer *composer) +{ + CamelInternetAddress *from; + gchar *tmp, *msg_id; + const gchar *from_domain = NULL; + + from = e_msg_composer_get_from (composer); + if (from && camel_internet_address_get (from, 0, NULL, &from_domain)) { + const gchar *at = strchr (from_domain, '@'); + if (at) + from_domain = at + 1; + else + from_domain = NULL; + } else { + from_domain = NULL; + } + + if (!from_domain || !*from_domain) + from_domain = "localhost"; + + msg_id = camel_header_msgid_generate (); + tmp = strchr (msg_id, '@'); + if (!tmp) { + g_clear_object (&from); + return msg_id; + } + + tmp[1] = '\0'; + + tmp = msg_id; + msg_id = g_strconcat (tmp, from_domain, NULL); + + g_clear_object (&from); + g_free (tmp); + + return msg_id; +} + static void composer_build_message (EMsgComposer *composer, ComposerFlags flags, @@ -1092,6 +1121,7 @@ EMsgComposerPrivate *priv; GSimpleAsyncResult *simple; AsyncContext *context; + GtkhtmlEditor *editor; EAttachmentView *view; EAttachmentStore *store; EComposerHeaderTable *table; @@ -1108,11 +1138,11 @@ CamelMimePart *part; GByteArray *data; ESource *source; - gchar *charset, *message_uid; - const gchar *from_domain; + gchar *charset, *message_id; gint i; priv = composer->priv; + editor = GTKHTML_EDITOR (composer); table = e_msg_composer_get_header_table (composer); view = e_msg_composer_get_attachment_view (composer); store = e_attachment_view_get_store (view); @@ -1129,17 +1159,17 @@ context->session = e_msg_composer_ref_session (composer); context->from = e_msg_composer_get_from (composer); - if (!(flags & COMPOSER_FLAG_SAVE_DRAFT)) { - if (flags & COMPOSER_FLAG_PGP_SIGN) + if ((flags & COMPOSER_FLAG_DRAFT) == 0) { + if ((flags & COMPOSER_FLAG_PGP_SIGN) != 0) context->pgp_sign = TRUE; - if (flags & COMPOSER_FLAG_PGP_ENCRYPT) + if ((flags & COMPOSER_FLAG_PGP_ENCRYPT) != 0) context->pgp_encrypt = TRUE; - if (flags & COMPOSER_FLAG_SMIME_SIGN) + if ((flags & COMPOSER_FLAG_SMIME_SIGN) != 0) context->smime_sign = TRUE; - if (flags & COMPOSER_FLAG_SMIME_ENCRYPT) + if ((flags & COMPOSER_FLAG_SMIME_ENCRYPT) != 0) context->smime_encrypt = TRUE; } @@ -1168,25 +1198,11 @@ context->message = camel_mime_message_new (); - if (context->from && camel_internet_address_get (context->from, 0, NULL, &from_domain)) { - const gchar *at = strchr (from_domain, '@'); - if (at) - from_domain = at + 1; - else - from_domain = NULL; - } else { - from_domain = NULL; - } - - if (!from_domain || !*from_domain) - from_domain = "localhost"; - - message_uid = camel_header_msgid_generate (from_domain); - /* Explicitly generate a Message-ID header here so it's * consistent for all outbound streams (SMTP, Fcc, etc). */ - camel_mime_message_set_message_id (context->message, message_uid); - g_free (message_uid); + message_id = msg_composer_generate_msg_id (composer); + camel_mime_message_set_message_id (context->message, message_id); + g_free (message_id); build_message_headers (composer, context->message, FALSE); for (i = 0; i < priv->extra_hdr_names->len; i++) { @@ -1231,45 +1247,9 @@ g_free (encoded_organization); } - if (flags & COMPOSER_FLAG_SAVE_DRAFT) { - gchar *text; - EHTMLEditor *editor; - EHTMLEditorView *view; - EHTMLEditorSelection *selection; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - selection = e_html_editor_view_get_selection (view); - - /* X-Evolution-Format */ - composer_add_evolution_format_header ( - CAMEL_MEDIUM (context->message), flags); - - /* X-Evolution-Composer-Mode */ - composer_add_evolution_composer_mode_header ( - CAMEL_MEDIUM (context->message), composer); - - data = g_byte_array_new (); - - e_html_editor_view_embed_styles (view); - e_html_editor_selection_save (selection); - - text = e_html_editor_view_get_text_html_for_drafts (view); - - e_html_editor_view_remove_embed_styles (view); - e_html_editor_selection_restore (selection); - e_html_editor_view_force_spell_check (view); - - g_byte_array_append (data, (guint8 *) text, strlen (text)); - - g_free (text); - - type = camel_content_type_new ("text", "html"); - camel_content_type_set_param (type, "charset", "utf-8"); - iconv_charset = camel_iconv_charset_name ("utf-8"); - - goto wrap_drafts_html; - } + /* X-Evolution-Format */ + composer_add_evolution_format_header ( + CAMEL_MEDIUM (context->message), flags); /* Build the text/plain part. */ @@ -1296,14 +1276,11 @@ } else { gchar *text; - EHTMLEditor *editor; - EHTMLEditorView *view; + gsize length; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); data = g_byte_array_new (); - text = e_html_editor_view_get_text_plain (view); - g_byte_array_append (data, (guint8 *) text, strlen (text)); + text = gtkhtml_editor_get_text_plain (editor, &length); + g_byte_array_append (data, (guint8 *) text, (guint) length); g_free (text); type = camel_content_type_new ("text", "plain"); @@ -1316,7 +1293,6 @@ } } - wrap_drafts_html: mem_stream = camel_stream_mem_new_with_byte_array (data); stream = camel_stream_filter_new (mem_stream); g_object_unref (mem_stream); @@ -1363,26 +1339,25 @@ * ... */ - if ((flags & COMPOSER_FLAG_HTML_CONTENT) != 0 && - !(flags & COMPOSER_FLAG_SAVE_DRAFT)) { + if (flags & COMPOSER_FLAG_HTML_CONTENT) { gchar *text; - guint count; gsize length; gboolean pre_encode; - EHTMLEditor *editor; - EHTMLEditorView *view; - GList *inline_images; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); + clear_current_images (composer); + + if (flags & COMPOSER_FLAG_SAVE_OBJECT_DATA) + gtkhtml_editor_run_command (editor, "save-data-on"); data = g_byte_array_new (); - text = e_html_editor_view_get_text_html (view, from_domain, &inline_images); - length = strlen (text); + text = gtkhtml_editor_get_text_html (editor, &length); g_byte_array_append (data, (guint8 *) text, (guint) length); pre_encode = text_requires_quoted_printable (text, length); g_free (text); + if (flags & COMPOSER_FLAG_SAVE_OBJECT_DATA) + gtkhtml_editor_run_command (editor, "save-data-off"); + mem_stream = camel_stream_mem_new_with_byte_array (data); stream = camel_stream_filter_new (mem_stream); g_object_unref (mem_stream); @@ -1432,9 +1407,7 @@ /* If there are inlined images, construct a multipart/related * containing the multipart/alternative and the images. */ - count = g_list_length (inline_images); - if (count > 0) { - guint ii; + if (priv->current_images) { CamelMultipart *html_with_images; html_with_images = camel_multipart_new (); @@ -1453,12 +1426,8 @@ g_object_unref (body); - for (ii = 0; ii < count; ii++) { - CamelMimePart *part = g_list_nth_data (inline_images, ii); - camel_multipart_add_part ( - html_with_images, part); - g_object_unref (part); - } + add_inlined_images (composer, html_with_images); + clear_current_images (composer); context->top_level_part = CAMEL_DATA_WRAPPER (html_with_images); @@ -1540,28 +1509,79 @@ /* Signatures */ +static gboolean +use_top_signature (EMsgComposer *composer) +{ + EMsgComposerPrivate *priv; + GSettings *settings; + gboolean top_signature; + + priv = E_MSG_COMPOSER_GET_PRIVATE (composer); + + /* The composer had been created from a stored message, thus the + * signature placement is either there already, or pt it at the + * bottom regardless of a preferences (which is for reply anyway, + * not for Edit as new) */ + if (priv->is_from_message) + return FALSE; + + /* FIXME This should be an EMsgComposer property. */ + settings = g_settings_new ("org.gnome.evolution.mail"); + top_signature = g_settings_get_boolean ( + settings, "composer-top-signature"); + g_object_unref (settings); + + return top_signature; +} + +#define NO_SIGNATURE_TEXT \ + "" \ + "
" + static void set_editor_text (EMsgComposer *composer, const gchar *text, - gboolean is_html, gboolean set_signature) { - EHTMLEditor *editor; - EHTMLEditorView *view; + gchar *body = NULL; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); g_return_if_fail (text != NULL); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); + /* + * + * Keeping Signatures in the beginning of composer + * ------------------------------------------------ + * + * Purists are gonna blast me for this. + * But there are so many people (read Outlook users) who want this. + * And Evo is an exchange-client, Outlook-replacement etc. + * So Here it goes :( + * + * -- Sankar + * + */ - if (is_html) - e_html_editor_view_set_text_html (view, text); - else - e_html_editor_view_set_text_plain (view, text); + /* "Edit as New Message" sets "priv->is_from_message". + * Always put the signature at the bottom for that case. */ + if (!composer->priv->is_from_message && use_top_signature (composer)) { + /* put marker to the top */ + body = g_strdup_printf ("
" NO_SIGNATURE_TEXT "%s", text); + } else { + /* no marker => to the bottom */ + body = g_strdup_printf ("%s
", text); + } + + gtkhtml_editor_set_text_html (GTKHTML_EDITOR (composer), body, -1); if (set_signature) e_composer_update_signature (composer); + + g_free (body); } /* Miscellaneous callbacks. */ @@ -1569,16 +1589,12 @@ static void attachment_store_changed_cb (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; /* Mark the editor as changed so it prompts about unsaved * changes on close. */ - editor = e_msg_composer_get_editor (composer); - if (editor) { - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); - } + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static void @@ -1599,8 +1615,6 @@ static void msg_composer_mail_identity_changed_cb (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; EMailSignatureComboBox *combo_box; ESourceMailComposition *mc; ESourceOpenPGP *pgp; @@ -1613,7 +1627,6 @@ gboolean pgp_sign; gboolean smime_sign; gboolean smime_encrypt; - gboolean is_message_from_edit_as_new; const gchar *extension_name; const gchar *uid; @@ -1646,26 +1659,21 @@ composer->priv->mime_type, "text/calendar", 13) != 0); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - is_message_from_edit_as_new = - e_html_editor_view_is_message_from_edit_as_new (view); - action = GTK_TOGGLE_ACTION (ACTION (PGP_SIGN)); active = gtk_toggle_action_get_active (action); - active &= is_message_from_edit_as_new; + active &= composer->priv->is_from_message; active |= (can_sign && pgp_sign); gtk_toggle_action_set_active (action, active); action = GTK_TOGGLE_ACTION (ACTION (SMIME_SIGN)); active = gtk_toggle_action_get_active (action); - active &= is_message_from_edit_as_new; + active &= composer->priv->is_from_message; active |= (can_sign && smime_sign); gtk_toggle_action_set_active (action, active); action = GTK_TOGGLE_ACTION (ACTION (SMIME_ENCRYPT)); active = gtk_toggle_action_get_active (action); - active &= is_message_from_edit_as_new; + active &= composer->priv->is_from_message; active |= smime_encrypt; gtk_toggle_action_set_active (action, active); @@ -1681,14 +1689,11 @@ gint n_targets, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); + GtkhtmlEditor *editor; + gboolean html_mode; - if (targets == NULL || n_targets < 0) - return; + editor = GTKHTML_EDITOR (composer); + html_mode = gtkhtml_editor_get_html_mode (editor); /* Order is important here to ensure common use cases are * handled correctly. See GNOME bug #603715 for details. */ @@ -1699,7 +1704,7 @@ } /* Only paste HTML content in HTML mode. */ - if (e_html_editor_view_get_html_mode (view)) { + if (html_mode) { if (e_targets_include_html (targets, n_targets)) { e_composer_paste_html (composer, clipboard); return; @@ -1718,31 +1723,48 @@ } static void -msg_composer_paste_primary_clipboard_cb (EHTMLEditorView *view, - EMsgComposer *composer) +msg_composer_paste_clipboard_cb (EWebViewGtkHTML *web_view, + EMsgComposer *composer) { GtkClipboard *clipboard; - clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY); + clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); gtk_clipboard_request_targets ( clipboard, (GtkClipboardTargetsReceivedFunc) msg_composer_paste_clipboard_targets_cb, composer); + + g_signal_stop_emission_by_name (web_view, "paste-clipboard"); } static void -msg_composer_paste_clipboard_cb (EHTMLEditorView *view, +msg_composer_realize_gtkhtml_cb (GtkWidget *widget, EMsgComposer *composer) { - GtkClipboard *clipboard; + EAttachmentView *view; + GtkTargetList *target_list; + GtkTargetEntry *targets; + gint n_targets; + + /* XXX GtkHTML doesn't set itself up as a drag destination until + * it's realized, and we need to amend to its target list so + * it will accept the same drag targets as the attachment bar. + * Do this any earlier and GtkHTML will just overwrite us. */ + + /* When redirecting a message, the message body is not + * editable and therefore cannot be a drag destination. */ + if (!e_web_view_gtkhtml_get_editable (E_WEB_VIEW_GTKHTML (widget))) + return; - clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD); + view = e_msg_composer_get_attachment_view (composer); - gtk_clipboard_request_targets ( - clipboard, (GtkClipboardTargetsReceivedFunc) - msg_composer_paste_clipboard_targets_cb, composer); + target_list = e_attachment_view_get_target_list (view); + targets = gtk_target_table_new_from_list (target_list, &n_targets); + + target_list = gtk_drag_dest_get_target_list (widget); + gtk_target_list_add_table (target_list, targets, n_targets); - g_signal_stop_emission_by_name (view, "paste-clipboard"); + gtk_target_table_free (targets, n_targets); } static gboolean @@ -1753,126 +1775,14 @@ guint time, EMsgComposer *composer) { - GtkWidget *source_widget; - EHTMLEditor *editor = e_msg_composer_get_editor (composer); - EHTMLEditorView *editor_view = e_html_editor_get_view (editor); - - source_widget = gtk_drag_get_source_widget (context); - /* When we are doind DnD just inside the web view, the DnD is supposed - * to move things around. */ - if (E_IS_HTML_EDITOR_VIEW (source_widget)) { - if ((gpointer) editor_view == (gpointer) source_widget) { - gdk_drag_status (context, GDK_ACTION_MOVE, time); - - return FALSE; - } - } - - gdk_drag_status (context, GDK_ACTION_COPY, time); - - return FALSE; -} - -static gboolean -msg_composer_drag_drop_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time, - EMsgComposer *composer) -{ - GdkAtom target; - GtkWidget *source_widget; - - /* When we are doind DnD just inside the web view, the DnD is supposed - * to move things around. */ - source_widget = gtk_drag_get_source_widget (context); - if (E_IS_HTML_EDITOR_VIEW (source_widget)) { - EHTMLEditor *editor = e_msg_composer_get_editor (composer); - EHTMLEditorView *editor_view = e_html_editor_get_view (editor); - - if ((gpointer) editor_view == (gpointer) source_widget) - return FALSE; - } - - target = gtk_drag_dest_find_target (widget, context, NULL); - if (target == GDK_NONE) - gdk_drag_status (context, 0, time); - else { - /* Prevent WebKit from pasting the URI of file into the view. */ - if (composer->priv->dnd_is_uri) - g_signal_stop_emission_by_name (widget, "drag-drop"); - - composer->priv->dnd_is_uri = FALSE; - - gdk_drag_status (context, GDK_ACTION_COPY, time); - composer->priv->drop_occured = TRUE; - gtk_drag_get_data (widget, context, target, time); - } - - return FALSE; -} - -static void -msg_composer_drag_data_received_after_cb (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - GtkSelectionData *selection, - guint info, - guint time, - EMsgComposer *composer) -{ - EHTMLEditor *editor; - EHTMLEditorView *view; - WebKitDOMDocument *document; - WebKitDOMDOMWindow *dom_window; - WebKitDOMDOMSelection *dom_selection; - - if (!composer->priv->drop_occured) - return; - - composer->priv->drop_occured = FALSE; - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - dom_window = webkit_dom_document_get_default_view (document); - dom_selection = webkit_dom_dom_window_get_selection (dom_window); - - /* When text is DnD'ed into the view, WebKit will select it. So let's - * collapse it to its end to have the caret after the DnD'ed text. */ - webkit_dom_dom_selection_collapse_to_end (dom_selection, NULL); - - e_html_editor_view_check_magic_links (view, FALSE); - /* Also force spell check on view. */ - e_html_editor_view_force_spell_check (view); -} - -static gchar * -next_uri (guchar **uri_list, - gint *len, - gint *list_len) -{ - guchar *uri, *begin; - - begin = *uri_list; - *len = 0; - while (**uri_list && **uri_list != '\n' && **uri_list != '\r' && *list_len) { - (*uri_list) ++; - (*len) ++; - (*list_len) --; - } + EAttachmentView *view; - uri = (guchar *) g_strndup ((gchar *) begin, *len); + view = e_msg_composer_get_attachment_view (composer); - while ((!**uri_list || **uri_list == '\n' || **uri_list == '\r') && *list_len) { - (*uri_list) ++; - (*list_len) --; - } + /* Stop the signal from propagating to GtkHtml. */ + g_signal_stop_emission_by_name (widget, "drag-motion"); - return (gchar *) uri; + return e_attachment_view_drag_motion (view, context, x, y, time); } static void @@ -1885,165 +1795,44 @@ guint time, EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *html_editor_view; - EHTMLEditorSelection *editor_selection; - gboolean html_mode, same_widget = FALSE; - GtkWidget *source_widget; - - editor = e_msg_composer_get_editor (composer); - html_editor_view = e_html_editor_get_view (editor); - html_mode = e_html_editor_view_get_html_mode (html_editor_view); - editor_selection = e_html_editor_view_get_selection (html_editor_view); - - /* When we are doind DnD just inside the web view, the DnD is supposed - * to move things around. */ - source_widget = gtk_drag_get_source_widget (context); - if (E_IS_HTML_EDITOR_VIEW (source_widget)) { - EHTMLEditor *editor = e_msg_composer_get_editor (composer); - EHTMLEditorView *editor_view = e_html_editor_get_view (editor); - - if ((gpointer) editor_view == (gpointer) source_widget) - same_widget = TRUE; - } - - /* Leave DnD inside the view on WebKit. */ - if (composer->priv->drop_occured && same_widget) { - gdk_drag_status (context, 0, time); - return; - } - - if (!composer->priv->drop_occured) { - if (!same_widget) { - /* Check if we are DnD'ing some URI, if so WebKit will - * insert the URI into the view and we have to prevent it - * from doing that. */ - if (info == DND_TARGET_TYPE_TEXT_URI_LIST) { - gchar **uris; - - uris = gtk_selection_data_get_uris (selection); - composer->priv->dnd_is_uri = uris != NULL; - g_strfreev (uris); - } - } - return; - } - - composer->priv->dnd_is_uri = FALSE; - - /* Leave the text on WebKit to handle it. */ - if (info == DND_TARGET_TYPE_UTF8_STRING || - info == DND_TARGET_TYPE_STRING || - info == DND_TARGET_TYPE_TEXT_PLAIN || - info == DND_TARGET_TYPE_TEXT_PLAIN_UTF8) { - gdk_drag_status (context, 0, time); - return; - } - - if (info == DND_TARGET_TYPE_TEXT_HTML) { - const guchar *data; - gint length; - gint list_len, len; - gchar *text; - - data = gtk_selection_data_get_data (selection); - length = gtk_selection_data_get_length (selection); - - if (!data || length < 0) { - gtk_drag_finish (context, FALSE, FALSE, time); - return; - } - - e_html_editor_selection_set_on_point (editor_selection, x, y); - - list_len = length; - do { - text = next_uri ((guchar **) &data, &len, &list_len); - e_html_editor_selection_insert_html (editor_selection, text); - } while (list_len); - - e_html_editor_view_check_magic_links (html_editor_view, FALSE); - e_html_editor_view_force_spell_check (html_editor_view); - - e_html_editor_selection_scroll_to_caret (editor_selection); - - gtk_drag_finish (context, TRUE, FALSE, time); - return; - } + EAttachmentView *view; /* HTML mode has a few special cases for drops... */ - /* If we're receiving URIs and -all- the URIs point to - * image files, we want the image(s) to be inserted in - * the message body. */ - if (html_mode && e_composer_selection_is_image_uris (composer, selection)) { - const guchar *data; - gint length; - gint list_len, len; - gchar *uri; - - data = gtk_selection_data_get_data (selection); - length = gtk_selection_data_get_length (selection); + if (gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (composer))) { - if (!data || length < 0) { - gtk_drag_finish (context, FALSE, FALSE, time); + /* If we're receiving an image, we want the image to be + * inserted in the message body. Let GtkHtml handle it. */ + if (gtk_selection_data_targets_include_image (selection, TRUE)) return; - } - - e_html_editor_selection_set_on_point (editor_selection, x, y); - - list_len = length; - do { - uri = next_uri ((guchar **) &data, &len, &list_len); - e_html_editor_selection_insert_image (editor_selection, uri); - } while (list_len); - - gtk_drag_finish (context, TRUE, FALSE, time); - } else if (html_mode && e_composer_selection_is_base64_uris (composer, selection)) { - const guchar *data; - gint length; - gint list_len, len; - gchar *uri; - data = gtk_selection_data_get_data (selection); - length = gtk_selection_data_get_length (selection); - - if (!data || length < 0) { - gtk_drag_finish (context, FALSE, FALSE, time); + /* If we're receiving URIs and -all- the URIs point to + * image files, we want the image(s) to be inserted in + * the message body. Let GtkHtml handle it. */ + if (e_composer_selection_is_image_uris (composer, selection)) return; - } - - e_html_editor_selection_set_on_point (editor_selection, x, y); - - list_len = length; - do { - uri = next_uri ((guchar **) &data, &len, &list_len); + } - e_html_editor_selection_insert_image (editor_selection, uri); - } while (list_len); + view = e_msg_composer_get_attachment_view (composer); - gtk_drag_finish (context, TRUE, FALSE, time); - } else { - EAttachmentView *view = e_msg_composer_get_attachment_view (composer); + /* Forward the data to the attachment view. Note that calling + * e_attachment_view_drag_data_received() will not work because + * that function only handles the case where all the other drag + * handlers have failed. */ + e_attachment_paned_drag_data_received ( + E_ATTACHMENT_PANED (view), + context, x, y, selection, info, time); - /* Forward the data to the attachment view. Note that calling - * e_attachment_view_drag_data_received() will not work because - * that function only handles the case where all the other drag - * handlers have failed. */ - e_attachment_paned_drag_data_received ( - E_ATTACHMENT_PANED (view), - context, x, y, selection, info, time); - } + /* Stop the signal from propagating to GtkHtml. */ + g_signal_stop_emission_by_name (widget, "drag-data-received"); } static void msg_composer_notify_header_cb (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, TRUE); } static gboolean @@ -2144,12 +1933,6 @@ GParamSpec *pspec) { switch (property_id) { - case PROP_BUSY: - g_value_set_boolean ( - value, e_msg_composer_is_busy ( - E_MSG_COMPOSER (object))); - return; - case PROP_FOCUS_TRACKER: g_value_set_object ( value, e_msg_composer_get_focus_tracker ( @@ -2209,71 +1992,30 @@ } static void -composer_notify_activity_cb (EActivityBar *activity_bar, - GParamSpec *pspec, - EMsgComposer *composer) -{ - EHTMLEditor *editor; - EHTMLEditorView *view; - WebKitWebView *web_view; - gboolean editable; - gboolean busy; - - busy = (e_activity_bar_get_activity (activity_bar) != NULL); - - if (busy == composer->priv->busy) - return; - - composer->priv->busy = busy; - - if (busy) - e_msg_composer_save_focused_widget (composer); - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - web_view = WEBKIT_WEB_VIEW (view); - - if (busy) { - editable = webkit_web_view_get_editable (web_view); - webkit_web_view_set_editable (web_view, FALSE); - composer->priv->saved_editable = editable; - } else { - editable = composer->priv->saved_editable; - webkit_web_view_set_editable (web_view, editable); - } - - g_object_notify (G_OBJECT (composer), "busy"); - - if (!busy) - e_msg_composer_restore_focus_on_composer (composer); -} - -static void msg_composer_constructed (GObject *object) { EShell *shell; + GtkhtmlEditor *editor; EMsgComposer *composer; - EActivityBar *activity_bar; EAttachmentView *view; EAttachmentStore *store; EComposerHeaderTable *table; - EHTMLEditor *editor; - EHTMLEditorView *html_editor_view; + EWebViewGtkHTML *web_view; GtkUIManager *ui_manager; GtkToggleAction *action; GSettings *settings; const gchar *id; gboolean active; + editor = GTKHTML_EDITOR (object); composer = E_MSG_COMPOSER (object); shell = e_msg_composer_get_shell (composer); e_composer_private_constructed (composer); - editor = e_msg_composer_get_editor (composer); - html_editor_view = e_html_editor_get_view (editor); - ui_manager = e_html_editor_get_ui_manager (editor); + web_view = e_msg_composer_get_web_view (composer); + ui_manager = gtkhtml_editor_get_ui_manager (editor); view = e_msg_composer_get_attachment_view (composer); table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table); @@ -2303,82 +2045,63 @@ "/org/gnome/evolution/mail/composer-window/", E_RESTORE_WINDOW_SIZE); - activity_bar = e_html_editor_get_activity_bar (editor); - g_signal_connect ( - activity_bar, "notify::activity", - G_CALLBACK (composer_notify_activity_cb), composer); - - /* Honor User Preferences */ /* FIXME This should be an EMsgComposer property. */ - settings = e_util_ref_settings ("org.gnome.evolution.mail"); + settings = g_settings_new ("org.gnome.evolution.mail"); action = GTK_TOGGLE_ACTION (ACTION (REQUEST_READ_RECEIPT)); active = g_settings_get_boolean (settings, "composer-request-receipt"); gtk_toggle_action_set_active (action, active); - - action = GTK_TOGGLE_ACTION (ACTION (UNICODE_SMILEYS)); - active = g_settings_get_boolean (settings, "composer-unicode-smileys"); - gtk_toggle_action_set_active (action, active); g_object_unref (settings); /* Clipboard Support */ g_signal_connect ( - html_editor_view, "paste-clipboard", + web_view, "paste-clipboard", G_CALLBACK (msg_composer_paste_clipboard_cb), composer); - g_signal_connect ( - html_editor_view, "paste-primary-clipboard", - G_CALLBACK (msg_composer_paste_primary_clipboard_cb), composer); - /* Drag-and-Drop Support */ g_signal_connect ( - html_editor_view, "drag-motion", - G_CALLBACK (msg_composer_drag_motion_cb), composer); + web_view, "realize", + G_CALLBACK (msg_composer_realize_gtkhtml_cb), composer); g_signal_connect ( - html_editor_view, "drag-drop", - G_CALLBACK (msg_composer_drag_drop_cb), composer); + web_view, "drag-motion", + G_CALLBACK (msg_composer_drag_motion_cb), composer); g_signal_connect ( - html_editor_view, "drag-data-received", + web_view, "drag-data-received", G_CALLBACK (msg_composer_drag_data_received_cb), composer); - /* Used for fixing various stuff after WebKit processed the DnD data. */ - g_signal_connect_after ( - html_editor_view, "drag-data-received", - G_CALLBACK (msg_composer_drag_data_received_after_cb), composer); - g_signal_connect ( composer->priv->gallery_icon_view, "drag-data-get", G_CALLBACK (msg_composer_gallery_drag_data_get), NULL); /* Configure Headers */ - composer->priv->notify_destinations_bcc_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::destinations-bcc", G_CALLBACK (msg_composer_notify_header_cb), composer); - composer->priv->notify_destinations_cc_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::destinations-cc", G_CALLBACK (msg_composer_notify_header_cb), composer); - composer->priv->notify_destinations_to_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::destinations-to", G_CALLBACK (msg_composer_notify_header_cb), composer); - composer->priv->notify_identity_uid_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::identity-uid", G_CALLBACK (msg_composer_mail_identity_changed_cb), composer); - composer->priv->notify_reply_to_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::reply-to", G_CALLBACK (msg_composer_notify_header_cb), composer); - composer->priv->notify_signature_uid_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::signature-uid", G_CALLBACK (e_composer_update_signature), composer); - composer->priv->notify_subject_changed_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::subject", G_CALLBACK (msg_composer_subject_changed_cb), composer); - composer->priv->notify_subject_handler = e_signal_connect_notify_swapped ( + e_signal_connect_notify_swapped ( table, "notify::subject", G_CALLBACK (msg_composer_notify_header_cb), composer); @@ -2397,13 +2120,7 @@ G_CALLBACK (attachment_store_changed_cb), composer); /* Initialization may have tripped the "changed" state. */ - e_html_editor_view_set_changed (html_editor_view, FALSE); - - gtk_target_list_add_table ( - gtk_drag_dest_get_target_list ( - GTK_WIDGET (html_editor_view)), - drag_dest_targets, - G_N_ELEMENTS (drag_dest_targets)); + gtkhtml_editor_set_changed (editor, FALSE); id = "org.gnome.evolution.composer"; e_plugin_ui_register_manager (ui_manager, id, composer); @@ -2411,7 +2128,6 @@ e_extensible_load_extensions (E_EXTENSIBLE (composer)); - e_msg_composer_set_body_text (composer, "", TRUE); /* Chain up to parent's constructed() method. */ G_OBJECT_CLASS (e_msg_composer_parent_class)->constructed (object); } @@ -2420,12 +2136,11 @@ msg_composer_dispose (GObject *object) { EMsgComposer *composer = E_MSG_COMPOSER (object); - EMsgComposerPrivate *priv = E_MSG_COMPOSER_GET_PRIVATE (composer); EShell *shell; - if (priv->address_dialog != NULL) { - gtk_widget_destroy (priv->address_dialog); - priv->address_dialog = NULL; + if (composer->priv->address_dialog != NULL) { + gtk_widget_destroy (composer->priv->address_dialog); + composer->priv->address_dialog = NULL; } /* FIXME Our EShell is already unreferenced. */ @@ -2436,27 +2151,6 @@ g_signal_handlers_disconnect_by_func ( shell, msg_composer_prepare_for_quit_cb, composer); - if (priv->header_table != NULL) { - EComposerHeaderTable *table; - - table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table); - - e_signal_disconnect_notify_handler ( - table, &priv->notify_destinations_bcc_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_destinations_cc_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_destinations_to_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_identity_uid_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_reply_to_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_destinations_to_handler); - e_signal_disconnect_notify_handler ( - table, &priv->notify_subject_changed_handler); - } - e_composer_private_dispose (composer); /* Chain up to parent's dispose() method. */ @@ -2466,19 +2160,14 @@ static void msg_composer_map (GtkWidget *widget) { - EMsgComposer *composer; EComposerHeaderTable *table; GtkWidget *input_widget; - EHTMLEditor *editor; - EHTMLEditorView *view; const gchar *text; /* Chain up to parent's map() method. */ GTK_WIDGET_CLASS (e_msg_composer_parent_class)->map (widget); - composer = E_MSG_COMPOSER (widget); - editor = e_msg_composer_get_editor (composer); - table = e_msg_composer_get_header_table (composer); + table = e_msg_composer_get_header_table (E_MSG_COMPOSER (widget)); /* If the 'To' field is empty, focus it. */ input_widget = @@ -2501,8 +2190,7 @@ } /* Jump to the editor as a last resort. */ - view = e_html_editor_get_view (editor); - gtk_widget_grab_focus (GTK_WIDGET (view)); + gtkhtml_editor_run_command (GTKHTML_EDITOR (widget), "grab-focus"); } static gboolean @@ -2511,12 +2199,12 @@ { EMsgComposer *composer; GtkWidget *input_widget; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; + EWebViewGtkHTML *web_view; + editor = GTKHTML_EDITOR (widget); composer = E_MSG_COMPOSER (widget); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); + web_view = e_msg_composer_get_web_view (composer); input_widget = e_composer_header_table_get_header ( @@ -2530,55 +2218,179 @@ } #endif /* HAVE_XFREE */ - if (event->keyval == GDK_KEY_Escape) { - gtk_action_activate (ACTION (CLOSE)); - return TRUE; - } + if (event->keyval == GDK_KEY_Escape) { + gtk_action_activate (ACTION (CLOSE)); + return TRUE; + } + + if (event->keyval == GDK_KEY_Tab && gtk_widget_is_focus (input_widget)) { + gtkhtml_editor_run_command (editor, "grab-focus"); + return TRUE; + } + + if (event->keyval == GDK_KEY_ISO_Left_Tab && + gtk_widget_is_focus (GTK_WIDGET (web_view))) { + gtk_widget_grab_focus (input_widget); + return TRUE; + } + + /* Chain up to parent's key_press_event() method. */ + return GTK_WIDGET_CLASS (e_msg_composer_parent_class)-> + key_press_event (widget, event); +} + +static void +msg_composer_cut_clipboard (GtkhtmlEditor *editor) +{ + /* Do nothing. EFocusTracker handles this. */ +} + +static void +msg_composer_copy_clipboard (GtkhtmlEditor *editor) +{ + /* Do nothing. EFocusTracker handles this. */ +} + +static void +msg_composer_paste_clipboard (GtkhtmlEditor *editor) +{ + /* Do nothing. EFocusTracker handles this. */ +} + +static void +msg_composer_select_all (GtkhtmlEditor *editor) +{ + /* Do nothing. EFocusTracker handles this. */ +} + +static void +msg_composer_command_before (GtkhtmlEditor *editor, + const gchar *command) +{ + EMsgComposer *composer; + const gchar *data; + + composer = E_MSG_COMPOSER (editor); + + if (strcmp (command, "insert-paragraph") != 0) + return; + + if (composer->priv->in_signature_insert) + return; + + data = gtkhtml_editor_get_paragraph_data (editor, "orig"); + if (data != NULL && *data == '1') { + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); + return; + }; + + data = gtkhtml_editor_get_paragraph_data (editor, "signature"); + if (data != NULL && *data == '1') { + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); + } +} + +static void +msg_composer_command_after (GtkhtmlEditor *editor, + const gchar *command) +{ + EMsgComposer *composer; + const gchar *data; + + composer = E_MSG_COMPOSER (editor); + + if (strcmp (command, "insert-paragraph") != 0) + return; + + if (composer->priv->in_signature_insert) + return; + + gtkhtml_editor_run_command (editor, "italic-off"); + + data = gtkhtml_editor_get_paragraph_data (editor, "orig"); + if (data != NULL && *data == '1') + e_msg_composer_reply_indent (composer); + gtkhtml_editor_set_paragraph_data (editor, "orig", "0"); + + data = gtkhtml_editor_get_paragraph_data (editor, "signature"); + if (data == NULL || *data != '1') + return; + + /* Clear the signature. */ + if (gtkhtml_editor_is_paragraph_empty (editor)) + gtkhtml_editor_set_paragraph_data (editor, "signature" ,"0"); + + else if (gtkhtml_editor_is_previous_paragraph_empty (editor) && + gtkhtml_editor_run_command (editor, "cursor-backward")) { + + gtkhtml_editor_set_paragraph_data (editor, "signature", "0"); + gtkhtml_editor_run_command (editor, "cursor-forward"); + } + + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); +} + +static gchar * +msg_composer_image_uri (GtkhtmlEditor *editor, + const gchar *uri) +{ + EMsgComposer *composer; + GHashTable *hash_table; + CamelMimePart *part; + const gchar *cid; + + composer = E_MSG_COMPOSER (editor); - if (event->keyval == GDK_KEY_Tab && gtk_widget_is_focus (input_widget)) { - gtk_widget_grab_focus (GTK_WIDGET (view)); - return TRUE; + hash_table = composer->priv->inline_images_by_url; + part = g_hash_table_lookup (hash_table, uri); + + if (part == NULL && g_str_has_prefix (uri, "file:")) + part = e_msg_composer_add_inline_image_from_file ( + composer, uri + 5); + + if (part == NULL && g_str_has_prefix (uri, "cid:")) { + hash_table = composer->priv->inline_images; + part = g_hash_table_lookup (hash_table, uri); } - if (gtk_widget_is_focus (GTK_WIDGET (view))) { - if (event->keyval == GDK_KEY_ISO_Left_Tab) { - gboolean view_processed = FALSE; + if (part == NULL) + return NULL; - g_signal_emit_by_name (view, "key-press-event", event, &view_processed); + composer->priv->current_images = + g_list_prepend (composer->priv->current_images, part); - if (!view_processed) - gtk_widget_grab_focus (input_widget); + cid = camel_mime_part_get_content_id (part); + if (cid == NULL) + return NULL; - return TRUE; - } + return g_strconcat ("cid:", cid, NULL); +} - if ((((event)->state & GDK_SHIFT_MASK) && - ((event)->keyval == GDK_KEY_Insert)) || - (((event)->state & GDK_CONTROL_MASK) && - ((event)->keyval == GDK_KEY_v))) { - g_signal_emit_by_name ( - WEBKIT_WEB_VIEW (view), "paste-clipboard"); - return TRUE; - } +static void +msg_composer_object_deleted (GtkhtmlEditor *editor) +{ + const gchar *data; - if (((event)->state & GDK_CONTROL_MASK) && - ((event)->keyval == GDK_KEY_Insert)) { - g_signal_emit_by_name ( - WEBKIT_WEB_VIEW (view), "copy-clipboard"); - return TRUE; - } + if (!gtkhtml_editor_is_paragraph_empty (editor)) + return; - if (((event)->state & GDK_SHIFT_MASK) && - ((event)->keyval == GDK_KEY_Delete)) { - g_signal_emit_by_name ( - WEBKIT_WEB_VIEW (view), "cut-clipboard"); - return TRUE; - } + data = gtkhtml_editor_get_paragraph_data (editor, "orig"); + if (data != NULL && *data == '1') { + gtkhtml_editor_set_paragraph_data (editor, "orig", "0"); + gtkhtml_editor_run_command (editor, "indent-zero"); + gtkhtml_editor_run_command (editor, "style-normal"); + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); + gtkhtml_editor_run_command (editor, "insert-paragraph"); + gtkhtml_editor_run_command (editor, "delete-back"); } - /* Chain up to parent's key_press_event() method. */ - return GTK_WIDGET_CLASS (e_msg_composer_parent_class)-> - key_press_event (widget, event); + data = gtkhtml_editor_get_paragraph_data (editor, "signature"); + if (data != NULL && *data == '1') + gtkhtml_editor_set_paragraph_data (editor, "signature", "0"); } static gboolean @@ -2588,6 +2400,34 @@ return TRUE; } +static void +msg_composer_submit_alert (EAlertSink *alert_sink, + EAlert *alert) +{ + EMsgComposerPrivate *priv; + EAlertBar *alert_bar; + GtkWidget *dialog; + GtkWindow *parent; + + priv = E_MSG_COMPOSER_GET_PRIVATE (alert_sink); + + switch (e_alert_get_message_type (alert)) { + case GTK_MESSAGE_INFO: + case GTK_MESSAGE_WARNING: + case GTK_MESSAGE_ERROR: + alert_bar = E_ALERT_BAR (priv->alert_bar); + e_alert_bar_add_alert (alert_bar, alert); + break; + + default: + parent = GTK_WINDOW (alert_sink); + dialog = e_alert_dialog_new (parent, alert); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); + break; + } +} + static gboolean msg_composer_accumulator_false_abort (GSignalInvocationHint *ihint, GValue *return_accu, @@ -2603,27 +2443,12 @@ return v_boolean; } -/** - * e_msg_composer_is_busy: - * @composer: an #EMsgComposer - * - * Returns %TRUE only while an #EActivity is in progress. - * - * Returns: whether @composer is busy - **/ -gboolean -e_msg_composer_is_busy (EMsgComposer *composer) -{ - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), FALSE); - - return composer->priv->busy; -} - static void e_msg_composer_class_init (EMsgComposerClass *class) { GObjectClass *object_class; GtkWidgetClass *widget_class; + GtkhtmlEditorClass *editor_class; g_type_class_add_private (class, sizeof (EMsgComposerPrivate)); @@ -2638,18 +2463,18 @@ widget_class->map = msg_composer_map; widget_class->key_press_event = msg_composer_key_press_event; - class->presend = msg_composer_presend; + editor_class = GTKHTML_EDITOR_CLASS (class); + editor_class->cut_clipboard = msg_composer_cut_clipboard; + editor_class->copy_clipboard = msg_composer_copy_clipboard; + editor_class->paste_clipboard = msg_composer_paste_clipboard; + editor_class->select_all = msg_composer_select_all; + editor_class->command_before = msg_composer_command_before; + editor_class->command_after = msg_composer_command_after; + editor_class->image_uri = msg_composer_image_uri; + editor_class->link_clicked = NULL; /* EWebView handles this */ + editor_class->object_deleted = msg_composer_object_deleted; - g_object_class_install_property ( - object_class, - PROP_BUSY, - g_param_spec_boolean ( - "busy", - "Busy", - "Whether an activity is in progress", - FALSE, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + class->presend = msg_composer_presend; g_object_class_install_property ( object_class, @@ -2728,11 +2553,15 @@ } static void +e_msg_composer_alert_sink_init (EAlertSinkInterface *iface) +{ + iface->submit_alert = msg_composer_submit_alert; +} + +static void e_msg_composer_init (EMsgComposer *composer) { composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer); - - composer->priv->editor = g_object_ref_sink (e_html_editor_new ()); } /** @@ -2750,23 +2579,7 @@ return g_object_new ( E_TYPE_MSG_COMPOSER, - "shell", shell, NULL); -} - -/** - * e_msg_composer_get_editor: - * @composer: an #EMsgComposer - * - * Returns @composer's internal #EHTMLEditor instance. - * - * Returns: an #EHTMLEditor - **/ -EHTMLEditor * -e_msg_composer_get_editor (EMsgComposer *composer) -{ - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - - return composer->priv->editor; + "html", e_web_view_gtkhtml_new (), "shell", shell, NULL); } EFocusTracker * @@ -2780,13 +2593,9 @@ static void e_msg_composer_set_pending_body (EMsgComposer *composer, gchar *text, - gssize length, - gboolean is_html) + gssize length) { g_object_set_data_full ( - G_OBJECT (composer), "body:text_mime_type", - GINT_TO_POINTER (is_html), NULL); - g_object_set_data_full ( G_OBJECT (composer), "body:text", text, (GDestroyNotify) g_free); } @@ -2795,14 +2604,11 @@ e_msg_composer_flush_pending_body (EMsgComposer *composer) { const gchar *body; - gboolean is_html; body = g_object_get_data (G_OBJECT (composer), "body:text"); - is_html = GPOINTER_TO_INT ( - g_object_get_data (G_OBJECT (composer), "body:text_mime_type")); if (body != NULL) - set_editor_text (composer, body, is_html, FALSE); + set_editor_text (composer, body, FALSE); g_object_set_data (G_OBJECT (composer), "body:text", NULL); } @@ -2816,16 +2622,12 @@ { CamelContentType *content_type; CamelDataWrapper *wrapper; - EHTMLEditor *editor; - EHTMLEditorView *view; if (!mime_part) return; content_type = camel_mime_part_get_content_type (mime_part); wrapper = camel_medium_get_content (CAMEL_MEDIUM (mime_part)); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); if (CAMEL_IS_MULTIPART (wrapper)) { /* another layer of multipartness... */ @@ -2835,10 +2637,10 @@ } else if (just_inlines) { if (camel_mime_part_get_content_id (mime_part) || camel_mime_part_get_content_location (mime_part)) - e_html_editor_view_add_inline_image_from_mime_part ( - view, mime_part); + e_msg_composer_add_inline_image_from_mime_part ( + composer, mime_part); } else if (related && camel_content_type_is (content_type, "image", "*")) { - e_html_editor_view_add_inline_image_from_mime_part (view, mime_part); + e_msg_composer_add_inline_image_from_mime_part (composer, mime_part); } else if (camel_content_type_is (content_type, "text", "*") && camel_mime_part_get_filename (mime_part) == NULL) { /* Do nothing if this is a text/anything without a @@ -2982,7 +2784,7 @@ html = emcu_part_to_html ( composer, mime_part, &length, keep_signature, cancellable); if (html) - e_msg_composer_set_pending_body (composer, html, length, TRUE); + e_msg_composer_set_pending_body (composer, html, length); } else { e_msg_composer_attach (composer, mime_part); @@ -3074,7 +2876,7 @@ html = emcu_part_to_html ( composer, mime_part, &length, keep_signature, cancellable); if (html) - e_msg_composer_set_pending_body (composer, html, length, TRUE); + e_msg_composer_set_pending_body (composer, html, length); } else { e_msg_composer_attach (composer, mime_part); @@ -3163,7 +2965,7 @@ html = emcu_part_to_html ( composer, fallback_text_part, &length, keep_signature, cancellable); if (html) - e_msg_composer_set_pending_body (composer, html, length, TRUE); + e_msg_composer_set_pending_body (composer, html, length); } } @@ -3222,53 +3024,21 @@ } } else if (depth == 0 && i == 0) { - EHTMLEditor *editor; - gboolean is_message_from_draft, is_html = FALSE; gchar *html; gssize length; - editor = e_msg_composer_get_editor (composer); - is_message_from_draft = e_html_editor_view_is_message_from_draft ( - e_html_editor_get_view (editor)); - is_html = camel_content_type_is (content_type, "text", "html"); - /* Since the first part is not multipart/alternative, * this must be the body. */ - - /* If we are opening message from Drafts */ - if (is_message_from_draft) { - /* Extract the body */ - CamelDataWrapper *dw; - - dw = camel_medium_get_content ((CamelMedium *) mime_part); - if (dw) { - CamelStream *mem = camel_stream_mem_new (); - GByteArray *bytes; - - camel_data_wrapper_decode_to_stream_sync (dw, mem, cancellable, NULL); - camel_stream_close (mem, cancellable, NULL); - - bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem)); - if (bytes && bytes->len) - html = g_strndup ((const gchar *) bytes->data, bytes->len); - - g_object_unref (mem); - } - } else { - is_html = TRUE; - html = emcu_part_to_html ( - composer, mime_part, &length, keep_signature, cancellable); - } - e_msg_composer_set_pending_body (composer, html, length, is_html); + html = emcu_part_to_html ( + composer, mime_part, &length, keep_signature, cancellable); + if (html) + e_msg_composer_set_pending_body (composer, html, length); } else if (camel_mime_part_get_content_id (mime_part) || camel_mime_part_get_content_location (mime_part)) { /* special in-line attachment */ - EHTMLEditor *editor; - - editor = e_msg_composer_get_editor (composer); - e_html_editor_view_add_inline_image_from_mime_part ( - e_html_editor_get_view (editor), mime_part); + e_msg_composer_add_inline_image_from_mime_part ( + composer, mime_part); } else { /* normal attachment */ @@ -3280,50 +3050,28 @@ static void set_signature_gui (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; - WebKitDOMDocument *document; - WebKitDOMNodeList *nodes; + GtkhtmlEditor *editor; EComposerHeaderTable *table; EMailSignatureComboBox *combo_box; + const gchar *data; gchar *uid; - gulong ii, length; + editor = GTKHTML_EDITOR (composer); table = e_msg_composer_get_header_table (composer); combo_box = e_composer_header_table_get_signature_combo_box (table); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - - uid = NULL; - nodes = webkit_dom_document_get_elements_by_class_name ( - document, "-x-evo-signature"); - length = webkit_dom_node_list_get_length (nodes); - for (ii = 0; ii < length; ii++) { - WebKitDOMNode *node; - gchar *id; + if (!gtkhtml_editor_search_by_data (editor, 1, "ClueFlow", "signature", "1")) + return; - node = webkit_dom_node_list_item (nodes, ii); - id = webkit_dom_element_get_id (WEBKIT_DOM_ELEMENT (node)); - if (id && (strlen (id) == 1) && (*id == '1')) { - uid = webkit_dom_element_get_attribute ( - WEBKIT_DOM_ELEMENT (node), "name"); - g_free (id); - g_object_unref (node); - break; - } - g_free (id); - g_object_unref (node); - } + data = gtkhtml_editor_get_paragraph_data (editor, "signature_name"); - g_object_unref (nodes); + if (!g_str_has_prefix (data, "uid:")) + return; /* The combo box active ID is the signature's ESource UID. */ - if (uid != NULL) { - gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid); - g_free (uid); - } + uid = e_composer_decode_clue_value (data + 4); + gtk_combo_box_set_active_id (GTK_COMBO_BOX (combo_box), uid); + g_free (uid); } static void @@ -3391,9 +3139,9 @@ gboolean keep_signature, GCancellable *cancellable) { - CamelInternetAddress *from, *to, *cc, *bcc; + CamelInternetAddress *to, *cc, *bcc; GList *To = NULL, *Cc = NULL, *Bcc = NULL, *postto = NULL; - const gchar *format, *subject, *composer_mode; + const gchar *format, *subject; EDestination **Tov, **Ccv, **Bccv; GHashTable *auto_cc, *auto_bcc; CamelContentType *content_type; @@ -3403,13 +3151,10 @@ EMsgComposerPrivate *priv; EComposerHeaderTable *table; ESource *source = NULL; - EHTMLEditor *editor; - EHTMLEditorView *view; GtkToggleAction *action; struct _camel_header_raw *xev; gchar *identity_uid; gint len, i; - gboolean is_message_from_draft = FALSE; g_return_val_if_fail (E_IS_SHELL (shell), NULL); @@ -3427,9 +3172,7 @@ composer = e_msg_composer_new (shell); priv = E_MSG_COMPOSER_GET_PRIVATE (composer); - editor = e_msg_composer_get_editor (composer); table = e_msg_composer_get_header_table (composer); - view = e_html_editor_get_view (editor); if (postto) { e_composer_header_table_set_post_to_list (table, postto); @@ -3446,13 +3189,7 @@ identity_uid = (gchar *) camel_medium_get_header ( CAMEL_MEDIUM (message), "X-Evolution-Account"); } - if (!identity_uid) { - source = em_utils_guess_mail_identity_with_recipients ( - e_shell_get_registry (shell), message, NULL, NULL); - if (source) - identity_uid = e_source_dup_uid (source); - } - if (identity_uid != NULL && !source) { + if (identity_uid != NULL) { identity_uid = g_strstrip (g_strdup (identity_uid)); source = e_composer_header_table_ref_source ( table, identity_uid); @@ -3551,47 +3288,9 @@ e_destination_freev (Ccv); e_destination_freev (Bccv); - from = camel_mime_message_get_from (message); - if (from) { - const gchar *name = NULL, *address = NULL; - - if (camel_address_length (CAMEL_ADDRESS (from)) == 1 && - camel_internet_address_get (from, 0, &name, &address)) { - EComposerFromHeader *header_from; - const gchar *filled_name, *filled_address; - - header_from = E_COMPOSER_FROM_HEADER (e_composer_header_table_get_header (table, E_COMPOSER_HEADER_FROM)); - - filled_name = e_composer_from_header_get_name (header_from); - filled_address = e_composer_from_header_get_address (header_from); - - if (name && !*name) - name = NULL; - - if (address && !*address) - address = NULL; - - if (g_strcmp0 (filled_name, name) != 0 || - g_strcmp0 (filled_address, address) != 0) { - e_composer_from_header_set_name (header_from, name); - e_composer_from_header_set_address (header_from, address); - e_composer_from_header_set_override_visible (header_from, TRUE); - } - } - } - /* Restore the format editing preference */ format = camel_medium_get_header ( CAMEL_MEDIUM (message), "X-Evolution-Format"); - - composer_mode = camel_medium_get_header ( - CAMEL_MEDIUM (message), "X-Evolution-Composer-Mode"); - - if (composer_mode && *composer_mode) { - is_message_from_draft = TRUE; - e_html_editor_view_set_is_message_from_draft (view, TRUE); - } - if (format != NULL) { gchar **flags; @@ -3601,21 +3300,11 @@ flags = g_strsplit (format, ", ", 0); for (i = 0; flags[i]; i++) { if (g_ascii_strcasecmp (flags[i], "text/html") == 0) { - if (composer_mode && g_ascii_strcasecmp (composer_mode, "text/html") == 0) { - e_html_editor_view_set_html_mode ( - view, TRUE); - } else { - e_html_editor_view_set_html_mode ( - view, FALSE); - } + gtkhtml_editor_set_html_mode ( + GTKHTML_EDITOR (composer), TRUE); } else if (g_ascii_strcasecmp (flags[i], "text/plain") == 0) { - if (composer_mode && g_ascii_strcasecmp (composer_mode, "text/html") == 0) { - e_html_editor_view_set_html_mode ( - view, TRUE); - } else { - e_html_editor_view_set_html_mode ( - view, FALSE); - } + gtkhtml_editor_set_html_mode ( + GTKHTML_EDITOR (composer), FALSE); } else if (g_ascii_strcasecmp (flags[i], "pgp-sign") == 0) { action = GTK_TOGGLE_ACTION (ACTION (PGP_SIGN)); gtk_toggle_action_set_active (action, TRUE); @@ -3702,13 +3391,11 @@ } } else { CamelMimePart *mime_part; - gboolean is_html = FALSE; - gchar *html = NULL; - gssize length = 0; + gchar *html; + gssize length; mime_part = CAMEL_MIME_PART (message); content_type = camel_mime_part_get_content_type (mime_part); - is_html = camel_content_type_is (content_type, "text", "html"); if (content_type != NULL && ( camel_content_type_is ( @@ -3721,36 +3408,14 @@ ACTION (SMIME_ENCRYPT)), TRUE); } - /* If we are opening message from Drafts */ - if (is_message_from_draft) { - /* Extract the body */ - CamelDataWrapper *dw; - - dw = camel_medium_get_content ((CamelMedium *) mime_part); - if (dw) { - CamelStream *mem = camel_stream_mem_new (); - GByteArray *bytes; - - camel_data_wrapper_decode_to_stream_sync (dw, mem, cancellable, NULL); - camel_stream_close (mem, cancellable, NULL); - - bytes = camel_stream_mem_get_byte_array (CAMEL_STREAM_MEM (mem)); - if (bytes && bytes->len) - html = g_strndup ((const gchar *) bytes->data, bytes->len); - - g_object_unref (mem); - } - } else { - is_html = TRUE; - html = emcu_part_to_html ( - composer, CAMEL_MIME_PART (message), - &length, keep_signature, cancellable); - } - e_msg_composer_set_pending_body (composer, html, length, is_html); + html = emcu_part_to_html ( + composer, CAMEL_MIME_PART (message), + &length, keep_signature, cancellable); + if (html) + e_msg_composer_set_pending_body (composer, html, length); } - e_html_editor_view_set_is_message_from_edit_as_new (view, TRUE); - priv->set_signature_from_message = TRUE; + priv->is_from_message = TRUE; /* We wait until now to set the body text because we need to * ensure that the attachment bar has all the attachments before @@ -3779,8 +3444,7 @@ { EMsgComposer *composer; EComposerHeaderTable *table; - EHTMLEditor *editor; - EHTMLEditorView *view; + EWebViewGtkHTML *web_view; const gchar *subject; g_return_val_if_fail (E_IS_SHELL (shell), NULL); @@ -3798,9 +3462,8 @@ e_composer_header_table_set_identity_uid (table, identity_uid); e_composer_header_table_set_subject (table, subject); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), FALSE); + web_view = e_msg_composer_get_web_view (composer); + e_web_view_gtkhtml_set_editable (web_view, FALSE); return composer; } @@ -3851,6 +3514,30 @@ return E_SHELL (composer->priv->shell); } +/** + * e_msg_composer_get_web_view: + * @composer: an #EMsgComposer + * + * Returns the #EWebView widget in @composer. + * + * Returns: the #EWebView + **/ +EWebViewGtkHTML * +e_msg_composer_get_web_view (EMsgComposer *composer) +{ + GtkHTML *html; + GtkhtmlEditor *editor; + + g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); + + /* This is a convenience function to avoid + * repeating this awkwardness everywhere */ + editor = GTKHTML_EDITOR (composer); + html = gtkhtml_editor_get_html (editor); + + return E_WEB_VIEW_GTKHTML (html); +} + static void msg_composer_send_cb (EMsgComposer *composer, GAsyncResult *result, @@ -3858,8 +3545,7 @@ { CamelMimeMessage *message; EAlertSink *alert_sink; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GError *error = NULL; alert_sink = e_activity_get_alert_sink (context->activity); @@ -3891,9 +3577,8 @@ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); /* The callback can set editor 'changed' if anything failed. */ - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, TRUE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, FALSE); g_signal_emit ( composer, signals[SEND], 0, @@ -3913,8 +3598,9 @@ void e_msg_composer_send (EMsgComposer *composer) { - EHTMLEditor *editor; AsyncContext *context; + EAlertSink *alert_sink; + EActivityBar *activity_bar; GCancellable *cancellable; gboolean proceed_with_send = TRUE; @@ -3928,12 +3614,18 @@ return; } - editor = e_msg_composer_get_editor (composer); - context = g_slice_new0 (AsyncContext); - context->activity = e_html_editor_new_activity (editor); + context->activity = e_composer_activity_new (composer); + + alert_sink = E_ALERT_SINK (composer); + e_activity_set_alert_sink (context->activity, alert_sink); - cancellable = e_activity_get_cancellable (context->activity); + cancellable = camel_operation_new (); + e_activity_set_cancellable (context->activity, cancellable); + g_object_unref (cancellable); + + activity_bar = E_ACTIVITY_BAR (composer->priv->activity_bar); + e_activity_bar_set_activity (activity_bar, context->activity); e_msg_composer_get_message ( composer, G_PRIORITY_DEFAULT, cancellable, @@ -3948,8 +3640,7 @@ { CamelMimeMessage *message; EAlertSink *alert_sink; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GError *error = NULL; alert_sink = e_activity_get_alert_sink (context->activity); @@ -3990,9 +3681,8 @@ g_return_if_fail (CAMEL_IS_MIME_MESSAGE (message)); /* The callback can set editor 'changed' if anything failed. */ - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, FALSE); + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, FALSE); g_signal_emit ( composer, signals[SAVE_TO_DRAFTS], @@ -4017,18 +3707,25 @@ void e_msg_composer_save_to_drafts (EMsgComposer *composer) { - EHTMLEditor *editor; AsyncContext *context; + EAlertSink *alert_sink; + EActivityBar *activity_bar; GCancellable *cancellable; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - editor = e_msg_composer_get_editor (composer); - context = g_slice_new0 (AsyncContext); - context->activity = e_html_editor_new_activity (editor); + context->activity = e_composer_activity_new (composer); + + alert_sink = E_ALERT_SINK (composer); + e_activity_set_alert_sink (context->activity, alert_sink); + + cancellable = camel_operation_new (); + e_activity_set_cancellable (context->activity, cancellable); + g_object_unref (cancellable); - cancellable = e_activity_get_cancellable (context->activity); + activity_bar = E_ACTIVITY_BAR (composer->priv->activity_bar); + e_activity_bar_set_activity (activity_bar, context->activity); e_msg_composer_get_message_draft ( composer, G_PRIORITY_DEFAULT, cancellable, @@ -4043,8 +3740,7 @@ { CamelMimeMessage *message; EAlertSink *alert_sink; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GError *error = NULL; alert_sink = e_activity_get_alert_sink (context->activity); @@ -4079,9 +3775,9 @@ async_context_free (context); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - e_html_editor_view_set_changed (view, FALSE); + /* XXX This should be elsewhere. */ + editor = GTKHTML_EDITOR (composer); + gtkhtml_editor_set_changed (editor, FALSE); } /** @@ -4093,8 +3789,9 @@ void e_msg_composer_save_to_outbox (EMsgComposer *composer) { - EHTMLEditor *editor; AsyncContext *context; + EAlertSink *alert_sink; + EActivityBar *activity_bar; GCancellable *cancellable; gboolean proceed_with_save = TRUE; @@ -4106,12 +3803,18 @@ if (!proceed_with_save) return; - editor = e_msg_composer_get_editor (composer); - context = g_slice_new0 (AsyncContext); - context->activity = e_html_editor_new_activity (editor); + context->activity = e_composer_activity_new (composer); + + alert_sink = E_ALERT_SINK (composer); + e_activity_set_alert_sink (context->activity, alert_sink); - cancellable = e_activity_get_cancellable (context->activity); + cancellable = camel_operation_new (); + e_activity_set_cancellable (context->activity, cancellable); + g_object_unref (cancellable); + + activity_bar = E_ACTIVITY_BAR (composer->priv->activity_bar); + e_activity_bar_set_activity (activity_bar, context->activity); e_msg_composer_get_message ( composer, G_PRIORITY_DEFAULT, cancellable, @@ -4173,19 +3876,26 @@ e_msg_composer_print (EMsgComposer *composer, GtkPrintOperationAction print_action) { - EHTMLEditor *editor; AsyncContext *context; + EAlertSink *alert_sink; + EActivityBar *activity_bar; GCancellable *cancellable; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - editor = e_msg_composer_get_editor (composer); - context = g_slice_new0 (AsyncContext); - context->activity = e_html_editor_new_activity (editor); + context->activity = e_composer_activity_new (composer); context->print_action = print_action; - cancellable = e_activity_get_cancellable (context->activity); + alert_sink = E_ALERT_SINK (composer); + e_activity_set_alert_sink (context->activity, alert_sink); + + cancellable = camel_operation_new (); + e_activity_set_cancellable (context->activity, cancellable); + g_object_unref (cancellable); + + activity_bar = E_ACTIVITY_BAR (composer->priv->activity_bar); + e_activity_bar_set_activity (activity_bar, context->activity); e_msg_composer_get_message_print ( composer, G_PRIORITY_DEFAULT, cancellable, @@ -4433,7 +4143,7 @@ camel_url_decode (content); if (file_is_blacklisted (content)) e_alert_submit ( - E_ALERT_SINK (e_msg_composer_get_editor (composer)), + E_ALERT_SINK (composer), "mail:blacklisted-file", content, NULL); if (g_ascii_strncasecmp (content, "file:", 5) == 0) @@ -4490,11 +4200,11 @@ g_free (subject); if (body) { - gchar *html_body; + gchar *htmlbody; - html_body = camel_text_to_html (body, CAMEL_MIME_FILTER_TOHTML_PRE, 0); - set_editor_text (composer, html_body, TRUE, TRUE); - g_free (html_body); + htmlbody = camel_text_to_html (body, CAMEL_MIME_FILTER_TOHTML_PRE, 0); + set_editor_text (composer, htmlbody, TRUE); + g_free (htmlbody); } } @@ -4539,8 +4249,7 @@ g_return_if_fail (E_IS_MSG_COMPOSER (composer)); g_return_if_fail (text != NULL); - /* Every usage of e_msg_composer_set_body_text is called with HTML text */ - set_editor_text (composer, text, TRUE, update_signature); + set_editor_text (composer, text, update_signature); } /** @@ -4558,16 +4267,13 @@ { EMsgComposerPrivate *priv = composer->priv; EComposerHeaderTable *table; - EHTMLEditor *editor; - EHTMLEditorView *view; + EWebViewGtkHTML *web_view; ESource *source; const gchar *identity_uid; - const gchar *content; + gchar *buff; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); table = e_msg_composer_get_header_table (composer); /* Disable signature */ @@ -4576,12 +4282,17 @@ identity_uid = e_composer_header_table_get_identity_uid (table); source = e_composer_header_table_ref_source (table, identity_uid); - content = _("The composer contains a non-text message body, which cannot be edited."); - set_editor_text (composer, content, TRUE, FALSE); + buff = g_markup_printf_escaped ( + "%s", + _("The composer contains a non-text " + "message body, which cannot be edited.")); + set_editor_text (composer, buff, FALSE); + g_free (buff); - e_html_editor_view_set_html_mode (view, FALSE); - e_html_editor_view_set_remove_initial_input_line (view, TRUE); - webkit_web_view_set_editable (WEBKIT_WEB_VIEW (view), FALSE); + gtkhtml_editor_set_html_mode (GTKHTML_EDITOR (composer), FALSE); + + web_view = e_msg_composer_get_web_view (composer); + e_web_view_gtkhtml_set_editable (web_view, FALSE); g_free (priv->mime_body); priv->mime_body = g_strdup (body); @@ -4792,12 +4503,109 @@ attachment = e_attachment_new (); e_attachment_set_mime_part (attachment, mime_part); e_attachment_store_add_attachment (store, attachment); - e_attachment_load_async ( - attachment, (GAsyncReadyCallback) - e_attachment_load_handle_error, composer); + e_attachment_load (attachment, NULL); g_object_unref (attachment); } +/** + * e_msg_composer_add_inline_image_from_file: + * @composer: a composer object + * @filename: the name of the file containing the image + * + * This reads in the image in @filename and adds it to @composer + * as an inline image, to be wrapped in a multipart/related. + * + * Returns: the newly-created CamelMimePart (which must be reffed + * if the caller wants to keep its own reference), or %NULL on error. + **/ +CamelMimePart * +e_msg_composer_add_inline_image_from_file (EMsgComposer *composer, + const gchar *filename) +{ + gchar *mime_type, *cid, *url, *name, *dec_file_name; + CamelStream *stream; + CamelDataWrapper *wrapper; + CamelMimePart *part; + EMsgComposerPrivate *p = composer->priv; + + dec_file_name = g_strdup (filename); + camel_url_decode (dec_file_name); + + if (!g_file_test (dec_file_name, G_FILE_TEST_IS_REGULAR)) + return NULL; + + stream = camel_stream_fs_new_with_name ( + dec_file_name, O_RDONLY, 0, NULL); + if (!stream) + return NULL; + + wrapper = camel_data_wrapper_new (); + camel_data_wrapper_construct_from_stream_sync ( + wrapper, stream, NULL, NULL); + g_object_unref (CAMEL_OBJECT (stream)); + + mime_type = e_util_guess_mime_type (dec_file_name, TRUE); + if (mime_type == NULL) + mime_type = g_strdup ("application/octet-stream"); + camel_data_wrapper_set_mime_type (wrapper, mime_type); + g_free (mime_type); + + part = camel_mime_part_new (); + camel_medium_set_content (CAMEL_MEDIUM (part), wrapper); + g_object_unref (wrapper); + + cid = msg_composer_generate_msg_id (composer); + camel_mime_part_set_content_id (part, cid); + name = g_path_get_basename (dec_file_name); + camel_mime_part_set_filename (part, name); + g_free (name); + camel_mime_part_set_encoding (part, CAMEL_TRANSFER_ENCODING_BASE64); + + url = g_strdup_printf ("file:%s", dec_file_name); + g_hash_table_insert (p->inline_images_by_url, url, part); + + url = g_strdup_printf ("cid:%s", cid); + g_hash_table_insert (p->inline_images, url, part); + g_free (cid); + + g_free (dec_file_name); + + return part; +} + +/** + * e_msg_composer_add_inline_image_from_mime_part: + * @composer: a composer object + * @part: a CamelMimePart containing image data + * + * This adds the mime part @part to @composer as an inline image, to + * be wrapped in a multipart/related. + **/ +void +e_msg_composer_add_inline_image_from_mime_part (EMsgComposer *composer, + CamelMimePart *part) +{ + gchar *url; + const gchar *location, *cid; + EMsgComposerPrivate *p = composer->priv; + + cid = camel_mime_part_get_content_id (part); + if (!cid) { + camel_mime_part_set_content_id (part, NULL); + cid = camel_mime_part_get_content_id (part); + } + + url = g_strdup_printf ("cid:%s", cid); + g_hash_table_insert (p->inline_images, url, part); + g_object_ref (part); + + location = camel_mime_part_get_content_location (part); + if (location != NULL) + g_hash_table_insert ( + p->inline_images_by_url, + g_strdup (location), part); +} + static void composer_get_message_ready (EMsgComposer *composer, GAsyncResult *result, @@ -4840,21 +4648,16 @@ GSimpleAsyncResult *simple; GtkAction *action; ComposerFlags flags = 0; - EHTMLEditor *editor; - EHTMLEditorView *view; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - simple = g_simple_async_result_new ( G_OBJECT (composer), callback, user_data, e_msg_composer_get_message); g_simple_async_result_set_check_cancellable (simple, cancellable); - if (e_html_editor_view_get_html_mode (view)) + if (gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (composer))) flags |= COMPOSER_FLAG_HTML_CONTENT; action = ACTION (PRIORITIZE_MESSAGE); @@ -4971,10 +4774,8 @@ GAsyncReadyCallback callback, gpointer user_data) { - EHTMLEditor *editor; - EHTMLEditorView *view; GSimpleAsyncResult *simple; - ComposerFlags flags = COMPOSER_FLAG_SAVE_DRAFT; + ComposerFlags flags = COMPOSER_FLAG_DRAFT; GtkAction *action; g_return_if_fail (E_IS_MSG_COMPOSER (composer)); @@ -4985,13 +4786,8 @@ g_simple_async_result_set_check_cancellable (simple, cancellable); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - /* We need to remember composer mode */ - if (e_html_editor_view_get_html_mode (view)) - flags |= COMPOSER_FLAG_HTML_MODE; - /* We want to save HTML content everytime when we save as draft */ - flags |= COMPOSER_FLAG_SAVE_DRAFT; + if (gtkhtml_editor_get_html_mode (GTKHTML_EDITOR (composer))) + flags |= COMPOSER_FLAG_HTML_CONTENT; action = ACTION (PRIORITIZE_MESSAGE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) @@ -5113,47 +4909,6 @@ } /** - * e_msg_composer_get_raw_message_text_without_signature: - * - * Returns the text/plain of the message from composer without signature - **/ -GByteArray * -e_msg_composer_get_raw_message_text_without_signature (EMsgComposer *composer) -{ - EHTMLEditor *editor; - EHTMLEditorView *view; - GByteArray *array; - gint ii, length; - WebKitDOMDocument *document; - WebKitDOMNodeList *list; - - g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - array = g_byte_array_new (); - - list = webkit_dom_document_query_selector_all ( - document, "body > *:not(.-x-evo-signature-wrapper)", NULL); - length = webkit_dom_node_list_get_length (list); - for (ii = 0; ii < length; ii++) { - gchar *text; - WebKitDOMNode *node = webkit_dom_node_list_item (list, ii); - - text = webkit_dom_html_element_get_inner_text ( - WEBKIT_DOM_HTML_ELEMENT (node)); - g_byte_array_append (array, (guint8 *) text, strlen (text)); - g_free (text); - g_object_unref (node); - } - - g_object_unref (list); - - return array; -} - -/** * e_msg_composer_get_raw_message_text: * * Returns the text/plain of the message from composer @@ -5161,23 +4916,17 @@ GByteArray * e_msg_composer_get_raw_message_text (EMsgComposer *composer) { - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; GByteArray *array; gchar *text; - WebKitDOMDocument *document; - WebKitDOMHTMLElement *body; + gsize length; g_return_val_if_fail (E_IS_MSG_COMPOSER (composer), NULL); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); - document = webkit_web_view_get_dom_document (WEBKIT_WEB_VIEW (view)); - body = webkit_dom_document_get_body (document); - array = g_byte_array_new (); - text = webkit_dom_html_element_get_inner_text (body); - g_byte_array_append (array, (guint8 *) text, strlen (text)); + editor = GTKHTML_EDITOR (composer); + text = gtkhtml_editor_get_text_plain (editor, &length); + g_byte_array_append (array, (guint8 *) text, (guint) length); g_free (text); return array; @@ -5210,24 +4959,22 @@ gboolean can_save_draft) { gboolean res = FALSE; - EHTMLEditor *editor; - EHTMLEditorView *view; + GtkhtmlEditor *editor; EComposerHeaderTable *table; GdkWindow *window; GtkWidget *widget; - const gchar *subject, *message_name; + const gchar *subject; gint response; + editor = GTKHTML_EDITOR (composer); widget = GTK_WIDGET (composer); - editor = e_msg_composer_get_editor (composer); - view = e_html_editor_get_view (editor); /* this means that there is an async operation running, * in which case the composer cannot be closed */ if (!gtk_action_group_get_sensitive (composer->priv->async_actions)) return FALSE; - if (!e_html_editor_view_get_changed (view)) + if (!gtkhtml_editor_get_changed (editor)) return TRUE; window = gtk_widget_get_window (widget); @@ -5237,13 +4984,11 @@ subject = e_composer_header_table_get_subject (table); if (subject == NULL || *subject == '\0') - message_name = "mail-composer:exit-unsaved-no-subject"; - else - message_name = "mail-composer:exit-unsaved"; + subject = _("Untitled Message"); response = e_alert_run_dialog_for_args ( GTK_WINDOW (composer), - message_name, + "mail-composer:exit-unsaved", subject, NULL); switch (response) { @@ -5265,6 +5010,32 @@ return res; } +void +e_msg_composer_reply_indent (EMsgComposer *composer) +{ + GtkhtmlEditor *editor; + + g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + + editor = GTKHTML_EDITOR (composer); + + if (!gtkhtml_editor_is_paragraph_empty (editor)) { + if (gtkhtml_editor_is_previous_paragraph_empty (editor)) + gtkhtml_editor_run_command (editor, "cursor-backward"); + else { + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); + gtkhtml_editor_run_command (editor, "insert-paragraph"); + return; + } + } + + gtkhtml_editor_run_command (editor, "style-normal"); + gtkhtml_editor_run_command (editor, "indent-zero"); + gtkhtml_editor_run_command (editor, "text-default-color"); + gtkhtml_editor_run_command (editor, "italic-off"); +} + EComposerHeaderTable * e_msg_composer_get_header_table (EMsgComposer *composer) { @@ -5281,101 +5052,76 @@ return E_ATTACHMENT_VIEW (composer->priv->attachment_paned); } -void -e_save_spell_languages (const GList *spell_dicts) +GList * +e_load_spell_languages (void) { GSettings *settings; - GPtrArray *lang_array; - - /* Build a list of spell check language codes. */ - lang_array = g_ptr_array_new (); - while (spell_dicts != NULL) { - ESpellDictionary *dict = spell_dicts->data; - const gchar *language_code; - - language_code = e_spell_dictionary_get_code (dict); - g_ptr_array_add (lang_array, (gpointer) language_code); - - spell_dicts = g_list_next (spell_dicts); - } - - g_ptr_array_add (lang_array, NULL); + GList *spell_languages = NULL; + gchar **strv; + gint ii; - /* Save the language codes to GSettings. */ - settings = e_util_ref_settings ("org.gnome.evolution.mail"); - g_settings_set_strv ( - settings, "composer-spell-languages", - (const gchar * const *) lang_array->pdata); + /* Ask GSettings for a list of spell check language codes. */ + settings = g_settings_new ("org.gnome.evolution.mail"); + strv = g_settings_get_strv (settings, "composer-spell-languages"); g_object_unref (settings); - g_ptr_array_free (lang_array, TRUE); -} - -void -e_msg_composer_is_from_new_message (EMsgComposer *composer, - gboolean is_from_new_message) -{ - g_return_if_fail (composer != NULL); - - composer->priv->is_from_new_message = is_from_new_message; -} + /* Convert the codes to spell language structs. */ + for (ii = 0; strv[ii] != NULL; ii++) { + gchar *language_code = strv[ii]; + const GtkhtmlSpellLanguage *language; -void -e_msg_composer_save_focused_widget (EMsgComposer *composer) -{ - GtkWidget *widget; + language = gtkhtml_spell_language_lookup (language_code); + if (language != NULL) + spell_languages = g_list_prepend ( + spell_languages, (gpointer) language); + } - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + g_strfreev (strv); - widget = gtk_window_get_focus (GTK_WINDOW (composer)); - composer->priv->focused_entry = widget; + spell_languages = g_list_reverse (spell_languages); - if (E_IS_HTML_EDITOR_VIEW (widget)) { - EHTMLEditorSelection *selection; + /* Pick a default spell language if it came back empty. */ + if (spell_languages == NULL) { + const GtkhtmlSpellLanguage *language; - selection = e_html_editor_view_get_selection ( - E_HTML_EDITOR_VIEW (widget)); + language = gtkhtml_spell_language_lookup (NULL); - e_html_editor_selection_save (selection); + if (language) { + spell_languages = g_list_prepend ( + spell_languages, (gpointer) language); + } } - if (GTK_IS_EDITABLE (widget)) { - gtk_editable_get_selection_bounds ( - GTK_EDITABLE (widget), - &composer->priv->focused_entry_selection_start, - &composer->priv->focused_entry_selection_end); - } + return spell_languages; } void -e_msg_composer_restore_focus_on_composer (EMsgComposer *composer) +e_save_spell_languages (GList *spell_languages) { - GtkWidget *widget = composer->priv->focused_entry; - - g_return_if_fail (E_IS_MSG_COMPOSER (composer)); + GSettings *settings; + GPtrArray *lang_array; - if (!widget) - return; + /* Build a list of spell check language codes. */ + lang_array = g_ptr_array_new (); + while (spell_languages != NULL) { + const GtkhtmlSpellLanguage *language; + const gchar *language_code; - gtk_window_set_focus (GTK_WINDOW (composer), widget); + language = spell_languages->data; + language_code = gtkhtml_spell_language_get_code (language); + g_ptr_array_add (lang_array, (gpointer) language_code); - if (GTK_IS_EDITABLE (widget)) { - gtk_editable_select_region ( - GTK_EDITABLE (widget), - composer->priv->focused_entry_selection_start, - composer->priv->focused_entry_selection_end); + spell_languages = g_list_next (spell_languages); } - if (E_IS_HTML_EDITOR_VIEW (widget)) { - EHTMLEditorSelection *selection; - - e_html_editor_view_force_spell_check (E_HTML_EDITOR_VIEW (widget)); - - selection = e_html_editor_view_get_selection ( - E_HTML_EDITOR_VIEW (widget)); + g_ptr_array_add (lang_array, NULL); - e_html_editor_selection_restore (selection); - } + /* Save the language codes to GSettings. */ + settings = g_settings_new ("org.gnome.evolution.mail"); + g_settings_set_strv ( + settings, "composer-spell-languages", + (const gchar * const *) lang_array->pdata); + g_object_unref (settings); - composer->priv->focused_entry = NULL; + g_ptr_array_free (lang_array, TRUE); } diff -Nru evolution-3.16.0/composer/e-msg-composer.h evolution-3.12.11/composer/e-msg-composer.h --- evolution-3.16.0/composer/e-msg-composer.h 2014-11-13 07:24:17.000000000 +0000 +++ evolution-3.12.11/composer/e-msg-composer.h 2014-03-24 09:25:23.000000000 +0000 @@ -24,6 +24,7 @@ #define E_MSG_COMPOSER_H #include +#include #include #include @@ -56,12 +57,12 @@ typedef struct _EMsgComposerPrivate EMsgComposerPrivate; struct _EMsgComposer { - GtkWindow parent; + GtkhtmlEditor parent; EMsgComposerPrivate *priv; }; struct _EMsgComposerClass { - GtkWindowClass parent_class; + GtkhtmlEditorClass parent_class; /* Signals */ gboolean (*presend) (EMsgComposer *composer); @@ -92,11 +93,12 @@ CamelMimeMessage *message, const gchar *identity_uid, GCancellable *cancellable); -EHTMLEditor * e_msg_composer_get_editor (EMsgComposer *composer); EFocusTracker * e_msg_composer_get_focus_tracker (EMsgComposer *composer); CamelSession * e_msg_composer_ref_session (EMsgComposer *composer); EShell * e_msg_composer_get_shell (EMsgComposer *composer); +EWebViewGtkHTML * + e_msg_composer_get_web_view (EMsgComposer *composer); void e_msg_composer_send (EMsgComposer *composer); void e_msg_composer_save_to_drafts (EMsgComposer *composer); @@ -129,6 +131,12 @@ CamelMessageFlags flags); void e_msg_composer_attach (EMsgComposer *composer, CamelMimePart *mime_part); +CamelMimePart * e_msg_composer_add_inline_image_from_file + (EMsgComposer *composer, + const gchar *filename); +void e_msg_composer_add_inline_image_from_mime_part + (EMsgComposer *composer, + CamelMimePart *part); void e_msg_composer_get_message (EMsgComposer *composer, gint io_priority, GCancellable *cancellable, @@ -167,6 +175,8 @@ CamelInternetAddress * e_msg_composer_get_reply_to (EMsgComposer *composer); +void e_msg_composer_clear_inlined_table + (EMsgComposer *composer); void e_msg_composer_add_message_attachments (EMsgComposer *composer, CamelMimeMessage *message, @@ -176,27 +186,21 @@ gboolean e_msg_composer_can_close (EMsgComposer *composer, gboolean can_save_draft); +void e_msg_composer_reply_indent (EMsgComposer *composer); + EComposerHeaderTable * e_msg_composer_get_header_table (EMsgComposer *composer); EAttachmentView * e_msg_composer_get_attachment_view (EMsgComposer *composer); -GByteArray * e_msg_composer_get_raw_message_text_without_signature - (EMsgComposer *composer); GByteArray * e_msg_composer_get_raw_message_text (EMsgComposer *composer); gboolean e_msg_composer_is_exiting (EMsgComposer *composer); -void e_save_spell_languages (const GList *spell_languages); -void e_msg_composer_is_from_new_message - (EMsgComposer *composer, - gboolean is_from_new_message); -void e_msg_composer_save_focused_widget - (EMsgComposer *composer); -void e_msg_composer_restore_focus_on_composer - (EMsgComposer *composer); -gboolean e_msg_composer_is_busy (EMsgComposer *composer); +GList * e_load_spell_languages (void); +void e_save_spell_languages (GList *spell_languages); + G_END_DECLS #endif /* E_MSG_COMPOSER_H */ diff -Nru evolution-3.16.0/composer/evolution-composer.ui evolution-3.12.11/composer/evolution-composer.ui --- evolution-3.16.0/composer/evolution-composer.ui 2015-02-25 12:48:56.000000000 +0000 +++ evolution-3.12.11/composer/evolution-composer.ui 2014-03-24 09:25:23.000000000 +0000 @@ -26,7 +26,6 @@ - @@ -51,7 +50,6 @@ - @@ -62,14 +60,6 @@ - - - - - - - - diff -Nru evolution-3.16.0/composer/mail-composer.error.xml evolution-3.12.11/composer/mail-composer.error.xml --- evolution-3.16.0/composer/mail-composer.error.xml 2015-01-06 10:12:35.000000000 +0000 +++ evolution-3.12.11/composer/mail-composer.error.xml 2014-03-24 09:25:23.000000000 +0000 @@ -43,14 +43,6 @@