evolution-3.6.4/calendar/gui/dialogs/alarm-list-dialog.c

No issues found

  1 /*
  2  * Evolution calendar - Alarm page of the calendar component dialogs
  3  *
  4  * This program is free software; you can redistribute it and/or
  5  * modify it under the terms of the GNU Lesser General Public
  6  * License as published by the Free Software Foundation; either
  7  * version 2 of the License, or (at your option) version 3.
  8  *
  9  * This program is distributed in the hope that it will be useful,
 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 12  * Lesser General Public License for more details.
 13  *
 14  * You should have received a copy of the GNU Lesser General Public
 15  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 16  *
 17  *
 18  * Authors:
 19  *		Federico Mena-Quintero <federico@ximian.com>
 20  *      Miguel de Icaza <miguel@ximian.com>
 21  *      Seth Alves <alves@hungry.com>
 22  *      JP Rosevear <jpr@ximian.com>
 23  *      Hans Petter Jansson <hpj@ximian.com>
 24  *
 25  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 26  *
 27  */
 28 
 29 #ifdef HAVE_CONFIG_H
 30 #include <config.h>
 31 #endif
 32 
 33 #include <string.h>
 34 #include <gtk/gtk.h>
 35 #include <glib/gi18n.h>
 36 
 37 #include "e-util/e-util.h"
 38 #include "e-util/e-util-private.h"
 39 #include "alarm-dialog.h"
 40 #include "alarm-list-dialog.h"
 41 
 42 typedef struct {
 43 	GtkBuilder *builder;
 44 	ESourceRegistry *registry;
 45 
 46 	/* The client */
 47 	ECalClient *cal_client;
 48 
 49 	/* The list store */
 50 	EAlarmList *list_store;
 51 
 52 	/* Toplevel */
 53 	GtkWidget *toplevel;
 54 
 55 	GtkWidget *list;
 56 	GtkWidget *add;
 57 	GtkWidget *edit;
 58 	GtkWidget *delete;
 59 	GtkWidget *box;
 60 
 61 } Dialog;
 62 
 63 /* Gets the widgets from the XML file and returns TRUE if they are all available. */
 64 static gboolean
 65 get_widgets (Dialog *dialog)
 66 {
 67 #define GW(name) e_builder_get_widget (dialog->builder, name)
 68 
 69 	dialog->toplevel = GW ("alarm-list-dialog");
 70 	if (!dialog->toplevel)
 71 		return FALSE;
 72 
 73 	dialog->box = GW ("vbox53");
 74 	dialog->list = GW ("list");
 75 	dialog->add = GW ("add");
 76 	dialog->edit = GW ("edit");
 77 	dialog->delete = GW ("delete");
 78 
 79 #undef GW
 80 
 81 	return (dialog->list
 82 		&& dialog->add
 83 		&& dialog->edit
 84 		&& dialog->delete);
 85 }
 86 
 87 static void
 88 sensitize_buttons (Dialog *dialog)
 89 {
 90 	GtkTreeSelection *selection;
 91 	GtkTreeIter iter;
 92 	gboolean have_selected, read_only = FALSE;
 93 
 94 	read_only = e_client_is_readonly (E_CLIENT (dialog->cal_client));
 95 
 96 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
 97 	have_selected = gtk_tree_selection_get_selected (selection, NULL, &iter);
 98 
 99 	if ((e_cal_client_check_one_alarm_only (dialog->cal_client) &&have_selected) || read_only)
100 		gtk_widget_set_sensitive (dialog->add, FALSE);
101 	else
102 		gtk_widget_set_sensitive (dialog->add, TRUE);
103 	gtk_widget_set_sensitive (dialog->delete, have_selected && !read_only);
104 	gtk_widget_set_sensitive (dialog->edit, have_selected && !read_only);
105 }
106 
107 /* Callback used for the "add reminder" button */
108 static void
109 add_clicked_cb (GtkButton *button,
110                 gpointer data)
111 {
112 	Dialog *dialog = data;
113 	ECalComponentAlarm *alarm;
114 	GtkTreeView *view;
115 	GtkTreeIter iter;
116 	icalcomponent *icalcomp;
117 	icalproperty *icalprop;
118 
119 	view = GTK_TREE_VIEW (dialog->list);
120 
121 	alarm = e_cal_component_alarm_new ();
122 
123 	icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
124 	icalprop = icalproperty_new_x ("1");
125 	icalproperty_set_x_name (icalprop, "X-EVOLUTION-NEEDS-DESCRIPTION");
126 	icalcomponent_add_property (icalcomp, icalprop);
127 
128 	if (alarm_dialog_run (dialog->toplevel, dialog->registry, dialog->cal_client, alarm)) {
129 		e_alarm_list_append (dialog->list_store, &iter, alarm);
130 		gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter);
131 	} else {
132 		e_cal_component_alarm_free (alarm);
133 	}
134 
135 	sensitize_buttons (dialog);
136 }
137 
138 /* Callback used for the "edit reminder" button */
139 static void
140 edit_clicked_cb (GtkButton *button,
141                  gpointer data)
142 {
143 	Dialog *dialog = data;
144 	GtkTreeSelection *selection;
145 	GtkTreeIter iter;
146 	GtkTreePath *path;
147 	ECalComponentAlarm *alarm;
148 	GtkTreeView *view;
149 
150 	view = GTK_TREE_VIEW (dialog->list);
151 
152 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
153 	if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
154 		g_warning ("Could not get a selection to edit.");
155 		return;
156 	}
157 
158 	alarm = (ECalComponentAlarm *) e_alarm_list_get_alarm (dialog->list_store, &iter);
159 	path = gtk_tree_model_get_path (GTK_TREE_MODEL (dialog->list_store), &iter);
160 
161 	if (alarm_dialog_run (dialog->toplevel, dialog->registry, dialog->cal_client, alarm)) {
162 		gtk_tree_selection_select_iter (gtk_tree_view_get_selection (view), &iter);
163 		gtk_tree_model_row_changed (GTK_TREE_MODEL (dialog->list_store), path, &iter);
164 	}
165 }
166 
167 /* Callback used for the "delete reminder" button */
168 static void
169 delete_clicked_cb (GtkButton *button,
170                    gpointer data)
171 {
172 	Dialog *dialog = data;
173 	GtkTreeSelection *selection;
174 	GtkTreeModel *model;
175 	GtkTreeIter iter;
176 	GtkTreePath *path;
177 	gboolean valid_iter;
178 
179 	selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list));
180 	if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) {
181 		g_warning ("Could not get a selection to delete.");
182 		return;
183 	}
184 
185 	model = GTK_TREE_MODEL (dialog->list_store);
186 	path = gtk_tree_model_get_path (model, &iter);
187 	e_alarm_list_remove (dialog->list_store, &iter);
188 
189 	/* Select closest item after removal */
190 	valid_iter = gtk_tree_model_get_iter (model, &iter, path);
191 	if (!valid_iter) {
192 		gtk_tree_path_prev (path);
193 		valid_iter = gtk_tree_model_get_iter (model, &iter, path);
194 	}
195 
196 	if (valid_iter)
197 		gtk_tree_selection_select_iter (selection, &iter);
198 
199 	sensitize_buttons (dialog);
200 
201 	gtk_tree_path_free (path);
202 }
203 
204 static void
205 selection_changed_cb (GtkTreeSelection *selection,
206                       gpointer data)
207 {
208 	Dialog *dialog = data;
209 
210 	sensitize_buttons (dialog);
211 }
212 
213 void
214 alarm_list_dialog_set_client (GtkWidget *dlg_box,
215                               ECalClient *cal_client)
216 {
217 	Dialog *dialog;
218 
219 	if (!dlg_box) return;
220 
221 	dialog = g_object_get_data (G_OBJECT (dlg_box), "dialog");
222 	if (dialog) {
223 		dialog->cal_client = cal_client;
224 		sensitize_buttons (dialog);
225 	}
226 }
227 
228 /* Hooks the widget signals */
229 static void
230 init_widgets (Dialog *dialog)
231 {
232 	GtkTreeViewColumn *column;
233 	GtkCellRenderer *cell_renderer;
234 
235 	/* View */
236 	gtk_tree_view_set_model (
237 		GTK_TREE_VIEW (dialog->list),
238 		GTK_TREE_MODEL (dialog->list_store));
239 
240 	column = gtk_tree_view_column_new ();
241 	gtk_tree_view_column_set_title (column, _("Action/Trigger"));
242 	cell_renderer = GTK_CELL_RENDERER (gtk_cell_renderer_text_new ());
243 	gtk_tree_view_column_pack_start (column, cell_renderer, TRUE);
244 	gtk_tree_view_column_add_attribute (
245 		column, cell_renderer,
246 		"text", E_ALARM_LIST_COLUMN_DESCRIPTION);
247 	gtk_tree_view_append_column (GTK_TREE_VIEW (dialog->list), column);
248 
249 	/* Reminder buttons */
250 	g_signal_connect (
251 		dialog->add, "clicked",
252 		G_CALLBACK (add_clicked_cb), dialog);
253 	g_signal_connect (
254 		dialog->delete, "clicked",
255 		G_CALLBACK (delete_clicked_cb), dialog);
256 	g_signal_connect (
257 		dialog->edit, "clicked",
258 		G_CALLBACK (edit_clicked_cb), dialog);
259 
260 	g_signal_connect (
261 		gtk_tree_view_get_selection (GTK_TREE_VIEW (dialog->list)),
262 		"changed", G_CALLBACK (selection_changed_cb), dialog);
263 }
264 
265 gboolean
266 alarm_list_dialog_run (GtkWidget *parent,
267                        ESourceRegistry *registry,
268                        ECalClient *cal_client,
269                        EAlarmList *list_store)
270 {
271 	Dialog dialog;
272 	GtkWidget *container;
273 	gint response_id;
274 
275 	g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), FALSE);
276 
277 	dialog.registry = registry;
278 	dialog.cal_client = cal_client;
279 	dialog.list_store = list_store;
280 
281 	dialog.builder = gtk_builder_new ();
282 	e_load_ui_builder_definition (dialog.builder, "alarm-list-dialog.ui");
283 
284 	if (!get_widgets (&dialog)) {
285 		g_object_unref (dialog.builder);
286 		return FALSE;
287 	}
288 
289 	init_widgets (&dialog);
290 
291 	sensitize_buttons (&dialog);
292 
293 	gtk_widget_ensure_style (dialog.toplevel);
294 
295 	container = gtk_dialog_get_action_area (GTK_DIALOG (dialog.toplevel));
296 	gtk_container_set_border_width (GTK_CONTAINER (container), 12);
297 
298 	container = gtk_dialog_get_content_area (GTK_DIALOG (dialog.toplevel));
299 	gtk_container_set_border_width (GTK_CONTAINER (container), 0);
300 
301 	gtk_window_set_icon_name (
302 		GTK_WINDOW (dialog.toplevel), "x-office-calendar");
303 
304 	gtk_window_set_transient_for (
305 		GTK_WINDOW (dialog.toplevel),
306 		GTK_WINDOW (parent));
307 
308 	response_id = gtk_dialog_run (GTK_DIALOG (dialog.toplevel));
309 	gtk_widget_hide (dialog.toplevel);
310 
311 	gtk_widget_destroy (dialog.toplevel);
312 	g_object_unref (dialog.builder);
313 
314 	return response_id == GTK_RESPONSE_OK ? TRUE : FALSE;
315 }
316 
317 GtkWidget *
318 alarm_list_dialog_peek (ESourceRegistry *registry,
319                         ECalClient *cal_client,
320                         EAlarmList *list_store)
321 {
322 	Dialog *dialog;
323 
324 	dialog = (Dialog *) g_new (Dialog, 1);
325 	dialog->registry = registry;
326 	dialog->cal_client = cal_client;
327 	dialog->list_store = list_store;
328 
329 	dialog->builder = gtk_builder_new ();
330 	e_load_ui_builder_definition (dialog->builder, "alarm-list-dialog.ui");
331 
332 	if (!get_widgets (dialog)) {
333 		g_object_unref (dialog->builder);
334 		return NULL;
335 	}
336 
337 	init_widgets (dialog);
338 
339 	sensitize_buttons (dialog);
340 
341 	g_object_unref (dialog->builder);
342 
343 	/* Free the other stuff when the parent really gets destroyed. */
344 	g_object_set_data_full (
345 		G_OBJECT (dialog->box),
346 		"toplevel", dialog->toplevel,
347 		(GDestroyNotify) gtk_widget_destroy);
348 	g_object_set_data_full (
349 		G_OBJECT (dialog->box), "dialog",
350 		dialog, (GDestroyNotify) g_free);
351 
352 	return dialog->box;
353 }