/*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program; if not, see .
*
*
* Authors:
* JP Rosevear
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "e-conflict-search-selector.h"
#include "e-source-conflict-search.h"
#include "itip-view.h"
#include "e-mail-part-itip.h"
#define d(x)
#define MEETING_ICON "stock_new-meeting"
#define ITIP_VIEW_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
((obj), ITIP_TYPE_VIEW, ItipViewPrivate))
G_DEFINE_TYPE (ItipView, itip_view, G_TYPE_OBJECT)
typedef struct {
ItipViewInfoItemType type;
gchar *message;
guint id;
} ItipViewInfoItem;
struct _ItipViewPrivate {
EClientCache *client_cache;
gchar *extension_name;
ESourceRegistry *registry;
gulong source_added_handler_id;
gulong source_removed_handler_id;
ItipViewMode mode;
ECalClientSourceType type;
gchar *sender;
gchar *organizer;
gchar *organizer_sentby;
gchar *delegator;
gchar *attendee;
gchar *attendee_sentby;
gchar *proxy;
gchar *summary;
gchar *location;
gchar *status;
gchar *comment;
struct tm *start_tm;
gint start_tm_is_date : 1;
gchar *start_label;
const gchar *start_header;
struct tm *end_tm;
gint end_tm_is_date : 1;
gchar *end_label;
const gchar *end_header;
GSList *upper_info_items;
GSList *lower_info_items;
guint next_info_item_id;
gchar *description;
gint buttons_sensitive : 1;
gboolean is_recur_set;
gint needs_decline : 1;
WebKitDOMDocument *dom_document;
EMailPartItip *itip_part;
gchar *error;
};
#define TEXT_ROW_SENDER "text_row_sender"
#define TABLE_ROW_SUMMARY "table_row_summary"
#define TABLE_ROW_LOCATION "table_row_location"
#define TABLE_ROW_START_DATE "table_row_start_time"
#define TABLE_ROW_END_DATE "table_row_end_time"
#define TABLE_ROW_STATUS "table_row_status"
#define TABLE_ROW_COMMENT "table_row_comment"
#define TABLE_ROW_DESCRIPTION "table_row_description"
#define TABLE_ROW_RSVP_COMMENT "table_row_rsvp_comment"
#define TABLE_ROW_ESCB "table_row_escb"
#define TABLE_ROW_BUTTONS "table_row_buttons"
#define TABLE_ROW_ESCB_LABEL "table_row_escb_label"
#define TABLE_BUTTONS "table_buttons"
#define SELECT_ESOURCE "select_esource"
#define TEXTAREA_RSVP_COMMENT "textarea_rsvp_comment"
#define CHECKBOX_RSVP "checkbox_rsvp"
#define CHECKBOX_RECUR "checkbox_recur"
#define CHECKBOX_UPDATE "checkbox_update"
#define CHECKBOX_FREE_TIME "checkbox_free_time"
#define CHECKBOX_KEEP_ALARM "checkbox_keep_alarm"
#define CHECKBOX_INHERIT_ALARM "checkbox_inherit_alarm"
#define BUTTON_OPEN_CALENDAR "button_open_calendar"
#define BUTTON_DECLINE "button_decline"
#define BUTTON_DECLINE_ALL "button_decline_all"
#define BUTTON_ACCEPT "button_accept"
#define BUTTON_ACCEPT_ALL "button_accept_all"
#define BUTTON_TENTATIVE "button_tentative"
#define BUTTON_TENTATIVE_ALL "button_tentative_all"
#define BUTTON_SEND_INFORMATION "button_send_information"
#define BUTTON_UPDATE "button_update"
#define BUTTON_UPDATE_ATTENDEE_STATUS "button_update_attendee_status"
#define BUTTON_SAVE "button_save"
#define TABLE_UPPER_ITIP_INFO "table_upper_itip_info"
#define TABLE_LOWER_ITIP_INFO "table_lower_itip_info"
#define DIV_ITIP_CONTENT "div_itip_content"
#define DIV_ITIP_ERROR "div_itip_error"
enum {
PROP_0,
PROP_CLIENT_CACHE,
PROP_EXTENSION_NAME
};
enum {
SOURCE_SELECTED,
RESPONSE,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
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,
gboolean is_date,
gchar *buffer,
gint buffer_size)
{
gchar *format;
struct tm tomorrow_tm, week_tm;
/* Calculate a normalized "tomorrow" */
tomorrow_tm = *current_tm;
/* Don't need this if date is in the past. Also, year assumption won't fail. */
if (date_tm->tm_year >= current_tm->tm_year && tomorrow_tm.tm_mday == time_days_in_month (current_tm->tm_year + 1900, current_tm->tm_mon)) {
tomorrow_tm.tm_mday = 1;
if (tomorrow_tm.tm_mon == 11) {
tomorrow_tm.tm_mon = 1;
tomorrow_tm.tm_year++;
} else {
tomorrow_tm.tm_mon++;
}
} else {
tomorrow_tm.tm_mday++;
}
/* Calculate a normalized "next seven days" */
week_tm = *current_tm;
/* Don't need this if date is in the past. Also, year assumption won't fail. */
if (date_tm->tm_year >= current_tm->tm_year && week_tm.tm_mday + 6 > time_days_in_month (date_tm->tm_year + 1900, date_tm->tm_mon)) {
week_tm.tm_mday = (week_tm.tm_mday + 6) % time_days_in_month (date_tm->tm_year + 1900, date_tm->tm_mon);
if (week_tm.tm_mon == 11) {
week_tm.tm_mon = 1;
week_tm.tm_year++;
} else {
week_tm.tm_mon++;
}
} else {
week_tm.tm_mday += 6;
}
/* 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 (is_date || (!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 time,
* in 24-hour format, without seconds. */
format = _("Today %H:%M");
else
/* strftime format of 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 time,
* in 12-hour format, without seconds. */
format = _("Today %l:%M %p");
else
/* strftime format of a time,
* in 12-hour format. */
format = _("Today %l:%M:%S %p");
}
/* Tomorrow */
} else if (date_tm->tm_mday == tomorrow_tm.tm_mday &&
date_tm->tm_mon == tomorrow_tm.tm_mon &&
date_tm->tm_year == tomorrow_tm.tm_year) {
if (is_date || (!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 = _("Tomorrow");
} else if (use_24_hour_format) {
if (!show_zero_seconds && date_tm->tm_sec == 0)
/* strftime format of a time,
* in 24-hour format, without seconds. */
format = _("Tomorrow %H:%M");
else
/* strftime format of a time,
* in 24-hour format. */
format = _("Tomorrow %H:%M:%S");
} else {
if (!show_zero_seconds && date_tm->tm_sec == 0)
/* strftime format of a time,
* in 12-hour format, without seconds. */
format = _("Tomorrow %l:%M %p");
else
/* strftime format of a time,
* in 12-hour format. */
format = _("Tomorrow %l:%M:%S %p");
}
/* Within 6 days */
} else if ((date_tm->tm_year >= current_tm->tm_year &&
date_tm->tm_mon >= current_tm->tm_mon &&
date_tm->tm_mday >= current_tm->tm_mday) &&
(date_tm->tm_year < week_tm.tm_year ||
(date_tm->tm_year == week_tm.tm_year &&
date_tm->tm_mon < week_tm.tm_mon) ||
(date_tm->tm_year == week_tm.tm_year &&
date_tm->tm_mon == week_tm.tm_mon &&
date_tm->tm_mday < week_tm.tm_mday))) {
if (is_date || (!show_midnight && date_tm->tm_hour == 0
&& date_tm->tm_min == 0 && date_tm->tm_sec == 0)) {
/* strftime format of a weekday. */
format = _("%A");
} else if (use_24_hour_format) {
if (!show_zero_seconds && date_tm->tm_sec == 0)
/* strftime format of a weekday and a
* time, in 24-hour format, without seconds. */
format = _("%A %H:%M");
else
/* strftime format of a weekday 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 and a
* time, in 12-hour format, without seconds. */
format = _("%A %l:%M %p");
else
/* strftime format of a weekday and a
* time, in 12-hour format. */
format = _("%A %l:%M:%S %p");
}
/* This Year */
} else if (date_tm->tm_year == current_tm->tm_year) {
if (is_date || (!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
* without a year. */
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
* without a year and a time,
* in 24-hour format, without seconds. */
format = _("%A, %B %e %H:%M");
else
/* strftime format of a weekday, a date without a year
* 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 without a year
* and a time, in 12-hour format, without seconds. */
format = _("%A, %B %e %l:%M %p");
else
/* strftime format of a weekday, a date without a year
* and a time, in 12-hour format. */
format = _("%A, %B %e %l:%M:%S %p");
}
} else {
if (is_date || (!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 %l:%M %p");
else
/* strftime format of a weekday, a date and a
* time, in 12-hour format. */
format = _("%A, %B %e, %Y %l:%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_fix_am_pm (buffer, buffer_size, format, date_tm) == 0)
buffer[0] = '\0';
}
static gchar *
dupe_first_bold (const gchar *format,
const gchar *first,
const gchar *second)
{
gchar *f, *s, *res;
f = g_markup_printf_escaped ("%s", first ? first : "");
s = g_markup_escape_text (second ? second : "", -1);
res = g_strdup_printf (format, f, s);
g_free (f);
g_free (s);
return res;
}
static gchar *
set_calendar_sender_text (ItipView *view)
{
ItipViewPrivate *priv;
const gchar *organizer, *attendee;
gchar *sender = NULL;
gchar *on_behalf_of = NULL;
priv = view->priv;
organizer = priv->organizer ? priv->organizer : _("An unknown person");
attendee = priv->attendee ? priv->attendee : _("An unknown person");
/* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */
if (priv->organizer && priv->proxy)
on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL);
else if (priv->attendee && priv->proxy)
on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL);
switch (priv->mode) {
case ITIP_VIEW_MODE_PUBLISH:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has published the following meeting information:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has published the following meeting information:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_REQUEST:
/* FIXME is the delegator stuff handled correctly here? */
if (priv->delegator) {
sender = dupe_first_bold (_("%s has delegated the following meeting to you:"), priv->delegator, NULL);
} else {
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s requests your presence at the following meeting:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s requests your presence at the following meeting:"), organizer, NULL);
}
break;
case ITIP_VIEW_MODE_ADD:
/* FIXME What text for this? */
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s wishes to add to an existing meeting:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s wishes to add to an existing meeting:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_REFRESH:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s wishes to receive the latest information for the following meeting:"), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s wishes to receive the latest information for the following meeting:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_REPLY:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s has sent back the following meeting response:"), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s has sent back the following meeting response:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_CANCEL:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has canceled the following meeting:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has canceled the following meeting:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_COUNTER:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s has proposed the following meeting changes."), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s has proposed the following meeting changes:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_DECLINECOUNTER:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has declined the following meeting changes:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has declined the following meeting changes:"), organizer, NULL);
break;
default:
break;
}
if (sender && on_behalf_of) {
gchar *tmp;
tmp = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
g_free (sender);
sender = tmp;
}
g_free (on_behalf_of);
return sender;
}
static gchar *
set_tasklist_sender_text (ItipView *view)
{
ItipViewPrivate *priv;
const gchar *organizer, *attendee;
gchar *sender = NULL;
gchar *on_behalf_of = NULL;
priv = view->priv;
organizer = priv->organizer ? priv->organizer : _("An unknown person");
attendee = priv->attendee ? priv->attendee : _("An unknown person");
/* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */
if (priv->organizer && priv->proxy)
on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL);
else if (priv->attendee && priv->proxy)
on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL);
switch (priv->mode) {
case ITIP_VIEW_MODE_PUBLISH:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has published the following task:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has published the following task:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_REQUEST:
/* FIXME is the delegator stuff handled correctly here? */
if (priv->delegator) {
sender = dupe_first_bold (_("%s requests the assignment of %s to the following task:"), organizer, priv->delegator);
} else {
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has assigned you a task:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has assigned you a task:"), organizer, NULL);
}
break;
case ITIP_VIEW_MODE_ADD:
/* FIXME What text for this? */
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s wishes to add to an existing task:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s wishes to add to an existing task:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_REFRESH:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s wishes to receive the latest information for the following assigned task:"), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s wishes to receive the latest information for the following assigned task:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_REPLY:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s has sent back the following assigned task response:"), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s has sent back the following assigned task response:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_CANCEL:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has canceled the following assigned task:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has canceled the following assigned task:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_COUNTER:
if (priv->attendee_sentby)
sender = dupe_first_bold (_("%s through %s has proposed the following task assignment changes:"), attendee, priv->attendee_sentby);
else
sender = dupe_first_bold (_("%s has proposed the following task assignment changes:"), attendee, NULL);
break;
case ITIP_VIEW_MODE_DECLINECOUNTER:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has declined the following assigned task:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has declined the following assigned task:"), organizer, NULL);
break;
default:
break;
}
if (sender && on_behalf_of) {
gchar *tmp;
tmp = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
g_free (sender);
sender = tmp;
}
g_free (on_behalf_of);
return sender;
}
static gchar *
set_journal_sender_text (ItipView *view)
{
ItipViewPrivate *priv;
const gchar *organizer;
gchar *sender = NULL;
gchar *on_behalf_of = NULL;
priv = view->priv;
organizer = priv->organizer ? priv->organizer : _("An unknown person");
/* The current account ID (i.e. the delegatee) is receiving a copy of the request/response. Here we ask the delegatee to respond/accept on behalf of the delegator. */
if (priv->organizer && priv->proxy)
on_behalf_of = dupe_first_bold (_("Please respond on behalf of %s"), priv->proxy, NULL);
else if (priv->attendee && priv->proxy)
on_behalf_of = dupe_first_bold (_("Received on behalf of %s"), priv->proxy, NULL);
switch (priv->mode) {
case ITIP_VIEW_MODE_PUBLISH:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has published the following memo:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has published the following memo:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_ADD:
/* FIXME What text for this? */
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s wishes to add to an existing memo:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s wishes to add to an existing memo:"), organizer, NULL);
break;
case ITIP_VIEW_MODE_CANCEL:
if (priv->organizer_sentby)
sender = dupe_first_bold (_("%s through %s has canceled the following shared memo:"), organizer, priv->organizer_sentby);
else
sender = dupe_first_bold (_("%s has canceled the following shared memo:"), organizer, NULL);
break;
default:
break;
}
if (sender && on_behalf_of)
sender = g_strjoin (NULL, sender, "\n", on_behalf_of, NULL);
g_free (on_behalf_of);
return sender;
}
static void
set_sender_text (ItipView *view)
{
ItipViewPrivate *priv;
priv = view->priv;
if (priv->sender)
g_free (priv->sender);
switch (priv->type) {
case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
priv->sender = set_calendar_sender_text (view);
break;
case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
priv->sender = set_tasklist_sender_text (view);
break;
case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
priv->sender = set_journal_sender_text (view);
break;
default:
priv->sender = NULL;
break;
}
if (priv->sender && priv->dom_document) {
WebKitDOMElement *div;
div = webkit_dom_document_get_element_by_id (
priv->dom_document, TEXT_ROW_SENDER);
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (div), priv->sender, NULL);
}
}
static void
update_start_end_times (ItipView *view)
{
ItipViewPrivate *priv;
WebKitDOMElement *row, *col;
gchar buffer[256];
time_t now;
struct tm *now_tm;
priv = view->priv;
now = time (NULL);
now_tm = localtime (&now);
if (priv->start_label)
g_free (priv->start_label);
if (priv->end_label)
g_free (priv->end_label);
#define is_same(_member) (priv->start_tm->_member == priv->end_tm->_member)
if (priv->start_tm && priv->end_tm && priv->start_tm_is_date && priv->end_tm_is_date
&& is_same (tm_mday) && is_same (tm_mon) && is_same (tm_year)) {
/* it's an all day event in one particular day */
format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256);
priv->start_label = g_strdup (buffer);
priv->start_header = _("All day:");
priv->end_header = NULL;
priv->end_label = NULL;
} else {
if (priv->start_tm) {
format_date_and_time_x (priv->start_tm, now_tm, FALSE, TRUE, FALSE, priv->start_tm_is_date, buffer, 256);
priv->start_header = priv->start_tm_is_date ? _("Start day:") : _("Start time:");
priv->start_label = g_strdup (buffer);
} else {
priv->start_header = NULL;
priv->start_label = NULL;
}
if (priv->end_tm) {
format_date_and_time_x (priv->end_tm, now_tm, FALSE, TRUE, FALSE, priv->end_tm_is_date, buffer, 256);
priv->end_header = priv->end_tm_is_date ? _("End day:") : _("End time:");
priv->end_label = g_strdup (buffer);
} else {
priv->end_header = NULL;
priv->end_label = NULL;
}
}
#undef is_same
if (priv->dom_document) {
row = webkit_dom_document_get_element_by_id (
priv->dom_document, TABLE_ROW_START_DATE);
if (priv->start_header && priv->start_label) {
webkit_dom_html_element_set_hidden (
WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
col = webkit_dom_element_get_first_element_child (row);
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (col), priv->start_header, NULL);
col = webkit_dom_element_get_last_element_child (row);
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (col), priv->start_label, NULL);
} else {
webkit_dom_html_element_set_hidden (
WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
}
row = webkit_dom_document_get_element_by_id (
priv->dom_document, TABLE_ROW_END_DATE);
if (priv->end_header && priv->end_label) {
webkit_dom_html_element_set_hidden (
WEBKIT_DOM_HTML_ELEMENT (row), FALSE);
col = webkit_dom_element_get_first_element_child (row);
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (col), priv->end_header, NULL);
col = webkit_dom_element_get_last_element_child (row);
webkit_dom_html_element_set_inner_html (
WEBKIT_DOM_HTML_ELEMENT (col), priv->end_label, NULL);
} else {
webkit_dom_html_element_set_hidden (
WEBKIT_DOM_HTML_ELEMENT (row), TRUE);
}
}
}
static void
button_clicked_cb (WebKitDOMElement *element,
WebKitDOMEvent *event,
gpointer data)
{
ItipViewResponse response;
gchar *responseStr;
responseStr = webkit_dom_html_button_element_get_value (
WEBKIT_DOM_HTML_BUTTON_ELEMENT (element));
response = atoi (responseStr);
g_signal_emit (data, signals[RESPONSE], 0, response);
}
static void
rsvp_toggled_cb (WebKitDOMHTMLInputElement *input,
WebKitDOMEvent *event,
gpointer data)
{
WebKitDOMElement *el;
ItipView *view = data;
gboolean rsvp;
rsvp = webkit_dom_html_input_element_get_checked (input);
el = webkit_dom_document_get_element_by_id (
view->priv->dom_document, TEXTAREA_RSVP_COMMENT);
webkit_dom_html_text_area_element_set_disabled (
WEBKIT_DOM_HTML_TEXT_AREA_ELEMENT (el), !rsvp);
}
static void
recur_toggled_cb (WebKitDOMHTMLInputElement *input,
WebKitDOMEvent *event,
gpointer data)
{
ItipView *view = data;
itip_view_set_mode (view, view->priv->mode);
}
/*
alarm_check_toggled_cb
check1 was changed, so make the second available based on state of the first check.
*/
static void
alarm_check_toggled_cb (WebKitDOMHTMLInputElement *check1,
WebKitDOMEvent *event,
ItipView *view)
{
WebKitDOMElement *check2;
gchar *id;
#if WEBKIT_CHECK_VERSION(2,2,0) /* XXX should really be (2,1,something) */
id = webkit_dom_element_get_id (
WEBKIT_DOM_ELEMENT (check1));
#else
id = webkit_dom_html_element_get_id (
WEBKIT_DOM_HTML_ELEMENT (check1));
#endif
if (g_strcmp0 (id, CHECKBOX_INHERIT_ALARM)) {
check2 = webkit_dom_document_get_element_by_id (
view->priv->dom_document, CHECKBOX_KEEP_ALARM);
} else {
check2 = webkit_dom_document_get_element_by_id (
view->priv->dom_document, CHECKBOX_INHERIT_ALARM);
}
g_free (id);
webkit_dom_html_input_element_set_disabled (
WEBKIT_DOM_HTML_INPUT_ELEMENT (check2),
(webkit_dom_html_element_get_hidden (
WEBKIT_DOM_HTML_ELEMENT (check1)) &&
webkit_dom_html_input_element_get_checked (check1)));
}
static void
source_changed_cb (WebKitDOMElement *select,
WebKitDOMEvent *event,
ItipView *view)
{
ESource *source;
source = itip_view_ref_source (view);
d (printf ("Source changed to '%s'\n", e_source_get_display_name (source)));
g_signal_emit (view, signals[SOURCE_SELECTED], 0, source);
g_object_unref (source);
}
static void
append_checkbox_table_row (GString *buffer,
const gchar *name,
const gchar *label)
{
gchar *access_key, *html_label;
html_label = e_mail_formatter_parse_html_mnemonics (label, &access_key);
g_string_append_printf (
buffer,
"
\n");
/* The first section listing the sender */
/* FIXME What to do if the send and organizer do not match */
g_string_append (
buffer,
"\n");
g_string_append (buffer, "\n");
/* Elementary event information */
g_string_append (
buffer,
"