From 2698f79304b6e643123c5765754169e92831b73f Mon Sep 17 00:00:00 2001 From: JP Rosevear Date: Wed, 22 Dec 2004 16:22:23 +0000 Subject: Initial checkin of new itip formatter 2004-12-22 JP Rosevear * Initial checkin of new itip formatter svn path=/trunk/; revision=28184 --- plugins/itip-formatter/itip-view.c | 720 +++++++++++++++++++++++++++++++++++++ 1 file changed, 720 insertions(+) create mode 100644 plugins/itip-formatter/itip-view.c (limited to 'plugins/itip-formatter/itip-view.c') diff --git a/plugins/itip-formatter/itip-view.c b/plugins/itip-formatter/itip-view.c new file mode 100644 index 0000000000..e58506605b --- /dev/null +++ b/plugins/itip-formatter/itip-view.c @@ -0,0 +1,720 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: JP Rosevear + * + * Copyright 2004 Novell, 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 Street #330, Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "itip-view.h" + +#define MEETING_ICON "stock_new-meeting" + +G_DEFINE_TYPE (ItipView, itip_view, GTK_TYPE_HBOX); + +struct _ItipViewPrivate { + ItipViewMode mode; + + GtkWidget *sender_label; + char *organizer; + char *sentby; + char *delegator; + char *attendee; + + GtkWidget *summary_label; + char *summary; + + GtkWidget *location_header; + GtkWidget *location_label; + char *location; + + GtkWidget *start_header; + GtkWidget *start_label; + struct tm *start_tm; + + GtkWidget *end_header; + GtkWidget *end_label; + struct tm *end_tm; +}; + +static void +format_date_and_time_x (struct tm *date_tm, + struct tm *current_tm, + gboolean use_24_hour_format, + gboolean show_midnight, + gboolean show_zero_seconds, + char *buffer, + int buffer_size) +{ + char *format; + + /* Today */ + if (date_tm->tm_mday == current_tm->tm_mday && + date_tm->tm_mon == current_tm->tm_mon && + date_tm->tm_year == current_tm->tm_year) { + if (!show_midnight && date_tm->tm_hour == 0 + && date_tm->tm_min == 0 && date_tm->tm_sec == 0) { + /* strftime format of a weekday and a date. */ + format = _("Today"); + } else if (use_24_hour_format) { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 24-hour format, without seconds. */ + format = _("Today %H:%M"); + else + /* strftime format of a weekday, a date and a + time, in 24-hour format. */ + format = _("Today %H:%M:%S"); + } else { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 12-hour format, without seconds. */ + format = _("Today %I:%M %p"); + else + /* strftime format of a weekday, a date and a + time, in 12-hour format. */ + format = _("Today %I:%M:%S %p"); + } + + /* Tomorrow */ + } else if (date_tm->tm_year == current_tm->tm_year) { + if (!show_midnight && date_tm->tm_hour == 0 + && date_tm->tm_min == 0 && date_tm->tm_sec == 0) { + /* strftime format of a weekday and a date. */ + format = _("%A, %B %e"); + } else if (use_24_hour_format) { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 24-hour format, without seconds. */ + format = _("%A, %B %e %H:%M"); + else + /* strftime format of a weekday, a date and a + time, in 24-hour format. */ + format = _("%A, %B %e %H:%M:%S"); + } else { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 12-hour format, without seconds. */ + format = _("%A, %B %e %I:%M %p"); + else + /* strftime format of a weekday, a date and a + time, in 12-hour format. */ + format = _("%A, %B %e %I:%M:%S %p"); + } + + /* Within 7 days */ + } else if (date_tm->tm_year == current_tm->tm_year) { + if (!show_midnight && date_tm->tm_hour == 0 + && date_tm->tm_min == 0 && date_tm->tm_sec == 0) { + /* strftime format of a weekday and a date. */ + format = _("%A"); + } else if (use_24_hour_format) { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 24-hour format, without seconds. */ + format = _("%A %H:%M"); + else + /* strftime format of a weekday, a date and a + time, in 24-hour format. */ + format = _("%A %H:%M:%S"); + } else { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 12-hour format, without seconds. */ + format = _("%A %I:%M %p"); + else + /* strftime format of a weekday, a date and a + time, in 12-hour format. */ + format = _("%A %I:%M:%S %p"); + } + + /* This Year */ + } else if (date_tm->tm_year == current_tm->tm_year) { + if (!show_midnight && date_tm->tm_hour == 0 + && date_tm->tm_min == 0 && date_tm->tm_sec == 0) { + /* strftime format of a weekday and a date. */ + format = _("%A, %B %e"); + } else if (use_24_hour_format) { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 24-hour format, without seconds. */ + format = _("%A, %B %e %H:%M"); + else + /* strftime format of a weekday, a date and a + time, in 24-hour format. */ + format = _("%A, %B %e %H:%M:%S"); + } else { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 12-hour format, without seconds. */ + format = _("%A, %B %e %I:%M %p"); + else + /* strftime format of a weekday, a date and a + time, in 12-hour format. */ + format = _("%A, %B %e %I:%M:%S %p"); + } + } else { + if (!show_midnight && date_tm->tm_hour == 0 + && date_tm->tm_min == 0 && date_tm->tm_sec == 0) { + /* strftime format of a weekday and a date. */ + format = _("%A, %B %e, %Y"); + } else if (use_24_hour_format) { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 24-hour format, without seconds. */ + format = _("%A, %B %e, %Y %H:%M"); + else + /* strftime format of a weekday, a date and a + time, in 24-hour format. */ + format = _("%A, %B %e, %Y %H:%M:%S"); + } else { + if (!show_zero_seconds && date_tm->tm_sec == 0) + /* strftime format of a weekday, a date and a + time, in 12-hour format, without seconds. */ + format = _("%A, %B %e, %Y %I:%M %p"); + else + /* strftime format of a weekday, a date and a + time, in 12-hour format. */ + format = _("%A, %B %e, %Y %I:%M:%S %p"); + } + } + + /* strftime returns 0 if the string doesn't fit, and leaves the buffer + undefined, so we set it to the empty string in that case. */ + if (e_utf8_strftime (buffer, buffer_size, format, date_tm) == 0) + buffer[0] = '\0'; +} + +static void +set_sender_text (ItipView *view) +{ + ItipViewPrivate *priv; + const char *organizer, *attendee; + char *sender = NULL; + + priv = view->priv; + + organizer = priv->organizer ? priv->organizer : _("An unknown person"); + attendee = priv->attendee ? priv->attendee : _("An unknown person"); + + switch (priv->mode) { + case ITIP_VIEW_MODE_PUBLISH: + if (priv->sentby) + sender = g_strdup_printf (_("%s through %s has published meeting information."), organizer, priv->sentby); + else + sender = g_strdup_printf (_("%s has published meeting information."), organizer); + break; + case ITIP_VIEW_MODE_REQUEST: + /* FIXME is the delegator stuff handled correctly here? */ + if (priv->delegator) { + sender = g_strdup_printf (_("%s requests the presence of %s at a meeting."), organizer, priv->delegator); + } else { + if (priv->sentby) + sender = g_strdup_printf (_("%s through %s requests your presence at a meeting."), organizer, priv->sentby); + else + sender = g_strdup_printf (_("%s requests your presence at a meeting."), organizer); + } + break; + case ITIP_VIEW_MODE_ADD: + if (priv->sentby) + sender = g_strdup_printf (_("%s through %s wishes to add to an existing meeting."), organizer, priv->sentby); + else + sender = g_strdup_printf (_("%s wishes to add to an existing meeting."), organizer); + break; + case ITIP_VIEW_MODE_REFRESH: + sender = g_strdup_printf (_("%s wishes to receive the latest meeting information."), attendee); + break; + case ITIP_VIEW_MODE_REPLY: + sender = g_strdup_printf (_("%s has replied to a meeting invitation."), attendee); + break; + case ITIP_VIEW_MODE_CANCEL: + if (priv->sentby) + sender = g_strdup_printf (_("%s through %s has cancelled a meeting."), organizer, priv->sentby); + else + sender = g_strdup_printf (_("%s has cancelled a meeting."), organizer); + break; + default: + break; + } + + gtk_label_set_text (GTK_LABEL (priv->sender_label), sender); + gtk_label_set_use_markup (GTK_LABEL (priv->sender_label), TRUE); + + g_free (sender); +} + +static void +set_summary_text (ItipView *view) +{ + ItipViewPrivate *priv; + char *summary = NULL; + + priv = view->priv; + + summary = g_strdup_printf ("%s", priv->summary); + + gtk_label_set_text (GTK_LABEL (priv->summary_label), summary); + gtk_label_set_use_markup (GTK_LABEL (priv->summary_label), TRUE); + + g_free (summary); +} + +static void +set_location_text (ItipView *view) +{ + ItipViewPrivate *priv; + + priv = view->priv; + + gtk_label_set_text (GTK_LABEL (priv->location_label), priv->location); + + priv->location ? gtk_widget_show (priv->location_header) : gtk_widget_hide (priv->location_header); + priv->location ? gtk_widget_show (priv->location_label) : gtk_widget_hide (priv->location_label); +} + +static void +set_start_text (ItipView *view) +{ + ItipViewPrivate *priv; + char buffer[256]; + time_t now; + struct tm *now_tm; + + priv = view->priv; + + now = time (NULL); + now_tm = localtime (&now); + + if (priv->start_tm) { + format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, buffer, 256); + gtk_label_set_text (GTK_LABEL (priv->start_label), buffer); + } else { + gtk_label_set_text (GTK_LABEL (priv->start_label), NULL); + } + + priv->start_tm ? gtk_widget_show (priv->start_header) : gtk_widget_hide (priv->start_header); + priv->start_tm ? gtk_widget_show (priv->start_label) : gtk_widget_hide (priv->start_label); +} + +static void +set_end_text (ItipView *view) +{ + ItipViewPrivate *priv; + char buffer[256]; + time_t now; + struct tm *now_tm; + + priv = view->priv; + + now = time (NULL); + now_tm = localtime (&now); + + if (priv->end_tm) { + format_date_and_time_x (priv->end_tm, now_tm, FALSE, TRUE, FALSE, buffer, 256); + gtk_label_set_text (GTK_LABEL (priv->end_label), buffer); + } else { + gtk_label_set_text (GTK_LABEL (priv->end_label), NULL); + } + + priv->end_tm ? gtk_widget_show (priv->end_header) : gtk_widget_hide (priv->end_header); + priv->end_tm ? gtk_widget_show (priv->end_label) : gtk_widget_hide (priv->end_label); +} + +static void +itip_view_destroy (GtkObject *object) +{ + ItipView *view = ITIP_VIEW (object); + ItipViewPrivate *priv = view->priv; + + if (priv) { + g_free (priv->organizer); + g_free (priv->sentby); + g_free (priv->delegator); + g_free (priv->attendee); + g_free (priv->location); + g_free (priv->start_tm); + g_free (priv->end_tm); + + g_free (priv); + view->priv = NULL; + } + + GTK_OBJECT_CLASS (itip_view_parent_class)->destroy (object); +} + +static void +itip_view_class_init (ItipViewClass *klass) +{ + GObjectClass *object_class; + GtkObjectClass *gtkobject_class; + + object_class = G_OBJECT_CLASS (klass); + gtkobject_class = GTK_OBJECT_CLASS (klass); + + gtkobject_class->destroy = itip_view_destroy; +} + +static void +itip_view_init (ItipView *view) +{ + ItipViewPrivate *priv; + GtkWidget *icon, *vbox, *separator, *table; + + priv = g_new0 (ItipViewPrivate, 1); + view->priv = priv; + + priv->mode = ITIP_VIEW_MODE_NONE; + + /* The icon on the LHS */ + icon = e_icon_factory_get_image (MEETING_ICON, E_ICON_SIZE_LARGE_TOOLBAR); + gtk_misc_set_alignment (GTK_MISC (icon), 0, 0); + gtk_widget_show (icon); + + gtk_box_pack_start (GTK_BOX (view), icon, FALSE, FALSE, 6); + + /* The RHS */ + vbox = gtk_vbox_new (FALSE, 0); + gtk_widget_show (vbox); + gtk_box_pack_start (GTK_BOX (view), vbox, FALSE, FALSE, 6); + + /* The first section listing the sender */ + /* FIXME What to do if the send and organizer do not match */ + priv->sender_label = gtk_label_new (NULL); + gtk_widget_show (priv->sender_label); + gtk_box_pack_start (GTK_BOX (vbox), priv->sender_label, FALSE, FALSE, 6); + + separator = gtk_hseparator_new (); + gtk_widget_show (separator); + gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 6); + + /* A table with information on the meeting and any extra info/warnings */ + table = gtk_table_new (3, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 6); + gtk_widget_show (table); + gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 6); + + /* Summary */ + priv->summary_label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (priv->summary_label), 0, 0.5); + gtk_widget_show (priv->summary_label); + gtk_table_attach (GTK_TABLE (table), priv->summary_label, 0, 2, 0, 1, GTK_FILL, 0, 0, 0); + + /* Location */ + priv->location_header = gtk_label_new (_("Location:")); + priv->location_label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (priv->location_label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), priv->location_header, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), priv->location_label, 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + + priv->start_header = gtk_label_new (_("Starts:")); + priv->start_label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (priv->start_header), 0, 0.5); + gtk_misc_set_alignment (GTK_MISC (priv->start_label), 0, 0.5); + gtk_widget_show (priv->start_header); + gtk_table_attach (GTK_TABLE (table), priv->start_header, 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), priv->start_label, 1, 2, 2, 3, GTK_FILL, 0, 0, 0); + + priv->end_header = gtk_label_new (_("Ends:")); + priv->end_label = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (priv->end_header), 0, 0.5); + gtk_misc_set_alignment (GTK_MISC (priv->end_label), 0, 0.5); + gtk_table_attach (GTK_TABLE (table), priv->end_header, 0, 1, 3, 4, GTK_FILL, 0, 0, 0); + gtk_table_attach (GTK_TABLE (table), priv->end_label, 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + + /* The buttons for actions */ +} + +GtkWidget * +itip_view_new (void) +{ + ItipView *itip_view = g_object_new (ITIP_TYPE_VIEW, "homogeneous", FALSE, "spacing", 6, NULL); + + return GTK_WIDGET (itip_view); +} + +void +itip_view_set_mode (ItipView *view, ItipViewMode mode) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + priv->mode = mode; + + set_sender_text (view); +} + +ItipViewMode +itip_view_get_mode (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, ITIP_VIEW_MODE_NONE); + g_return_val_if_fail (ITIP_IS_VIEW (view), ITIP_VIEW_MODE_NONE); + + priv = view->priv; + + return priv->mode; +} + +void +itip_view_set_organizer (ItipView *view, const char *organizer) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->organizer) + g_free (priv->organizer); + + priv->organizer = g_strdup (organizer); + + set_sender_text (view); +} + +const char * +itip_view_get_organizer (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->organizer; +} + +void +itip_view_set_sentby (ItipView *view, const char *sentby) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->sentby) + g_free (priv->sentby); + + priv->sentby = g_strdup (sentby); + + set_sender_text (view); +} + +const char * +itip_view_get_sentby (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->sentby; +} + +void +itip_view_set_attendee (ItipView *view, const char *attendee) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->attendee) + g_free (priv->attendee); + + priv->attendee = g_strdup (attendee); + + set_sender_text (view); +} + +const char * +itip_view_get_attendee (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->attendee; +} + +void +itip_view_set_summary (ItipView *view, const char *summary) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->summary) + g_free (priv->summary); + + priv->summary = g_strdup (summary); + + set_summary_text (view); +} + +const char * +itip_view_get_summary (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->summary; +} + +void +itip_view_set_location (ItipView *view, const char *location) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->location) + g_free (priv->location); + + priv->location = g_strdup (location); + + set_location_text (view); +} + +const char * +itip_view_get_location (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->location; +} + +void +itip_view_set_start (ItipView *view, struct tm *start) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->start_tm && !start) { + g_free (priv->start_tm); + priv->start_tm = NULL; + } else if (start) { + if (!priv->start_tm) + priv->start_tm = g_new0 (struct tm, 1); + + *priv->start_tm = *start; + } + + set_start_text (view); +} + +const struct tm * +itip_view_get_start (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->start_tm; +} + +void +itip_view_set_end (ItipView *view, struct tm *end) +{ + ItipViewPrivate *priv; + + g_return_if_fail (view != NULL); + g_return_if_fail (ITIP_IS_VIEW (view)); + + priv = view->priv; + + if (priv->end_tm && !end) { + g_free (priv->end_tm); + priv->end_tm = NULL; + } else if (end) { + if (!priv->end_tm) + priv->end_tm = g_new0 (struct tm, 1); + + *priv->end_tm = *end; + } + + set_end_text (view); +} + +const struct tm * +itip_view_get_end (ItipView *view) +{ + ItipViewPrivate *priv; + + g_return_val_if_fail (view != NULL, NULL); + g_return_val_if_fail (ITIP_IS_VIEW (view), NULL); + + priv = view->priv; + + return priv->end_tm; +} -- cgit v1.2.3