~ubuntu-branches/ubuntu/lucid/evolution/lucid

1.1.52 by Sebastien Bacher
Import upstream version 2.24.1
1
/*
2
 * Evolution calendar - Main calendar view widget
1 by Sebastien Bacher
Import upstream version 2.5.3
3
 *
4
 * This program is free software; you can redistribute it and/or
1.1.52 by Sebastien Bacher
Import upstream version 2.24.1
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.
1 by Sebastien Bacher
Import upstream version 2.5.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
1.1.52 by Sebastien Bacher
Import upstream version 2.24.1
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
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
15
 * License along with the program; if not, see <http://www.gnu.org/licenses/>
1.1.52 by Sebastien Bacher
Import upstream version 2.24.1
16
 *
17
 *
18
 * Authors:
19
 *		Miguel de Icaza <miguel@ximian.com>
20
 *      Federico Mena-Quintero <federico@ximian.com>
21
 *      Seth Alves <alves@hungry.com>
22
 *      Rodrigo Moya <rodrigo@ximian.com>
23
 *
24
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
25
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
26
 */
27
28
#ifdef HAVE_CONFIG_H
29
#include <config.h>
30
#endif
31
32
#include <unistd.h>
33
#include <math.h>
34
#include <signal.h>
35
#include <fcntl.h>
36
#include <glib.h>
37
#include <gdk/gdkkeysyms.h>
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
38
#include <glib/gi18n.h>
1 by Sebastien Bacher
Import upstream version 2.5.3
39
#include <bonobo/bonobo-exception.h>
40
#include <libedataserver/e-categories.h>
41
#include <libedataserver/e-url.h>
1.1.37 by Sebastien Bacher
Import upstream version 2.21.4
42
#include <libedataserverui/e-passwords.h>
43
1 by Sebastien Bacher
Import upstream version 2.5.3
44
#include "shell/e-user-creatable-items-handler.h"
45
#include <libecal/e-cal-time-util.h>
46
#include <widgets/menus/gal-view-factory-etable.h>
47
#include <widgets/menus/gal-view-etable.h>
48
#include <widgets/menus/gal-define-views-dialog.h>
49
#include "widgets/menus/gal-view-menus.h"
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
50
#include "e-util/e-util.h"
1 by Sebastien Bacher
Import upstream version 2.5.3
51
#include "e-util/e-error.h"
52
#include "e-util/e-util-private.h"
53
#include "e-comp-editor-registry.h"
54
#include "dialogs/delete-error.h"
55
#include "dialogs/event-editor.h"
56
#include "dialogs/task-editor.h"
57
#include "comp-util.h"
58
#include "e-cal-model-calendar.h"
59
#include "e-day-view.h"
60
#include "e-day-view-config.h"
61
#include "e-day-view-time-item.h"
62
#include "e-week-view.h"
63
#include "e-week-view-config.h"
64
#include "e-cal-list-view.h"
65
#include "e-cal-list-view-config.h"
66
#include "e-mini-calendar-config.h"
67
#include "e-calendar-table-config.h"
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
68
#include "e-memo-table-config.h"
1 by Sebastien Bacher
Import upstream version 2.5.3
69
#include "evolution-calendar.h"
70
#include "gnome-cal.h"
71
#include "calendar-component.h"
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
72
#include "memos-component.h"
1 by Sebastien Bacher
Import upstream version 2.5.3
73
#include "cal-search-bar.h"
74
#include "calendar-commands.h"
75
#include "calendar-config.h"
76
#include "calendar-view.h"
77
#include "calendar-view-factory.h"
78
#include "tag-calendar.h"
79
#include "misc.h"
80
#include "ea-calendar.h"
81
#include "common/authentication.h"
82
#include "e-cal-popup.h"
83
#include "e-cal-menu.h"
84
#include "e-cal-model-tasks.h"
85
86
/* FIXME glib 2.4 and above has this */
87
#ifndef G_MAXINT32
88
#define G_MAXINT32	((gint32)  0x7fffffff)
89
#endif
90
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
91
#define d(x)
92
93
/* hash table define for non intrusive error dialog */
94
static GHashTable *non_intrusive_error_table = NULL;
1.3.2 by Yves-Alexis Perez
Import upstream version 2.26.1.1
95
1 by Sebastien Bacher
Import upstream version 2.5.3
96
/* Private part of the GnomeCalendar structure */
97
struct _GnomeCalendarPrivate {
98
	/* The clients for display */
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
99
1 by Sebastien Bacher
Import upstream version 2.5.3
100
	GHashTable *clients[E_CAL_SOURCE_TYPE_LAST];
101
	GList *clients_list[E_CAL_SOURCE_TYPE_LAST];
102
	ECal *default_client[E_CAL_SOURCE_TYPE_LAST];
103
104
	/*
105
	 * Fields for the calendar view
106
	 */
107
108
	/* This is the last time explicitly selected by the user */
109
	time_t base_view_time;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
110
1 by Sebastien Bacher
Import upstream version 2.5.3
111
	/* Widgets */
112
113
	GtkWidget   *search_bar;
114
115
	GtkWidget   *hpane;
116
	GtkWidget   *notebook;
117
	GtkWidget   *vpane;
118
119
	ECalendar   *date_navigator;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
120
	EMiniCalendarConfig *date_navigator_config;
1 by Sebastien Bacher
Import upstream version 2.5.3
121
	GtkWidget   *todo;
122
	ECalendarTableConfig *todo_config;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
123
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
124
	GtkWidget   *memo;
125
	EMemoTableConfig *memo_config;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
126
1 by Sebastien Bacher
Import upstream version 2.5.3
127
	GtkWidget   *day_view;
128
	GtkWidget   *work_week_view;
129
	GtkWidget   *week_view;
130
	GtkWidget   *month_view;
131
	GtkWidget   *list_view;
132
133
	/* Activity */
134
	EActivityHandler *activity_handler;
135
136
	/* plugin menu managers */
137
	ECalMenu    *calendar_menu;
138
	ECalMenu    *taskpad_menu;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
139
	ECalMenu    *memopad_menu;
1 by Sebastien Bacher
Import upstream version 2.5.3
140
141
	/* Calendar query for the date navigator */
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
142
	GMutex      *dn_queries_lock; /* lock for dn_queries list */
1 by Sebastien Bacher
Import upstream version 2.5.3
143
	GList       *dn_queries; /* list of CalQueries */
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
144
	gchar        *sexp;
145
	gchar        *todo_sexp;
146
	gchar        *memo_sexp;
1 by Sebastien Bacher
Import upstream version 2.5.3
147
	guint        update_timeout;
148
	guint        update_marcus_bains_line_timeout;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
149
1 by Sebastien Bacher
Import upstream version 2.5.3
150
	/* This is the view currently shown. We use it to keep track of the
151
	   positions of the panes. range_selected is TRUE if a range of dates
152
	   was selected in the date navigator to show the view. */
153
	ECalendarView    *views[GNOME_CAL_LAST_VIEW];
154
	GObject    *configs[GNOME_CAL_LAST_VIEW];
155
	GnomeCalendarViewType current_view_type;
156
	GList *notifications;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
157
1 by Sebastien Bacher
Import upstream version 2.5.3
158
	gboolean range_selected;
159
160
	/* These are the saved positions of the panes. They are multiples of
161
	   calendar month widths & heights in the date navigator, so that they
162
	   will work OK after theme changes. */
163
	gint	     hpane_pos;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
164
	gint	     hpane_pos_month_view;
1 by Sebastien Bacher
Import upstream version 2.5.3
165
	gint	     vpane_pos;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
166
	gint	     vpane_pos_month_view;
1 by Sebastien Bacher
Import upstream version 2.5.3
167
168
	/* The signal handler id for our GtkCalendar "day_selected" handler. */
169
	guint	     day_selected_id;
170
171
	/* View instance and menus for the control */
172
	GalViewInstance *view_instance;
173
	GalViewMenus *view_menus;
174
175
	/* Our current week start */
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
176
	gint week_start;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
177
1 by Sebastien Bacher
Import upstream version 2.5.3
178
	/* Our current timezone. */
179
	icaltimezone *zone;
180
181
	/* The dates currently shown. If they are -1 then we have no dates
182
	   shown. We only use these to check if we need to emit a
183
	   'dates-shown-changed' signal.*/
184
	time_t visible_start;
185
	time_t visible_end;
186
	gboolean updating;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
187
188
	/* If this is true list view uses range of showing the events as the  dates selected in date navigator which is one month, else
189
	   it uses the date range set in search bar */
190
	gboolean lview_select_daten_range;
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
191
192
	/* We should know which calendar has been used to create object, so store it here
193
	   before emitting "user_created" signal and make it NULL just after the emit. */
194
	ECal *user_created_cal;
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
195
196
	/* used in update_todo_view, to prevent interleaving when called in separate thread */
197
	GMutex *todo_update_lock;
1 by Sebastien Bacher
Import upstream version 2.5.3
198
};
199
200
/* Signal IDs */
201
202
enum {
203
	DATES_SHOWN_CHANGED,
204
	CALENDAR_SELECTION_CHANGED,
205
	TASKPAD_SELECTION_CHANGED,
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
206
	MEMOPAD_SELECTION_CHANGED,
1 by Sebastien Bacher
Import upstream version 2.5.3
207
	CALENDAR_FOCUS_CHANGE,
208
	TASKPAD_FOCUS_CHANGE,
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
209
	MEMOPAD_FOCUS_CHANGE,
1 by Sebastien Bacher
Import upstream version 2.5.3
210
	GOTO_DATE,
211
	SOURCE_ADDED,
212
	SOURCE_REMOVED,
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
213
	CHANGE_VIEW,
1 by Sebastien Bacher
Import upstream version 2.5.3
214
	LAST_SIGNAL
215
};
216
217
/* Used to indicate who has the focus within the calendar view */
218
typedef enum {
219
	FOCUS_CALENDAR,
220
	FOCUS_TASKPAD,
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
221
	FOCUS_MEMOPAD,
1 by Sebastien Bacher
Import upstream version 2.5.3
222
	FOCUS_OTHER
223
} FocusLocation;
224
225
static guint gnome_calendar_signals[LAST_SIGNAL];
226
227

228
229
static void gnome_calendar_destroy (GtkObject *object);
230
static void gnome_calendar_goto_date (GnomeCalendar *gcal,
231
				      GnomeCalendarGotoDateType goto_date);
232
static void gnome_calendar_change_view (GnomeCalendar *gcal,
233
					 GnomeCalendarViewType view_type);
234
235
static void gnome_calendar_set_pane_positions	(GnomeCalendar	*gcal);
236
static void update_view_times (GnomeCalendar *gcal, time_t start_time);
237
static void gnome_calendar_update_date_navigator (GnomeCalendar *gcal);
238
239
static void gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
240
static void gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data);
241
static gboolean gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
242
static void gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal);
243
static gboolean gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal);
244
245
static void gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem,
246
								 GnomeCalendar *gcal);
247
static void gnome_calendar_on_date_navigator_selection_changed (ECalendarItem    *calitem,
248
								GnomeCalendar    *gcal);
249
static void gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal);
250
251
static void update_query (GnomeCalendar *gcal);
252
253
static void update_todo_view (GnomeCalendar *gcal);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
254
static void update_memo_view (GnomeCalendar *gcal);
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
255
static void default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal);
256
static void client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal);
257
258
/* Simple asynchronous message dispatcher */
259
typedef struct _Message Message;
260
typedef void (*MessageFunc) (Message *msg);
261
262
struct _Message {
263
	MessageFunc func;
264
};
265
266
static void
267
message_proxy (Message *msg)
268
{
269
	g_return_if_fail (msg->func != NULL);
270
271
	msg->func (msg);
272
}
273
274
static gpointer
275
create_thread_pool (void)
276
{
277
	/* once created, run forever */
278
	return g_thread_pool_new ((GFunc) message_proxy, NULL, 1, FALSE, NULL);
279
}
280
281
static void
282
message_push (Message *msg)
283
{
284
	static GOnce once = G_ONCE_INIT;
285
286
	g_once (&once, (GThreadFunc) create_thread_pool, NULL);
287
288
	g_thread_pool_push ((GThreadPool *) once.retval, msg, NULL);
289
}
1 by Sebastien Bacher
Import upstream version 2.5.3
290
1.1.4 by Sebastien Bacher
Import upstream version 2.5.91
291
G_DEFINE_TYPE (GnomeCalendar, gnome_calendar, GTK_TYPE_VBOX)
1 by Sebastien Bacher
Import upstream version 2.5.3
292
293
/* Class initialization function for the gnome calendar */
294
static void
295
gnome_calendar_class_init (GnomeCalendarClass *class)
296
{
297
	GtkObjectClass *object_class;
298
	GtkBindingSet *binding_set;
299
300
	object_class = (GtkObjectClass *) class;
301
302
	gnome_calendar_signals[DATES_SHOWN_CHANGED] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
303
		g_signal_new ("dates_shown_changed",
1 by Sebastien Bacher
Import upstream version 2.5.3
304
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
305
				G_SIGNAL_RUN_LAST,
306
				G_STRUCT_OFFSET (GnomeCalendarClass, dates_shown_changed),
307
				NULL, NULL,
308
				g_cclosure_marshal_VOID__VOID,
309
				G_TYPE_NONE, 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
310
311
	gnome_calendar_signals[CALENDAR_SELECTION_CHANGED] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
312
		g_signal_new ("calendar_selection_changed",
1 by Sebastien Bacher
Import upstream version 2.5.3
313
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
314
				G_SIGNAL_RUN_LAST,
315
				G_STRUCT_OFFSET (GnomeCalendarClass, calendar_selection_changed),
316
				NULL, NULL,
317
				g_cclosure_marshal_VOID__VOID,
318
				G_TYPE_NONE, 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
319
320
	gnome_calendar_signals[TASKPAD_SELECTION_CHANGED] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
321
		g_signal_new ("taskpad_selection_changed",
1 by Sebastien Bacher
Import upstream version 2.5.3
322
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
323
				G_SIGNAL_RUN_LAST,
324
				G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_selection_changed),
325
				NULL, NULL,
326
				g_cclosure_marshal_VOID__VOID,
327
				G_TYPE_NONE, 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
328
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
329
	gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
330
		g_signal_new ("memopad_selection_changed",
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
331
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
332
				G_SIGNAL_RUN_LAST,
333
				G_STRUCT_OFFSET (GnomeCalendarClass, memopad_selection_changed),
334
				NULL, NULL,
335
				g_cclosure_marshal_VOID__VOID,
336
				G_TYPE_NONE, 0);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
337
1 by Sebastien Bacher
Import upstream version 2.5.3
338
	gnome_calendar_signals[CALENDAR_FOCUS_CHANGE] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
339
		g_signal_new ("calendar_focus_change",
1 by Sebastien Bacher
Import upstream version 2.5.3
340
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
341
				G_SIGNAL_RUN_FIRST,
342
				G_STRUCT_OFFSET (GnomeCalendarClass, calendar_focus_change),
343
				NULL, NULL,
344
				g_cclosure_marshal_VOID__BOOLEAN,
345
				G_TYPE_NONE, 1,
346
				G_TYPE_BOOLEAN);
1 by Sebastien Bacher
Import upstream version 2.5.3
347
348
	gnome_calendar_signals[TASKPAD_FOCUS_CHANGE] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
349
		g_signal_new ("taskpad_focus_change",
1 by Sebastien Bacher
Import upstream version 2.5.3
350
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
351
				G_SIGNAL_RUN_FIRST,
352
				G_STRUCT_OFFSET (GnomeCalendarClass, taskpad_focus_change),
353
				NULL, NULL,
354
				g_cclosure_marshal_VOID__BOOLEAN,
355
				G_TYPE_NONE, 1,
356
				G_TYPE_BOOLEAN);
1 by Sebastien Bacher
Import upstream version 2.5.3
357
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
358
	gnome_calendar_signals[MEMOPAD_FOCUS_CHANGE] =
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
359
		g_signal_new ("memopad_focus_change",
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
360
				G_TYPE_FROM_CLASS (object_class),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
361
				G_SIGNAL_RUN_FIRST,
362
				G_STRUCT_OFFSET (GnomeCalendarClass, memopad_focus_change),
363
				NULL, NULL,
364
				g_cclosure_marshal_VOID__BOOLEAN,
365
				G_TYPE_NONE, 1,
366
				G_TYPE_BOOLEAN);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
367
1 by Sebastien Bacher
Import upstream version 2.5.3
368
	gnome_calendar_signals[SOURCE_ADDED] =
369
		g_signal_new ("source_added",
370
			      G_TYPE_FROM_CLASS (object_class),
371
			      G_SIGNAL_RUN_FIRST,
372
			      G_STRUCT_OFFSET (GnomeCalendarClass, source_added),
373
			      NULL, NULL,
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
374
			      e_marshal_VOID__INT_OBJECT,
1 by Sebastien Bacher
Import upstream version 2.5.3
375
			      G_TYPE_NONE,
376
			      2,
377
			      G_TYPE_INT, G_TYPE_OBJECT);
378
379
	gnome_calendar_signals[SOURCE_REMOVED] =
380
		g_signal_new ("source_removed",
381
			      G_TYPE_FROM_CLASS (object_class),
382
			      G_SIGNAL_RUN_FIRST,
383
			      G_STRUCT_OFFSET (GnomeCalendarClass, source_removed),
384
			      NULL, NULL,
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
385
			      e_marshal_VOID__INT_OBJECT,
1 by Sebastien Bacher
Import upstream version 2.5.3
386
			      G_TYPE_NONE,
387
			      2,
388
			      G_TYPE_INT, G_TYPE_OBJECT);
389
390
	gnome_calendar_signals[GOTO_DATE] =
391
		g_signal_new ("goto_date",
392
			      G_TYPE_FROM_CLASS (object_class),
393
			      G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
394
			      G_STRUCT_OFFSET (GnomeCalendarClass, goto_date),
395
			      NULL, NULL,
396
			      g_cclosure_marshal_VOID__INT,
397
			      G_TYPE_NONE,
398
			      1,
399
			      G_TYPE_INT);
400
401
	gnome_calendar_signals[CHANGE_VIEW] =
402
		g_signal_new ("change_view",
403
			      G_TYPE_FROM_CLASS (object_class),
404
			      G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
405
			      G_STRUCT_OFFSET (GnomeCalendarClass, change_view),
406
			      NULL, NULL,
407
			      g_cclosure_marshal_VOID__INT,
408
			      G_TYPE_NONE,
409
			      1,
410
			      G_TYPE_INT);
411
412
	object_class->destroy = gnome_calendar_destroy;
413
414
	class->dates_shown_changed = NULL;
415
	class->calendar_selection_changed = NULL;
416
	class->taskpad_selection_changed = NULL;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
417
	class->memopad_selection_changed = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
418
	class->calendar_focus_change = NULL;
419
	class->taskpad_focus_change = NULL;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
420
	class->memopad_focus_change = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
421
	class->source_added = NULL;
422
	class->source_removed = NULL;
423
	class->goto_date = gnome_calendar_goto_date;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
424
	class->change_view = gnome_calendar_change_view;
1 by Sebastien Bacher
Import upstream version 2.5.3
425
426
	/*
427
	 * Key bindings
428
	 */
429
430
	binding_set = gtk_binding_set_by_class (class);
431
432
	/* Alt+PageUp/PageDown, go to the first/last day of the month */
433
	gtk_binding_entry_add_signal (binding_set, GDK_Page_Up,
434
				      GDK_MOD1_MASK,
435
				      "goto_date", 1,
436
				      G_TYPE_ENUM,
437
				      GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH);
438
	gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Up,
439
				      GDK_MOD1_MASK,
440
				      "goto_date", 1,
441
				      G_TYPE_ENUM,
442
				      GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH);
443
	gtk_binding_entry_add_signal (binding_set, GDK_Page_Down,
444
				      GDK_MOD1_MASK,
445
				      "goto_date", 1,
446
				      G_TYPE_ENUM,
447
				      GNOME_CAL_GOTO_LAST_DAY_OF_MONTH);
448
	gtk_binding_entry_add_signal (binding_set, GDK_KP_Page_Down,
449
				      GDK_MOD1_MASK,
450
				      "goto_date", 1,
451
				      G_TYPE_ENUM,
452
				      GNOME_CAL_GOTO_LAST_DAY_OF_MONTH);
453
454
	/* Alt+Home/End, go to the first/last day of the week */
455
	gtk_binding_entry_add_signal (binding_set, GDK_Home,
456
				      GDK_MOD1_MASK,
457
				      "goto_date", 1,
458
				      G_TYPE_ENUM,
459
				      GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK);
460
	gtk_binding_entry_add_signal (binding_set, GDK_End,
461
				      GDK_MOD1_MASK,
462
				      "goto_date", 1,
463
				      G_TYPE_ENUM,
464
				      GNOME_CAL_GOTO_LAST_DAY_OF_WEEK);
465
	gtk_binding_entry_add_signal (binding_set, GDK_KP_Home,
466
				      GDK_MOD1_MASK,
467
				      "goto_date", 1,
468
				      G_TYPE_ENUM,
469
				      GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK);
470
	gtk_binding_entry_add_signal (binding_set, GDK_KP_End,
471
				      GDK_MOD1_MASK,
472
				      "goto_date", 1,
473
				      G_TYPE_ENUM,
474
				      GNOME_CAL_GOTO_LAST_DAY_OF_WEEK);
475
476
	/*Alt+Left/Right, go to the same day of the previous/next week*/
477
	gtk_binding_entry_add_signal (binding_set,GDK_Left,
478
				      GDK_MOD1_MASK,
479
				      "goto_date",1,
480
				      G_TYPE_ENUM,
481
				      GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK);
482
	gtk_binding_entry_add_signal (binding_set,GDK_KP_Left,
483
				      GDK_MOD1_MASK,
484
				      "goto_date",1,
485
				      G_TYPE_ENUM,
486
				      GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK);
487
	gtk_binding_entry_add_signal (binding_set,GDK_Right,
488
				      GDK_MOD1_MASK,
489
				      "goto_date",1,
490
				      G_TYPE_ENUM,
491
				      GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK);
492
	gtk_binding_entry_add_signal (binding_set,GDK_KP_Right,
493
				      GDK_MOD1_MASK,
494
				      "goto_date",1,
495
				      G_TYPE_ENUM,
496
				      GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
497
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
498
	/* Ctrl+Y/J/K/M/L to switch between
1 by Sebastien Bacher
Import upstream version 2.5.3
499
	 * DayView/WorkWeekView/WeekView/MonthView/ListView */
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
500
	gtk_binding_entry_add_signal (binding_set, GDK_y,
501
				      GDK_CONTROL_MASK,
502
				      "change_view", 1,
503
				      G_TYPE_ENUM,
504
				      GNOME_CAL_DAY_VIEW);
505
	gtk_binding_entry_add_signal (binding_set, GDK_j,
506
				      GDK_CONTROL_MASK,
507
				      "change_view", 1,
508
				      G_TYPE_ENUM,
509
				      GNOME_CAL_WORK_WEEK_VIEW);
510
	gtk_binding_entry_add_signal (binding_set, GDK_k,
511
				      GDK_CONTROL_MASK,
512
				      "change_view", 1,
513
				      G_TYPE_ENUM,
514
				      GNOME_CAL_WEEK_VIEW);
515
	gtk_binding_entry_add_signal (binding_set, GDK_m,
516
				      GDK_CONTROL_MASK,
517
				      "change_view", 1,
518
				      G_TYPE_ENUM,
519
				      GNOME_CAL_MONTH_VIEW);
1 by Sebastien Bacher
Import upstream version 2.5.3
520
	gtk_binding_entry_add_signal (binding_set, GDK_l,
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
521
				      GDK_CONTROL_MASK,
522
				      "change_view", 1,
523
				      G_TYPE_ENUM,
524
				      GNOME_CAL_LIST_VIEW);
1 by Sebastien Bacher
Import upstream version 2.5.3
525
526
	/* init the accessibility support for gnome_calendar */
527
	gnome_calendar_a11y_init ();
528
529
}
530
531
/* We do this check since the calendar items are downloaded from the server in the open_method,
532
   since the default timezone might not be set there */
533
static void
534
ensure_dates_are_in_default_zone (icalcomponent *icalcomp)
535
{
536
	icaltimetype dt;
537
	icaltimezone *zone = calendar_config_get_icaltimezone ();
538
539
	if (!zone)
540
		return;
541
542
	dt = icalcomponent_get_dtstart (icalcomp);
543
	if (dt.is_utc) {
544
		dt = icaltime_convert_to_zone (dt, zone);
545
		icalcomponent_set_dtstart (icalcomp, dt);
546
	}
547
548
	dt = icalcomponent_get_dtend (icalcomp);
549
	if (dt.is_utc) {
550
		dt = icaltime_convert_to_zone (dt, zone);
551
		icalcomponent_set_dtend (icalcomp, dt);
552
	}
553
}
554
555
/* Callback used when the calendar query reports of an updated object */
556
static void
557
dn_e_cal_view_objects_added_cb (ECalView *query, GList *objects, gpointer data)
558
{
559
	GnomeCalendar *gcal;
560
	GnomeCalendarPrivate *priv;
561
	GList *l;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
562
1 by Sebastien Bacher
Import upstream version 2.5.3
563
	gcal = GNOME_CALENDAR (data);
564
	priv = gcal->priv;
565
566
	for (l = objects; l; l = l->next) {
567
		ECalComponent *comp = NULL;
568
569
		ensure_dates_are_in_default_zone (l->data);
570
		comp = e_cal_component_new ();
571
		if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (l->data))) {
572
			g_object_unref (comp);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
573
1 by Sebastien Bacher
Import upstream version 2.5.3
574
			continue;
575
		}
576
577
		tag_calendar_by_comp (priv->date_navigator, comp, e_cal_view_get_client (query), NULL,
578
				      FALSE, TRUE);
579
		g_object_unref (comp);
580
	}
581
}
582
583
static void
584
dn_e_cal_view_objects_modified_cb (ECalView *query, GList *objects, gpointer data)
585
{
586
	GnomeCalendar *gcal;
587
588
	gcal = GNOME_CALENDAR (data);
589
590
	/* We have to retag the whole thing: an event may change dates
591
	 * and the tag_calendar_by_comp() below would not know how to
592
	 * untag the old dates.
593
	 */
594
	update_query (gcal);
595
}
596
597
/* Callback used when the calendar query reports of a removed object */
598
static void
599
dn_e_cal_view_objects_removed_cb (ECalView *query, GList *ids, gpointer data)
600
{
601
	GnomeCalendar *gcal;
602
603
	gcal = GNOME_CALENDAR (data);
604
605
	/* Just retag the whole thing */
606
	update_query (gcal);
607
}
608
609
/* Callback used when the calendar query is done */
610
static void
611
dn_e_cal_view_done_cb (ECalView *query, ECalendarStatus status, gpointer data)
612
{
613
	/* FIXME Better error reporting */
614
	if (status != E_CALENDAR_STATUS_OK)
615
		g_warning (G_STRLOC ": Query did not successfully complete");
616
}
617
618
/* Returns the current view widget, an EDayView, EWeekView or ECalListView. */
619
GtkWidget*
620
gnome_calendar_get_current_view_widget (GnomeCalendar *gcal)
621
{
622
	GnomeCalendarPrivate *priv;
623
624
	priv = gcal->priv;
625
626
	return GTK_WIDGET (priv->views[priv->current_view_type]);
627
}
628
629
static void
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
630
get_times_for_views (GnomeCalendar *gcal, GnomeCalendarViewType view_type, time_t *start_time, time_t *end_time, time_t *select_time)
1 by Sebastien Bacher
Import upstream version 2.5.3
631
{
632
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
633
	gint shown, display_start;
1 by Sebastien Bacher
Import upstream version 2.5.3
634
	GDate date;
635
	gint weekday, first_day, last_day, days_shown, i;
636
	gboolean has_working_days = FALSE;
637
	guint offset;
638
	struct icaltimetype tt = icaltime_null_time ();
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
639
1 by Sebastien Bacher
Import upstream version 2.5.3
640
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
641
1 by Sebastien Bacher
Import upstream version 2.5.3
642
	switch (view_type) {
643
	case GNOME_CAL_DAY_VIEW:
644
		shown  = e_day_view_get_days_shown (E_DAY_VIEW (priv->views[view_type]));
645
		*start_time = time_day_begin_with_zone (*start_time, priv->zone);
646
		*end_time = time_add_day_with_zone (*start_time, shown, priv->zone);
647
		break;
648
	case GNOME_CAL_WORK_WEEK_VIEW:
649
		/* FIXME Kind of gross, but it works */
650
		time_to_gdate_with_zone (&date, *start_time, priv->zone);
651
652
		/* The start of the work-week is the first working day after the
653
		   week start day. */
654
655
		/* Get the weekday corresponding to start_time, 0 (Sun) to 6 (Sat). */
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
656
		weekday = g_date_get_weekday (&date) % 7;
1 by Sebastien Bacher
Import upstream version 2.5.3
657
658
		/* Find the first working day in the week, 0 (Sun) to 6 (Sat). */
659
		first_day = (E_DAY_VIEW (priv->views[view_type])->week_start_day + 1) % 7;
660
		for (i = 0; i < 7; i++) {
661
			if (E_DAY_VIEW (priv->views[view_type])->working_days & (1 << first_day)) {
662
				has_working_days = TRUE;
663
				break;
664
			}
665
			first_day = (first_day + 1) % 7;
666
		}
667
668
		if (has_working_days) {
669
			/* Now find the last working day of the week, backwards. */
670
			last_day = E_DAY_VIEW (priv->views[view_type])->week_start_day % 7;
671
			for (i = 0; i < 7; i++) {
672
				if (E_DAY_VIEW (priv->views[view_type])->working_days & (1 << last_day))
673
					break;
674
				last_day = (last_day + 6) % 7;
675
			}
676
			/* Now calculate the days we need to show to include all the
677
			   working days in the week. Add 1 to make it inclusive. */
678
			days_shown = (last_day + 7 - first_day) % 7 + 1;
679
		} else {
680
			/* If no working days are set, just use 7. */
681
			days_shown = 7;
682
		}
683
684
		/* Calculate how many days we need to go back to the first workday. */
685
		if (weekday < first_day) {
686
			offset = (first_day - weekday) % 7;
687
			g_date_add_days (&date, offset);
688
		} else {
689
			offset = (weekday - first_day) % 7;
690
			g_date_subtract_days (&date, offset);
691
		}
692
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
693
		tt.year = g_date_get_year (&date);
694
		tt.month = g_date_get_month (&date);
695
		tt.day = g_date_get_day (&date);
1 by Sebastien Bacher
Import upstream version 2.5.3
696
697
		*start_time = icaltime_as_timet_with_zone (tt, priv->zone);
698
		*end_time = time_add_day_with_zone (*start_time, days_shown, priv->zone);
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
699
700
		if (select_time && E_DAY_VIEW (priv->views[view_type])->selection_start_day == -1)
701
			time (select_time);
1 by Sebastien Bacher
Import upstream version 2.5.3
702
		break;
703
	case GNOME_CAL_WEEK_VIEW:
704
		/* FIXME We should be using the same day of the week enum every where */
705
		display_start = (E_WEEK_VIEW (priv->views[view_type])->display_start_day + 1) % 7;
706
707
		*start_time = time_week_begin_with_zone (*start_time, display_start, priv->zone);
708
		*end_time = time_add_week_with_zone (*start_time, 1, priv->zone);
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
709
710
		if (select_time && E_WEEK_VIEW (priv->views[view_type])->selection_start_day == -1)
711
			time (select_time);
1 by Sebastien Bacher
Import upstream version 2.5.3
712
		break;
713
	case GNOME_CAL_MONTH_VIEW:
714
		shown = e_week_view_get_weeks_shown (E_WEEK_VIEW (priv->views[view_type]));
715
		/* FIXME We should be using the same day of the week enum every where */
716
		display_start = (E_WEEK_VIEW (priv->views[view_type])->display_start_day + 1) % 7;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
717
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
718
		if (!priv->range_selected && (!E_WEEK_VIEW (priv->views[view_type])->multi_week_view || !E_WEEK_VIEW (priv->views[view_type])->month_scroll_by_week))
1 by Sebastien Bacher
Import upstream version 2.5.3
719
			*start_time = time_month_begin_with_zone (*start_time, priv->zone);
720
		*start_time = time_week_begin_with_zone (*start_time, display_start, priv->zone);
721
		*end_time = time_add_week_with_zone (*start_time, shown, priv->zone);
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
722
723
		if (select_time && E_WEEK_VIEW (priv->views[view_type])->selection_start_day == -1)
724
			time (select_time);
1 by Sebastien Bacher
Import upstream version 2.5.3
725
		break;
726
	case GNOME_CAL_LIST_VIEW:
727
		/* FIXME What to do here? */
728
		*start_time = time_month_begin_with_zone (*start_time, priv->zone);
729
		*end_time = time_add_month_with_zone (*start_time, 1, priv->zone);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
730
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
731
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
732
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
733
	}
734
}
735
736
/* Gets the focus location based on who is the focused widget within the
737
 * calendar view.
738
 */
