/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ /* e-tasks.c * * Copyright (C) 2001-2003 Ximian, Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public * License as published by the Free Software Foundation. * * 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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * Authors: Federico Mena Quintero * Damon Chaplin * Rodrigo Moya */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include #include #include #include #include #include #include "calendar-config.h" #include "e-cal-component-preview.h" struct _ECalComponentPreviewPrivate { GtkWidget *html; icaltimezone *zone; }; G_DEFINE_TYPE (ECalComponentPreview, e_cal_component_preview, GTK_TYPE_TABLE) static void on_link_clicked (GtkHTML *html, const char *url, gpointer data) { GError *err = NULL; gnome_url_show (url, &err); if (err) { g_warning ("gnome_url_show: %s", err->message); g_error_free (err); } } static void on_url_cb (GtkHTML *html, const char *url, gpointer data) { #if 0 char *msg; ECalComponentPreview *preview = data; if (url && *url) { msg = g_strdup_printf (_("Click to open %s"), url); e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), msg); g_free (msg); } else e_calendar_table_set_status_message (e_tasks_get_calendar_table (tasks), NULL); #endif } /* Callback used when the user selects a URL in the HTML widget */ static void url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) { if (!strncmp ("file:///", url, strlen ("file:///"))) { GnomeVFSHandle *handle; GnomeVFSResult result; char buffer[4096]; if (gnome_vfs_open (&handle, url, GNOME_VFS_OPEN_READ) == GNOME_VFS_OK) { do { GnomeVFSFileSize bread; result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bread); if (result == GNOME_VFS_OK) gtk_html_stream_write (stream, buffer, bread); } while (result == GNOME_VFS_OK); gnome_vfs_close (handle); if (result == GNOME_VFS_ERROR_EOF) gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); } } } /* Converts a time_t to a string, relative to the specified timezone */ static char * timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone) { struct icaltimetype itt; icaltimezone *zone; struct tm tm; char buf[256]; if (dt->tzid) { /* If we can't find the zone, we'll guess its "local" */ if (!e_cal_get_timezone (ecal, dt->tzid, &zone, NULL)) zone = NULL; } else if (dt->value->is_utc) { zone = icaltimezone_get_utc_timezone (); } else { zone = NULL; } itt = *dt->value; if (zone) icaltimezone_convert_time (&itt, zone, default_zone); tm = icaltimetype_to_tm (&itt); e_time_format_date_and_time (&tm, calendar_config_get_24_hour_format (), FALSE, FALSE, buf, sizeof (buf)); return g_locale_to_utf8 (buf, -1, NULL, NULL, NULL); } static void write_html (GtkHTMLStream *stream, ECal *ecal, ECalComponent *comp, icaltimezone *default_zone) { ECalComponentText text; ECalComponentDateTime dt; gchar *str; GSList *l; icalproperty_status status; const char *location; int *priority_value; g_return_if_fail (E_IS_CAL_COMPONENT (comp)); /* write document header */ e_cal_component_get_summary (comp, &text); if (text.value) gtk_html_stream_printf (stream, "

%s

", text.value); else gtk_html_stream_printf (stream, "

%s

