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 }