From 45b1f2233e3e97510696b3775d38d0088a125c70 Mon Sep 17 00:00:00 2001 From: Iain Holmes Date: Thu, 26 Oct 2000 18:26:21 +0000 Subject: Added some functionality to the Executive Summary Doesn't return to the top when refreshed Can execute programs when the user clicks on exec:// URLs and can compose an email when mailto:'s are clicked. svn path=/trunk/; revision=6205 --- art/Makefile.am | 2 + executive-summary/ChangeLog | 18 ++ executive-summary/component/Makefile.am | 23 ++- executive-summary/component/e-summary-url.c | 299 +++++++++++++++++++++++++++ executive-summary/component/e-summary-url.h | 34 +++ executive-summary/component/e-summary-util.c | 63 ++++++ executive-summary/component/e-summary-util.h | 29 +++ executive-summary/component/e-summary.c | 124 ++--------- 8 files changed, 481 insertions(+), 111 deletions(-) create mode 100644 executive-summary/component/e-summary-url.c create mode 100644 executive-summary/component/e-summary-url.h create mode 100644 executive-summary/component/e-summary-util.c create mode 100644 executive-summary/component/e-summary-util.h diff --git a/art/Makefile.am b/art/Makefile.am index 5168740740..8b6e3d81be 100644 --- a/art/Makefile.am +++ b/art/Makefile.am @@ -22,6 +22,7 @@ images_DATA = \ buttonsdir = $(datadir)/images/evolution/buttons buttons_DATA = \ + add-service.png \ compose-message.png \ copy-message.png \ fetch-mail.png \ @@ -31,6 +32,7 @@ buttons_DATA = \ reply.png EXTRA_DIST = \ + add-service.png \ attachment.xpm \ compose-message.png \ copy-message.png \ diff --git a/executive-summary/ChangeLog b/executive-summary/ChangeLog index 70f12d2a95..e6e9b48afc 100644 --- a/executive-summary/ChangeLog +++ b/executive-summary/ChangeLog @@ -1,3 +1,21 @@ +2000-10-25 Iain Holmes + + * component/e-summary-url.c (e_summary_url_exec): Execute a program + specified in the format "exec://program args". + (e_summary_url_mail_compose): Run the mail composer when a mailto: + URL is clicked. + +2000-10-25 Iain Holmes + + * component/e-summary.c (e_summary_start_load): Add a hack to stop the + GtkHTML widget returning to the top when it is redrawn. + + * component/e-summary-url.[ch] + * component/e-summary-util.[ch]: Split some functions out of e-summary.c + + * component/Makefile.am: Added the new files, and run orbit-idl on the + mail composer idl. + 2000-10-25 * component/e-summary-factory.c (control_activate): User diff --git a/executive-summary/component/Makefile.am b/executive-summary/component/Makefile.am index 0731ff40ca..496d70d2ac 100644 --- a/executive-summary/component/Makefile.am +++ b/executive-summary/component/Makefile.am @@ -19,27 +19,32 @@ INCLUDES = \ -DEVOLUTION_DATADIR=\""$(datadir)"\" \ -DG_LOG_DOMAIN=\"evolution-executive-summary\" -CLEANFILES = $(IDL_GENERATED) +CLEANFILES = $(COMPOSER_GENERATED) -IDL_GENERATED = \ - Executive-Summary.h \ - Executive-Summary-common.c \ - Executive-Summary-skels.c \ - Executive-Summary-stubs.c +COMPOSER_GENERATED = \ + Composer.h \ + Composer-common.c \ + Composer-skels.c \ + Composer-stubs.c -Executive-Summary-impl.o: Executive-Summary.h +Composer-impl.o: Composer.h -$(IDL_GENERATED): +$(COMPOSER_GENERATED): $(ORBIT_IDL) -I $(datadir)/idl `$(GNOME_CONFIG) --cflags idl` \ - -I$(srcdir) $(srcdir)/../idl/Executive-Summary.idl + -I$(srcdir) $(top_srcdir)/composer/Composer.idl evolution_executive_summary_SOURCES = \ + $(COMPOSER_GENERATED) \ component-factory.c \ component-factory.h \ e-summary.c \ e-summary.h \ e-summary-factory.c \ e-summary-factory.h \ + e-summary-url.c \ + e-summary-url.h \ + e-summary-util.c \ + e-summary-util.h \ main.c evolution_executive_summary_LDADD = \ diff --git a/executive-summary/component/e-summary-url.c b/executive-summary/component/e-summary-url.c new file mode 100644 index 0000000000..856297bb68 --- /dev/null +++ b/executive-summary/component/e-summary-url.c @@ -0,0 +1,299 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-summary-url.c + * + * Authors: Iain Holmes + * + * 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 +#endif + +#include +#include + +#include +#include +#include + +#include + +#include +#include "e-summary.h" +#include "e-summary-url.h" +#include "e-summary-util.h" + +#include "Composer.h" + +typedef enum _ESummaryProtocol { + PROTOCOL_NONE, + PROTOCOL_HTTP, + PROTOCOL_MAILTO, + PROTOCOL_VIEW, + PROTOCOL_EXEC, + PROTOCOL_FILE, + PROTOCOL_OTHER +} ESummaryProtocol; + +#define COMPOSER_IID "OAFIID:evolution-composer:evolution-mail:cd8618ea-53e1-4b9e-88cf-ec578bdb903b" + +void +e_summary_url_request (GtkHTML *html, + const gchar *url, + GtkHTMLStream *stream) +{ + char *filename; + GnomeVFSHandle *handle = NULL; + GnomeVFSResult result; + + if (strncasecmp (url, "file:", 5) == 0) { + url += 5; + filename = e_pixmap_file (url); + } else if (strchr (url, ':') >= strchr (url, '/')) { + filename = e_pixmap_file (url); + } else + filename = g_strdup (url); + + if (filename == NULL) { + gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); + return; + } + + result = gnome_vfs_open (&handle, filename, GNOME_VFS_OPEN_READ); + + if (result != GNOME_VFS_OK) { + g_warning ("%s: %s", filename, + gnome_vfs_result_to_string (result)); + g_free (filename); + gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); + return; + } + + g_free (filename); + while (1) { + char buffer[4096]; + GnomeVFSFileSize size; + + /* Clear buffer */ + memset (buffer, 0x00, 4096); + + result = gnome_vfs_read (handle, buffer, 4096, &size); + if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { + g_warning ("Error reading data: %s", + gnome_vfs_result_to_string (result)); + gnome_vfs_close (handle); + gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); + } + + if (size == 0) + break; /* EOF */ + + gtk_html_stream_write (stream, buffer, size); + } + + gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); + gnome_vfs_close (handle); +} + +static ESummaryProtocol +get_protocol (const char *url) +{ + char *lowerurl; + ESummaryProtocol protocol = PROTOCOL_OTHER; + + lowerurl = g_strdup (url); + g_strdown (lowerurl); + + /* Check for no :/ */ + if (strstr (lowerurl, "://") == NULL) { + + /* Annoying alternative for mailto URLs */ + if (strncmp (lowerurl, "mailto:", 6) != 0) { + g_free (lowerurl); + return PROTOCOL_NONE; + } else { + g_free (lowerurl); + return PROTOCOL_MAILTO; + } + } + + switch (lowerurl[0]) { + case 'h': + if (strncmp (lowerurl + 1, "ttp", 3) == 0) + protocol = PROTOCOL_HTTP; + break; + + case 'm': + if (strncmp (lowerurl + 1, "ailto", 5) == 0) + protocol = PROTOCOL_MAILTO; + break; + + case 'v': + if (strncmp (lowerurl + 1, "iew", 3) == 0) + protocol = PROTOCOL_VIEW; + break; + + case 'e': + if (strncmp (lowerurl + 1, "xec", 3) == 0) + protocol = PROTOCOL_EXEC; + break; + + case 'f': + if (strncmp (lowerurl + 1, "ile", 3) == 0) + protocol = PROTOCOL_FILE; + break; + + default: + break; + } + + g_free (lowerurl); + + return protocol; +} + +void +e_summary_url_click (GtkWidget *widget, + const char *url, + ESummary *esummary) +{ + ESummaryProtocol protocol; + g_print ("URL: %s\n", url); + + protocol = get_protocol (url); + + switch (protocol) { + case PROTOCOL_MAILTO: + /* Open a composer window */ + e_summary_url_mail_compose (esummary, url); + break; + + case PROTOCOL_VIEW: + /* Change the EShellView's current uri */ + break; + + case PROTOCOL_EXEC: + /* Execute the rest of the url */ + e_summary_url_exec (url + 7); + break; + + case PROTOCOL_NONE: + case PROTOCOL_OTHER: + case PROTOCOL_HTTP: + case PROTOCOL_FILE: + default: + /* Let browser handle it */ + gnome_url_show (url); + break; + + } +} + +gboolean +e_summary_url_mail_compose (ESummary *esummary, + const char *url) +{ + CORBA_Object composer; + CORBA_Environment ev; + Evolution_Composer_RecipientList *to, *cc, *bcc; + Evolution_Composer_Recipient *recipient; + char *address, *proto; + CORBA_char *subject; + + CORBA_exception_init (&ev); + + /* FIXME: Query for IIDs? */ + composer = oaf_activate_from_id ((char *)COMPOSER_IID, 0, NULL, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + g_warning ("Unable to start composer component!"); + return FALSE; + } + + if ( (proto = strstr (url, "://")) != NULL){ + address = proto + 3; + } else { + address = url + 7; + } + + to = Evolution_Composer_RecipientList__alloc (); + to->_length = 1; + to->_maximum = 1; + to->_buffer = CORBA_sequence_Evolution_Composer_Recipient_allocbuf (to->_maximum); + + recipient = to->_buffer; + recipient->name = CORBA_string_dup (""); + recipient->address = CORBA_string_dup (address?address:""); + + /* FIXME: Get these out of the URL */ + cc = Evolution_Composer_RecipientList__alloc (); + cc->_length = 0; + cc->_maximum = 0; + cc->_buffer = CORBA_sequence_Evolution_Composer_Recipient_allocbuf (cc->_maximum); + + bcc = Evolution_Composer_RecipientList__alloc (); + bcc->_length = 0; + bcc->_maximum = 0; + bcc->_buffer = CORBA_sequence_Evolution_Composer_Recipient_allocbuf (bcc->_maximum); + + subject = CORBA_string_dup (""); + + CORBA_exception_init (&ev); + Evolution_Composer_set_headers (composer, to, cc, bcc, subject, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + CORBA_free (to); + g_warning ("%s(%d): Error setting headers", __FUNCTION__, __LINE__); + return FALSE; + } + + CORBA_free (to); + + CORBA_exception_init (&ev); + Evolution_Composer_show (composer, &ev); + if (ev._major != CORBA_NO_EXCEPTION) { + CORBA_exception_free (&ev); + g_warning ("%s(%d): Error showing composer", __FUNCTION__, __LINE__); + return FALSE; + } + + CORBA_exception_free (&ev); + + /* FIXME: Free the composer? */ + + return TRUE; +} + +gboolean +e_summary_url_exec (const char *exec) +{ + gchar **exec_array; + int argc; + + exec_array = g_strsplit (exec, " ", 0); + + argc = 0; + while (exec_array[argc] != NULL) { + argc++; + } + + gnome_execute_async (NULL, argc, exec_array); + + g_strfreev (exec_array); +} diff --git a/executive-summary/component/e-summary-url.h b/executive-summary/component/e-summary-url.h new file mode 100644 index 0000000000..de45caf7c7 --- /dev/null +++ b/executive-summary/component/e-summary-url.h @@ -0,0 +1,34 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-summary-url.h + * + * Authors: Iain Holmes + * + * 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. + */ + +#ifndef _E_SUMMARY_URL_H__ +#define _E_SUMMARY_URL_H__ + +void e_summary_url_request (GtkHTML *html, + const gchar *url, + GtkHTMLStream *stream); +void e_summary_url_click (GtkWidget *widget, + const char *url, + ESummary *esummary); + +#endif diff --git a/executive-summary/component/e-summary-util.c b/executive-summary/component/e-summary-util.c new file mode 100644 index 0000000000..8ed8d4daea --- /dev/null +++ b/executive-summary/component/e-summary-util.c @@ -0,0 +1,63 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-summary-url.c + * + * Authors: Iain Holmes + * + * 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. + */ + +#include + +char * +e_pixmap_file (const char *filename) +{ + char *ret; + char *edir; + + if (g_file_exists (filename)) { + ret = g_strdup (filename); + + return ret; + } + + /* 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); +} + diff --git a/executive-summary/component/e-summary-util.h b/executive-summary/component/e-summary-util.h new file mode 100644 index 0000000000..0cfd50403a --- /dev/null +++ b/executive-summary/component/e-summary-util.h @@ -0,0 +1,29 @@ +/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ +/* e-summary-util.h + * + * Authors: Iain Holmes + * + * 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. + */ + +#ifndef _E_SUMMARY_UTIL_H__ +#define _E_SUMMARY_UTIL_H__ + +char *e_pixmap_file (const char *filename); + +#endif diff --git a/executive-summary/component/e-summary.c b/executive-summary/component/e-summary.c index e7cbc4b6e6..736398214b 100644 --- a/executive-summary/component/e-summary.c +++ b/executive-summary/component/e-summary.c @@ -30,21 +30,23 @@ #include #include -#include #include #include #include #include -#include #include "e-summary.h" +#include "e-summary-util.h" +#include "e-summary-url.h" #define PARENT_TYPE (gtk_vbox_get_type ()) static GtkObjectClass *e_summary_parent_class; struct _ESummaryPrivate { + Evolution_Shell shell; + GtkWidget *html_scroller; GtkWidget *html; @@ -75,7 +77,6 @@ s2w_foreach (gpointer *key, gpointer *value, ESummaryPrivate *priv) { - g_print ("%s\n", __FUNCTION__); e_summary_window_free ((ESummaryWindow *) value, priv); g_free (value); } @@ -86,7 +87,6 @@ e_summary_destroy (GtkObject *object) ESummary *esummary = E_SUMMARY (object); ESummaryPrivate *priv; - g_print ("Destroy\n"); priv = esummary->private; if (priv == NULL) return; @@ -110,102 +110,6 @@ e_summary_class_init (GtkObjectClass *object_class) e_summary_parent_class = gtk_type_class (PARENT_TYPE); } -static char * -e_pixmap_file (const char *filename) -{ - char *ret; - char *edir; - - if (g_file_exists (filename)) { - ret = g_strdup (filename); - - return ret; - } - - /* 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; - GnomeVFSHandle *handle = NULL; - GnomeVFSResult result; - - if (strncasecmp (url, "file:", 5) == 0) { - url += 5; - filename = e_pixmap_file (url); - } else if (strchr (url, ':') >= strchr (url, '/')) { - filename = e_pixmap_file (url); - } else - filename = g_strdup (url); - - if (filename == NULL) { - gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); - return; - } - - result = gnome_vfs_open (&handle, filename, GNOME_VFS_OPEN_READ); - - if (result != GNOME_VFS_OK) { - g_warning ("%s: %s", filename, - gnome_vfs_result_to_string (result)); - g_free (filename); - gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); - return; - } - - g_free (filename); - while (1) { - char buffer[4096]; - GnomeVFSFileSize size; - - /* Clear buffer */ - memset (buffer, 0x00, 4096); - - result = gnome_vfs_read (handle, buffer, 4096, &size); - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { - g_warning ("Error reading data: %s", - gnome_vfs_result_to_string (result)); - gnome_vfs_close (handle); - gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR); - } - - if (size == 0) - break; /* EOF */ - - gtk_html_stream_write (stream, buffer, size); - } - - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); - gnome_vfs_close (handle); -} - static void e_summary_start_load (ESummary *summary) { @@ -213,7 +117,12 @@ e_summary_start_load (ESummary *summary) char *header = ""; priv = summary->private; + priv->stream = gtk_html_begin (GTK_HTML (priv->html)); + + /* Hack to stop page returning to the top */ + GTK_HTML (priv->html)->engine->newPage = FALSE; + gtk_html_write (GTK_HTML (priv->html), priv->stream, header, strlen (header)); } @@ -222,7 +131,11 @@ static void load_default (ESummary *summary) { ESummaryPrivate *priv; - char *def = "

