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
568 lines
13 KiB
C
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);
|
|
}
|
|
}
|