739
static FocusLocation
740
get_focus_location (GnomeCalendar *gcal)
741
{
742
	GnomeCalendarPrivate *priv;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
743
	ETable *etable, *m_etable;
1 by Sebastien Bacher
Import upstream version 2.5.3
744
745
	priv = gcal->priv;
746
747
	etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
748
	m_etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
1 by Sebastien Bacher
Import upstream version 2.5.3
749
750
	if (GTK_WIDGET_HAS_FOCUS (etable->table_canvas))
751
		return FOCUS_TASKPAD;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
752
	else if (GTK_WIDGET_HAS_FOCUS (m_etable->table_canvas))
753
		return FOCUS_MEMOPAD;
1 by Sebastien Bacher
Import upstream version 2.5.3
754
	else {
755
		GtkWidget *widget;
756
		EDayView *dv;
757
		EWeekView *wv;
758
		ECalListView *lv;
759
760
		widget = gnome_calendar_get_current_view_widget (gcal);
761
762
		switch (priv->current_view_type) {
763
		case GNOME_CAL_DAY_VIEW:
764
		case GNOME_CAL_WORK_WEEK_VIEW:
765
			dv = E_DAY_VIEW (widget);
766
767
			if (GTK_WIDGET_HAS_FOCUS (dv->top_canvas)
768
			    || GNOME_CANVAS (dv->top_canvas)->focused_item != NULL
769
			    || GTK_WIDGET_HAS_FOCUS (dv->main_canvas)
1.1.65 by Sebastien Bacher
Import upstream version 2.27.90
770
			    || GNOME_CANVAS (dv->main_canvas)->focused_item != NULL
771
			    || GTK_WIDGET_HAS_FOCUS (dv))
1 by Sebastien Bacher
Import upstream version 2.5.3
772
				return FOCUS_CALENDAR;
773
			else
774
				return FOCUS_OTHER;
775
776
		case GNOME_CAL_WEEK_VIEW:
777
		case GNOME_CAL_MONTH_VIEW:
778
			wv = E_WEEK_VIEW (widget);
779
780
			if (GTK_WIDGET_HAS_FOCUS (wv->main_canvas)
1.1.65 by Sebastien Bacher
Import upstream version 2.27.90
781
			    || GNOME_CANVAS (wv->main_canvas)->focused_item != NULL
782
			    || GTK_WIDGET_HAS_FOCUS (wv))
1 by Sebastien Bacher
Import upstream version 2.5.3
783
				return FOCUS_CALENDAR;
784
			else
785
				return FOCUS_OTHER;
786
787
		case GNOME_CAL_LIST_VIEW:
788
			lv = E_CAL_LIST_VIEW (widget);
789
1.1.65 by Sebastien Bacher
Import upstream version 2.27.90
790
			if (GTK_WIDGET_HAS_FOCUS (e_table_scrolled_get_table (lv->table_scrolled))
791
			    || GTK_WIDGET_HAS_FOCUS (lv))
1 by Sebastien Bacher
Import upstream version 2.5.3
792
				return FOCUS_CALENDAR;
793
			else
794
				return FOCUS_OTHER;
795
796
		default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
797
			g_return_val_if_reached (FOCUS_OTHER);
1 by Sebastien Bacher
Import upstream version 2.5.3
798
		}
799
	}
800
}
801
802
/* Computes the range of time that the date navigator is showing */
803
static void
804
get_date_navigator_range (GnomeCalendar *gcal, time_t *start_time, time_t *end_time)
805
{
806
	GnomeCalendarPrivate *priv;
807
	gint start_year, start_month, start_day;
808
	gint end_year, end_month, end_day;
809
	struct icaltimetype start_tt;
810
	struct icaltimetype end_tt;
811
812
	priv = gcal->priv;
813
814
	start_tt = icaltime_null_time ();
815
	end_tt = icaltime_null_time ();
816
817
	if (!e_calendar_item_get_date_range (priv->date_navigator->calitem,
818
					     &start_year, &start_month, &start_day,
819
					     &end_year, &end_month, &end_day)) {
820
		*start_time = -1;
821
		*end_time = -1;
822
		return;
823
	}
824
825
	start_tt.year = start_year;
826
	start_tt.month = start_month + 1;
827
	start_tt.day = start_day;
828
829
	end_tt.year = end_year;
830
	end_tt.month = end_month + 1;
831
	end_tt.day = end_day;
832
833
	icaltime_adjust (&end_tt, 1, 0, 0, 0);
834
835
	*start_time = icaltime_as_timet_with_zone (start_tt, priv->zone);
836
	*end_time = icaltime_as_timet_with_zone (end_tt, priv->zone);
837
}
838
839
/* Adjusts a given query sexp with the time range of the date navigator */
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
840
static gchar *
841
adjust_e_cal_view_sexp (GnomeCalendar *gcal, const gchar *sexp)
1 by Sebastien Bacher
Import upstream version 2.5.3
842
{
843
	time_t start_time, end_time;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
844
	gchar *start, *end;
845
	gchar *new_sexp;
1 by Sebastien Bacher
Import upstream version 2.5.3
846
847
	get_date_navigator_range (gcal, &start_time, &end_time);
848
	if (start_time == -1 || end_time == -1)
849
		return NULL;
850
851
	start = isodate_from_time_t (start_time);
852
	end = isodate_from_time_t (end_time);
853
854
	new_sexp = g_strdup_printf ("(and (occur-in-time-range? (make-time \"%s\")"
855
				    "                           (make-time \"%s\"))"
856
				    "     %s)",
857
				    start, end,
858
				    sexp);
859
	g_free (start);
860
	g_free (end);
861
862
	return new_sexp;
863
}
864
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
865
struct _date_query_msg {
866
	Message header;
867
	GnomeCalendar *gcal;
868
};
869
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
870
static void
871
update_query_async (struct _date_query_msg *msg)
1 by Sebastien Bacher
Import upstream version 2.5.3
872
{
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
873
	GnomeCalendar *gcal = msg->gcal;
1 by Sebastien Bacher
Import upstream version 2.5.3
874
	GnomeCalendarPrivate *priv;
875
	ECalView *old_query;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
876
	gchar *real_sexp;
1 by Sebastien Bacher
Import upstream version 2.5.3
877
	GList *l;
878
879
	priv = gcal->priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
880
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
881
	g_mutex_lock (priv->dn_queries_lock);
882
1 by Sebastien Bacher
Import upstream version 2.5.3
883
	/* free the previous queries */
884
	for (l = priv->dn_queries; l != NULL; l = l->next) {
885
		old_query = l->data;
886
887
		if (old_query) {
888
			g_signal_handlers_disconnect_matched (old_query, G_SIGNAL_MATCH_DATA,
889
							      0, 0, NULL, NULL, gcal);
890
			g_object_unref (old_query);
891
		}
892
	}
893
894
	g_list_free (priv->dn_queries);
895
	priv->dn_queries = NULL;
896
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
897
	g_mutex_unlock (priv->dn_queries_lock);
898
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
899
	g_return_if_fail (priv->sexp != NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
900
901
	real_sexp = adjust_e_cal_view_sexp (gcal, priv->sexp);
902
	if (!real_sexp) {
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
903
		g_object_unref (msg->gcal);
904
		g_slice_free (struct _date_query_msg, msg);
1 by Sebastien Bacher
Import upstream version 2.5.3
905
		return; /* No time range is set, so don't start a query */
906
	}
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
907
1 by Sebastien Bacher
Import upstream version 2.5.3
908
	/* create queries for each loaded client */
909
	for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
910
		GError *error = NULL;
911
		gint tries = 0;
912
1 by Sebastien Bacher
Import upstream version 2.5.3
913
		/* don't create queries for clients not loaded yet */
914
		if (e_cal_get_load_state ((ECal *) l->data) != E_CAL_LOAD_LOADED)
915
			continue;
916
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
917
try_again:
1 by Sebastien Bacher
Import upstream version 2.5.3
918
		old_query = NULL;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
919
		if (!e_cal_get_query ((ECal *) l->data, real_sexp, &old_query, &error)) {
920
			/* If calendar is busy try again for 3 times. */
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
921
			if (error->code == E_CALENDAR_STATUS_BUSY && tries != 10) {
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
922
				tries++;
923
				/*TODO chose an optimal value */
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
924
				g_usleep (500);
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
925
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
926
				g_clear_error (&error);
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
927
				goto try_again;
928
			}
929
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
930
			g_warning (G_STRLOC ": Could not create the query: %s ", error->message);
931
			g_clear_error (&error);
1 by Sebastien Bacher
Import upstream version 2.5.3
932
933
			continue;
934
		}
935
936
		g_signal_connect (old_query, "objects_added",
937
				  G_CALLBACK (dn_e_cal_view_objects_added_cb), gcal);
938
		g_signal_connect (old_query, "objects_modified",
939
				  G_CALLBACK (dn_e_cal_view_objects_modified_cb), gcal);
940
		g_signal_connect (old_query, "objects_removed",
941
				  G_CALLBACK (dn_e_cal_view_objects_removed_cb), gcal);
942
		g_signal_connect (old_query, "view_done",
943
				  G_CALLBACK (dn_e_cal_view_done_cb), gcal);
944
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
945
		g_mutex_lock (priv->dn_queries_lock);
1 by Sebastien Bacher
Import upstream version 2.5.3
946
		priv->dn_queries = g_list_append (priv->dn_queries, old_query);
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
947
		g_mutex_unlock (priv->dn_queries_lock);
1 by Sebastien Bacher
Import upstream version 2.5.3
948
949
		e_cal_view_start (old_query);
950
	}
951
952
	/* free memory */
953
	g_free (real_sexp);
954
	update_todo_view (gcal);
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
955
956
	g_object_unref (msg->gcal);
957
	g_slice_free (struct _date_query_msg, msg);
958
}
959
960
/* Restarts a query for the date navigator in the calendar */
961
static void
962
update_query (GnomeCalendar *gcal)
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
963
{
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
964
	struct _date_query_msg *msg;
965
966
	e_calendar_item_clear_marks (gcal->priv->date_navigator->calitem);
967
968
	msg = g_slice_new0 (struct _date_query_msg);
969
	msg->header.func = (MessageFunc) update_query_async;
970
	msg->gcal = g_object_ref (gcal);
971
972
	message_push ((Message *) msg);
1 by Sebastien Bacher
Import upstream version 2.5.3
973
}
974
975
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
976
set_search_query (GnomeCalendar *gcal, const gchar *sexp)
1 by Sebastien Bacher
Import upstream version 2.5.3
977
{
978
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
979
	gint i;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
980
	time_t start, end;
1 by Sebastien Bacher
Import upstream version 2.5.3
981
982
	g_return_if_fail (gcal != NULL);
983
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
984
	g_return_if_fail (sexp != NULL);
985
986
	priv = gcal->priv;
987
988
	/* Set the query on the date navigator */
989
990
	if (priv->sexp)
991
		g_free (priv->sexp);
992
993
	priv->sexp = g_strdup (sexp);
994
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
995
	d(g_print ("Changing the queries %s \n", sexp));
996
1 by Sebastien Bacher
Import upstream version 2.5.3
997
	update_query (gcal);
998
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
999
	i = priv->current_view_type;
1000
1 by Sebastien Bacher
Import upstream version 2.5.3
1001
	/* Set the query on the views */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1002
	if (i == GNOME_CAL_LIST_VIEW) {
1003
		if (!priv->lview_select_daten_range) {
1004
			cal_search_bar_get_time_range ((CalSearchBar *)priv->search_bar, &start, &end);
1005
			e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
1006
		} else {
1007
			start = priv->base_view_time;
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
1008
			get_times_for_views (gcal, GNOME_CAL_LIST_VIEW, &start, &end, NULL);
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1009
1010
			e_cal_model_set_search_query_with_time_range (e_calendar_view_get_model (priv->views [i]), sexp, start, end);
1011
1012
			if (priv->current_view_type == GNOME_CAL_LIST_VIEW)
1013
				gnome_calendar_update_date_navigator (gcal);
1014
		}
1015
	} else
1016
		e_cal_model_set_search_query (e_calendar_view_get_model (priv->views[i]), sexp);
1 by Sebastien Bacher
Import upstream version 2.5.3
1017
1018
	/* Set the query on the task pad */
1019
	update_todo_view (gcal);
1020
}
1021
1022
/* Returns the current time, for the ECalendarItem. */
1023
static struct tm
1024
get_current_time (ECalendarItem *calitem, gpointer data)
1025
{
1026
	GnomeCalendar *cal = data;
1027
	struct tm tmp_tm = { 0 };
1028
	struct icaltimetype tt;
1029
1030
	g_return_val_if_fail (cal != NULL, tmp_tm);
1031
	g_return_val_if_fail (GNOME_IS_CALENDAR (cal), tmp_tm);
1032
1033
	tt = icaltime_from_timet_with_zone (time (NULL), FALSE,
1034
					    cal->priv->zone);
1035
1036
	/* Now copy it to the struct tm and return it. */
1037
	tmp_tm = icaltimetype_to_tm (&tt);
1038
1039
	return tmp_tm;
1040
}
1041
1042
/* Callback used when the sexp changes in the calendar search bar */
1043
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1044
search_bar_sexp_changed_cb (CalSearchBar *cal_search, const gchar *sexp, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
1045
{
1046
	GnomeCalendar *gcal;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1047
	const gchar *d_sexp = "occur-in-time-range?";
1 by Sebastien Bacher
Import upstream version 2.5.3
1048
1049
	gcal = GNOME_CALENDAR (data);
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
1050
1051
	/* Choose List view if the search made in the search bar is based on date */
1.1.64 by Sebastien Bacher
Import upstream version 2.27.5
1052
	if (sexp != NULL && strstr (sexp, d_sexp ) != NULL) {
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
1053
		gcal->priv->lview_select_daten_range = FALSE;
1054
		gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator));
1055
		gnome_calendar_set_view (gcal, GNOME_CAL_LIST_VIEW);
1056
	} else {
1057
		gcal->priv->lview_select_daten_range = TRUE;
1058
		gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1059
	}
