aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/alarm-notify/alarm-notify-dialog.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/alarm-notify/alarm-notify-dialog.c')
-rw-r--r--calendar/gui/alarm-notify/alarm-notify-dialog.c346
1 files changed, 276 insertions, 70 deletions
diff --git a/calendar/gui/alarm-notify/alarm-notify-dialog.c b/calendar/gui/alarm-notify/alarm-notify-dialog.c
index 77c83520d9..a84e13f66b 100644
--- a/calendar/gui/alarm-notify/alarm-notify-dialog.c
+++ b/calendar/gui/alarm-notify/alarm-notify-dialog.c
@@ -23,7 +23,6 @@
#include <stdio.h>
#include <string.h>
#include <gtk/gtkdialog.h>
-#include <gtk/gtkimage.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkspinbutton.h>
#include <gtk/gtksignal.h>
@@ -35,6 +34,8 @@
#endif
#include <glade/glade.h>
#include <e-util/e-time-utils.h>
+#include <gtkhtml/gtkhtml.h>
+#include <gtkhtml/gtkhtml-stream.h>
#include <libecal/e-cal-time-util.h>
#include "alarm-notify-dialog.h"
#include "config-data.h"
@@ -42,38 +43,246 @@
#include <e-util/e-icon-factory.h>
+GtkWidget *make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow);
+
/* The useful contents of the alarm notify dialog */
typedef struct {
GladeXML *xml;
GtkWidget *dialog;
- GtkWidget *title;
+ GtkWidget *close;
+ GtkWidget *snooze;
+ GtkWidget *edit;
GtkWidget *snooze_time;
- GtkWidget *description;
- GtkWidget *location;
- GtkWidget *start;
- GtkWidget *end;
+ GtkWidget *html;
AlarmNotifyFunc func;
gpointer func_data;
} AlarmNotify;
-enum {
- AN_RESPONSE_EDIT = 0,
- AN_RESPONSE_SNOOZE = 1
-};
-
+/* Callback used when the notify dialog is destroyed */
+static void
+dialog_destroy_cb (GtkObject *object, gpointer data)
+{
+ AlarmNotify *an;
+
+ an = data;
+ g_object_unref (an->xml);
+ g_free (an);
+}
+
+/* Delete_event handler for the alarm notify dialog */
+static gint
+delete_event_cb (GtkWidget *widget, GdkEvent *event, gpointer data)
+{
+ AlarmNotify *an;
+
+ an = data;
+ g_assert (an->func != NULL);
+
+ (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data);
+
+ gtk_widget_destroy (widget);
+ return TRUE;
+}
+
+/* Callback for the close button */
+static void
+close_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ AlarmNotify *an;
+
+ an = data;
+ g_assert (an->func != NULL);
+
+ (* an->func) (ALARM_NOTIFY_CLOSE, -1, an->func_data);
+
+ gtk_widget_destroy (an->dialog);
+}
+
+/* Callback for the snooze button */
+static void
+snooze_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ AlarmNotify *an;
+ int snooze_time;
+
+ an = data;
+ g_assert (an->func != NULL);
+
+ snooze_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time));
+ (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_time, an->func_data);
+
+ gtk_widget_destroy (an->dialog);
+}
+
+/* Callback for the edit button */
+static void
+edit_clicked_cb (GtkWidget *widget, gpointer data)
+{
+ AlarmNotify *an;
+
+ an = data;
+ g_assert (an->func != NULL);
+
+ (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data);
+
+ gtk_widget_destroy (an->dialog);
+}
+
+static void
+url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data)
+{
+
+ if (!strncmp ("file:///", url, strlen ("file:///"))) {
+ FILE *fp;
+ const char *filename = url + strlen ("file://");
+ char buf[4096];
+ size_t len;
+
+ fp = fopen (filename, "r");
+
+ if (fp == NULL) {
+ g_warning ("Error opening image: %s\n", url);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ return;
+ }
+
+ while ((len = fread (buf, 1, sizeof(buf), fp)) > 0)
+ gtk_html_stream_write (stream, buf, len);
+
+ if (feof (fp)) {
+ fclose (fp);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
+ return;
+ }
+
+ fclose (fp);
+ }
+
+ g_warning ("Error loading image");
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_ERROR);
+ return;
+}
+
+GtkWidget *
+make_html_display (gchar *widget_name, char *s1, char *s2, int scroll, int shadow)
+{
+ GtkWidget *html, *scrolled_window;
+
+ gtk_widget_push_colormap (gdk_rgb_get_colormap ());
+
+ html = gtk_html_new();
+
+ gtk_html_set_default_content_type (GTK_HTML (html),
+ "charset=utf-8");
+ gtk_html_load_empty (GTK_HTML (html));
+
+ g_signal_connect (html, "url_requested",
+ G_CALLBACK (url_requested_cb),
+ NULL);
+
+ gtk_widget_pop_colormap();
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_AUTOMATIC,
+ GTK_POLICY_AUTOMATIC);
+
+
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
+ GTK_SHADOW_IN);
+
+ gtk_widget_set_size_request (scrolled_window, 300, 200);
+
+ gtk_container_add(GTK_CONTAINER (scrolled_window), html);
+
+ gtk_widget_show_all(scrolled_window);
+
+ g_object_set_data (G_OBJECT (scrolled_window), "html", html);
+ return scrolled_window;
+}
+
+static void
+write_times (GtkHTMLStream *stream, char *start, char *end)
+{
+ if (start)
+ gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", _("Starting:"), start);
+ if (end)
+ gtk_html_stream_printf (stream, "<b>%s</b> %s<br>", _("Ending:"), end);
+
+}
+
+/* Creates a heading for the alarm notification dialog */
+static void
+write_html_heading (GtkHTMLStream *stream, const char *message,
+ ECalComponentVType vtype, time_t occur_start, time_t occur_end)
+{
+ char *start, *end;
+ char *bg_path = "file://" EVOLUTION_IMAGESDIR "/bcg.png";
+ gchar *image_path;
+ gchar *icon_path;
+ icaltimezone *current_zone;
+
+ icon_path = e_icon_factory_get_icon_filename ("stock_alarm", E_ICON_SIZE_DIALOG);
+ image_path = g_strdup_printf ("file://%s", icon_path);
+ g_free (icon_path);
+
+ /* Stringize the times */
+
+ current_zone = config_data_get_timezone ();
+
+ start = timet_to_str_with_zone (occur_start, current_zone);
+ end = timet_to_str_with_zone (occur_end, current_zone);
+
+ /* Write the header */
+
+ gtk_html_stream_printf (stream,
+ "<HTML><BODY background=\"%s\">"
+ "<TABLE WIDTH=\"100%%\">"
+ "<TR>"
+ "<TD><IMG SRC=\"%s\" ALIGN=\"top\" BORDER=\"0\"></TD>"
+ "<TD><H1>%s</H1></TD>"
+ "</TR>"
+ "</TABLE>",
+ bg_path,
+ image_path,
+ _("Evolution Alarm"));
+
+ gtk_html_stream_printf (stream, "<br><br><font size=\"+2\">%s</font><br><br>", message);
+
+ /* Write the times */
+
+ switch (vtype) {
+ case E_CAL_COMPONENT_EVENT:
+ write_times (stream, start, end);
+ break;
+
+ case E_CAL_COMPONENT_TODO:
+ write_times (stream, start, end);
+ break;
+
+ default:
+ /* Only VEVENTs and VTODOs can have alarms */
+ g_assert_not_reached ();
+ break;
+ }
+
+ g_free (start);
+ g_free (end);
+ g_free (image_path);
+}
+
/**
* alarm_notify_dialog:
* @trigger: Trigger time for the alarm.
* @occur_start: Start of occurrence time for the event.
* @occur_end: End of occurrence time for the event.
* @vtype: Type of the component which corresponds to the alarm.
- * @summary: Short summary of the appointment
- * @description: Long description of the appointment
- * @location: Location of the appointment
+ * @message; Message to display in the dialog; usually comes from the component.
* @func: Function to be called when a dialog action is invoked.
* @func_data: Closure data for @func.
*
@@ -82,30 +291,23 @@ enum {
*
* Return value: a pointer to the dialog structure if successful or NULL if an error occurs.
**/
-void
+gpointer
alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end,
- ECalComponentVType vtype, const char *summary,
- const char *description, const char *location,
+ ECalComponentVType vtype, const char *message,
AlarmNotifyFunc func, gpointer func_data)
{
AlarmNotify *an;
- GtkWidget *image;
+ GtkHTMLStream *stream;
icaltimezone *current_zone;
- char *title;
- char *start, *end;
- char *icon_path;
+ char *buf, *title;
GList *icon_list;
- int snooze_timeout;
- g_return_if_fail (trigger != -1);
+ g_return_val_if_fail (trigger != -1, NULL);
/* Only VEVENTs or VTODOs can have alarms */
- g_return_if_fail (vtype == E_CAL_COMPONENT_EVENT
- || vtype == E_CAL_COMPONENT_TODO);
- g_return_if_fail (summary != NULL);
- g_return_if_fail (description != NULL);
- g_return_if_fail (location != NULL);
- g_return_if_fail (func != NULL);
+ g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, NULL);
+ g_return_val_if_fail (message != NULL, NULL);
+ g_return_val_if_fail (func != NULL, NULL);
an = g_new0 (AlarmNotify, 1);
@@ -116,56 +318,65 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end,
if (!an->xml) {
g_message ("alarm_notify_dialog(): Could not load the Glade XML file!");
g_free (an);
- return;
+ return NULL;
}
an->dialog = glade_xml_get_widget (an->xml, "alarm-notify");
- an->title = glade_xml_get_widget (an->xml, "title-label");
+ an->close = glade_xml_get_widget (an->xml, "close");
+ an->snooze = glade_xml_get_widget (an->xml, "snooze");
+ an->edit = glade_xml_get_widget (an->xml, "edit");
an->snooze_time = glade_xml_get_widget (an->xml, "snooze-time");
- an->description = glade_xml_get_widget (an->xml, "description-label");
- an->location = glade_xml_get_widget (an->xml, "location-label");
- an->start = glade_xml_get_widget (an->xml, "start-label");
- an->end = glade_xml_get_widget (an->xml, "end-label");
+ an->html = g_object_get_data (G_OBJECT (glade_xml_get_widget (an->xml, "frame")), "html");
- if (!(an->dialog && an->title && an->snooze_time
- && an->description && an->location && an->start && an->end)) {
+ if (!(an->dialog && an->close && an->snooze && an->edit
+ && an->snooze_time)) {
g_message ("alarm_notify_dialog(): Could not find all widgets in Glade file!");
g_object_unref (an->xml);
g_free (an);
- return;
+ return NULL;
}
gtk_widget_realize (an->dialog);
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (an->dialog)->vbox), 0);
gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (an->dialog)->action_area), 12);
- image = glade_xml_get_widget (an->xml, "alarm-image");
- icon_path = e_icon_factory_get_icon_filename ("stock_alarm", E_ICON_SIZE_DIALOG);
- gtk_image_set_from_file (GTK_IMAGE (image), icon_path);
- g_free (icon_path);
+ g_signal_connect (G_OBJECT (an->dialog), "destroy",
+ G_CALLBACK (dialog_destroy_cb),
+ an);
/* Title */
- gtk_window_set_title (GTK_WINDOW (an->dialog), summary);
+ current_zone = config_data_get_timezone ();
- /* Set the widget contents */
+ buf = timet_to_str_with_zone (trigger, current_zone);
+ title = g_strdup_printf (_("Alarm on %s"), buf);
+ g_free (buf);
- title = g_strdup_printf ("<big><b>%s</b></big>", summary);
- gtk_label_set_markup (GTK_LABEL (an->title), title);
+ gtk_window_set_title (GTK_WINDOW (an->dialog), title);
g_free (title);
- gtk_label_set_text (GTK_LABEL (an->description), description);
- gtk_label_set_text (GTK_LABEL (an->location), location);
+ /* html heading */
+ stream = gtk_html_begin (GTK_HTML (an->html));
+ write_html_heading (stream, message, vtype, occur_start, occur_end);
+ gtk_html_stream_close (stream, GTK_HTML_STREAM_OK);
- /* Stringize the times */
+ /* Connect actions */
- current_zone = config_data_get_timezone ();
+ g_signal_connect (an->dialog, "delete_event",
+ G_CALLBACK (delete_event_cb),
+ an);
- start = timet_to_str_with_zone (occur_start, current_zone);
- gtk_label_set_text (GTK_LABEL (an->start), start);
+ g_signal_connect (an->close, "clicked",
+ G_CALLBACK (close_clicked_cb),
+ an);
- end = timet_to_str_with_zone (occur_end, current_zone);
- gtk_label_set_text (GTK_LABEL (an->end), end);
+ g_signal_connect (an->snooze, "clicked",
+ G_CALLBACK (snooze_clicked_cb),
+ an);
+
+ g_signal_connect (an->edit, "clicked",
+ G_CALLBACK (edit_clicked_cb),
+ an);
/* Run! */
@@ -179,20 +390,15 @@ alarm_notify_dialog (time_t trigger, time_t occur_start, time_t occur_end,
g_list_free (icon_list);
}
- switch (gtk_dialog_run (GTK_DIALOG (an->dialog))) {
- case AN_RESPONSE_EDIT:
- (* an->func) (ALARM_NOTIFY_EDIT, -1, an->func_data);
- break;
- case AN_RESPONSE_SNOOZE:
- snooze_timeout = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time));
- (* an->func) (ALARM_NOTIFY_SNOOZE, snooze_timeout, an->func_data);
- break;
- case GTK_RESPONSE_CLOSE:
- case GTK_RESPONSE_DELETE_EVENT:
- break;
- }
- gtk_widget_destroy (an->dialog);
-
- g_object_unref (an->xml);
- g_free (an);
+ gtk_widget_show (an->dialog);
+ return an;
+}
+
+void
+alarm_notify_dialog_disable_buttons (gpointer dialog)
+{
+ AlarmNotify *an = dialog;
+
+ gtk_widget_set_sensitive (an->snooze, FALSE);
+ gtk_widget_set_sensitive (an->edit, FALSE);
}