Files
evolution/executive-summary/component/e-summary-url.c
Iain Holmes 4f3a4c8234 Moving the executive summarys now :)
mail-summary now has clickable names to change to that view
executive summary remembers what components are running when you close.
selection now blocks ES updating so it won't be cleared.

svn path=/trunk/; revision=6330
2000-11-02 00:42:35 +00:00

568 lines
13 KiB
C

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
/* e-summary-url.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 <gal/util/e-util.h>
#include <liboaf/liboaf.h>
#include <libgnomevfs/gnome-vfs.h>
#include "e-summary.h"
#include "e-summary-url.h"
#include "e-summary-util.h"
#include <evolution-services/executive-summary-component-view.h>
#include "Composer.h"
typedef enum _ESummaryProtocol {
PROTOCOL_NONE,
PROTOCOL_HTTP,
PROTOCOL_MAILTO,
PROTOCOL_VIEW,
PROTOCOL_EXEC,
PROTOCOL_FILE,
PROTOCOL_CLOSE,
PROTOCOL_LEFT,
PROTOCOL_RIGHT,
PROTOCOL_UP,
PROTOCOL_DOWN,
PROTOCOL_CONFIGURE,
PROTOCOL_OTHER
} ESummaryProtocol;
static char *descriptions[] = {
N_("Open %s with the default GNOME application"),
N_("Open %s with the default GNOME web browser"),
N_("Send an email to %s"),
N_("Change the view to %s"),
N_("Run %s"),
N_("Open %s with the default GNOME application"),
N_("Close %s"),
N_("Move %s to the left"),
N_("Move %s to the right"),
N_("Move %s into the previous row"),
N_("Move %s into the next row"),
N_("Configure %s"),
N_("Open %s with the default GNOME application")
};
#define COMPOSER_IID "OAFIID:evolution-composer:evolution-mail:cd8618ea-53e1-4b9e-88cf-ec578bdb903b"
gboolean e_summary_url_mail_compose (ESummary *esummary,
const char *url);
gboolean e_summary_url_exec (const char *exec);
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 char *
parse_uri (const char *uri,
ESummaryProtocol protocol,
ESummary *esummary)
{
ExecutiveSummaryComponentView *view;
char *parsed;
char *p;
int id;
switch (protocol) {
case PROTOCOL_HTTP:
/* "http://" == 7 */
parsed = g_strdup (uri + 7);
break;
case PROTOCOL_EXEC:
/* "exec://" == 7 */
parsed = g_strdup (uri + 7);
break;
case PROTOCOL_VIEW:
/* "view://" == 7 */
parsed = g_strdup (uri + 7);
break;
case PROTOCOL_MAILTO:
/* Fun. Mailto's might be "mailto:" or "mailto://" */
if (strstr (uri, "mailto://") == NULL) {
parsed = (char *) (uri + 7);
} else {
parsed = (char *) (uri + 9);
}
/* Now strip anything after a question mark,
as it is a parameter (that we ignore for the time being) */
if ( (p = strchr (parsed, '?')) != NULL) {
parsed = g_strndup (parsed, p - parsed);
} else {
parsed = g_strdup (parsed);
}
break;
case PROTOCOL_CLOSE:
id = atoi (uri + 8);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_LEFT:
id = atoi (uri + 7);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_RIGHT:
id = atoi (uri + 8);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_UP:
id = atoi (uri + 5);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_DOWN:
id = atoi (uri + 7);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_CONFIGURE:
id = atoi (uri + 12);
view = e_summary_view_from_id (esummary, id);
parsed = g_strdup (executive_summary_component_view_get_title (view));
break;
case PROTOCOL_NONE:
case PROTOCOL_OTHER:
default:
/* Just return the uneditted uri. */
parsed = g_strdup (uri);
break;
}
return parsed;
}
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 'c':
switch (lowerurl[1]) {
case 'l':
if (strncmp (lowerurl + 2, "ose", 3) == 0)
protocol = PROTOCOL_CLOSE;
break;
case 'o':
if (strncmp (lowerurl + 2, "nfigure", 7) == 0)
protocol = PROTOCOL_CONFIGURE;
break;
}
case 'd':
if (strncmp (lowerurl + 1, "own", 3) == 0)
protocol = PROTOCOL_DOWN;
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;
case 'h':
if (strncmp (lowerurl + 1, "ttp", 3) == 0)
protocol = PROTOCOL_HTTP;
break;
case 'l':
if (strncmp (lowerurl + 1, "eft", 3) == 0)
protocol = PROTOCOL_LEFT;
break;
case 'm':
if (strncmp (lowerurl + 1, "ailto", 5) == 0)
protocol = PROTOCOL_MAILTO;
break;
case 'r':
if (strncmp (lowerurl + 1, "ight", 4) == 0)
protocol = PROTOCOL_RIGHT;
break;
case 'u':
if (lowerurl[1] == 'p')
protocol = PROTOCOL_UP;
break;
case 'v':
if (strncmp (lowerurl + 1, "iew", 3) == 0)
protocol = PROTOCOL_VIEW;
break;
default:
break;
}
g_free (lowerurl);
return protocol;
}
void
e_summary_url_click (GtkWidget *widget,
const char *url,
ESummary *esummary)
{
ESummaryProtocol protocol;
ExecutiveSummaryComponentView *view;
gpointer window; /* FIXME */
char *parsed;
int id;
protocol = get_protocol (url);
parsed = parse_uri (url, protocol, esummary);
switch (protocol) {
case PROTOCOL_MAILTO:
/* Open a composer window */
e_summary_url_mail_compose (esummary, parsed);
break;
case PROTOCOL_VIEW:
/* Change the EShellView's current uri */
e_summary_change_current_view (esummary, parsed);
break;
case PROTOCOL_EXEC:
/* Execute the rest of the url */
e_summary_url_exec (parsed);
break;
case PROTOCOL_CLOSE:
/* Close the window. */
id = atoi (url + 8);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
window = e_summary_window_from_view (esummary, view);
e_summary_window_remove_from_ht (window, esummary);
e_summary_window_free (window, esummary);
e_summary_rebuild_page (esummary);
break;
case PROTOCOL_CONFIGURE:
/* Configure the window. . . */
id = atoi (url + 12);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
/* Issue the configure command some how :) */
break;
case PROTOCOL_LEFT:
/* Window left */
id = atoi (url + 7);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
window = e_summary_window_from_view (esummary, view);
e_summary_window_move_left (esummary, window);
e_summary_rebuild_page (esummary);
break;
case PROTOCOL_RIGHT:
id = atoi (url + 8);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
window = e_summary_window_from_view (esummary, view);
e_summary_window_move_right (esummary, window);
e_summary_rebuild_page (esummary);
break;
case PROTOCOL_UP:
id = atoi (url + 5);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
window = e_summary_window_from_view (esummary, view);
e_summary_window_move_up (esummary, window);
e_summary_rebuild_page (esummary);
break;
case PROTOCOL_DOWN:
id = atoi (url + 7);
view = e_summary_view_from_id (esummary, id);
if (view == NULL)
return;
window = e_summary_window_from_view (esummary, view);
e_summary_window_move_down (esummary, window);
e_summary_rebuild_page (esummary);
break;
case PROTOCOL_NONE:
case PROTOCOL_OTHER:
case PROTOCOL_HTTP:
case PROTOCOL_FILE:
default:
/* Let browser handle it */
gnome_url_show (url);
break;
}
g_free (parsed);
}
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 {
if (strncmp (url, "mailto:", 7) == 0)
address = (char *) (url + 7);
else
address = (char *) url;
}
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);
return TRUE;
}
static char *
e_summary_url_describe (const char *uri,
ESummary *esummary)
{
ESummaryProtocol protocol;
char *contents, *description;
protocol = get_protocol (uri);
contents = parse_uri (uri, protocol, esummary);
description = g_strdup_printf (_(descriptions[protocol]), contents);
g_free (contents);
return description;
}
void
e_summary_url_over (GtkHTML *html,
const char *uri,
ESummary *esummary)
{
char *description;
if (uri != NULL) {
description = e_summary_url_describe (uri, esummary);
e_summary_set_message (esummary, description, FALSE);
g_free (description);
} else {
e_summary_unset_message (esummary);
}
}