aboutsummaryrefslogtreecommitdiffstats
path: root/mail
diff options
context:
space:
mode:
Diffstat (limited to 'mail')
-rw-r--r--mail/ChangeLog11
-rw-r--r--mail/Makefile.am4
-rw-r--r--mail/mail-types.h1
-rw-r--r--mail/subscribe-control-factory.c189
-rw-r--r--mail/subscribe-control-factory.h21
-rw-r--r--mail/subscribe-control.c387
-rw-r--r--mail/subscribe-control.h60
7 files changed, 673 insertions, 0 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index b6870cefd4..0244838e78 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,3 +1,14 @@
+2000-09-27 Chris Toshok <toshok@helixcode.com>
+
+ * mail-types.h: add SubscribeControl typedef.
+
+ * Makefile.am (evolution_mail_SOURCES): add the subscribe stuff.
+
+ * subscribe-control-factory.h
+ * subscribe-control-factory.c
+ * subscribe-control.c:
+ * subscribe-control.h: Mostly mocked up subscribe ui.
+
2000-09-27 Jeffrey Stedfast <fejj@helixcode.com>
Note: We need a configuration option to specify whether to log
filtering actions or not.
diff --git a/mail/Makefile.am b/mail/Makefile.am
index 83ae9cf4be..d2d44b3fdd 100644
--- a/mail/Makefile.am
+++ b/mail/Makefile.am
@@ -78,6 +78,10 @@ evolution_mail_SOURCES = \
message-thread.c \
message-thread.h \
session.c \
+ subscribe-control.c \
+ subscribe-control.h \
+ subscribe-control-factory.c \
+ subscribe-control-factory.h \
mail.h
evolution_mail_LDADD = \
diff --git a/mail/mail-types.h b/mail/mail-types.h
index c5b690563d..9f72b23800 100644
--- a/mail/mail-types.h
+++ b/mail/mail-types.h
@@ -29,6 +29,7 @@ extern "C" {
typedef struct _FolderBrowser FolderBrowser;
+typedef struct _SubscribeControl SubscribeControl;
typedef struct _MessageList MessageList;
typedef struct _MailDisplay MailDisplay;
diff --git a/mail/subscribe-control-factory.c b/mail/subscribe-control-factory.c
new file mode 100644
index 0000000000..c49b6471a8
--- /dev/null
+++ b/mail/subscribe-control-factory.c
@@ -0,0 +1,189 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * subscribe-control-factory.c: A Bonobo Control factory for Subscribe Controls
+ *
+ * Author:
+ * Chris Toshok (toshok@helixcode.com)
+ *
+ * (C) 2000 Helix Code, Inc.
+ */
+
+#include <config.h>
+
+#include <gnome.h>
+#include <bonobo/bonobo-main.h>
+#include <bonobo/bonobo-object.h>
+#include <bonobo/bonobo-generic-factory.h>
+#include <bonobo/bonobo-control.h>
+#include <bonobo/bonobo-ui-component.h>
+
+#include <gal/util/e-util.h>
+#include <gal/widgets/e-gui-utils.h>
+
+#include "subscribe-control-factory.h"
+
+#include "subscribe-control.h"
+#include "mail.h"
+#include "shell/Evolution.h"
+#include "mail-config.h"
+#include "mail-ops.h"
+
+/* The Subscribe BonoboControls we have. */
+static GList *control_list = NULL;
+
+/*
+ * Add with 'subscribe_control'
+ */
+static BonoboUIVerb verbs [] = {
+ /* Edit Menu */
+ BONOBO_UI_VERB ("EditSelectAll", subscribe_select_all),
+ BONOBO_UI_VERB ("EditUnSelectAll", subscribe_unselect_all),
+
+ /* Folder Menu */
+ BONOBO_UI_VERB ("SubscribeFolder", subscribe_folder),
+ BONOBO_UI_VERB ("UnsubscribeFolder", unsubscribe_folder),
+
+ BONOBO_UI_VERB_END
+};
+
+static void
+set_pixmap (Bonobo_UIContainer container,
+ const char *xml_path,
+ const char *icon)
+{
+ char *path;
+ GdkPixbuf *pixbuf;
+
+ path = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution/buttons", icon);
+
+ pixbuf = gdk_pixbuf_new_from_file (path);
+ g_return_if_fail (pixbuf != NULL);
+
+ bonobo_ui_util_set_pixbuf (container, xml_path, pixbuf);
+
+ gdk_pixbuf_unref (pixbuf);
+
+ g_free (path);
+}
+
+static void
+update_pixmaps (Bonobo_UIContainer container)
+{
+ set_pixmap (container, "/Toolbar/SubscribeFolder", "fetch-mail.png");
+ set_pixmap (container, "/Toolbar/UnsubscribeFolder", "compose-message.png");
+}
+
+static void
+control_activate (BonoboControl *control, BonoboUIHandler *uih,
+ SubscribeControl *fb)
+{
+ GtkWidget *subscribe_control;
+ BonoboUIComponent *component;
+ Bonobo_UIContainer container;
+
+ container = bonobo_control_get_remote_ui_handler (control);
+ bonobo_ui_handler_set_container (uih, container);
+ bonobo_object_release_unref (container, NULL);
+
+ g_assert (container == bonobo_ui_compat_get_container (uih));
+ g_return_if_fail (container != CORBA_OBJECT_NIL);
+
+ subscribe_control = bonobo_control_get_widget (control);
+
+ component = bonobo_ui_compat_get_component (uih);
+ bonobo_ui_component_add_verb_list_with_data (
+ component, verbs, subscribe_control);
+
+ bonobo_ui_container_freeze (container, NULL);
+
+ bonobo_ui_util_set_ui (
+ component, container,
+ EVOLUTION_DATADIR, "evolution-subscribe.xml",
+ "evolution-mail");
+
+ update_pixmaps (container);
+
+ bonobo_ui_container_thaw (container, NULL);
+}
+
+static void
+control_deactivate (BonoboControl *control,
+ BonoboUIHandler *uih,
+ SubscribeControl *subscribe)
+{
+ g_warning ("In subscribe control_deactivate");
+ bonobo_ui_component_rm (
+ bonobo_ui_compat_get_component (uih),
+ bonobo_ui_compat_get_container (uih), "/", NULL);
+
+ bonobo_ui_handler_unset_container (uih);
+}
+
+static void
+control_activate_cb (BonoboControl *control,
+ gboolean activate,
+ gpointer user_data)
+{
+ BonoboUIHandler *uih;
+
+ uih = bonobo_control_get_ui_handler (control);
+ g_assert (uih);
+
+ if (activate)
+ control_activate (control, uih, user_data);
+ else
+ control_deactivate (control, uih, user_data);
+}
+
+static void
+control_destroy_cb (BonoboControl *control,
+ gpointer user_data)
+{
+ GtkWidget *subscribe_control = user_data;
+
+ control_list = g_list_remove (control_list, control);
+
+ gtk_object_destroy (GTK_OBJECT (subscribe_control));
+}
+
+BonoboControl *
+subscribe_control_factory_new_control (const char *uri,
+ const Evolution_Shell shell)
+{
+ BonoboControl *control;
+ GtkWidget *subscribe_control;
+
+ subscribe_control = subscribe_control_new (shell);
+ if (subscribe_control == NULL)
+ return NULL;
+
+ if (!subscribe_control_set_uri (SUBSCRIBE_CONTROL (subscribe_control), uri)) {
+ gtk_object_sink (GTK_OBJECT (subscribe_control));
+ return NULL;
+ }
+
+ gtk_widget_show (subscribe_control);
+
+ control = bonobo_control_new (subscribe_control);
+
+ if (control == NULL) {
+ gtk_object_destroy (GTK_OBJECT (subscribe_control));
+ return NULL;
+ }
+
+ gtk_signal_connect (GTK_OBJECT (control), "activate",
+ control_activate_cb, subscribe_control);
+
+ gtk_signal_connect (GTK_OBJECT (control), "destroy",
+ control_destroy_cb, subscribe_control);
+
+ control_list = g_list_prepend (control_list, control);
+
+ return control;
+}
+
+GList *
+subscribe_control_factory_get_control_list (void)
+{
+ return control_list;
+}
diff --git a/mail/subscribe-control-factory.h b/mail/subscribe-control-factory.h
new file mode 100644
index 0000000000..7c1eaa0b18
--- /dev/null
+++ b/mail/subscribe-control-factory.h
@@ -0,0 +1,21 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * subscribe-control-factory.h: A Bonobo Control factory for Subscribe Controls
+ *
+ * Author:
+ * Chris Toshok (toshok@helixcode.com)
+ *
+ * (C) 2000 Helix Code, Inc.
+ */
+
+#ifndef _SUBSCRIBE_CONTROL_FACTORY_H
+#define _SUBSCRIBE_CONTROL_FACTORY_H
+
+#include <bonobo.h>
+#include "Evolution.h"
+
+BonoboControl *subscribe_control_factory_new_control (const char *uri,
+ const Evolution_Shell shell);
+GList *subscribe_control_factory_get_control_list (void);
+
+#endif /* _SUBSCRIBE_CONTROL_FACTORY_H */
diff --git a/mail/subscribe-control.c b/mail/subscribe-control.c
new file mode 100644
index 0000000000..6bc674261b
--- /dev/null
+++ b/mail/subscribe-control.c
@@ -0,0 +1,387 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * subscribe-control.c: Subscribe control top level component
+ *
+ * Author:
+ * Chris Toshok (toshok@helixcode.com)
+ *
+ * (C) 2000 Helix Code, Inc.
+ */
+#include <config.h>
+#include <gnome.h>
+#include "subscribe-control.h"
+#include "e-util/e-html-utils.h"
+#include <gtkhtml/gtkhtml.h>
+#include <gal/util/e-util.h>
+#include <gal/e-table/e-cell-text.h>
+#include <gal/e-table/e-cell-tree.h>
+#include <gal/e-table/e-cell-toggle.h>
+#include <gal/e-table/e-table-scrolled.h>
+#include <gal/e-table/e-tree-simple.h>
+
+#include "art/mark.xpm"
+
+#define PARENT_TYPE (gtk_table_get_type ())
+
+#define ETABLE_SPEC "<ETableSpecification> \
+ <columns-shown> \
+ <column> 1 </column> \
+ <column> 0 </column> \
+ <column> 2 </column> \
+ </columns-shown> \
+ <grouping></grouping> \
+</ETableSpecification>"
+
+enum {
+ COL_FOLDER_NAME,
+ COL_FOLDER_SUBSCRIBED,
+ COL_FOLDER_DESCRIPTION,
+ COL_LAST
+};
+
+/*
+ * Virtual Column list:
+ * 0 Folder Name
+ * 1 Subscribed
+ * 2 Description
+ */
+char *headers [COL_LAST] = {
+ "Folder",
+ "Subscribed",
+ "Description",
+};
+
+static GtkObjectClass *subscribe_control_parent_class;
+
+void
+subscribe_select_all (BonoboUIHandler *uih,
+ void *user_data, const char *path)
+{
+}
+
+void
+subscribe_unselect_all (BonoboUIHandler *uih,
+ void *user_data, const char *path)
+{
+}
+
+void
+subscribe_folder (GtkWidget *widget, gpointer user_data)
+{
+}
+
+void
+unsubscribe_folder (GtkWidget *widget, gpointer user_data)
+{
+}
+
+gboolean
+subscribe_control_set_uri (SubscribeControl *subscribe_control,
+ const char *uri)
+{
+ printf ("set_uri (%s) called\n", uri);
+ return TRUE;
+}
+
+
+/* HTML Helpers */
+static void
+html_size_req (GtkWidget *widget, GtkRequisition *requisition)
+{
+ if (GTK_LAYOUT (widget)->height > 90)
+ requisition->height = 90;
+ else
+ requisition->height = GTK_LAYOUT (widget)->height;
+}
+
+/* Returns a GtkHTML which is already inside a GtkScrolledWindow. If
+ * @white is TRUE, the GtkScrolledWindow will be inside a GtkFrame.
+ */
+static GtkWidget *
+html_new (gboolean white)
+{
+ GtkWidget *html, *scrolled, *frame;
+ GtkStyle *style;
+
+ html = gtk_html_new ();
+ GTK_LAYOUT (html)->height = 0;
+ gtk_signal_connect (GTK_OBJECT (html), "size_request",
+ GTK_SIGNAL_FUNC (html_size_req), NULL);
+ gtk_html_set_editable (GTK_HTML (html), FALSE);
+ style = gtk_rc_get_style (html);
+ if (style) {
+ gtk_html_set_default_background_color (GTK_HTML (html),
+ white ? &style->white :
+ &style->bg[0]);
+ }
+ gtk_widget_set_sensitive (html, FALSE);
+ scrolled = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_NEVER);
+ gtk_container_add (GTK_CONTAINER (scrolled), html);
+
+ if (white) {
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame),
+ GTK_SHADOW_ETCHED_IN);
+ gtk_container_add (GTK_CONTAINER (frame), scrolled);
+ gtk_widget_show_all (frame);
+ } else
+ gtk_widget_show_all (scrolled);
+
+ return html;
+}
+
+static void
+put_html (GtkHTML *html, char *text)
+{
+ GtkHTMLStream *handle;
+
+ text = e_text_to_html (text, (E_TEXT_TO_HTML_CONVERT_NL |
+ E_TEXT_TO_HTML_CONVERT_SPACES |
+ E_TEXT_TO_HTML_CONVERT_URLS));
+ handle = gtk_html_begin (html);
+ gtk_html_write (html, handle, "<HTML><BODY>", 12);
+ gtk_html_write (html, handle, text, strlen (text));
+ gtk_html_write (html, handle, "</BODY></HTML>", 14);
+ g_free (text);
+ gtk_html_end (html, handle, GTK_HTML_STREAM_OK);
+}
+
+
+
+/* etable stuff for the subscribe ui */
+
+static int
+etable_col_count (ETableModel *etm, void *data)
+{
+ return COL_LAST;
+}
+
+static void*
+etable_duplicate_value (ETableModel *etm, int col, const void *val, void *data)
+{
+ return g_strdup (val);
+}
+
+static void
+etable_free_value (ETableModel *etm, int col, void *val, void *data)
+{
+ g_free (val);
+}
+
+static void*
+etable_init_value (ETableModel *etm, int col, void *data)
+{
+ return g_strdup ("");
+}
+
+static gboolean
+etable_value_is_empty (ETableModel *etm, int col, const void *val, void *data)
+{
+ return !(val && *(char *)val);
+}
+
+static char*
+etable_value_to_string (ETableModel *etm, int col, const void *val, void *data)
+{
+ return g_strdup(val);
+}
+
+static GdkPixbuf*
+etree_icon_at (ETreeModel *etree, ETreePath *path, void *model_data)
+{
+ return NULL; /* XXX no icons for now */
+}
+
+static void*
+etree_value_at (ETreeModel *etree, ETreePath *path, int col, void *model_data)
+{
+ if (col == COL_FOLDER_NAME)
+ return "Folder Name";
+ else if (col == COL_FOLDER_DESCRIPTION)
+ return "Folder Description";
+ else /* COL_FOLDER_SUBSCRIBED */
+ return 1; /* XXX */
+}
+
+static void
+etree_set_value_at (ETreeModel *etree, ETreePath *path, int col, const void *val, void *model_data)
+{
+ /* nothing */
+}
+
+static gboolean
+etree_is_editable (ETreeModel *etree, ETreePath *path, int col, void *model_data)
+{
+ return FALSE;
+}
+
+
+
+#define EXAMPLE_DESCR "And the beast shall come forth surrounded by a roiling cloud of vengeance.\n" \
+" The house of the unbelievers shall be razed and they shall be scorched to the\n" \
+" earth. Their tags shall blink until the end of days. \n" \
+" from The Book of Mozilla, 12:10"
+
+static void
+subscribe_control_gui_init (SubscribeControl *sc)
+{
+ int i;
+ ECell *cells[3];
+ ETableHeader *e_table_header;
+ GdkPixbuf *toggles[2];
+
+ sc->description = html_new (TRUE);
+ put_html (GTK_HTML (sc->description), EXAMPLE_DESCR);
+
+ gtk_table_attach (
+ GTK_TABLE (sc), sc->description->parent->parent,
+ 0, 1, 0, 1,
+ GTK_FILL | GTK_EXPAND,
+ 0,
+ 0, 0);
+
+ sc->model = e_tree_simple_new (etable_col_count,
+ etable_duplicate_value,
+ etable_free_value,
+ etable_init_value,
+ etable_value_is_empty,
+ etable_value_to_string,
+ etree_icon_at,
+ etree_value_at,
+ etree_set_value_at,
+ etree_is_editable,
+ sc);
+
+ sc->root = e_tree_model_node_insert (sc->model, NULL,
+ 0, NULL);
+
+ e_tree_model_root_node_set_visible (sc->model, FALSE);
+
+
+ for (i = 0; i < 100; i ++)
+ e_tree_model_node_insert (sc->model, sc->root,
+ 0, NULL);
+
+ e_table_header = e_table_header_new ();
+
+ toggles[0] = NULL;
+ toggles[1] = gdk_pixbuf_new_from_xpm_data ((const char **)mark_xpm);
+
+ cells[2] = e_cell_text_new (E_TABLE_MODEL(sc->model), NULL, GTK_JUSTIFY_LEFT);
+ cells[1] = e_cell_toggle_new (0, 2, toggles);
+ cells[0] = e_cell_tree_new (E_TABLE_MODEL(sc->model),
+ NULL, NULL,
+ /*tree_expanded_pixbuf, tree_unexpanded_pixbuf,*/
+ TRUE, cells[2]);
+
+ for (i = 0; i < COL_LAST; i++) {
+ /* Create the column. */
+ ETableCol *ecol;
+
+ if (i == 1)
+ ecol = e_table_col_new_with_pixbuf (i, toggles[1],
+ 0, gdk_pixbuf_get_width (toggles[1]),
+ cells[i], g_str_compare, FALSE);
+ else
+ ecol = e_table_col_new (i, headers [i],
+ 80, 20,
+ cells[i],
+ g_str_compare, TRUE);
+ /* Add it to the header. */
+ e_table_header_add_column (e_table_header, ecol, i);
+ }
+
+ sc->table = e_table_scrolled_new (e_table_header, E_TABLE_MODEL(sc->model), ETABLE_SPEC);
+
+ gtk_table_attach (
+ GTK_TABLE (sc), sc->table,
+ 0, 1, 1, 3,
+ GTK_FILL | GTK_EXPAND,
+ GTK_FILL | GTK_EXPAND,
+ 0, 0);
+
+ gtk_widget_show_all (GTK_WIDGET(sc));
+}
+
+static void
+subscribe_control_destroy (GtkObject *object)
+{
+ SubscribeControl *subscribe_control;
+ CORBA_Environment ev;
+
+ subscribe_control = SUBSCRIBE_CONTROL (object);
+
+ CORBA_exception_init (&ev);
+
+ if (subscribe_control->shell != CORBA_OBJECT_NIL)
+ CORBA_Object_release (subscribe_control->shell, &ev);
+
+ CORBA_exception_free (&ev);
+
+ subscribe_control_parent_class->destroy (object);
+}
+
+static void
+subscribe_control_class_init (GtkObjectClass *object_class)
+{
+ object_class->destroy = subscribe_control_destroy;
+
+ subscribe_control_parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+static void
+subscribe_control_init (GtkObject *object)
+{
+}
+
+static void
+subscribe_control_construct (GtkObject *object)
+{
+ SubscribeControl *sc = SUBSCRIBE_CONTROL (object);
+
+ /*
+ * Setup parent class fields.
+ */
+ GTK_TABLE (sc)->homogeneous = FALSE;
+ gtk_table_resize (GTK_TABLE (sc), 1, 2);
+
+ /*
+ * Our instance data
+ */
+
+ subscribe_control_gui_init (sc);
+}
+
+GtkWidget *
+subscribe_control_new (const Evolution_Shell shell)
+{
+ static int serial = 0;
+ CORBA_Environment ev;
+ SubscribeControl *subscribe_control;
+
+ CORBA_exception_init (&ev);
+
+ subscribe_control = gtk_type_new (subscribe_control_get_type ());
+
+ subscribe_control_construct (GTK_OBJECT (subscribe_control));
+ subscribe_control->uri = NULL;
+ subscribe_control->serial = serial++;
+
+ subscribe_control->shell = CORBA_Object_duplicate (shell, &ev);
+ if (ev._major != CORBA_NO_EXCEPTION) {
+ subscribe_control->shell = CORBA_OBJECT_NIL;
+ gtk_widget_destroy (GTK_WIDGET (subscribe_control));
+ CORBA_exception_free (&ev);
+ return NULL;
+ }
+
+ CORBA_exception_free (&ev);
+
+ return GTK_WIDGET (subscribe_control);
+}
+
+E_MAKE_TYPE (subscribe_control, "SubscribeControl", SubscribeControl, subscribe_control_class_init, subscribe_control_init, PARENT_TYPE);
+
diff --git a/mail/subscribe-control.h b/mail/subscribe-control.h
new file mode 100644
index 0000000000..5124f3a8b7
--- /dev/null
+++ b/mail/subscribe-control.h
@@ -0,0 +1,60 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+
+#ifndef _SUBSCRIBE_CONTROL_H_
+#define _SUBSCRIBE_CONTROL_H_
+
+#include "mail-types.h"
+#include <gtk/gtktable.h>
+#include <gal/e-table/e-tree-model.h>
+#include <bonobo/bonobo-ui-handler.h>
+#include <bonobo/bonobo-property-bag.h>
+#include "shell/Evolution.h"
+
+
+#define SUBSCRIBE_CONTROL_TYPE (subscribe_control_get_type ())
+#define SUBSCRIBE_CONTROL(o) (GTK_CHECK_CAST ((o), SUBSCRIBE_CONTROL_TYPE, SubscribeControl))
+#define SUBSCRIBE_CONTROL_CLASS(k) (GTK_CHECK_CLASS_CAST((k), SUBSCRIBE_CONTROL_TYPE, SubscribeControlClass))
+#define IS_SUBSCRIBE_CONTROL(o) (GTK_CHECK_TYPE ((o), SUBSCRIBE_CONTROL_TYPE))
+#define IS_SUBSCRIBE_CONTROL_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), SUBSCRIBE_CONTROL_TYPE))
+
+struct _SubscribeControl {
+ GtkTable parent;
+
+ BonoboPropertyBag *properties;
+
+ Evolution_Shell shell;
+
+ /* This is a kludge for the toolbar problem. */
+ int serial;
+
+ /*
+ * The current URI being displayed by the SubscribeControl
+ */
+ char *uri;
+ gboolean is_news;
+
+ GtkWidget *description;
+ GtkWidget *table;
+ ETreeModel *model;
+ ETreePath *root;
+};
+
+
+typedef struct {
+ GtkTableClass parent_class;
+} SubscribeControlClass;
+
+GtkType subscribe_control_get_type (void);
+GtkWidget *subscribe_control_new (const Evolution_Shell shell);
+
+gboolean subscribe_control_set_uri (SubscribeControl *subscribe_control,
+ const char *uri);
+
+/* menu/toolbar callbacks */
+void subscribe_select_all (BonoboUIHandler *uih, void *user_data, const char *path);
+void subscribe_unselect_all (BonoboUIHandler *uih, void *user_data, const char *path);
+void subscribe_folder (GtkWidget *widget, gpointer user_data);
+void unsubscribe_folder (GtkWidget *widget, gpointer user_data);
+
+#endif /* _SUBSCRIBE_CONTROL_H_ */