1060
1 by Sebastien Bacher
Import upstream version 2.5.3
1061
	set_search_query (gcal, sexp);
1062
}
1063
1064
/* Callback used when the selected category in the search bar changes */
1065
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1066
search_bar_category_changed_cb (CalSearchBar *cal_search, const gchar *category, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
1067
{
1068
	GnomeCalendar *gcal;
1069
	GnomeCalendarPrivate *priv;
1070
	ECalModel *model;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1071
	gint i;
1 by Sebastien Bacher
Import upstream version 2.5.3
1072
1073
	gcal = GNOME_CALENDAR (data);
1074
	priv = gcal->priv;
1075
1076
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
1077
		e_calendar_view_set_default_category (E_CALENDAR_VIEW (priv->views[i]),
1078
						 category);
1079
	}
1080
1081
	model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
1082
	e_cal_model_set_default_category (model, category);
1083
}
1084
1085
static void
1086
view_selection_changed_cb (GtkWidget *view, GnomeCalendar *gcal)
1087
{
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1088
	g_signal_emit (gcal, gnome_calendar_signals[CALENDAR_SELECTION_CHANGED], 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
1089
}
1090
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
1091
/**
1092
 * gnome_calendar_emit_user_created_signal
1093
 * Emits "user_created" signal on a gcal and use calendar as a store where was event created.
1094
 *
1095
 * @param instance Instance on which emit signal.
1096
 * @param gcal GnomeCalendar, it will store info about used calendar here.
1097
 * @param calendar Used calendar, where was event created.
1098
 **/
1099
void
1100
gnome_calendar_emit_user_created_signal (gpointer instance, GnomeCalendar *gcal, ECal *calendar)
1101
{
1102
	GnomeCalendarPrivate *priv;
1103
1104
	g_return_if_fail (gcal != NULL);
1105
1106
	priv = gcal->priv;
1107
	priv->user_created_cal = calendar;
1108
	g_signal_emit_by_name (instance, "user_created");
1109
	priv->user_created_cal = NULL;
1110
}
1111
1 by Sebastien Bacher
Import upstream version 2.5.3
1112
static void
1113
user_created_cb (GtkWidget *view, GnomeCalendar *gcal)
1114
{
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1115
	GnomeCalendarPrivate *priv;
1 by Sebastien Bacher
Import upstream version 2.5.3
1116
	ECal *ecal;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1117
1118
	priv = gcal->priv;
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
1119
	ecal = priv->user_created_cal;
1120
1121
	if (!ecal) {
1122
		ECalModel *model;
1123
1124
		model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
1125
		ecal = e_cal_model_get_default_client (model);
1126
	}
1 by Sebastien Bacher
Import upstream version 2.5.3
1127
1128
	gnome_calendar_add_source (gcal, E_CAL_SOURCE_TYPE_EVENT, e_cal_get_source (ecal));
1129
}
1130
1131
/* Callback used when the taskpad receives a focus event.  We emit the
1132
 * corresponding signal so that parents can change the menus as appropriate.
1133
 */
1134
static gint
1135
table_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
1136
{
1137
	GnomeCalendar *gcal;
1138
1139
	gcal = GNOME_CALENDAR (data);
1140
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1141
	g_signal_emit (gcal, gnome_calendar_signals [TASKPAD_FOCUS_CHANGE], 0,
1142
		       event->in ? TRUE : FALSE);
1 by Sebastien Bacher
Import upstream version 2.5.3
1143
1144
	return FALSE;
1145
}
1146
1147
static gint
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1148
memo_canvas_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
1149
{
1150
	GnomeCalendar *gcal;
1151
1152
	gcal = GNOME_CALENDAR (data);
1153
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1154
	g_signal_emit (gcal, gnome_calendar_signals [MEMOPAD_FOCUS_CHANGE], 0,
1155
		       event->in ? TRUE : FALSE);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1156
1157
	return FALSE;
1158
}
1159
1160
static gint
1 by Sebastien Bacher
Import upstream version 2.5.3
1161
calendar_focus_change_cb (GtkWidget *widget, GdkEventFocus *event, gpointer data)
1162
{
1163
	GnomeCalendar *gcal;
1164
1165
	gcal = GNOME_CALENDAR (data);
1166
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1167
	g_signal_emit (gcal, gnome_calendar_signals [CALENDAR_FOCUS_CHANGE], 0,
1168
		       event->in ? TRUE : FALSE);
1 by Sebastien Bacher
Import upstream version 2.5.3
1169
1170
	return FALSE;
1171
}
1172
1173
/* Connects to the focus change signals of a day view widget */
1174
static void
1175
connect_day_view_focus (GnomeCalendar *gcal, EDayView *dv)
1176
{
1177
	g_signal_connect_after (dv->top_canvas, "focus_in_event",
1178
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1179
	g_signal_connect_after (dv->top_canvas, "focus_out_event",
1180
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1181
1182
	g_signal_connect_after (dv->main_canvas, "focus_in_event",
1183
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1184
	g_signal_connect_after (dv->main_canvas, "focus_out_event",
1185
				G_CALLBACK (calendar_focus_change_cb), gcal);
1186
}
1187
1188
/* Connects to the focus change signals of a week view widget */
1189
static void
1190
connect_week_view_focus (GnomeCalendar *gcal, EWeekView *wv)
1191
{
1192
	if (!E_IS_WEEK_VIEW (wv))
1193
		return;
1194
1195
	g_signal_connect (wv->main_canvas, "focus_in_event",
1196
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1197
	g_signal_connect (wv->main_canvas, "focus_out_event",
1198
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1199
}
1200
1201
static void
1202
connect_list_view_focus (GnomeCalendar *gcal, ECalListView *lv)
1203
{
1204
	ETable *etable;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1205
1 by Sebastien Bacher
Import upstream version 2.5.3
1206
	etable = e_table_scrolled_get_table (lv->table_scrolled);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1207
1 by Sebastien Bacher
Import upstream version 2.5.3
1208
	g_signal_connect (etable->table_canvas, "focus_in_event",
1209
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1210
	g_signal_connect (etable->table_canvas, "focus_out_event",
1211
			  G_CALLBACK (calendar_focus_change_cb), gcal);
1212
}
1213
1214
/* Callback used when the selection in the taskpad table changes.  We just proxy
1215
 * the signal with our own one.
1216
 */
1217
static void
1218
table_selection_change_cb (ETable *etable, gpointer data)
1219
{
1220
	GnomeCalendar *gcal;
1221
1222
	gcal = GNOME_CALENDAR (data);
1223
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1224
	g_signal_emit (gcal, gnome_calendar_signals[TASKPAD_SELECTION_CHANGED], 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
1225
}
1226
1227
static void
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1228
memo_selection_change_cb (ETable *etable, gpointer data)
1229
{
1230
	GnomeCalendar *gcal;
1231
1232
	gcal = GNOME_CALENDAR (data);
1233
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1234
	g_signal_emit (gcal, gnome_calendar_signals[MEMOPAD_SELECTION_CHANGED], 0);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1235
}
1236
1237
static void
1 by Sebastien Bacher
Import upstream version 2.5.3
1238
set_week_start (GnomeCalendar *calendar)
1239
{
1240
	GnomeCalendarPrivate *priv;
1241
1242
	priv = calendar->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1243
1 by Sebastien Bacher
Import upstream version 2.5.3
1244
	priv->week_start = calendar_config_get_week_start_day ();
1245
1246
	/* Only do this if views exist */
1247
	if (priv->day_view && priv->work_week_view && priv->week_view && priv->month_view && priv->list_view) {
1248
		update_view_times (calendar, priv->base_view_time);
1249
		gnome_calendar_update_date_navigator (calendar);
1250
		gnome_calendar_notify_dates_shown_changed (calendar);
1251
	}
1252
}
1253
1254
static void
1255
week_start_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
1256
{
1257
	GnomeCalendar *calendar = data;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1258
1 by Sebastien Bacher
Import upstream version 2.5.3
1259
	set_week_start (calendar);
1260
}
1261
1262
static void
1263
set_working_days (GnomeCalendar *calendar)
1264
{
1265
	GnomeCalendarPrivate *priv;
1266
1267
	priv = calendar->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1268
1 by Sebastien Bacher
Import upstream version 2.5.3
1269
	/* Only do this if views exist */
1270
	if (priv->day_view && priv->work_week_view && priv->week_view && priv->month_view && priv->list_view) {
1271
		update_view_times (calendar, priv->base_view_time);
1272
		gnome_calendar_update_date_navigator (calendar);
1273
		gnome_calendar_notify_dates_shown_changed (calendar);
1274
	}
1275
}
1276
1277
static void
1278
working_days_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
1279
{
1280
	GnomeCalendar *calendar = data;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1281
1 by Sebastien Bacher
Import upstream version 2.5.3
1282
	set_working_days (calendar);
1283
}
1284
1285
static void
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1286
set_timezone (GnomeCalendar *calendar)
1 by Sebastien Bacher
Import upstream version 2.5.3
1287
{
1288
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1289
	gint i;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1290
1 by Sebastien Bacher
Import upstream version 2.5.3
1291
	priv = calendar->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1292
1 by Sebastien Bacher
Import upstream version 2.5.3
1293
	priv->zone = calendar_config_get_icaltimezone ();
1294
1295
	for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
1296
		GList *l;
1297
1298
		for (l = priv->clients_list[i]; l != NULL; l = l->next) {
1299
			ECal *client = l->data;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1300
1 by Sebastien Bacher
Import upstream version 2.5.3
1301
			if (e_cal_get_load_state (client) == E_CAL_LOAD_LOADED)
1302
				/* FIXME Error checking */
1303
				e_cal_set_default_timezone (client, priv->zone, NULL);
1304
		}
1305
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1306
		if (priv->default_client[i]
1 by Sebastien Bacher
Import upstream version 2.5.3
1307
		    && e_cal_get_load_state (priv->default_client[i]) == E_CAL_LOAD_LOADED)
1308
			/* FIXME Error checking */
1309
			e_cal_set_default_timezone (priv->default_client[i], priv->zone, NULL);
1310
	}
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1311
1312
	if (priv->views [priv->current_view_type])
1313
		e_calendar_view_set_timezone (priv->views [priv->current_view_type], priv->zone);
1 by Sebastien Bacher
Import upstream version 2.5.3
1314
}
1315
1316
static void
1317
timezone_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
1318
{
1319
	GnomeCalendar *calendar = data;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1320
1 by Sebastien Bacher
Import upstream version 2.5.3
1321
	set_timezone (calendar);
1322
}
1323
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1324
struct _mupdate_todo_msg {
1325
	Message header;
1326
	GnomeCalendar *gcal;
1327
};
1328
1 by Sebastien Bacher
Import upstream version 2.5.3
1329
static void
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1330
update_todo_view_async (struct _mupdate_todo_msg *msg)
1 by Sebastien Bacher
Import upstream version 2.5.3
1331
{
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1332
	GnomeCalendar *gcal;
1 by Sebastien Bacher
Import upstream version 2.5.3
1333
	GnomeCalendarPrivate *priv;
1334
	ECalModel *model;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1335
	gchar *sexp = NULL;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1336
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1337
	g_return_if_fail (msg != NULL);
1338
1339
	gcal = msg->gcal;
1 by Sebastien Bacher
Import upstream version 2.5.3
1340
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1341
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1342
	g_mutex_lock (priv->todo_update_lock);
1343
1 by Sebastien Bacher
Import upstream version 2.5.3
1344
	/* Set the query on the task pad */
1345
	if (priv->todo_sexp) {
1346
		g_free (priv->todo_sexp);
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1347
		priv->todo_sexp = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
1348
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1349
1 by Sebastien Bacher
Import upstream version 2.5.3
1350
	model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1351
1 by Sebastien Bacher
Import upstream version 2.5.3
1352
	if ((sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE)) != NULL) {
1.1.37 by Sebastien Bacher
Import upstream version 2.21.4
1353
		priv->todo_sexp = g_strdup_printf ("(and %s %s)", sexp,
1354
							priv->sexp ? priv->sexp : "");
1 by Sebastien Bacher
Import upstream version 2.5.3
1355
		e_cal_model_set_search_query (model, priv->todo_sexp);
1356
		g_free (sexp);
1357
	} else {
1358
		priv->todo_sexp = g_strdup (priv->sexp);
1359
		e_cal_model_set_search_query (model, priv->todo_sexp);
1360
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1361
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1362
	g_mutex_unlock (priv->todo_update_lock);
1363
1364
	g_object_unref (msg->gcal);
1365
	g_slice_free (struct _mupdate_todo_msg, msg);
1366
}
1367
1368
static void
1369
update_todo_view (GnomeCalendar *gcal)
1370
{
1371
	struct _mupdate_todo_msg *msg;
1372
1373
	msg = g_slice_new0 (struct _mupdate_todo_msg);
1374
	msg->header.func = (MessageFunc) update_todo_view_async;
1375
	msg->gcal = g_object_ref (gcal);
1376
1377
	message_push ((Message *) msg);
1 by Sebastien Bacher
Import upstream version 2.5.3
1378
}
1379
1380
static void
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1381
update_memo_view (GnomeCalendar *gcal)
1382
{
1383
	GnomeCalendarPrivate *priv;
1384
	ECalModel *model, *view_model;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1385
	time_t start, end;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1386
	gchar *iso_start, *iso_end;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1387
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1388
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1389
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1390
	/* Set the query on the memo pad*/
1391
	model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
1392
	view_model = e_calendar_view_get_model(priv->views[priv->current_view_type]);
1393
	e_cal_model_get_time_range (view_model, &start, &end);
1394
1395
	if (start != -1 && end != -1) {
1396
		iso_start = isodate_from_time_t (start);
1397
		iso_end = isodate_from_time_t (end);
1398
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
1399
		if (priv->memo_sexp) {
1400
			g_free (priv->memo_sexp);
1401
		}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1402
1.1.37 by Sebastien Bacher
Import upstream version 2.21.4
1403
		priv->memo_sexp = g_strdup_printf ("(or (not (has-start?)) (and (occur-in-time-range? (make-time \"%s\")"
1404
				" (make-time \"%s\"))"
1405
				"  %s))",
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1406
				iso_start, iso_end,
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1407
				priv->sexp ? priv->sexp : "");
1.1.37 by Sebastien Bacher
Import upstream version 2.21.4
1408
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1409
		e_cal_model_set_search_query (model, priv->memo_sexp);
1410
1411
		g_free (iso_start);
1412
		g_free (iso_end);
1413
	}
1414
}
1415
1416
static void
1 by Sebastien Bacher
Import upstream version 2.5.3
1417
process_completed_tasks (GnomeCalendar *gcal, gboolean config_changed)
1418
{
1419
	GnomeCalendarPrivate *priv;
1420
1421
	g_return_if_fail (gcal != NULL);
1422
	g_return_if_fail (GNOME_IS_CALENDAR(gcal));
1423
1424
	priv = gcal->priv;
1425
1426
	e_calendar_table_process_completed_tasks (E_CALENDAR_TABLE (priv->todo), priv->clients_list[E_CAL_SOURCE_TYPE_TODO], config_changed);
1427
}
1428
1429
static gboolean
1430
update_todo_view_cb (GnomeCalendar *gcal)
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1431
{
1 by Sebastien Bacher
Import upstream version 2.5.3
1432
	ECalModel *model;
1433
1434
	model = e_calendar_table_get_model (E_CALENDAR_TABLE (gcal->priv->todo));
1435
1436
	process_completed_tasks (gcal, FALSE);
1437
	e_cal_model_tasks_update_due_tasks (E_CAL_MODEL_TASKS (model));
1438
1439
	return TRUE;
1440
}
1441
1442
static gboolean
1443
update_marcus_bains_line_cb (GnomeCalendar *gcal)
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1444
{
1 by Sebastien Bacher
Import upstream version 2.5.3
1445
	GnomeCalendarPrivate *priv;
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
1446
	time_t now, day_begin;
1 by Sebastien Bacher
Import upstream version 2.5.3
1447
1448
	priv = gcal->priv;
1449
1450
	if ((priv->current_view_type == GNOME_CAL_DAY_VIEW) ||
1451
	    (priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW)) {
1452
		e_day_view_update_marcus_bains (E_DAY_VIEW (gnome_calendar_get_current_view_widget (gcal)));
1453
	}
1454
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
1455
	time (&now);
1456
	day_begin = time_day_begin (now);
1457
1458
	/* check in the first two minutes */
1459
	if (now >= day_begin && now <= day_begin + 120) {
1460
		ECalendarView *view = priv->views[priv->current_view_type];
1461
		time_t start_time = 0, end_time = 0;
1462
1463
		g_return_val_if_fail (view != NULL, TRUE);
1464
1465
		e_calendar_view_get_selected_time_range (view, &start_time, &end_time);
1466
1467
		if (end_time >= time_add_day (day_begin, -1) && start_time <= day_begin) {
1468
			gnome_calendar_goto (gcal, now);
1469
		}
1470
	}
1471
1 by Sebastien Bacher
Import upstream version 2.5.3
1472
	return TRUE;
1473
}
1474
1475
static void
1476
config_hide_completed_tasks_changed_cb (GConfClient *client, guint id, GConfEntry *entry, gpointer data)
1477
{
1478
	process_completed_tasks (data, TRUE);
1479
}
1480
1481
static void
1482
setup_config (GnomeCalendar *calendar)
1483
{
1484
	GnomeCalendarPrivate *priv;
1485
	guint not;
1486
1487
	priv = calendar->priv;
1488
1489
	/* Week Start */
1490
	set_week_start (calendar);
1491
	not = calendar_config_add_notification_week_start_day (week_start_changed_cb, calendar);
1492
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1493
1494
	/* Working Days */
1495
	set_working_days (calendar);
1496
	not = calendar_config_add_notification_working_days (working_days_changed_cb, calendar);
1497
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1498
1499
	/* Timezone */
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1500
	set_timezone (calendar);
1 by Sebastien Bacher
Import upstream version 2.5.3
1501
	not = calendar_config_add_notification_timezone (timezone_changed_cb, calendar);
1502
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1503
1504
	/* Hide completed tasks */
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1505
	not = calendar_config_add_notification_hide_completed_tasks (config_hide_completed_tasks_changed_cb,
1506
							      calendar);
1507
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1508
1509
	not = calendar_config_add_notification_hide_completed_tasks_units (config_hide_completed_tasks_changed_cb,
1510
							      calendar);
1511
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1512
1513
	not = calendar_config_add_notification_hide_completed_tasks_value (config_hide_completed_tasks_changed_cb,
1514
							      calendar);
1515
	priv->notifications = g_list_prepend (priv->notifications, GUINT_TO_POINTER (not));
1516
1 by Sebastien Bacher
Import upstream version 2.5.3
1517
	/* Pane positions */
1518
	priv->hpane_pos = calendar_config_get_hpane_pos ();
1519
	priv->vpane_pos = calendar_config_get_vpane_pos ();
1520
	priv->hpane_pos_month_view = calendar_config_get_month_hpane_pos ();
1521
	priv->vpane_pos_month_view = calendar_config_get_month_vpane_pos ();
1522
}
1523
1524
static void
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1525
update_adjustment (GnomeCalendar *gcal, GtkAdjustment *adjustment, EWeekView *week_view)
1 by Sebastien Bacher
Import upstream version 2.5.3
1526
{
1527
	GDate date;
1528
	gint week_offset;
1529
	struct icaltimetype start_tt = icaltime_null_time ();
1530
	time_t lower;
1531
	guint32 old_first_day_julian, new_first_day_julian;
1532
1533
	/* If we don't have a valid date set yet, just return. */
1534
	if (!g_date_valid (&week_view->first_day_shown))
1535
		return;
1536
1537
	/* Determine the first date shown. */
1538
	date = week_view->base_date;
1539
	week_offset = floor (adjustment->value + 0.5);
1540
	g_date_add_days (&date, week_offset * 7);
1541
1542
	/* Convert the old & new first days shown to julian values. */
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
1543
	old_first_day_julian = g_date_get_julian (&week_view->first_day_shown);
1544
	new_first_day_julian = g_date_get_julian (&date);
1 by Sebastien Bacher
Import upstream version 2.5.3
1545
1546
	/* If we are already showing the date, just return. */
1547
	if (old_first_day_julian == new_first_day_julian)
1548
		return;
1549
1550
	/* Convert it to a time_t. */
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
1551
	start_tt.year = g_date_get_year (&date);
1552
	start_tt.month = g_date_get_month (&date);
1553
	start_tt.day = g_date_get_day (&date);
1 by Sebastien Bacher
Import upstream version 2.5.3
1554
1555
	lower = icaltime_as_timet_with_zone (start_tt, gcal->priv->zone);
1556
1557
	e_week_view_set_update_base_date (week_view, FALSE);
1558
	update_view_times (gcal, lower);
1559
	gnome_calendar_update_date_navigator (gcal);
1560
	gnome_calendar_notify_dates_shown_changed (gcal);
1561
	e_week_view_set_update_base_date (week_view, TRUE);
1562
}
1563
1564
static void
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1565
week_view_adjustment_changed_cb (GtkAdjustment *adjustment, GnomeCalendar *gcal)
1 by Sebastien Bacher
Import upstream version 2.5.3
1566
{
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1567
	update_adjustment (gcal, adjustment, E_WEEK_VIEW (gcal->priv->week_view));
1 by Sebastien Bacher
Import upstream version 2.5.3
1568
}
1569
1570
static void
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1571
month_view_adjustment_changed_cb (GtkAdjustment *adjustment, GnomeCalendar *gcal)
1 by Sebastien Bacher
Import upstream version 2.5.3
1572
{
1573
	update_adjustment (gcal, adjustment, E_WEEK_VIEW (gcal->priv->month_view));
1574
}
1575
1576
static void
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1577
categories_changed_cb (gpointer object, gpointer user_data)
1 by Sebastien Bacher
Import upstream version 2.5.3
1578
{
1579
	GList *cat_list;
1580
	GPtrArray *cat_array;
1581
	GnomeCalendarPrivate *priv;
1582
	GnomeCalendar *gcal = user_data;
1583
1584
	priv = gcal->priv;
1585
1586
	cat_array = g_ptr_array_new ();
1587
	cat_list = e_categories_get_list ();
1588
	while (cat_list != NULL) {
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1589
		if (e_categories_is_searchable ((const gchar *) cat_list->data))
1 by Sebastien Bacher
Import upstream version 2.5.3
1590
			g_ptr_array_add (cat_array, cat_list->data);
1591
		cat_list = g_list_remove (cat_list, cat_list->data);
1592
	}
1593
1594
	cal_search_bar_set_categories ((CalSearchBar *)priv->search_bar, cat_array);
1595
1596
	g_ptr_array_free (cat_array, TRUE);
1597
}
1598
1599
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1600
view_progress_cb (ECalModel *model, const gchar *message, gint percent, ECalSourceType type, GnomeCalendar *gcal)
1 by Sebastien Bacher
Import upstream version 2.5.3
1601
{
1602
	if (type == E_CAL_SOURCE_TYPE_EVENT) {
1603
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), message, percent);
1604
	} else if (type == E_CAL_SOURCE_TYPE_TODO) {
1605
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), message, percent);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1606
	} else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
1607
		e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), message);
1 by Sebastien Bacher
Import upstream version 2.5.3
1608
	}
1609
}
1610
1611
static void
1612
view_done_cb (ECalModel *model, ECalendarStatus status, ECalSourceType type, GnomeCalendar *gcal)
1613
{
1614
	if (type == E_CAL_SOURCE_TYPE_EVENT) {
1615
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (gcal->priv->week_view), NULL, -1);
1616
	} else if (type == E_CAL_SOURCE_TYPE_TODO) {
1617
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (gcal->priv->todo), NULL, -1);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1618
	} else if (type == E_CAL_SOURCE_TYPE_JOURNAL) {
1619
		e_memo_table_set_status_message (E_MEMO_TABLE (gcal->priv->memo), NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
1620
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1621
1 by Sebastien Bacher
Import upstream version 2.5.3
1622
}
1623
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1624
GtkWidget *
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1625
gnome_calendar_get_tag (GnomeCalendar *gcal)
1626
{
1.1.15 by Sebastien Bacher
Import upstream version 2.9.2
1627
	return GTK_WIDGET (gcal->priv->date_navigator);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1628
}
1629
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1630
static time_t
1631
gc_get_default_time (ECalModel *model, gpointer user_data)
1632
{
1633
	GnomeCalendar *gcal = user_data;
1634
	time_t res = 0, end;
1635
1636
	g_return_val_if_fail (model != NULL, 0);
1637
	g_return_val_if_fail (GNOME_IS_CALENDAR (user_data), 0);
1638
1639
	gnome_calendar_get_current_time_range (gcal, &res, &end);
1640
1641
	return res;
1642
}
1643
1 by Sebastien Bacher
Import upstream version 2.5.3
1644
static void
1645
setup_widgets (GnomeCalendar *gcal)
1646
{
1647
	GnomeCalendarPrivate *priv;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1648
	GtkWidget *w, *sep;
1 by Sebastien Bacher
Import upstream version 2.5.3
1649
	gchar *filename;
1650
	ETable *etable;
1651
	GtkAdjustment *adjustment;
1652
	ECalModel *w_model;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1653
	GtkWidget *vbox;
1654
	GtkWidget *label;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1655
	ECalModel *cal_model;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1656
	gint i;
1657
	gchar *tmp;
1 by Sebastien Bacher
Import upstream version 2.5.3
1658
1659
	priv = gcal->priv;
1660
1661
	priv->search_bar = cal_search_bar_new (CAL_SEARCH_CALENDAR_DEFAULT);
1662
	g_signal_connect (priv->search_bar, "sexp_changed",
1663
			  G_CALLBACK (search_bar_sexp_changed_cb), gcal);
1664
	g_signal_connect (priv->search_bar, "category_changed",
1665
			  G_CALLBACK (search_bar_category_changed_cb), gcal);
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1666
	categories_changed_cb (NULL, gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
1667
1668
	gtk_widget_show (priv->search_bar);
1669
	gtk_box_pack_start (GTK_BOX (gcal), priv->search_bar, FALSE, FALSE, 6);
1670
1671
	/* The main HPaned, with the notebook of calendar views on the left
1672
	   and the ECalendar and ToDo list on the right. */
1673
	priv->hpane = gtk_hpaned_new ();
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1674
	g_signal_connect_after(priv->hpane, "realize",
1 by Sebastien Bacher
Import upstream version 2.5.3
1675
			       G_CALLBACK(gnome_calendar_hpane_realized), gcal);
1676
	g_signal_connect (priv->hpane, "button_release_event",
1677
			  G_CALLBACK (gnome_calendar_hpane_resized), gcal);
1678
	gtk_widget_show (priv->hpane);
1679
	gtk_box_pack_start (GTK_BOX (gcal), priv->hpane, TRUE, TRUE, 6);
1680
1681
	/* The Notebook containing the 4 calendar views. */
1682
	priv->notebook = gtk_notebook_new ();
1683
	gtk_notebook_set_show_border (GTK_NOTEBOOK (priv->notebook), FALSE);
1684
	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (priv->notebook), FALSE);
1685
	gtk_widget_show (priv->notebook);
1686
	gtk_paned_pack1 (GTK_PANED (priv->hpane), priv->notebook, FALSE, TRUE);
1687
1688
	/* The ECalendar. */
1689
	w = e_calendar_new ();
1690
	priv->date_navigator = E_CALENDAR (w);
1691
	priv->date_navigator_config = e_mini_calendar_config_new (priv->date_navigator);
1692
	e_calendar_item_set_days_start_week_sel (priv->date_navigator->calitem, 9);
1693
	e_calendar_item_set_max_days_sel (priv->date_navigator->calitem, 42);
1694
	gtk_widget_show (w);
1695
	e_calendar_item_set_get_time_callback (priv->date_navigator->calitem,
1696
					       (ECalendarItemGetTimeCallback) get_current_time,
1697
					       gcal, NULL);
1698
1699
	g_signal_connect (priv->date_navigator->calitem, "selection_changed",
1700
			  G_CALLBACK (gnome_calendar_on_date_navigator_selection_changed), gcal);
1701
	g_signal_connect (priv->date_navigator->calitem, "date_range_changed",
1702
			  G_CALLBACK (gnome_calendar_on_date_navigator_date_range_changed), gcal);
1703
	g_signal_connect (w, "scroll-event",
1704
			  G_CALLBACK (gnome_calendar_date_navigator_scrolled), gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1705
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1706
	/* The VPaned widget, to contain the ToDo list & Memo list */
1707
	priv->vpane = gtk_vpaned_new ();
1708
	g_signal_connect_after (priv->vpane, "realize",
1709
				G_CALLBACK(gnome_calendar_vpane_realized), gcal);
1710
	g_signal_connect (priv->vpane, "button_release_event",
1711
			  G_CALLBACK (gnome_calendar_vpane_resized), gcal);
1712
	gtk_widget_show (priv->vpane);
1713
	gtk_paned_pack2 (GTK_PANED (priv->hpane), priv->vpane, TRUE, TRUE);
1 by Sebastien Bacher
Import upstream version 2.5.3
1714
1715
	/* The ToDo list. */
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1716
	vbox = gtk_vbox_new (FALSE, 0);
1717
	sep = gtk_hseparator_new ();
1718
	gtk_box_pack_start ((GtkBox *)vbox, sep, FALSE, TRUE, 0);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1719
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1720
	label = gtk_label_new (NULL);
1.1.13 by Sebastien Bacher
Import upstream version 2.8.0
1721
	tmp = g_strdup_printf ("<b> %s </b>", _("Tasks"));
1722
	gtk_label_set_markup ((GtkLabel *)label, tmp);
1723
	g_free (tmp);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1724
	gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1725
1 by Sebastien Bacher
Import upstream version 2.5.3
1726
	priv->todo = e_calendar_table_new ();
1727
	priv->todo_config = e_calendar_table_config_new (E_CALENDAR_TABLE (priv->todo));
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1728
	gtk_paned_pack1 (GTK_PANED (priv->vpane), vbox, FALSE, FALSE);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1729
	gtk_box_pack_end ((GtkBox *)vbox, priv->todo, TRUE, TRUE, 0);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1730
1 by Sebastien Bacher
Import upstream version 2.5.3
1731
	gtk_widget_show (priv->todo);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1732
	gtk_widget_show (label);
1733
	gtk_widget_show (vbox);
1734
	gtk_widget_show (sep);
1 by Sebastien Bacher
Import upstream version 2.5.3
1735
1736
	filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
1737
				     "TaskPad", NULL);
1738
	e_calendar_table_load_state (E_CALENDAR_TABLE (priv->todo), filename);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1739
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1740
	/* update_todo_view (gcal); */
1 by Sebastien Bacher
Import upstream version 2.5.3
1741
	g_free (filename);
1742
1743
	etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
1744
	g_signal_connect (etable->table_canvas, "focus_in_event",
1745
			  G_CALLBACK (table_canvas_focus_change_cb), gcal);
1746
	g_signal_connect (etable->table_canvas, "focus_out_event",
1747
			  G_CALLBACK (table_canvas_focus_change_cb), gcal);
1748
1749
	g_signal_connect (etable, "selection_change",
1750
			  G_CALLBACK (table_selection_change_cb), gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1751
1 by Sebastien Bacher
Import upstream version 2.5.3
1752
	g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_progress",
1753
				G_CALLBACK (view_progress_cb), gcal);
1754
	g_signal_connect (e_calendar_table_get_model ((ECalendarTable *)priv->todo), "cal_view_done",
1755
				G_CALLBACK (view_done_cb), gcal);
1756
1757
	/* Timeout check to hide completed items */
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1758
	priv->update_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_todo_view_cb, gcal, NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
1759
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1760
	/* Create the model for the views */
1761
	cal_model = (ECalModel *) e_cal_model_calendar_new ();
1762
	e_cal_model_set_flags (cal_model, E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES);
1763
1 by Sebastien Bacher
Import upstream version 2.5.3
1764
	/* The Day View. */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1765
	priv->day_view = e_day_view_new (cal_model);
1 by Sebastien Bacher
Import upstream version 2.5.3
1766
	e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->day_view), gcal);
