aboutsummaryrefslogtreecommitdiffstats
path: root/executive-summary/component/e-summary.c
diff options
context:
space:
mode:
Diffstat (limited to 'executive-summary/component/e-summary.c')
-rw-r--r--executive-summary/component/e-summary.c496
1 files changed, 496 insertions, 0 deletions
diff --git a/executive-summary/component/e-summary.c b/executive-summary/component/e-summary.c
new file mode 100644
index 0000000000..0684a8c083
--- /dev/null
+++ b/executive-summary/component/e-summary.c
@@ -0,0 +1,496 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* e-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 <gnome.h>
+#include <bonobo.h>
+
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
+#include <gtk/gtkvbox.h>
+#include <gal/util/e-util.h>
+#include <e-summary-subwindow.h>
+
+#include <widgets/misc/e-title-bar.h>
+#include <executive-summary.h>
+
+#include "e-summary.h"
+
+#define PARENT_TYPE (gtk_vbox_get_type ())
+
+static GtkObjectClass *e_summary_parent_class;
+
+struct _ESummaryPrivate {
+ GtkWidget *html_scroller;
+ GtkWidget *html;
+
+ GHashTable *summary_to_window;
+ GList *window_list;
+
+ GtkHTMLStream *stream;
+};
+
+typedef enum {
+ E_SUMMARY_WINDOW_BONOBO,
+ E_SUMMARY_WINDOW_HTML
+} ESummaryWindowType;
+
+typedef struct _ESummaryWindow {
+ ExecutiveSummary *summary;
+ char *title;
+
+ ESummaryWindowType type;
+
+ char *html;
+ GtkWidget *control;
+} ESummaryWindow;
+
+static gboolean on_object_requested (GtkHTML *html,
+ GtkHTMLEmbedded *eb,
+ ESummary *summary);
+static void e_summary_window_free (ESummaryWindow *window,
+ ESummaryPrivate *priv);
+
+/* GtkObject methods */
+
+static void
+s2w_foreach (gpointer *key,
+ gpointer *value,
+ ESummaryPrivate *priv)
+{
+ bonobo_object_unref (BONOBO_OBJECT (key));
+ e_summary_window_free ((ESummaryWindow *) value, priv);
+}
+
+static void
+e_summary_destroy (GtkObject *object)
+{
+ ESummary *esummary = E_SUMMARY (object);
+ ESummaryPrivate *priv;
+
+ priv = esummary->private;
+ if (priv == NULL)
+ return;
+
+ g_hash_table_foreach (priv->summary_to_window,
+ s2w_foreach, priv);
+ g_hash_table_destroy (priv->summary_to_window);
+
+ g_free (esummary->private);
+ esummary->private = NULL;
+
+ e_summary_parent_class->destroy (object);
+}
+
+static void
+e_summary_class_init (GtkObjectClass *object_class)
+{
+ object_class->destroy = e_summary_destroy;
+
+ e_summary_parent_class = gtk_type_class (PARENT_TYPE);
+}
+
+static char *
+e_pixmap_file (const char *filename)
+{
+ char *ret;
+ char *edir;
+
+ /* Try the evolution images dir */
+ edir = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution",
+ filename);
+
+ if (g_file_exists (edir)) {
+ ret = g_strdup (edir);
+ g_free (edir);
+
+ return ret;
+ }
+
+ /* Try the evolution button images dir */
+ edir = g_concat_dir_and_file (EVOLUTION_DATADIR "/images/evolution/buttons",
+ filename);
+
+ if (g_file_exists (edir)) {
+ ret = g_strdup (edir);
+ g_free (edir);
+
+ return ret;
+ }
+
+ /* Fall back to the gnome_pixmap_file */
+ return gnome_pixmap_file (filename);
+}
+
+static void
+request_cb (GtkHTML *html,
+ const gchar *url,
+ GtkHTMLStream *stream)
+{
+ char *filename;
+ FILE *handle;
+
+ filename = e_pixmap_file (url);
+
+ if (filename == NULL) {
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ return;
+ }
+
+ handle = fopen (filename, "r");
+ g_free (filename);
+
+ if (handle == NULL) {
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ return;
+ }
+
+ while (!feof (handle)) {
+ char buffer[4096];
+ int size;
+
+ /* Clear buffer */
+ memset (buffer, 0x00, 4096);
+
+ size = fread (buffer, 1, 4096, handle);
+ if (size != 4096) {
+ /* Under run */
+ if (feof (handle)) {
+ gtk_html_stream_write (stream, buffer, size);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ fclose (handle);
+ return;
+ } else {
+ /* Error occurred */
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ fclose (handle);
+ return;
+ }
+ }
+ gtk_html_stream_write (stream, buffer, 4096);
+ }
+
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ fclose (handle);
+}
+
+static void
+e_summary_start_load (ESummary *summary)
+{
+ ESummaryPrivate *priv;
+ char *header = "<html><body>";
+
+ priv = summary->private;
+ priv->stream = gtk_html_begin (GTK_HTML (priv->html));
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ header, strlen (header));
+}
+
+static void
+load_default (ESummary *summary)
+{
+ ESummaryPrivate *priv;
+ char *def = "<table width=\"100%\"><tr><td align=\"right\"><img src=\"ccsplash.png\"></td></tr></table><hr>";
+
+ g_return_if_fail (summary != NULL);
+ g_return_if_fail (IS_E_SUMMARY (summary));
+
+ priv = summary->private;
+
+ g_return_if_fail (priv->stream != NULL);
+
+ gtk_html_write (GTK_HTML (priv->html), priv->stream, def, strlen (def));
+}
+
+static void
+e_summary_end_load (ESummary *summary)
+{
+ ESummaryPrivate *priv;
+ char *footer = "<hr></body></html>";
+
+ priv = summary->private;
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ footer, strlen (footer));
+ gtk_html_end (GTK_HTML (priv->html), priv->stream, GTK_HTML_STREAM_OK);
+
+ priv->stream = NULL;
+}
+
+static void
+e_summary_init (ESummary *esummary)
+{
+ GdkColor bgcolour = {0, 0xdfff, 0xdfff, 0xffff};
+ ESummaryPrivate *priv;
+
+ esummary->private = g_new0 (ESummaryPrivate, 1);
+ priv = esummary->private;
+ g_print ("priv: %p\n", priv);
+
+ priv->window_list = NULL;
+ /* HTML widget */
+ priv->html_scroller = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->html_scroller),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ priv->html = gtk_html_new ();
+ gtk_html_set_editable (GTK_HTML (priv->html), FALSE);
+ gtk_signal_connect (GTK_OBJECT (priv->html), "url-requested",
+ GTK_SIGNAL_FUNC (request_cb), NULL);
+ gtk_signal_connect (GTK_OBJECT (priv->html), "object-requested",
+ GTK_SIGNAL_FUNC (on_object_requested), esummary);
+
+ gtk_html_set_default_background_color (GTK_HTML (priv->html), &bgcolour);
+ gtk_container_add (GTK_CONTAINER (priv->html_scroller), priv->html);
+ gtk_widget_show_all (priv->html_scroller);
+
+ e_summary_rebuild_page (esummary);
+
+ /* Pack stuff */
+ gtk_box_pack_start (GTK_BOX (esummary), priv->html_scroller,
+ TRUE, TRUE, 0);
+
+ /* Init hashtable */
+ priv->summary_to_window = g_hash_table_new (NULL, NULL);
+}
+
+E_MAKE_TYPE (e_summary, "ESummary", ESummary, e_summary_class_init,
+ e_summary_init, PARENT_TYPE);
+
+GtkWidget *
+e_summary_new (const Evolution_Shell shell)
+{
+ ESummary *esummary;
+
+ esummary = gtk_type_new (e_summary_get_type ());
+
+ return GTK_WIDGET (esummary);
+}
+
+static gboolean
+on_object_requested (GtkHTML *html,
+ GtkHTMLEmbedded *eb,
+ ESummary *summary)
+{
+ ESummaryWindow *window;
+ int type;
+
+ if (sscanf (eb->classid, "cid:%d-%p", &type, &window) != 2) {
+ g_warning ("Could not get the window reference\n");
+ return FALSE;
+ }
+
+ switch (type) {
+ case 1:
+ g_assert_not_reached ();
+ break;
+
+ case 2:
+ gtk_widget_show (window->control);
+
+ gtk_widget_ref (GTK_WIDGET (window->control));
+ if (window->control->parent != NULL) {
+ gtk_container_remove (GTK_CONTAINER (window->control->parent), window->control);
+ }
+ gtk_container_add (GTK_CONTAINER (eb), window->control);
+
+ gtk_widget_unref (GTK_WIDGET (window->control));
+ break;
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return TRUE;
+}
+
+static void
+e_summary_display_window (ESummary *esummary,
+ ESummaryWindow *window)
+{
+ ESummaryPrivate *priv;
+ char *footer = "</td></tr></table>";
+ char *title_cid, *body_cid;
+
+ priv = esummary->private;
+
+ title_cid = g_strdup_printf ("<table height=\"100%%\" width=\"100%%\"><tr><td bgcolor=\"#ff0000\" align=\"left\"><b>%s</b></td></tr><tr><td>", window->title);
+ gtk_html_write (GTK_HTML (priv->html), priv->stream, title_cid,
+ strlen (title_cid));
+ g_free (title_cid);
+
+ switch (window->type) {
+ case E_SUMMARY_WINDOW_HTML:
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ window->html, strlen (window->html));
+ break;
+
+ case E_SUMMARY_WINDOW_BONOBO:
+ body_cid = g_strdup_printf ("<object classid=\"cid:2-%p\"></object>", window);
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ body_cid, strlen (body_cid));
+ break;
+
+ default:
+ break;
+ }
+
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ footer, strlen (footer));
+}
+
+void
+e_summary_rebuild_page (ESummary *esummary)
+{
+ ESummaryPrivate *priv;
+ GList *windows;
+ char *service_table = "<table numcols=\"2\" width=\"100%\">";
+ int loc;
+
+ g_return_if_fail (esummary != NULL);
+ g_return_if_fail (IS_E_SUMMARY (esummary));
+
+ priv = esummary->private;
+
+ gtk_layout_freeze (GTK_LAYOUT (priv->html));
+ e_summary_start_load (esummary);
+ load_default (esummary);
+
+ /* Load the start of the services */
+ gtk_html_write (GTK_HTML (priv->html), priv->stream, service_table,
+ strlen (service_table));
+ /* Load each of the services */
+ loc = 0;
+ for (windows = priv->window_list; windows; windows = windows->next) {
+ ESummaryWindow *window;
+
+ window = windows->data;
+
+ if (loc % 2 == 0) {
+ g_print ("new line:%d\n", loc);
+ if (loc != 0) {
+ gtk_html_write (GTK_HTML (priv->html),
+ priv->stream, "</tr>", 5);
+ }
+ gtk_html_write (GTK_HTML (priv->html),
+ priv->stream, "<tr>", 4);
+ }
+
+ gtk_html_write (GTK_HTML (priv->html), priv->stream,
+ "<td>", 4);
+
+ e_summary_display_window (esummary, window);
+
+ gtk_html_write (GTK_HTML (priv->html), priv->stream, "</td>", 5);
+ loc++;
+ }
+
+ gtk_html_write (GTK_HTML (priv->html), priv->stream, "</tr></table>",
+ 13);
+ e_summary_end_load (esummary);
+ gtk_layout_thaw (GTK_LAYOUT (priv->html));
+}
+
+void
+e_summary_add_html_service (ESummary *esummary,
+ ExecutiveSummary *summary,
+ const char *html,
+ const char *title)
+{
+ ESummaryWindow *window;
+ ESummaryPrivate *priv;
+
+ window = g_new0 (ESummaryWindow, 1);
+ window->type = E_SUMMARY_WINDOW_HTML;
+ window->html = g_strdup (html);
+ window->title = g_strdup (title);
+
+ window->summary = summary;
+ priv = esummary->private;
+ priv->window_list = g_list_append (priv->window_list, window);
+
+ g_hash_table_insert (priv->summary_to_window, summary, window);
+}
+
+void
+e_summary_add_bonobo_service (ESummary *esummary,
+ ExecutiveSummary *summary,
+ GtkWidget *control,
+ const char *title)
+{
+ ESummaryWindow *window;
+ ESummaryPrivate *priv;
+
+ window = g_new0 (ESummaryWindow, 1);
+ window->type = E_SUMMARY_WINDOW_BONOBO;
+ window->control = control;
+
+ window->title = g_strdup (title);
+ window->summary = summary;
+
+ priv = esummary->private;
+ priv->window_list = g_list_append (priv->window_list, window);
+
+ g_hash_table_insert (priv->summary_to_window, summary, window);
+}
+
+static void
+e_summary_window_free (ESummaryWindow *window,
+ ESummaryPrivate *priv)
+{
+ g_free (window->title);
+ if (window->type == E_SUMMARY_WINDOW_BONOBO)
+ gtk_widget_unref (window->control);
+ else
+ g_free (window->html);
+
+ priv->window_list = g_list_remove (priv->window_list, window);
+
+ g_hash_table_remove (priv->summary_to_window, window->summary);
+ g_free (window);
+}
+
+void
+e_summary_update_window (ESummary *esummary,
+ ExecutiveSummary *summary,
+ const char *html)
+{
+ ESummaryWindow *window;
+ ESummaryPrivate *priv;
+
+ g_return_if_fail (esummary != NULL);
+ g_return_if_fail (IS_E_SUMMARY (esummary));
+ g_return_if_fail (summary != NULL);
+
+ priv = esummary->private;
+ window = g_hash_table_lookup (priv->summary_to_window, summary);
+
+ g_return_if_fail (window != NULL);
+
+ g_free (window->html);
+ window->html = g_strdup (html);
+
+ e_summary_rebuild_page (esummary);
+}
+