", _("Untitled")); /* write icons for the categories */ e_cal_component_get_categories_list (comp, &l); if (l) { GSList *node; for (node = l; node != NULL; node = node->next) { const char *icon_file; icon_file = e_categories_get_icon_file_for ((const char *) node->data); if (icon_file) { gchar *icon_file_uri = g_filename_to_uri (icon_file, NULL, NULL); gtk_html_stream_printf (stream, "\"%s\"", (const char *) node->data, icon_file_uri); g_free (icon_file_uri); } } e_cal_component_free_categories_list (l); gtk_html_stream_printf (stream, "


"); } /* Start table */ gtk_html_stream_printf (stream, "" ""); /* write location */ e_cal_component_get_location (comp, &location); if (location) gtk_html_stream_printf (stream, "", _("Summary:"), text.value); /* write start date */ e_cal_component_get_dtstart (comp, &dt); if (dt.value != NULL) { str = timet_to_str_with_zone (&dt, ecal, default_zone); gtk_html_stream_printf (stream, "", _("Start Date:"), str); g_free (str); } e_cal_component_free_datetime (&dt); /* write end date */ e_cal_component_get_dtend (comp, &dt); if (dt.value != NULL) { str = timet_to_str_with_zone (&dt, ecal, default_zone); gtk_html_stream_printf (stream, "", _("Start Date:"), str); g_free (str); } e_cal_component_free_datetime (&dt); /* write Due Date */ e_cal_component_get_due (comp, &dt); if (dt.value != NULL) { str = timet_to_str_with_zone (&dt, ecal, default_zone); gtk_html_stream_printf (stream, "", _("Due Date:"), str); g_free (str); } e_cal_component_free_datetime (&dt); /* write status */ gtk_html_stream_printf (stream, "", _("Status:")); e_cal_component_get_status (comp, &status); switch (status) { case ICAL_STATUS_INPROCESS : str = g_strdup (_("In Progress")); break; case ICAL_STATUS_COMPLETED : str = g_strdup (_("Completed")); break; case ICAL_STATUS_CANCELLED : str = g_strdup (_("Canceled")); break; case ICAL_STATUS_NONE : default : str = g_strdup (_("Not Started")); break; } gtk_html_stream_printf (stream, "", str); g_free (str); /* write priority */ e_cal_component_get_priority (comp, &priority_value); if (priority_value && *priority_value != 0) { gtk_html_stream_printf (stream, "", _("Priority:")); if (*priority_value <= 4) str = g_strdup (_("High")); else if (*priority_value == 5) str = g_strdup (_("Normal")); else str = g_strdup (_("Low")); gtk_html_stream_printf (stream, "", str); g_free (str); e_cal_component_free_priority (priority_value); } /* write description and URL */ gtk_html_stream_printf (stream, ""); e_cal_component_get_description_list (comp, &l); if (l) { GSList *node; gtk_html_stream_printf (stream, "", _("Description:")); gtk_html_stream_printf (stream, ""); e_cal_component_free_text_list (l); } /* URL */ e_cal_component_get_url (comp, (const char **) &str); if (str) { gtk_html_stream_printf (stream, "", _("Web Page:")); gtk_html_stream_printf (stream, "", str, str); } gtk_html_stream_printf (stream, "
%s%s
%s%s
%s%s
%s%s
%s%s
%s%s

%s
");

		for (node = l; node != NULL; node = node->next) {
			gint i, len;
			GString *string = g_string_new (NULL);;

			text = * (ECalComponentText *) node->data;
			len =  text.value ? strlen (text.value) : 0;
			for (i = 0; i ", 4);
				else if (text.value[i] == '<')
					string = g_string_append_len (string, "<", 4);
				else if (text.value[i] == '>')
					string = g_string_append_len (string, ">", 4);
				else
					string = g_string_append_c (string, text.value[i]);
			}

			gtk_html_stream_printf (stream, "%s", string->str);
			g_string_free (string, TRUE);
		}

		gtk_html_stream_printf (stream, "
%s%s
"); /* close document */ gtk_html_stream_printf (stream, ""); } static void e_cal_component_preview_init (ECalComponentPreview *preview) { ECalComponentPreviewPrivate *priv; GtkWidget *scroll; priv = g_new0 (ECalComponentPreviewPrivate, 1); preview->priv = priv; priv->html = gtk_html_new (); gtk_html_set_default_content_type (GTK_HTML (priv->html), "charset=utf-8"); gtk_html_load_empty (GTK_HTML (priv->html)); g_signal_connect (G_OBJECT (priv->html), "url_requested", G_CALLBACK (url_requested_cb), NULL); g_signal_connect (G_OBJECT (priv->html), "link_clicked", G_CALLBACK (on_link_clicked), preview); g_signal_connect (G_OBJECT (priv->html), "on_url", G_CALLBACK (on_url_cb), preview); scroll = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroll), GTK_SHADOW_IN); gtk_container_add (GTK_CONTAINER (scroll), priv->html); gtk_container_add (GTK_CONTAINER (preview), scroll); gtk_widget_show_all (scroll); priv->zone = icaltimezone_get_utc_timezone (); } static void e_cal_component_preview_destroy (GtkObject *object) { ECalComponentPreview *preview; ECalComponentPreviewPrivate *priv; g_return_if_fail (object != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (object)); preview = E_CAL_COMPONENT_PREVIEW (object); priv = preview->priv; if (priv) { g_free (priv); preview->priv = NULL; } if (GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy) (* GTK_OBJECT_CLASS (e_cal_component_preview_parent_class)->destroy) (object); } static void e_cal_component_preview_class_init (ECalComponentPreviewClass *klass) { GtkObjectClass *object_class; object_class = (GtkObjectClass *) klass; object_class->destroy = e_cal_component_preview_destroy; } GtkWidget * e_cal_component_preview_new (void) { ECalComponentPreview *preview; preview = g_object_new (e_cal_component_preview_get_type (), NULL); return GTK_WIDGET (preview); } icaltimezone * e_cal_component_preview_get_default_timezone (ECalComponentPreview *preview) { ECalComponentPreviewPrivate *priv; g_return_val_if_fail (preview != NULL, NULL); g_return_val_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview), NULL); priv = preview->priv; return priv->zone; } void e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview, icaltimezone *zone) { ECalComponentPreviewPrivate *priv; g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); g_return_if_fail (zone != NULL); priv = preview->priv; priv->zone = zone; } void e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp) { ECalComponentPreviewPrivate *priv; GtkHTMLStream *stream; g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); g_return_if_fail (comp != NULL); g_return_if_fail (E_IS_CAL_COMPONENT (comp)); priv = preview->priv; stream = gtk_html_begin (GTK_HTML (priv->html)); write_html (stream, ecal, comp, priv->zone); gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); } void e_cal_component_preview_clear (ECalComponentPreview *preview) { ECalComponentPreviewPrivate *priv; g_return_if_fail (preview != NULL); g_return_if_fail (E_IS_CAL_COMPONENT_PREVIEW (preview)); priv = preview->priv; gtk_html_load_empty (GTK_HTML (priv->html)); }