1767
	e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->day_view), priv->zone);
1768
	g_signal_connect (priv->day_view, "selection_changed",
1769
			  G_CALLBACK (view_selection_changed_cb), gcal);
1770
	connect_day_view_focus (gcal, E_DAY_VIEW (priv->day_view));
1771
1772
	/* The Work Week View. */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1773
	priv->work_week_view = e_day_view_new (cal_model);
1 by Sebastien Bacher
Import upstream version 2.5.3
1774
	e_day_view_set_work_week_view (E_DAY_VIEW (priv->work_week_view),
1775
				       TRUE);
1776
	e_day_view_set_days_shown (E_DAY_VIEW (priv->work_week_view), 5);
1777
	e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->work_week_view), gcal);
1778
	e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->work_week_view), priv->zone);
1779
	connect_day_view_focus (gcal, E_DAY_VIEW (priv->work_week_view));
1780
1781
	/* The Marcus Bains line */
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1782
	priv->update_marcus_bains_line_timeout = g_timeout_add_full (G_PRIORITY_LOW, 60000, (GSourceFunc) update_marcus_bains_line_cb, gcal, NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
1783
1784
	/* The Week View. */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1785
	priv->week_view = e_week_view_new (cal_model);
1 by Sebastien Bacher
Import upstream version 2.5.3
1786
	e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->week_view), gcal);
1787
	e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->week_view), priv->zone);
1788
	g_signal_connect (priv->week_view, "selection_changed",
1789
			  G_CALLBACK (view_selection_changed_cb), gcal);
1790
1791
	connect_week_view_focus (gcal, E_WEEK_VIEW (priv->week_view));
1792
1793
	adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->week_view)->vscrollbar));
1794
	g_signal_connect (adjustment, "value_changed",
1795
			  G_CALLBACK (week_view_adjustment_changed_cb),
1796
			  gcal);
1797
	w_model = e_calendar_view_get_model ((ECalendarView *)priv->week_view);
1798
	g_signal_connect (w_model, "cal_view_progress",
1799
				G_CALLBACK (view_progress_cb), gcal);
1800
	g_signal_connect (w_model, "cal_view_done",
1801
				G_CALLBACK (view_done_cb), gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1802
1 by Sebastien Bacher
Import upstream version 2.5.3
1803
	/* The Month View. */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1804
	priv->month_view = e_week_view_new (cal_model);
1 by Sebastien Bacher
Import upstream version 2.5.3
1805
	e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->month_view), gcal);
1806
	e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->month_view), priv->zone);
1807
	e_week_view_set_multi_week_view (E_WEEK_VIEW (priv->month_view), TRUE);
1808
	e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 6);
1809
	g_signal_connect (priv->month_view, "selection_changed",
1810
			  G_CALLBACK (view_selection_changed_cb), gcal);
1811
1812
	connect_week_view_focus (gcal, E_WEEK_VIEW (priv->month_view));
1813
1814
	adjustment = gtk_range_get_adjustment (GTK_RANGE (E_WEEK_VIEW (priv->month_view)->vscrollbar));
1815
	g_signal_connect (adjustment, "value_changed",
1816
			  G_CALLBACK (month_view_adjustment_changed_cb),
1817
			  gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1818
1 by Sebastien Bacher
Import upstream version 2.5.3
1819
	/* The List View. */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
1820
	priv->list_view = e_cal_list_view_new (cal_model);
1 by Sebastien Bacher
Import upstream version 2.5.3
1821
1822
	e_calendar_view_set_calendar (E_CALENDAR_VIEW (priv->list_view), gcal);
1823
	e_calendar_view_set_timezone (E_CALENDAR_VIEW (priv->list_view), priv->zone);
1824
	g_signal_connect (priv->list_view, "selection_changed",
1825
			  G_CALLBACK (view_selection_changed_cb), gcal);
1826
1827
	connect_list_view_focus (gcal, E_CAL_LIST_VIEW (priv->list_view));
1828
1829
	priv->views[GNOME_CAL_DAY_VIEW] = E_CALENDAR_VIEW (priv->day_view);
1830
	priv->configs[GNOME_CAL_DAY_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_DAY_VIEW])));
1831
	priv->views[GNOME_CAL_WORK_WEEK_VIEW] = E_CALENDAR_VIEW (priv->work_week_view);
1832
	priv->configs[GNOME_CAL_WORK_WEEK_VIEW] = G_OBJECT (e_day_view_config_new (E_DAY_VIEW (priv->views[GNOME_CAL_WORK_WEEK_VIEW])));
1833
	priv->views[GNOME_CAL_WEEK_VIEW] = E_CALENDAR_VIEW (priv->week_view);
1834
	priv->configs[GNOME_CAL_WEEK_VIEW] = G_OBJECT (e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_WEEK_VIEW])));
1835
	priv->views[GNOME_CAL_MONTH_VIEW] = E_CALENDAR_VIEW (priv->month_view);
1836
	priv->configs[GNOME_CAL_MONTH_VIEW] = G_OBJECT (e_week_view_config_new (E_WEEK_VIEW (priv->views[GNOME_CAL_MONTH_VIEW])));
1837
	priv->views[GNOME_CAL_LIST_VIEW] = E_CALENDAR_VIEW (priv->list_view);
1838
	priv->configs[GNOME_CAL_LIST_VIEW] = G_OBJECT (e_cal_list_view_config_new (E_CAL_LIST_VIEW (priv->views[GNOME_CAL_LIST_VIEW])));
1839
1840
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
1841
		gtk_notebook_append_page (GTK_NOTEBOOK (priv->notebook),
1842
					  GTK_WIDGET (priv->views[i]), gtk_label_new (""));
1843
1844
		g_signal_connect (priv->views[i], "user_created",
1845
				  G_CALLBACK (user_created_cb), gcal);
1846
1847
		gtk_widget_show (GTK_WIDGET (priv->views[i]));
1848
	}
1849
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1850
	/* Memo view */
1851
	vbox = gtk_vbox_new (FALSE, 0);
1852
	label = gtk_label_new (NULL);
1.1.13 by Sebastien Bacher
Import upstream version 2.8.0
1853
	tmp = g_strdup_printf ("<b> %s </b>", _("Memos"));
1854
	gtk_label_set_markup ((GtkLabel *)label, tmp);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1855
	g_free (tmp);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1856
	gtk_box_pack_start ((GtkBox *)vbox, label, FALSE, TRUE, 0);
1857
	priv->memo = e_memo_table_new ();
1858
	priv->memo_config = e_memo_table_config_new (E_MEMO_TABLE (priv->memo));
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1859
	gtk_paned_pack2 (GTK_PANED (priv->vpane), vbox, TRUE, FALSE);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1860
	gtk_box_pack_end ((GtkBox *)vbox, priv->memo, TRUE, TRUE, 0);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1861
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1862
	gtk_widget_show (priv->memo);
1863
	gtk_widget_show (label);
1864
	gtk_widget_show (vbox);
1865
1866
	filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
1867
				     "MemoPad", NULL);
1868
	e_memo_table_load_state (E_MEMO_TABLE (priv->memo), filename);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1869
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1870
	e_cal_model_set_default_time_func (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), gc_get_default_time, gcal);
1871
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1872
	update_memo_view (gcal);
1873
	g_free (filename);
1874
1875
	etable = e_memo_table_get_table (E_MEMO_TABLE (priv->memo));
1876
	g_signal_connect (etable->table_canvas, "focus_in_event",
1877
			  G_CALLBACK (memo_canvas_focus_change_cb), gcal);
1878
	g_signal_connect (etable->table_canvas, "focus_out_event",
1879
			  G_CALLBACK (memo_canvas_focus_change_cb), gcal);
1880
1881
	g_signal_connect (etable, "selection_change",
1882
			  G_CALLBACK (memo_selection_change_cb), gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1883
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1884
	g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_progress",
1885
				G_CALLBACK (view_progress_cb), gcal);
1886
	g_signal_connect (e_memo_table_get_model ((EMemoTable *)priv->memo), "cal_view_done",
1887
				G_CALLBACK (view_done_cb), gcal);
1888
1 by Sebastien Bacher
Import upstream version 2.5.3
1889
}
1890
1891
/* Object initialization function for the gnome calendar */
1892
static void
1893
gnome_calendar_init (GnomeCalendar *gcal)
1894
{
1895
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1896
	gint i;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1897
1 by Sebastien Bacher
Import upstream version 2.5.3
1898
	priv = g_new0 (GnomeCalendarPrivate, 1);
1899
	gcal->priv = priv;
1900
1901
	for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++)
1902
		priv->clients[i] = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1903
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1904
	if (non_intrusive_error_table == NULL)
1905
		non_intrusive_error_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