"; + char *def = "
" + "
" + "
" + "Submit a bug report" + "All Executive Summary comments to Iain Holmes

"; g_return_if_fail (summary != NULL); g_return_if_fail (IS_E_SUMMARY (summary)); @@ -259,6 +172,7 @@ e_summary_init (ESummary *esummary) priv->window_list = NULL; priv->idle = 0; + /* HTML widget */ priv->html_scroller = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->html_scroller), @@ -267,9 +181,11 @@ e_summary_init (ESummary *esummary) gtk_html_set_editable (GTK_HTML (priv->html), FALSE); gtk_html_set_default_background_color (GTK_HTML (priv->html), &bgcolour); gtk_signal_connect (GTK_OBJECT (priv->html), "url-requested", - GTK_SIGNAL_FUNC (request_cb), NULL); + GTK_SIGNAL_FUNC (e_summary_url_request), esummary); gtk_signal_connect (GTK_OBJECT (priv->html), "object-requested", GTK_SIGNAL_FUNC (on_object_requested), esummary); + gtk_signal_connect (GTK_OBJECT (priv->html), "link-clicked", + GTK_SIGNAL_FUNC (e_summary_url_click), esummary); gtk_container_add (GTK_CONTAINER (priv->html_scroller), priv->html); gtk_widget_show_all (priv->html_scroller); @@ -292,8 +208,12 @@ GtkWidget * e_summary_new (const Evolution_Shell shell) { ESummary *esummary; + ESummaryPrivate *priv; esummary = gtk_type_new (e_summary_get_type ()); + priv = esummary->private; + + priv->shell = shell; return GTK_WIDGET (esummary); } -- cgit v1.2.3