Files
evolution/modules/offline-alert/evolution-offline-alert.c
Matthew Barnes b674a37a38 Add an EOfflineAlert module.
This module posts an alert to the first EShellWindow when starting
offline, and also posts an alert when the network connection drops.

We get frequent questions on the mailing list from users not realizing
Evolution is starting in offline mode, so this is meant to help address
that confusion.
2010-10-18 12:32:36 -04:00

222 lines
5.5 KiB
C

/*
* evolution-offline-alert.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see <http://www.gnu.org/licenses/>
*
*/
#include <shell/e-shell-view.h>
#include <shell/e-shell-window-actions.h>
#include <e-util/e-alert-sink.h>
#include <e-util/e-extension.h>
/* Standard GObject macros */
#define E_TYPE_OFFLINE_ALERT \
(e_offline_alert_get_type ())
#define E_OFFLINE_ALERT(obj) \
(G_TYPE_CHECK_INSTANCE_CAST \
((obj), E_TYPE_OFFLINE_ALERT, EOfflineAlert))
typedef struct _EOfflineAlert EOfflineAlert;
typedef struct _EOfflineAlertClass EOfflineAlertClass;
struct _EOfflineAlert {
EExtension parent;
gpointer alert; /* weak pointer */
};
struct _EOfflineAlertClass {
EExtensionClass parent_class;
};
/* Module Entry Points */
void e_module_load (GTypeModule *type_module);
void e_module_unload (GTypeModule *type_module);
/* Forward Declarations */
GType e_offline_alert_get_type (void);
G_DEFINE_DYNAMIC_TYPE (EOfflineAlert, e_offline_alert, E_TYPE_EXTENSION)
static EShell *
offline_alert_get_shell (EOfflineAlert *extension)
{
EExtensible *extensible;
extensible = e_extension_get_extensible (E_EXTENSION (extension));
return E_SHELL (extensible);
}
static void
offline_alert_online_cb (EShell *shell,
GParamSpec *pspec,
EOfflineAlert *extension)
{
if (!e_shell_get_online (shell))
return;
if (extension->alert != NULL)
e_alert_response (extension->alert, GTK_RESPONSE_OK);
}
static void
offline_alert_network_available_cb (EShell *shell,
GParamSpec *pspec,
EOfflineAlert *extension)
{
GList *list, *iter;
if (e_shell_get_network_available (shell))
return;
g_return_if_fail (extension->alert == NULL);
extension->alert = e_alert_new ("offline-alert:no-network", NULL);
g_object_add_weak_pointer (
G_OBJECT (extension->alert), &extension->alert);
/* Broadcast the alert to all EShellWindows. */
list = e_shell_get_watched_windows (shell);
for (iter = list; iter != NULL; iter = g_list_next (iter)) {
GtkWidget *window = iter->data;
if (!E_IS_SHELL_WINDOW (window))
continue;
e_alert_sink_submit_alert (window, extension->alert);
}
g_object_unref (extension->alert);
}
static void
offline_alert_window_created_cb (EShell *shell,
GtkWindow *window,
EOfflineAlert *extension)
{
GtkAction *action;
if (!E_IS_SHELL_WINDOW (window))
return;
/* Connect these signals after we have the first EShellWindow
* to avoid false-positive signals during EShell initialization. */
g_signal_connect (
shell, "notify::online",
G_CALLBACK (offline_alert_online_cb), extension);
g_signal_connect (
shell, "notify::network-available",
G_CALLBACK (offline_alert_network_available_cb), extension);
g_signal_handlers_disconnect_by_func (
shell, offline_alert_window_created_cb, extension);
if (e_shell_get_online (shell))
return;
if (!e_shell_get_network_available (shell)) {
g_object_notify (G_OBJECT (shell), "network-available");
return;
}
g_return_if_fail (extension->alert == NULL);
/* This alert only shows at startup, not when the user
* chooses to work offline. That's why we only wanted
* the first EShellWindow. */
action = E_SHELL_WINDOW_ACTION_WORK_ONLINE (window);
extension->alert = e_alert_new ("offline-alert:offline", NULL);
e_alert_add_action (extension->alert, action, GTK_RESPONSE_NONE);
g_object_add_weak_pointer (
G_OBJECT (extension->alert), &extension->alert);
e_alert_sink_submit_alert (GTK_WIDGET (window), extension->alert);
g_object_unref (extension->alert);
}
static void
offline_alert_dispose (GObject *object)
{
EOfflineAlert *extension;
extension = E_OFFLINE_ALERT (object);
if (extension->alert != NULL) {
g_object_remove_weak_pointer (
G_OBJECT (extension->alert), &extension->alert);
extension->alert = NULL;
}
/* Chain up to parent's dispose() method. */
G_OBJECT_CLASS (e_offline_alert_parent_class)->dispose (object);
}
static void
offline_alert_constructed (GObject *object)
{
EShell *shell;
EOfflineAlert *extension;
extension = E_OFFLINE_ALERT (object);
shell = offline_alert_get_shell (extension);
/* Watch for the first EShellWindow. */
g_signal_connect (
shell, "window-created",
G_CALLBACK (offline_alert_window_created_cb), extension);
}
static void
e_offline_alert_class_init (EOfflineAlertClass *class)
{
GObjectClass *object_class;
EExtensionClass *extension_class;
object_class = G_OBJECT_CLASS (class);
object_class->dispose = offline_alert_dispose;
object_class->constructed = offline_alert_constructed;
extension_class = E_EXTENSION_CLASS (class);
extension_class->extensible_type = E_TYPE_SHELL;
}
static void
e_offline_alert_class_finalize (EOfflineAlertClass *class)
{
}
static void
e_offline_alert_init (EOfflineAlert *extension)
{
}
G_MODULE_EXPORT void
e_module_load (GTypeModule *type_module)
{
e_offline_alert_register_type (type_module);
}
G_MODULE_EXPORT void
e_module_unload (GTypeModule *type_module)
{
}