1906
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1907
	e_categories_register_change_listener (G_CALLBACK (categories_changed_cb), gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
1908
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
1909
	priv->todo_update_lock = g_mutex_new ();
1910
1 by Sebastien Bacher
Import upstream version 2.5.3
1911
	priv->current_view_type = GNOME_CAL_DAY_VIEW;
1912
	priv->range_selected = FALSE;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
1913
	priv->lview_select_daten_range = TRUE;
1 by Sebastien Bacher
Import upstream version 2.5.3
1914
1915
	setup_config (gcal);
1916
	setup_widgets (gcal);
1917
1918
	priv->calendar_menu = e_cal_menu_new("org.gnome.evolution.calendar.view");
1919
	priv->taskpad_menu = e_cal_menu_new("org.gnome.evolution.calendar.taskpad");
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1920
	priv->memopad_menu = e_cal_menu_new ("org.gnome.evolution.calendar.memopad");
1 by Sebastien Bacher
Import upstream version 2.5.3
1921
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
1922
	priv->dn_queries_lock = g_mutex_new ();
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1923
	priv->dn_queries = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
1924
	priv->sexp = g_strdup ("#t"); /* Match all */
1925
	priv->todo_sexp = g_strdup ("#t");
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1926
	priv->memo_sexp = g_strdup ("#t");
1 by Sebastien Bacher
Import upstream version 2.5.3
1927
1928
	priv->view_instance = NULL;
1929
	priv->view_menus = NULL;
1930
1931
	priv->visible_start = -1;
1932
	priv->visible_end = -1;
1933
	priv->updating = FALSE;
1934
}
1935
1936
static void
1937
gnome_calendar_destroy (GtkObject *object)
1938
{
1939
	GnomeCalendar *gcal;
1940
	GnomeCalendarPrivate *priv;
1941
	gchar *filename;
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
1942
	ECalModel *cal_model;
1 by Sebastien Bacher
Import upstream version 2.5.3
1943
1944
	g_return_if_fail (object != NULL);
1945
	g_return_if_fail (GNOME_IS_CALENDAR (object));
1946
1947
	gcal = GNOME_CALENDAR (object);
1948
	priv = gcal->priv;
1949
1950
	if (priv) {
1951
		GList *l;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1952
		gint i;
1 by Sebastien Bacher
Import upstream version 2.5.3
1953
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
1954
		e_categories_unregister_change_listener (G_CALLBACK (categories_changed_cb), gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
1955
1956
		/* Clean up the clients */
1957
		for (i = 0; i < E_CAL_SOURCE_TYPE_LAST; i++) {
1958
			for (l = priv->clients_list[i]; l != NULL; l = l->next) {
1.1.58 by Sebastien Bacher
Import upstream version 2.25.92
1959
				ESource *source = e_cal_get_source (l->data);
1960
1 by Sebastien Bacher
Import upstream version 2.5.3
1961
				g_signal_handlers_disconnect_matched (l->data, G_SIGNAL_MATCH_DATA,
1962
								      0, 0, NULL, NULL, gcal);
1.1.58 by Sebastien Bacher
Import upstream version 2.25.92
1963
1964
				if (source)
1965
					g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
1966
			}
1967
1968
			g_hash_table_destroy (priv->clients[i]);
1969
			g_list_free (priv->clients_list[i]);
1970
1971
			priv->clients[i] = NULL;
1972
			priv->clients_list[i] = NULL;
1973
1974
			if (priv->default_client[i]) {
1.1.58 by Sebastien Bacher
Import upstream version 2.25.92
1975
				ESource *source = e_cal_get_source (priv->default_client[i]);
1976
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1977
				g_signal_handlers_disconnect_matched (priv->default_client[i],
1 by Sebastien Bacher
Import upstream version 2.5.3
1978
								      G_SIGNAL_MATCH_DATA,
1979
								      0, 0, NULL, NULL, gcal);
1.1.58 by Sebastien Bacher
Import upstream version 2.25.92
1980
1981
				if (source)
1982
					g_signal_handlers_disconnect_matched (source, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
1983
1 by Sebastien Bacher
Import upstream version 2.5.3
1984
				g_object_unref (priv->default_client[i]);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1985
			}
1 by Sebastien Bacher
Import upstream version 2.5.3
1986
			priv->default_client[i] = NULL;
1987
		}
1988
1989
		for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
1990
			if (priv->configs[i])
1 by Sebastien Bacher
Import upstream version 2.5.3
1991
				g_object_unref (priv->configs[i]);
1992
			priv->configs[i] = NULL;
1993
		}
1994
		g_object_unref (priv->date_navigator_config);
1995
		g_object_unref (priv->todo_config);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
1996
		g_object_unref (priv->memo_config);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
1997
1 by Sebastien Bacher
Import upstream version 2.5.3
1998
		for (l = priv->notifications; l; l = l->next)
1999
			calendar_config_remove_notification (GPOINTER_TO_UINT (l->data));
2000
		g_list_free (priv->notifications);
2001
		priv->notifications = NULL;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2002
1 by Sebastien Bacher
Import upstream version 2.5.3
2003
		/* Save the TaskPad layout. */
2004
		filename = g_build_filename (calendar_component_peek_config_directory (calendar_component_peek ()),
2005
					     "TaskPad", NULL);
2006
		e_calendar_table_save_state (E_CALENDAR_TABLE (priv->todo), filename);
2007
		g_free (filename);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2008
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2009
		/* Save the MemoPad layout. */
2010
		filename = g_build_filename (memos_component_peek_config_directory (memos_component_peek ()),
2011
					     "MemoPad", NULL);
2012
		e_memo_table_save_state (E_MEMO_TABLE (priv->memo), filename);
2013
		g_free (filename);
1 by Sebastien Bacher
Import upstream version 2.5.3
2014
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
2015
		g_mutex_lock (priv->dn_queries_lock);
1 by Sebastien Bacher
Import upstream version 2.5.3
2016
		if (priv->dn_queries) {
2017
			for (l = priv->dn_queries; l != NULL; l = l->next) {
2018
				g_signal_handlers_disconnect_matched ((ECalView *) l->data, G_SIGNAL_MATCH_DATA,
2019
								      0, 0, NULL, NULL, gcal);
2020
				g_object_unref (l->data);
2021
			}
2022
2023
			g_list_free (priv->dn_queries);
2024
			priv->dn_queries = NULL;
2025
		}
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
2026
		g_mutex_unlock (priv->dn_queries_lock);
2027
		g_mutex_free (priv->dn_queries_lock);
2028
		priv->dn_queries_lock = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
2029
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2030
		if (non_intrusive_error_table) {
2031
			g_hash_table_destroy (non_intrusive_error_table);
2032
			non_intrusive_error_table = NULL;
2033
		}
2034
1 by Sebastien Bacher
Import upstream version 2.5.3
2035
		if (priv->sexp) {
2036
			g_free (priv->sexp);
2037
			priv->sexp = NULL;
2038
		}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2039
1 by Sebastien Bacher
Import upstream version 2.5.3
2040
		if (priv->todo_sexp) {
2041
			g_free (priv->todo_sexp);
2042
			priv->todo_sexp = NULL;
2043
		}
2044
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2045
		if (priv->memo_sexp) {
2046
			g_free (priv->memo_sexp);
2047
			priv->memo_sexp = NULL;
2048
		}
2049
1 by Sebastien Bacher
Import upstream version 2.5.3
2050
		if (priv->update_timeout) {
2051
			g_source_remove (priv->update_timeout);
2052
			priv->update_timeout = 0;
2053
		}
2054
2055
		if (priv->view_instance) {
2056
			g_object_unref (priv->view_instance);
2057
			priv->view_instance = NULL;
2058
		}
2059
2060
		if (priv->update_marcus_bains_line_timeout) {
2061
			g_source_remove (priv->update_marcus_bains_line_timeout);
2062
			priv->update_marcus_bains_line_timeout = 0;
2063
		}
2064
2065
		if (priv->view_menus) {
2066
			g_object_unref (priv->view_menus);
2067
			priv->view_menus = NULL;
2068
		}
2069
2070
		if (priv->calendar_menu) {
2071
			g_object_unref (priv->calendar_menu);
2072
			priv->calendar_menu = NULL;
2073
		}
2074
2075
		if (priv->taskpad_menu) {
2076
			g_object_unref (priv->taskpad_menu);
2077
			priv->taskpad_menu = NULL;
2078
		}
2079
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2080
		if (priv->memopad_menu) {
2081
			g_object_unref (priv->memopad_menu);
2082
			priv->memopad_menu = NULL;
2083
		}
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
2084
		/* Disconnect all handlers */
2085
		cal_model = e_calendar_view_get_model ((ECalendarView *)priv->week_view);
2086
		g_signal_handlers_disconnect_by_func (cal_model,
2087
				G_CALLBACK (view_progress_cb), gcal);
2088
		g_signal_handlers_disconnect_by_func (cal_model,
2089
				G_CALLBACK (view_done_cb), gcal);
2090
2091
		cal_model = e_calendar_table_get_model ((ECalendarTable *) priv->todo);
2092
		g_signal_handlers_disconnect_by_func (cal_model,
2093
				G_CALLBACK (view_progress_cb), gcal);
2094
		g_signal_handlers_disconnect_by_func (cal_model,
2095
				G_CALLBACK (view_done_cb), gcal);
2096
2097
		cal_model = e_memo_table_get_model ((EMemoTable *)priv->memo);
2098
		g_signal_handlers_disconnect_by_func (cal_model,
2099
				G_CALLBACK (view_progress_cb), gcal);
2100
		g_signal_handlers_disconnect_by_func (cal_model,
2101
				G_CALLBACK (view_done_cb), gcal);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2102
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2103
		g_mutex_free (priv->todo_update_lock);
2104
1 by Sebastien Bacher
Import upstream version 2.5.3
2105
		g_free (priv);
2106
		gcal->priv = NULL;
2107
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2108
1 by Sebastien Bacher
Import upstream version 2.5.3
2109
	if (GTK_OBJECT_CLASS (gnome_calendar_parent_class)->destroy)
2110
		(* GTK_OBJECT_CLASS (gnome_calendar_parent_class)->destroy) (object);
2111
}
2112
2113
static void
2114
notify_selected_time_changed (GnomeCalendar *gcal)
2115
{
2116
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2117
	gint i;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2118
1 by Sebastien Bacher
Import upstream version 2.5.3
2119
	priv = gcal->priv;
2120
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
2121
		g_signal_emit_by_name (priv->views[i], "selected_time_changed");
2122
	}
2123
}
2124
2125
static void
2126
gnome_calendar_goto_date (GnomeCalendar *gcal,
2127
			  GnomeCalendarGotoDateType goto_date)
2128
{
2129
	GnomeCalendarPrivate *priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2130
	time_t	 new_time = 0;
1 by Sebastien Bacher
Import upstream version 2.5.3
2131
	gboolean need_updating = FALSE;
2132
2133
	g_return_if_fail (gcal != NULL);
2134
	g_return_if_fail (GNOME_IS_CALENDAR(gcal));
2135
2136
	priv = gcal->priv;
2137
2138
	switch (goto_date) {
2139
		/* GNOME_CAL_GOTO_TODAY and GNOME_CAL_GOTO_DATE are
2140
		   currently not used
2141
		*/
2142
	case GNOME_CAL_GOTO_TODAY:
2143
		break;
2144
	case GNOME_CAL_GOTO_DATE:
2145
		break;
2146
	case GNOME_CAL_GOTO_FIRST_DAY_OF_MONTH:
2147
		new_time = time_month_begin_with_zone (priv->base_view_time, priv->zone);
2148
		need_updating = TRUE;
2149
		break;
2150
	case GNOME_CAL_GOTO_LAST_DAY_OF_MONTH:
2151
		new_time = time_add_month_with_zone (priv->base_view_time, 1, priv->zone);
2152
		new_time = time_month_begin_with_zone (new_time, priv->zone);
2153
		new_time = time_add_day_with_zone (new_time, -1, priv->zone);
2154
		need_updating = TRUE;
2155
		break;
2156
	case GNOME_CAL_GOTO_FIRST_DAY_OF_WEEK:
2157
		new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone);
2158
		need_updating = TRUE;
2159
		break;
2160
	case GNOME_CAL_GOTO_LAST_DAY_OF_WEEK:
2161
		new_time = time_week_begin_with_zone (priv->base_view_time, priv->week_start, priv->zone);
2162
		if (priv->current_view_type == GNOME_CAL_DAY_VIEW ||
2163
		    priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW) {
2164
			/* FIXME Shouldn't hard code work week end */
2165
			/* goto Friday of this week */
2166
			new_time = time_add_day_with_zone (new_time, 4, priv->zone);
2167
		} else {
2168
			/* goto Sunday of this week */
2169
			/* FIXME Shouldn't hard code week end */
2170
			new_time = time_add_day_with_zone (new_time, 6, priv->zone);
2171
		}
2172
		need_updating = TRUE;
2173
		break;
2174
	case GNOME_CAL_GOTO_SAME_DAY_OF_PREVIOUS_WEEK:
2175
		new_time = time_add_week_with_zone (priv->base_view_time, -1, priv->zone);
2176
		need_updating = TRUE;
2177
		break;
2178
	case GNOME_CAL_GOTO_SAME_DAY_OF_NEXT_WEEK:
2179
		new_time = time_add_week_with_zone (priv->base_view_time, 1, priv->zone);
2180
		need_updating = TRUE;
2181
		break;
2182
	default:
2183
		break;
2184
	}
2185
2186
	if (need_updating) {
2187
		update_view_times (gcal, new_time);
2188
		gnome_calendar_update_date_navigator (gcal);
2189
		gnome_calendar_notify_dates_shown_changed (gcal);
2190
		notify_selected_time_changed (gcal);
2191
	}
2192
}
2193
2194
void
2195
gnome_calendar_goto (GnomeCalendar *gcal, time_t new_time)
2196
{
2197
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2198
	gint i;
1.1.2 by Sebastien Bacher
Import upstream version 2.5.5.1
2199
1 by Sebastien Bacher
Import upstream version 2.5.3
2200
	g_return_if_fail (gcal != NULL);
2201
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2202
	g_return_if_fail (new_time != -1);
2203
2204
	priv = gcal->priv;
2205
2206
	update_view_times (gcal, new_time);
2207
	gnome_calendar_update_date_navigator (gcal);
2208
	gnome_calendar_notify_dates_shown_changed (gcal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2209
1.1.2 by Sebastien Bacher
Import upstream version 2.5.5.1
2210
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2211
		if (E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (priv->views[i]))->set_selected_time_range)
1.1.2 by Sebastien Bacher
Import upstream version 2.5.5.1
2212
			E_CALENDAR_VIEW_CLASS (G_OBJECT_GET_CLASS (priv->views[i]))->set_selected_time_range (priv->views[i], new_time, new_time);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2213
	}
1 by Sebastien Bacher
Import upstream version 2.5.3
2214
}
2215
2216
static void
2217
update_view_times (GnomeCalendar *gcal, time_t start_time)
2218
{
2219
	GnomeCalendarPrivate *priv;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2220
	ECalModel *model;
2221
	time_t real_start_time = start_time;
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
2222
	time_t end_time, select_time = 0;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2223
1 by Sebastien Bacher
Import upstream version 2.5.3
2224
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2225
1 by Sebastien Bacher
Import upstream version 2.5.3
2226
	priv->base_view_time = start_time;
2227
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2228
	model = e_calendar_view_get_model (priv->views [priv->current_view_type]);
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
2229
	get_times_for_views (gcal, priv->current_view_type, &real_start_time, &end_time, &select_time);
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2230
2231
	if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
2232
		return;
2233
2234
	e_cal_model_set_time_range (model, real_start_time, end_time);
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
2235
2236
	if (select_time != 0 && select_time >= real_start_time && select_time <= end_time)
2237
		e_calendar_view_set_selected_time_range (priv->views [priv->current_view_type], select_time, select_time);
1 by Sebastien Bacher
Import upstream version 2.5.3
2238
}
2239
2240
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2241
gnome_calendar_direction (GnomeCalendar *gcal, gint direction)
1 by Sebastien Bacher
Import upstream version 2.5.3
2242
{
2243
	GnomeCalendarPrivate *priv;
2244
2245
	priv = gcal->priv;
2246
2247
	switch (priv->current_view_type) {
2248
	case GNOME_CAL_DAY_VIEW:
2249
		priv->base_view_time = time_add_day_with_zone (priv->base_view_time, direction, priv->zone);
2250
		break;
2251
	case GNOME_CAL_WORK_WEEK_VIEW:
2252
	case GNOME_CAL_WEEK_VIEW:
2253
		priv->base_view_time = time_add_week_with_zone (priv->base_view_time, direction, priv->zone);
2254
		break;
2255
	case GNOME_CAL_LIST_VIEW:
2256
		g_warning ("Using month view time interval for list view.");
2257
	case GNOME_CAL_MONTH_VIEW:
2258
		priv->base_view_time = time_add_month_with_zone (priv->base_view_time, direction, priv->zone);
2259
		break;
2260
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2261
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
2262
	}
2263
2264
	update_view_times (gcal, priv->base_view_time);
2265
	gnome_calendar_update_date_navigator (gcal);
2266
	gnome_calendar_notify_dates_shown_changed (gcal);
2267
}
2268
2269
void
2270
gnome_calendar_next (GnomeCalendar *gcal)
2271
{
2272
	g_return_if_fail (gcal != NULL);
2273
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2274
2275
	gnome_calendar_direction (gcal, 1);
2276
}
2277
2278
void
2279
gnome_calendar_previous (GnomeCalendar *gcal)
2280
{
2281
	g_return_if_fail (gcal != NULL);
2282
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2283
2284
	gnome_calendar_direction (gcal, -1);
2285
}
2286
2287
void
2288
gnome_calendar_dayjump (GnomeCalendar *gcal, time_t time)
2289
{
2290
	GnomeCalendarPrivate *priv;
2291
2292
	g_return_if_fail (gcal != NULL);
2293
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2294
2295
	priv = gcal->priv;
2296
2297
	priv->base_view_time = time_day_begin_with_zone (time, priv->zone);
2298
2299
	update_view_times (gcal, priv->base_view_time);
2300
	gnome_calendar_set_view (gcal, GNOME_CAL_DAY_VIEW);
2301
}
2302
2303
static void
2304
focus_current_view (GnomeCalendar *gcal)
2305
{
2306
	gtk_widget_grab_focus (gnome_calendar_get_current_view_widget (gcal));
2307
}
2308
2309
void
2310
gnome_calendar_goto_today (GnomeCalendar *gcal)
2311
{
2312
	g_return_if_fail (gcal != NULL);
2313
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2314
2315
	gnome_calendar_goto (gcal, time (NULL));
2316
	focus_current_view (gcal);
2317
}
2318
2319
/**
2320
 * gnome_calendar_get_view:
2321
 * @gcal: A calendar.
2322
 *
2323
 * Queries the type of the view that is being shown in a calendar.
2324
 *
2325
 * Return value: Type of the view that is currently shown.
2326
 **/
2327
GnomeCalendarViewType
2328
gnome_calendar_get_view (GnomeCalendar *gcal)
2329
{
2330
	GnomeCalendarPrivate *priv;
2331
2332
	g_return_val_if_fail (gcal != NULL, GNOME_CAL_DAY_VIEW);
2333
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), GNOME_CAL_DAY_VIEW);
2334
2335
	priv = gcal->priv;
2336
	return priv->current_view_type;
2337
}
2338
2339
static void
2340
set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean range_selected)
2341
{
2342
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2343
	const gchar *view_id;
1 by Sebastien Bacher
Import upstream version 2.5.3
2344
2345
	g_return_if_fail (gcal != NULL);
2346
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2347
2348
	priv = gcal->priv;
2349
2350
	switch (view_type) {
2351
	case GNOME_CAL_DAY_VIEW:
2352
		view_id = "Day_View";
2353
		break;
2354
2355
	case GNOME_CAL_WORK_WEEK_VIEW:
2356
		view_id = "Work_Week_View";
2357
		break;
2358
2359
	case GNOME_CAL_WEEK_VIEW:
2360
		view_id = "Week_View";
2361
		break;
2362
2363
	case GNOME_CAL_MONTH_VIEW:
2364
		view_id = "Month_View";
2365
		break;
2366
2367
	case GNOME_CAL_LIST_VIEW:
2368
		view_id = "List_View";
2369
		break;
2370
2371
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2372
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
2373
	}
2374
2375
	priv->range_selected = range_selected;
2376
	priv->current_view_type = view_type;
2377
2378
	gal_view_instance_set_current_view_id (priv->view_instance, view_id);
2379
	focus_current_view (gcal);
2380
}
2381
2382
/**
2383
 * gnome_calendar_set_view:
2384
 * @gcal: A calendar.
2385
 * @view_type: Type of view to show.
2386
 *
2387
 * Sets the view that should be shown in a calendar.  If @reset_range is true,
2388
 * this function will automatically set the number of days or weeks shown in
2389
 * the view; otherwise the last configuration will be kept.
2390
 **/
2391
void
2392
gnome_calendar_set_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type)
2393
{
2394
	g_return_if_fail (gcal != NULL);
2395
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2396
2397
	set_view (gcal, view_type, FALSE);
2398
}
2399
2400
/* Sets the view without changing the selection or updating the date
2401
 * navigator. If a range of dates isn't selected it will also reset the number
2402
 * of days/weeks shown to the default (i.e. 1 day for the day view or 5 weeks
2403
 * for the month view).
2404
 */
2405
static void
2406
display_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type, gboolean grab_focus)
2407
{
2408
	GnomeCalendarPrivate *priv;
2409
	gboolean preserve_day;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2410
	gint i;
1 by Sebastien Bacher
Import upstream version 2.5.3
2411
2412
	priv = gcal->priv;
2413
2414
	preserve_day = FALSE;
2415
2416
	switch (view_type) {
2417
	case GNOME_CAL_DAY_VIEW:
2418
		if (!priv->range_selected)
2419
			e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), 1);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2420
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2421
		gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1 by Sebastien Bacher
Import upstream version 2.5.3
2422
		break;
2423
2424
	case GNOME_CAL_WORK_WEEK_VIEW:
2425
		preserve_day = TRUE;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2426
		gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1 by Sebastien Bacher
Import upstream version 2.5.3
2427
		break;
2428
2429
	case GNOME_CAL_WEEK_VIEW:
2430
		preserve_day = TRUE;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2431
		gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1 by Sebastien Bacher
Import upstream version 2.5.3
2432
		break;
2433
2434
	case GNOME_CAL_MONTH_VIEW:
2435
		if (!priv->range_selected)
2436
			e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view), 6);
2437
2438
		preserve_day = TRUE;
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2439
		gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1 by Sebastien Bacher
Import upstream version 2.5.3
2440
		break;
2441
2442
	case GNOME_CAL_LIST_VIEW:
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2443
		if (!priv->lview_select_daten_range)
2444
			gtk_widget_hide (GTK_WIDGET (gcal->priv->date_navigator));
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2445
		else
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2446
			gtk_widget_show (GTK_WIDGET (gcal->priv->date_navigator));
1 by Sebastien Bacher
Import upstream version 2.5.3
2447
		break;
2448
2449
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2450
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
2451
	}
2452
2453
	priv->current_view_type = view_type;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2454
	E_CALENDAR_VIEW (priv->views [view_type])->in_focus = TRUE;
1 by Sebastien Bacher
Import upstream version 2.5.3
2455
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
2456
	gtk_notebook_set_current_page (
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2457
		GTK_NOTEBOOK (priv->notebook), (gint) view_type);
1 by Sebastien Bacher
Import upstream version 2.5.3
2458
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2459
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++) {
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2460
		if (i == view_type)
2461
			continue;
2462
		E_CALENDAR_VIEW (priv->views [i])->in_focus = FALSE;
2463
	}
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2464
1 by Sebastien Bacher
Import upstream version 2.5.3
2465
	if (grab_focus)
2466
		focus_current_view (gcal);
2467
2468
	gnome_calendar_set_pane_positions (gcal);
2469
2470
	/* For the week & month views we want the selection in the date
2471
	   navigator to be rounded to the nearest week when the arrow buttons
2472
	   are pressed to move to the previous/next month. */
2473
	g_object_set (G_OBJECT (priv->date_navigator->calitem),
2474
		      "preserve_day_when_moving", preserve_day,
2475
		      NULL);
2476
}
2477
2478
static void gnome_calendar_change_view (GnomeCalendar *gcal, GnomeCalendarViewType view_type)
2479
{
2480
	if (gnome_calendar_get_view(gcal) == view_type)
2481
		return;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2482
1 by Sebastien Bacher
Import upstream version 2.5.3
2483
	gnome_calendar_set_view(gcal, view_type);
2484
}
2485
2486
/* Callback used when the view collection asks us to display a particular view */
2487
static void
2488
display_view_cb (GalViewInstance *view_instance, GalView *view, gpointer data)
2489
{
2490
	GnomeCalendar *gcal;
2491
	GnomeCalendarPrivate *priv;
2492
	CalendarView *cal_view;
2493
	GnomeCalendarViewType view_type;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2494
1 by Sebastien Bacher
Import upstream version 2.5.3
2495
	gcal = GNOME_CALENDAR (data);
2496
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2497
1 by Sebastien Bacher
Import upstream version 2.5.3
2498
	if (GAL_IS_VIEW_ETABLE(view)) {
2499
		ETable *table;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2500
1 by Sebastien Bacher
Import upstream version 2.5.3
2501
		view_type = GNOME_CAL_LIST_VIEW;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2502
1 by Sebastien Bacher
Import upstream version 2.5.3
2503
		table = e_table_scrolled_get_table (E_CAL_LIST_VIEW (priv->list_view)->table_scrolled);
2504
		gal_view_etable_attach_table (GAL_VIEW_ETABLE (view), table);
2505
	} else if (IS_CALENDAR_VIEW (view)) {
2506
		cal_view = CALENDAR_VIEW (view);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2507
1 by Sebastien Bacher
Import upstream version 2.5.3
2508
		view_type = calendar_view_get_view_type (cal_view);
2509
	} else {
2510
		g_error (G_STRLOC ": Unknown type of view for GnomeCalendar");
2511
		return;
2512
	}
2513
2514
	display_view (gcal, view_type, TRUE);
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2515
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2516
	if (!priv->base_view_time)
2517
		update_view_times (gcal, time (NULL));
2518
	else
2519
		update_view_times (gcal, priv->base_view_time);
2520
1 by Sebastien Bacher
Import upstream version 2.5.3
2521
	gnome_calendar_update_date_navigator (gcal);
2522
	gnome_calendar_notify_dates_shown_changed (gcal);
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
2523
1 by Sebastien Bacher
Import upstream version 2.5.3
2524
}
2525
2526
/**
2527
 * gnome_calendar_setup_view_menus:
2528
 * @gcal: A calendar.
2529
 * @uic: UI controller to use for the menus.
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2530
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
2531
 * Sets up the #GalView menus for a calendar.  This function should be called
2532
 * from the Bonobo control activation callback for this calendar.  Also, the
2533
 * menus should be discarded using gnome_calendar_discard_view_menus().
2534
 **/
