evolution-3.6.4/calendar/gui/dialogs/comp-editor-page.c

No issues found

  1 /*
  2  *
  3  * Evolution calendar - Base class for calendar component editor pages
  4  *
  5  * This program is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2 of the License, or (at your option) version 3.
  9  *
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with the program; if not, see <http://www.gnu.org/licenses/>
 17  *
 18  *
 19  * Authors:
 20  *		Federico Mena-Quintero <federico@ximian.com>
 21  *
 22  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 23  *
 24  */
 25 
 26 #ifdef HAVE_CONFIG_H
 27 #include <config.h>
 28 #endif
 29 
 30 #include <glib/gi18n.h>
 31 #include "comp-editor.h"
 32 #include "comp-editor-page.h"
 33 
 34 #define COMP_EDITOR_PAGE_GET_PRIVATE(obj) \
 35 	(G_TYPE_INSTANCE_GET_PRIVATE \
 36 	((obj), TYPE_COMP_EDITOR_PAGE, CompEditorPagePrivate))
 37 
 38 struct _CompEditorPagePrivate {
 39 	CompEditor *editor;  /* not referenced */
 40 	gboolean updating;
 41 };
 42 
 43 enum {
 44 	PROP_0,
 45 	PROP_EDITOR,
 46 	PROP_UPDATING
 47 };
 48 
 49 enum {
 50 	DATES_CHANGED,
 51 	LAST_SIGNAL
 52 };
 53 
 54 static guint comp_editor_page_signals[LAST_SIGNAL];
 55 
 56 G_DEFINE_TYPE (CompEditorPage, comp_editor_page, G_TYPE_OBJECT)
 57 
 58 static void
 59 comp_editor_page_set_property (GObject *object,
 60                                guint property_id,
 61                                const GValue *value,
 62                                GParamSpec *pspec)
 63 {
 64 	CompEditorPagePrivate *priv;
 65 
 66 	priv = COMP_EDITOR_PAGE_GET_PRIVATE (object);
 67 
 68 	switch (property_id) {
 69 		case PROP_EDITOR:
 70 			priv->editor = g_value_get_object (value);
 71 			return;
 72 
 73 		case PROP_UPDATING:
 74 			comp_editor_page_set_updating (
 75 				COMP_EDITOR_PAGE (object),
 76 				g_value_get_boolean (value));
 77 			return;
 78 	}
 79 
 80 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 81 }
 82 
 83 static void
 84 comp_editor_page_get_property (GObject *object,
 85                                guint property_id,
 86                                GValue *value,
 87                                GParamSpec *pspec)
 88 {
 89 	switch (property_id) {
 90 		case PROP_EDITOR:
 91 			g_value_set_object (
 92 				value, comp_editor_page_get_editor (
 93 				COMP_EDITOR_PAGE (object)));
 94 			return;
 95 
 96 		case PROP_UPDATING:
 97 			g_value_set_boolean (
 98 				value, comp_editor_page_get_updating (
 99 				COMP_EDITOR_PAGE (object)));
100 	}
101 
102 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
103 }
104 
105 static void
106 comp_editor_page_dispose (GObject *object)
107 {
108 	CompEditorPage *page;
109 
110 	g_return_if_fail (object != NULL);
111 	g_return_if_fail (IS_COMP_EDITOR_PAGE (object));
112 
113 	page = COMP_EDITOR_PAGE (object);
114 
115 	if (page->accel_group) {
116 		g_object_unref (page->accel_group);
117 		page->accel_group = NULL;
118 	}
119 
120 	/* Chain up to parent's dispose() method. */
121 	G_OBJECT_CLASS (comp_editor_page_parent_class)->dispose (object);
122 }
123 
124 static void
125 comp_editor_page_class_init (CompEditorPageClass *class)
126 {
127 	GObjectClass *object_class;
128 
129 	g_type_class_add_private (class, sizeof (CompEditorPagePrivate));
130 
131 	object_class = G_OBJECT_CLASS (class);
132 	object_class->set_property = comp_editor_page_set_property;
133 	object_class->get_property = comp_editor_page_get_property;
134 	object_class->dispose = comp_editor_page_dispose;
135 
136 	g_object_class_install_property (
137 		object_class,
138 		PROP_EDITOR,
139 		g_param_spec_object (
140 			"editor",
141 			NULL,
142 			NULL,
143 			TYPE_COMP_EDITOR,
144 			G_PARAM_READWRITE |
145 			G_PARAM_CONSTRUCT_ONLY));
146 
147 	g_object_class_install_property (
148 		object_class,
149 		PROP_UPDATING,
150 		g_param_spec_boolean (
151 			"updating",
152 			NULL,
153 			NULL,
154 			FALSE,
155 			G_PARAM_READWRITE));
156 
157 	comp_editor_page_signals[DATES_CHANGED] = g_signal_new (
158 		"dates_changed",
159 		G_TYPE_FROM_CLASS (class),
160 		G_SIGNAL_RUN_FIRST,
161 		G_STRUCT_OFFSET (CompEditorPageClass, dates_changed),
162 		NULL, NULL,
163 		g_cclosure_marshal_VOID__POINTER,
164 		G_TYPE_NONE, 1,
165 		G_TYPE_POINTER);
166 }
167 
168 static void
169 comp_editor_page_init (CompEditorPage *page)
170 {
171 	page->priv = COMP_EDITOR_PAGE_GET_PRIVATE (page);
172 }
173 
174 /**
175  * comp_editor_page_get_editor:
176  * @page: a #CompEditorPage
177  *
178  * Returns the #CompEditor to which @page belongs.
179  *
180  * Returns: the parent #CompEditor
181  **/
182 CompEditor *
183 comp_editor_page_get_editor (CompEditorPage *page)
184 {
185 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), NULL);
186 
187 	return page->priv->editor;
188 }
189 
190 /**
191  * comp_editor_page_get_widget:
192  * @page: An editor page.
193  *
194  * Queries the main widget of an editor page.
195  *
196  * Return value: The widget that is the page's upper container.  It should
197  * normally be inserted in a notebook widget.
198  **/
199 GtkWidget *
200 comp_editor_page_get_widget (CompEditorPage *page)
201 {
202 	CompEditorPageClass *class;
203 
204 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), NULL);
205 
206 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
207 	g_return_val_if_fail (class->get_widget != NULL, NULL);
208 
209 	return class->get_widget (page);
210 }
211 
212 gboolean
213 comp_editor_page_get_updating (CompEditorPage *page)
214 {
215 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
216 
217 	return page->priv->updating;
218 }
219 
220 void
221 comp_editor_page_set_updating (CompEditorPage *page,
222                                gboolean updating)
223 {
224 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
225 
226 	if (page->priv->updating == updating)
227 		return;
228 
229 	page->priv->updating = updating;
230 
231 	g_object_notify (G_OBJECT (page), "updating");
232 }
233 
234 void
235 comp_editor_page_changed (CompEditorPage *page)
236 {
237 	CompEditor *editor;
238 
239 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
240 
241 	/* Block change notifications if the page is updating.  This right
242 	 * here is why we have an 'updating' flag.  It's up to subclasses
243 	 * to set and clear it at appropriate times. */
244 	if (page->priv->updating)
245 		return;
246 
247 	editor = comp_editor_page_get_editor (page);
248 	comp_editor_set_changed (editor, TRUE);
249 }
250 
251 /**
252  * comp_editor_page_focus_main_widget:
253  * @page: An editor page.
254  *
255  * Makes an editor page focus its main widget.  This is used by the component
256  * editor when it first pops up so that it can focus the main widget in the
257  * first page.
258  **/
259 void
260 comp_editor_page_focus_main_widget (CompEditorPage *page)
261 {
262 	CompEditorPageClass *class;
263 
264 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
265 
266 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
267 	g_return_if_fail (class->focus_main_widget != NULL);
268 
269 	class->focus_main_widget (page);
270 }
271 
272 /**
273  * comp_editor_page_fill_widgets:
274  * @page: An editor page.
275  * @comp: A calendar component.
276  *
277  * Fills the widgets of an editor page with the data from a calendar component.
278  **/
279 gboolean
280 comp_editor_page_fill_widgets (CompEditorPage *page,
281                                ECalComponent *comp)
282 {
283 	CompEditorPageClass *class;
284 	gboolean success;
285 
286 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
287 	g_return_val_if_fail (E_IS_CAL_COMPONENT (comp), FALSE);
288 
289 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
290 	g_return_val_if_fail (class->fill_widgets != NULL, FALSE);
291 
292 	comp_editor_page_set_updating (page, TRUE);
293 	success = class->fill_widgets (page, comp);
294 	comp_editor_page_set_updating (page, FALSE);
295 
296 	return success;
297 }
298 
299 /**
300  * comp_editor_page_fill_component:
301  * @page: An editor page.
302  * @comp: A calendar component.
303  *
304  * Takes the data from the widgets of an editor page and sets it on a calendar
305  * component, replacing the contents of the properties that the editor page
306  * knows how to manipulate.
307  *
308  * Returns: TRUE if the component could be filled, FALSE otherwise
309  **/
310 gboolean
311 comp_editor_page_fill_component (CompEditorPage *page,
312                                  ECalComponent *comp)
313 {
314 	CompEditorPageClass *class;
315 
316 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
317 	g_return_val_if_fail (comp != NULL, FALSE);
318 
319 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
320 
321 	if (class->fill_component != NULL)
322 		return class->fill_component (page, comp);
323 
324 	return TRUE;
325 }
326 
327 /**
328  * comp_editor_page_fill_timezones:
329  * @page: An editor page.
330  * @timezones: Hash table to which timezones will be added.
331  *
332  * Fills the given hash table with all the timezones used by the dates in the
333  * specific editor page.
334  *
335  * Returns: TRUE if the timezones were added, FALSE otherwise.
336  */
337 gboolean
338 comp_editor_page_fill_timezones (CompEditorPage *page,
339                                  GHashTable *timezones)
340 {
341 	CompEditorPageClass *class;
342 
343 	g_return_val_if_fail (IS_COMP_EDITOR_PAGE (page), FALSE);
344 	g_return_val_if_fail (timezones != NULL, FALSE);
345 
346 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
347 
348 	if (class->fill_timezones != NULL)
349 		return class->fill_timezones (page, timezones);
350 
351 	return TRUE;
352 }
353 
354 /**
355  * comp_editor_page_set_dates:
356  * @page: An editor page
357  * @dates: A collection of various dates in time_t format
358  *
359  * Sets the date values for this group of widgets
360  **/
361 void
362 comp_editor_page_set_dates (CompEditorPage *page,
363                             CompEditorPageDates *dates)
364 {
365 	CompEditorPageClass *class;
366 
367 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
368 
369 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
370 
371 	if (class->set_dates != NULL)
372 		class->set_dates (page, dates);
373 }
374 
375 /**
376  * comp_editor_page_add_attendee:
377  * @page: a #CompEditorPage
378  * @attendee: an #EMeetingAttendee
379  *
380  * Adds @attendee to an internal meeting store.
381  **/
382 void
383 comp_editor_page_add_attendee (CompEditorPage *page,
384                                EMeetingAttendee *attendee)
385 {
386 	CompEditorPageClass *class;
387 
388 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
389 	g_return_if_fail (E_IS_MEETING_ATTENDEE (attendee));
390 
391 	class = COMP_EDITOR_PAGE_GET_CLASS (page);
392 	g_return_if_fail (class->add_attendee != NULL);
393 
394 	class->add_attendee (page, attendee);
395 }
396 
397 /**
398  * comp_editor_page_notify_dates_changed:
399  * @page: An editor page.
400  *
401  * Makes an editor page emit the "dates_changed" signal.  This is meant to be
402  * used only by page implementations.
403  **/
404 void
405 comp_editor_page_notify_dates_changed (CompEditorPage *page,
406                                        CompEditorPageDates *dates)
407 {
408 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
409 
410 	g_signal_emit (
411 		page,
412 		comp_editor_page_signals[DATES_CHANGED], 0,
413 		dates);
414 }
415 
416 /**
417  * comp_editor_page_display_validation_error:
418  * @page: An editor page.
419  * @msg: Error message to display.
420  * @field: Widget that caused the validation error.
421  *
422  * Displays an error message about a validation problem in the
423  * given field. Once the error message has been displayed, the
424  * focus is set to the widget that caused the validation error.
425  */
426 void
427 comp_editor_page_display_validation_error (CompEditorPage *page,
428                                            const gchar *msg,
429                                            GtkWidget *field)
430 {
431 	GtkWidget *dialog;
432 
433 	g_return_if_fail (IS_COMP_EDITOR_PAGE (page));
434 	g_return_if_fail (msg != NULL);
435 	g_return_if_fail (GTK_IS_WIDGET (field));
436 
437 	dialog = gtk_message_dialog_new (
438 		NULL, 0,
439 		GTK_MESSAGE_ERROR,
440 		GTK_BUTTONS_CLOSE,
441 		_("Validation error: %s"), msg);
442 	gtk_dialog_run (GTK_DIALOG (dialog));
443 	gtk_widget_destroy (dialog);
444 
445 	gtk_widget_grab_focus (field);
446 }