From 42a69b14dfe9b4f05bfd24e71f228c1f392e2a39 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 7 Apr 2010 11:31:22 -0400 Subject: Bug 614644 - Email window's title is blank when subject is blank --- mail/e-mail-browser.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/mail/e-mail-browser.c b/mail/e-mail-browser.c index a6461e2bfe..78dd91b5c2 100644 --- a/mail/e-mail-browser.c +++ b/mail/e-mail-browser.c @@ -244,6 +244,7 @@ mail_browser_message_selected_cb (EMailBrowser *browser, CamelMessageInfo *info; CamelFolder *folder; EMailReader *reader; + const gchar *title; if (uid == NULL) return; @@ -257,9 +258,14 @@ mail_browser_message_selected_cb (EMailBrowser *browser, if (info == NULL) return; - gtk_window_set_title ( - GTK_WINDOW (browser), - camel_message_info_subject (info)); + /* XXX The string here was added after the 2.30.0 release, so + * it's not marked for translation. But it IS marked for + * translation in 2.31. */ + title = camel_message_info_subject (info); + if (title == NULL || *title == '\0') + title = "(No Subject)"; + + gtk_window_set_title (GTK_WINDOW (browser), title); gtk_widget_grab_focus ( GTK_WIDGET (((EMFormatHTML *) html_display)->html)); -- cgit v1.2.3 From fe94770c2e5689f8442e088c3e14004a30143e01 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Fri, 19 Mar 2010 17:18:19 -0400 Subject: Introduce a simple extension system for objects. This introduces a simple means of extending Evolution objects. Any GObject subclass wishing to be extensible need only call g_type_add_interface_static (type, E_TYPE_EXTENSIBLE, NULL); when registering its GType, and then at some point during initialization call e_extensible_load_extensions() to load extensions for that subclass. Extensions are implemented by subclassing EExtension, setting the GType being extended in EExtensionClass, and making sure its own GType gets registered at startup. This usually done while loading a GTypeModule. e_extension_get_extensible() provides extensions access to the object being extended. --- e-util/Makefile.am | 4 ++ e-util/e-extensible.c | 112 +++++++++++++++++++++++++++++++++++ e-util/e-extensible.h | 57 ++++++++++++++++++ e-util/e-extension.c | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ e-util/e-extension.h | 67 +++++++++++++++++++++ 5 files changed, 400 insertions(+) create mode 100644 e-util/e-extensible.c create mode 100644 e-util/e-extensible.h create mode 100644 e-util/e-extension.c create mode 100644 e-util/e-extension.h diff --git a/e-util/Makefile.am b/e-util/Makefile.am index 7384333452..99f873cbd8 100644 --- a/e-util/Makefile.am +++ b/e-util/Makefile.am @@ -25,6 +25,8 @@ eutilinclude_HEADERS = \ e-dialog-utils.h \ e-dialog-widgets.h \ e-event.h \ + e-extensible.h \ + e-extension.h \ e-file-utils.h \ e-folder-map.h \ e-html-utils.h \ @@ -103,6 +105,8 @@ libeutil_la_SOURCES = \ e-dialog-utils.c \ e-dialog-widgets.c \ e-event.c \ + e-extensible.c \ + e-extension.c \ e-file-utils.c \ e-folder-map.c \ e-html-utils.c \ diff --git a/e-util/e-extensible.c b/e-util/e-extensible.c new file mode 100644 index 0000000000..9960d31d9f --- /dev/null +++ b/e-util/e-extensible.c @@ -0,0 +1,112 @@ +/* + * e-extensible.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#include "e-extensible.h" + +#include +#include + +static GQuark extensible_quark; + +static GPtrArray * +extensible_get_extensions (EExtensible *extensible) +{ + return g_object_get_qdata (G_OBJECT (extensible), extensible_quark); +} + +static void +extensible_load_extension (GType extension_type, + EExtensible *extensible) +{ + EExtensionClass *extension_class; + GType extensible_type; + GPtrArray *extensions; + EExtension *extension; + + extensible_type = G_OBJECT_TYPE (extensible); + extension_class = g_type_class_ref (extension_type); + + /* Only load extensions that extend the given extensible object. */ + if (!g_type_is_a (extensible_type, extension_class->extensible_type)) + goto exit; + + extension = g_object_new ( + extension_type, "extensible", extensible, NULL); + + extensions = extensible_get_extensions (extensible); + g_ptr_array_add (extensions, extension); + +exit: + g_type_class_unref (extension_class); +} + +static void +extensible_interface_init (EExtensibleInterface *interface) +{ + extensible_quark = g_quark_from_static_string ("e-extensible-quark"); +} + +GType +e_extensible_get_type (void) +{ + static GType type = 0; + + if (G_UNLIKELY (type == 0)) { + static const GTypeInfo type_info = { + sizeof (EExtensibleInterface), + (GBaseInitFunc) NULL, + (GBaseFinalizeFunc) NULL, + (GClassInitFunc) extensible_interface_init, + (GClassFinalizeFunc) NULL, + NULL, /* class_data */ + 0, /* instance_size */ + 0, /* n_preallocs */ + (GInstanceInitFunc) NULL, + NULL /* value_table */ + }; + + type = g_type_register_static ( + G_TYPE_INTERFACE, "EExtensible", &type_info, 0); + + g_type_interface_add_prerequisite (type, G_TYPE_OBJECT); + } + + return type; +} + +void +e_extensible_load_extensions (EExtensible *extensible) +{ + GPtrArray *extensions; + + g_return_if_fail (E_IS_EXTENSIBLE (extensible)); + + if (extensible_get_extensions (extensible) != NULL) + return; + + extensions = g_ptr_array_new_with_free_func ( + (GDestroyNotify) g_object_unref); + + g_object_set_qdata_full ( + G_OBJECT (extensible), extensible_quark, + extensions, (GDestroyNotify) g_ptr_array_unref); + + e_type_traverse ( + E_TYPE_EXTENSION, (ETypeFunc) + extensible_load_extension, extensible); +} diff --git a/e-util/e-extensible.h b/e-util/e-extensible.h new file mode 100644 index 0000000000..a72ea71611 --- /dev/null +++ b/e-util/e-extensible.h @@ -0,0 +1,57 @@ +/* + * e-extensible.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef E_EXTENSIBLE_H +#define E_EXTENSIBLE_H + +#include + +/* Standard GObject macros */ +#define E_TYPE_EXTENSIBLE \ + (e_extensible_get_type ()) +#define E_EXTENSIBLE(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_EXTENSIBLE, EExtensible)) +#define E_EXTENSIBLE_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_EXTENSIBLE, EExtensibleInterface)) +#define E_IS_EXTENSIBLE(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_EXTENSIBLE)) +#define E_IS_EXTENSIBLE_INTERFACE(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_EXTENSIBLE)) +#define E_EXTENSIBLE_GET_INTERFACE(obj) \ + (G_TYPE_INSTANCE_GET_INTERFACE \ + ((obj), E_TYPE_EXTENSIBLE, EExtensibleInterface)) + +G_BEGIN_DECLS + +typedef struct _EExtensible EExtensible; +typedef struct _EExtensibleInterface EExtensibleInterface; + +struct _EExtensibleInterface { + GTypeInterface parent_interface; +}; + +GType e_extensible_get_type (void); +void e_extensible_load_extensions (EExtensible *extensible); + +G_END_DECLS + +#endif /* E_EXTENSIBLE_H */ diff --git a/e-util/e-extension.c b/e-util/e-extension.c new file mode 100644 index 0000000000..05687b64ba --- /dev/null +++ b/e-util/e-extension.c @@ -0,0 +1,160 @@ +/* + * e-extension.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#include "e-extension.h" + +#define E_EXTENSION_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_EXTENSION, EExtensionPrivate)) + +struct _EExtensionPrivate { + gpointer extensible; /* weak pointer */ +}; + +enum { + PROP_0, + PROP_EXTENSIBLE +}; + +G_DEFINE_ABSTRACT_TYPE (EExtension, e_extension, G_TYPE_OBJECT) + +static void +extension_set_extensible (EExtension *extension, + EExtensible *extensible) +{ + EExtensionClass *class; + GType extensible_type; + + g_return_if_fail (E_IS_EXTENSIBLE (extensible)); + g_return_if_fail (extension->priv->extensible == NULL); + + class = E_EXTENSION_GET_CLASS (extension); + extensible_type = G_OBJECT_TYPE (extensible); + + /* Verify the EExtensible object is the type we want. */ + if (!g_type_is_a (extensible_type, class->extensible_type)) { + g_warning ("%s is meant to extend %s but was given an %s", + G_OBJECT_TYPE_NAME (extension), + g_type_name (class->extensible_type), + g_type_name (extensible_type)); + return; + } + + extension->priv->extensible = extensible; + + g_object_add_weak_pointer ( + G_OBJECT (extensible), &extension->priv->extensible); +} + +static void +extension_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EXTENSIBLE: + extension_set_extensible ( + E_EXTENSION (object), + g_value_get_object (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +extension_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_EXTENSIBLE: + g_value_set_object ( + value, e_extension_get_extensible ( + E_EXTENSION (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +extension_constructed (GObject *object) +{ + /* This allows subclasses to chain up safely since GObject + * does not implement this method, and we might want to do + * something here in the future. */ +} + +static void +extension_dispose (GObject *object) +{ + EExtensionPrivate *priv; + + priv = E_EXTENSION_GET_PRIVATE (object); + + if (priv->extensible != NULL) { + g_object_remove_weak_pointer ( + G_OBJECT (priv->extensible), &priv->extensible); + priv->extensible = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (e_extension_parent_class)->dispose (object); +} + +static void +e_extension_class_init (EExtensionClass *class) +{ + GObjectClass *object_class; + + g_type_class_add_private (class, sizeof (EExtensionPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = extension_set_property; + object_class->get_property = extension_get_property; + object_class->constructed = extension_constructed; + object_class->dispose = extension_dispose; + + g_object_class_install_property ( + object_class, + PROP_EXTENSIBLE, + g_param_spec_object ( + "extensible", + "Extensible Object", + "The object being extended", + E_TYPE_EXTENSIBLE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); +} + +static void +e_extension_init (EExtension *extension) +{ + extension->priv = E_EXTENSION_GET_PRIVATE (extension); +} + +EExtensible * +e_extension_get_extensible (EExtension *extension) +{ + g_return_val_if_fail (E_IS_EXTENSION (extension), NULL); + + return E_EXTENSIBLE (extension->priv->extensible); +} diff --git a/e-util/e-extension.h b/e-util/e-extension.h new file mode 100644 index 0000000000..905ef412f3 --- /dev/null +++ b/e-util/e-extension.h @@ -0,0 +1,67 @@ +/* + * e-extension.h + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifndef E_EXTENSION_H +#define E_EXTENSION_H + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_EXTENSION \ + (e_extension_get_type ()) +#define E_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_EXTENSION, EExtension)) +#define E_EXTENSION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_CAST \ + ((cls), E_TYPE_EXTENSION, EExtensionClass)) +#define E_IS_EXTENSION(obj) \ + (G_TYPE_CHECK_INSTANCE_TYPE \ + ((obj), E_TYPE_EXTENSION)) +#define E_IS_EXTENSION_CLASS(cls) \ + (G_TYPE_CHECK_CLASS_TYPE \ + ((cls), E_TYPE_EXTENSION)) +#define E_EXTENSION_GET_CLASS(obj) \ + (G_TYPE_INSTANCE_GET_CLASS \ + ((obj), E_TYPE_EXTENSION, EExtensionClass)) + +G_BEGIN_DECLS + +typedef struct _EExtension EExtension; +typedef struct _EExtensionClass EExtensionClass; +typedef struct _EExtensionPrivate EExtensionPrivate; + +struct _EExtension { + GObject parent; + EExtensionPrivate *priv; +}; + +struct _EExtensionClass { + GObjectClass parent_class; + + /* The type to extend. */ + GType extensible_type; +}; + +GType e_extension_get_type (void); +EExtensible * e_extension_get_extensible (EExtension *extension); + +G_END_DECLS + +#endif /* E_EXTENSION_H */ -- cgit v1.2.3 From 5c43eaf3ddb344cc14f7a30dd73330f027794620 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 20 Mar 2010 00:00:28 -0400 Subject: Make EShell extensible. --- shell/e-shell.c | 47 +++++++++++++---------------------------------- 1 file changed, 13 insertions(+), 34 deletions(-) diff --git a/shell/e-shell.c b/shell/e-shell.c index 00c1e4a7a7..8bbcde784d 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -24,9 +24,10 @@ #include #include +#include "e-util/e-module.h" +#include "e-util/e-extensible.h" #include "e-util/e-util-private.h" #include "e-util/e-util.h" -#include "e-util/e-module.h" #include "smclient/eggsmclient.h" #include "widgets/misc/e-preferences-window.h" @@ -94,7 +95,6 @@ static GDebugKey debug_keys[] = { { "settings", DEBUG_KEY_SETTINGS } }; -static gpointer parent_class; static gpointer default_shell; static guint signals[LAST_SIGNAL]; @@ -102,6 +102,10 @@ static guint signals[LAST_SIGNAL]; gboolean e_shell_dbus_initialize (EShell *shell); #endif +G_DEFINE_TYPE_WITH_CODE ( + EShell, e_shell, UNIQUE_TYPE_APP, + G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) + static void shell_parse_debug_string (EShell *shell) { @@ -606,7 +610,7 @@ shell_dispose (GObject *object) } /* Chain up to parent's dispose() method. */ - G_OBJECT_CLASS (parent_class)->dispose (object); + G_OBJECT_CLASS (e_shell_parent_class)->dispose (object); } static void @@ -627,7 +631,7 @@ shell_finalize (GObject *object) g_free (priv->module_directory); /* Chain up to parent's finalize() method. */ - G_OBJECT_CLASS (parent_class)->finalize (object); + G_OBJECT_CLASS (e_shell_parent_class)->finalize (object); } static void @@ -656,6 +660,8 @@ shell_constructed (GObject *object) e_type_traverse ( E_TYPE_SHELL_BACKEND, (ETypeFunc) shell_add_backend, object); + + e_extensible_load_extensions (E_EXTENSIBLE (object)); } static UniqueResponse @@ -740,7 +746,7 @@ shell_message_received (UniqueApp *app, } /* Chain up to parent's message_received() method. */ - return UNIQUE_APP_CLASS (parent_class)-> + return UNIQUE_APP_CLASS (e_shell_parent_class)-> message_received (app, command, data, time_); } @@ -752,12 +758,11 @@ shell_window_destroyed (EShell *shell) } static void -shell_class_init (EShellClass *class) +e_shell_class_init (EShellClass *class) { GObjectClass *object_class; UniqueAppClass *unique_app_class; - parent_class = g_type_class_peek_parent (class); g_type_class_add_private (class, sizeof (EShellPrivate)); object_class = G_OBJECT_CLASS (class); @@ -1061,7 +1066,7 @@ shell_class_init (EShellClass *class) } static void -shell_init (EShell *shell) +e_shell_init (EShell *shell) { GHashTable *backends_by_name; GHashTable *backends_by_scheme; @@ -1150,32 +1155,6 @@ shell_init (EShell *shell) G_CALLBACK (shell_sm_quit_cb), shell); } -GType -e_shell_get_type (void) -{ - static GType type = 0; - - if (G_UNLIKELY (type == 0)) { - const GTypeInfo type_info = { - sizeof (EShellClass), - (GBaseInitFunc) NULL, - (GBaseFinalizeFunc) NULL, - (GClassInitFunc) shell_class_init, - (GClassFinalizeFunc) NULL, - NULL, /* class_data */ - sizeof (EShell), - 0, /* n_preallocs */ - (GInstanceInitFunc) shell_init, - NULL /* value_table */ - }; - - type = g_type_register_static ( - UNIQUE_TYPE_APP, "EShell", &type_info, 0); - } - - return type; -} - /** * e_shell_get_default: * -- cgit v1.2.3 From cd7fadfcdbbf983dbee379d55bd8a6e44351e8fa Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Sat, 20 Mar 2010 11:38:33 -0400 Subject: Convert NetworkManager integration to an EShell extension. This demonstrates how to extend EShell without having to modify and recompile e-shell.c. If NetworkManager integration is enabled, the extension is loaded automatically when the EShell is created. The same pattern can be applied to integrate other network monitoring software like ConnMan or Microsoft's Wireless Zero Configuration. --- configure.ac | 15 +- modules/Makefile.am | 13 +- modules/network-manager/Makefile.am | 22 ++ .../network-manager/evolution-network-manager.c | 245 +++++++++++++++++++++ shell/Makefile.am | 12 - shell/e-shell-nm.c | 177 --------------- shell/e-shell.c | 8 - 7 files changed, 285 insertions(+), 207 deletions(-) create mode 100644 modules/network-manager/Makefile.am create mode 100644 modules/network-manager/evolution-network-manager.c delete mode 100644 shell/e-shell-nm.c diff --git a/configure.ac b/configure.ac index 61bee0fc91..3f3a2bbef7 100644 --- a/configure.ac +++ b/configure.ac @@ -1133,18 +1133,14 @@ AC_ARG_ENABLE([nm], AC_MSG_CHECKING([if NetworkManager support is enabled]) AC_MSG_RESULT([$enable_nm]) if test "$enable_nm" = yes; then - PKG_CHECK_MODULES([NM], [NetworkManager >= nm_minimum_version], - [NM_SUPPORT="yes"], - [AC_MSG_ERROR([NetworkManager not found (or version < nm_minimum_version)! - If you want to disable NetworkManager, please append --disable-nm to configure!])]) - AC_DEFINE(NM_SUPPORT, 1, [network manager available]) + PKG_CHECK_MODULES([NM], [NetworkManager >= nm_minimum_version],, + [AC_MSG_ERROR([NetworkManager not found (or version < nm_minimum_version). + If you want to disable NetworkManager, please append --disable-nm to configure.])]) AC_SUBST(HAVE_NM) AC_SUBST(NM_CFLAGS) -else - NM_SUPPORT="no" fi -AM_CONDITIONAL([NM_SUPPORT], [test "$NM_SUPPORT" = yes]) +AM_CONDITIONAL([ENABLE_NETWORK_MANAGER], [test "$enable_nm" = yes]) dnl ****************************** dnl Camel Flags @@ -1693,6 +1689,7 @@ modules/Makefile modules/addressbook/Makefile modules/calendar/Makefile modules/mail/Makefile +modules/network-manager/Makefile modules/plugin-lib/Makefile modules/plugin-mono/Makefile modules/plugin-python/Makefile @@ -1762,7 +1759,7 @@ fi echo " LDAP support: $msg_ldap - NetworkManager: $NM_SUPPORT + NetworkManager: $enable_nm Pilot conduits: $msg_pilot Libnotify: $HAVE_LIBNOTIFY Kerberos 5: $msg_krb5 diff --git a/modules/Makefile.am b/modules/Makefile.am index f792a4d9ee..0b6ccf22ec 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -6,6 +6,17 @@ if ENABLE_PYTHON PYTHON_DIR = plugin-python endif -SUBDIRS = addressbook calendar mail plugin-lib $(MONO_DIR) $(PYTHON_DIR) +if ENABLE_NETWORK_MANAGER +NETWORK_MANAGER_DIR = network-manager +endif + +SUBDIRS = \ + addressbook \ + calendar \ + mail \ + plugin-lib \ + $(MONO_DIR) \ + $(PYTHON_DIR) \ + $(NETWORK_MANAGER_DIR) -include $(top_srcdir)/git.mk diff --git a/modules/network-manager/Makefile.am b/modules/network-manager/Makefile.am new file mode 100644 index 0000000000..24cd80a246 --- /dev/null +++ b/modules/network-manager/Makefile.am @@ -0,0 +1,22 @@ +module_LTLIBRARIES = libevolution-module-network-manager.la + +libevolution_module_network_manager_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-network-manager\" \ + $(GNOME_PLATFORM_CFLAGS) \ + $(DBUS_GLIB_CFLAGS) \ + $(NM_CFLAGS) + +libevolution_module_network_manager_la_SOURCES = \ + evolution-network-manager.c + +libevolution_module_network_manager_la_LIBADD = \ + $(top_builddir)/shell/libeshell.la \ + $(GNOME_PLATFORM_LIBS) \ + $(DBUS_GLIB_LIBS) + +libevolution_module_network_manager_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +-include $(top_srcdir)/git.mk diff --git a/modules/network-manager/evolution-network-manager.c b/modules/network-manager/evolution-network-manager.c new file mode 100644 index 0000000000..7dc110f411 --- /dev/null +++ b/modules/network-manager/evolution-network-manager.c @@ -0,0 +1,245 @@ +/* + * evolution-network-manager.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#include +#include +#include +#include + +#include +#include + +/* Standard GObject macros */ +#define E_TYPE_NETWORK_MANAGER \ + (e_network_manager_get_type ()) +#define E_NETWORK_MANAGER(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_NETWORK_MANAGER, ENetworkManager)) + +typedef struct _ENetworkManager ENetworkManager; +typedef struct _ENetworkManagerClass ENetworkManagerClass; + +struct _ENetworkManager { + EExtension parent; + DBusConnection *connection; +}; + +struct _ENetworkManagerClass { + EExtensionClass parent_class; +}; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_network_manager_get_type (void); +static gboolean network_manager_connect (ENetworkManager *extension); + +G_DEFINE_DYNAMIC_TYPE (ENetworkManager, e_network_manager, E_TYPE_EXTENSION) + +static EShell * +network_manager_get_shell (ENetworkManager *extension) +{ + EExtensible *extensible; + + extensible = e_extension_get_extensible (E_EXTENSION (extension)); + + return E_SHELL (extensible); +} + +static DBusHandlerResult +network_manager_monitor (DBusConnection *connection G_GNUC_UNUSED, + DBusMessage *message, + gpointer user_data) +{ + ENetworkManager *extension = user_data; + EShell *shell; + const gchar *path; + guint32 state; + DBusError error = DBUS_ERROR_INIT; + + shell = network_manager_get_shell (extension); + + path = dbus_message_get_path (message); + + if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && + g_strcmp0 (path, DBUS_PATH_LOCAL) == 0) { + dbus_connection_unref (extension->connection); + extension->connection = NULL; + + g_timeout_add_seconds ( + 3, (GSourceFunc) network_manager_connect, extension); + + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (!dbus_message_is_signal (message, NM_DBUS_INTERFACE, "StateChanged")) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + dbus_message_get_args ( + message, &error, + DBUS_TYPE_UINT32, &state, + DBUS_TYPE_INVALID); + + if (dbus_error_is_set (&error)) { + g_warning ("%s", error.message); + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + } + + switch (state) { + case NM_STATE_CONNECTED: + e_shell_set_network_available (shell, TRUE); + break; + case NM_STATE_ASLEEP: + case NM_STATE_DISCONNECTED: + e_shell_set_network_available (shell, FALSE); + break; + default: + break; + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +static void +network_manager_check_initial_state (ENetworkManager *extension) +{ + EShell *shell; + DBusMessage *message = NULL; + DBusMessage *response = NULL; + guint32 state = -1; + DBusError error = DBUS_ERROR_INIT; + + shell = network_manager_get_shell (extension); + + message = dbus_message_new_method_call ( + NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state"); + + /* XXX Assuming this should be safe to call synchronously. */ + response = dbus_connection_send_with_reply_and_block ( + extension->connection, message, 100, &error); + + if (response != NULL) { + dbus_message_get_args ( + response, &error, DBUS_TYPE_UINT32, + &state, DBUS_TYPE_INVALID); + } else { + g_warning ("%s", error.message); + dbus_error_free (&error); + return; + } + + /* Update the state only in the absence of a network connection, + * otherwise let the old state prevail. */ + if (state == NM_STATE_ASLEEP || state == NM_STATE_DISCONNECTED) + e_shell_set_network_available (shell, FALSE); + + dbus_message_unref (message); + dbus_message_unref (response); +} + +static gboolean +network_manager_connect (ENetworkManager *extension) +{ + DBusError error = DBUS_ERROR_INIT; + + /* This is a timeout callback, so the return value denotes + * whether to reschedule, not whether we're successful. */ + + if (extension->connection != NULL) + return FALSE; + + extension->connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); + if (extension->connection == NULL) { + g_warning ("%s", error.message); + dbus_error_free (&error); + return TRUE; + } + + dbus_connection_setup_with_g_main (extension->connection, NULL); + dbus_connection_set_exit_on_disconnect (extension->connection, FALSE); + + if (!dbus_connection_add_filter ( + extension->connection, + network_manager_monitor, extension, NULL)) + goto fail; + + network_manager_check_initial_state (extension); + + dbus_bus_add_match ( + extension->connection, + "type='signal'," + "interface='" NM_DBUS_INTERFACE "'," + "sender='" NM_DBUS_SERVICE "'," + "path='" NM_DBUS_PATH "'", + &error); + if (dbus_error_is_set (&error)) { + g_warning ("%s", error.message); + dbus_error_free (&error); + goto fail; + } + + return FALSE; + +fail: + dbus_connection_unref (extension->connection); + extension->connection = NULL; + + return TRUE; +} + +static void +network_manager_constructed (GObject *object) +{ + network_manager_connect (E_NETWORK_MANAGER (object)); +} + +static void +e_network_manager_class_init (ENetworkManagerClass *class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + object_class = G_OBJECT_CLASS (class); + object_class->constructed = network_manager_constructed; + + extension_class = E_EXTENSION_CLASS (class); + extension_class->extensible_type = E_TYPE_SHELL; +} + +static void +e_network_manager_class_finalize (ENetworkManagerClass *class) +{ +} + +static void +e_network_manager_init (ENetworkManager *extension) +{ +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_network_manager_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} diff --git a/shell/Makefile.am b/shell/Makefile.am index 8afc886d46..0a93912680 100644 --- a/shell/Makefile.am +++ b/shell/Makefile.am @@ -2,13 +2,6 @@ if ENABLE_TEST_COMPONENT SUBDIRS = . test endif -if NM_SUPPORT -NM_CPPFLAGS = \ - $(DBUS_GLIB_CFLAGS) \ - $(NM_CFLAGS) -NM_SUPPORT_FILES = e-shell-nm.c -endif - # Executable bin_PROGRAMS = evolution @@ -61,7 +54,6 @@ libeshell_la_CPPFLAGS = \ $(SHELL_CFLAGS) libeshell_la_SOURCES = \ - $(NM_SUPPORT_FILES) \ $(eshellinclude_HEADERS) \ e-shell.c \ e-shell-backend.c \ @@ -92,10 +84,6 @@ libeshell_la_LIBADD = \ $(GNOME_PLATFORM_LIBS) \ $(SHELL_LIBS) -if NM_SUPPORT -libeshell_la_LIBADD += $(DBUS_GLIB_LIBS) -endif - # Evolution executable if HAVE_WINDRES diff --git a/shell/e-shell-nm.c b/shell/e-shell-nm.c deleted file mode 100644 index 7f17d9716f..0000000000 --- a/shell/e-shell-nm.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with the program; if not, see - * - * - * Authors: - * Shreyas Srinivasan - * - * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) - * - */ - -#define DBUS_API_SUBJECT_TO_CHANGE 1 - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -static DBusConnection *dbus_connection; - -/* Forward Declaration */ -gboolean e_shell_dbus_initialize (EShell *shell); - -static gboolean -reinit_dbus (EShell *shell) -{ - return !e_shell_dbus_initialize (shell); -} - -static DBusHandlerResult -e_shell_network_monitor (DBusConnection *connection G_GNUC_UNUSED, - DBusMessage *message, - gpointer user_data) -{ - DBusError error = DBUS_ERROR_INIT; - EShell *shell = user_data; - const gchar *path; - guint32 state; - - path = dbus_message_get_path (message); - - if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") && - path != NULL && strcmp (path, DBUS_PATH_LOCAL) == 0) { - dbus_connection_unref (dbus_connection); - dbus_connection = NULL; - - g_timeout_add_seconds (3, (GSourceFunc) reinit_dbus, shell); - - return DBUS_HANDLER_RESULT_HANDLED; - } - - if (!dbus_message_is_signal (message, NM_DBUS_INTERFACE, "StateChanged")) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - dbus_message_get_args ( - message, &error, - DBUS_TYPE_UINT32, &state, - DBUS_TYPE_INVALID); - - if (dbus_error_is_set (&error)) { - g_warning ("%s", error.message); - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - } - - switch (state) { - case NM_STATE_CONNECTED: - e_shell_set_network_available (shell, TRUE); - break; - case NM_STATE_ASLEEP: - case NM_STATE_DISCONNECTED: - e_shell_set_network_available (shell, FALSE); - break; - default: - break; - } - - return DBUS_HANDLER_RESULT_HANDLED; -} - -static void -check_initial_state (EShell *shell) -{ - DBusMessage *message = NULL, *response = NULL; - guint32 state = -1; - DBusError error = DBUS_ERROR_INIT; - - message = dbus_message_new_method_call ( - NM_DBUS_SERVICE, NM_DBUS_PATH, NM_DBUS_INTERFACE, "state"); - - /* assuming this should be safe to call syncronously */ - response = dbus_connection_send_with_reply_and_block ( - dbus_connection, message, 100, &error); - - if (response) - dbus_message_get_args ( - response, &error, DBUS_TYPE_UINT32, - &state, DBUS_TYPE_INVALID); - else { - g_warning ("%s", error.message); - dbus_error_free (&error); - return; - } - - /* Update the state only in the absence of a network connection, - * otherwise let the old state prevail. */ - if (state == NM_STATE_DISCONNECTED) - e_shell_set_network_available (shell, FALSE); - - dbus_message_unref (message); - dbus_message_unref (response); -} - -gboolean -e_shell_dbus_initialize (EShell *shell) -{ - DBusError error = DBUS_ERROR_INIT; - - g_return_val_if_fail (E_IS_SHELL (shell), FALSE); - - if (dbus_connection != NULL) - return TRUE; - - dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &error); - if (dbus_connection == NULL) { - g_warning ("%s", error.message); - dbus_error_free (&error); - return FALSE; - } - - dbus_connection_setup_with_g_main (dbus_connection, NULL); - dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE); - - if (!dbus_connection_add_filter ( - dbus_connection, e_shell_network_monitor, shell, NULL)) - goto exception; - - check_initial_state (shell); - - dbus_bus_add_match (dbus_connection, - "type='signal'," - "interface='" NM_DBUS_INTERFACE "'," - "sender='" NM_DBUS_SERVICE "'," - "path='" NM_DBUS_PATH "'", &error); - if (dbus_error_is_set (&error)) { - g_warning ("%s", error.message); - dbus_error_free (&error); - goto exception; - } - - return TRUE; - -exception: - - dbus_connection_unref (dbus_connection); - dbus_connection = NULL; - - return FALSE; -} diff --git a/shell/e-shell.c b/shell/e-shell.c index 8bbcde784d..459ebdc64a 100644 --- a/shell/e-shell.c +++ b/shell/e-shell.c @@ -98,10 +98,6 @@ static GDebugKey debug_keys[] = { static gpointer default_shell; static guint signals[LAST_SIGNAL]; -#if defined(NM_SUPPORT) && NM_SUPPORT -gboolean e_shell_dbus_initialize (EShell *shell); -#endif - G_DEFINE_TYPE_WITH_CODE ( EShell, e_shell, UNIQUE_TYPE_APP, G_IMPLEMENT_INTERFACE (E_TYPE_EXTENSIBLE, NULL)) @@ -1087,10 +1083,6 @@ e_shell_init (EShell *shell) g_object_ref_sink (shell->priv->preferences_window); -#if defined(NM_SUPPORT) && NM_SUPPORT - e_shell_dbus_initialize (shell); -#endif - /* Add our icon directory to the theme's search path * here instead of in main() so Anjal picks it up. */ icon_theme = gtk_icon_theme_get_default (); -- cgit v1.2.3 From d358da9481a125e7eefa80cde88a6bed0c1b7fc3 Mon Sep 17 00:00:00 2001 From: Fridrich Strba Date: Tue, 23 Mar 2010 18:54:37 +0100 Subject: [win32] Implement network status detection The implementation is done using System Event Notification Service by implementing ConnectionMade ConnectionMadeNoQOCInfo and ConnectionLost methods of ISensNetwork interface. Make the subscription to the network status notification receive the event only if the ownerof the subscription is logged on to the same computer as the publisher. This makes this module work on Windows Vista and Windows 7 with normal user account. Don't try to build Windows SENS when not building for Windows. Extract the relevant COM structs and typedefs from mingw-w64 headers to allow to build the module with mingw.org toolchain and fix build breakages with Microsoft compilers. --- configure.ac | 38 ++ modules/Makefile.am | 7 +- modules/windows-sens/Makefile.am | 20 + modules/windows-sens/evolution-windows-sens.c | 602 ++++++++++++++++++++++++++ 4 files changed, 666 insertions(+), 1 deletion(-) create mode 100644 modules/windows-sens/Makefile.am create mode 100644 modules/windows-sens/evolution-windows-sens.c diff --git a/configure.ac b/configure.ac index 3f3a2bbef7..882dd1d3a8 100644 --- a/configure.ac +++ b/configure.ac @@ -1142,6 +1142,42 @@ fi AM_CONDITIONAL([ENABLE_NETWORK_MANAGER], [test "$enable_nm" = yes]) +dnl ****************************** +dnl Check for Windows SENS API +dnl ****************************** +AC_ARG_ENABLE([sens], + [AS_HELP_STRING([--enable-sens], + [enable Windows SENS support (default=yes)])], + [enable_sens=$enableval],[enable_sens=yes]) +if test "x$os_win32" = xyes; then + if test "x$enable_sens" = xyes; then + AC_CHECK_HEADER([rpc.h],[ enable_sens="yes" ],[ enable_sens="no" ]) + fi +else + enable_sens="no" +fi +AC_MSG_CHECKING([if Windows SENS support is enabled]) +AC_MSG_RESULT([$enable_sens]) +if test "$enable_sens" = yes; then + SENS_LIBS="-lole32 -loleaut32 -luuid -lrpcrt4" + AC_CHECK_HEADER([eventsys.h], + [AC_DEFINE([HAVE_EVENTSYS_H], 1, [Have ])],, + [[ #if HAVE_EVENTSYS_H + #include + #endif + ]]) + AC_CHECK_HEADER([sensevts.h], + [AC_DEFINE([HAVE_SENSEVTS_H], 1, [Have ])],, + [[ #if HAVE_SENSEVTS_H + #include + #endif + ]]) + AC_SUBST(HAVE_SENS) + AC_SUBST(SENS_LIBS) +fi + +AM_CONDITIONAL([ENABLE_WINDOWS_SENS], [test "$enable_sens" = yes]) + dnl ****************************** dnl Camel Flags dnl ****************************** @@ -1693,6 +1729,7 @@ modules/network-manager/Makefile modules/plugin-lib/Makefile modules/plugin-mono/Makefile modules/plugin-python/Makefile +modules/windows-sens/Makefile plugins/Makefile plugins/addressbook-file/Makefile plugins/attachment-reminder/Makefile @@ -1760,6 +1797,7 @@ fi echo " LDAP support: $msg_ldap NetworkManager: $enable_nm + Windows SENS: $enable_sens Pilot conduits: $msg_pilot Libnotify: $HAVE_LIBNOTIFY Kerberos 5: $msg_krb5 diff --git a/modules/Makefile.am b/modules/Makefile.am index 0b6ccf22ec..653d1b69c6 100644 --- a/modules/Makefile.am +++ b/modules/Makefile.am @@ -10,6 +10,10 @@ if ENABLE_NETWORK_MANAGER NETWORK_MANAGER_DIR = network-manager endif +if ENABLE_WINDOWS_SENS +WINDOWS_SENS_DIR = windows-sens +endif + SUBDIRS = \ addressbook \ calendar \ @@ -17,6 +21,7 @@ SUBDIRS = \ plugin-lib \ $(MONO_DIR) \ $(PYTHON_DIR) \ - $(NETWORK_MANAGER_DIR) + $(NETWORK_MANAGER_DIR) \ + $(WINDOWS_SENS_DIR) -include $(top_srcdir)/git.mk diff --git a/modules/windows-sens/Makefile.am b/modules/windows-sens/Makefile.am new file mode 100644 index 0000000000..5036642d09 --- /dev/null +++ b/modules/windows-sens/Makefile.am @@ -0,0 +1,20 @@ +module_LTLIBRARIES = libevolution-module-windows-sens.la + +libevolution_module_windows_sens_la_CPPFLAGS = \ + $(AM_CPPFLAGS) \ + -I$(top_srcdir) \ + -DG_LOG_DOMAIN=\"evolution-windows-sens\" \ + $(GNOME_PLATFORM_CFLAGS) + +libevolution_module_windows_sens_la_SOURCES = \ + evolution-windows-sens.c + +libevolution_module_windows_sens_la_LIBADD = \ + $(top_builddir)/shell/libeshell.la \ + $(GNOME_PLATFORM_LIBS) \ + $(SENS_LIBS) + +libevolution_module_windows_sens_la_LDFLAGS = \ + -module -avoid-version $(NO_UNDEFINED) + +-include $(top_srcdir)/git.mk diff --git a/modules/windows-sens/evolution-windows-sens.c b/modules/windows-sens/evolution-windows-sens.c new file mode 100644 index 0000000000..d228fc02ac --- /dev/null +++ b/modules/windows-sens/evolution-windows-sens.c @@ -0,0 +1,602 @@ +/* + * evolution-windows-sens.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see + * + */ + +#ifdef __cplusplus +#error This file cannot be built with C++ compiler +#endif + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define INITGUID +#include +#include + +#ifdef HAVE_EVENTSYS_H +#include +#else + +/* Extract relevant typedefs from mingw-w64 headers */ + +typedef struct IEnumEventObject IEnumEventObject; + +const IID IID_IEnumEventObject; +typedef struct IEnumEventObjectVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEnumEventObject *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEnumEventObject *This); + ULONG (WINAPI *Release)(IEnumEventObject *This); + HRESULT (WINAPI *Clone)(IEnumEventObject *This,IEnumEventObject **ppInterface); + HRESULT (WINAPI *Next)(IEnumEventObject *This,ULONG cReqElem,IUnknown **ppInterface,ULONG *cRetElem); + HRESULT (WINAPI *Reset)(IEnumEventObject *This); + HRESULT (WINAPI *Skip)(IEnumEventObject *This,ULONG cSkipElem); + END_INTERFACE +} IEnumEventObjectVtbl; +struct IEnumEventObject { + CONST_VTBL struct IEnumEventObjectVtbl *lpVtbl; +}; + +typedef struct IEventObjectCollection IEventObjectCollection; + +const IID IID_IEventObjectCollection; +typedef struct IEventObjectCollectionVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventObjectCollection *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventObjectCollection *This); + ULONG (WINAPI *Release)(IEventObjectCollection *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventObjectCollection *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventObjectCollection *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventObjectCollection *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventObjectCollection *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *get__NewEnum)(IEventObjectCollection *This,IUnknown **ppUnkEnum); + HRESULT (WINAPI *get_Item)(IEventObjectCollection *This,BSTR objectID,VARIANT *pItem); + HRESULT (WINAPI *get_NewEnum)(IEventObjectCollection *This,IEnumEventObject **ppEnum); + HRESULT (WINAPI *get_Count)(IEventObjectCollection *This,long *pCount); + HRESULT (WINAPI *Add)(IEventObjectCollection *This,VARIANT *item,BSTR objectID); + HRESULT (WINAPI *Remove)(IEventObjectCollection *This,BSTR objectID); + END_INTERFACE +} IEventObjectCollectionVtbl; +struct IEventObjectCollection { + CONST_VTBL struct IEventObjectCollectionVtbl *lpVtbl; +}; + + +typedef struct IEventSystem IEventSystem; + +const IID IID_IEventSystem; +typedef struct IEventSystemVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventSystem *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventSystem *This); + ULONG (WINAPI *Release)(IEventSystem *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventSystem *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventSystem *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventSystem *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventSystem *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *Query)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex,IUnknown **ppInterface); + HRESULT (WINAPI *Store)(IEventSystem *This,BSTR ProgID,IUnknown *pInterface); + HRESULT (WINAPI *Remove)(IEventSystem *This,BSTR progID,BSTR queryCriteria,int *errorIndex); + HRESULT (WINAPI *get_EventObjectChangeEventClassID)(IEventSystem *This,BSTR *pbstrEventClassID); + HRESULT (WINAPI *QueryS)(IEventSystem *This,BSTR progID,BSTR queryCriteria,IUnknown **ppInterface); + HRESULT (WINAPI *RemoveS)(IEventSystem *This,BSTR progID,BSTR queryCriteria); + END_INTERFACE +} IEventSystemVtbl; +struct IEventSystem { + CONST_VTBL struct IEventSystemVtbl *lpVtbl; +}; + +typedef struct IEventSubscription IEventSubscription; + +const IID IID_IEventSubscription; +typedef struct IEventSubscriptionVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(IEventSubscription *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(IEventSubscription *This); + ULONG (WINAPI *Release)(IEventSubscription *This); + HRESULT (WINAPI *GetTypeInfoCount)(IEventSubscription *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(IEventSubscription *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(IEventSubscription *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(IEventSubscription *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *get_SubscriptionID)(IEventSubscription *This,BSTR *pbstrSubscriptionID); + HRESULT (WINAPI *put_SubscriptionID)(IEventSubscription *This,BSTR bstrSubscriptionID); + HRESULT (WINAPI *get_SubscriptionName)(IEventSubscription *This,BSTR *pbstrSubscriptionName); + HRESULT (WINAPI *put_SubscriptionName)(IEventSubscription *This,BSTR bstrSubscriptionName); + HRESULT (WINAPI *get_PublisherID)(IEventSubscription *This,BSTR *pbstrPublisherID); + HRESULT (WINAPI *put_PublisherID)(IEventSubscription *This,BSTR bstrPublisherID); + HRESULT (WINAPI *get_EventClassID)(IEventSubscription *This,BSTR *pbstrEventClassID); + HRESULT (WINAPI *put_EventClassID)(IEventSubscription *This,BSTR bstrEventClassID); + HRESULT (WINAPI *get_MethodName)(IEventSubscription *This,BSTR *pbstrMethodName); + HRESULT (WINAPI *put_MethodName)(IEventSubscription *This,BSTR bstrMethodName); + HRESULT (WINAPI *get_SubscriberCLSID)(IEventSubscription *This,BSTR *pbstrSubscriberCLSID); + HRESULT (WINAPI *put_SubscriberCLSID)(IEventSubscription *This,BSTR bstrSubscriberCLSID); + HRESULT (WINAPI *get_SubscriberInterface)(IEventSubscription *This,IUnknown **ppSubscriberInterface); + HRESULT (WINAPI *put_SubscriberInterface)(IEventSubscription *This,IUnknown *pSubscriberInterface); + HRESULT (WINAPI *get_PerUser)(IEventSubscription *This,WINBOOL *pfPerUser); + HRESULT (WINAPI *put_PerUser)(IEventSubscription *This,WINBOOL fPerUser); + HRESULT (WINAPI *get_OwnerSID)(IEventSubscription *This,BSTR *pbstrOwnerSID); + HRESULT (WINAPI *put_OwnerSID)(IEventSubscription *This,BSTR bstrOwnerSID); + HRESULT (WINAPI *get_Enabled)(IEventSubscription *This,WINBOOL *pfEnabled); + HRESULT (WINAPI *put_Enabled)(IEventSubscription *This,WINBOOL fEnabled); + HRESULT (WINAPI *get_Description)(IEventSubscription *This,BSTR *pbstrDescription); + HRESULT (WINAPI *put_Description)(IEventSubscription *This,BSTR bstrDescription); + HRESULT (WINAPI *get_MachineName)(IEventSubscription *This,BSTR *pbstrMachineName); + HRESULT (WINAPI *put_MachineName)(IEventSubscription *This,BSTR bstrMachineName); + HRESULT (WINAPI *GetPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *PutPublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *RemovePublisherProperty)(IEventSubscription *This,BSTR bstrPropertyName); + HRESULT (WINAPI *GetPublisherPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection); + HRESULT (WINAPI *GetSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *PutSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName,VARIANT *propertyValue); + HRESULT (WINAPI *RemoveSubscriberProperty)(IEventSubscription *This,BSTR bstrPropertyName); + HRESULT (WINAPI *GetSubscriberPropertyCollection)(IEventSubscription *This,IEventObjectCollection **collection); + HRESULT (WINAPI *get_InterfaceID)(IEventSubscription *This,BSTR *pbstrInterfaceID); + HRESULT (WINAPI *put_InterfaceID)(IEventSubscription *This,BSTR bstrInterfaceID); + END_INTERFACE +} IEventSubscriptionVtbl; +struct IEventSubscription { + CONST_VTBL struct IEventSubscriptionVtbl *lpVtbl; +}; + +#define PROGID_EventSubscription OLESTR("EventSystem.EventSubscription") + +#endif + +#ifdef HAVE_SENSEVTS_H +#include +#else + +/* Extract relevant typedefs from mingw-w64 headers */ + +typedef struct { + DWORD dwSize; + DWORD dwFlags; + DWORD dwOutSpeed; + DWORD dwInSpeed; +} *LPSENS_QOCINFO; + +typedef struct ISensNetwork ISensNetwork; + +const IID IID_ISensNetwork; +typedef struct ISensNetworkVtbl { + BEGIN_INTERFACE + HRESULT (WINAPI *QueryInterface)(ISensNetwork *This,REFIID riid,void **ppvObject); + ULONG (WINAPI *AddRef)(ISensNetwork *This); + ULONG (WINAPI *Release)(ISensNetwork *This); + HRESULT (WINAPI *GetTypeInfoCount)(ISensNetwork *This,UINT *pctinfo); + HRESULT (WINAPI *GetTypeInfo)(ISensNetwork *This,UINT iTInfo,LCID lcid,ITypeInfo **ppTInfo); + HRESULT (WINAPI *GetIDsOfNames)(ISensNetwork *This,REFIID riid,LPOLESTR *rgszNames,UINT cNames,LCID lcid,DISPID *rgDispId); + HRESULT (WINAPI *Invoke)(ISensNetwork *This,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS *pDispParams,VARIANT *pVarResult,EXCEPINFO *pExcepInfo,UINT *puArgErr); + HRESULT (WINAPI *ConnectionMade)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType,LPSENS_QOCINFO lpQOCInfo); + HRESULT (WINAPI *ConnectionMadeNoQOCInfo)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType); + HRESULT (WINAPI *ConnectionLost)(ISensNetwork *This,BSTR bstrConnection,ULONG ulType); + HRESULT (WINAPI *DestinationReachable)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,ULONG ulType,LPSENS_QOCINFO lpQOCInfo); + HRESULT (WINAPI *DestinationReachableNoQOCInfo)(ISensNetwork *This,BSTR bstrDestination,BSTR bstrConnection,ULONG ulType); + END_INTERFACE +} ISensNetworkVtbl; +struct ISensNetwork { + CONST_VTBL struct ISensNetworkVtbl *lpVtbl; +}; + +#endif + +#include +#include + +/* 4E14FB9F-2E22-11D1-9964-00C04FBBB345 */ +DEFINE_GUID(IID_IEventSystem, 0x4E14FB9F, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45); + +/* 4A6B0E15-2E38-11D1-9965-00C04FBBB345 */ +DEFINE_GUID(IID_IEventSubscription, 0x4A6B0E15, 0x2E38, 0x11D1, 0x99, 0x65, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45); + +/* d597bab1-5b9f-11d1-8dd2-00aa004abd5e */ +DEFINE_GUID(IID_ISensNetwork, 0xd597bab1, 0x5b9f, 0x11d1, 0x8d, 0xd2, 0x00, 0xaa, 0x00, 0x4a, 0xbd, 0x5e); + +/* 4E14FBA2-2E22-11D1-9964-00C04FBBB345 */ +DEFINE_GUID(CLSID_CEventSystem, 0x4E14FBA2, 0x2E22, 0x11D1, 0x99, 0x64, 0x00, 0xC0, 0x4F, 0xBB, 0xB3, 0x45); + +/* 7542e960-79c7-11d1-88f9-0080c7d771bf */ +DEFINE_GUID(CLSID_CEventSubscription, 0x7542e960, 0x79c7, 0x11d1, 0x88, 0xf9, 0x00, 0x80, 0xc7, 0xd7, 0x71, 0xbf); + + +/* Standard GObject macros */ +#define E_TYPE_WINDOWS_SENS \ + (e_windows_sens_get_type ()) +#define E_WINDOWS_SENS(obj) \ + (G_TYPE_CHECK_INSTANCE_CAST \ + ((obj), E_TYPE_WINDOWS_SENS, EWindowsSENS)) + +typedef struct _EWindowsSENS EWindowsSENS; +typedef struct _EWindowsSENSClass EWindowsSENSClass; + +struct _EWindowsSENS { + EExtension parent; +}; + +struct _EWindowsSENSClass { + EExtensionClass parent_class; +}; + +/* Module Entry Points */ +void e_module_load (GTypeModule *type_module); +void e_module_unload (GTypeModule *type_module); + +/* Forward Declarations */ +GType e_windows_sens_get_type (void); + +G_DEFINE_DYNAMIC_TYPE (EWindowsSENS, e_windows_sens, E_TYPE_EXTENSION) + +static EShell * +windows_sens_get_shell (EWindowsSENS *extension) +{ + EExtensible *extensible; + + extensible = e_extension_get_extensible (E_EXTENSION (extension)); + + return E_SHELL (extensible); +} + +/* Object to receive the ISensNetwork events */ + +typedef struct ESensNetworkListener { + ISensNetworkVtbl *lpVtbl; + long ref; + EWindowsSENS *ews_ptr; +} ESensNetworkListener; + +static void e_sens_network_listener_init(ESensNetworkListener**,EWindowsSENS*); + +/* Functions to implement ISensNetwork interface */ + +static HRESULT WINAPI e_sens_network_listener_queryinterface (ISensNetwork*,REFIID,void**); +static ULONG WINAPI e_sens_network_listener_addref (ISensNetwork*); +static ULONG WINAPI e_sens_network_listener_release (ISensNetwork*); +static HRESULT WINAPI e_sens_network_listener_gettypeinfocount (ISensNetwork*, UINT*); +static HRESULT WINAPI e_sens_network_listener_gettypeinfo (ISensNetwork*,UINT,LCID,ITypeInfo**); +static HRESULT WINAPI e_sens_network_listener_getidsofnames (ISensNetwork*,REFIID,LPOLESTR*,UINT,LCID, DISPID*); +static HRESULT WINAPI e_sens_network_listener_invoke (ISensNetwork*,DISPID,REFIID,LCID,WORD,DISPPARAMS*,VARIANT*,EXCEPINFO*,UINT*); +static HRESULT WINAPI e_sens_network_listener_connectionmade (ISensNetwork*,BSTR,ULONG,LPSENS_QOCINFO); +static HRESULT WINAPI e_sens_network_listener_connectionmadenoqocinfo (ISensNetwork*,BSTR,ULONG); +static HRESULT WINAPI e_sens_network_listener_connectionlost (ISensNetwork*,BSTR,ULONG); +static HRESULT WINAPI e_sens_network_listener_destinationreachable (ISensNetwork*,BSTR,BSTR,ULONG,LPSENS_QOCINFO); +static HRESULT WINAPI e_sens_network_listener_destinationreachablenoqocinfo (ISensNetwork*,BSTR,BSTR,ULONG); + +/* Initializing the VTable of our ESensNetworkListener object */ + +static ISensNetworkVtbl ESensNetworkListenerVtbl = { + e_sens_network_listener_queryinterface, + e_sens_network_listener_addref, + e_sens_network_listener_release, + e_sens_network_listener_gettypeinfocount, + e_sens_network_listener_gettypeinfo, + e_sens_network_listener_getidsofnames, + e_sens_network_listener_invoke, + e_sens_network_listener_connectionmade, + e_sens_network_listener_connectionmadenoqocinfo, + e_sens_network_listener_connectionlost, + e_sens_network_listener_destinationreachable, + e_sens_network_listener_destinationreachablenoqocinfo +}; + + +static HRESULT WINAPI +e_sens_network_listener_queryinterface (ISensNetwork *This, + REFIID iid, + void **ppv) +{ + if (IsEqualIID (iid, &IID_IUnknown) || IsEqualIID (iid, &IID_IDispatch) || IsEqualIID (iid, &IID_ISensNetwork)) { + *ppv = This; + ((LPUNKNOWN)*ppv)->lpVtbl->AddRef((LPUNKNOWN)*ppv); + return S_OK; + } + *ppv = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI +e_sens_network_listener_addref (ISensNetwork *This) +{ + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + return InterlockedIncrement(&(esnl_ptr->ref)); +} + +static ULONG WINAPI +e_sens_network_listener_release (ISensNetwork *This) +{ + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + ULONG tmp = InterlockedDecrement(&(esnl_ptr->ref)); + return tmp; +} + +static HRESULT WINAPI +e_sens_network_listener_gettypeinfocount (ISensNetwork *This, + UINT *pctinfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_gettypeinfo (ISensNetwork *This, + UINT iTInfo, + LCID lcid, + ITypeInfo **ppTInfo) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_getidsofnames (ISensNetwork *This, + REFIID riid, + LPOLESTR *rgszNames, + UINT cNames, + LCID lcid, + DISPID *rgDispId) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_invoke (ISensNetwork *This, + DISPID dispIdMember, + REFIID riid, + LCID lcid, + WORD wFlags, + DISPPARAMS *pDispParams, + VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, + UINT *puArgErr) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionmade (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType, + LPSENS_QOCINFO lpQOCInfo) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + /* Wait a second so that the connection stabilizes */ + g_usleep(G_USEC_PER_SEC); + e_shell_set_network_available (shell, TRUE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionmadenoqocinfo (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType) +{ + //Always followed by ConnectionMade + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_connectionlost (ISensNetwork *This, + BSTR bstrConnection, + ULONG ulType) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + e_shell_set_network_available (shell, FALSE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_destinationreachable (ISensNetwork *This, + BSTR bstrDestination, + BSTR bstrConnection, + ULONG ulType, + LPSENS_QOCINFO lpQOCInfo) +{ + if (ulType) { + ESensNetworkListener *esnl_ptr=(ESensNetworkListener*)This; + EShell *shell = windows_sens_get_shell (esnl_ptr->ews_ptr); + /* Wait a second so that the connection stabilizes */ + g_usleep(G_USEC_PER_SEC); + e_shell_set_network_available (shell, TRUE); + } + return S_OK; +} + +static HRESULT WINAPI +e_sens_network_listener_destinationreachablenoqocinfo (ISensNetwork *This, + BSTR bstrDestination, + BSTR bstrConnection, + ULONG ulType) +{ + return S_OK; +} + +static void +e_sens_network_listener_init(ESensNetworkListener **esnl_ptr, + EWindowsSENS *ews) +{ + (*esnl_ptr) = g_new0(ESensNetworkListener,1); + (*esnl_ptr)->lpVtbl = &ESensNetworkListenerVtbl; + (*esnl_ptr)->ews_ptr = ews; + (*esnl_ptr)->ref = 1; +} + + +static BSTR +_mb2wchar (const char* a) +{ + static WCHAR b[64]; + MultiByteToWideChar (0, 0, a, -1, b, 64); + return b; +} + +static const char* add_curly_braces_to_uuid (const char* string_uuid) +{ + static char curly_braced_uuid_string[64]; + int i; + if (!string_uuid) + return NULL; + lstrcpy(curly_braced_uuid_string,"{"); + i = strlen(curly_braced_uuid_string); + lstrcat(curly_braced_uuid_string+i,string_uuid); + i = strlen(curly_braced_uuid_string); + lstrcat(curly_braced_uuid_string+i,"}"); + return curly_braced_uuid_string; +} + +static void +windows_sens_constructed (GObject *object) +{ + HRESULT res; + static IEventSystem *pEventSystem =0; + static IEventSubscription* pEventSubscription = 0; + static ESensNetworkListener *pESensNetworkListener = 0; + static const char* eventclassid="{D5978620-5B9F-11D1-8DD2-00AA004ABD5E}"; + static const char* methods[]={ + "ConnectionMade", + "ConnectionMadeNoQOCInfo", + "ConnectionLost", + "DestinationReachable", + "DestinationReachableNoQOCInfo" + }; + static const char* names[]={ + "EWS_ConnectionMade", + "EWS_ConnectionMadeNoQOCInfo", + "EWS_ConnectionLost", + "EWS_DestinationReachable", + "EWS_DestinationReachableNoQOCInfo" + }; + unsigned char* subids[] = { 0, 0, 0, 0, 0 }; + + EWindowsSENS *extension = (E_WINDOWS_SENS (object)); + e_sens_network_listener_init(&pESensNetworkListener, extension); + + CoInitialize(0); + + res=CoCreateInstance (&CLSID_CEventSystem, 0,CLSCTX_SERVER,&IID_IEventSystem,(LPVOID*)&pEventSystem); + + if (res == S_OK && pEventSystem) { + + unsigned i; + + for (i=0; ilpVtbl->put_SubscriptionID (pEventSubscription, _mb2wchar (add_curly_braces_to_uuid ((char*)subids[i]))); + if (res) { + RpcStringFree (&subids[i]); + break; + } + RpcStringFree (&subids[i]); + res=pEventSubscription->lpVtbl->put_SubscriptionName (pEventSubscription, _mb2wchar (names[i])); + if (res) + break; + res=pEventSubscription->lpVtbl->put_MethodName (pEventSubscription, _mb2wchar (methods[i])); + if (res) + break; + res=pEventSubscription->lpVtbl->put_EventClassID (pEventSubscription, _mb2wchar (eventclassid)); + if (res) + break; + res=pEventSubscription->lpVtbl->put_SubscriberInterface (pEventSubscription, (IUnknown*)pESensNetworkListener); + if (res) + break; + /* Make the subscription receive the event only if the owner of the subscription + * is logged on to the same computer as the publisher. This makes this module + * work with normal user account without administrative privileges. + */ + res=pEventSubscription->lpVtbl->put_PerUser (pEventSubscription, TRUE); + if (res) + break; + + res=pEventSystem->lpVtbl->Store (pEventSystem, (BSTR)PROGID_EventSubscription, (IUnknown*)pEventSubscription); + if (res) + break; + pEventSubscription->lpVtbl->Release (pEventSubscription); + pEventSubscription=0; + } + } + if (pEventSubscription) + pEventSubscription->lpVtbl->Release(pEventSubscription); + } + + /* Do not try to get initial state when we are sure we will not get system events. + * Like that we don't get stuck with Disconnected status if we were disconnected + * on start. + */ + if (res == S_OK) { + + typedef BOOL (WINAPI* IsNetworkAlive_t) (LPDWORD); + BOOL alive = TRUE; + EShell *shell = windows_sens_get_shell (extension); + + IsNetworkAlive_t pIsNetworkAlive = NULL; + + HMODULE hDLL=LoadLibrary ("sensapi.dll"); + + if ((pIsNetworkAlive=(IsNetworkAlive_t) GetProcAddress (hDLL, "IsNetworkAlive"))) { + DWORD Network; + alive=pIsNetworkAlive (&Network); + } + + FreeLibrary(hDLL); + + e_shell_set_network_available (shell, alive); + } +} + +static void +e_windows_sens_class_init (EWindowsSENSClass *_class) +{ + GObjectClass *object_class; + EExtensionClass *extension_class; + + object_class = G_OBJECT_CLASS (_class); + object_class->constructed = windows_sens_constructed; + + extension_class = E_EXTENSION_CLASS (_class); + extension_class->extensible_type = E_TYPE_SHELL; +} + +static void +e_windows_sens_class_finalize (EWindowsSENSClass *_class) +{ +} + +static void +e_windows_sens_init (EWindowsSENS *extension) +{ +} + +G_MODULE_EXPORT void +e_module_load (GTypeModule *type_module) +{ + e_windows_sens_register_type (type_module); +} + +G_MODULE_EXPORT void +e_module_unload (GTypeModule *type_module) +{ +} + -- cgit v1.2.3 From f07352c5b344cb7f254a41695909622a759efe86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fridrich=20=C5=A0trba?= Date: Thu, 25 Mar 2010 17:05:15 +0100 Subject: Avoid warning about redefined localtime_r --- e-util/e-datetime-format.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/e-util/e-datetime-format.c b/e-util/e-datetime-format.c index ec3e4fb8fe..0595d58add 100644 --- a/e-util/e-datetime-format.c +++ b/e-util/e-datetime-format.c @@ -29,6 +29,9 @@ #define KEYS_GROUPNAME "formats" #ifdef G_OS_WIN32 +#ifdef localtime_r +#undef localtime_r +#endif /* The localtime() in Microsoft's C library *is* thread-safe */ #define localtime_r(timep, result) (localtime (timep) ? memcpy ((result), localtime (timep), sizeof (*(result))) : 0) #endif -- cgit v1.2.3 From 3dfd9aa7c4b24f8971382dcc5278714956066ff8 Mon Sep 17 00:00:00 2001 From: Fridrich Strba Date: Sun, 21 Mar 2010 00:12:01 +0100 Subject: [win32] Be consistent in disabling the lockdown options. --- mail/e-mail-reader.c | 4 ++++ modules/mail/em-composer-prefs.c | 4 ++++ shell/e-shell-utils.c | 2 ++ shell/e-shell-window-private.c | 2 ++ widgets/misc/e-web-view.c | 2 ++ 5 files changed, 14 insertions(+) diff --git a/mail/e-mail-reader.c b/mail/e-mail-reader.c index ad60195b58..d238d500a9 100644 --- a/mail/e-mail-reader.c +++ b/mail/e-mail-reader.c @@ -2159,8 +2159,12 @@ mail_reader_update_actions (EMailReader *reader) shell = e_shell_backend_get_shell (shell_backend); shell_settings = e_shell_get_shell_settings (shell); +#ifndef G_OS_WIN32 disable_printing = e_shell_settings_get_boolean ( shell_settings, "disable-printing"); +#else + disable_printing = FALSE; +#endif have_an_account = (state & E_MAIL_READER_HAVE_ACCOUNT); diff --git a/modules/mail/em-composer-prefs.c b/modules/mail/em-composer-prefs.c index 3d1cf2ed08..574657806e 100644 --- a/modules/mail/em-composer-prefs.c +++ b/modules/mail/em-composer-prefs.c @@ -521,9 +521,11 @@ em_composer_prefs_construct (EMComposerPrefs *prefs, shell_settings, "composer-format-html", widget, "prefer-html"); +#ifndef G_OS_WIN32 e_binding_new_with_negation ( shell_settings, "disable-command-line", widget, "allow-scripts"); +#endif signature_tree_view = e_signature_manager_get_tree_view ( E_SIGNATURE_MANAGER (widget)); @@ -533,9 +535,11 @@ em_composer_prefs_construct (EMComposerPrefs *prefs, gtk_container_add (GTK_CONTAINER (container), widget); gtk_widget_show (widget); +#ifndef G_OS_WIN32 e_binding_new_with_negation ( shell_settings, "disable-command-line", widget, "allow-scripts"); +#endif e_binding_new ( signature_tree_view, "selected", diff --git a/shell/e-shell-utils.c b/shell/e-shell-utils.c index a584289d20..c7b296931c 100644 --- a/shell/e-shell-utils.c +++ b/shell/e-shell-utils.c @@ -70,6 +70,7 @@ e_shell_configure_web_view (EShell *shell, shell_settings = e_shell_get_shell_settings (shell); +#ifndef G_OS_WIN32 e_binding_new ( shell_settings, "disable-printing", web_view, "disable-printing"); @@ -77,6 +78,7 @@ e_shell_configure_web_view (EShell *shell, e_binding_new ( shell_settings, "disable-save-to-disk", web_view, "disable-save-to-disk"); +#endif } /** diff --git a/shell/e-shell-window-private.c b/shell/e-shell-window-private.c index c4389ab3bc..faccac8052 100644 --- a/shell/e-shell-window-private.c +++ b/shell/e-shell-window-private.c @@ -359,6 +359,7 @@ e_shell_window_private_constructed (EShellWindow *shell_window) shell_window, "notify::active-view", G_CALLBACK (e_shell_window_update_search_menu), NULL); +#ifndef G_OS_WIN32 /* Support lockdown. */ action_group = ACTION_GROUP (LOCKDOWN_PRINTING); @@ -378,6 +379,7 @@ e_shell_window_private_constructed (EShellWindow *shell_window) e_binding_new_with_negation ( shell_settings, "disable-save-to-disk", action_group, "visible"); +#endif /* Bind GObject properties to GObject properties. */ diff --git a/widgets/misc/e-web-view.c b/widgets/misc/e-web-view.c index ce41c32d4c..e9fc71d7ca 100644 --- a/widgets/misc/e-web-view.c +++ b/widgets/misc/e-web-view.c @@ -1063,6 +1063,7 @@ web_view_class_init (EWebViewClass *class) PROP_COPY_TARGET_LIST, "copy-target-list"); +#ifndef G_OS_WIN32 g_object_class_install_property ( object_class, PROP_DISABLE_PRINTING, @@ -1082,6 +1083,7 @@ web_view_class_init (EWebViewClass *class) NULL, FALSE, G_PARAM_READWRITE)); +#endif g_object_class_install_property ( object_class, -- cgit v1.2.3 From f0a09020d6824e86e13e1ee64c23a4a0a0200f40 Mon Sep 17 00:00:00 2001 From: Jeff Cai Date: Thu, 8 Apr 2010 10:18:37 +0800 Subject: Fix for bug #613564 If no <> in the email address, addr should be the full email address. --- addressbook/gui/contact-editor/e-contact-quick-add.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addressbook/gui/contact-editor/e-contact-quick-add.c b/addressbook/gui/contact-editor/e-contact-quick-add.c index 36bd4ed948..d10ceeac6f 100644 --- a/addressbook/gui/contact-editor/e-contact-quick-add.c +++ b/addressbook/gui/contact-editor/e-contact-quick-add.c @@ -605,6 +605,8 @@ e_contact_quick_add_email (const gchar *email, EContactQuickAddCallback cb, gpoi if (lt != NULL && gt != NULL && (gt - lt) > 0) { name = g_strndup (email, lt - email); addr = g_strndup (lt + 1, gt - lt - 1); + } else { + addr = email; } e_contact_quick_add (name, addr, cb, closure); -- cgit v1.2.3 From a629756a400180bb1b2764a276aebabdd78770d1 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 8 Apr 2010 12:14:55 +0200 Subject: Bug #612236 - Find-As-You-Type in Folder list stops working --- mail/message-list.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/mail/message-list.c b/mail/message-list.c index 02b7ce9908..ed1236524c 100644 --- a/mail/message-list.c +++ b/mail/message-list.c @@ -2516,12 +2516,6 @@ message_list_finalize (GObject *object) G_OBJECT_CLASS (parent_class)->finalize (object); } -static void -message_list_built (MessageList *message_list) -{ - gtk_widget_grab_focus (GTK_WIDGET (message_list)); -} - static void message_list_selectable_update_actions (ESelectable *selectable, EFocusTracker *focus_tracker, @@ -2563,7 +2557,7 @@ message_list_class_init (MessageListClass *class) gtk_object_class = GTK_OBJECT_CLASS (class); gtk_object_class->destroy = message_list_destroy; - class->message_list_built = message_list_built; + class->message_list_built = NULL; /* Inherited from ESelectableInterface */ g_object_class_override_property ( -- cgit v1.2.3 From 5df72deec71e159ff4aa4fa9d55695c806a37c29 Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 8 Apr 2010 13:56:03 +0200 Subject: Bug #614325 - Shrink/expand To,Cc header images is missing --- mail/e-mail-display.c | 4 +-- mail/em-format-html.c | 68 ++++++++++++++++----------------------------------- 2 files changed, 23 insertions(+), 49 deletions(-) diff --git a/mail/e-mail-display.c b/mail/e-mail-display.c index 70789c0d47..86ed222f04 100644 --- a/mail/e-mail-display.c +++ b/mail/e-mail-display.c @@ -239,12 +239,12 @@ mail_display_link_clicked (GtkHTML *html, if (!(flags & EM_FORMAT_HTML_HEADER_CC)) flags |= EM_FORMAT_HTML_HEADER_CC; else - flags |= EM_FORMAT_HTML_HEADER_CC; + flags &= ~EM_FORMAT_HTML_HEADER_CC; } else if (strcmp (uri, "##BCC##") == 0) { if (!(flags & EM_FORMAT_HTML_HEADER_BCC)) flags |= EM_FORMAT_HTML_HEADER_BCC; else - flags |= EM_FORMAT_HTML_HEADER_BCC; + flags &= ~EM_FORMAT_HTML_HEADER_BCC; } priv->formatter->header_wrap_flags = flags; diff --git a/mail/em-format-html.c b/mail/em-format-html.c index 26c6f92ff3..ad47742ba8 100644 --- a/mail/em-format-html.c +++ b/mail/em-format-html.c @@ -1480,17 +1480,22 @@ efh_url_requested(GtkHTML *html, const gchar *url, GtkHTMLStream *handle, EMForm } else if (g_ascii_strncasecmp(url, "http:", 5) == 0 || g_ascii_strncasecmp(url, "https:", 6) == 0) { d(printf(" adding job, get %s\n", url)); job = em_format_html_job_new(efh, emfh_gethttp, g_strdup(url)); - } else if (g_ascii_strncasecmp(url, "/", 1) == 0) { + } else if (g_str_has_prefix (url, "file://")) { gchar *data = NULL; gsize length = 0; gboolean status; + gchar *path; + + path = g_filename_from_uri (url, NULL, NULL); + g_return_if_fail (path != NULL); - status = g_file_get_contents (url, &data, &length, NULL); + status = g_file_get_contents (path, &data, &length, NULL); if (status) gtk_html_stream_write (handle, data, length); - gtk_html_stream_close(handle, status? GTK_HTML_STREAM_OK : GTK_HTML_STREAM_ERROR); + gtk_html_stream_close (handle, status ? GTK_HTML_STREAM_OK : GTK_HTML_STREAM_ERROR); g_free (data); + g_free (path); } else { d(printf("HTML Includes reference to unknown uri '%s'\n", url)); gtk_html_stream_close(handle, GTK_HTML_STREAM_ERROR); @@ -2295,74 +2300,43 @@ efh_format_address (EMFormatHTML *efh, GString *out, struct _camel_header_addres /* Let us add a '...' if we have more addresses */ if (limit > 0 && wrap && a && (i>(limit-1))) { - - gchar * evolution_imagesdir = g_filename_to_uri(EVOLUTION_IMAGESDIR, NULL, NULL); + gchar *evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL); if (!strcmp (field, _("To"))) { - g_string_append (out, "..."); -#ifdef G_OS_WIN32 - str = g_strdup_printf ("+ "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif - g_free(evolution_imagesdir); - - return str; + str = g_strdup_printf (" ", evolution_imagesdir); } else if (!strcmp (field, _("Cc"))) { g_string_append (out, "..."); -#ifdef G_OS_WIN32 - str = g_strdup_printf ("+ "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif - g_free(evolution_imagesdir); - - return str; + str = g_strdup_printf (" ", evolution_imagesdir); } else if (!strcmp (field, _("Bcc"))) { g_string_append (out, "..."); -#ifdef G_OS_WIN32 - str = g_strdup_printf ("+ "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif - g_free(evolution_imagesdir); + str = g_strdup_printf (" ", evolution_imagesdir); + } + g_free (evolution_imagesdir); + + if (str) return str; - } } } if (limit > 0 && i>(limit)) { - - gchar * evolution_imagesdir = g_filename_to_uri(EVOLUTION_IMAGESDIR, NULL, NULL); + gchar *evolution_imagesdir = g_filename_to_uri (EVOLUTION_IMAGESDIR, NULL, NULL); if (!strcmp (field, _("To"))) { -#ifdef G_OS_WIN32 - str = g_strdup_printf ("- "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif + str = g_strdup_printf (" ", evolution_imagesdir); } else if (!strcmp (field, _("Cc"))) { -#ifdef G_OS_WIN32 - str = g_strdup_printf ("- "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif + str = g_strdup_printf (" ", evolution_imagesdir); } else if (!strcmp (field, _("Bcc"))) { -#ifdef G_OS_WIN32 - str = g_strdup_printf ("- "); -#else - str = g_strdup_printf (" ", evolution_imagesdir); -#endif + str = g_strdup_printf (" ", evolution_imagesdir); } - g_free(evolution_imagesdir); + g_free (evolution_imagesdir); } return str; -- cgit v1.2.3 From 74e6e7c71db8f30b1c140275d2fccf4f7bef0c04 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 8 Apr 2010 10:16:18 -0400 Subject: Remove gtk_notebook_set_tab_label_packing(). --- capplet/settings/mail-view.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/capplet/settings/mail-view.c b/capplet/settings/mail-view.c index 84214888a9..a344d59251 100644 --- a/capplet/settings/mail-view.c +++ b/capplet/settings/mail-view.c @@ -319,7 +319,6 @@ mail_view_add_folder (MailView *mv, gpointer data, gboolean block) g_signal_connect (mfv, "view-close", G_CALLBACK(mv_close_mcv), mv); if (!block) gtk_notebook_set_current_page ((GtkNotebook *)mv, position); - gtk_notebook_set_tab_label_packing ((GtkNotebook *)mv, (GtkWidget *)mfv, FALSE, FALSE, 0); g_signal_connect (mfv, "message-shown", G_CALLBACK(mv_message_shown), mv); g_signal_connect (mfv, "message-new", G_CALLBACK(mv_message_new), mv); g_signal_connect (mfv, "search-set", G_CALLBACK(mv_search_set), mv); @@ -359,7 +358,6 @@ mail_view_add_composer (MailView *mv, gpointer data, gboolean block) gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (mv), (GtkWidget *)mcv, FALSE); if (!block) gtk_notebook_set_current_page ((GtkNotebook *)mv, position); - gtk_notebook_set_tab_label_packing ((GtkNotebook *)mv, (GtkWidget *)mcv, FALSE, FALSE, 0); if (!block) mail_composer_view_activate (mcv, mv->folder_tree, mv->check_mail, mv->sort_by, FALSE); @@ -387,7 +385,6 @@ mail_view_add_message (MailView *mv, gpointer data, gboolean block) gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (mv), (GtkWidget *)mcv, FALSE); if (!block) gtk_notebook_set_current_page ((GtkNotebook *)mv, position+1); - gtk_notebook_set_tab_label_packing ((GtkNotebook *)mv, (GtkWidget *)mcv, FALSE, FALSE, 0); if (!block) mail_conv_view_activate (mcv, mv->tree, mv->folder_tree, mv->check_mail, mv->sort_by, FALSE); -- cgit v1.2.3 From 5d362dba25a974b826a864dbfab5cd3510b77f12 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Thu, 8 Apr 2010 13:52:58 -0400 Subject: Add missing linker flag to NetworkManager extension. --- modules/network-manager/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/network-manager/Makefile.am b/modules/network-manager/Makefile.am index 24cd80a246..f7a01a6c31 100644 --- a/modules/network-manager/Makefile.am +++ b/modules/network-manager/Makefile.am @@ -13,6 +13,7 @@ libevolution_module_network_manager_la_SOURCES = \ libevolution_module_network_manager_la_LIBADD = \ $(top_builddir)/shell/libeshell.la \ + $(top_builddir)/e-util/libeutil.la \ $(GNOME_PLATFORM_LIBS) \ $(DBUS_GLIB_LIBS) -- cgit v1.2.3 From ad1de0aa0889edaa0ad9bc41c170fa84ec5536f2 Mon Sep 17 00:00:00 2001 From: Dominique Leuenberger Date: Fri, 9 Apr 2010 10:13:18 +0200 Subject: Bug #589393 - Configure fails to detect pilot-link utf8 capabilities --- configure.ac | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index 882dd1d3a8..bb82419c13 100644 --- a/configure.ac +++ b/configure.ac @@ -656,8 +656,8 @@ if test "x$enable_pilot_conduits" = "xyes"; then CFLAGS_save="$CFLAGS" CFLAGS="$CFLAGS $GNOME_PILOT_CFLAGS" - LDFLAGS_save="$LDFLAGS" - LDFLAGS="$GNOME_PILOT_LIBS $LDFLAGS" + LIBS_save="$LIBS" + LIBS="$LIBS $GNOME_PILOT_LIBS $LDFLAGS" AC_CACHE_CHECK([if pilot-link handles UTF-8 conversions],[ac_cv_pilot_link_utf8], AC_RUN_IFELSE([AC_LANG_SOURCE( @@ -677,7 +677,7 @@ if test "x$enable_pilot_conduits" = "xyes"; then )],[ac_cv_pilot_link_utf8=yes],[ac_cv_pilot_link_utf8=no],[ac_cv_pilot_link_utf8=no])) CFLAGS="$CFLAGS_save" - LDFLAGS="$LDFLAGS_save" + LIBS="$LIBS_save" if test "$ac_cv_pilot_link_utf8" = no; then AC_MSG_ERROR([evolution requires pilot-link to have working UTF-8 conversion routines]) -- cgit v1.2.3