2535
void
2536
gnome_calendar_setup_view_menus (GnomeCalendar *gcal, BonoboUIComponent *uic)
2537
{
2538
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2539
	gchar *path0, *path1, *etspecfile;
1 by Sebastien Bacher
Import upstream version 2.5.3
2540
	CalendarViewFactory *factory;
2541
	GalViewFactory *gal_factory;
2542
	static GalViewCollection *collection = NULL;
2543
2544
	g_return_if_fail (gcal != NULL);
2545
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2546
	g_return_if_fail (uic != NULL);
2547
	g_return_if_fail (BONOBO_IS_UI_COMPONENT (uic));
2548
2549
	priv = gcal->priv;
2550
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2551
	g_return_if_fail (priv->view_instance == NULL);
2552
	g_return_if_fail (priv->view_menus == NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
2553
2554
	/* Create the view instance */
2555
	if (collection == NULL) {
2556
		ETableSpecification *spec;
2557
2558
		collection = gal_view_collection_new ();
2559
2560
		gal_view_collection_set_title (collection, _("Calendar"));
2561
2562
		path0 = g_build_filename (EVOLUTION_GALVIEWSDIR,
2563
					  "calendar",
2564
					  NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2565
		path1 = g_build_filename (calendar_component_peek_base_directory (calendar_component_peek ()),
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
2566
					 "views", NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
2567
		gal_view_collection_set_storage_directories (collection,
2568
							     path0,
2569
							     path1);
2570
		g_free (path1);
2571
		g_free (path0);
2572
2573
		/* Create the views */
2574
2575
		factory = calendar_view_factory_new (GNOME_CAL_DAY_VIEW);
2576
		gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
2577
		g_object_unref (factory);
2578
2579
		factory = calendar_view_factory_new (GNOME_CAL_WORK_WEEK_VIEW);
2580
		gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
2581
		g_object_unref (factory);
2582
2583
		factory = calendar_view_factory_new (GNOME_CAL_WEEK_VIEW);
2584
		gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
2585
		g_object_unref (factory);
2586
2587
		factory = calendar_view_factory_new (GNOME_CAL_MONTH_VIEW);
2588
		gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (factory));
2589
		g_object_unref (factory);
2590
2591
		spec = e_table_specification_new ();
2592
		etspecfile = g_build_filename (EVOLUTION_ETSPECDIR,
2593
					       "e-cal-list-view.etspec",
2594
					       NULL);
1.1.28 by Sebastien Bacher
Import upstream version 2.11.5
2595
		if (!e_table_specification_load_from_file (spec, etspecfile))
2596
			g_error ("Unable to load ETable specification file "
2597
				 "for calendar");
1 by Sebastien Bacher
Import upstream version 2.5.3
2598
		g_free (etspecfile);
2599
		gal_factory = gal_view_factory_etable_new (spec);
2600
		g_object_unref (spec);
2601
		gal_view_collection_add_factory (collection, GAL_VIEW_FACTORY (gal_factory));
2602
		g_object_unref (gal_factory);
2603
2604
		/* Load the collection and create the menus */
2605
2606
		gal_view_collection_load (collection);
2607
2608
	}
2609
2610
	priv->view_instance = gal_view_instance_new (collection, NULL);
2611
	priv->view_menus = gal_view_menus_new (priv->view_instance);
2612
	gal_view_menus_apply (priv->view_menus, uic, NULL);
2613
2614
	g_signal_connect (priv->view_instance, "display_view", G_CALLBACK (display_view_cb), gcal);
2615
	display_view_cb (priv->view_instance, gal_view_instance_get_current_view (priv->view_instance), gcal);
2616
}
2617
2618
/**
2619
 * gnome_calendar_discard_view_menus:
2620
 * @gcal: A calendar.
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2621
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
2622
 * Discards the #GalView menus used by a calendar.  This function should be
2623
 * called from the Bonobo control deactivation callback for this calendar.  The
2624
 * menus should have been set up with gnome_calendar_setup_view_menus().
2625
 **/
2626
void
2627
gnome_calendar_discard_view_menus (GnomeCalendar *gcal)
2628
{
2629
	GnomeCalendarPrivate *priv;
2630
2631
	g_return_if_fail (gcal != NULL);
2632
2633
	priv = gcal->priv;
2634
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2635
	g_return_if_fail (priv->view_instance != NULL);
2636
	g_return_if_fail (priv->view_menus != NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
2637
2638
	g_object_unref (priv->view_instance);
2639
	priv->view_instance = NULL;
2640
2641
	g_object_unref (priv->view_menus);
2642
	priv->view_menus = NULL;
2643
}
2644
2645
/* This is copied/moved from gal-view-instance, only the calendar uses this for a popup menu */
2646
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2647
gc_set_view(EPopup *ep, EPopupItem *pitem, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
2648
{
2649
	GnomeCalendar *gcal = data;
2650
2651
	if (pitem->type & E_POPUP_ACTIVE)
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2652
		gal_view_instance_set_current_view_id(gcal->priv->view_instance, (gchar *)pitem->user_data);
1 by Sebastien Bacher
Import upstream version 2.5.3
2653
}
2654
2655
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2656
gc_save_custom_view(EPopup *ep, EPopupItem *pitem, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
2657
{
2658
	GnomeCalendar *gcal = data;
2659
2660
	gal_view_instance_save_as(gcal->priv->view_instance);
2661
}
2662
2663
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2664
gc_define_views_response(GtkWidget *d, gint id, GnomeCalendar *gcal)
1 by Sebastien Bacher
Import upstream version 2.5.3
2665
{
2666
	if (id == GTK_RESPONSE_OK)
2667
		gal_view_collection_save(gcal->priv->view_instance->collection);
2668
2669
	gtk_widget_destroy(d);
2670
}
2671
2672
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2673
gc_define_views(EPopup *ep, EPopupItem *pitem, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
2674
{
2675
	GnomeCalendar *gcal = data;
2676
	GtkWidget *dialog = gal_define_views_dialog_new(gcal->priv->view_instance->collection);
2677
2678
	g_signal_connect(dialog, "response", G_CALLBACK(gc_define_views_response), data);
2679
	gtk_widget_show(dialog);
2680
}
2681
2682
static EPopupItem gc_popups[] = {
2683
	/* Code generates the path to fit */
2684
	{ E_POPUP_BAR, NULL },
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2685
	{ E_POPUP_RADIO|E_POPUP_ACTIVE, NULL, (gchar *) N_("_Custom View"), },
2686
	{ E_POPUP_ITEM, NULL, (gchar *) N_("_Save Custom View"), gc_save_custom_view },
1 by Sebastien Bacher
Import upstream version 2.5.3
2687
2688
	/* index == 3, when we have non-custom view */
2689
2690
	{ E_POPUP_BAR, NULL },
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2691
	{ E_POPUP_ITEM, NULL, (gchar *) N_("_Define Views..."), gc_define_views },
1 by Sebastien Bacher
Import upstream version 2.5.3
2692
};
2693
2694
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2695
gc_popup_free (EPopup *ep, GSList *list, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
2696
{
2697
	while (list) {
2698
		GSList *n = list->next;
2699
		EPopupItem *pitem = list->data;
2700
2701
		g_free(pitem->path);
2702
		g_free(pitem->label);
2703
		g_free(pitem->user_data);
2704
		g_free(pitem);
2705
		g_slist_free_1(list);
2706
		list = n;
2707
	}
2708
}
2709
2710
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2711
gc_popup_free_static (EPopup *ep, GSList *list, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
2712
{
2713
	while (list) {
2714
		GSList *n = list->next;
2715
		EPopupItem *pitem = list->data;
2716
2717
		g_free(pitem->path);
2718
		g_free(pitem);
2719
		g_slist_free_1(list);
2720
		list = n;
2721
	}
2722
}
2723
2724
void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2725
gnome_calendar_view_popup_factory (GnomeCalendar *gcal, EPopup *ep, const gchar *prefix)
1 by Sebastien Bacher
Import upstream version 2.5.3
2726
{
2727
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2728
	gint length;
2729
	gint i;
1 by Sebastien Bacher
Import upstream version 2.5.3
2730
	gboolean found = FALSE;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2731
	gchar *id;
1 by Sebastien Bacher
Import upstream version 2.5.3
2732
	GSList *menus = NULL;
2733
	EPopupItem *pitem;
2734
2735
	g_return_if_fail (gcal != NULL);
2736
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
2737
	g_return_if_fail (prefix != NULL);
2738
2739
	priv = gcal->priv;
2740
2741
	g_return_if_fail (priv->view_instance != NULL);
2742
2743
	length = gal_view_collection_get_count(priv->view_instance->collection);
2744
	id = gal_view_instance_get_current_view_id (priv->view_instance);
2745
2746
	for (i = 0; i < length; i++) {
2747
		GalViewCollectionItem *item = gal_view_collection_get_view_item(priv->view_instance->collection, i);
2748
2749
		pitem = g_malloc0(sizeof(*pitem));
2750
		pitem->type = E_POPUP_RADIO;
2751
		pitem->path = g_strdup_printf("%s/%02d.item", prefix, i);
2752
		pitem->label = g_strdup(item->title);
2753
		pitem->activate = gc_set_view;
2754
		pitem->user_data = g_strdup(item->id);
2755
2756
		if (!found && id && !strcmp (id, item->id)) {
2757
			found = TRUE;
2758
			pitem->type |= E_POPUP_ACTIVE;
2759
		}
2760
2761
		menus = g_slist_prepend(menus, pitem);
2762
	}
2763
2764
	if (menus)
2765
		e_popup_add_items(ep, menus, NULL, gc_popup_free, gcal);
2766
2767
	menus = NULL;
2768
	for (i = found?3:0; i<sizeof(gc_popups)/sizeof(gc_popups[0]);i++) {
2769
		pitem = g_malloc0(sizeof(*pitem));
2770
		memcpy(pitem, &gc_popups[i], sizeof(*pitem));
2771
		pitem->path = g_strdup_printf("%s/%02d.item", prefix, i+length);
2772
		menus = g_slist_prepend(menus, pitem);
2773
	}
2774
2775
	e_popup_add_items(ep, menus, NULL, gc_popup_free_static, gcal);
2776
}
2777
2778
static void
2779
gnome_calendar_set_pane_positions	(GnomeCalendar	*gcal)
2780
{
2781
	GnomeCalendarPrivate *priv;
2782
2783
	priv = gcal->priv;
2784
2785
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
2786
		gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view);
2787
		gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
2788
	} else {
2789
		gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos);
2790
		gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
2791
	}
2792
}
2793
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2794
struct _mclient_msg {
2795
	Message header;
2796
	ECalModel *model;
2797
	ECal *client;
2798
};
2799
2800
static void
2801
add_mclient_async (struct _mclient_msg *msg)
2802
{
2803
	e_cal_model_add_client (msg->model, msg->client);
2804
2805
	g_object_unref (msg->client);
2806
	g_object_unref (msg->model);
2807
	g_slice_free (struct _mclient_msg, msg);
2808
}
2809
2810
static void
2811
add_mclient (ECalModel *model, ECal *client)
2812
{
2813
	struct _mclient_msg *msg;
2814
2815
	msg = g_slice_new0 (struct _mclient_msg);
2816
	msg->header.func = (MessageFunc) add_mclient_async;
2817
	msg->model = g_object_ref (model);
2818
	msg->client = g_object_ref (client);
2819
2820
	message_push ((Message *) msg);
2821
}
2822
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2823
static void
2824
non_intrusive_error_remove(GtkWidget *w, gpointer data)
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2825
{
2826
	g_hash_table_remove(non_intrusive_error_table, data);
2827
}
2828
1 by Sebastien Bacher
Import upstream version 2.5.3
2829
static void
2830
client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
2831
{
2832
	GnomeCalendarPrivate *priv;
2833
	ECalSourceType source_type;
2834
	ESource *source;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2835
	ECalModel *model;
1 by Sebastien Bacher
Import upstream version 2.5.3
2836
	ECalLoadState state;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2837
	gchar *msg;
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2838
	GtkWidget *w = NULL;
2839
	gchar *id;
1 by Sebastien Bacher
Import upstream version 2.5.3
2840
2841
	priv = gcal->priv;
2842
2843
	source_type = e_cal_get_source_type (ecal);
2844
	source = e_cal_get_source (ecal);
2845
	state = e_cal_get_load_state (ecal);
2846
2847
	switch (source_type) {
2848
	case E_CAL_SOURCE_TYPE_EVENT:
2849
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
2850
		break;
2851
	case E_CAL_SOURCE_TYPE_TODO:
2852
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
2853
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2854
	case E_CAL_SOURCE_TYPE_JOURNAL:
2855
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
2856
	default:
2857
		break;
2858
	}
1.1.41 by Sebastien Bacher
Import upstream version 2.21.92
2859
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2860
	if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
1.1.41 by Sebastien Bacher
Import upstream version 2.21.92
2861
		auth_cal_forget_password (ecal);
2862
1 by Sebastien Bacher
Import upstream version 2.5.3
2863
	switch (status) {
2864
	case E_CALENDAR_STATUS_OK:
2865
		break;
2866
	case E_CALENDAR_STATUS_BUSY:
2867
		if (state == E_CAL_LOAD_NOT_LOADED)
2868
			e_cal_open_async (ecal, FALSE);
2869
		return;
2870
	case E_CALENDAR_STATUS_INVALID_SERVER_VERSION:
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2871
		id = g_strdup ("calendar:server-version");
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
2872
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2873
		if (g_hash_table_lookup(non_intrusive_error_table, id)) {
2874
			/* We already have it */
2875
			g_message("Error occurred while existing dialog active:\n");
1.1.37 by Sebastien Bacher
Import upstream version 2.21.4
2876
			return;
2877
		}
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2878
2879
		w = e_error_new(NULL, "calendar:server-version", NULL);
2880
		e_calendar_utils_show_error_silent (w);
2881
		g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w));
2882
		g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id);
2883
2884
		status = E_CALENDAR_STATUS_OK;
2885
		break;
2886
	case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
2887
		/* try to reopen calendar - it'll ask for a password once again */
2888
		e_cal_open_async (ecal, FALSE);
2889
		return;
1 by Sebastien Bacher
Import upstream version 2.5.3
2890
	case E_CALENDAR_STATUS_REPOSITORY_OFFLINE:
2891
		if (source_type == E_CAL_SOURCE_TYPE_EVENT)
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2892
		{
2893
			/* check to see if we have dialog already running for this operation */
2894
			id = g_strdup ("calendar:unable-to-load-the-calendar");
2895
2896
			if (g_hash_table_lookup(non_intrusive_error_table, id)) {
2897
				/* We already have it */
2898
				g_message("Error occurred while existing dialog active:\n");
2899
				return;
2900
			}
2901
2902
			w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:unable-to-load-the-calendar", e_cal_get_error_message (status), NULL);
2903
			e_calendar_utils_show_error_silent (w);
2904
			g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(w));
2905
			g_signal_connect(w, "destroy", G_CALLBACK(non_intrusive_error_remove), id);
2906
		}
1 by Sebastien Bacher
Import upstream version 2.5.3
2907
	default:
2908
		/* Make sure the source doesn't disappear on us */
2909
		g_object_ref (source);
2910
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2911
		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
2912
1 by Sebastien Bacher
Import upstream version 2.5.3
2913
		priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
2914
		g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
2915
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
2916
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
2917
		g_object_unref (source);
2918
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
2919
		g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status));
2920
1 by Sebastien Bacher
Import upstream version 2.5.3
2921
		return;
2922
	}
2923
2924
	g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, client_cal_opened_cb, NULL);
2925
2926
	switch (source_type) {
2927
	case E_CAL_SOURCE_TYPE_EVENT :
2928
		msg = g_strdup_printf (_("Loading appointments at %s"), e_cal_get_uri (ecal));
2929
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1);
2930
		g_free (msg);
2931
2932
		/* add client to the views */
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
2933
		model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
2934
		add_mclient (model, ecal);
1 by Sebastien Bacher
Import upstream version 2.5.3
2935
2936
		/* update date navigator query */
2937
		update_query (gcal);
2938
2939
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
2940
		break;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2941
1 by Sebastien Bacher
Import upstream version 2.5.3
2942
	case E_CAL_SOURCE_TYPE_TODO :
2943
		msg = g_strdup_printf (_("Loading tasks at %s"), e_cal_get_uri (ecal));
2944
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1);
2945
		g_free (msg);
2946
2947
		e_cal_model_add_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal);
2948
2949
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
2950
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2951
	case E_CAL_SOURCE_TYPE_JOURNAL:
2952
		msg = g_strdup_printf (_("Loading memos at %s"), e_cal_get_uri (ecal));
2953
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
2954
		g_free (msg);
2955
		e_cal_model_add_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
2956
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2957
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
2958
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
2959
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
2960
	}
2961
}
2962
2963
static void
2964
default_client_cal_opened_cb (ECal *ecal, ECalendarStatus status, GnomeCalendar *gcal)
2965
{
2966
	GnomeCalendarPrivate *priv;
2967
	ECalSourceType source_type;
2968
	ESource *source;
2969
	ECalLoadState state;
2970
2971
	priv = gcal->priv;
2972
2973
	source_type = e_cal_get_source_type (ecal);
2974
	source = e_cal_get_source (ecal);
2975
	state = e_cal_get_load_state (ecal);
2976
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
2977
	if (status == E_CALENDAR_STATUS_AUTHENTICATION_FAILED || status == E_CALENDAR_STATUS_AUTHENTICATION_REQUIRED)
2978
		auth_cal_forget_password (ecal);
2979
1 by Sebastien Bacher
Import upstream version 2.5.3
2980
	switch (source_type) {
2981
	case E_CAL_SOURCE_TYPE_EVENT:
2982
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2983
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
2984
	case E_CAL_SOURCE_TYPE_TODO:
2985
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
2986
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
2987
	case E_CAL_SOURCE_TYPE_JOURNAL:
2988
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
2989
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
2990
	default:
2991
		break;
2992
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
2993
1 by Sebastien Bacher
Import upstream version 2.5.3
2994
	switch (status) {
2995
	case E_CALENDAR_STATUS_OK:
2996
		break;
2997
	case E_CALENDAR_STATUS_BUSY:
2998
		if (state == E_CAL_LOAD_NOT_LOADED)
2999
			e_cal_open_async (ecal, FALSE);
3000
		return;
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3001
	case E_CALENDAR_STATUS_AUTHENTICATION_FAILED:
3002
		/* try to reopen calendar - it'll ask for a password once again */
3003
		e_cal_open_async (ecal, FALSE);
3004
		return;
3005
	case E_CALENDAR_STATUS_INVALID_SERVER_VERSION:
1 by Sebastien Bacher
Import upstream version 2.5.3
3006
		e_error_run (NULL, "calendar:server-version", NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3007
	default:
1 by Sebastien Bacher
Import upstream version 2.5.3
3008
		/* Make sure the source doesn't disappear on us */
3009
		g_object_ref (source);
3010
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3011
		g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, gcal);
3012
1 by Sebastien Bacher
Import upstream version 2.5.3
3013
		/* FIXME should we do this to prevent multiple error dialogs? */
3014
		priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
3015
		g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
3016
3017
		/* FIXME Is there a better way to handle this? */
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3018
		if (priv->default_client[source_type])
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
3019
			g_object_unref (priv->default_client[source_type]);
1 by Sebastien Bacher
Import upstream version 2.5.3
3020
		priv->default_client[source_type] = NULL;
3021
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3022
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
3023
		g_object_unref (source);
3024
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
3025
		g_warning ("Unable to load the calendar %s \n", e_cal_get_error_message (status));
3026
1 by Sebastien Bacher
Import upstream version 2.5.3
3027
		return;
3028
	}
3029
3030
	g_signal_handlers_disconnect_matched (ecal, G_SIGNAL_MATCH_FUNC, 0, 0, NULL, default_client_cal_opened_cb, NULL);
3031
3032
	switch (source_type) {
3033
	case E_CAL_SOURCE_TYPE_EVENT:
3034
			e_cal_model_set_default_client (
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
3035
				e_calendar_view_get_model (E_CALENDAR_VIEW (priv->views[priv->current_view_type])),
1 by Sebastien Bacher
Import upstream version 2.5.3
3036
				ecal);
3037
		break;
3038
3039
	case E_CAL_SOURCE_TYPE_TODO:
3040
		e_cal_model_set_default_client (e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo)), ecal);
3041
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3042
	case E_CAL_SOURCE_TYPE_JOURNAL:
3043
		e_cal_model_set_default_client (e_memo_table_get_model (E_MEMO_TABLE (priv->memo)), ecal);
3044
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
3045
	default:
3046
		break;
3047
        }
3048
}
3049
3050
typedef void (*open_func) (ECal *, ECalendarStatus, GnomeCalendar *);
3051
3052
static gboolean
3053
open_ecal (GnomeCalendar *gcal, ECal *cal, gboolean only_if_exists, open_func of)
3054
{
3055
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3056
	gchar *msg;
1 by Sebastien Bacher
Import upstream version 2.5.3
3057
	icaltimezone *zone;
3058
3059
	priv = gcal->priv;
3060
3061
	zone = calendar_config_get_icaltimezone ();
3062
	e_cal_set_default_timezone (cal, zone, NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3063
1 by Sebastien Bacher
Import upstream version 2.5.3
3064
	msg = g_strdup_printf (_("Opening %s"), e_cal_get_uri (cal));
3065
	switch (e_cal_get_source_type (cal)) {
3066
	case E_CAL_SOURCE_TYPE_EVENT :
3067
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), msg, -1);
3068
		break;
3069
	case E_CAL_SOURCE_TYPE_TODO :
3070
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), msg, -1);
3071
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3072
	case E_CAL_SOURCE_TYPE_JOURNAL:
3073
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), msg);
3074
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
3075
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
3076
		g_free (msg);
3077
		g_return_val_if_reached (FALSE);
1 by Sebastien Bacher
Import upstream version 2.5.3
3078
	}
3079
3080
	g_free (msg);
3081
3082
	g_signal_connect (G_OBJECT (cal), "cal_opened", G_CALLBACK (of), gcal);
3083
	e_cal_open_async (cal, only_if_exists);
3084
3085
	return TRUE;
3086
}
3087
3088
/* Callback when we get an error message from the backend */
3089
static void
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3090
backend_error_cb (ECal *client, const gchar *message, gpointer data)
1 by Sebastien Bacher
Import upstream version 2.5.3
3091
{
3092
	GnomeCalendar *gcal;
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
3093
	GtkDialog *dialog;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3094
	gchar *uristr;
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3095
	gchar *id;
1 by Sebastien Bacher
Import upstream version 2.5.3
3096
3097
	gcal = GNOME_CALENDAR (data);
3098
3099
	uristr = get_uri_without_password (e_cal_get_uri (client));
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3100
	id = g_strdup ("calendar:error-on-loading-the-calendar");
3101
3102
	if (g_hash_table_lookup(non_intrusive_error_table,id)) {
3103
		/* We already have it */
3104
		g_message("Error occurred while existing dialog active:\n");
3105
		return;
3106
	}
3107
3108
	dialog = (GtkDialog *)e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:error-on-loading-the-calendar", uristr, message, NULL);
3109
	e_calendar_utils_show_error_silent(GTK_WIDGET (dialog));
3110
3111
	g_hash_table_insert (non_intrusive_error_table, id, g_object_ref(dialog));
3112
	g_signal_connect(GTK_WIDGET (dialog), "destroy", G_CALLBACK(non_intrusive_error_remove), id);
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3113
1 by Sebastien Bacher
Import upstream version 2.5.3
3114
	g_free (uristr);
3115
}
3116
3117
/* Callback when the backend dies */
3118
static void
3119
backend_died_cb (ECal *ecal, gpointer data)
3120
{
3121
	GnomeCalendar *gcal;
3122
	GnomeCalendarPrivate *priv;
3123
	ECalSourceType source_type;
3124
	ESource *source;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3125
	const gchar *id;
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3126
	GtkWidget *w = NULL;
1 by Sebastien Bacher
Import upstream version 2.5.3
3127
3128
	gcal = GNOME_CALENDAR (data);
3129
	priv = gcal->priv;
3130
3131
	/* FIXME What about default sources? */
3132
3133
	/* Make sure the source doesn't go away on us since we use it below */
3134
	source_type = e_cal_get_source_type (ecal);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3135
	source = g_object_ref (e_cal_get_source (ecal));
3136
1 by Sebastien Bacher
Import upstream version 2.5.3
3137
	priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], ecal);
3138
	g_hash_table_remove (priv->clients[source_type], e_source_peek_uid (source));
3139
3140
	switch (source_type) {
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3141
	case E_CAL_SOURCE_TYPE_EVENT:
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3142
		id = g_strdup ("calendar:calendar-crashed");
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3143
1 by Sebastien Bacher
Import upstream version 2.5.3
3144
		e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
3145
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3146
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
3147
		break;
3148
3149
	case E_CAL_SOURCE_TYPE_TODO:
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3150
		id = g_strdup ("calendar:calendar-crashed");
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3151
1 by Sebastien Bacher
Import upstream version 2.5.3
3152
		e_calendar_table_set_status_message (E_CALENDAR_TABLE (priv->todo), NULL, -1);
3153
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3154
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
3155
		break;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3156
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3157
	case E_CAL_SOURCE_TYPE_JOURNAL:
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3158
		id = g_strdup ("calendar:calendar-crashed");
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3159
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3160
		e_memo_table_set_status_message (E_MEMO_TABLE (priv->memo), NULL);
1 by Sebastien Bacher
Import upstream version 2.5.3
3161
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3162
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3163
		break;
1 by Sebastien Bacher
Import upstream version 2.5.3
3164
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
3165
		g_return_if_reached ();
1 by Sebastien Bacher
Import upstream version 2.5.3
3166
	}
