diff options
Diffstat (limited to 'mail/mail-summary.c')
-rw-r--r-- | mail/mail-summary.c | 523 |
1 files changed, 0 insertions, 523 deletions
diff --git a/mail/mail-summary.c b/mail/mail-summary.c deleted file mode 100644 index 94057e53ab..0000000000 --- a/mail/mail-summary.c +++ /dev/null @@ -1,523 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ -/* mail-summary.c - * - * Authors: Iain Holmes <iain@helixcode.com> - * - * Copyright (C) 2000 Helix Code, Inc. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <bonobo/bonobo-property-bag.h> - -#include "camel.h" -#include "mail.h" -#include "mail-tools.h" -#include "mail-ops.h" -#include "mail-vfolder.h" -#include "mail-summary.h" - -#include "Evolution.h" -#include "evolution-storage.h" -#include "evolution-storage-listener.h" - -#include "filter/vfolder-context.h" - -#include <evolution-services/executive-summary-component.h> -#include <evolution-services/executive-summary-html-view.h> - -typedef struct { - CamelFolder *folder; - - char *name; - char *uri; - int total, unread; -} FolderSummary; - -typedef struct { - BonoboObject *component; - BonoboObject *view; - EvolutionStorageListener *listener; - - GHashTable *folder_to_summary; - FolderSummary **folders; - int numfolders; - - char *title; - char *icon; - - guint idle; - gboolean in_summary; -} MailSummary; - -#define SUMMARY_IN() g_print ("IN: %s: %d\n", __FUNCTION__, __LINE__); -#define SUMMARY_OUT() g_print ("OUT: %s: %d\n", __FUNCTION__, __LINE__); - -static int queue_len = 0; - -extern char *evolution_dir; -extern EvolutionStorage *vfolder_storage; - -#define MAIN_READER main_compipe[0] -#define MAIN_WRITER main_compipe[1] -#define DISPATCH_READER dispatch_compipe[0] -#define DISPATCH_WRITER dispatch_compipe[1] - -static int main_compipe[2] = {-1, -1}; -static int dispatch_compipe[2] = {-1, -1}; - -GIOChannel *summary_chan_reader = NULL; - -static gboolean do_changed (MailSummary *summary); - -enum { - PROPERTY_TITLE, - PROPERTY_ICON -}; - -/* Read a message from the pipe */ -static gboolean -read_msg (GIOChannel *source, - GIOCondition condition, - gpointer user_data) -{ - MailSummary *summary; - int size; - - summary = g_new0 (MailSummary, 1); - g_io_channel_read (source, (gchar *) summary, - sizeof (MailSummary) / sizeof (gchar), &size); - - if (size != sizeof (MailSummary)) { - g_warning (_("Incomplete message written on pipe!")); - return TRUE; - } - - do_changed (summary); - g_free (summary); - - return TRUE; -} - -/* check_compipes: */ -static void -check_compipes (void) -{ - if (MAIN_READER < 0) { - if (pipe (main_compipe) < 0) { - g_warning ("Call to pipe failed"); - return; - } - - summary_chan_reader = g_io_channel_unix_new (MAIN_READER); - g_io_add_watch (summary_chan_reader, G_IO_IN, read_msg, NULL); - } - - if (DISPATCH_READER < 0) { - if (pipe (dispatch_compipe) < 0) { - g_warning ("Call to pipe failed"); - return; - } - } -} - -static void -folder_free (FolderSummary *folder) -{ - g_free (folder->name); - g_free (folder->uri); -} - -static void -summary_free (MailSummary *summary) -{ - int i; - - for (i = 0; i < summary->numfolders; i++){ - folder_free (summary->folders[i]); - } - - g_free (summary->folders); - g_free (summary->title); - g_free (summary->icon); - - g_hash_table_destroy (summary->folder_to_summary); -} - -static void -view_destroy_cb (GtkObject *object, - MailSummary *summary) -{ - summary_free (summary); - g_free (summary); -} - -static char * -generate_html_summary (MailSummary *summary) -{ - char *ret_html = NULL, *tmp; - FolderSummary *fs; - int i; - - summary->in_summary = TRUE; - /* Inbox first */ - fs = summary->folders[0]; - - g_print ("%p: %p\n", fs, fs->name); - g_print ("unread: %d\n", fs->unread); - g_print ("total: %d\n", fs->total); - - tmp = g_strdup_printf ("<table><tr><td><b><a href=\"view://evolution:/local/Inbox\">%s</a>:</b>" - "<td align=\"right\">%d/%d</td></tr>", - fs->name, fs->unread, fs->total); - - ret_html = g_strdup (tmp); - for (i = 1; i < summary->numfolders; i++) { - char *tmp2; - - fs = summary->folders[i]; - tmp2 = g_strdup_printf ("<tr><td><a href=\"view://%s\">%s</a>:</td>" - "<td align=\"right\">%d/%d</td></tr>", - fs->uri, fs->name, fs->unread, fs->total); - - tmp = ret_html; - ret_html = g_strconcat (ret_html, tmp2, NULL); - g_free (tmp); - g_free (tmp2); - } - - tmp = ret_html; - ret_html = g_strconcat (ret_html, "</table>", NULL); - g_free (tmp); - - summary->in_summary = FALSE; - return ret_html; -} - -static gboolean -do_changed (MailSummary *summary) -{ - char *ret_html; - - ret_html = generate_html_summary (summary); - executive_summary_html_view_set_html(EXECUTIVE_SUMMARY_HTML_VIEW(summary->view), (const char *) ret_html); - g_free (ret_html); - - summary->idle = 0; - return TRUE; -} - -/* These two callbacks are called from the Camel thread, - which can't make any CORBA calls, or else ORBit locks up, - and likewise the thread that can call ORBit, cannot call - camel. - - So, when the callbacks are triggered, they generate a MailSummary - structure and write this onto a pipe. The ORBit calling thread - detects when something is written to the pipe and creates its own - MailSummary structure, and calls the appropriate CORBA calls. - - Same theory as mail-threads.c, but a lot less complicated - as there is only one way communication, and only one type of message -*/ -static void -folder_changed_cb (CamelObject *folder, - gpointer event_data, - gpointer user_data) -{ - MailSummary *summary; - FolderSummary *fs; - - summary = (MailSummary *) user_data; - fs = g_hash_table_lookup (summary->folder_to_summary, folder); - if (fs == NULL) { - g_warning ("%s: Unknown folder", __FUNCTION__); - return; - } - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - - write (MAIN_WRITER, summary, sizeof (MailSummary)); - queue_len++; - - return; -} - -static void -message_changed_cb (CamelObject *folder, - gpointer event_data, - gpointer user_data) -{ - MailSummary *summary; - FolderSummary *fs; - - summary = (MailSummary *)user_data; - fs = g_hash_table_lookup (summary->folder_to_summary, folder); - if (fs == NULL) { - g_warning ("%s: Unknown folder.", __FUNCTION__); - return; - } - - fs->unread = camel_folder_get_unread_message_count (fs->folder); - fs->total = camel_folder_get_message_count (fs->folder); - - write (MAIN_WRITER, summary, sizeof (MailSummary)); - queue_len++; - - return; -} - -static void -generate_folder_summaries (MailSummary *summary) -{ - int numfolders = 1; /* Always at least the Inbox */ - char *user, *system; - FilterRule *rule; - VfolderContext *context; - FolderSummary *fs; - CamelException *ex; - int i; - - user = g_strdup_printf ("%s/vfolders.xml", evolution_dir); - system = g_strdup_printf ("%s/evolution/vfoldertypes.xml", EVOLUTION_DATADIR); - - context = vfolder_context_new (); - rule_context_load ((RuleContext *)context, system, user); - g_free (user); - g_free (system); - - rule = NULL; - while ((rule = rule_context_next_rule ((RuleContext *)context, rule, NULL))){ - g_print ("rule->name: %s\n", rule->name); - numfolders++; - } - - if (summary->folders != NULL) { - int i; - - for (i = 0; i < summary->numfolders; i++){ - folder_free (summary->folders[i]); - } - - g_free (summary->folders); - } - - summary->folders = g_new (FolderSummary *, numfolders); - - /* Inbox */ - fs = summary->folders[0] = g_new (FolderSummary, 1); - fs->name = g_strdup ("Inbox"); - g_print ("%p: %s(%p)\n", fs, fs->name, fs->name); - fs->uri = NULL; - ex = camel_exception_new (); - fs->folder = mail_tool_get_local_inbox (ex); - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - camel_exception_free (ex); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), "folder_changed", - (CamelObjectEventHookFunc) folder_changed_cb, - summary); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), "message_changed", - (CamelObjectEventHookFunc) message_changed_cb, - summary); - g_hash_table_insert (summary->folder_to_summary, fs->folder, fs); - - - summary->numfolders = 1; - - for (i = 1, rule = NULL; i < numfolders; i++) { - char *uri; - - ex = camel_exception_new (); - fs = summary->folders[i] = g_new (FolderSummary, 1); - rule = rule_context_next_rule ((RuleContext *)context, rule, NULL); - fs->name = g_strdup (rule->name); - - uri = g_strconcat ("vfolder:", rule->name, NULL); - fs->folder = vfolder_uri_to_folder (uri, ex); - fs->uri = g_strconcat ("evolution:/VFolders/", rule->name, NULL); - g_free (uri); - - fs->total = camel_folder_get_message_count (fs->folder); - fs->unread = camel_folder_get_unread_message_count (fs->folder); - - /* Connect to each folder */ - camel_object_hook_event (CAMEL_OBJECT (fs->folder), - "folder_changed", - (CamelObjectEventHookFunc) folder_changed_cb, - summary); - camel_object_hook_event (CAMEL_OBJECT (fs->folder), - "message_changed", - (CamelObjectEventHookFunc) message_changed_cb, - summary); - g_hash_table_insert (summary->folder_to_summary, fs->folder, fs); - summary->numfolders++; - - camel_exception_free (ex); - } - - gtk_object_destroy (GTK_OBJECT (context)); -} - -static void -get_property (BonoboPropertyBag *bag, - BonoboArg *arg, - guint arg_id, - CORBA_Environment *ev, - gpointer user_data) -{ - MailSummary *summary = (MailSummary *) user_data; - - switch (arg_id) { - case PROPERTY_TITLE: - BONOBO_ARG_SET_STRING (arg, summary->title); - break; - - case PROPERTY_ICON: - BONOBO_ARG_SET_STRING (arg, summary->icon); - break; - - default: - break; - } -} - -/* This code may play with the threads wrongly... - if the mail component locks when you use the summary - remove this define */ -#define DETECT_NEW_VFOLDERS -#ifdef DETECT_NEW_VFOLDERS - -/* Check that we can generate a new summary - and keep coming back until we can. */ -static gboolean -idle_check (gpointer data) -{ - MailSummary *summary = (MailSummary *) data; - - if (summary->in_summary == TRUE) - return TRUE; - - generate_folder_summaries (summary); - write (MAIN_WRITER, summary, sizeof (MailSummary)); - queue_len++; - summary->idle = 0; - - return FALSE; -} - -static void -new_folder_cb (EvolutionStorageListener *listener, - const char *path, - const GNOME_Evolution_Folder *folder, - MailSummary *summary) -{ - g_print ("New folder: %s\n", path); - - if (summary->idle == 0) - summary->idle = g_idle_add ((GSourceFunc) idle_check, summary); -} - -static void -removed_folder_cb (EvolutionStorageListener *listener, - const char *path, - MailSummary *summary) -{ - g_print ("Removed folder: %s\n", path); - - if (summary->idle == 0) - summary->idle = g_idle_add ((GSourceFunc) idle_check, summary); -} -#endif - -BonoboObject * -create_summary_view (ExecutiveSummaryComponentFactory *_factory, - void *closure) -{ - GNOME_Evolution_Storage corba_local_objref; - GNOME_Evolution_StorageListener corba_object; - CORBA_Environment ev; - BonoboObject *component, *view; - BonoboPropertyBag *bag; - BonoboEventSource *event_source; - MailSummary *summary; - - summary = g_new (MailSummary, 1); - summary->folders = 0; - summary->in_summary = FALSE; - summary->folder_to_summary = g_hash_table_new (NULL, NULL); - summary->title = g_strdup ("Mail Summary"); - summary->icon = g_strdup ("envelope.png"); - summary->idle = 0; - - check_compipes (); - - component = executive_summary_component_new (); - summary->component = component; - - event_source = bonobo_event_source_new (); - - view = executive_summary_html_view_new_full (event_source); - bonobo_object_add_interface (component, view); - summary->view = view; - gtk_signal_connect (GTK_OBJECT (view), "destroy", - GTK_SIGNAL_FUNC (view_destroy_cb), summary); - - bag = bonobo_property_bag_new_full (get_property, NULL, - event_source, summary); - bonobo_property_bag_add (bag, - "window_title", PROPERTY_TITLE, - BONOBO_ARG_STRING, NULL, - "The title of this component's window", - BONOBO_PROPERTY_READABLE); - bonobo_property_bag_add (bag, - "window_icon", PROPERTY_ICON, - BONOBO_ARG_STRING, NULL, - "The icon for this component's window", - BONOBO_PROPERTY_READABLE); - bonobo_object_add_interface (component, BONOBO_OBJECT(bag)); - -#ifdef DETECT_NEW_VFOLDERS - summary->listener = evolution_storage_listener_new (); - gtk_signal_connect (GTK_OBJECT (summary->listener), "new_folder", - GTK_SIGNAL_FUNC (new_folder_cb), summary); - gtk_signal_connect (GTK_OBJECT (summary->listener), "removed_folder", - GTK_SIGNAL_FUNC (removed_folder_cb), summary); - - corba_object = evolution_storage_listener_corba_objref (summary->listener); - - CORBA_exception_init (&ev); - corba_local_objref = bonobo_object_corba_objref (BONOBO_OBJECT (vfolder_storage)); - - GNOME_Evolution_Storage_addListener (corba_local_objref, - corba_object, &ev); - if (ev._major != CORBA_NO_EXCEPTION) { - g_warning ("Cannot add a listener to the vfolder storage."); - } - CORBA_exception_free (&ev); -#endif - - if (summary->idle == 0) - summary->idle = g_idle_add ((GSourceFunc) idle_check, summary); - - return component; -} |