diff options
author | Milan Crha <mcrha@redhat.com> | 2012-01-03 00:07:59 +0800 |
---|---|---|
committer | Milan Crha <mcrha@redhat.com> | 2012-01-03 00:07:59 +0800 |
commit | 4dc5558f19f96858ec2a97d82b23b6401ed74a0b (patch) | |
tree | 461df0416fabcaf872539cd650b0b3e8b7366b3a /calendar/alarm-notify/alarm-notify-dialog.c | |
parent | 49ffbb973093f15e4d5e34f287445f66a8d64e6d (diff) | |
download | gsoc2013-evolution-4dc5558f19f96858ec2a97d82b23b6401ed74a0b.tar.gz gsoc2013-evolution-4dc5558f19f96858ec2a97d82b23b6401ed74a0b.tar.zst gsoc2013-evolution-4dc5558f19f96858ec2a97d82b23b6401ed74a0b.zip |
Bug #353743 - Add Print button to meeting notification dialog
Diffstat (limited to 'calendar/alarm-notify/alarm-notify-dialog.c')
-rw-r--r-- | calendar/alarm-notify/alarm-notify-dialog.c | 525 |
1 files changed, 525 insertions, 0 deletions
diff --git a/calendar/alarm-notify/alarm-notify-dialog.c b/calendar/alarm-notify/alarm-notify-dialog.c new file mode 100644 index 0000000000..c9a264d880 --- /dev/null +++ b/calendar/alarm-notify/alarm-notify-dialog.c @@ -0,0 +1,525 @@ +/* + * Evolution calendar - alarm notification dialog + * + * 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; either + * version 2 of the License, or (at your option) version 3. + * + * 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Federico Mena-Quintero <federico@ximian.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <string.h> +#include <glib/gi18n.h> +#include <libedataserver/e-time-utils.h> +#include <libecal/e-cal-time-util.h> +#include "alarm-notify-dialog.h" +#include "config-data.h" +#include "util.h" + +#include "e-util/e-util.h" +#include "e-util/e-util-private.h" +#include "misc/e-buffer-tagger.h" + +enum { + ALARM_DISPLAY_COLUMN, + ALARM_SUMMARY_COLUMN, + ALARM_DESCRIPTION_COLUMN, + ALARM_LOCATION_COLUMN, + + ALARM_START_COLUMN, + ALARM_END_COLUMN, + + ALARM_FUNCINFO_COLUMN, + + N_ALARM_COLUMNS +}; + +/* The useful contents of the alarm notify dialog */ + +typedef struct { + AlarmNotifyFunc func; + gpointer func_data; +} AlarmFuncInfo; + +typedef struct { + GtkBuilder *builder; + + GtkWidget *dialog; + GtkWidget *snooze_time_min; + GtkWidget *snooze_time_hrs; + GtkWidget *snooze_time_days; + GtkWidget *snooze_btn; + GtkWidget *edit_btn; + GtkWidget *print_btn; + GtkWidget *dismiss_btn; + GtkWidget *minutes_label; + GtkWidget *hrs_label; + GtkWidget *days_label; + GtkWidget *description; + GtkWidget *location; + GtkWidget *treeview; + + AlarmFuncInfo *cur_funcinfo; + +} AlarmNotify; + +static void tree_selection_changed_cb (GtkTreeSelection *selection, + gpointer data); +static void fill_in_labels (AlarmNotify *an, + const gchar *summary, + const gchar *description, + const gchar *location, + time_t occur_start, + time_t occur_end); + +static void edit_pressed_cb (GtkButton *button, + gpointer user_data); +static void snooze_pressed_cb (GtkButton *button, + gpointer user_data); + +static void +an_update_minutes_label (GtkSpinButton *sb, + gpointer data) +{ + AlarmNotify *an; + gint snooze_timeout_min; + + an = (AlarmNotify *) data; + + snooze_timeout_min = gtk_spin_button_get_value_as_int (sb); + gtk_label_set_text (GTK_LABEL (an->minutes_label), ngettext ("minute", "minutes", snooze_timeout_min)); +} + +static void +an_update_hrs_label (GtkSpinButton *sb, + gpointer data) +{ + AlarmNotify *an; + gint snooze_timeout_hrs; + + an = (AlarmNotify *) data; + + snooze_timeout_hrs = gtk_spin_button_get_value_as_int (sb); + gtk_label_set_text (GTK_LABEL (an->hrs_label), ngettext ("hour", "hours", snooze_timeout_hrs)); +} + +static void +an_update_days_label (GtkSpinButton *sb, + gpointer data) +{ + AlarmNotify *an; + gint snooze_timeout_days; + + an = (AlarmNotify *) data; + + snooze_timeout_days = gtk_spin_button_get_value_as_int (sb); + gtk_label_set_text (GTK_LABEL (an->days_label), ngettext ("day", "days", snooze_timeout_days)); +} + +static void +dialog_response_cb (GtkDialog *dialog, + guint response_id, + gpointer user_data) +{ + AlarmNotify *an = user_data; + GtkTreeIter iter; + GtkTreeModel *model = NULL; + AlarmFuncInfo *funcinfo = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + } + + if (!funcinfo) { + GtkTreeModel *treemodel = gtk_tree_view_get_model (GTK_TREE_VIEW (an->treeview)); + if (!gtk_tree_model_get_iter_first (treemodel, &iter)) + return; + + gtk_tree_model_get (treemodel, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + } + + g_return_if_fail (funcinfo); + + switch (response_id) { + case GTK_RESPONSE_CLOSE: + case GTK_RESPONSE_DELETE_EVENT: + (* funcinfo->func) (ALARM_NOTIFY_CLOSE, -1, funcinfo->func_data); + break; + } +} + +static void +edit_pressed_cb (GtkButton *button, + gpointer user_data) +{ + AlarmNotify *an = user_data; + AlarmFuncInfo *funcinfo = NULL; + GtkTreeIter iter; + GtkTreeModel *model = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + + g_return_if_fail (funcinfo); + + (* funcinfo->func) (ALARM_NOTIFY_EDIT, -1, funcinfo->func_data); +} + +static void +print_pressed_cb (GtkButton *button, + gpointer user_data) +{ + AlarmNotify *an = user_data; + AlarmFuncInfo *funcinfo = NULL; + GtkTreeIter iter; + GtkTreeModel *model = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + + g_return_if_fail (funcinfo); + + (* funcinfo->func) (ALARM_NOTIFY_PRINT, -1, funcinfo->func_data); +} + +#define DEFAULT_SNOOZE_MINS 5 + +static void +snooze_pressed_cb (GtkButton *button, + gpointer user_data) +{ + gint snooze_timeout; + AlarmNotify *an = user_data; + GtkTreeIter iter; + GtkTreeModel *model = NULL; + AlarmFuncInfo *funcinfo = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + + gtk_widget_grab_focus ((GtkWidget *) button); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + + g_return_if_fail (funcinfo); + + snooze_timeout = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_min)); + snooze_timeout += 60 * (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_hrs))); + snooze_timeout += 60 * 24 * (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (an->snooze_time_days))); + if (!snooze_timeout) + snooze_timeout = DEFAULT_SNOOZE_MINS; + (* funcinfo->func) (ALARM_NOTIFY_SNOOZE, snooze_timeout, funcinfo->func_data); +} + +static void +dismiss_pressed_cb (GtkButton *button, + gpointer user_data) +{ + AlarmNotify *an = user_data; + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (an->treeview)); + + g_return_if_fail (model != NULL); + + if (gtk_tree_model_iter_n_children (model, NULL) <= 1) { + gtk_dialog_response (GTK_DIALOG (an->dialog), GTK_RESPONSE_CLOSE); + } else { + GtkTreeIter iter; + AlarmFuncInfo *funcinfo = NULL; + GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &funcinfo, -1); + + g_return_if_fail (funcinfo); + + (* funcinfo->func) (ALARM_NOTIFY_DISMISS, -1, funcinfo->func_data); + } +} + +static void +dialog_destroyed_cb (GtkWidget *dialog, + gpointer user_data) +{ + AlarmNotify *an = user_data; + + g_object_unref (an->builder); + g_free (an); +} + +/** + * notified_alarms_dialog_new: + * + * Return value: a new dialog in which you can add alarm notifications + **/ +AlarmNotificationsDialog * +notified_alarms_dialog_new (void) +{ + GtkWidget *container; + GtkWidget *image; + GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); + AlarmNotificationsDialog *na = NULL; + AlarmNotify *an = g_new0 (AlarmNotify, 1); + GtkTreeViewColumn *column = NULL; + GtkTreeSelection *selection = NULL; + GtkTreeModel *model = GTK_TREE_MODEL (gtk_list_store_new ( + N_ALARM_COLUMNS, + + G_TYPE_STRING, /* Display */ + G_TYPE_STRING, /* Summary */ + G_TYPE_STRING, /* Description */ + G_TYPE_STRING, /* Location */ + + G_TYPE_POINTER, /* Start */ + G_TYPE_POINTER, /* End */ + + G_TYPE_POINTER /* FuncInfo */)); + + an->builder = gtk_builder_new (); + e_load_ui_builder_definition (an->builder, "alarm-notify.ui"); + + an->dialog = e_builder_get_widget (an->builder, "alarm-notify"); + an->snooze_time_min = e_builder_get_widget (an->builder, "snooze-time-min"); + an->minutes_label = e_builder_get_widget (an->builder, "minutes-label"); + an->snooze_time_hrs = e_builder_get_widget (an->builder, "snooze-time-hrs"); + an->hrs_label = e_builder_get_widget (an->builder, "hrs-label"); + an->snooze_time_days = e_builder_get_widget (an->builder, "snooze-time-days"); + an->days_label = e_builder_get_widget (an->builder, "days-label"); + an->description = e_builder_get_widget (an->builder, "description-label"); + an->location = e_builder_get_widget (an->builder, "location-label"); + an->treeview = e_builder_get_widget (an->builder, "appointments-treeview"); + an->snooze_btn = e_builder_get_widget (an->builder, "snooze-button"); + an->edit_btn = e_builder_get_widget (an->builder, "edit-button"); + an->print_btn = e_builder_get_widget (an->builder, "print-button"); + an->dismiss_btn = e_builder_get_widget (an->builder, "dismiss-button"); + + if (!(an->dialog && an->treeview + && an->snooze_time_min && an->snooze_time_hrs && an->snooze_time_days + && an->description && an->location && an->edit_btn && an->print_btn && an->snooze_btn && an->dismiss_btn)) { + g_warning ("alarm_notify_dialog(): Could not find all widgets in alarm-notify.ui file!"); + g_object_unref (an->builder); + g_free (an); + return NULL; + } + + e_buffer_tagger_connect (GTK_TEXT_VIEW (an->description)); + + gtk_tree_view_set_model (GTK_TREE_VIEW (an->treeview), model); + + gtk_window_set_keep_above (GTK_WINDOW (an->dialog), TRUE); + + column = gtk_tree_view_column_new_with_attributes (_("Start time"), + renderer, "text", ALARM_DISPLAY_COLUMN, NULL); + + gtk_tree_view_column_set_attributes (column, renderer, + "markup", ALARM_DISPLAY_COLUMN, NULL); + + gtk_tree_view_append_column (GTK_TREE_VIEW (an->treeview), column); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (an->treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE); + g_signal_connect ( + selection, "changed", + G_CALLBACK (tree_selection_changed_cb), an); + tree_selection_changed_cb (selection, an); + + gtk_widget_realize (an->dialog); + + container = gtk_dialog_get_action_area (GTK_DIALOG (an->dialog)); + gtk_container_set_border_width (GTK_CONTAINER (container), 12); + + container = gtk_dialog_get_content_area (GTK_DIALOG (an->dialog)); + gtk_container_set_border_width (GTK_CONTAINER (container), 0); + + image = e_builder_get_widget (an->builder, "alarm-image"); + gtk_image_set_from_icon_name ( + GTK_IMAGE (image), "stock_alarm", GTK_ICON_SIZE_DIALOG); + + g_signal_connect (an->edit_btn, "clicked", G_CALLBACK (edit_pressed_cb), an); + g_signal_connect (an->print_btn, "clicked", G_CALLBACK (print_pressed_cb), an); + g_signal_connect (an->snooze_btn, "clicked", G_CALLBACK (snooze_pressed_cb), an); + g_signal_connect (an->dismiss_btn, "clicked", G_CALLBACK (dismiss_pressed_cb), an); + g_signal_connect ( + an->dialog, "response", + G_CALLBACK (dialog_response_cb), an); + g_signal_connect ( + an->dialog, "destroy", + G_CALLBACK (dialog_destroyed_cb), an); + + if (!gtk_widget_get_realized (an->dialog)) + gtk_widget_realize (an->dialog); + + gtk_window_set_icon_name (GTK_WINDOW (an->dialog), "stock_alarm"); + + /* Set callback for updating the snooze "minutes" label */ + g_signal_connect ( + an->snooze_time_min, "value_changed", + G_CALLBACK (an_update_minutes_label), an); + + /* Set callback for updating the snooze "hours" label */ + g_signal_connect ( + an->snooze_time_hrs, "value_changed", + G_CALLBACK (an_update_hrs_label), an); + + /* Set callback for updating the snooze "days" label */ + g_signal_connect ( + an->snooze_time_days, "value_changed", + G_CALLBACK (an_update_days_label), an); + + na = g_new0 (AlarmNotificationsDialog, 1); + + na->treeview = an->treeview; + na->dialog = an->dialog; + + return na; +} + +/** + * add_alarm_to_notified_alarms_dialog: + * @na: Pointer to the dialog-info + * @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 + * @func: Function to be called when a dialog action is invoked. + * @func_data: Closure data for @func. + * + * The specified @func will be used to notify the client about result of + * the actions in the dialog. + * + * Return value: the iter in the treeview of the dialog + **/ + +GtkTreeIter +add_alarm_to_notified_alarms_dialog (AlarmNotificationsDialog *na, + time_t trigger, + time_t occur_start, + time_t occur_end, + ECalComponentVType vtype, + const gchar *summary, + const gchar *description, + const gchar *location, + AlarmNotifyFunc func, + gpointer func_data) +{ + GtkTreeIter iter; + GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW (na->treeview)); + AlarmFuncInfo *funcinfo = NULL; + gchar *to_display = NULL, *start, *end, *str_time; + icaltimezone *current_zone; + + /* Iter is not yet defined but still we return it in all the g_return_val_if_fail() calls? */ + g_return_val_if_fail (trigger != -1, iter); + + /* Only VEVENTs or VTODOs can have alarms */ + g_return_val_if_fail (vtype == E_CAL_COMPONENT_EVENT || vtype == E_CAL_COMPONENT_TODO, iter); + g_return_val_if_fail (summary != NULL, iter); + g_return_val_if_fail (description != NULL, iter); + g_return_val_if_fail (location != NULL, iter); + g_return_val_if_fail (func != NULL, iter); + + funcinfo = g_new0 (AlarmFuncInfo, 1); + funcinfo->func = func; + funcinfo->func_data = func_data; + + gtk_list_store_append (GTK_LIST_STORE (model), &iter); + + 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); + str_time = calculate_time (occur_start, occur_end); + to_display = g_markup_printf_escaped ("<big><b>%s</b></big>\n%s %s", + summary, start, str_time); + g_free (start); + g_free (end); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, + ALARM_DISPLAY_COLUMN, to_display, -1); + g_free (to_display); + g_free (str_time); + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_SUMMARY_COLUMN, summary, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_DESCRIPTION_COLUMN, description, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_LOCATION_COLUMN, location, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_START_COLUMN, occur_start, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_END_COLUMN, occur_end, -1); + gtk_list_store_set (GTK_LIST_STORE (model), &iter, ALARM_FUNCINFO_COLUMN, funcinfo, -1); + + return iter; +} + +static void +tree_selection_changed_cb (GtkTreeSelection *selection, + gpointer user_data) +{ + GtkTreeModel *model; + GtkTreeIter iter; + AlarmNotify *an = user_data; + + if (gtk_tree_selection_get_selected (selection, &model, &iter)) { + gchar *summary, *description, *location; + time_t occur_start, occur_end; + + gtk_widget_set_sensitive (an->snooze_btn, TRUE); + gtk_widget_set_sensitive (an->edit_btn, TRUE); + gtk_widget_set_sensitive (an->print_btn, TRUE); + gtk_widget_set_sensitive (an->dismiss_btn, TRUE); + gtk_tree_model_get (model, &iter, ALARM_SUMMARY_COLUMN, &summary, -1); + gtk_tree_model_get (model, &iter, ALARM_DESCRIPTION_COLUMN, &description, -1); + gtk_tree_model_get (model, &iter, ALARM_LOCATION_COLUMN, &location, -1); + gtk_tree_model_get (model, &iter, ALARM_START_COLUMN, &occur_start, -1); + gtk_tree_model_get (model, &iter, ALARM_END_COLUMN, &occur_end, -1);\ + gtk_tree_model_get (model, &iter, ALARM_FUNCINFO_COLUMN, &an->cur_funcinfo, -1); + + fill_in_labels (an, summary, description, location, occur_start, occur_end); + } else { + gtk_widget_set_sensitive (an->snooze_btn, FALSE); + gtk_widget_set_sensitive (an->edit_btn, FALSE); + gtk_widget_set_sensitive (an->print_btn, FALSE); + gtk_widget_set_sensitive (an->dismiss_btn, FALSE); + + fill_in_labels (an, "", "", "", -1, -1); + } +} + +static void +fill_in_labels (AlarmNotify *an, + const gchar *summary, + const gchar *description, + const gchar *location, + time_t occur_start, + time_t occur_end) +{ + GtkTextTagTable *table = gtk_text_tag_table_new (); + GtkTextBuffer *buffer = gtk_text_buffer_new (table); + gtk_text_buffer_set_text (buffer, description, -1); + e_buffer_tagger_disconnect (GTK_TEXT_VIEW (an->description)); + gtk_text_view_set_buffer (GTK_TEXT_VIEW (an->description), buffer); + gtk_label_set_text (GTK_LABEL (an->location), location); + e_buffer_tagger_connect (GTK_TEXT_VIEW (an->description)); + e_buffer_tagger_update_tags (GTK_TEXT_VIEW (an->description)); + g_object_unref (table); + g_object_unref (buffer); +} |