3167
3168
	g_object_unref (source);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3169
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
3170
	if (g_hash_table_lookup(non_intrusive_error_table,id)) {
3171
		/* We already have it */
3172
		g_message("Error occurred while existing dialog active:\n");
3173
		return;
3174
	}
3175
3176
	w = e_error_new(GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (gcal))), "calendar:backend_died", NULL);
3177
	e_calendar_utils_show_error_silent (w);
3178
	g_hash_table_insert (non_intrusive_error_table, (gpointer) id, g_object_ref(w));
3179
	g_signal_connect((GtkObject *)w, "destroy", G_CALLBACK(non_intrusive_error_remove), (gpointer) id);
1 by Sebastien Bacher
Import upstream version 2.5.3
3180
}
3181
3182
GtkWidget *
3183
gnome_calendar_construct (GnomeCalendar *gcal)
3184
{
3185
	GnomeCalendarPrivate *priv;
3186
3187
	g_return_val_if_fail (gcal != NULL, NULL);
3188
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
3189
3190
	priv = gcal->priv;
3191
3192
	return GTK_WIDGET (gcal);
3193
}
3194
3195
GtkWidget *
3196
gnome_calendar_new (void)
3197
{
3198
	GnomeCalendar *gcal;
3199
3200
	gcal = g_object_new (gnome_calendar_get_type (), NULL);
3201
3202
	if (!gnome_calendar_construct (gcal)) {
3203
		g_message (G_STRLOC ": Could not construct the calendar GUI");
3204
		g_object_unref (gcal);
3205
		return NULL;
3206
	}
3207
3208
	return GTK_WIDGET (gcal);
3209
}
3210
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3211
void
1 by Sebastien Bacher
Import upstream version 2.5.3
3212
gnome_calendar_set_activity_handler (GnomeCalendar *cal, EActivityHandler *activity_handler)
3213
{
3214
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3215
	gint i;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3216
1 by Sebastien Bacher
Import upstream version 2.5.3
3217
	g_return_if_fail (cal != NULL);
3218
	g_return_if_fail (GNOME_IS_CALENDAR (cal));
3219
3220
	priv = cal->priv;
3221
3222
	priv->activity_handler = activity_handler;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3223
1 by Sebastien Bacher
Import upstream version 2.5.3
3224
	for (i = 0; i < GNOME_CAL_LAST_VIEW; i++)
3225
		e_calendar_view_set_activity_handler (priv->views[i], activity_handler);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3226
1 by Sebastien Bacher
Import upstream version 2.5.3
3227
	e_calendar_table_set_activity_handler (E_CALENDAR_TABLE (priv->todo), activity_handler);
3228
}
3229
3230
void
3231
gnome_calendar_set_ui_component (GnomeCalendar *gcal,
3232
				 BonoboUIComponent *ui_component)
3233
{
3234
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3235
	g_return_if_fail (ui_component == NULL || BONOBO_IS_UI_COMPONENT (ui_component));
3236
3237
	e_search_bar_set_ui_component (E_SEARCH_BAR (gcal->priv->search_bar), ui_component);
3238
}
3239
3240
/**
3241
 * gnome_calendar_get_calendar_model:
3242
 * @gcal: A calendar view.
3243
 *
3244
 * Queries the calendar model object that a calendar view is using.
3245
 *
3246
 * Return value: A calendar client interface object.
3247
 **/
3248
ECalModel *
3249
gnome_calendar_get_calendar_model (GnomeCalendar *gcal)
3250
{
3251
	GnomeCalendarPrivate *priv;
3252
3253
	g_return_val_if_fail (gcal != NULL, NULL);
3254
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
3255
3256
	priv = gcal->priv;
3257
3258
	return e_calendar_view_get_model (priv->views[priv->current_view_type]);
3259
}
3260
3261
/**
3262
 * gnome_calendar_get_default_client
3263
 */
3264
ECal *
3265
gnome_calendar_get_default_client (GnomeCalendar *gcal)
3266
{
3267
	GnomeCalendarPrivate *priv;
3268
3269
	g_return_val_if_fail (gcal != NULL, NULL);
3270
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
3271
3272
	priv = gcal->priv;
3273
3274
	return e_cal_model_get_default_client (e_calendar_view_get_model (gcal->priv->views[priv->current_view_type]));
3275
}
3276
3277
/**
3278
 * gnome_calendar_add_source:
3279
 * @gcal: A GnomeCalendar.
3280
 * @source: #ESource to add to the calendar views.
3281
 *
3282
 * Adds the given calendar source to the calendar views.
3283
 *
3284
 * Returns: TRUE if successful, FALSE if error.
3285
 */
3286
gboolean
3287
gnome_calendar_add_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
3288
{
3289
	GnomeCalendarPrivate *priv;
3290
	ECal *client;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3291
1 by Sebastien Bacher
Import upstream version 2.5.3
3292
	g_return_val_if_fail (gcal != NULL, FALSE);
3293
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
3294
	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
3295
3296
	priv = gcal->priv;
3297
3298
	client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source));
3299
	if (client) {
3300
		/* We already have it */
3301
3302
		return TRUE;
3303
	} else {
3304
		ESource *default_source;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3305
1 by Sebastien Bacher
Import upstream version 2.5.3
3306
		if (priv->default_client[source_type]) {
3307
			default_source = e_cal_get_source (priv->default_client[source_type]);
3308
3309
			g_message ("Check if default client matches (%s %s)", e_source_peek_uid (default_source), e_source_peek_uid (source));
3310
			/* We don't have it but the default client is it */
3311
			if (!strcmp (e_source_peek_uid (default_source), e_source_peek_uid (source)))
3312
				client = g_object_ref (priv->default_client[source_type]);
3313
		}
3314
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3315
		/* Create a new one */
1 by Sebastien Bacher
Import upstream version 2.5.3
3316
		if (!client) {
3317
			client = auth_new_cal_from_source (source, source_type);
3318
			if (!client)
3319
				return FALSE;
3320
		}
3321
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3322
1 by Sebastien Bacher
Import upstream version 2.5.3
3323
	g_signal_connect (G_OBJECT (client), "backend_error", G_CALLBACK (backend_error_cb), gcal);
3324
	g_signal_connect (G_OBJECT (client), "backend_died", G_CALLBACK (backend_died_cb), gcal);
3325
3326
	/* add the client to internal structure */
3327
	g_hash_table_insert (priv->clients[source_type], g_strdup (e_source_peek_uid (source)), client);
3328
	priv->clients_list[source_type] = g_list_prepend (priv->clients_list[source_type], client);
3329
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3330
	g_signal_emit (gcal, gnome_calendar_signals[SOURCE_ADDED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
3331
3332
	open_ecal (gcal, client, FALSE, client_cal_opened_cb);
3333
3334
	return TRUE;
3335
}
3336
3337
/**
3338
 * gnome_calendar_remove_source
3339
 * @gcal: A #GnomeCalendar.
3340
 * @source: #ESource to be removed from the clients.
3341
 *
3342
 * Removes the given source from the list of clients being shown by the
3343
 * calendar views.
3344
 *
3345
 * Returns: TRUE if successful, FALSE otherwise.
3346
 */
3347
gboolean
3348
gnome_calendar_remove_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
3349
{
3350
	gboolean result;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3351
1 by Sebastien Bacher
Import upstream version 2.5.3
3352
	g_return_val_if_fail (gcal != NULL, FALSE);
3353
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
3354
	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
3355
3356
	result = gnome_calendar_remove_source_by_uid (gcal, source_type, e_source_peek_uid (source));
3357
	if (result)
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3358
		g_signal_emit (gcal, gnome_calendar_signals[SOURCE_REMOVED], 0, source_type, source);
1 by Sebastien Bacher
Import upstream version 2.5.3
3359
3360
	return result;
3361
}
3362
3363
gboolean
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3364
gnome_calendar_remove_source_by_uid (GnomeCalendar *gcal, ECalSourceType source_type, const gchar *uid)
1 by Sebastien Bacher
Import upstream version 2.5.3
3365
{
3366
	GnomeCalendarPrivate *priv;
3367
	ECal *client;
3368
	ECalModel *model;
3369
	GList *l;
3370
3371
	g_return_val_if_fail (gcal != NULL, FALSE);
3372
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
3373
	g_return_val_if_fail (uid != NULL, FALSE);
3374
3375
	priv = gcal->priv;
3376
3377
	client = g_hash_table_lookup (priv->clients[source_type], uid);
3378
	if (!client)
3379
		return TRUE;
3380
3381
	priv->clients_list[source_type] = g_list_remove (priv->clients_list[source_type], client);
3382
	g_signal_handlers_disconnect_matched (client, G_SIGNAL_MATCH_DATA,
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3383
					      0, 0, NULL, NULL, gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
3384
3385
	switch (source_type) {
3386
	case E_CAL_SOURCE_TYPE_EVENT:
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
3387
		g_mutex_lock (priv->dn_queries_lock);
1 by Sebastien Bacher
Import upstream version 2.5.3
3388
		/* remove the query for this client */
3389
		for (l = priv->dn_queries; l != NULL; l = l->next) {
3390
			ECalView *query = l->data;
3391
3392
			if (query && (client == e_cal_view_get_client (query))) {
3393
				g_signal_handlers_disconnect_matched (query, G_SIGNAL_MATCH_DATA,
3394
								      0, 0, NULL, NULL, gcal);
3395
				priv->dn_queries = g_list_remove (priv->dn_queries, query);
3396
				g_object_unref (query);
3397
				break;
3398
			}
3399
		}
1.1.71 by Sebastien Bacher
Import upstream version 2.28.3
3400
		g_mutex_unlock (priv->dn_queries_lock);
1 by Sebastien Bacher
Import upstream version 2.5.3
3401
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
3402
		model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
3403
		e_cal_model_remove_client (model, client);
1 by Sebastien Bacher
Import upstream version 2.5.3
3404
3405
		/* update date navigator query */
3406
		update_query (gcal);
3407
		break;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3408
1 by Sebastien Bacher
Import upstream version 2.5.3
3409
	case E_CAL_SOURCE_TYPE_TODO:
3410
		model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
3411
		e_cal_model_remove_client (model, client);
3412
		break;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3413
3414
	case E_CAL_SOURCE_TYPE_JOURNAL:
3415
		model = e_memo_table_get_model (E_MEMO_TABLE (priv->memo));
3416
		e_cal_model_remove_client (model, client);
3417
		break;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3418
1 by Sebastien Bacher
Import upstream version 2.5.3
3419
	default:
1.1.33 by Sebastien Bacher
Import upstream version 2.11.92
3420
		g_return_val_if_reached (TRUE);
1 by Sebastien Bacher
Import upstream version 2.5.3
3421
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3422
1 by Sebastien Bacher
Import upstream version 2.5.3
3423
	g_hash_table_remove (priv->clients[source_type], uid);
3424
3425
	return TRUE;
3426
}
3427
3428
/**
3429
 * gnome_calendar_set_default_source:
3430
 * @gcal: A calendar view
3431
 * @source: The #ESource to use as default
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3432
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
3433
 * Set the default uri on the given calendar view, the default uri
3434
 * will be used as the default when creating events in the view.
3435
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3436
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
3437
 * Return value: TRUE if the uri was already added and is set, FALSE
3438
 * otherwise
3439
 **/
3440
gboolean
3441
gnome_calendar_set_default_source (GnomeCalendar *gcal, ECalSourceType source_type, ESource *source)
3442
{
3443
	GnomeCalendarPrivate *priv;
3444
	ECal *client;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3445
1 by Sebastien Bacher
Import upstream version 2.5.3
3446
	g_return_val_if_fail (gcal != NULL, FALSE);
3447
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
3448
	g_return_val_if_fail (E_IS_SOURCE (source), FALSE);
3449
3450
	priv = gcal->priv;
3451
3452
	client = g_hash_table_lookup (priv->clients[source_type], e_source_peek_uid (source));
3453
3454
	if (priv->default_client[source_type])
3455
		g_object_unref (priv->default_client[source_type]);
3456
3457
	if (client) {
3458
		priv->default_client[source_type] = g_object_ref (client);
3459
	} else {
3460
		priv->default_client[source_type] = auth_new_cal_from_source (source, source_type);
3461
		if (!priv->default_client[source_type])
3462
			return FALSE;
3463
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3464
1 by Sebastien Bacher
Import upstream version 2.5.3
3465
	open_ecal (gcal, priv->default_client[source_type], FALSE, default_client_cal_opened_cb);
3466
3467
	return TRUE;
3468
}
3469
3470
void
3471
gnome_calendar_set_selected_time_range (GnomeCalendar *gcal,
3472
					time_t	       start_time,
3473
					time_t	       end_time)
3474
{
3475
	update_view_times (gcal, start_time);
3476
	gnome_calendar_update_date_navigator (gcal);
3477
	gnome_calendar_notify_dates_shown_changed (gcal);
3478
}
3479
3480
/**
3481
 * gnome_calendar_get_selected_time_range:
3482
 * @gcal: A calendar view.
3483
 * @start_time: Return value for the start of the time selection.
3484
 * @end_time: Return value for the end of the time selection.
3485
 *
3486
 * Queries the time selection range on the calendar view.
3487
 **/
3488
void
3489
gnome_calendar_get_selected_time_range (GnomeCalendar *gcal,
3490
					time_t	 *start_time,
3491
					time_t	 *end_time)
3492
{
3493
	GnomeCalendarPrivate *priv;
3494
	ECalModel *model;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3495
1 by Sebastien Bacher
Import upstream version 2.5.3
3496
	g_return_if_fail (gcal != NULL);
3497
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3498
3499
	priv = gcal->priv;
3500
3501
	model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
3502
	e_cal_model_get_time_range (model, start_time, end_time);
3503
}
3504
3505
/**
3506
 * gnome_calendar_new_task:
3507
 * @gcal: An Evolution calendar.
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
3508
 * @param dtstart Start time of the task, in same timezone as model.
3509
 * @param dtend End time of the task, in same timezone as model.
1 by Sebastien Bacher
Import upstream version 2.5.3
3510
 *
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
3511
 * Opens a task editor dialog for a new task. dtstart or dtend can be NULL.
1 by Sebastien Bacher
Import upstream version 2.5.3
3512
 **/
3513
void
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
3514
gnome_calendar_new_task		(GnomeCalendar *gcal, time_t *dtstart, time_t *dtend)
1 by Sebastien Bacher
Import upstream version 2.5.3
3515
{
3516
	GnomeCalendarPrivate *priv;
3517
	ECal *ecal;
3518
	ECalModel *model;
1.1.48 by Sebastien Bacher
Import upstream version 2.23.6
3519
	CompEditor *editor;
1 by Sebastien Bacher
Import upstream version 2.5.3
3520
	ECalComponent *comp;
3521
	icalcomponent *icalcomp;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3522
	const gchar *category;
1 by Sebastien Bacher
Import upstream version 2.5.3
3523
	guint32 flags = 0;
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
3524
	ECalComponentDateTime dt;
3525
	struct icaltimetype itt;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3526
1 by Sebastien Bacher
Import upstream version 2.5.3
3527
	g_return_if_fail (gcal != NULL);
3528
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3529
3530
	priv = gcal->priv;
3531
	model = e_calendar_table_get_model (E_CALENDAR_TABLE (priv->todo));
3532
	ecal = e_cal_model_get_default_client (model);
3533
	if (!ecal)
3534
		return;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3535
1 by Sebastien Bacher
Import upstream version 2.5.3
3536
	flags |= COMP_EDITOR_NEW_ITEM;
1.1.48 by Sebastien Bacher
Import upstream version 2.23.6
3537
	editor = task_editor_new (ecal, flags);
1 by Sebastien Bacher
Import upstream version 2.5.3
3538
1.1.62 by Sebastien Bacher
Import upstream version 2.27.4
3539
	icalcomp = e_cal_model_create_component_with_defaults (model, FALSE);
1 by Sebastien Bacher
Import upstream version 2.5.3
3540
	comp = e_cal_component_new ();
3541
	e_cal_component_set_icalcomponent (comp, icalcomp);
3542
3543
	category = cal_search_bar_get_category (CAL_SEARCH_BAR (priv->search_bar));
3544
	e_cal_component_set_categories (comp, category);
3545
1.1.35 by Sebastien Bacher
Import upstream version 2.21.2
3546
	dt.value = &itt;
3547
	dt.tzid = icaltimezone_get_tzid (e_cal_model_get_timezone (model));
3548
3549
	if (dtstart) {
3550
		itt = icaltime_from_timet_with_zone (*dtstart, FALSE, e_cal_model_get_timezone (model));
3551
		e_cal_component_set_dtstart (comp, &dt);
3552
	}
3553
3554
	if (dtend) {
3555
		itt = icaltime_from_timet_with_zone (*dtend, FALSE, e_cal_model_get_timezone (model));
3556
		e_cal_component_set_due (comp, &dt); /* task uses 'due' not 'dtend' */
3557
	}
3558
3559
	if (dtstart || dtend)
3560
		e_cal_component_commit_sequence (comp);
3561
1.1.48 by Sebastien Bacher
Import upstream version 2.23.6
3562
	comp_editor_edit_comp (editor, comp);
1 by Sebastien Bacher
Import upstream version 2.5.3
3563
	g_object_unref (comp);
3564
1.1.48 by Sebastien Bacher
Import upstream version 2.23.6
3565
	gtk_window_present (GTK_WINDOW (editor));
1 by Sebastien Bacher
Import upstream version 2.5.3
3566
}
3567
3568
/* Returns the selected time range for the current view. Note that this may be
3569
   different from the fields in the GnomeCalendar, since the view may clip
3570
   this or choose a more appropriate time. */
3571
void
3572
gnome_calendar_get_current_time_range (GnomeCalendar *gcal,
3573
				       time_t	 *start_time,
3574
				       time_t	 *end_time)
3575
{
3576
	e_calendar_view_get_selected_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)),
3577
					    start_time, end_time);
3578
}
3579
3580
/* Gets the visible time range for the current view. Returns FALSE if no
3581
   time range has been set yet. */
3582
gboolean
3583
gnome_calendar_get_visible_time_range (GnomeCalendar *gcal,
3584
				       time_t	 *start_time,
3585
				       time_t	 *end_time)
3586
{
3587
	gboolean retval = FALSE;
3588
3589
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), FALSE);
3590
3591
	retval = e_calendar_view_get_visible_time_range (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)),
3592
						    start_time, end_time);
3593
3594
	return retval;
3595
}
3596
3597
/* This updates the month shown and the days selected in the calendar, if
3598
   necessary. */
3599
static void
3600
gnome_calendar_update_date_navigator (GnomeCalendar *gcal)
3601
{
3602
	GnomeCalendarPrivate *priv;
3603
	ECalModel *model;
3604
	time_t start, end;
3605
	GDate start_date, end_date;
3606
3607
	priv = gcal->priv;
3608
3609
	/* If the ECalendar isn't visible, we just return. */
3610
	if (!GTK_WIDGET_VISIBLE (priv->date_navigator))
3611
		return;
3612
1.1.26 by Sebastien Bacher
Import upstream version 2.11.3
3613
	if (priv->current_view_type == GNOME_CAL_LIST_VIEW && !priv->lview_select_daten_range)
3614
		return;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3615
1 by Sebastien Bacher
Import upstream version 2.5.3
3616
	model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
3617
	e_cal_model_get_time_range (model, &start, &end);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3618
1 by Sebastien Bacher
Import upstream version 2.5.3
3619
	time_to_gdate_with_zone (&start_date, start, priv->zone);
3620
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW) {
3621
		EWeekView *week_view = E_WEEK_VIEW (priv->views[priv->current_view_type]);
3622
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3623
		if (priv->week_start == 0
1 by Sebastien Bacher
Import upstream version 2.5.3
3624
		    && (!week_view->multi_week_view || week_view->compress_weekend))
3625
			g_date_add_days (&start_date, 1);
3626
	}
3627
	time_to_gdate_with_zone (&end_date, end, priv->zone);
3628
	g_date_subtract_days (&end_date, 1);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3629
1 by Sebastien Bacher
Import upstream version 2.5.3
3630
	e_calendar_item_set_selection (priv->date_navigator->calitem,
3631
				       &start_date, &end_date);
3632
}
3633
3634
static void
3635
gnome_calendar_on_date_navigator_selection_changed (ECalendarItem *calitem, GnomeCalendar *gcal)
3636
{
3637
	GnomeCalendarPrivate *priv;
3638
	GnomeCalendarViewType view_type;
3639
	ECalModel *model;
3640
	GDate start_date, end_date, new_start_date, new_end_date;
3641
	gint new_days_shown;
3642
	gboolean starts_on_week_start_day;
3643
	time_t new_time, start, end;
3644
	struct icaltimetype tt;
3645
3646
	priv = gcal->priv;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3647
1 by Sebastien Bacher
Import upstream version 2.5.3
3648
	starts_on_week_start_day = FALSE;
3649
3650
	model = e_calendar_view_get_model (priv->views[priv->current_view_type]);
3651
	e_cal_model_get_time_range (model, &start, &end);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3652
1 by Sebastien Bacher
Import upstream version 2.5.3
3653
	time_to_gdate_with_zone (&start_date, start, priv->zone);
3654
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW) {
3655
		EWeekView *week_view = E_WEEK_VIEW (priv->views[priv->current_view_type]);
3656
3657
		if (priv->week_start == 0 && (!week_view->multi_week_view || week_view->compress_weekend))
3658
			g_date_add_days (&start_date, 1);
3659
	}
3660
	time_to_gdate_with_zone (&end_date, end, priv->zone);
3661
	g_date_subtract_days (&end_date, 1);
3662
3663
	e_calendar_item_get_selection (calitem, &new_start_date, &new_end_date);
3664
3665
	/* If the selection hasn't changed just return. */
3666
	if (!g_date_compare (&start_date, &new_start_date)
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
3667
	    && !g_date_compare (&end_date, &new_end_date)) {
1 by Sebastien Bacher
Import upstream version 2.5.3
3668
		return;
1.1.49 by Sebastien Bacher
Import upstream version 2.23.90
3669
	}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3670
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
3671
	new_days_shown = g_date_get_julian (&new_end_date) - g_date_get_julian (&new_start_date) + 1;
1 by Sebastien Bacher
Import upstream version 2.5.3
3672
3673
	/* If a complete week is selected we show the Week view.
3674
	   Note that if weekends are compressed and the week start day is set
3675
	   to Sunday we don't actually show complete weeks in the Week view,
3676
	   so this may need tweaking. */
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
3677
	if (g_date_get_weekday (&new_start_date) % 7 == priv->week_start)
1 by Sebastien Bacher
Import upstream version 2.5.3
3678
		starts_on_week_start_day = TRUE;
3679
3680
	/* Update selection to be in the new time range */
3681
	tt = icaltime_null_time ();
1.1.16 by Sebastien Bacher
Import upstream version 2.9.3
3682
	tt.year = g_date_get_year (&new_start_date);
