diff options
author | Iain Holmes <iain@src.gnome.org> | 2002-03-18 23:47:04 +0800 |
---|---|---|
committer | Iain Holmes <iain@src.gnome.org> | 2002-03-18 23:47:04 +0800 |
commit | bc73d24d04269d1cd4df99acdb511580626ca98f (patch) | |
tree | be2344b66d4dcbfe8a28fac8446f3243f2c1b800 | |
parent | 0ae3f73824ac55fab40594bc0ee16812d0f3bbf4 (diff) | |
download | gsoc2013-evolution-bc73d24d04269d1cd4df99acdb511580626ca98f.tar.gz gsoc2013-evolution-bc73d24d04269d1cd4df99acdb511580626ca98f.tar.zst gsoc2013-evolution-bc73d24d04269d1cd4df99acdb511580626ca98f.zip |
VFolders in the summary
svn path=/trunk/; revision=16190
-rw-r--r-- | my-evolution/ChangeLog | 73 | ||||
-rw-r--r-- | my-evolution/Makefile.am | 4 | ||||
-rw-r--r-- | my-evolution/check-empty.xpm | 21 | ||||
-rw-r--r-- | my-evolution/check-filled.xpm | 21 | ||||
-rw-r--r-- | my-evolution/check-none.xpm | 20 | ||||
-rw-r--r-- | my-evolution/e-cell-tri.c | 121 | ||||
-rw-r--r-- | my-evolution/e-cell-tri.h | 44 | ||||
-rw-r--r-- | my-evolution/e-summary-mail.c | 329 | ||||
-rw-r--r-- | my-evolution/e-summary-preferences.c | 96 | ||||
-rw-r--r-- | my-evolution/e-summary-shown.c | 582 | ||||
-rw-r--r-- | my-evolution/e-summary-shown.h | 73 | ||||
-rw-r--r-- | my-evolution/e-summary-table.c | 26 | ||||
-rw-r--r-- | my-evolution/e-summary-table.h | 3 | ||||
-rw-r--r-- | my-evolution/e-summary-weather.c | 51 | ||||
-rw-r--r-- | my-evolution/e-summary-weather.h | 3 | ||||
-rw-r--r-- | my-evolution/e-summary.c | 3 | ||||
-rw-r--r-- | my-evolution/e-summary.h | 1 |
17 files changed, 1306 insertions, 165 deletions
diff --git a/my-evolution/ChangeLog b/my-evolution/ChangeLog index 06672392e0..b646f0e252 100644 --- a/my-evolution/ChangeLog +++ b/my-evolution/ChangeLog @@ -1,3 +1,76 @@ +2002-03-15 Iain Holmes <iain@ximian.com> + + * Makefile.am: Add the e-summary-shown.[ch] files. + + * e-summary-mail.c: Add entries for the Storages in the private + struct. + (new_folder_cb): Only allow mail folders that are local or vfolders. + Store the StorageInfo that the folder belongs to in the folder struct + Add the folder to the list of folders in the storage. + (update_folder_cb): Update the signature. + (mail_change_notify): Simplify the check to see if we are displaying + the folder. + (e_summary_mail_register_storage): Take a name argument. + Create a StorageInfo structure, connect the signals and add the + listener. + (e_summary_mail_register_local_storage): Get the local storage from + the shell and register it with e_summary_mail_register_storage. + (storage_notify): Receive notifications when a new storage is created + or destroyed or changed. Stuff only happens when a storage is + created, currently. + (e_summary_mail_register_storages): Don't register local storage + here. Get the StorageRegistry from the corba_shell, create a new + BonoboListener and add it to the registry. + (e_summary_mail_init): Free a CORBA_Environment. + (e_summary_mail_reconfigure): Add a check for the uri being a + vfolder. + (str_compare): Compare ESummaryMailFolders instead of MailRowDatas. + (sort_storages): Compare 2 storage names. + (get_parent_path): Special case for the vfolders. + (insert_path_recur): Remove the toplevel creation. + Create a toplevel node if the uri is a storage toplevel. + Special case the name finder for vfolders. + Get the number of children in the parent so that we can add the new + child after the rest. + (add_storage_to_table): For each folder in a storage, add it to the + table. + (make_toplevel): Generate the toplevel name for each storage. + (e_summary_mail_fill_list): For each storage, add the folders. + + * e-summary-preferences.c (fill_rdf_etable): Put the entries into an + ESummaryShown instead of an ESummaryTable. + (make_property_dialog): Hook up to the Showns. + (add_shown_to_list): Add the locations to the list. + (property_box_clicked_cb): Create a new list for the RDFs and + weathers. + (e_summary_preferences_make_rdf_table): Make an ESummaryShown. + (e_summary_preferences_make_weather_table): Make an ESummaryShown. + + * e-summary-table.c: Use ECellTri. + (value_at): Get the right value for the TriCell. + (set_value_at): Set the right value for the TriCell. + (e_summary_table_init): Use the ECellTri. + (e_summary_table_get_num_children): Get the number of children a + path has. + + * e-summary-weather.c (e_summary_weather_fill_etable): Use an + ESummaryShown instead of ESummaryTable. + + * e-summary.[ch]: Store the GNOME_Evolution_Shell in the nonprivate + structure. + + * e-summary-shown.[ch]: Widget to do Add-> <-Remove with two tables. + +2002-02-22 Iain Holmes <iain@ximian.com> + + * e-summary-factory.c: Use the new configure icon. + +2002-02-13 Iain Holmes <iain@ximian.com> + + * Makefile.am: Add the e-cell-tri.[ch] files + + * e-summary-table.c + 2002-03-14 Ettore Perazzoli <ettore@ximian.com> * e-summary-factory.c (e_summary_factory_new_control): Call diff --git a/my-evolution/Makefile.am b/my-evolution/Makefile.am index 4507864148..d3ab2b8418 100644 --- a/my-evolution/Makefile.am +++ b/my-evolution/Makefile.am @@ -30,6 +30,8 @@ evolution_executive_summary_SOURCES = \ $(MAIL_GENERATED) \ component-factory.c \ component-factory.h \ + e-cell-tri.c \ + e-cell-tri.h \ e-summary.c \ e-summary.h \ e-summary-calendar.c \ @@ -44,6 +46,8 @@ evolution_executive_summary_SOURCES = \ e-summary-preferences.h \ e-summary-rdf.c \ e-summary-rdf.h \ + e-summary-shown.c \ + e-summary-shown.h \ e-summary-table.c \ e-summary-table.h \ e-summary-tasks.c \ diff --git a/my-evolution/check-empty.xpm b/my-evolution/check-empty.xpm new file mode 100644 index 0000000000..746b20234e --- /dev/null +++ b/my-evolution/check-empty.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * check_empty_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ............ ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" ............ ", +" ", +" "}; diff --git a/my-evolution/check-filled.xpm b/my-evolution/check-filled.xpm new file mode 100644 index 0000000000..c0468fc25b --- /dev/null +++ b/my-evolution/check-filled.xpm @@ -0,0 +1,21 @@ +/* XPM */ +static const char * check_filled_xpm[] = { +"16 16 2 1", +" c None", +". c #000000", +" ", +" ", +" ............ ", +" . . ", +" . . . ", +" . .. . ", +" . ... . ", +" . . ... . ", +" . .. ... . ", +" . ..... . ", +" . ... . ", +" . . . ", +" . . ", +" ............ ", +" ", +" "}; diff --git a/my-evolution/check-none.xpm b/my-evolution/check-none.xpm new file mode 100644 index 0000000000..7213f1c565 --- /dev/null +++ b/my-evolution/check-none.xpm @@ -0,0 +1,20 @@ +/* XPM */ +static const char * check_none_xpm[] = { +"16 16 1 1", +" c None", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" ", +" "}; diff --git a/my-evolution/e-cell-tri.c b/my-evolution/e-cell-tri.c new file mode 100644 index 0000000000..677ce26a2c --- /dev/null +++ b/my-evolution/e-cell-tri.c @@ -0,0 +1,121 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Iain Holmes <iain@ximian.com> + * + * Copyright 2002 Ximain, Inc. (www.ximian.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <gdk/gdkkeysyms.h> +#include <gdk-pixbuf/gdk-pixbuf.h> +#include <gal/util/e-util.h> +#include <gal/e-table/e-table-item.h> + +#include "e-cell-tri.h" + +#include "check-none.xpm" +#include "check-empty.xpm" +#include "check-filled.xpm" + +#define PARENT_TYPE e_cell_toggle_get_type () + +static GdkPixbuf *checks[3]; + +static void +set_value (ECellView *view, + int model_col, + int view_col, + int row, + int value) +{ + ECell *ecell = view->ecell; + ECellToggle *toggle = E_CELL_TOGGLE (ecell); + + if (value >= toggle->n_states) { + g_print ("Value 2: %d\n", value); + value = 1; + } + + e_table_model_set_value_at (view->e_table_model, + model_col, row, GINT_TO_POINTER (value)); +} + +static gint +event (ECellView *ecell_view, + GdkEvent *event, + int model_col, + int view_col, + int row, + ECellFlags flags, + ECellActions *actions) +{ + void *_value = e_table_model_value_at (ecell_view->e_table_model, model_col, row); + const int value = GPOINTER_TO_INT (_value); + + switch (event->type) { + case GDK_KEY_PRESS: + if (event->key.keyval != GDK_space) { + return FALSE; + } + /* Fall through */ + case GDK_BUTTON_PRESS: + if (e_table_model_is_cell_editable (ecell_view->e_table_model, model_col, row) == FALSE) { + return FALSE; + } + if (value == 0) { + return FALSE; + } + + set_value (ecell_view, model_col, view_col, row, value + 1); + return TRUE; + + default: + return FALSE; + } + + return TRUE; +} + +static void +e_cell_tri_class_init (GtkObjectClass *object_class) +{ + ECellClass *e_cell_class = E_CELL_CLASS (object_class); + + e_cell_class->event = event; + + checks[0] = gdk_pixbuf_new_from_xpm_data (check_none_xpm); + checks[1] = gdk_pixbuf_new_from_xpm_data (check_empty_xpm); + checks[2] = gdk_pixbuf_new_from_xpm_data (check_filled_xpm); + +} + +E_MAKE_TYPE (e_cell_tri, "ECellTri", ECellTri, e_cell_tri_class_init, NULL, PARENT_TYPE); + +ECell * +e_cell_tri_new (void) +{ + ECellTri *ect = gtk_type_new (e_cell_tri_get_type ()); + + e_cell_toggle_construct (E_CELL_TOGGLE (ect), 2, 3, checks); + + return (ECell *) ect; +} + diff --git a/my-evolution/e-cell-tri.h b/my-evolution/e-cell-tri.h new file mode 100644 index 0000000000..52221e3cb6 --- /dev/null +++ b/my-evolution/e-cell-tri.h @@ -0,0 +1,44 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Iain Holmes <iain@ximian.com> + * + * Copyright 2002 Ximain, Inc. (www.ximian.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __E_CELL_TRI_H__ +#define __E_CELL_TRI_H__ + +#include <gal/e-table/e-cell-toggle.h> +#include <libgnome/gnome-defs.h> + +BEGIN_GNOME_DECLS + +typedef struct _ECellTri { + ECellToggle parent; +} ECellTri; + +typedef struct _ECellTriClass { + ECellToggleClass parent_class; +} ECellTriClass; + +GtkType e_cell_tri_get_type (void); +ECell *e_cell_tri_new (void); + +END_GNOME_DECLS + +#endif diff --git a/my-evolution/e-summary-mail.c b/my-evolution/e-summary-mail.c index 5d6d7fc0d2..3d5c378c6f 100644 --- a/my-evolution/e-summary-mail.c +++ b/my-evolution/e-summary-mail.c @@ -47,9 +47,12 @@ struct _ESummaryMail { GNOME_Evolution_FolderInfo folder_info; + GNOME_Evolution_StorageRegistry registry; BonoboListener *listener; EvolutionStorageListener *storage_listener; + GSList *storage_list; + GHashTable *folders; GList *shown; ESummaryMailMode mode; @@ -57,6 +60,16 @@ struct _ESummaryMail { char *html; }; +typedef struct _StorageInfo { + char *name; + char *toplevel; + + GNOME_Evolution_Storage storage; + EvolutionStorageListener *listener; + ESummary *summary; + GList *folders; +} StorageInfo; + typedef struct _ESummaryMailFolder { char *name; char *path; @@ -65,6 +78,7 @@ typedef struct _ESummaryMailFolder { int unread; gboolean init; /* Has this folder been initialised? */ + StorageInfo *si; } ESummaryMailFolder; /* Work out what to do with folder names */ @@ -179,21 +193,26 @@ static void new_folder_cb (EvolutionStorageListener *listener, const char *path, const GNOME_Evolution_Folder *folder, - ESummary *summary) + StorageInfo *si) { + ESummary *summary = si->summary; ESummaryMail *mail; ESummaryMailFolder *mail_folder; GList *p; /* Don't care about non mail */ + g_print ("Folder->physicalUri: %s...", folder->physicalUri); if (strcmp (folder->type, "mail") != 0 || - strncmp (folder->physicalUri, "file://", 7) != 0) { + (strncmp (folder->physicalUri, "file://", 7) != 0 && + strncmp (folder->physicalUri, "vfolder", 7) != 0)) { + g_print ("rejected\n"); return; } - + g_print ("accepted\n"); mail = summary->mail; mail_folder = g_new (ESummaryMailFolder, 1); + mail_folder->si = si; mail_folder->path = g_strdup (folder->physicalUri); mail_folder->name = g_strdup (path); mail_folder->count = -1; @@ -201,17 +220,14 @@ new_folder_cb (EvolutionStorageListener *listener, mail_folder->init = FALSE; g_hash_table_insert (mail->folders, mail_folder->path, mail_folder); - + si->folders = g_list_prepend (si->folders, mail_folder); + for (p = summary->preferences->display_folders; p; p = p->next) { - char *uri; - - uri = g_strconcat ("file://", p->data, NULL); - if (strcmp (uri, folder->physicalUri) == 0) { + if (strcmp (p->data, folder->physicalUri) == 0) { mail->shown = g_list_append (mail->shown, mail_folder); e_summary_mail_get_info (mail, mail_folder->path, mail->listener); } - g_free (uri); } } @@ -219,8 +235,9 @@ static void update_folder_cb (EvolutionStorageListener *listener, const char *path, int unread_count, - ESummary *summary) + StorageInfo *si) { + ESummary *summary = si->summary; char *evolution_dir; static char *proto = NULL; char *uri; @@ -242,8 +259,9 @@ update_folder_cb (EvolutionStorageListener *listener, static void remove_folder_cb (EvolutionStorageListener *listener, const char *path, - ESummary *summary) + StorageInfo *si) { + ESummary *summary = si->summary; ESummaryMail *mail; ESummaryMailFolder *mail_folder; GList *p; @@ -298,17 +316,10 @@ mail_change_notify (BonoboListener *listener, /* Are we displaying this folder? */ for (p = summary->preferences->display_folders; p; p = p->next) { - char *uri; - - uri = g_strconcat ("file://", p->data, NULL); - if (strcmp (uri, folder->path) == 0) { + if (strcmp (p->data, folder->path) == 0) { e_summary_draw (summary); - - g_free (uri); return; } - - g_free (uri); } } @@ -319,30 +330,38 @@ e_summary_mail_protocol (ESummary *summary, { } + + static gboolean e_summary_mail_register_storage (ESummary *summary, + const char *name, GNOME_Evolution_Storage corba_storage) { ESummaryMail *mail; - EvolutionStorageListener *listener; GNOME_Evolution_StorageListener corba_listener; + StorageInfo *si; CORBA_Environment ev; mail = summary->mail; - if (mail->storage_listener == NULL) { - mail->storage_listener = evolution_storage_listener_new (); + si = g_new (StorageInfo, 1); + si->name = g_strdup (name); + si->toplevel = NULL; + si->summary = summary; + si->storage = corba_storage; + si->listener = evolution_storage_listener_new (); + si->folders = NULL; - gtk_signal_connect (GTK_OBJECT (mail->storage_listener), "new-folder", - GTK_SIGNAL_FUNC (new_folder_cb), summary); - gtk_signal_connect (GTK_OBJECT (mail->storage_listener), "removed-folder", - GTK_SIGNAL_FUNC (remove_folder_cb), summary); - gtk_signal_connect (GTK_OBJECT (mail->storage_listener), "update_folder", - GTK_SIGNAL_FUNC (update_folder_cb), summary); - } - listener = mail->storage_listener; + mail->storage_list = g_slist_prepend (mail->storage_list, si); - corba_listener = evolution_storage_listener_corba_objref (listener); + gtk_signal_connect (GTK_OBJECT (si->listener), "new-folder", + GTK_SIGNAL_FUNC (new_folder_cb), si); + gtk_signal_connect (GTK_OBJECT (si->listener), "removed-folder", + GTK_SIGNAL_FUNC (remove_folder_cb), si); + gtk_signal_connect (GTK_OBJECT (si->listener), "update_folder", + GTK_SIGNAL_FUNC (update_folder_cb), si); + + corba_listener = evolution_storage_listener_corba_objref (si->listener); CORBA_exception_init (&ev); GNOME_Evolution_Storage_addListener (corba_storage, corba_listener, &ev); @@ -360,31 +379,116 @@ e_summary_mail_register_storage (ESummary *summary, return TRUE; } +static void +e_summary_mail_register_local_storage (ESummary *summary) +{ + ESummaryMail *mail; + GNOME_Evolution_Storage local_storage; + CORBA_Environment ev; + + mail = summary->mail; + + CORBA_exception_init (&ev); + local_storage = GNOME_Evolution_Shell_getLocalStorage (summary->shell, &ev); + if (BONOBO_EX (&ev) || local_storage == CORBA_OBJECT_NIL) { + g_warning ("Error getting local storage: %s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); + return; + } + CORBA_exception_free (&ev); + + e_summary_mail_register_storage (summary, _("Local Folders"), local_storage); +} + +static void +storage_notify (BonoboListener *listener, + const char *name, + const BonoboArg *arg, + CORBA_Environment *ev, + ESummary *summary) +{ + GNOME_Evolution_StorageRegistry_NotifyResult *nr; + GNOME_Evolution_Storage corba_storage; + CORBA_Environment ev2; + ESummaryMail *mail; + + mail = summary->mail; + g_return_if_fail (mail != NULL); + + nr = arg->_value; + switch (nr->type) { + case GNOME_Evolution_StorageRegistry_STORAGE_CREATED: + /* These need to be special cased because they're special */ + if (strcmp (nr->name, "summary") == 0) { + break; + } + + if (strcmp (nr->name, "local") == 0) { + e_summary_mail_register_local_storage (summary); + break; + } + + CORBA_exception_init (&ev2); + corba_storage = GNOME_Evolution_StorageRegistry_getStorageByName (mail->registry, + nr->name, &ev2); + if (BONOBO_EX (&ev2) || corba_storage == CORBA_OBJECT_NIL) { + g_warning ("Error getting storage %s\n%s", nr->name, + CORBA_exception_id (&ev2)); + CORBA_exception_free (&ev2); + return; + } + + CORBA_exception_free (&ev2); + e_summary_mail_register_storage (summary, nr->name, corba_storage); + break; + + case GNOME_Evolution_StorageRegistry_STORAGE_DESTROYED: + g_print ("%s removed\n", nr->name); + break; + + default: + g_print ("Unknown response %d\n", nr->type); + break; + } +} + static gboolean e_summary_mail_register_storages (ESummary *summary, GNOME_Evolution_Shell corba_shell) { - GNOME_Evolution_Storage local_storage; + Bonobo_Listener corba_listener; + BonoboListener *listener; CORBA_Environment ev; g_return_val_if_fail (summary != NULL, FALSE); g_return_val_if_fail (IS_E_SUMMARY (summary), FALSE); CORBA_exception_init (&ev); - local_storage = GNOME_Evolution_Shell_getLocalStorage (corba_shell, &ev); - if (BONOBO_EX (&ev)) { - g_warning ("Exception getting local storage: %s", - CORBA_exception_id (&ev)); + + summary->mail->registry = Bonobo_Unknown_queryInterface (corba_shell, + "IDL:GNOME/Evolution/StorageRegistry:1.0", + &ev); + if (BONOBO_EX (&ev) || summary->mail->registry == NULL) { + g_warning ("No storage registry: %s", CORBA_exception_id (&ev)); CORBA_exception_free (&ev); - return FALSE; } - CORBA_exception_free (&ev); - if (e_summary_mail_register_storage (summary, local_storage)) - return TRUE; - else + listener = bonobo_listener_new (NULL, NULL); + gtk_signal_connect (GTK_OBJECT (listener), "event-notify", + GTK_SIGNAL_FUNC (storage_notify), summary); + corba_listener = bonobo_object_corba_objref (BONOBO_OBJECT (listener)); + + /* Storages will be added whenever the listener gets an event. */ + GNOME_Evolution_StorageRegistry_addListener (summary->mail->registry, corba_listener, &ev); + if (BONOBO_EX (&ev)) { + g_warning ("Cannot add listener\n%s", CORBA_exception_id (&ev)); + CORBA_exception_free (&ev); return FALSE; + } + + CORBA_exception_free (&ev); + return TRUE; } void @@ -411,6 +515,8 @@ e_summary_mail_init (ESummary *summary, return; } + CORBA_exception_free (&ev); + /* Create a BonoboListener for all the notifies. */ mail->listener = bonobo_listener_new (NULL, NULL); gtk_signal_connect (GTK_OBJECT (mail->listener), "event-notify", @@ -442,11 +548,13 @@ e_summary_mail_reconfigure (ESummary *summary) ESummaryMailFolder *folder; char *uri; - if (strncmp (p->data, "file://", 7) == 0) { + if (strncmp (p->data, "file://", 7) == 0 || + strncmp (p->data, "vfolder:", 8) == 0) { uri = g_strdup (p->data); } else { uri = g_strconcat ("file://", p->data, NULL); } + folder = g_hash_table_lookup (mail->folders, uri); if (folder != NULL) { if (folder->init == FALSE) { @@ -499,11 +607,23 @@ static int str_compare (gconstpointer a, gconstpointer b) { - ESummaryMailRowData *rda, *rdb; + ESummaryMailFolder *folder_a, *folder_b; - rda = (ESummaryMailRowData *) a; - rdb = (ESummaryMailRowData *) b; - return strcmp (rda->name, rdb->name); + folder_a = (ESummaryMailFolder *) a; + folder_b = (ESummaryMailFolder *) b; + return strcasecmp (folder_a->name, folder_b->name); +} + +static int +sort_storages (gconstpointer a, + gconstpointer b) +{ + StorageInfo *si_a, *si_b; + + si_a = (StorageInfo *) a; + si_b = (StorageInfo *) b; + + return strcasecmp (si_a->name, si_b->name); } static char * @@ -511,8 +631,16 @@ get_parent_path (const char *path) { char *last; - last = strrchr (path, '/'); - return g_strndup (path, last - path); + if (strncmp (path, "vfolder", 7) == 0) { + last = strrchr (path, '#'); + if (last == NULL) { + return g_strdup (path); + } + return g_strndup (path, last - path); + } else { + last = strrchr (path, '/'); + return g_strndup (path, last - path); + } } static gboolean @@ -533,6 +661,7 @@ is_folder_shown (ESummaryMail *mail, static ETreePath insert_path_recur (ESummaryTable *est, + StorageInfo *si, GHashTable *hash_table, const char *path, ESummaryMail *mail) @@ -540,37 +669,46 @@ insert_path_recur (ESummaryTable *est, char *parent_path, *name; ETreePath parent_node, node; ESummaryTableModelEntry *entry; - static char *toplevel = NULL; + int children; parent_path = get_parent_path (path); - if (toplevel == NULL) { - char *tmp; - - tmp = gnome_util_prepend_user_home ("evolution/local"); - toplevel = g_strconcat ("file://", tmp, NULL); - g_free (tmp); - } - parent_node = g_hash_table_lookup (hash_table, parent_path); if (parent_node == NULL) { - if (strcmp (toplevel, path) == 0) { + if (strcmp (si->toplevel, path) == 0) { /* Insert root */ - return NULL; + children = e_summary_table_get_num_children (est, NULL); + node = e_summary_table_add_node (est, NULL, children, NULL); + entry = g_new (ESummaryTableModelEntry, 1); + entry->path = node; + entry->location = NULL; + entry->name = g_strdup (si->name); + entry->editable = FALSE; + entry->removable = FALSE; + entry->shown = FALSE; + + g_hash_table_insert (est->model, entry->path, entry); + g_hash_table_insert (hash_table, g_strdup (path), node); + return node; } else { - parent_node = insert_path_recur (est, hash_table, parent_path, mail); + parent_node = insert_path_recur (est, si, hash_table, parent_path, mail); } } g_free (parent_path); - name = strrchr (path, '/'); + if (strcmp (si->name, "VFolders") == 0) { + name = strrchr (path, '#'); + } else { + name = strrchr (path, '/'); + } /* Leave out folders called "subfolder" */ if (strcmp (name + 1, "subfolders") == 0) { return parent_node; } - - node = e_summary_table_add_node (est, parent_node, 0, NULL); + + children = e_summary_table_get_num_children (est, parent_node); + node = e_summary_table_add_node (est, parent_node, children, NULL); entry = g_new (ESummaryTableModelEntry, 1); entry->path = node; entry->location = g_strdup (path); @@ -594,13 +732,52 @@ free_path_hash (gpointer key, g_free (key); } +static void +add_storage_to_table (ESummaryTable *est, + StorageInfo *si, + ESummary *summary) +{ + GHashTable *path_hash; + GList *p; + + path_hash = g_hash_table_new (g_str_hash, g_str_equal); + p = g_list_sort (si->folders, str_compare); + + for (; p; p = p->next) { + ESummaryMailFolder *folder = p->data; + + insert_path_recur (est, si, path_hash, folder->path, summary->mail); + } + + g_hash_table_foreach (path_hash, free_path_hash, NULL); + g_hash_table_destroy (path_hash); +} + +static void +make_toplevel (StorageInfo *si) +{ + if (si->toplevel != NULL) { + return; + } + + if (strcmp (si->name, "VFolders") == 0) { + si->toplevel = g_strdup_printf ("vfolder:%s/evolution/vfolder", + g_get_home_dir ()); + } else if (strcmp (si->name, "Local Folders") == 0) { + si->toplevel = g_strdup_printf ("file://%s/evolution/local", + g_get_home_dir ()); + } else { + g_warning ("Unknown folder name... EEEEEEKEKEKEKEE!"); + si->toplevel = g_strdup ("Dunno"); + } +} + void e_summary_mail_fill_list (ESummaryTable *est, ESummary *summary) { ESummaryMail *mail; - GList *names, *p; - GHashTable *path_hash; + GSList *p; g_return_if_fail (IS_E_SUMMARY_TABLE (est)); g_return_if_fail (IS_E_SUMMARY (summary)); @@ -610,22 +787,16 @@ e_summary_mail_fill_list (ESummaryTable *est, return; } - names = NULL; - g_hash_table_foreach (mail->folders, hash_to_list, &names); + p = g_slist_sort (mail->storage_list, sort_storages); + for (; p; p = p->next) { + StorageInfo *si = p->data; - path_hash = g_hash_table_new (g_str_hash, g_str_equal); - - names = g_list_sort (names, str_compare); - for (p = names; p; p = p->next) { - ESummaryMailRowData *rd = p->data; - insert_path_recur (est, path_hash, rd->uri, mail); - free_row_data (rd); + if (si->toplevel == NULL) { + make_toplevel (si); + } + + add_storage_to_table (est, si, summary); } - - /* Free everything */ - g_list_free (names); - g_hash_table_foreach (path_hash, free_path_hash, NULL); - g_hash_table_destroy (path_hash); } const char * diff --git a/my-evolution/e-summary-preferences.c b/my-evolution/e-summary-preferences.c index ec3aa02327..9b8f63dfa0 100644 --- a/my-evolution/e-summary-preferences.c +++ b/my-evolution/e-summary-preferences.c @@ -45,6 +45,7 @@ #include "e-summary.h" #include "e-summary-preferences.h" #include "e-summary-table.h" +#include "e-summary-shown.h" #include "evolution-config-control.h" @@ -570,8 +571,8 @@ static void fill_rdf_etable (GtkWidget *widget, PropertyData *pd) { - ESummaryTableModelEntry *entry; - ESummaryTable *est; + ESummaryShownModelEntry *entry; + ESummaryShown *ess; FILE *handle; int i, total; char *rdf_file, line[4096]; @@ -580,22 +581,20 @@ fill_rdf_etable (GtkWidget *widget, pd->rdf->default_hash = g_hash_table_new (g_str_hash, g_str_equal); } - est = E_SUMMARY_TABLE (widget); + ess = E_SUMMARY_SHOWN (widget); /* Fill the defaults first */ for (i = 0; rdfs[i].url; i++) { - ETreePath path; - - path = e_summary_table_add_node (est, NULL, i, NULL); - - entry = g_new (ESummaryTableModelEntry, 1); - entry->path = path; + entry = g_new (ESummaryShownModelEntry, 1); entry->location = g_strdup (rdfs[i].url); entry->name = g_strdup (rdfs[i].name); - entry->editable = TRUE; - entry->removable = FALSE; - entry->shown = rdf_is_shown (pd, entry->location); - g_hash_table_insert (est->model, entry->path, entry); + entry->showable = TRUE; + + e_summary_shown_add_node (ess, TRUE, entry, NULL, NULL); + + if (rdf_is_shown (pd, rdfs[i].url) == TRUE) { + e_summary_shown_add_node (ess, FALSE, entry, NULL, NULL); + } pd->rdf->known = g_list_append (pd->rdf->known, &rdfs[i]); @@ -619,7 +618,6 @@ fill_rdf_etable (GtkWidget *widget, } while (fgets (line, 4095, handle)) { - ETreePath path; char **tokens; struct _RDFInfo *info; int len; @@ -646,16 +644,17 @@ fill_rdf_etable (GtkWidget *widget, pd->rdf->known = g_list_append (pd->rdf->known, info); - path = e_summary_table_add_node (est, NULL, total++, NULL); - entry = g_new (ESummaryTableModelEntry, 1); - entry->path = path; + entry = g_new (ESummaryShownModelEntry, 1); entry->location = g_strdup (info->url); entry->name = g_strdup (info->name); - entry->editable = TRUE; - entry->removable = TRUE; - entry->shown = rdf_is_shown (pd, entry->location); - g_hash_table_insert (est->model, entry->path, entry); - + entry->showable = TRUE; + + e_summary_shown_add_node (ess, TRUE, entry, NULL, NULL); + + if (rdf_is_shown (pd, tokens[0]) == TRUE) { + e_summary_shown_add_node (ess, FALSE, entry, NULL, NULL); + } + g_strfreev (tokens); } @@ -663,10 +662,10 @@ fill_rdf_etable (GtkWidget *widget, } static void -fill_weather_etable (ESummaryTable *est, +fill_weather_etable (ESummaryShown *ess, PropertyData *pd) { - e_summary_weather_fill_etable (est, pd->summary); + e_summary_weather_fill_etable (ess, pd->summary); } static void @@ -796,7 +795,6 @@ mail_etable_item_changed_cb (ESummaryTable *est, static void rdf_etable_item_changed_cb (ESummaryTable *est, - ETreePath path, PropertyData *pd) { evolution_config_control_changed (pd->config_control); @@ -804,7 +802,6 @@ rdf_etable_item_changed_cb (ESummaryTable *est, static void weather_etable_item_changed_cb (ESummaryTable *est, - ETreePath path, PropertyData *pd) { evolution_config_control_changed (pd->config_control); @@ -955,10 +952,7 @@ make_property_dialog (PropertyData *pd) gtk_signal_connect (GTK_OBJECT (rdf->etable), "item-changed", GTK_SIGNAL_FUNC (rdf_etable_item_changed_cb), pd); - rdf->model = E_SUMMARY_TABLE (rdf->etable)->model; - fill_rdf_etable (rdf->etable, pd); - rdf->refresh = glade_xml_get_widget (pd->xml, "spinbutton1"); g_return_val_if_fail (rdf->refresh != NULL, FALSE); gtk_spin_button_set_value (GTK_SPIN_BUTTON (rdf->refresh), @@ -983,9 +977,8 @@ make_property_dialog (PropertyData *pd) gtk_signal_connect (GTK_OBJECT (weather->etable), "item-changed", GTK_SIGNAL_FUNC (weather_etable_item_changed_cb), pd); - weather->model = E_SUMMARY_TABLE (weather->etable)->model; - fill_weather_etable (E_SUMMARY_TABLE (weather->etable), pd); + fill_weather_etable (E_SUMMARY_SHOWN (weather->etable), pd); weather->refresh = glade_xml_get_widget (pd->xml, "spinbutton5"); g_return_val_if_fail (weather->refresh != NULL, FALSE); @@ -1110,6 +1103,7 @@ maybe_add_to_shown (gpointer key, GtkWidget *e_summary_preferences_make_mail_table (PropertyData *pd); GtkWidget *e_summary_preferences_make_rdf_table (PropertyData *pd); GtkWidget *e_summary_preferences_make_weather_table (PropertyData *pd); + GtkWidget * e_summary_preferences_make_mail_table (PropertyData *pd) { @@ -1119,19 +1113,33 @@ e_summary_preferences_make_mail_table (PropertyData *pd) GtkWidget * e_summary_preferences_make_rdf_table (PropertyData *pd) { - return e_summary_table_new (g_hash_table_new (NULL, NULL)); + return e_summary_shown_new (); } GtkWidget * e_summary_preferences_make_weather_table (PropertyData *pd) { - return e_summary_table_new (g_hash_table_new (NULL, NULL)); + return e_summary_shown_new (); } /* The factory for the ConfigControl. */ static void +add_shown_to_list (gpointer key, + gpointer value, + gpointer data) +{ + ESummaryShownModelEntry *item; + GList **list; + + item = (ESummaryShownModelEntry *) value; + list = (GList **) data; + + *list = g_list_prepend (*list, g_strdup (item->location)); +} + +static void config_control_apply_cb (EvolutionConfigControl *control, void *data) { @@ -1139,38 +1147,38 @@ config_control_apply_cb (EvolutionConfigControl *control, pd = (PropertyData *) data; - /* RDFs */ if (pd->rdf->tmp_list) { free_str_list (pd->rdf->tmp_list); g_list_free (pd->rdf->tmp_list); pd->rdf->tmp_list = NULL; } - /* Take each news feed which is on and add it to the shown list */ - g_hash_table_foreach (pd->rdf->model, maybe_add_to_shown, &pd->rdf->tmp_list); - + g_hash_table_foreach (E_SUMMARY_SHOWN (pd->rdf->etable)->shown_model, + add_shown_to_list, &pd->rdf->tmp_list); + if (pd->summary->preferences->rdf_urls) { free_str_list (pd->summary->preferences->rdf_urls); g_list_free (pd->summary->preferences->rdf_urls); } - + pd->summary->preferences->rdf_urls = copy_str_list (pd->rdf->tmp_list); - + /* Weather */ if (pd->weather->tmp_list) { free_str_list (pd->weather->tmp_list); g_list_free (pd->weather->tmp_list); pd->weather->tmp_list = NULL; } - g_hash_table_foreach (pd->weather->model, maybe_add_to_shown, &pd->weather->tmp_list); - + + g_hash_table_foreach (E_SUMMARY_SHOWN (pd->weather->etable)->shown_model, + add_shown_to_list, &pd->weather->tmp_list); if (pd->summary->preferences->stations) { free_str_list (pd->summary->preferences->stations); g_list_free (pd->summary->preferences->stations); } pd->summary->preferences->stations = copy_str_list (pd->weather->tmp_list); - + /* Folders */ if (pd->mail->tmp_list) { free_str_list (pd->mail->tmp_list); @@ -1178,13 +1186,13 @@ config_control_apply_cb (EvolutionConfigControl *control, pd->mail->tmp_list = NULL; } g_hash_table_foreach (pd->mail->model, maybe_add_to_shown, &pd->mail->tmp_list); - + if (pd->summary->preferences->display_folders) { free_str_list (pd->summary->preferences->display_folders); g_list_free (pd->summary->preferences->display_folders); } pd->summary->preferences->display_folders = copy_str_list (pd->mail->tmp_list); - + e_summary_reconfigure (pd->summary); } diff --git a/my-evolution/e-summary-shown.c b/my-evolution/e-summary-shown.c new file mode 100644 index 0000000000..42f6bf83f5 --- /dev/null +++ b/my-evolution/e-summary-shown.c @@ -0,0 +1,582 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Iain Holmes <iain@ximian.com> + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <string.h> + +#include <gtk/gtkhbox.h> +#include <gtk/gtkenums.h> +#include <gtk/gtksignal.h> + +#include <gal/util/e-util.h> +#include <gal/widgets/e-gui-utils.h> + +#include <gal/e-table/e-table-header.h> +#include <gal/e-table/e-table-header-item.h> +#include <gal/e-table/e-table-item.h> +#include <gal/e-table/e-cell-text.h> +#include <gal/e-table/e-cell-tree.h> +#include <gal/e-table/e-table.h> +#include <gal/e-table/e-tree.h> + +#include <gal/e-table/e-tree-scrolled.h> +#include <gal/e-table/e-tree-memory.h> +#include <gal/e-table/e-tree-memory-callbacks.h> +#include <gal/e-table/e-tree-table-adapter.h> + +#include <libgnome/gnome-i18n.h> +#include <libgnomeui/gnome-init.h> + +#include "e-summary-shown.h" + +#define COLS 1 + +/* Needs to be filled in before use */ +#define SPEC "<ETableSpecification cursor-mode=\"line\" draw-focus=\"true\"> \ +<ETableColumn model_col=\"0\" _title=\" \" resizable=\"true\" cell=\"tree-string\" compare=\"string\"/> \ +<ETableState> \ +<column source=\"0\"/> \ +<grouping></grouping> \ +</ETableState> \ +</ETableSpecification>" + +#define PARENT_TYPE (gtk_hbox_get_type ()) +static GtkObjectClass *e_summary_shown_parent_class; + +enum { + ITEM_CHANGED, + LAST_SIGNAL +}; +static guint32 shown_signals[LAST_SIGNAL] = { 0 }; + +typedef struct _TableData { + ETreeModel *etm; + ETreePath *root; + + GtkWidget *etable; + GSList *contents; +} TableData; + +struct _ESummaryShownPrivate { + TableData *all, *shown; + GtkWidget *add, *remove; +}; + +static GdkPixbuf * +icon_at (ETreeModel *etm, + ETreePath path, + void *model_data) +{ + return NULL; +} + +static int +column_count (ETreeModel *etm, + void *data) +{ + return COLS; +} + +static void * +duplicate_value (ETreeModel *etm, + int col, + const void *value, + void *data) +{ + return g_strdup (value); +} + +static void +free_value (ETreeModel *etm, + int col, + void *value, + void *data) +{ + g_free (value); +} + +static void * +initialise_value (ETreeModel *etm, + int col, + void *data) +{ + return g_strdup (""); +} + +static gboolean +value_is_empty (ETreeModel *etm, + int col, + const void *value, + void *data) +{ + return !(value && *(char *)value); +} + +static char * +value_to_string (ETreeModel *etm, + int col, + const void *value, + void *data) +{ + return g_strdup (value); +} + +static void * +value_at (ETreeModel *etm, + ETreePath path, + int col, + void *model_data) +{ + GHashTable *model = model_data; + ESummaryShownModelEntry *entry; + + if (e_tree_model_node_is_root (etm, path)) { + return "<Root>"; + } + + entry = g_hash_table_lookup (model, path); + if (entry == NULL) { + return "<None>"; + } else { + return entry->name; + } +} + +static gboolean +is_editable (ETreeModel *etm, + ETreePath path, + int col, + void *model_data) +{ + return FALSE; +} + +static void +destroy (GtkObject *object) +{ + ESummaryShown *shown; + ESummaryShownPrivate *priv; + + shown = E_SUMMARY_SHOWN (object); + priv = shown->priv; + + if (priv == NULL) { + return; + } + + g_free (priv); + shown->priv = NULL; + + e_summary_shown_parent_class->destroy (object); +} + +static void +e_summary_shown_class_init (GtkObjectClass *object_class) +{ + object_class->destroy = destroy; + + e_summary_shown_parent_class = gtk_type_class (PARENT_TYPE); + + shown_signals[ITEM_CHANGED] = gtk_signal_new ("item-changed", + GTK_RUN_LAST, + object_class->type, + GTK_SIGNAL_OFFSET (ESummaryShownClass, item_changed), + gtk_marshal_NONE__NONE, + GTK_TYPE_NONE, 0); + gtk_object_class_add_signals (object_class, shown_signals, LAST_SIGNAL); +} + +static gboolean +is_location_in_shown (ESummaryShown *shown, + const char *location) +{ + GSList *p; + + for (p = shown->priv->shown->contents; p; p = p->next) { + ESummaryShownModelEntry *entry = p->data; + if (entry->location == NULL) { + continue; + } + + if (strcmp (entry->location, location) == 0) { + return TRUE; + } + } + + return FALSE; +} + +static ESummaryShownModelEntry * +find_entry_from_location (ESummaryShown *shown, + const char *location) +{ + GSList *p; + + for (p = shown->priv->shown->contents; p; p = p->next) { + ESummaryShownModelEntry *entry = p->data; + + if (entry->location == NULL) { + continue; + } + + if (strcmp ((char *) entry->location, location) == 0) { + return entry; + } + } + + return NULL; +} + +struct _CountData { + ESummaryShown *shown; + int count; +}; + +static void +real_selected_count (ETreePath path, + gpointer data) +{ + ESummaryShownModelEntry *entry; + struct _CountData *cd = data; + + entry = g_hash_table_lookup (cd->shown->all_model, path); + g_return_if_fail (entry != NULL); + + if (entry->showable == FALSE) { + return; + } + + if (is_location_in_shown (cd->shown, entry->location)) { + return; + } + + cd->count++; +} + +static void +all_selection_changed (ETree *et, + ESummaryShown *shown) +{ + ESelectionModel *esm; + int count; + + esm = e_tree_get_selection_model (et); + + count = e_selection_model_selected_count (esm); + if (count == 0) { + gtk_widget_set_sensitive (shown->priv->add, FALSE); + } else { + struct _CountData *cd; + + cd = g_new (struct _CountData, 1); + cd->shown = shown; + cd->count = 0; + + e_tree_selection_model_foreach (E_TREE_SELECTION_MODEL (esm), + real_selected_count, cd); + if (cd->count != 0) { + gtk_widget_set_sensitive (shown->priv->add, TRUE); + } else { + gtk_widget_set_sensitive (shown->priv->add, FALSE); + } + } +} + +static void +shown_selection_changed (ETree *et, + ESummaryShown *shown) +{ + ESelectionModel *esm; + int count; + + esm = e_tree_get_selection_model (et); + + count = e_selection_model_selected_count (esm); + if (count == 0) { + gtk_widget_set_sensitive (shown->priv->remove, FALSE); + } else { + gtk_widget_set_sensitive (shown->priv->remove, TRUE); + } +} + +static void +maybe_move_to_shown (ETreePath path, + gpointer closure) +{ + ESummaryShown *shown = closure; + ESummaryShownModelEntry *entry, *new_entry; + + entry = g_hash_table_lookup (shown->all_model, path); + g_return_if_fail (entry != NULL); + + /* Check is the entry can be shown */ + if (entry->showable == FALSE) { + return; + } + + /* check if the entry is already in the shown list */ + if (is_location_in_shown (shown, entry->location) == TRUE) { + return; + } + + new_entry = g_new (ESummaryShownModelEntry, 1); + new_entry->name = g_strdup (entry->name); + new_entry->location = g_strdup (entry->location); + new_entry->showable = entry->showable; + new_entry->ref_count = 0; + + e_summary_shown_add_node (shown, FALSE, new_entry, NULL, NULL); + gtk_signal_emit (GTK_OBJECT (shown), shown_signals[ITEM_CHANGED]); + g_print ("Added %s\n", entry->name); +} + +static void +add_clicked (GtkWidget *button, + ESummaryShown *shown) +{ + ESelectionModel *esm; + ETree *et; + + et = e_tree_scrolled_get_tree (E_TREE_SCROLLED (shown->priv->all->etable)); + esm = e_tree_get_selection_model (et); + + e_tree_selection_model_foreach (E_TREE_SELECTION_MODEL (esm), + maybe_move_to_shown, shown); +} + +static void +remove_from_shown (ETreePath path, + gpointer closure) +{ + ESummaryShown *shown = closure; + ESummaryShownModelEntry *entry; + + entry = g_hash_table_lookup (shown->shown_model, path); + g_return_if_fail (entry != NULL); + + e_summary_shown_remove_node (shown, FALSE, entry); + gtk_signal_emit (GTK_OBJECT (shown), shown_signals[ITEM_CHANGED]); +} + +static void +remove_clicked (GtkWidget *button, + ESummaryShown *shown) +{ + ESelectionModel *esm; + ETree *et; + + et = e_tree_scrolled_get_tree (E_TREE_SCROLLED (shown->priv->shown->etable)); + esm = e_tree_get_selection_model (et); + + e_tree_selection_model_foreach (E_TREE_SELECTION_MODEL (esm), + remove_from_shown, shown); +} + +static TableData * +make_table (GHashTable *data_model, + GtkSignalFunc callback, + gpointer closure) +{ + TableData *td; + ETreeMemory *etmm; + ETree *tree; + + td = g_new (TableData, 1); + td->etm = e_tree_memory_callbacks_new (icon_at, + column_count, + + NULL, + NULL, + + NULL, + NULL, + + value_at, + NULL, + is_editable, + + duplicate_value, + free_value, + initialise_value, + value_is_empty, + value_to_string, + + data_model); + gtk_object_ref (GTK_OBJECT (td->etm)); + gtk_object_sink (GTK_OBJECT (td->etm)); + + etmm = E_TREE_MEMORY (td->etm); + e_tree_memory_set_expanded_default (etmm, TRUE); + + td->root = e_tree_memory_node_insert (etmm, NULL, 0, NULL); + + td->etable = e_tree_scrolled_new (td->etm, NULL, SPEC, NULL); + + tree = e_tree_scrolled_get_tree (E_TREE_SCROLLED (td->etable)); + e_tree_root_node_set_visible (tree, FALSE); + gtk_signal_connect (GTK_OBJECT (tree), "selection-change", + callback, closure); + + td->contents = NULL; + return td; +} + +static void +e_summary_shown_init (ESummaryShown *shown) +{ + ESummaryShownPrivate *priv; + GtkWidget *vbox; + + shown->shown_model = g_hash_table_new (NULL, NULL); + shown->all_model = g_hash_table_new (NULL, NULL); + + priv = g_new (ESummaryShownPrivate, 1); + shown->priv = priv; + + priv->all = make_table (shown->all_model, GTK_SIGNAL_FUNC (all_selection_changed), shown); + + gtk_box_pack_start (GTK_BOX (shown), priv->all->etable, TRUE, TRUE, 0); + gtk_widget_show (priv->all->etable); + + vbox = gtk_vbox_new (TRUE, 0); + gtk_box_pack_start (GTK_BOX (shown), vbox, FALSE, FALSE, 0); + + priv->add = gtk_button_new_with_label (_("Add->")); + gtk_widget_set_sensitive (priv->add, FALSE); + gtk_box_pack_start (GTK_BOX (vbox), priv->add, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (priv->add), "clicked", + GTK_SIGNAL_FUNC (add_clicked), shown); + + priv->remove = gtk_button_new_with_label (_("<-Remove")); + gtk_widget_set_sensitive (priv->remove, FALSE); + gtk_box_pack_start (GTK_BOX (vbox), priv->remove, TRUE, FALSE, 0); + gtk_signal_connect (GTK_OBJECT (priv->remove), "clicked", + GTK_SIGNAL_FUNC (remove_clicked), shown); + + gtk_widget_show_all (vbox); + + priv->shown = make_table (shown->shown_model, GTK_SIGNAL_FUNC (shown_selection_changed), shown); + + gtk_box_pack_start (GTK_BOX (shown), priv->shown->etable, TRUE, TRUE, 0); + gtk_widget_show (priv->shown->etable); +} + +E_MAKE_TYPE (e_summary_shown, "ESummaryShown", ESummaryShown, + e_summary_shown_class_init, e_summary_shown_init, PARENT_TYPE); + +GtkWidget * +e_summary_shown_new (void) +{ + ESummaryShown *shown; + + shown = gtk_type_new (e_summary_shown_get_type ()); + return GTK_WIDGET (shown); +} + +static ETreePath +e_tree_model_node_append (ETreeModel *etm, + ETreePath parent, + gpointer data) +{ + ETreeMemory *etmm; + int position; + + position = e_tree_model_node_get_children (etm, parent, NULL); + + etmm = E_TREE_MEMORY (etm); + return e_tree_memory_node_insert (etmm, parent, position, data); +} + +ETreePath +e_summary_shown_add_node (ESummaryShown *shown, + gboolean all, + ESummaryShownModelEntry *entry, + ETreePath parent, + gpointer data) +{ + TableData *td; + ETreePath path; + ETreeMemory *etmm; + GHashTable *model; + + g_return_val_if_fail (IS_E_SUMMARY_SHOWN (shown), NULL); + + if (all == TRUE) { + td = shown->priv->all; + model = shown->all_model; + } else { + td = shown->priv->shown; + model = shown->shown_model; + } + + if (parent == NULL) { + parent = td->root; + } + + etmm = E_TREE_MEMORY (td->etm); + path = e_tree_model_node_append (td->etm, parent, data); + + entry->path = path; + + g_hash_table_insert (model, path, entry); + + if (all == FALSE) { + /* Add the location to the list */ + td->contents = g_slist_prepend (td->contents, entry); + } + + return path; +} + +void +e_summary_shown_remove_node (ESummaryShown *shown, + gboolean all, + ESummaryShownModelEntry *entry) +{ + TableData *td; + GHashTable *model; + ETreeMemory *etmm; + + g_return_if_fail (IS_E_SUMMARY_SHOWN (shown)); + + if (all == TRUE) { + td = shown->priv->all; + model = shown->all_model; + } else { + td = shown->priv->shown; + model = shown->shown_model; + } + + etmm = E_TREE_MEMORY (td->etm); + e_tree_memory_node_remove (etmm, entry->path); + + g_hash_table_remove (model, entry->path); + + if (all == FALSE) { + td->contents = g_slist_remove (td->contents, entry); + } + +} diff --git a/my-evolution/e-summary-shown.h b/my-evolution/e-summary-shown.h new file mode 100644 index 0000000000..d834874f0c --- /dev/null +++ b/my-evolution/e-summary-shown.h @@ -0,0 +1,73 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Iain Holmes <iain@ximian.com> + * + * Copyright 2002 Ximain, Inc. (www.ximian.com) + * + * 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#ifndef __E_SUMMARY_SHOWN_H__ +#define __E_SUMMARY_SHOWN_H__ + +#include <gtk/gtkhbox.h> +#include <glib.h> +#include <gal/e-table/e-tree-memory.h> + +#define E_SUMMARY_SHOWN_TYPE (e_summary_shown_get_type ()) +#define E_SUMMARY_SHOWN(obj) (GTK_CHECK_CAST ((obj), E_SUMMARY_SHOWN_TYPE, ESummaryShown)) +#define E_SUMMARY_SHOWN_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), E_SUMMARY_SHOWN_TYPE, ESummaryShownClass)) +#define IS_E_SUMMARY_SHOWN(obj) (GTK_CHECK_TYPE ((obj), E_SUMMARY_SHOWN_TYPE)) +#define IS_E_SUMMARY_SHOWN_CLASS(klass) (GTK_CHECK_TYPE ((klass), E_SUMMARY_SHOWN_TYPE)) + +typedef struct _ESummaryShownPrivate ESummaryShownPrivate; +typedef struct _ESummaryShownClass ESummaryShownClass; +typedef struct _ESummaryShown ESummaryShown; + +typedef struct _ESummaryShownModelEntry { + ETreePath path; + char *name; + char *location; + + gboolean showable; + int ref_count; +} ESummaryShownModelEntry; + +struct _ESummaryShown { + GtkHBox parent; + + GHashTable *all_model; + GHashTable *shown_model; + ESummaryShownPrivate *priv; +}; + +struct _ESummaryShownClass { + GtkHBoxClass parent_class; + + void (* item_changed) (ESummaryShown *shown); +}; + +GtkType e_summary_shown_get_type (void); +GtkWidget *e_summary_shown_new (void); +ETreePath e_summary_shown_add_node (ESummaryShown *shown, + gboolean all, + ESummaryShownModelEntry *entry, + ETreePath parent, + gpointer data); +void e_summary_shown_remove_node (ESummaryShown *shown, + gboolean all, + ESummaryShownModelEntry *entry); +#endif diff --git a/my-evolution/e-summary-table.c b/my-evolution/e-summary-table.c index 888b777bbd..da2bf64f5b 100644 --- a/my-evolution/e-summary-table.c +++ b/my-evolution/e-summary-table.c @@ -49,6 +49,7 @@ #include <libgnomeui/gnome-init.h> #include "e-summary-table.h" +#include "e-cell-tri.h" #define COLS 2 @@ -60,7 +61,7 @@ char *headers[COLS] = { #endif #define SPEC "<ETableSpecification cursor-mode=\"line\" draw-focus=\"true\"> \ -<ETableColumn model_col=\"0\" _title=\"Shown\" resizable=\"true\" cell=\"checkbox\" compare=\"integer\"/> \ +<ETableColumn model_col=\"0\" _title=\"Shown\" resizable=\"true\" cell=\"tricell\" compare=\"integer\"/> \ <ETableColumn model_col=\"1\" _title=\"Name\" minimum_width=\"20\" resizable=\"true\" cell=\"render-name\" compare=\"string\"/> \ <ETableState> \ <column source=\"0\"/> \ @@ -214,7 +215,11 @@ value_at (ETreeModel *etm, return entry->name; } else { - return GINT_TO_POINTER (entry->shown); + if (entry->editable == TRUE) { + return GINT_TO_POINTER (entry->shown ? 2 : 1); + } else { + return GINT_TO_POINTER (0); + } } } } @@ -243,7 +248,7 @@ set_value_at (ETreeModel *etm, g_return_if_fail (entry != NULL); if (entry->editable == TRUE) { - entry->shown = GPOINTER_TO_INT (val); + entry->shown = GPOINTER_TO_INT (val) == 1 ? FALSE : TRUE; gtk_signal_emit (GTK_OBJECT (est), table_signals[ITEM_CHANGED], path); } } @@ -370,7 +375,8 @@ e_summary_table_init (ESummaryTable *est) cell = e_cell_text_new (NULL, GTK_JUSTIFY_LEFT); priv->extras = e_table_extras_new (); e_table_extras_add_cell (priv->extras, "render-name", e_cell_tree_new (NULL, NULL, FALSE, cell)); - + e_table_extras_add_cell (priv->extras, "tricell", e_cell_tri_new ()); + priv->etable = e_tree_scrolled_new (priv->etm, priv->extras, SPEC, NULL); if (priv->etable == NULL) { g_warning ("Could not create ETable for ESummaryTable"); @@ -420,4 +426,14 @@ e_summary_table_add_node (ESummaryTable *table, return p; } - +guint +e_summary_table_get_num_children (ESummaryTable *table, + ETreePath path) +{ + if (path == NULL) { + return e_tree_model_node_get_children (table->priv->etm, + table->priv->root_node, NULL); + } else { + return e_tree_model_node_get_children (table->priv->etm, path, NULL); + } +} diff --git a/my-evolution/e-summary-table.h b/my-evolution/e-summary-table.h index cbddb9bec9..859f8f7ec9 100644 --- a/my-evolution/e-summary-table.h +++ b/my-evolution/e-summary-table.h @@ -69,5 +69,6 @@ ETreePath e_summary_table_add_node (ESummaryTable *est, ETreePath path, int position, gpointer node_data); - +guint e_summary_table_get_num_children (ESummaryTable *est, + ETreePath path); #endif diff --git a/my-evolution/e-summary-weather.c b/my-evolution/e-summary-weather.c index db539641d8..c121ba4927 100644 --- a/my-evolution/e-summary-weather.c +++ b/my-evolution/e-summary-weather.c @@ -35,7 +35,7 @@ #include <gal/widgets/e-unicode.h> #include "e-summary.h" -#include "e-summary-table.h" +#include "e-summary-shown.h" #include "e-summary-weather.h" #include "weather.h" #include "metar.h" @@ -663,16 +663,15 @@ is_weather_shown (ESummaryWeather *weather, } void -e_summary_weather_fill_etable (ESummaryTable *est, +e_summary_weather_fill_etable (ESummaryShown *ess, ESummary *summary) { ESummaryWeather *weather; ETreePath region, state, location; - ESummaryTableModelEntry *entry; + ESummaryShownModelEntry *entry; char *key, *path; int nregions, iregions; char **regions; - int i, n, l; g_return_if_fail (IS_E_SUMMARY (summary)); @@ -688,7 +687,7 @@ e_summary_weather_fill_etable (ESummaryTable *est, gnome_config_get_vector ("Main/regions", &nregions, ®ions); region = NULL; - for (i = 0, iregions = nregions - 1; iregions >= 0; iregions--, i++) { + for (iregions = nregions - 1; iregions >= 0; iregions--) { int nstates, istates; char **states; char *region_name; @@ -699,21 +698,17 @@ e_summary_weather_fill_etable (ESummaryTable *est, states_key = g_strconcat (regions[iregions], "/states", NULL); region_name = gnome_config_get_string (region_name_key); - region = e_summary_table_add_node (est, NULL, i, NULL); - - entry = g_new (ESummaryTableModelEntry, 1); - entry->path = region; + entry = g_new (ESummaryShownModelEntry, 1); entry->location = NULL; entry->name = g_strdup (region_name); - entry->editable = FALSE; - entry->removable = FALSE; - entry->shown = FALSE; - g_hash_table_insert (est->model, entry->path, entry); + entry->showable = FALSE; + region = e_summary_shown_add_node (ess, TRUE, entry, NULL, NULL); + gnome_config_get_vector (states_key, &nstates, &states); state = NULL; - for (n = 0, istates = nstates - 1; istates >= 0; istates--, n++) { + for (istates = nstates - 1; istates >= 0; istates--) { void *iter; char *iter_key, *iter_val; char *state_path, *state_name_key, *state_name; @@ -722,21 +717,16 @@ e_summary_weather_fill_etable (ESummaryTable *est, state_name_key = g_strconcat (state_path, "name", NULL); state_name = gnome_config_get_string (state_name_key); - state = e_summary_table_add_node (est, region, n, NULL); - - entry = g_new (ESummaryTableModelEntry, 1); - entry->path = state; + entry = g_new (ESummaryShownModelEntry, 1); entry->location = NULL; entry->name = g_strdup (state_name); - entry->editable = FALSE; - entry->removable = FALSE; - entry->shown = FALSE; - g_hash_table_insert (est->model, entry->path, entry); + entry->showable = FALSE; + + state = e_summary_shown_add_node (ess, TRUE, entry, region, NULL); location = NULL; iter = gnome_config_init_iterator (state_path); - l = 0; while ((iter = gnome_config_iterator_next (iter, &iter_key, &iter_val)) != NULL) { if (strstr (iter_key, "loc") != NULL) { char **locdata; @@ -746,24 +736,19 @@ e_summary_weather_fill_etable (ESummaryTable *est, &nlocdata, &locdata); g_return_if_fail (nlocdata == 4); - - location = e_summary_table_add_node (est, state, l, NULL); - entry = g_new (ESummaryTableModelEntry, 1); - entry->path = location; + + entry = g_new (ESummaryShownModelEntry, 1); entry->location = g_strdup (locdata[1]); entry->name = g_strdup (locdata[0]); - entry->editable = TRUE; - entry->removable = FALSE; - - entry->shown = is_weather_shown (weather, locdata[1]); - g_hash_table_insert (est->model, entry->path, entry); + entry->showable = TRUE; + + location = e_summary_shown_add_node (ess, TRUE, entry, state, NULL); g_strfreev (locdata); } g_free (iter_key); g_free (iter_val); - l++; } g_free (state_name); diff --git a/my-evolution/e-summary-weather.h b/my-evolution/e-summary-weather.h index 795afcfede..3dac76f7ee 100644 --- a/my-evolution/e-summary-weather.h +++ b/my-evolution/e-summary-weather.h @@ -26,6 +26,7 @@ #include <time.h> #include "e-summary-type.h" +#include "e-summary-shown.h" typedef struct _ESummaryWeather ESummaryWeather; @@ -144,7 +145,7 @@ typedef time_t ESummaryWeatherUpdate; char *e_summary_weather_get_html (ESummary *summary); void e_summary_weather_init (ESummary *summary); void e_summary_weather_reconfigure (ESummary *summary); -void e_summary_weather_fill_etable (ESummaryTable *est, +void e_summary_weather_fill_etable (ESummaryShown *ess, ESummary *summary); const char *e_summary_weather_code_to_name (const char *code); void e_summary_weather_free (ESummary *summary); diff --git a/my-evolution/e-summary.c b/my-evolution/e-summary.c index 6db05c9700..2b85958f74 100644 --- a/my-evolution/e-summary.c +++ b/my-evolution/e-summary.c @@ -82,7 +82,6 @@ struct _ESummaryMailFolderInfo { }; struct _ESummaryPrivate { - GNOME_Evolution_Shell shell; GNOME_Evolution_ShellView shell_view_interface; GtkWidget *html_scroller; @@ -535,7 +534,7 @@ e_summary_new (const GNOME_Evolution_Shell shell) ESummary *summary; summary = gtk_type_new (e_summary_get_type ()); - summary->priv->shell = shell; + summary->shell = shell; e_summary_add_protocol_listener (summary, "evolution", e_summary_evolution_protocol_listener, summary); diff --git a/my-evolution/e-summary.h b/my-evolution/e-summary.h index cb5a6ece91..703d38a747 100644 --- a/my-evolution/e-summary.h +++ b/my-evolution/e-summary.h @@ -112,6 +112,7 @@ struct _ESummary { ESummaryPrivate *priv; + GNOME_Evolution_Shell shell; GNOME_Evolution_ShellView shell_view_interface; gboolean online; |