evolution-3.6.4/calendar/gui/dialogs/goto-dialog.c

No issues found

  1 /*
  2  * Go to date dialog for Evolution
  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 <federico@ximian.com>
 20  *      JP Rosevear <jpr@ximian.com>
 21  *
 22  * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 23  * Copyright (C) 1998 Red Hat, Inc.
 24  *
 25  */
 26 
 27 #ifdef HAVE_CONFIG_H
 28 #include <config.h>
 29 #endif
 30 
 31 #include <gtk/gtk.h>
 32 
 33 #include "goto-dialog.h"
 34 
 35 #include "e-util/e-util.h"
 36 #include "e-util/e-util-private.h"
 37 #include "calendar/gui/calendar-config.h"
 38 #include "calendar/gui/tag-calendar.h"
 39 
 40 typedef struct
 41 {
 42 	GtkBuilder *builder;
 43 	GtkWidget *dialog;
 44 
 45 	GtkWidget *month_combobox;
 46 	GtkWidget *year;
 47 	ECalendar *ecal;
 48 	GtkWidget *vbox;
 49 
 50 	GnomeCalendar *gcal;
 51 	gint year_val;
 52 	gint month_val;
 53 	gint day_val;
 54 
 55 	GCancellable *cancellable;
 56 } GoToDialog;
 57 
 58 static GoToDialog *dlg = NULL;
 59 
 60 /* Callback used when the year adjustment is changed */
 61 static void
 62 year_changed (GtkAdjustment *adj,
 63               gpointer data)
 64 {
 65 	GtkSpinButton *spin_button;
 66 	GoToDialog *dlg = data;
 67 
 68 	spin_button = GTK_SPIN_BUTTON (dlg->year);
 69 	dlg->year_val = gtk_spin_button_get_value_as_int (spin_button);
 70 
 71 	e_calendar_item_set_first_month (
 72 		dlg->ecal->calitem, dlg->year_val, dlg->month_val);
 73 }
 74 
 75 /* Callback used when a month button is toggled */
 76 static void
 77 month_changed (GtkToggleButton *toggle,
 78                gpointer data)
 79 {
 80 	GtkComboBox *combo_box;
 81 	GoToDialog *dlg = data;
 82 
 83 	combo_box = GTK_COMBO_BOX (dlg->month_combobox);
 84 	dlg->month_val = gtk_combo_box_get_active (combo_box);
 85 
 86 	e_calendar_item_set_first_month (
 87 		dlg->ecal->calitem, dlg->year_val, dlg->month_val);
 88 }
 89 
 90 static void
 91 ecal_date_range_changed (ECalendarItem *calitem,
 92                          gpointer user_data)
 93 {
 94 	GoToDialog *dlg = user_data;
 95 	ECalModel *model;
 96 	ECalClient *client;
 97 
 98 	model = gnome_calendar_get_model (dlg->gcal);
 99 	client = e_cal_model_get_default_client (model);
100 	if (client)
101 		tag_calendar_by_client (dlg->ecal, client, dlg->cancellable);
102 }
103 
104 /* Event handler for day groups in the month item.  A button press makes
105  * the calendar jump to the selected day and destroys the Go-to dialog box. */
106 static void
107 ecal_event (ECalendarItem *calitem,
108             gpointer user_data)
109 {
110 	GoToDialog *dlg = user_data;
111 	GDate start_date, end_date;
112 	ECalModel *model;
113 	struct icaltimetype tt = icaltime_null_time ();
114 	icaltimezone *timezone;
115 	time_t et;
116 
117 	model = gnome_calendar_get_model (dlg->gcal);
118 	e_calendar_item_get_selection (calitem, &start_date, &end_date);
119 	timezone = e_cal_model_get_timezone (model);
120 
121 	tt.year = g_date_get_year (&start_date);
122 	tt.month = g_date_get_month (&start_date);
123 	tt.day = g_date_get_day (&start_date);
124 
125 	et = icaltime_as_timet_with_zone (tt, timezone);
126 
127 	gnome_calendar_goto (dlg->gcal, et);
128 
129 	gtk_dialog_response (GTK_DIALOG (dlg->dialog), GTK_RESPONSE_NONE);
130 }
131 
132 /* Returns the current time, for the ECalendarItem. */
133 static struct tm
134 get_current_time (ECalendarItem *calitem,
135                   gpointer data)
136 {
137 	icaltimezone *zone;
138 	struct tm tmp_tm = { 0 };
139 	struct icaltimetype tt;
140 
141 	/* Get the current timezone. */
142 	zone = calendar_config_get_icaltimezone ();
143 
144 	tt = icaltime_from_timet_with_zone (time (NULL), FALSE, zone);
145 
146 	/* Now copy it to the struct tm and return it. */
147 	tmp_tm.tm_year  = tt.year - 1900;
148 	tmp_tm.tm_mon   = tt.month - 1;
149 	tmp_tm.tm_mday  = tt.day;
150 	tmp_tm.tm_hour  = tt.hour;
151 	tmp_tm.tm_min   = tt.minute;
152 	tmp_tm.tm_sec   = tt.second;
153 	tmp_tm.tm_isdst = -1;
154 
155 	return tmp_tm;
156 }
157 
158 /* Creates the ecalendar */
159 static void
160 create_ecal (GoToDialog *dlg)
161 {
162 	ECalendarItem *calitem;
163 
164 	dlg->ecal = E_CALENDAR (e_calendar_new ());
165 	calitem = dlg->ecal->calitem;
166 
167 	gnome_canvas_item_set (
168 		GNOME_CANVAS_ITEM (calitem),
169 		"move_selection_when_moving", FALSE,
170 		NULL);
171 	e_calendar_item_set_display_popup (calitem, FALSE);
172 	gtk_widget_show (GTK_WIDGET (dlg->ecal));
173 	gtk_box_pack_start (GTK_BOX (dlg->vbox), GTK_WIDGET (dlg->ecal), TRUE, TRUE, 0);
174 
175 	e_calendar_item_set_first_month (calitem, dlg->year_val, dlg->month_val);
176 	e_calendar_item_set_get_time_callback (
177 		calitem,
178 		get_current_time,
179 		dlg, NULL);
180 
181 	ecal_date_range_changed (calitem, dlg);
182 }
183 
184 static void
185 goto_today (GoToDialog *dlg)
186 {
187 	gnome_calendar_goto_today (dlg->gcal);
188 }
189 
190 /* Gets the widgets from the XML file and returns if they are all available. */
191 static gboolean
192 get_widgets (GoToDialog *dlg)
193 {
194 	#define GW(name) e_builder_get_widget (dlg->builder, name)
195 
196 	dlg->dialog = GW ("goto-dialog");
197 
198 	dlg->month_combobox = GW ("month-combobox");
199 	dlg->year = GW ("year");
200 	dlg->vbox = GW ("vbox");
201 
202 	#undef GW
203 
204 	return (dlg->dialog
205 		&& dlg->month_combobox
206 		&& dlg->year
207 		&& dlg->vbox);
208 }
209 
210 static void
211 goto_dialog_init_widgets (GoToDialog *dlg)
212 {
213 	GtkAdjustment *adj;
214 
215 	g_signal_connect (
216 		dlg->month_combobox, "changed",
217 		G_CALLBACK (month_changed), dlg);
218 
219 	adj = gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (dlg->year));
220 	g_signal_connect (
221 		adj, "value_changed",
222 		G_CALLBACK (year_changed), dlg);
223 
224 	g_signal_connect (
225 		dlg->ecal->calitem, "date_range_changed",
226 		G_CALLBACK (ecal_date_range_changed), dlg);
227 	g_signal_connect (
228 		dlg->ecal->calitem, "selection_changed",
229 		G_CALLBACK (ecal_event), dlg);
230 }
231 
232 /* Creates a "goto date" dialog and runs it */
233 void
234 goto_dialog (GtkWindow *parent,
235              GnomeCalendar *gcal)
236 {
237 	ECalModel *model;
238 	time_t start_time;
239 	struct icaltimetype tt;
240 	icaltimezone *timezone;
241 	gint week_start_day;
242 	gint b;
243 
244 	if (dlg) {
245 		return;
246 	}
247 
248 	dlg = g_new0 (GoToDialog, 1);
249 
250 	/* Load the content widgets */
251 	dlg->builder = gtk_builder_new ();
252 	e_load_ui_builder_definition (dlg->builder, "goto-dialog.ui");
253 
254 	if (!get_widgets (dlg)) {
255 		g_message ("goto_dialog(): Could not find all widgets in the XML file!");
256 		g_free (dlg);
257 		return;
258 	}
259 	dlg->gcal = gcal;
260 	dlg->cancellable = g_cancellable_new ();
261 
262 	model = gnome_calendar_get_model (gcal);
263 	timezone = e_cal_model_get_timezone (model);
264 	e_cal_model_get_time_range (model, &start_time, NULL);
265 	tt = icaltime_from_timet_with_zone (start_time, FALSE, timezone);
266 	dlg->year_val = tt.year;
267 	dlg->month_val = tt.month - 1;
268 	dlg->day_val = tt.day;
269 
270 	gtk_combo_box_set_active (GTK_COMBO_BOX (dlg->month_combobox), dlg->month_val);
271 	gtk_spin_button_set_value (GTK_SPIN_BUTTON (dlg->year), dlg->year_val);
272 
273 	create_ecal (dlg);
274 
275 	goto_dialog_init_widgets (dlg);
276 
277 	gtk_window_set_transient_for (GTK_WINDOW (dlg->dialog), parent);
278 
279 	/* set initial selection to current day */
280 
281 	dlg->ecal->calitem->selection_set = TRUE;
282 	dlg->ecal->calitem->selection_start_month_offset = 0;
283 	dlg->ecal->calitem->selection_start_day = tt.day;
284 	dlg->ecal->calitem->selection_end_month_offset = 0;
285 	dlg->ecal->calitem->selection_end_day = tt.day;
286 
287 	/* Set week_start_day. Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
288 	week_start_day = e_cal_model_get_week_start_day (model);
289 	dlg->ecal->calitem->week_start_day = (week_start_day + 6) % 7;
290 
291 	gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (dlg->ecal->calitem));
292 
293 	b = gtk_dialog_run (GTK_DIALOG (dlg->dialog));
294 	gtk_widget_destroy (dlg->dialog);
295 
296 	if (b == 0)
297 		goto_today (dlg);
298 
299 	g_object_unref (dlg->builder);
300 	g_cancellable_cancel (dlg->cancellable);
301 	g_object_unref (dlg->cancellable);
302 	g_free (dlg);
303 	dlg = NULL;
304 }