3683
	tt.month  = g_date_get_month (&new_start_date);
3684
	tt.day = g_date_get_day (&new_start_date);
1 by Sebastien Bacher
Import upstream version 2.5.3
3685
	new_time = icaltime_as_timet_with_zone (tt, priv->zone);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3686
1 by Sebastien Bacher
Import upstream version 2.5.3
3687
	/* Switch views as appropriate, and change the number of days or weeks
3688
	   shown. */
3689
	if (new_days_shown > 9) {
3690
		/* FIXME Gross hack so that the view times are updated properly */
3691
		priv->range_selected = TRUE;
3692
1.1.6 by Sebastien Bacher
Import upstream version 2.6.0
3693
		if (priv->current_view_type != GNOME_CAL_LIST_VIEW) {
1.1.2 by Sebastien Bacher
Import upstream version 2.5.5.1
3694
			e_week_view_set_weeks_shown (E_WEEK_VIEW (priv->month_view),
1 by Sebastien Bacher
Import upstream version 2.5.3
3695
					     (new_days_shown + 6) / 7);
1.1.2 by Sebastien Bacher
Import upstream version 2.5.5.1
3696
			view_type = GNOME_CAL_MONTH_VIEW;
3697
		} else
3698
			view_type = GNOME_CAL_LIST_VIEW;
1 by Sebastien Bacher
Import upstream version 2.5.3
3699
	} else if (new_days_shown == 7 && starts_on_week_start_day) {
3700
		view_type = GNOME_CAL_WEEK_VIEW;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3701
	} else {
1 by Sebastien Bacher
Import upstream version 2.5.3
3702
		e_day_view_set_days_shown (E_DAY_VIEW (priv->day_view), new_days_shown);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3703
3704
		if (new_days_shown == 5 && starts_on_week_start_day
1 by Sebastien Bacher
Import upstream version 2.5.3
3705
		    && priv->current_view_type == GNOME_CAL_WORK_WEEK_VIEW)
3706
			view_type = GNOME_CAL_WORK_WEEK_VIEW;
3707
		else
3708
			view_type = GNOME_CAL_DAY_VIEW;
3709
	}
3710
3711
	/* Make the views display things properly */
3712
	update_view_times (gcal, new_time);
3713
	set_view (gcal, view_type, TRUE);
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
3714
1 by Sebastien Bacher
Import upstream version 2.5.3
3715
	gnome_calendar_notify_dates_shown_changed (gcal);
3716
}
3717
3718
static void
3719
gnome_calendar_on_date_navigator_date_range_changed (ECalendarItem *calitem, GnomeCalendar *gcal)
3720
{
3721
	update_query (gcal);
3722
}
3723
3724
static void
3725
gnome_calendar_hpane_realized (GtkWidget *w, GnomeCalendar *gcal)
3726
{
3727
	GnomeCalendarPrivate *priv;
3728
3729
	priv = gcal->priv;
3730
3731
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
3732
		gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos_month_view);
3733
	} else {
3734
		gtk_paned_set_position (GTK_PANED (priv->hpane), priv->hpane_pos);
3735
	}
3736
}
3737
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3738
static void
1 by Sebastien Bacher
Import upstream version 2.5.3
3739
gnome_calendar_date_navigator_scrolled (GtkWidget *widget, GdkEventScroll *event, gpointer user_data)
3740
{
3741
	GnomeCalendar *gcal = user_data;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3742
	ECalendarItem *calitem = gcal->priv->date_navigator->calitem;
1 by Sebastien Bacher
Import upstream version 2.5.3
3743
	GDate start_date, end_date;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3744
1 by Sebastien Bacher
Import upstream version 2.5.3
3745
	if (e_calendar_item_get_selection (calitem, &start_date, &end_date)) {
3746
		switch (event->direction) {
3747
		case GDK_SCROLL_UP:
3748
			g_date_subtract_months (&start_date, 1);
3749
			g_date_subtract_months (&end_date, 1);
3750
			break;
3751
		case GDK_SCROLL_DOWN:
3752
			g_date_add_months (&start_date, 1);
3753
			g_date_add_months (&end_date, 1);
3754
			break;
3755
		default:
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3756
			break;
3757
1 by Sebastien Bacher
Import upstream version 2.5.3
3758
		}
3759
		e_calendar_item_set_selection (calitem, &start_date, &end_date);
3760
		gnome_calendar_on_date_navigator_selection_changed (calitem, gcal);
3761
	}
3762
}
3763
3764
static gboolean
3765
gnome_calendar_hpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal)
3766
{
3767
	GnomeCalendarPrivate *priv;
3768
	gint times_width;
3769
3770
	priv = gcal->priv;
3771
3772
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
3773
		priv->hpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->hpane));
3774
		calendar_config_set_month_hpane_pos (priv->hpane_pos_month_view);
3775
	} else {
3776
		priv->hpane_pos = gtk_paned_get_position (GTK_PANED (priv->hpane));
3777
		calendar_config_set_hpane_pos (priv->hpane_pos);
3778
	}
3779
3780
	/* adjust the size of the EDayView's time column */
3781
	times_width = e_day_view_time_item_get_column_width (
3782
		E_DAY_VIEW_TIME_ITEM (E_DAY_VIEW (priv->day_view)->time_canvas_item));
3783
	if (times_width < priv->hpane_pos - 20)
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
3784
		gtk_widget_set_size_request (E_DAY_VIEW (priv->day_view)->time_canvas, times_width, -1);
1 by Sebastien Bacher
Import upstream version 2.5.3
3785
	else
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
3786
		gtk_widget_set_size_request (E_DAY_VIEW (priv->day_view)->time_canvas, priv->hpane_pos - 20, -1);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3787
1 by Sebastien Bacher
Import upstream version 2.5.3
3788
	return FALSE;
3789
}
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3790
static void
3791
gnome_calendar_vpane_realized (GtkWidget *w, GnomeCalendar *gcal)
3792
{
3793
	GnomeCalendarPrivate *priv;
3794
3795
	priv = gcal->priv;
3796
3797
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
3798
		gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos_month_view);
3799
	} else {
3800
		gtk_paned_set_position (GTK_PANED (priv->vpane), priv->vpane_pos);
3801
	}
3802
}
3803
3804
static gboolean
3805
gnome_calendar_vpane_resized (GtkWidget *w, GdkEventButton *e, GnomeCalendar *gcal)
3806
{
3807
	GnomeCalendarPrivate *priv;
3808
3809
	priv = gcal->priv;
3810
3811
	if (priv->current_view_type == GNOME_CAL_MONTH_VIEW && !priv->range_selected) {
3812
		priv->vpane_pos_month_view = gtk_paned_get_position (GTK_PANED (priv->vpane));
3813
		calendar_config_set_month_vpane_pos (priv->vpane_pos_month_view);
3814
	} else {
3815
		priv->vpane_pos = gtk_paned_get_position (GTK_PANED (priv->vpane));
3816
		calendar_config_set_vpane_pos (priv->vpane_pos);
3817
	}
3818
3819
	return FALSE;
3820
}
1 by Sebastien Bacher
Import upstream version 2.5.3
3821
3822
void
3823
gnome_calendar_cut_clipboard (GnomeCalendar *gcal)
3824
{
3825
	GnomeCalendarPrivate *priv;
3826
	FocusLocation location;
3827
3828
	priv = gcal->priv;
3829
3830
	location = get_focus_location (gcal);
3831
3832
	if (location == FOCUS_CALENDAR) {
3833
		e_calendar_view_cut_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
3834
	} else if (location == FOCUS_TASKPAD)
3835
		e_calendar_table_cut_clipboard (E_CALENDAR_TABLE (priv->todo));
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3836
	else if (location == FOCUS_MEMOPAD)
1.1.15 by Sebastien Bacher
Import upstream version 2.9.2
3837
		e_memo_table_cut_clipboard (E_MEMO_TABLE (priv->memo));
1 by Sebastien Bacher
Import upstream version 2.5.3
3838
}
3839
3840
void
3841
gnome_calendar_copy_clipboard (GnomeCalendar *gcal)
3842
{
3843
	GnomeCalendarPrivate *priv;
3844
	FocusLocation location;
3845
3846
	priv = gcal->priv;
3847
3848
	location = get_focus_location (gcal);
3849
3850
	if (location == FOCUS_CALENDAR) {
3851
		e_calendar_view_copy_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
3852
	} else if (location == FOCUS_TASKPAD)
3853
		e_calendar_table_copy_clipboard (E_CALENDAR_TABLE (priv->todo));
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3854
	else if (location == FOCUS_MEMOPAD)
1.1.15 by Sebastien Bacher
Import upstream version 2.9.2
3855
		e_memo_table_copy_clipboard (E_MEMO_TABLE (priv->memo));
1 by Sebastien Bacher
Import upstream version 2.5.3
3856
}
3857
3858
void
3859
gnome_calendar_paste_clipboard (GnomeCalendar *gcal)
3860
{
3861
	GnomeCalendarPrivate *priv;
3862
	FocusLocation location;
3863
3864
	priv = gcal->priv;
3865
3866
	location = get_focus_location (gcal);
3867
3868
	if (location == FOCUS_CALENDAR) {
3869
		e_calendar_view_paste_clipboard (E_CALENDAR_VIEW (gnome_calendar_get_current_view_widget (gcal)));
3870
	} else if (location == FOCUS_TASKPAD)
3871
		e_calendar_table_paste_clipboard (E_CALENDAR_TABLE (priv->todo));
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3872
	else if (location == FOCUS_MEMOPAD)
3873
		e_memo_table_paste_clipboard (E_MEMO_TABLE (priv->memo));
1 by Sebastien Bacher
Import upstream version 2.5.3
3874
}
3875
3876
/* Get the current timezone. */
3877
icaltimezone*
3878
gnome_calendar_get_timezone	(GnomeCalendar	*gcal)
3879
{
3880
	g_return_val_if_fail (gcal != NULL, NULL);
3881
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
3882
3883
	return gcal->priv->zone;
3884
}
3885
3886
static void
3887
gnome_calendar_notify_dates_shown_changed (GnomeCalendar *gcal)
3888
{
3889
	GnomeCalendarPrivate *priv;
3890
	time_t start_time, end_time;
3891
3892
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3893
3894
	priv = gcal->priv;
3895
3896
	/* If no time range is set yet, just return. */
3897
	if (!gnome_calendar_get_visible_time_range (gcal, &start_time,
3898
						    &end_time))
3899
		return;
3900
3901
	/* We check if the visible date range has changed, and only emit the
3902
	   signal if it has. (This makes sure we only change the folder title
3903
	   bar label in the shell when we need to.) */
3904
	if (priv->visible_start != start_time
3905
	    || priv->visible_end != end_time) {
3906
		priv->visible_start = start_time;
3907
		priv->visible_end = end_time;
3908
1.1.46 by Sebastien Bacher
Import upstream version 2.23.3.1
3909
		g_signal_emit (gcal, gnome_calendar_signals[DATES_SHOWN_CHANGED], 0);
1 by Sebastien Bacher
Import upstream version 2.5.3
3910
	}
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3911
	update_memo_view (gcal);
1 by Sebastien Bacher
Import upstream version 2.5.3
3912
}
3913
3914
/* Returns the number of selected events (0 or 1 at present). */
3915
gint
3916
gnome_calendar_get_num_events_selected (GnomeCalendar *gcal)
3917
{
3918
	GtkWidget *view;
3919
	gint retval = 0;
3920
3921
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), 0);
3922
3923
	view = gnome_calendar_get_current_view_widget (gcal);
3924
	if (E_IS_DAY_VIEW (view))
3925
		retval = e_day_view_get_num_events_selected (E_DAY_VIEW (view));
3926
	else
3927
		retval = e_week_view_get_num_events_selected (E_WEEK_VIEW (view));
3928
3929
	return retval;
3930
}
3931
3932
/**
3933
 * gnome_calendar_get_num_tasks_selected:
3934
 * @gcal: A calendar view.
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3935
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
3936
 * Queries the number of tasks that are currently selected in the task pad of a
3937
 * calendar view.
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
3938
 *
1 by Sebastien Bacher
Import upstream version 2.5.3
3939
 * Return value: Number of selected tasks.
3940
 **/
3941
gint
3942
gnome_calendar_get_num_tasks_selected (GnomeCalendar *gcal)
3943
{
3944
	GnomeCalendarPrivate *priv;
3945
	ETable *etable;
3946
3947
	g_return_val_if_fail (gcal != NULL, -1);
3948
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), -1);
3949
3950
	priv = gcal->priv;
3951
3952
	etable = e_calendar_table_get_table (E_CALENDAR_TABLE (priv->todo));
3953
	return e_table_selected_count (etable);
3954
}
3955
3956
void
3957
gnome_calendar_delete_selection		(GnomeCalendar  *gcal)
3958
{
3959
	GnomeCalendarPrivate *priv;
3960
	FocusLocation location;
3961
	GtkWidget *view;
3962
3963
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3964
3965
	priv = gcal->priv;
3966
3967
	location = get_focus_location (gcal);
3968
3969
	if (location == FOCUS_CALENDAR) {
3970
		view = gnome_calendar_get_current_view_widget (gcal);
3971
3972
		e_calendar_view_delete_selected_events (E_CALENDAR_VIEW (view));
3973
	} else if (location == FOCUS_TASKPAD)
3974
		e_calendar_table_delete_selected (E_CALENDAR_TABLE (priv->todo));
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
3975
	else if (location == FOCUS_MEMOPAD)
3976
		e_memo_table_delete_selected (E_MEMO_TABLE (priv->memo));
1 by Sebastien Bacher
Import upstream version 2.5.3
3977
}
3978
3979
void
3980
gnome_calendar_delete_selected_occurrence (GnomeCalendar *gcal)
3981
{
3982
	FocusLocation location;
3983
	GtkWidget *view;
3984
3985
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
3986
3987
	location = get_focus_location (gcal);
3988
3989
	if (location == FOCUS_CALENDAR) {
3990
3991
		view = gnome_calendar_get_current_view_widget (gcal);
3992
		e_calendar_view_delete_selected_occurrence (E_CALENDAR_VIEW (view));
3993
	}
3994
}
3995
1.1.68 by Sebastien Bacher
Import upstream version 2.28.0
3996
struct purge_data {
3997
	gboolean remove;
3998
	time_t older_than;
3999
};
4000
1 by Sebastien Bacher
Import upstream version 2.5.3
4001
static gboolean
4002
check_instance_cb (ECalComponent *comp,
4003
		   time_t instance_start,
4004
		   time_t instance_end,
4005
		   gpointer data)
4006
{
1.1.68 by Sebastien Bacher
Import upstream version 2.28.0
4007
	struct purge_data *pd = data;
4008
4009
	if (instance_end >= pd->older_than)
4010
		pd->remove = FALSE;
4011
4012
	return pd->remove;
1 by Sebastien Bacher
Import upstream version 2.5.3
4013
}
4014
4015
void
4016
gnome_calendar_purge (GnomeCalendar *gcal, time_t older_than)
4017
{
4018
	GnomeCalendarPrivate *priv;
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4019
	gchar *sexp, *start, *end;
1 by Sebastien Bacher
Import upstream version 2.5.3
4020
	GList *l;
4021
4022
	g_return_if_fail (GNOME_IS_CALENDAR (gcal));
4023
4024
	priv = gcal->priv;
4025
4026
	start = isodate_from_time_t (0);
4027
	end = isodate_from_time_t (older_than);
4028
	sexp = g_strdup_printf ("(occur-in-time-range? (make-time \"%s\")"
4029
				"                      (make-time \"%s\"))",
4030
				start, end);
4031
4032
	e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), _("Purging"), -1);
4033
4034
	/* FIXME Confirm expunge */
4035
	for (l = priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
4036
		ECal *client = l->data;
4037
		GList *objects, *m;
4038
		gboolean read_only;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4039
1 by Sebastien Bacher
Import upstream version 2.5.3
4040
		if (!e_cal_is_read_only (client, &read_only, NULL) || read_only)
4041
			continue;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4042
1 by Sebastien Bacher
Import upstream version 2.5.3
4043
		if (!e_cal_get_object_list (client, sexp, &objects, NULL)) {
4044
			g_warning (G_STRLOC ": Could not get the objects");
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4045
1 by Sebastien Bacher
Import upstream version 2.5.3
4046
			continue;
4047
		}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4048
1 by Sebastien Bacher
Import upstream version 2.5.3
4049
		for (m = objects; m; m = m->next) {
4050
			gboolean remove = TRUE;
4051
4052
			/* FIXME write occur-before and occur-after
4053
			 * sexp funcs so we don't have to use the max
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4054
			 * gint */
1.1.68 by Sebastien Bacher
Import upstream version 2.28.0
4055
			if (!e_cal_get_static_capability (client, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
4056
				struct purge_data pd;
4057
4058
				pd.remove = TRUE;
4059
				pd.older_than = older_than;
4060
1.1.3 by Sebastien Bacher
Import upstream version 2.5.90
4061
				e_cal_generate_instances_for_object (client, m->data,
1 by Sebastien Bacher
Import upstream version 2.5.3
4062
							     older_than, G_MAXINT32,
4063
							     (ECalRecurInstanceFn) check_instance_cb,
1.1.68 by Sebastien Bacher
Import upstream version 2.28.0
4064
							     &pd);
4065
4066
				remove = pd.remove;
4067
			}
1 by Sebastien Bacher
Import upstream version 2.5.3
4068
4069
			/* FIXME Better error handling */
4070
			if (remove) {
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4071
				const gchar *uid = icalcomponent_get_uid (m->data);
1.1.3 by Sebastien Bacher
Import upstream version 2.5.90
4072
				GError *error = NULL;
4073
4074
				if (e_cal_util_component_is_instance (m->data) || e_cal_util_component_has_recurrences (m->data)) {
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4075
					gchar *rid = NULL;
1.1.3 by Sebastien Bacher
Import upstream version 2.5.90
4076
					struct icaltimetype recur_id = icalcomponent_get_recurrenceid (m->data);
4077
4078
					if (!icaltime_is_null_time (recur_id) )
1.1.56 by Andrew Starr-Bochicchio
Import upstream version 2.25.90
4079
						rid = icaltime_as_ical_string_r (recur_id);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4080
1.1.3 by Sebastien Bacher
Import upstream version 2.5.90
4081
					e_cal_remove_object_with_mod (client, uid, rid, CALOBJ_MOD_ALL, &error);
1.1.41 by Sebastien Bacher
Import upstream version 2.21.92
4082
					g_free (rid);
1.1.3 by Sebastien Bacher
Import upstream version 2.5.90
4083
				} else {
4084
					e_cal_remove_object (client, uid, &error);
4085
				}
4086
4087
				if (error) {
4088
					g_warning ("Unable to purge events %s \n", error->message);
4089
					g_error_free (error);
4090
				}
1 by Sebastien Bacher
Import upstream version 2.5.3
4091
			}
4092
		}
4093
4094
		g_list_foreach (objects, (GFunc) icalcomponent_free, NULL);
4095
		g_list_free (objects);
4096
	}
4097
4098
	e_calendar_view_set_status_message (E_CALENDAR_VIEW (priv->week_view), NULL, -1);
4099
4100
	g_free (sexp);
4101
	g_free (start);
4102
	g_free (end);
4103
4104
}
4105
4106
ECalendarTable*
4107
gnome_calendar_get_task_pad	(GnomeCalendar *gcal)
4108
{
4109
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
4110
4111
	return E_CALENDAR_TABLE (gcal->priv->todo);
4112
}
4113
4114
GtkWidget *
4115
gnome_calendar_get_e_calendar_widget (GnomeCalendar *gcal)
4116
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4117
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4118
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4119
	return GTK_WIDGET(gcal->priv->date_navigator);
1 by Sebastien Bacher
Import upstream version 2.5.3
4120
}
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4121
1 by Sebastien Bacher
Import upstream version 2.5.3
4122
GtkWidget *
4123
gnome_calendar_get_search_bar_widget (GnomeCalendar *gcal)
4124
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4125
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4126
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4127
	return GTK_WIDGET(gcal->priv->search_bar);
1 by Sebastien Bacher
Import upstream version 2.5.3
4128
}
4129
4130
GtkWidget *
4131
gnome_calendar_get_view_notebook_widget (GnomeCalendar *gcal)
4132
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4133
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4134
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4135
	return GTK_WIDGET(gcal->priv->notebook);
1 by Sebastien Bacher
Import upstream version 2.5.3
4136
}
4137
4138
ECalMenu *gnome_calendar_get_taskpad_menu (GnomeCalendar *gcal)
4139
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4140
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4141
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4142
	return gcal->priv->taskpad_menu;
1 by Sebastien Bacher
Import upstream version 2.5.3
4143
}
4144
4145
ECalMenu *gnome_calendar_get_calendar_menu (GnomeCalendar *gcal)
4146
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4147
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4148
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4149
	return gcal->priv->calendar_menu;
1 by Sebastien Bacher
Import upstream version 2.5.3
4150
}
4151
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
4152
ECalMenu *gnome_calendar_get_memopad_menu (GnomeCalendar *gcal)
4153
{
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4154
	g_return_val_if_fail (GNOME_IS_CALENDAR (gcal), NULL);
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4155
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4156
	return gcal->priv->memopad_menu;
1.1.10 by Sebastien Bacher
Import upstream version 2.7.90
4157
}
4158
1 by Sebastien Bacher
Import upstream version 2.5.3
4159
void
4160
gnome_calendar_edit_appointment (GnomeCalendar *gcal,
1.1.61 by Sebastien Bacher
Import upstream version 2.27.3
4161
				 const gchar * src_uid,
4162
				 const gchar * comp_uid,
4163
				 const gchar * comp_rid)
1 by Sebastien Bacher
Import upstream version 2.5.3
4164
{
4165
	ECal *client = NULL;
4166
	GList *l;
4167
	icalcomponent* icalcomp = NULL;
4168
	icalproperty *attendee_prop = NULL;
4169
4170
	if (!src_uid || !comp_uid)
4171
		return;
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4172
1 by Sebastien Bacher
Import upstream version 2.5.3
4173
	for (l = gcal->priv->clients_list[E_CAL_SOURCE_TYPE_EVENT]; l != NULL; l = l->next) {
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
4174
		ESource *client_src;
4175
1 by Sebastien Bacher
Import upstream version 2.5.3
4176
		client = l->data;
1.1.24 by Sebastien Bacher
Import upstream version 2.11.1.1
4177
		client_src = e_cal_get_source (client);
1 by Sebastien Bacher
Import upstream version 2.5.3
4178
4179
		if (!strcmp (src_uid, e_source_peek_uid (client_src)))
4180
			break;
4181
	}
4182
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4183
	if (!client)
1 by Sebastien Bacher
Import upstream version 2.5.3
4184
		return;
4185
4186
	e_cal_get_object (client, comp_uid, comp_rid, &icalcomp, NULL);
4187
4188
	if (!icalcomp)
4189
		return;
4190
4191
	attendee_prop = icalcomponent_get_first_property (icalcomp, ICAL_ATTENDEE_PROPERTY);
4192
	e_calendar_view_edit_appointment (gcal->priv->views[gcal->priv->current_view_type],
1.1.36 by Sebastien Bacher
Import upstream version 2.21.3
4193
					  client, icalcomp, attendee_prop ? TRUE:FALSE);
1 by Sebastien Bacher
Import upstream version 2.5.3
4194
	icalcomponent_free (icalcomp);
4195
}