Blame src/modules/calendar/e-cal-shell-content.c

Packit 15f964
/*
Packit 15f964
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
Packit 15f964
 * Copyright (C) 2014 Red Hat, Inc. (www.redhat.com)
Packit 15f964
 *
Packit 15f964
 * This program is free software; you can redistribute it and/or modify it
Packit 15f964
 * under the terms of the GNU Lesser General Public License as published by
Packit 15f964
 * the Free Software Foundation.
Packit 15f964
 *
Packit 15f964
 * This program is distributed in the hope that it will be useful, but
Packit 15f964
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit 15f964
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
Packit 15f964
 * for more details.
Packit 15f964
 *
Packit 15f964
 * You should have received a copy of the GNU Lesser General Public License
Packit 15f964
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit 15f964
 */
Packit 15f964
Packit 15f964
#include "evolution-config.h"
Packit 15f964
Packit 15f964
#include <string.h>
Packit 15f964
#include <math.h>
Packit 15f964
#include <glib/gi18n-lib.h>
Packit 15f964
Packit 15f964
#include "calendar/gui/calendar-config.h"
Packit 15f964
#include "calendar/gui/calendar-view.h"
Packit 15f964
#include "calendar/gui/comp-util.h"
Packit 15f964
#include "calendar/gui/e-cal-list-view.h"
Packit 15f964
#include "calendar/gui/e-cal-model-calendar.h"
Packit 15f964
#include "calendar/gui/e-cal-model-memos.h"
Packit 15f964
#include "calendar/gui/e-cal-model-tasks.h"
Packit 15f964
#include "calendar/gui/e-calendar-view.h"
Packit 15f964
#include "calendar/gui/e-day-view.h"
Packit 15f964
#include "calendar/gui/e-month-view.h"
Packit 15f964
#include "calendar/gui/e-week-view.h"
Packit 15f964
#include "calendar/gui/itip-utils.h"
Packit 15f964
#include "calendar/gui/tag-calendar.h"
Packit 15f964
Packit 15f964
#include "e-cal-base-shell-sidebar.h"
Packit 15f964
#include "e-cal-shell-view-private.h"
Packit 15f964
#include "e-cal-shell-content.h"
Packit 15f964
Packit 15f964
#define E_CAL_SHELL_CONTENT_GET_PRIVATE(obj) \
Packit 15f964
	(G_TYPE_INSTANCE_GET_PRIVATE \
Packit 15f964
	((obj), E_TYPE_CAL_SHELL_CONTENT, ECalShellContentPrivate))
Packit 15f964
Packit 15f964
struct _ECalShellContentPrivate {
Packit 15f964
	GtkWidget *hpaned;
Packit 15f964
	GtkWidget *vpaned;
Packit 15f964
Packit 15f964
	GtkWidget *calendar_notebook;
Packit 15f964
	GtkWidget *task_table;
Packit 15f964
	ECalModel *task_model;
Packit 15f964
	ECalDataModel *task_data_model;
Packit 15f964
Packit 15f964
	GtkWidget *memo_table;
Packit 15f964
	ECalModel *memo_model;
Packit 15f964
	ECalDataModel *memo_data_model;
Packit 15f964
Packit 15f964
	ETagCalendar *tag_calendar;
Packit 15f964
	gulong datepicker_selection_changed_id;
Packit 15f964
	gulong datepicker_range_moved_id;
Packit 15f964
Packit 15f964
	ECalViewKind current_view;
Packit 15f964
	ECalendarView *views[E_CAL_VIEW_KIND_LAST];
Packit 15f964
	GDate view_start, view_end;
Packit 15f964
	guint32 view_start_range_day_offset;
Packit 15f964
	GDate last_range_start; /* because "date-range-changed" can be emit with no real change */
Packit 15f964
Packit 15f964
	time_t previous_selected_start_time;
Packit 15f964
	time_t previous_selected_end_time;
Packit 15f964
Packit 15f964
	gulong current_view_id_changed_id;
Packit 15f964
};
Packit 15f964
Packit 15f964
enum {
Packit 15f964
	PROP_0,
Packit 15f964
	PROP_CALENDAR_NOTEBOOK,
Packit 15f964
	PROP_MEMO_TABLE,
Packit 15f964
	PROP_TASK_TABLE,
Packit 15f964
	PROP_CURRENT_VIEW_ID,
Packit 15f964
	PROP_CURRENT_VIEW
Packit 15f964
};
Packit 15f964
Packit 15f964
/* Used to indicate who has the focus within the calendar view. */
Packit 15f964
typedef enum {
Packit 15f964
	FOCUS_CALENDAR_NOTEBOOK,
Packit 15f964
	FOCUS_MEMO_TABLE,
Packit 15f964
	FOCUS_TASK_TABLE,
Packit 15f964
	FOCUS_OTHER
Packit 15f964
} FocusLocation;
Packit 15f964
Packit 15f964
G_DEFINE_DYNAMIC_TYPE (ECalShellContent, e_cal_shell_content, E_TYPE_CAL_BASE_SHELL_CONTENT)
Packit 15f964
Packit 15f964
static time_t
Packit 15f964
convert_to_local_zone (time_t tm,
Packit 15f964
		       icaltimezone *from_zone)
Packit 15f964
{
Packit 15f964
	struct icaltimetype tt;
Packit 15f964
Packit 15f964
	tt = icaltime_from_timet_with_zone (tm, FALSE, from_zone);
Packit 15f964
	return icaltime_as_timet (tt);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_update_model_and_current_view_times (ECalShellContent *cal_shell_content,
Packit 15f964
						       ECalModel *model,
Packit 15f964
						       ECalendarItem *calitem,
Packit 15f964
						       time_t view_start_tt,
Packit 15f964
						       time_t view_end_tt,
Packit 15f964
						       const GDate *view_start,
Packit 15f964
						       const GDate *view_end)
Packit 15f964
{
Packit 15f964
	ECalendarView *current_view;
Packit 15f964
	EDayView *day_view = NULL;
Packit 15f964
	gint day_view_selection_start_day = -1, day_view_selection_end_day = -1;
Packit 15f964
	gint day_view_selection_start_row = -1, day_view_selection_end_row = -1;
Packit 15f964
	gdouble day_view_scrollbar_position = 0.0;
Packit 15f964
	gint syy, smm, sdd, eyy, emm, edd;
Packit 15f964
	time_t visible_range_start, visible_range_end;
Packit 15f964
	gboolean filters_updated = FALSE;
Packit 15f964
	icaltimezone *zone;
Packit 15f964
	gchar *cal_filter;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
Packit 15f964
Packit 15f964
	current_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
Packit 15f964
	g_return_if_fail (current_view != NULL);
Packit 15f964
Packit 15f964
	zone = e_cal_model_get_timezone (model);
Packit 15f964
	cal_filter = e_cal_data_model_dup_filter (e_cal_model_get_data_model (model));
Packit 15f964
Packit 15f964
	if (E_IS_DAY_VIEW (current_view)) {
Packit 15f964
		GtkAdjustment *adjustment;
Packit 15f964
Packit 15f964
		day_view = E_DAY_VIEW (current_view);
Packit 15f964
		day_view_selection_start_day = day_view->selection_start_day;
Packit 15f964
		day_view_selection_end_day = day_view->selection_end_day;
Packit 15f964
		day_view_selection_start_row = day_view->selection_start_row;
Packit 15f964
		day_view_selection_end_row = day_view->selection_end_row;
Packit 15f964
Packit 15f964
		adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->main_canvas));
Packit 15f964
		day_view_scrollbar_position = gtk_adjustment_get_value (adjustment);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	g_signal_handler_block (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
	g_signal_handler_block (calitem, cal_shell_content->priv->datepicker_selection_changed_id);
Packit 15f964
Packit 15f964
	visible_range_start = view_start_tt;
Packit 15f964
	visible_range_end = view_end_tt;
Packit 15f964
Packit 15f964
	e_calendar_view_precalc_visible_time_range (current_view, view_start_tt, view_end_tt, &visible_range_start, &visible_range_end);
Packit 15f964
	if (view_start_tt != visible_range_start || view_end_tt != visible_range_end) {
Packit 15f964
		time_t cmp_range_start = convert_to_local_zone (visible_range_start, zone);
Packit 15f964
		time_t cmp_range_end = convert_to_local_zone (visible_range_end, zone);
Packit 15f964
Packit 15f964
		if (view_start_tt != cmp_range_start ||
Packit 15f964
		    view_end_tt != cmp_range_end - 1) {
Packit 15f964
			/* Calendar views update their inner time range during e_cal_model_set_time_range() call,
Packit 15f964
			   while they can change it if needed (like a clamp of a week view with a week start day
Packit 15f964
			   not being Monday */
Packit 15f964
			GDate new_view_start, new_view_end;
Packit 15f964
Packit 15f964
			/* Midnight means the next day, which is not desired here */
Packit 15f964
			cmp_range_end--;
Packit 15f964
			visible_range_end--;
Packit 15f964
Packit 15f964
			/* These times are in the correct zone already */
Packit 15f964
			time_to_gdate_with_zone (&new_view_start, cmp_range_start, NULL);
Packit 15f964
			time_to_gdate_with_zone (&new_view_end, cmp_range_end, NULL);
Packit 15f964
Packit 15f964
			e_calendar_item_set_selection (calitem, &new_view_start, &new_view_end);
Packit 15f964
			e_cal_shell_content_update_filters (cal_shell_content, cal_filter, visible_range_start, visible_range_end);
Packit 15f964
			e_calendar_view_set_selected_time_range (current_view, cmp_range_start, cmp_range_start);
Packit 15f964
			filters_updated = TRUE;
Packit 15f964
			view_start_tt = cmp_range_start;
Packit 15f964
			view_end_tt = cmp_range_end;
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (!filters_updated) {
Packit 15f964
		e_calendar_item_set_selection (calitem, view_start, view_end);
Packit 15f964
		e_cal_shell_content_update_filters (cal_shell_content, cal_filter, view_start_tt, view_end_tt);
Packit 15f964
		e_calendar_view_set_selected_time_range (current_view, view_start_tt, view_start_tt);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (day_view && day_view_selection_start_day != -1 && day_view_selection_end_day != -1 &&
Packit 15f964
	    day_view_selection_start_row != -1 && day_view_selection_end_row != -1) {
Packit 15f964
		GtkAdjustment *adjustment;
Packit 15f964
Packit 15f964
		day_view->selection_start_day = day_view_selection_start_day;
Packit 15f964
		day_view->selection_end_day = day_view_selection_end_day;
Packit 15f964
		day_view->selection_start_row = day_view_selection_start_row;
Packit 15f964
		day_view->selection_end_row = day_view_selection_end_row;
Packit 15f964
Packit 15f964
		/* This is better than e_day_view_ensure_rows_visible(), because it keeps both
Packit 15f964
		   selection and the exact scrollbar position in the main canvas, which may not
Packit 15f964
		   always correspond to each other. */
Packit 15f964
		adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->main_canvas));
Packit 15f964
		gtk_adjustment_set_value (adjustment, day_view_scrollbar_position);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	gtk_widget_queue_draw (GTK_WIDGET (current_view));
Packit 15f964
Packit 15f964
	g_free (cal_filter);
Packit 15f964
Packit 15f964
	g_signal_handler_unblock (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
	g_signal_handler_unblock (calitem, cal_shell_content->priv->datepicker_selection_changed_id);
Packit 15f964
Packit 15f964
	if (e_calendar_item_get_date_range (calitem, &syy, &smm, &sdd, &eyy, &emm, &edd)) {
Packit 15f964
		GDate range_start;
Packit 15f964
Packit 15f964
		g_date_set_dmy (&range_start, sdd, smm + 1, syy);
Packit 15f964
Packit 15f964
		cal_shell_content->priv->view_start_range_day_offset =
Packit 15f964
			g_date_get_julian (&cal_shell_content->priv->view_start) - g_date_get_julian (&range_start);
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
e_cal_shell_content_change_view (ECalShellContent *cal_shell_content,
Packit 15f964
				 ECalViewKind to_view,
Packit 15f964
				 const GDate *view_start,
Packit 15f964
				 const GDate *view_end,
Packit 15f964
				 gboolean force_change)
Packit 15f964
{
Packit 15f964
	EShellSidebar *shell_sidebar;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	ECalendar *calendar;
Packit 15f964
	ECalModel *model;
Packit 15f964
	icaltimezone *zone;
Packit 15f964
	time_t view_start_tt, view_end_tt;
Packit 15f964
	gboolean view_changed = FALSE;
Packit 15f964
	gint selected_days;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (to_view >= E_CAL_VIEW_KIND_DAY && to_view < E_CAL_VIEW_KIND_LAST);
Packit 15f964
	g_return_if_fail (view_start != NULL);
Packit 15f964
	g_return_if_fail (g_date_valid (view_start));
Packit 15f964
	g_return_if_fail (view_end != NULL);
Packit 15f964
	g_return_if_fail (g_date_valid (view_end));
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
Packit 15f964
	g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
Packit 15f964
	calendar = e_cal_base_shell_sidebar_get_date_navigator (E_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR (calendar));
Packit 15f964
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	zone = e_cal_model_get_timezone (model);
Packit 15f964
	view_start_tt = cal_comp_gdate_to_timet (view_start, zone);
Packit 15f964
	view_end_tt = cal_comp_gdate_to_timet (view_end, zone);
Packit 15f964
Packit 15f964
	if (to_view != cal_shell_content->priv->current_view) {
Packit 15f964
		g_signal_handler_block (cal_shell_content, cal_shell_content->priv->current_view_id_changed_id);
Packit 15f964
		e_cal_shell_content_set_current_view_id (cal_shell_content, to_view);
Packit 15f964
		g_signal_handler_unblock (cal_shell_content, cal_shell_content->priv->current_view_id_changed_id);
Packit 15f964
		view_changed = TRUE;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	selected_days = g_date_get_julian (view_end) - g_date_get_julian (view_start) + 1;
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_DAY) {
Packit 15f964
		EDayView *day_view;
Packit 15f964
Packit 15f964
		day_view = E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_DAY]);
Packit 15f964
		e_day_view_set_days_shown (day_view, selected_days);
Packit 15f964
	} else if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_MONTH) {
Packit 15f964
		EWeekView *month_view;
Packit 15f964
Packit 15f964
		month_view = E_WEEK_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_MONTH]);
Packit 15f964
		e_week_view_set_weeks_shown (month_view, selected_days / 7);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (!force_change &&
Packit 15f964
	    g_date_valid (&cal_shell_content->priv->view_start) &&
Packit 15f964
	    g_date_valid (&cal_shell_content->priv->view_end) &&
Packit 15f964
	    g_date_compare (&cal_shell_content->priv->view_start, view_start) == 0 &&
Packit 15f964
	    g_date_compare (&cal_shell_content->priv->view_end, view_end) == 0) {
Packit 15f964
		ECalendarItem *calitem = e_calendar_get_item (calendar);
Packit 15f964
Packit 15f964
		if (view_changed)
Packit 15f964
			cal_shell_content_update_model_and_current_view_times (
Packit 15f964
				cal_shell_content, model, calitem, view_start_tt, view_end_tt, view_start, view_end);
Packit 15f964
Packit 15f964
		g_signal_handler_block (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
		g_signal_handler_block (calitem, cal_shell_content->priv->datepicker_selection_changed_id);
Packit 15f964
Packit 15f964
		e_calendar_item_set_selection (calitem, view_start, view_end);
Packit 15f964
Packit 15f964
		g_signal_handler_unblock (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
		g_signal_handler_unblock (calitem, cal_shell_content->priv->datepicker_selection_changed_id);
Packit 15f964
Packit 15f964
		return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	cal_shell_content->priv->view_start = *view_start;
Packit 15f964
	cal_shell_content->priv->view_end = *view_end;
Packit 15f964
Packit 15f964
	cal_shell_content_update_model_and_current_view_times (
Packit 15f964
		cal_shell_content, model, e_calendar_get_item (calendar), view_start_tt, view_end_tt, view_start, view_end);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_clamp_for_whole_weeks (GDateWeekday week_start_day,
Packit 15f964
					 GDate *sel_start,
Packit 15f964
					 GDate *sel_end,
Packit 15f964
					 gboolean saturday_as_sunday)
Packit 15f964
{
Packit 15f964
	GDateWeekday wday;
Packit 15f964
	guint32 julian_start, julian_end;
Packit 15f964
Packit 15f964
	g_return_if_fail (sel_start != NULL);
Packit 15f964
	g_return_if_fail (sel_end != NULL);
Packit 15f964
Packit 15f964
	wday = g_date_get_weekday (sel_start);
Packit 15f964
Packit 15f964
	/* This is because the month/week view doesn't split weekends */
Packit 15f964
	if (saturday_as_sunday && wday == G_DATE_SATURDAY && week_start_day == G_DATE_SUNDAY)
Packit 15f964
		wday = G_DATE_SUNDAY;
Packit 15f964
Packit 15f964
	if (week_start_day > wday) {
Packit 15f964
		g_date_subtract_days (sel_start, wday);
Packit 15f964
		wday = g_date_get_weekday (sel_start);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (week_start_day < wday)
Packit 15f964
		g_date_subtract_days (sel_start, wday - week_start_day);
Packit 15f964
Packit 15f964
	julian_start = g_date_get_julian (sel_start);
Packit 15f964
	julian_end = g_date_get_julian (sel_end);
Packit 15f964
Packit 15f964
	if (((julian_end - julian_start + 1) % 7) != 0)
Packit 15f964
		g_date_add_days (sel_end, 7 - ((julian_end - julian_start + 1) % 7));
Packit 15f964
Packit 15f964
	julian_end = g_date_get_julian (sel_end);
Packit 15f964
Packit 15f964
	/* Can show only up to 6 weeks */
Packit 15f964
	if ((julian_end - julian_start + 1) / 7 > 6) {
Packit 15f964
		*sel_end = *sel_start;
Packit 15f964
		g_date_add_days (sel_end, (7 * 6) - 1);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (g_date_compare (sel_start, sel_end) == 0)
Packit 15f964
		g_date_add_days (sel_end, 6);
Packit 15f964
}
Packit 15f964
Packit 15f964
static gboolean
Packit 15f964
cal_shell_content_weekday_within (GDateWeekday start_wday,
Packit 15f964
				  GDateWeekday end_wday,
Packit 15f964
				  GDateWeekday test_wday)
Packit 15f964
{
Packit 15f964
	gint ii;
Packit 15f964
Packit 15f964
	if (start_wday <= end_wday)
Packit 15f964
		return start_wday <= test_wday && test_wday <= end_wday;
Packit 15f964
Packit 15f964
	for (ii = 0; ii < 7; ii++) {
Packit 15f964
		if (start_wday == test_wday)
Packit 15f964
			return TRUE;
Packit 15f964
Packit 15f964
		if (start_wday == end_wday)
Packit 15f964
			break;
Packit 15f964
Packit 15f964
		start_wday = e_weekday_get_next (start_wday);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	return FALSE;
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_change_selection_in_current_view (ECalShellContent *cal_shell_content,
Packit 15f964
						    time_t sel_start_tt,
Packit 15f964
						    time_t sel_end_tt,
Packit 15f964
						    icaltimezone *zone)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->current_view >= E_CAL_VIEW_KIND_DAY &&
Packit 15f964
	    cal_shell_content->priv->current_view < E_CAL_VIEW_KIND_LAST) {
Packit 15f964
		ECalendarView *view;
Packit 15f964
Packit 15f964
		view = cal_shell_content->priv->views[cal_shell_content->priv->current_view];
Packit 15f964
Packit 15f964
		/* Preserve selected time (change only date) for these views */
Packit 15f964
		if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_DAY ||
Packit 15f964
		    cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WORKWEEK) {
Packit 15f964
			time_t current_sel_start = (time_t) -1, current_sel_end = (time_t) -1;
Packit 15f964
Packit 15f964
			if (e_calendar_view_get_selected_time_range (view, &current_sel_start, &current_sel_end)) {
Packit 15f964
				current_sel_start = icaltime_as_timet_with_zone (icaltime_from_timet_with_zone (current_sel_start, 0, zone), NULL);
Packit 15f964
				current_sel_end = icaltime_as_timet_with_zone (icaltime_from_timet_with_zone (current_sel_end, 0, zone), NULL);
Packit 15f964
Packit 15f964
				sel_start_tt += current_sel_start % (24 * 60 * 60);
Packit 15f964
				sel_end_tt += current_sel_end % (24 * 60 * 60);
Packit 15f964
			}
Packit 15f964
		}
Packit 15f964
Packit 15f964
		e_calendar_view_set_selected_time_range (view, sel_start_tt, sel_end_tt);
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_datepicker_selection_changed_cb (ECalendarItem *calitem,
Packit 15f964
						   ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	GDate sel_start, sel_end;
Packit 15f964
	guint32 selected_days, start_julian, end_julian;
Packit 15f964
	icaltimezone *zone;
Packit 15f964
	time_t sel_start_tt, sel_end_tt;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
Packit 15f964
Packit 15f964
	g_date_clear (&sel_start, 1);
Packit 15f964
	g_date_clear (&sel_end, 1);
Packit 15f964
Packit 15f964
	e_calendar_item_get_selection (calitem, &sel_start, &sel_end);
Packit 15f964
Packit 15f964
	start_julian = g_date_get_julian (&sel_start);
Packit 15f964
	end_julian = g_date_get_julian (&sel_end);
Packit 15f964
Packit 15f964
	g_return_if_fail (start_julian <= end_julian);
Packit 15f964
Packit 15f964
	if (g_date_compare (&cal_shell_content->priv->view_start, &sel_start) == 0 &&
Packit 15f964
	    g_date_compare (&cal_shell_content->priv->view_end, &sel_end) == 0) {
Packit 15f964
		/* No change in the selection range */
Packit 15f964
		return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	zone = e_cal_model_get_timezone (e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content)));
Packit 15f964
	sel_start_tt = cal_comp_gdate_to_timet (&sel_start, zone);
Packit 15f964
	sel_end_tt = cal_comp_gdate_to_timet (&sel_end, zone);
Packit 15f964
Packit 15f964
	selected_days = end_julian - start_julian + 1;
Packit 15f964
	if (selected_days == 1) {
Packit 15f964
		GDateWeekday sel_start_wday, sel_end_wday, cur_start_wday, cur_end_wday;
Packit 15f964
Packit 15f964
		/* Clicked inside currently selected view range; do not do anything,
Packit 15f964
		   just make sure the days are selected again */
Packit 15f964
		if (g_date_compare (&cal_shell_content->priv->view_start, &sel_start) <= 0 &&
Packit 15f964
		    g_date_compare (&sel_start, &cal_shell_content->priv->view_end) <= 0) {
Packit 15f964
			sel_start = cal_shell_content->priv->view_start;
Packit 15f964
			sel_end = cal_shell_content->priv->view_end;
Packit 15f964
Packit 15f964
			e_calendar_item_set_selection (calitem, &sel_start, &sel_end);
Packit 15f964
Packit 15f964
			cal_shell_content_change_selection_in_current_view (cal_shell_content, sel_start_tt, sel_end_tt, zone);
Packit 15f964
			return;
Packit 15f964
		}
Packit 15f964
Packit 15f964
		sel_start_wday = g_date_get_weekday (&sel_start);
Packit 15f964
		sel_end_wday = g_date_get_weekday (&sel_end);
Packit 15f964
		cur_start_wday = g_date_get_weekday (&cal_shell_content->priv->view_start);
Packit 15f964
		cur_end_wday = g_date_get_weekday (&cal_shell_content->priv->view_end);
Packit 15f964
Packit 15f964
		if ((cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WORKWEEK ||
Packit 15f964
		    (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_DAY &&
Packit 15f964
		    e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_DAY])) != 1)) &&
Packit 15f964
		    cal_shell_content_weekday_within (cur_start_wday, cur_end_wday, sel_start_wday)) {
Packit 15f964
			if (cur_start_wday < sel_start_wday) {
Packit 15f964
				g_date_subtract_days (&sel_start, sel_start_wday - cur_start_wday);
Packit 15f964
			} else if (cur_start_wday > sel_start_wday) {
Packit 15f964
				g_date_subtract_days (&sel_start, 7 - (cur_start_wday - sel_start_wday));
Packit 15f964
			}
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_DAY)
Packit 15f964
				g_date_add_days (&sel_end, e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_DAY])) - 1);
Packit 15f964
			else
Packit 15f964
				g_date_add_days (&sel_end, e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_WORKWEEK])) - 1);
Packit 15f964
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, cal_shell_content->priv->current_view, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WEEK &&
Packit 15f964
		    cal_shell_content_weekday_within (cur_start_wday, cur_end_wday, sel_start_wday) &&
Packit 15f964
		    cal_shell_content_weekday_within (cur_start_wday, cur_end_wday, sel_end_wday)) {
Packit 15f964
			if (cur_start_wday < sel_start_wday)
Packit 15f964
				g_date_subtract_days (&sel_start, sel_start_wday - cur_start_wday);
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (calitem->week_start_day, &sel_start, &sel_end, TRUE);
Packit 15f964
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_WEEK, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_MONTH ||
Packit 15f964
			   cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_LIST) {
Packit 15f964
			/* whole month */
Packit 15f964
			g_date_set_day (&sel_start, 1);
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			g_date_set_day (&sel_end, g_date_get_days_in_month (g_date_get_month (&sel_start), g_date_get_year (&sel_start)) - 1);
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (calitem->week_start_day, &sel_start, &sel_end, cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_MONTH);
Packit 15f964
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, cal_shell_content->priv->current_view, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WORKWEEK) {
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (calitem->week_start_day, &sel_start, &sel_end, TRUE);
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_WEEK, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else {
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_DAY, &sel_start, &sel_end, FALSE);
Packit 15f964
		}
Packit 15f964
Packit 15f964
		cal_shell_content_change_selection_in_current_view (cal_shell_content, sel_start_tt, sel_end_tt, zone);
Packit 15f964
	} else if (selected_days < 7) {
Packit 15f964
		GDateWeekday first_work_wday;
Packit 15f964
Packit 15f964
		first_work_wday = e_cal_model_get_work_day_first (e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content)));
Packit 15f964
Packit 15f964
		if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WORKWEEK &&
Packit 15f964
		    first_work_wday == g_date_get_weekday (&sel_start) &&
Packit 15f964
		    selected_days == e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_WORKWEEK])))
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_WORKWEEK, &sel_start, &sel_end, FALSE);
Packit 15f964
		else
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_DAY, &sel_start, &sel_end, FALSE);
Packit 15f964
	} else if (selected_days == 7) {
Packit 15f964
		GDateWeekday sel_start_wday;
Packit 15f964
Packit 15f964
		sel_start_wday = g_date_get_weekday (&sel_start);
Packit 15f964
Packit 15f964
		if (sel_start_wday == calitem->week_start_day &&
Packit 15f964
		    cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_DAY &&
Packit 15f964
		    e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_DAY])) == 7) {
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_DAY, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else {
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_WEEK, &sel_start, &sel_end, FALSE);
Packit 15f964
		}
Packit 15f964
	} else {
Packit 15f964
		if (cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_LIST) {
Packit 15f964
			/* whole month */
Packit 15f964
			g_date_set_day (&sel_start, 1);
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			g_date_set_day (&sel_end, g_date_get_days_in_month (g_date_get_month (&sel_start), g_date_get_year (&sel_start)));
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (calitem->week_start_day, &sel_start, &sel_end, FALSE);
Packit 15f964
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_LIST, &sel_start, &sel_end, FALSE);
Packit 15f964
		} else {
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (calitem->week_start_day, &sel_start, &sel_end,
Packit 15f964
				cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_MONTH || cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_WEEK);
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_MONTH, &sel_start, &sel_end, FALSE);
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_datepicker_range_moved_cb (ECalendarItem *calitem,
Packit 15f964
					     ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	gint start_year, start_month, start_day, end_year, end_month, end_day;
Packit 15f964
	GDate sel_start_date, sel_end_date, range_start_date;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	if (!e_calendar_item_get_date_range (calitem, &start_year, &start_month, &start_day, &end_year, &end_month, &end_day))
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	g_date_set_dmy (&range_start_date, start_day, start_month + 1, start_year);
Packit 15f964
Packit 15f964
	if (g_date_valid (&cal_shell_content->priv->last_range_start) &&
Packit 15f964
	    g_date_compare (&cal_shell_content->priv->last_range_start, &range_start_date) == 0) {
Packit 15f964
		return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	cal_shell_content->priv->last_range_start = range_start_date;
Packit 15f964
Packit 15f964
	g_date_clear (&sel_start_date, 1);
Packit 15f964
	g_date_clear (&sel_end_date, 1);
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->view_start_range_day_offset == (guint32) -1) {
Packit 15f964
		sel_start_date = cal_shell_content->priv->view_start;
Packit 15f964
		sel_end_date = cal_shell_content->priv->view_end;
Packit 15f964
		cal_shell_content->priv->view_start_range_day_offset =
Packit 15f964
			g_date_get_julian (&cal_shell_content->priv->view_start) - g_date_get_julian (&range_start_date);
Packit 15f964
	} else {
Packit 15f964
		gint view_days;
Packit 15f964
Packit 15f964
		view_days = g_date_get_julian (&cal_shell_content->priv->view_end) - g_date_get_julian (&cal_shell_content->priv->view_start);
Packit 15f964
Packit 15f964
		sel_start_date = range_start_date;
Packit 15f964
		g_date_add_days (&sel_start_date, cal_shell_content->priv->view_start_range_day_offset);
Packit 15f964
Packit 15f964
		sel_end_date = sel_start_date;
Packit 15f964
		g_date_add_days (&sel_end_date, view_days);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	g_signal_handler_block (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
Packit 15f964
	e_calendar_item_set_selection (calitem, &sel_start_date, &sel_end_date);
Packit 15f964
Packit 15f964
	g_signal_handler_unblock (calitem, cal_shell_content->priv->datepicker_range_moved_id);
Packit 15f964
}
Packit 15f964
Packit 15f964
static gboolean
Packit 15f964
cal_shell_content_datepicker_button_press_cb (ECalendar *calendar,
Packit 15f964
					      GdkEvent *event,
Packit 15f964
					      ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), FALSE);
Packit 15f964
Packit 15f964
	if (!event)
Packit 15f964
		return FALSE;
Packit 15f964
Packit 15f964
	if (event->type == GDK_2BUTTON_PRESS) {
Packit 15f964
		ECalendarItem *calitem = e_calendar_get_item (calendar);
Packit 15f964
		GDate sel_start, sel_end;
Packit 15f964
Packit 15f964
		g_date_clear (&sel_start, 1);
Packit 15f964
		g_date_clear (&sel_end, 1);
Packit 15f964
Packit 15f964
		e_calendar_item_get_selection (calitem, &sel_start, &sel_end);
Packit 15f964
Packit 15f964
		/* Switch to a day view on a double-click */
Packit 15f964
		e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_DAY, &sel_start, &sel_start, FALSE);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	return FALSE;
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_current_view_id_changed_cb (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	GDate sel_start, sel_end;
Packit 15f964
	GDateWeekday work_day_first, week_start_day;
Packit 15f964
	ECalModel *model;
Packit 15f964
	gint ii;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	work_day_first = e_cal_model_get_work_day_first (model);
Packit 15f964
	week_start_day = e_cal_model_get_week_start_day (model);
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->previous_selected_start_time != -1 &&
Packit 15f964
	    cal_shell_content->priv->previous_selected_end_time != -1) {
Packit 15f964
		icaltimezone *zone;
Packit 15f964
Packit 15f964
		zone = e_cal_model_get_timezone (model);
Packit 15f964
		time_to_gdate_with_zone (&sel_start, cal_shell_content->priv->previous_selected_start_time, zone);
Packit 15f964
		time_to_gdate_with_zone (&sel_end, cal_shell_content->priv->previous_selected_end_time, zone);
Packit 15f964
	} else {
Packit 15f964
		sel_start = cal_shell_content->priv->view_start;
Packit 15f964
		sel_end = cal_shell_content->priv->view_end;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	switch (cal_shell_content->priv->current_view) {
Packit 15f964
		case E_CAL_VIEW_KIND_DAY:
Packit 15f964
			/* Left the start & end being the current view start */
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_WORKWEEK:
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (week_start_day, &sel_start, &sel_end, FALSE);
Packit 15f964
			ii = 0;
Packit 15f964
			while (g_date_get_weekday (&sel_start) != work_day_first && ii < 7) {
Packit 15f964
				g_date_add_days (&sel_start, 1);
Packit 15f964
				ii++;
Packit 15f964
			}
Packit 15f964
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			g_date_add_days (&sel_end, e_day_view_get_days_shown (E_DAY_VIEW (cal_shell_content->priv->views[E_CAL_VIEW_KIND_WORKWEEK])) - 1);
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_WEEK:
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (week_start_day, &sel_start, &sel_end, TRUE);
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_MONTH:
Packit 15f964
		case E_CAL_VIEW_KIND_LIST:
Packit 15f964
			if (g_date_get_day (&sel_start) != 1 &&
Packit 15f964
			    (g_date_get_julian (&sel_end) - g_date_get_julian (&sel_start) + 1) / 7 >= 3 &&
Packit 15f964
			    g_date_get_month (&sel_start) != g_date_get_month (&sel_end)) {
Packit 15f964
				g_date_set_day (&sel_start, 1);
Packit 15f964
				g_date_add_months (&sel_start, 1);
Packit 15f964
			} else {
Packit 15f964
				g_date_set_day (&sel_start, 1);
Packit 15f964
			}
Packit 15f964
			sel_end = sel_start;
Packit 15f964
			g_date_add_months (&sel_end, 1);
Packit 15f964
			g_date_subtract_days (&sel_end, 1);
Packit 15f964
			cal_shell_content_clamp_for_whole_weeks (week_start_day, &sel_start, &sel_end, cal_shell_content->priv->current_view == E_CAL_VIEW_KIND_MONTH);
Packit 15f964
			break;
Packit 15f964
		default:
Packit 15f964
			g_warn_if_reached ();
Packit 15f964
			return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	/* Ensure a change */
Packit 15f964
	e_cal_shell_content_change_view (cal_shell_content, cal_shell_content->priv->current_view, &sel_start, &sel_end, TRUE);
Packit 15f964
Packit 15f964
	/* Try to preserve selection between the views */
Packit 15f964
	if (cal_shell_content->priv->previous_selected_start_time != -1 &&
Packit 15f964
	    cal_shell_content->priv->previous_selected_end_time != -1) {
Packit 15f964
		if (cal_shell_content->priv->current_view >= E_CAL_VIEW_KIND_DAY &&
Packit 15f964
		    cal_shell_content->priv->current_view < E_CAL_VIEW_KIND_LAST) {
Packit 15f964
			ECalendarView *cal_view = cal_shell_content->priv->views[cal_shell_content->priv->current_view];
Packit 15f964
Packit 15f964
			e_calendar_view_set_selected_time_range (cal_view,
Packit 15f964
				cal_shell_content->priv->previous_selected_start_time,
Packit 15f964
				cal_shell_content->priv->previous_selected_end_time);
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
Packit 15f964
	cal_shell_content->priv->previous_selected_start_time = -1;
Packit 15f964
	cal_shell_content->priv->previous_selected_end_time = -1;
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_display_view_cb (ECalShellContent *cal_shell_content,
Packit 15f964
                                   GalView *gal_view)
Packit 15f964
{
Packit 15f964
	ECalViewKind view_kind;
Packit 15f964
	GType gal_view_type;
Packit 15f964
Packit 15f964
	gal_view_type = G_OBJECT_TYPE (gal_view);
Packit 15f964
Packit 15f964
	if (gal_view_type == GAL_TYPE_VIEW_ETABLE) {
Packit 15f964
		ECalendarView *calendar_view;
Packit 15f964
Packit 15f964
		view_kind = E_CAL_VIEW_KIND_LIST;
Packit 15f964
		calendar_view = cal_shell_content->priv->views[view_kind];
Packit 15f964
		gal_view_etable_attach_table (
Packit 15f964
			GAL_VIEW_ETABLE (gal_view),
Packit 15f964
			E_CAL_LIST_VIEW (calendar_view)->table);
Packit 15f964
Packit 15f964
	} else if (gal_view_type == GAL_TYPE_VIEW_CALENDAR_DAY) {
Packit 15f964
		view_kind = E_CAL_VIEW_KIND_DAY;
Packit 15f964
Packit 15f964
	} else if (gal_view_type == GAL_TYPE_VIEW_CALENDAR_WORK_WEEK) {
Packit 15f964
		view_kind = E_CAL_VIEW_KIND_WORKWEEK;
Packit 15f964
Packit 15f964
	} else if (gal_view_type == GAL_TYPE_VIEW_CALENDAR_WEEK) {
Packit 15f964
		view_kind = E_CAL_VIEW_KIND_WEEK;
Packit 15f964
Packit 15f964
	} else if (gal_view_type == GAL_TYPE_VIEW_CALENDAR_MONTH) {
Packit 15f964
		view_kind = E_CAL_VIEW_KIND_MONTH;
Packit 15f964
Packit 15f964
	} else {
Packit 15f964
		g_return_if_reached ();
Packit 15f964
	}
Packit 15f964
Packit 15f964
	e_cal_shell_content_set_current_view_id (cal_shell_content, view_kind);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_notify_view_id_cb (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	EShellContent *shell_content;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	GSettings *settings;
Packit 15f964
	GtkWidget *paned;
Packit 15f964
	const gchar *key;
Packit 15f964
	const gchar *view_id;
Packit 15f964
Packit 15f964
	settings = e_util_ref_settings ("org.gnome.evolution.calendar");
Packit 15f964
	paned = cal_shell_content->priv->hpaned;
Packit 15f964
Packit 15f964
	shell_content = E_SHELL_CONTENT (cal_shell_content);
Packit 15f964
	shell_view = e_shell_content_get_shell_view (shell_content);
Packit 15f964
	view_id = e_shell_view_get_view_id (shell_view);
Packit 15f964
Packit 15f964
	if (view_id != NULL && strcmp (view_id, "Month_View") == 0)
Packit 15f964
		key = "month-hpane-position";
Packit 15f964
	else
Packit 15f964
		key = "hpane-position";
Packit 15f964
Packit 15f964
	g_settings_unbind (paned, "hposition");
Packit 15f964
Packit 15f964
	g_settings_bind (
Packit 15f964
		settings, key,
Packit 15f964
		paned, "hposition",
Packit 15f964
		G_SETTINGS_BIND_DEFAULT);
Packit 15f964
Packit 15f964
	g_object_unref (settings);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_is_editing_changed_cb (gpointer cal_view_tasks_memos_table,
Packit 15f964
                                         GParamSpec *param,
Packit 15f964
                                         EShellView *shell_view)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
Packit 15f964
Packit 15f964
	e_shell_view_update_actions (shell_view);
Packit 15f964
}
Packit 15f964
Packit 15f964
static gchar *
Packit 15f964
cal_shell_content_get_pad_state_filename (EShellContent *shell_content,
Packit 15f964
                                          ETable *table)
Packit 15f964
{
Packit 15f964
	EShellBackend *shell_backend;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	const gchar *config_dir, *nick = NULL;
Packit 15f964
Packit 15f964
	g_return_val_if_fail (shell_content != NULL, NULL);
Packit 15f964
	g_return_val_if_fail (E_IS_SHELL_CONTENT (shell_content), NULL);
Packit 15f964
	g_return_val_if_fail (table != NULL, NULL);
Packit 15f964
	g_return_val_if_fail (E_IS_TABLE (table), NULL);
Packit 15f964
Packit 15f964
	if (E_IS_TASK_TABLE (table))
Packit 15f964
		nick = "TaskPad";
Packit 15f964
	else if (E_IS_MEMO_TABLE (table))
Packit 15f964
		nick = "MemoPad";
Packit 15f964
Packit 15f964
	g_return_val_if_fail (nick != NULL, NULL);
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (shell_content);
Packit 15f964
	shell_backend = e_shell_view_get_shell_backend (shell_view);
Packit 15f964
	config_dir = e_shell_backend_get_config_dir (shell_backend);
Packit 15f964
Packit 15f964
	return g_build_filename (config_dir, nick, NULL);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_save_table_state (EShellContent *shell_content,
Packit 15f964
                                    ETable *table)
Packit 15f964
{
Packit 15f964
	gchar *filename;
Packit 15f964
Packit 15f964
	filename = cal_shell_content_get_pad_state_filename (
Packit 15f964
		shell_content, table);
Packit 15f964
	g_return_if_fail (filename != NULL);
Packit 15f964
Packit 15f964
	e_table_save_state (table, filename);
Packit 15f964
	g_free (filename);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_load_table_state (EShellContent *shell_content,
Packit 15f964
                                    ETable *table)
Packit 15f964
{
Packit 15f964
	gchar *filename;
Packit 15f964
Packit 15f964
	filename = cal_shell_content_get_pad_state_filename (shell_content, table);
Packit 15f964
	g_return_if_fail (filename != NULL);
Packit 15f964
Packit 15f964
	e_table_load_state (table, filename);
Packit 15f964
	g_free (filename);
Packit 15f964
}
Packit 15f964
Packit 15f964
static icalproperty *
Packit 15f964
cal_shell_content_get_attendee_prop (icalcomponent *icalcomp,
Packit 15f964
                                     const gchar *address)
Packit 15f964
{
Packit 15f964
	icalproperty *prop;
Packit 15f964
Packit 15f964
	if (address == NULL || *address == '\0')
Packit 15f964
		return NULL;
Packit 15f964
Packit 15f964
	prop = icalcomponent_get_first_property (
Packit 15f964
		icalcomp, ICAL_ATTENDEE_PROPERTY);
Packit 15f964
Packit 15f964
	while (prop != NULL) {
Packit 15f964
		const gchar *attendee;
Packit 15f964
Packit Service d11a94
		attendee = icalproperty_get_attendee (prop);
Packit 15f964
Packit Service d11a94
		if (g_str_equal (itip_strip_mailto (attendee), address))
Packit 15f964
			return prop;
Packit 15f964
Packit 15f964
		prop = icalcomponent_get_next_property (
Packit 15f964
			icalcomp, ICAL_ATTENDEE_PROPERTY);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	return NULL;
Packit 15f964
}
Packit 15f964
Packit 15f964
static gboolean
Packit 15f964
cal_shell_content_icalcomp_is_delegated (icalcomponent *icalcomp,
Packit 15f964
                                         const gchar *user_email)
Packit 15f964
{
Packit 15f964
	icalproperty *prop;
Packit 15f964
	icalparameter *param;
Packit 15f964
	const gchar *delto = NULL;
Packit 15f964
	gboolean is_delegated = FALSE;
Packit 15f964
Packit 15f964
	prop = cal_shell_content_get_attendee_prop (icalcomp, user_email);
Packit 15f964
Packit 15f964
	if (prop != NULL) {
Packit 15f964
		param = icalproperty_get_first_parameter (
Packit 15f964
			prop, ICAL_DELEGATEDTO_PARAMETER);
Packit 15f964
		if (param != NULL) {
Packit 15f964
			delto = icalparameter_get_delegatedto (param);
Packit 15f964
			delto = itip_strip_mailto (delto);
Packit 15f964
		}
Packit 15f964
	} else
Packit 15f964
		return FALSE;
Packit 15f964
Packit 15f964
	prop = cal_shell_content_get_attendee_prop (icalcomp, delto);
Packit 15f964
Packit 15f964
	if (prop != NULL) {
Packit 15f964
		const gchar *delfrom = NULL;
Packit 15f964
		icalparameter_partstat status = ICAL_PARTSTAT_NONE;
Packit 15f964
Packit 15f964
		param = icalproperty_get_first_parameter (
Packit 15f964
			prop, ICAL_DELEGATEDFROM_PARAMETER);
Packit 15f964
		if (param != NULL) {
Packit 15f964
			delfrom = icalparameter_get_delegatedfrom (param);
Packit 15f964
			delfrom = itip_strip_mailto (delfrom);
Packit 15f964
		}
Packit 15f964
		param = icalproperty_get_first_parameter (
Packit 15f964
			prop, ICAL_PARTSTAT_PARAMETER);
Packit 15f964
		if (param != NULL)
Packit 15f964
			status = icalparameter_get_partstat (param);
Packit 15f964
		is_delegated =
Packit 15f964
			(status != ICAL_PARTSTAT_DECLINED) &&
Packit 15f964
			(g_strcmp0 (delfrom, user_email) == 0);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	return is_delegated;
Packit 15f964
}
Packit 15f964
Packit 15f964
static guint32
Packit 15f964
cal_shell_content_check_state (EShellContent *shell_content)
Packit 15f964
{
Packit 15f964
	EShell *shell;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	EShellBackend *shell_backend;
Packit 15f964
	ESourceRegistry *registry;
Packit 15f964
	ECalShellContent *cal_shell_content;
Packit 15f964
	ECalendarView *calendar_view;
Packit 15f964
	gboolean selection_is_editable = FALSE;
Packit 15f964
	gboolean selection_is_instance = FALSE;
Packit 15f964
	gboolean selection_is_meeting = FALSE;
Packit 15f964
	gboolean selection_is_organizer = FALSE;
Packit 15f964
	gboolean selection_is_recurring = FALSE;
Packit 15f964
	gboolean selection_can_delegate = FALSE;
Packit 15f964
	guint32 state = 0;
Packit 15f964
	GList *selected;
Packit 15f964
	GList *link;
Packit 15f964
	guint n_selected;
Packit 15f964
Packit 15f964
	cal_shell_content = E_CAL_SHELL_CONTENT (shell_content);
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (shell_content);
Packit 15f964
	shell_backend = e_shell_view_get_shell_backend (shell_view);
Packit 15f964
	shell = e_shell_backend_get_shell (shell_backend);
Packit 15f964
	registry = e_shell_get_registry (shell);
Packit 15f964
Packit 15f964
	calendar_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
Packit 15f964
Packit 15f964
	selected = e_calendar_view_get_selected_events (calendar_view);
Packit 15f964
	n_selected = g_list_length (selected);
Packit 15f964
Packit 15f964
	/* If we have a selection, assume it's
Packit 15f964
	 * editable until we learn otherwise. */
Packit 15f964
	if (n_selected > 0)
Packit 15f964
		selection_is_editable = TRUE;
Packit 15f964
Packit 15f964
	for (link = selected; link != NULL; link = g_list_next (link)) {
Packit 15f964
		ECalendarViewEvent *event = link->data;
Packit 15f964
		ECalClient *client;
Packit 15f964
		ECalComponent *comp;
Packit 15f964
		gchar *user_email;
Packit 15f964
		icalcomponent *icalcomp;
Packit 15f964
		const gchar *capability;
Packit 15f964
		gboolean cap_delegate_supported;
Packit 15f964
		gboolean cap_delegate_to_many;
Packit 15f964
		gboolean icalcomp_is_delegated;
Packit 15f964
		gboolean read_only;
Packit 15f964
Packit 15f964
		if (!is_comp_data_valid (event))
Packit 15f964
			continue;
Packit 15f964
Packit 15f964
		client = event->comp_data->client;
Packit 15f964
		icalcomp = event->comp_data->icalcomp;
Packit 15f964
Packit 15f964
		read_only = e_client_is_readonly (E_CLIENT (client));
Packit 15f964
		selection_is_editable &= !read_only;
Packit 15f964
Packit 15f964
		selection_is_instance |=
Packit 15f964
			e_cal_util_component_is_instance (icalcomp);
Packit 15f964
Packit 15f964
		selection_is_meeting =
Packit 15f964
			(n_selected == 1) &&
Packit 15f964
			e_cal_util_component_has_attendee (icalcomp);
Packit 15f964
Packit 15f964
		selection_is_recurring |=
Packit 15f964
			e_cal_util_component_is_instance (icalcomp) ||
Packit 15f964
			e_cal_util_component_has_recurrences (icalcomp);
Packit 15f964
Packit 15f964
		/* XXX The rest of this is rather expensive and
Packit 15f964
		 *     only applies if a single event is selected,
Packit 15f964
		 *     so continue with the loop iteration if the
Packit 15f964
		 *     rest of this is not applicable. */
Packit 15f964
		if (n_selected > 1)
Packit 15f964
			continue;
Packit 15f964
Packit 15f964
		/* XXX This probably belongs in comp-util.c. */
Packit 15f964
Packit 15f964
		comp = e_cal_component_new ();
Packit 15f964
		e_cal_component_set_icalcomponent (
Packit 15f964
			comp, icalcomponent_new_clone (icalcomp));
Packit 15f964
		user_email = itip_get_comp_attendee (
Packit 15f964
			registry, comp, client);
Packit 15f964
Packit 15f964
		selection_is_organizer =
Packit 15f964
			e_cal_util_component_has_organizer (icalcomp) &&
Packit 15f964
			itip_organizer_is_user (registry, comp, client);
Packit 15f964
Packit 15f964
		capability = CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED;
Packit 15f964
		cap_delegate_supported =
Packit 15f964
			e_client_check_capability (
Packit 15f964
			E_CLIENT (client), capability);
Packit 15f964
Packit 15f964
		capability = CAL_STATIC_CAPABILITY_DELEGATE_TO_MANY;
Packit 15f964
		cap_delegate_to_many =
Packit 15f964
			e_client_check_capability (
Packit 15f964
			E_CLIENT (client), capability);
Packit 15f964
Packit 15f964
		icalcomp_is_delegated =
Packit 15f964
			(user_email != NULL) &&
Packit 15f964
			cal_shell_content_icalcomp_is_delegated (
Packit 15f964
			icalcomp, user_email);
Packit 15f964
Packit 15f964
		selection_can_delegate =
Packit 15f964
			cap_delegate_supported &&
Packit 15f964
			(cap_delegate_to_many ||
Packit 15f964
			(!selection_is_organizer &&
Packit 15f964
			 !icalcomp_is_delegated));
Packit 15f964
Packit 15f964
		g_free (user_email);
Packit 15f964
		g_object_unref (comp);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	g_list_free (selected);
Packit 15f964
Packit 15f964
	if (n_selected == 1)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_SINGLE;
Packit 15f964
	if (n_selected > 1)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_MULTIPLE;
Packit 15f964
	if (selection_is_editable)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_EDITABLE;
Packit 15f964
	if (selection_is_instance)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_INSTANCE;
Packit 15f964
	if (selection_is_meeting)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_MEETING;
Packit 15f964
	if (selection_is_organizer)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_ORGANIZER;
Packit 15f964
	if (selection_is_recurring)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_IS_RECURRING;
Packit 15f964
	if (selection_can_delegate)
Packit 15f964
		state |= E_CAL_BASE_SHELL_CONTENT_SELECTION_CAN_DELEGATE;
Packit 15f964
Packit 15f964
	return state;
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_focus_search_results (EShellContent *shell_content)
Packit 15f964
{
Packit 15f964
	ECalendarView *calendar_view;
Packit 15f964
Packit 15f964
	calendar_view = e_cal_shell_content_get_current_calendar_view (E_CAL_SHELL_CONTENT (shell_content));
Packit 15f964
Packit 15f964
	gtk_widget_grab_focus (GTK_WIDGET (calendar_view));
Packit 15f964
}
Packit 15f964
Packit 15f964
static time_t
Packit 15f964
cal_shell_content_get_default_time (ECalModel *model,
Packit 15f964
				    gpointer user_data)
Packit 15f964
{
Packit 15f964
	ECalShellContent *cal_shell_content = user_data;
Packit 15f964
	icaltimezone *zone;
Packit 15f964
Packit 15f964
	g_return_val_if_fail (model != NULL, 0);
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), 0);
Packit 15f964
Packit 15f964
	if (e_cal_shell_content_get_current_view_id (cal_shell_content) != E_CAL_VIEW_KIND_LIST) {
Packit 15f964
		ECalendarView *cal_view;
Packit 15f964
		time_t selected_start = (time_t) 0, selected_end = (time_t) 0;
Packit 15f964
Packit 15f964
		cal_view = e_cal_shell_content_get_current_calendar_view (cal_shell_content);
Packit 15f964
Packit 15f964
		if (cal_view && e_calendar_view_get_selected_time_range (cal_view, &selected_start, &selected_end))
Packit 15f964
			return selected_start;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	zone = e_cal_model_get_timezone (model);
Packit 15f964
Packit 15f964
	return icaltime_as_timet_with_zone (icaltime_current_time_with_zone (zone), zone);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
update_adjustment (ECalShellContent *cal_shell_content,
Packit 15f964
                   GtkAdjustment *adjustment,
Packit 15f964
                   EWeekView *week_view,
Packit 15f964
		   gboolean move_by_week)
Packit 15f964
{
Packit 15f964
	GDate start_date, end_date;
Packit 15f964
	GDate first_day_shown;
Packit 15f964
	ECalModel *model;
Packit 15f964
	gint week_offset;
Packit 15f964
	struct icaltimetype start_tt = icaltime_null_time ();
Packit 15f964
	time_t lower;
Packit 15f964
	guint32 old_first_day_julian, new_first_day_julian;
Packit 15f964
	icaltimezone *timezone;
Packit 15f964
	gdouble value;
Packit 15f964
Packit 15f964
	e_week_view_get_first_day_shown (week_view, &first_day_shown);
Packit 15f964
Packit 15f964
	/* If we don't have a valid date set yet, just return. */
Packit 15f964
	if (!g_date_valid (&first_day_shown))
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	value = gtk_adjustment_get_value (adjustment);
Packit 15f964
Packit 15f964
	/* Determine the first date shown. */
Packit 15f964
	start_date = week_view->base_date;
Packit 15f964
	week_offset = floor (value + 0.5);
Packit 15f964
	g_date_add_days (&start_date, week_offset * 7);
Packit 15f964
Packit 15f964
	/* Convert the old & new first days shown to julian values. */
Packit 15f964
	old_first_day_julian = g_date_get_julian (&first_day_shown);
Packit 15f964
	new_first_day_julian = g_date_get_julian (&start_date);
Packit 15f964
Packit 15f964
	/* If we are already showing the date, just return. */
Packit 15f964
	if (old_first_day_julian == new_first_day_julian)
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	/* Convert it to a time_t. */
Packit 15f964
	start_tt.year = g_date_get_year (&start_date);
Packit 15f964
	start_tt.month = g_date_get_month (&start_date);
Packit 15f964
	start_tt.day = g_date_get_day (&start_date);
Packit 15f964
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	timezone = e_cal_model_get_timezone (model);
Packit 15f964
	lower = icaltime_as_timet_with_zone (start_tt, timezone);
Packit 15f964
Packit 15f964
	end_date = start_date;
Packit 15f964
	if (move_by_week) {
Packit 15f964
		g_date_add_days (&end_date, 7 - 1);
Packit 15f964
	} else {
Packit 15f964
		g_date_add_days (&end_date, 7 * e_week_view_get_weeks_shown (week_view) - 1);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	e_week_view_set_update_base_date (week_view, FALSE);
Packit 15f964
	e_cal_shell_content_change_view (cal_shell_content, cal_shell_content->priv->current_view, &start_date, &end_date, FALSE);
Packit 15f964
	e_calendar_view_set_selected_time_range (E_CALENDAR_VIEW (week_view), lower, lower);
Packit 15f964
	e_week_view_set_update_base_date (week_view, TRUE);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
week_view_adjustment_changed_cb (GtkAdjustment *adjustment,
Packit 15f964
				 ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	ECalendarView *view;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	view = cal_shell_content->priv->views[E_CAL_VIEW_KIND_WEEK];
Packit 15f964
	update_adjustment (cal_shell_content, adjustment, E_WEEK_VIEW (view), TRUE);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
month_view_adjustment_changed_cb (GtkAdjustment *adjustment,
Packit 15f964
				  ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	ECalendarView *view;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	view = cal_shell_content->priv->views[E_CAL_VIEW_KIND_MONTH];
Packit 15f964
	update_adjustment (cal_shell_content, adjustment, E_WEEK_VIEW (view), FALSE);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_notify_work_day_cb (ECalModel *model,
Packit 15f964
				      GParamSpec *param,
Packit 15f964
				      ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	GDateWeekday work_day_first, work_day_last;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->current_view != E_CAL_VIEW_KIND_WORKWEEK)
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	work_day_first = e_cal_model_get_work_day_first (model);
Packit 15f964
	work_day_last = e_cal_model_get_work_day_last (model);
Packit 15f964
Packit 15f964
	if (work_day_first == g_date_get_weekday (&cal_shell_content->priv->view_start) &&
Packit 15f964
	    work_day_last == g_date_get_weekday (&cal_shell_content->priv->view_end))
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	cal_shell_content->priv->previous_selected_start_time = -1;
Packit 15f964
	cal_shell_content->priv->previous_selected_end_time = -1;
Packit 15f964
Packit 15f964
	/* This makes sure that the selection in the datepicker corresponds
Packit 15f964
	   to the time range used in the Work Week view */
Packit 15f964
	cal_shell_content_current_view_id_changed_cb (cal_shell_content);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_notify_week_start_day_cb (ECalModel *model,
Packit 15f964
					    GParamSpec *param,
Packit 15f964
					    ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	cal_shell_content->priv->previous_selected_start_time = -1;
Packit 15f964
	cal_shell_content->priv->previous_selected_end_time = -1;
Packit 15f964
Packit 15f964
	/* This makes sure that the selection in the datepicker corresponds
Packit 15f964
	   to the time range used in the current view */
Packit 15f964
	cal_shell_content_current_view_id_changed_cb (cal_shell_content);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_move_view_range_cb (ECalendarView *cal_view,
Packit 15f964
				      ECalendarViewMoveType move_type,
Packit 15f964
				      gint64 exact_date,
Packit 15f964
				      ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	if (!cal_view->in_focus)
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	e_cal_shell_content_move_view_range (cal_shell_content, move_type, (time_t) exact_date);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_foreign_client_opened_cb (ECalBaseShellSidebar *cal_base_shell_sidebar,
Packit 15f964
					    ECalClient *client,
Packit 15f964
					    ECalModel *model)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_CAL_CLIENT (client));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
Packit 15f964
	e_cal_data_model_add_client (e_cal_model_get_data_model (model), client);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_foreign_client_closed_cb (ECalBaseShellSidebar *cal_base_shell_sidebar,
Packit 15f964
					    ESource *source,
Packit 15f964
					    ECalModel *model)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_SOURCE (source));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
Packit 15f964
	e_cal_data_model_remove_client (e_cal_model_get_data_model (model), e_source_get_uid (source));
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_setup_foreign_sources (EShellWindow *shell_window,
Packit 15f964
					 const gchar *view_name,
Packit 15f964
					 const gchar *extension_name,
Packit 15f964
					 ECalModel *model)
Packit 15f964
{
Packit 15f964
	EShellSidebar *foreign_sidebar;
Packit 15f964
	EShellContent *foreign_content;
Packit 15f964
	EShellView *foreign_view;
Packit 15f964
	ECalModel *foreign_model;
Packit 15f964
	gboolean is_new_view;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_SHELL_WINDOW (shell_window));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
Packit 15f964
	is_new_view = e_shell_window_peek_shell_view (shell_window, view_name) == NULL;
Packit 15f964
Packit 15f964
	foreign_view = e_shell_window_get_shell_view (shell_window, view_name);
Packit 15f964
	g_return_if_fail (E_IS_SHELL_VIEW (foreign_view));
Packit 15f964
Packit 15f964
	foreign_sidebar = e_shell_view_get_shell_sidebar (foreign_view);
Packit 15f964
	g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (foreign_sidebar));
Packit 15f964
Packit 15f964
	if (is_new_view) {
Packit 15f964
		/* Preselect default source, when the view was not created yet */
Packit 15f964
		ESourceSelector *source_selector;
Packit 15f964
		ESourceRegistry *registry;
Packit 15f964
		ESource *source;
Packit 15f964
Packit 15f964
		source_selector = e_cal_base_shell_sidebar_get_selector (E_CAL_BASE_SHELL_SIDEBAR (foreign_sidebar));
Packit 15f964
		registry = e_source_selector_get_registry (source_selector);
Packit 15f964
		source = e_source_registry_ref_default_for_extension_name (registry, extension_name);
Packit 15f964
Packit 15f964
		if (source)
Packit 15f964
			e_source_selector_set_primary_selection (source_selector, source);
Packit 15f964
Packit 15f964
		g_clear_object (&source);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	g_signal_connect_object (foreign_sidebar, "client-opened",
Packit 15f964
		G_CALLBACK (cal_shell_content_foreign_client_opened_cb), model, 0);
Packit 15f964
	g_signal_connect_object (foreign_sidebar, "client-closed",
Packit 15f964
		G_CALLBACK (cal_shell_content_foreign_client_closed_cb), model, 0);
Packit 15f964
Packit 15f964
	foreign_content = e_shell_view_get_shell_content (foreign_view);
Packit 15f964
	foreign_model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (foreign_content));
Packit 15f964
Packit 15f964
	e_binding_bind_property (
Packit 15f964
		foreign_model, "default-source-uid",
Packit 15f964
		model, "default-source-uid",
Packit 15f964
		G_BINDING_SYNC_CREATE);
Packit 15f964
Packit 15f964
	g_signal_connect_object (model, "row-appended",
Packit 15f964
		G_CALLBACK (e_cal_base_shell_view_model_row_appended), foreign_view, G_CONNECT_SWAPPED);
Packit 15f964
Packit 15f964
	/* This makes sure that the local models for memos and tasks
Packit 15f964
	   in the calendar view get populated with the same sources
Packit 15f964
	   as those in the respective views. */
Packit 15f964
Packit 15f964
	e_cal_base_shell_sidebar_ensure_sources_open (E_CAL_BASE_SHELL_SIDEBAR (foreign_sidebar));
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_view_created (ECalBaseShellContent *cal_base_shell_content)
Packit 15f964
{
Packit 15f964
	ECalShellContent *cal_shell_content;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	EShellWindow *shell_window;
Packit 15f964
	EShellSidebar *shell_sidebar;
Packit 15f964
	GalViewInstance *view_instance;
Packit 15f964
	ECalendar *calendar;
Packit 15f964
	ECalModel *model;
Packit 15f964
	ECalDataModel *data_model;
Packit 15f964
	GDate date;
Packit 15f964
	time_t today;
Packit 15f964
Packit 15f964
	cal_shell_content = E_CAL_SHELL_CONTENT (cal_base_shell_content);
Packit 15f964
	cal_shell_content->priv->current_view = E_CAL_VIEW_KIND_DAY;
Packit 15f964
Packit 15f964
	today = time (NULL);
Packit 15f964
	g_date_clear (&date, 1);
Packit 15f964
	g_date_set_time_t (&date, today);
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	shell_window = e_shell_view_get_shell_window (shell_view);
Packit 15f964
	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
Packit 15f964
	g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
Packit 15f964
	calendar = e_cal_base_shell_sidebar_get_date_navigator (E_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR (calendar));
Packit 15f964
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	e_calendar_item_set_selection (e_calendar_get_item (calendar), &date, &date);
Packit 15f964
	e_cal_model_set_time_range (model, today, today);
Packit 15f964
Packit 15f964
	/* Show everything known by default in the task and memo pads */
Packit 15f964
	e_cal_model_set_time_range (cal_shell_content->priv->memo_model, 0, 0);
Packit 15f964
	e_cal_model_set_time_range (cal_shell_content->priv->task_model, 0, 0);
Packit 15f964
Packit 15f964
	cal_shell_content->priv->datepicker_selection_changed_id =
Packit 15f964
		g_signal_connect (e_calendar_get_item (calendar), "selection-changed",
Packit 15f964
		G_CALLBACK (cal_shell_content_datepicker_selection_changed_cb), cal_shell_content);
Packit 15f964
	cal_shell_content->priv->datepicker_range_moved_id =
Packit 15f964
		g_signal_connect (e_calendar_get_item (calendar), "date-range-moved",
Packit 15f964
		G_CALLBACK (cal_shell_content_datepicker_range_moved_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	g_signal_connect_after (calendar, "button-press-event",
Packit 15f964
		G_CALLBACK (cal_shell_content_datepicker_button_press_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	cal_shell_content->priv->tag_calendar = e_tag_calendar_new (calendar);
Packit 15f964
	e_tag_calendar_subscribe (cal_shell_content->priv->tag_calendar, data_model);
Packit 15f964
Packit 15f964
	/* Intentionally not using e_signal_connect_notify() here, no need to filter
Packit 15f964
	   out "false" notifications, it's dealt with them in another way */
Packit 15f964
	cal_shell_content->priv->current_view_id_changed_id = g_signal_connect (
Packit 15f964
		cal_shell_content, "notify::current-view-id",
Packit 15f964
		G_CALLBACK (cal_shell_content_current_view_id_changed_cb), NULL);
Packit 15f964
Packit 15f964
	/* List of selected Task/Memo sources is taken from respective views,
Packit 15f964
	   which are loaded if necessary. */
Packit 15f964
	cal_shell_content_setup_foreign_sources (shell_window, "memos", E_SOURCE_EXTENSION_MEMO_LIST,
Packit 15f964
		cal_shell_content->priv->memo_model);
Packit 15f964
Packit 15f964
	cal_shell_content_setup_foreign_sources (shell_window, "tasks", E_SOURCE_EXTENSION_TASK_LIST,
Packit 15f964
		cal_shell_content->priv->task_model);
Packit 15f964
Packit 15f964
	/* Finally load the view instance */
Packit 15f964
	view_instance = e_shell_view_get_view_instance (shell_view);
Packit 15f964
	gal_view_instance_load (view_instance);
Packit 15f964
Packit 15f964
	/* Keep the toolbar view buttons in sync with the calendar. */
Packit 15f964
	e_binding_bind_property (
Packit 15f964
		cal_shell_content, "current-view-id",
Packit 15f964
		ACTION (CALENDAR_VIEW_DAY), "current-value",
Packit 15f964
		G_BINDING_BIDIRECTIONAL |
Packit 15f964
		G_BINDING_SYNC_CREATE);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-monday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-tuesday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-wednesday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-thursday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-friday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-saturday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::work-day-sunday",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_work_day_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		model, "notify::week-start-day",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_week_start_day_cb), cal_shell_content);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
e_cal_shell_content_create_calendar_views (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	ECalModel *model;
Packit 15f964
	ECalendarView *calendar_view;
Packit 15f964
	GtkAdjustment *adjustment;
Packit 15f964
	time_t today;
Packit 15f964
	gint ii;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (cal_shell_content->priv->calendar_notebook != NULL);
Packit 15f964
	g_return_if_fail (cal_shell_content->priv->views[0] == NULL);
Packit 15f964
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	/* Day View */
Packit 15f964
	calendar_view = e_day_view_new (model);
Packit 15f964
	cal_shell_content->priv->views[E_CAL_VIEW_KIND_DAY] = calendar_view;
Packit 15f964
	g_object_ref_sink (calendar_view);
Packit 15f964
Packit 15f964
	/* Work Week View */
Packit 15f964
	calendar_view = e_day_view_new (model);
Packit 15f964
	e_day_view_set_work_week_view (E_DAY_VIEW (calendar_view), TRUE);
Packit 15f964
	e_day_view_set_days_shown (E_DAY_VIEW (calendar_view), 5);
Packit 15f964
	cal_shell_content->priv->views[E_CAL_VIEW_KIND_WORKWEEK] = calendar_view;
Packit 15f964
	g_object_ref_sink (calendar_view);
Packit 15f964
Packit 15f964
	/* Week View */
Packit 15f964
	calendar_view = e_week_view_new (model);
Packit 15f964
	cal_shell_content->priv->views[E_CAL_VIEW_KIND_WEEK] = calendar_view;
Packit 15f964
	g_object_ref_sink (calendar_view);
Packit 15f964
Packit 15f964
	adjustment = gtk_range_get_adjustment (
Packit 15f964
		GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar));
Packit 15f964
	g_signal_connect (
Packit 15f964
		adjustment, "value-changed",
Packit 15f964
		G_CALLBACK (week_view_adjustment_changed_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	/* Month View */
Packit 15f964
	calendar_view = e_month_view_new (model);
Packit 15f964
	e_week_view_set_multi_week_view (E_WEEK_VIEW (calendar_view), TRUE);
Packit 15f964
	e_week_view_set_weeks_shown (E_WEEK_VIEW (calendar_view), 6);
Packit 15f964
	cal_shell_content->priv->views[E_CAL_VIEW_KIND_MONTH] = calendar_view;
Packit 15f964
	g_object_ref_sink (calendar_view);
Packit 15f964
Packit 15f964
	adjustment = gtk_range_get_adjustment (
Packit 15f964
		GTK_RANGE (E_WEEK_VIEW (calendar_view)->vscrollbar));
Packit 15f964
	g_signal_connect (
Packit 15f964
		adjustment, "value-changed",
Packit 15f964
		G_CALLBACK (month_view_adjustment_changed_cb), cal_shell_content);
Packit 15f964
Packit 15f964
	/* List View */
Packit 15f964
	calendar_view = e_cal_list_view_new (model);
Packit 15f964
	cal_shell_content->priv->views[E_CAL_VIEW_KIND_LIST] = calendar_view;
Packit 15f964
	g_object_ref_sink (calendar_view);
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	today = time (NULL);
Packit 15f964
Packit 15f964
	for (ii = 0; ii < E_CAL_VIEW_KIND_LAST; ii++) {
Packit 15f964
		calendar_view = cal_shell_content->priv->views[ii];
Packit 15f964
Packit 15f964
		calendar_view->in_focus = ii == cal_shell_content->priv->current_view;
Packit 15f964
Packit 15f964
		e_calendar_view_set_selected_time_range (calendar_view, today, today);
Packit 15f964
Packit 15f964
		e_signal_connect_notify (
Packit 15f964
			calendar_view, "notify::is-editing",
Packit 15f964
			G_CALLBACK (cal_shell_content_is_editing_changed_cb), shell_view);
Packit 15f964
Packit 15f964
		g_signal_connect (
Packit 15f964
			calendar_view, "move-view-range",
Packit 15f964
			G_CALLBACK (cal_shell_content_move_view_range_cb), cal_shell_content);
Packit 15f964
Packit 15f964
		gtk_notebook_append_page (
Packit 15f964
			GTK_NOTEBOOK (cal_shell_content->priv->calendar_notebook),
Packit 15f964
			GTK_WIDGET (calendar_view), NULL);
Packit 15f964
		gtk_widget_show (GTK_WIDGET (calendar_view));
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_set_property (GObject *object,
Packit 15f964
				guint property_id,
Packit 15f964
				const GValue *value,
Packit 15f964
				GParamSpec *pspec)
Packit 15f964
{
Packit 15f964
	switch (property_id) {
Packit 15f964
		case PROP_CURRENT_VIEW_ID:
Packit 15f964
			e_cal_shell_content_set_current_view_id (E_CAL_SHELL_CONTENT (object),
Packit 15f964
				g_value_get_int (value));
Packit 15f964
			return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_get_property (GObject *object,
Packit 15f964
				guint property_id,
Packit 15f964
				GValue *value,
Packit 15f964
				GParamSpec *pspec)
Packit 15f964
{
Packit 15f964
	switch (property_id) {
Packit 15f964
		case PROP_CALENDAR_NOTEBOOK:
Packit 15f964
			g_value_set_object (
Packit 15f964
				value, e_cal_shell_content_get_calendar_notebook (
Packit 15f964
				E_CAL_SHELL_CONTENT (object)));
Packit 15f964
			return;
Packit 15f964
Packit 15f964
		case PROP_MEMO_TABLE:
Packit 15f964
			g_value_set_object (
Packit 15f964
				value, e_cal_shell_content_get_memo_table (
Packit 15f964
				E_CAL_SHELL_CONTENT (object)));
Packit 15f964
			return;
Packit 15f964
Packit 15f964
		case PROP_TASK_TABLE:
Packit 15f964
			g_value_set_object (
Packit 15f964
				value, e_cal_shell_content_get_task_table (
Packit 15f964
				E_CAL_SHELL_CONTENT (object)));
Packit 15f964
			return;
Packit 15f964
Packit 15f964
		case PROP_CURRENT_VIEW_ID:
Packit 15f964
			g_value_set_int (value,
Packit 15f964
				e_cal_shell_content_get_current_view_id (E_CAL_SHELL_CONTENT (object)));
Packit 15f964
			return;
Packit 15f964
Packit 15f964
		case PROP_CURRENT_VIEW:
Packit 15f964
			g_value_set_object (value,
Packit 15f964
				e_cal_shell_content_get_current_calendar_view (E_CAL_SHELL_CONTENT (object)));
Packit 15f964
			return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_dispose (GObject *object)
Packit 15f964
{
Packit 15f964
	ECalShellContent *cal_shell_content = E_CAL_SHELL_CONTENT (object);
Packit 15f964
	gint ii;
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->task_data_model) {
Packit 15f964
		e_cal_data_model_set_disposing (cal_shell_content->priv->task_data_model, TRUE);
Packit 15f964
		e_cal_data_model_unsubscribe (cal_shell_content->priv->task_data_model,
Packit 15f964
			E_CAL_DATA_MODEL_SUBSCRIBER (cal_shell_content->priv->task_model));
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->memo_data_model) {
Packit 15f964
		e_cal_data_model_set_disposing (cal_shell_content->priv->memo_data_model, TRUE);
Packit 15f964
		e_cal_data_model_unsubscribe (cal_shell_content->priv->memo_data_model,
Packit 15f964
			E_CAL_DATA_MODEL_SUBSCRIBER (cal_shell_content->priv->memo_model));
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->tag_calendar) {
Packit 15f964
		ECalDataModel *data_model;
Packit 15f964
Packit 15f964
		data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
		e_cal_data_model_set_disposing (data_model, TRUE);
Packit 15f964
		e_tag_calendar_unsubscribe (cal_shell_content->priv->tag_calendar, data_model);
Packit 15f964
		g_clear_object (&cal_shell_content->priv->tag_calendar);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	for (ii = 0; ii < E_CAL_VIEW_KIND_LAST; ii++) {
Packit 15f964
		g_clear_object (&(cal_shell_content->priv->views[ii]));
Packit 15f964
	}
Packit 15f964
Packit 15f964
	g_clear_object (&cal_shell_content->priv->hpaned);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->vpaned);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->calendar_notebook);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->task_table);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->task_model);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->task_data_model);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->memo_table);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->memo_model);
Packit 15f964
	g_clear_object (&cal_shell_content->priv->memo_data_model);
Packit 15f964
Packit 15f964
	/* Chain up to parent's dispose() method. */
Packit 15f964
	G_OBJECT_CLASS (e_cal_shell_content_parent_class)->dispose (object);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_constructed (GObject *object)
Packit 15f964
{
Packit 15f964
	ECalShellContent *cal_shell_content;
Packit 15f964
	EShellContent *shell_content;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	EShellWindow *shell_window;
Packit 15f964
	EShell *shell;
Packit 15f964
	GalViewInstance *view_instance;
Packit 15f964
	GSettings *settings;
Packit 15f964
	GtkWidget *container;
Packit 15f964
	GtkWidget *widget;
Packit 15f964
	gchar *markup;
Packit 15f964
Packit 15f964
	/* Chain up to parent's constructed() method. */
Packit 15f964
	G_OBJECT_CLASS (e_cal_shell_content_parent_class)->constructed (object);
Packit 15f964
Packit 15f964
	cal_shell_content = E_CAL_SHELL_CONTENT (object);
Packit 15f964
	shell_content = E_SHELL_CONTENT (cal_shell_content);
Packit 15f964
	shell_view = e_shell_content_get_shell_view (shell_content);
Packit 15f964
	shell_window = e_shell_view_get_shell_window (shell_view);
Packit 15f964
	shell = e_shell_window_get_shell (shell_window);
Packit 15f964
Packit 15f964
	cal_shell_content->priv->memo_data_model =
Packit 15f964
		e_cal_base_shell_content_create_new_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	cal_shell_content->priv->memo_model =
Packit 15f964
		e_cal_model_memos_new (cal_shell_content->priv->memo_data_model, e_shell_get_registry (shell), shell);
Packit 15f964
Packit 15f964
	cal_shell_content->priv->task_data_model =
Packit 15f964
		e_cal_base_shell_content_create_new_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	cal_shell_content->priv->task_model =
Packit 15f964
		e_cal_model_tasks_new (cal_shell_content->priv->task_data_model, e_shell_get_registry (shell), shell);
Packit 15f964
Packit 15f964
	e_binding_bind_property (
Packit 15f964
		cal_shell_content->priv->memo_model, "timezone",
Packit 15f964
		cal_shell_content->priv->memo_data_model, "timezone",
Packit 15f964
		G_BINDING_SYNC_CREATE);
Packit 15f964
Packit 15f964
	e_binding_bind_property (
Packit 15f964
		cal_shell_content->priv->task_model, "timezone",
Packit 15f964
		cal_shell_content->priv->task_data_model, "timezone",
Packit 15f964
		G_BINDING_SYNC_CREATE);
Packit 15f964
Packit 15f964
	/* Build content widgets. */
Packit 15f964
Packit 15f964
	container = GTK_WIDGET (object);
Packit 15f964
Packit 15f964
	widget = e_paned_new (GTK_ORIENTATION_HORIZONTAL);
Packit 15f964
	gtk_container_add (GTK_CONTAINER (container), widget);
Packit 15f964
	cal_shell_content->priv->hpaned = g_object_ref (widget);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = cal_shell_content->priv->hpaned;
Packit 15f964
Packit 15f964
	widget = gtk_notebook_new ();
Packit 15f964
	gtk_notebook_set_show_tabs (GTK_NOTEBOOK (widget), FALSE);
Packit 15f964
	gtk_notebook_set_show_border (GTK_NOTEBOOK (widget), FALSE);
Packit 15f964
	gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, FALSE);
Packit 15f964
	cal_shell_content->priv->calendar_notebook = g_object_ref (widget);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	widget = e_paned_new (GTK_ORIENTATION_VERTICAL);
Packit 15f964
	e_paned_set_fixed_resize (E_PANED (widget), FALSE);
Packit 15f964
	gtk_paned_pack2 (GTK_PANED (container), widget, FALSE, TRUE);
Packit 15f964
	cal_shell_content->priv->vpaned = g_object_ref (widget);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = cal_shell_content->priv->calendar_notebook;
Packit 15f964
Packit 15f964
	e_cal_shell_content_create_calendar_views (cal_shell_content);
Packit 15f964
Packit 15f964
	e_binding_bind_property (
Packit 15f964
		cal_shell_content, "current-view-id",
Packit 15f964
		cal_shell_content->priv->calendar_notebook, "page",
Packit 15f964
		G_BINDING_SYNC_CREATE);
Packit 15f964
Packit 15f964
	container = cal_shell_content->priv->vpaned;
Packit 15f964
Packit 15f964
	widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit 15f964
	gtk_paned_pack1 (GTK_PANED (container), widget, TRUE, TRUE);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = widget;
Packit 15f964
Packit 15f964
	widget = gtk_label_new (NULL);
Packit 15f964
	markup = g_strdup_printf ("%s", _("Tasks"));
Packit 15f964
	gtk_label_set_markup (GTK_LABEL (widget), markup);
Packit 15f964
	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
	g_free (markup);
Packit 15f964
Packit 15f964
	widget = gtk_scrolled_window_new (NULL, NULL);
Packit 15f964
	gtk_scrolled_window_set_policy (
Packit 15f964
		GTK_SCROLLED_WINDOW (widget),
Packit 15f964
		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
Packit 15f964
	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = widget;
Packit 15f964
Packit 15f964
	widget = e_task_table_new (shell_view, cal_shell_content->priv->task_model);
Packit 15f964
	gtk_container_add (GTK_CONTAINER (container), widget);
Packit 15f964
	cal_shell_content->priv->task_table = g_object_ref (widget);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	cal_shell_content_load_table_state (shell_content, E_TABLE (widget));
Packit 15f964
Packit 15f964
	g_signal_connect_swapped (
Packit 15f964
		widget, "open-component",
Packit 15f964
		G_CALLBACK (e_cal_shell_view_taskpad_open_task),
Packit 15f964
		shell_view);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		widget, "notify::is-editing",
Packit 15f964
		G_CALLBACK (cal_shell_content_is_editing_changed_cb), shell_view);
Packit 15f964
Packit 15f964
	container = cal_shell_content->priv->vpaned;
Packit 15f964
Packit 15f964
	widget = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
Packit 15f964
	gtk_paned_pack2 (GTK_PANED (container), widget, TRUE, TRUE);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = widget;
Packit 15f964
Packit 15f964
	widget = gtk_label_new (NULL);
Packit 15f964
	markup = g_strdup_printf ("%s", _("Memos"));
Packit 15f964
	gtk_label_set_markup (GTK_LABEL (widget), markup);
Packit 15f964
	gtk_box_pack_start (GTK_BOX (container), widget, FALSE, TRUE, 0);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
	g_free (markup);
Packit 15f964
Packit 15f964
	widget = gtk_scrolled_window_new (NULL, NULL);
Packit 15f964
	gtk_scrolled_window_set_policy (
Packit 15f964
		GTK_SCROLLED_WINDOW (widget),
Packit 15f964
		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
Packit 15f964
	gtk_box_pack_start (GTK_BOX (container), widget, TRUE, TRUE, 0);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	container = widget;
Packit 15f964
Packit 15f964
	widget = e_memo_table_new (shell_view, cal_shell_content->priv->memo_model);
Packit 15f964
	gtk_container_add (GTK_CONTAINER (container), widget);
Packit 15f964
	cal_shell_content->priv->memo_table = g_object_ref (widget);
Packit 15f964
	gtk_widget_show (widget);
Packit 15f964
Packit 15f964
	cal_shell_content_load_table_state (shell_content, E_TABLE (widget));
Packit 15f964
Packit 15f964
	e_cal_model_set_default_time_func (cal_shell_content->priv->memo_model, cal_shell_content_get_default_time, cal_shell_content);
Packit 15f964
Packit 15f964
	g_signal_connect_swapped (
Packit 15f964
		widget, "open-component",
Packit 15f964
		G_CALLBACK (e_cal_shell_view_memopad_open_memo),
Packit 15f964
		shell_view);
Packit 15f964
Packit 15f964
	e_signal_connect_notify (
Packit 15f964
		widget, "notify::is-editing",
Packit 15f964
		G_CALLBACK (cal_shell_content_is_editing_changed_cb), shell_view);
Packit 15f964
Packit 15f964
	/* Prepare the view instance. */
Packit 15f964
Packit 15f964
	view_instance = e_shell_view_new_view_instance (shell_view, NULL);
Packit 15f964
	g_signal_connect_swapped (
Packit 15f964
		view_instance, "display-view",
Packit 15f964
		G_CALLBACK (cal_shell_content_display_view_cb),
Packit 15f964
		object);
Packit 15f964
	/* Actual load happens at cal_shell_content_view_created() */
Packit 15f964
	e_shell_view_set_view_instance (shell_view, view_instance);
Packit 15f964
	g_object_unref (view_instance);
Packit 15f964
Packit 15f964
	e_signal_connect_notify_swapped (
Packit 15f964
		shell_view, "notify::view-id",
Packit 15f964
		G_CALLBACK (cal_shell_content_notify_view_id_cb),
Packit 15f964
		cal_shell_content);
Packit 15f964
Packit 15f964
	settings = e_util_ref_settings ("org.gnome.evolution.calendar");
Packit 15f964
Packit 15f964
	g_settings_bind (
Packit 15f964
		settings, "tag-vpane-position",
Packit 15f964
		cal_shell_content->priv->vpaned, "proportion",
Packit 15f964
		G_SETTINGS_BIND_DEFAULT);
Packit 15f964
Packit 15f964
	g_object_unref (settings);
Packit 15f964
Packit 15f964
	/* Cannot access shell sidebar here, thus rely on cal_shell_content_view_created()
Packit 15f964
	   with exact widget settings which require it */
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
e_cal_shell_content_class_init (ECalShellContentClass *class)
Packit 15f964
{
Packit 15f964
	GObjectClass *object_class;
Packit 15f964
	EShellContentClass *shell_content_class;
Packit 15f964
	ECalBaseShellContentClass *cal_base_shell_content_class;
Packit 15f964
Packit 15f964
	g_type_class_add_private (class, sizeof (ECalShellContentPrivate));
Packit 15f964
Packit 15f964
	object_class = G_OBJECT_CLASS (class);
Packit 15f964
	object_class->set_property = cal_shell_content_set_property;
Packit 15f964
	object_class->get_property = cal_shell_content_get_property;
Packit 15f964
	object_class->dispose = cal_shell_content_dispose;
Packit 15f964
	object_class->constructed = cal_shell_content_constructed;
Packit 15f964
Packit 15f964
	shell_content_class = E_SHELL_CONTENT_CLASS (class);
Packit 15f964
	shell_content_class->check_state = cal_shell_content_check_state;
Packit 15f964
	shell_content_class->focus_search_results = cal_shell_content_focus_search_results;
Packit 15f964
Packit 15f964
	cal_base_shell_content_class = E_CAL_BASE_SHELL_CONTENT_CLASS (class);
Packit 15f964
	cal_base_shell_content_class->new_cal_model = e_cal_model_calendar_new;
Packit 15f964
	cal_base_shell_content_class->view_created = cal_shell_content_view_created;
Packit 15f964
Packit 15f964
	g_object_class_install_property (
Packit 15f964
		object_class,
Packit 15f964
		PROP_CALENDAR_NOTEBOOK,
Packit 15f964
		g_param_spec_object (
Packit 15f964
			"calendar-notebook",
Packit 15f964
			NULL,
Packit 15f964
			NULL,
Packit 15f964
			GTK_TYPE_NOTEBOOK,
Packit 15f964
			G_PARAM_READABLE));
Packit 15f964
Packit 15f964
	g_object_class_install_property (
Packit 15f964
		object_class,
Packit 15f964
		PROP_MEMO_TABLE,
Packit 15f964
		g_param_spec_object (
Packit 15f964
			"memo-table",
Packit 15f964
			NULL,
Packit 15f964
			NULL,
Packit 15f964
			E_TYPE_MEMO_TABLE,
Packit 15f964
			G_PARAM_READABLE));
Packit 15f964
Packit 15f964
	g_object_class_install_property (
Packit 15f964
		object_class,
Packit 15f964
		PROP_TASK_TABLE,
Packit 15f964
		g_param_spec_object (
Packit 15f964
			"task-table",
Packit 15f964
			NULL,
Packit 15f964
			NULL,
Packit 15f964
			E_TYPE_TASK_TABLE,
Packit 15f964
			G_PARAM_READABLE));
Packit 15f964
Packit 15f964
	g_object_class_install_property (
Packit 15f964
		object_class,
Packit 15f964
		PROP_CURRENT_VIEW_ID,
Packit 15f964
		g_param_spec_int (
Packit 15f964
			"current-view-id",
Packit 15f964
			"Current Calendar View ID",
Packit 15f964
			NULL,
Packit 15f964
			E_CAL_VIEW_KIND_DAY,
Packit 15f964
			E_CAL_VIEW_KIND_LAST - 1,
Packit 15f964
			E_CAL_VIEW_KIND_DAY,
Packit 15f964
			G_PARAM_READWRITE));
Packit 15f964
Packit 15f964
	g_object_class_install_property (
Packit 15f964
		object_class,
Packit 15f964
		PROP_CURRENT_VIEW,
Packit 15f964
		g_param_spec_object (
Packit 15f964
			"current-view",
Packit 15f964
			"Current Calendar View",
Packit 15f964
			NULL,
Packit 15f964
			E_TYPE_CALENDAR_VIEW,
Packit 15f964
			G_PARAM_READABLE));
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
e_cal_shell_content_class_finalize (ECalShellContentClass *class)
Packit 15f964
{
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
e_cal_shell_content_init (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	time_t now;
Packit 15f964
Packit 15f964
	cal_shell_content->priv = E_CAL_SHELL_CONTENT_GET_PRIVATE (cal_shell_content);
Packit 15f964
	g_date_clear (&cal_shell_content->priv->view_start, 1);
Packit 15f964
	g_date_clear (&cal_shell_content->priv->view_end, 1);
Packit 15f964
	g_date_clear (&cal_shell_content->priv->last_range_start, 1);
Packit 15f964
Packit 15f964
	now = time (NULL);
Packit 15f964
	g_date_set_time_t (&cal_shell_content->priv->view_start, now);
Packit 15f964
	g_date_set_time_t (&cal_shell_content->priv->view_end, now);
Packit 15f964
Packit 15f964
	cal_shell_content->priv->view_start_range_day_offset = (guint32) -1;
Packit 15f964
	cal_shell_content->priv->previous_selected_start_time = -1;
Packit 15f964
	cal_shell_content->priv->previous_selected_end_time = -1;
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_type_register (GTypeModule *type_module)
Packit 15f964
{
Packit 15f964
	/* XXX G_DEFINE_DYNAMIC_TYPE declares a static type registration
Packit 15f964
	 *     function, so we have to wrap it with a public function in
Packit 15f964
	 *     order to register types from a separate compilation unit. */
Packit 15f964
	e_cal_shell_content_register_type (type_module);
Packit 15f964
}
Packit 15f964
Packit 15f964
GtkWidget *
Packit 15f964
e_cal_shell_content_new (EShellView *shell_view)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_SHELL_VIEW (shell_view), NULL);
Packit 15f964
Packit 15f964
	return g_object_new (
Packit 15f964
		E_TYPE_CAL_SHELL_CONTENT,
Packit 15f964
		"shell-view", shell_view, NULL);
Packit 15f964
}
Packit 15f964
Packit 15f964
GtkNotebook *
Packit 15f964
e_cal_shell_content_get_calendar_notebook (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
Packit 15f964
	return GTK_NOTEBOOK (cal_shell_content->priv->calendar_notebook);
Packit 15f964
}
Packit 15f964
Packit 15f964
EMemoTable *
Packit 15f964
e_cal_shell_content_get_memo_table (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
Packit 15f964
	return E_MEMO_TABLE (cal_shell_content->priv->memo_table);
Packit 15f964
}
Packit 15f964
Packit 15f964
ETaskTable *
Packit 15f964
e_cal_shell_content_get_task_table (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
Packit 15f964
	return E_TASK_TABLE (cal_shell_content->priv->task_table);
Packit 15f964
}
Packit 15f964
Packit 15f964
EShellSearchbar *
Packit 15f964
e_cal_shell_content_get_searchbar (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	EShellContent *shell_content;
Packit 15f964
	GtkWidget *widget;
Packit 15f964
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
Packit 15f964
	shell_content = E_SHELL_CONTENT (cal_shell_content);
Packit 15f964
	shell_view = e_shell_content_get_shell_view (shell_content);
Packit 15f964
	widget = e_shell_view_get_searchbar (shell_view);
Packit 15f964
Packit 15f964
	return E_SHELL_SEARCHBAR (widget);
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_resubscribe (ECalendarView *cal_view,
Packit 15f964
			       ECalModel *model)
Packit 15f964
{
Packit 15f964
	ECalDataModel *data_model;
Packit 15f964
	ECalDataModelSubscriber *subscriber;
Packit 15f964
	time_t range_start, range_end;
Packit 15f964
	gboolean is_tasks_or_memos;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
Packit 15f964
	data_model = e_cal_model_get_data_model (model);
Packit 15f964
	subscriber = E_CAL_DATA_MODEL_SUBSCRIBER (model);
Packit 15f964
	is_tasks_or_memos = e_cal_model_get_component_kind (model) == ICAL_VJOURNAL_COMPONENT ||
Packit 15f964
		e_cal_model_get_component_kind (model) == ICAL_VTODO_COMPONENT;
Packit 15f964
Packit 15f964
	if ((!is_tasks_or_memos && e_calendar_view_get_visible_time_range (cal_view, &range_start, &range_end)) ||
Packit 15f964
	    e_cal_data_model_get_subscriber_range (data_model, subscriber, &range_start, &range_end)) {
Packit 15f964
		e_cal_data_model_unsubscribe (data_model, subscriber);
Packit 15f964
		e_cal_model_remove_all_objects (model);
Packit 15f964
Packit 15f964
		if (is_tasks_or_memos)
Packit 15f964
			e_cal_data_model_subscribe (data_model, subscriber, range_start, range_end);
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_set_current_view_id (ECalShellContent *cal_shell_content,
Packit 15f964
					 ECalViewKind view_kind)
Packit 15f964
{
Packit 15f964
	time_t start_time = -1, end_time = -1;
Packit 15f964
	gint ii;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (view_kind >= E_CAL_VIEW_KIND_DAY && view_kind < E_CAL_VIEW_KIND_LAST);
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->current_view == view_kind)
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->current_view >= E_CAL_VIEW_KIND_DAY &&
Packit 15f964
	    cal_shell_content->priv->current_view < E_CAL_VIEW_KIND_LAST) {
Packit 15f964
		ECalendarView *cal_view = cal_shell_content->priv->views[cal_shell_content->priv->current_view];
Packit 15f964
Packit 15f964
		if (!e_calendar_view_get_selected_time_range (cal_view, &start_time, &end_time)) {
Packit 15f964
			start_time = -1;
Packit 15f964
			end_time = -1;
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
Packit 15f964
	cal_shell_content->priv->previous_selected_start_time = start_time;
Packit 15f964
	cal_shell_content->priv->previous_selected_end_time = end_time;
Packit 15f964
Packit 15f964
	for (ii = 0; ii < E_CAL_VIEW_KIND_LAST; ii++) {
Packit 15f964
		ECalendarView *cal_view = cal_shell_content->priv->views[ii];
Packit 15f964
		gboolean in_focus = ii == view_kind;
Packit 15f964
		gboolean focus_changed;
Packit 15f964
Packit 15f964
		if (!cal_view) {
Packit 15f964
			g_warn_if_reached ();
Packit 15f964
			continue;
Packit 15f964
		}
Packit 15f964
Packit 15f964
		focus_changed = (cal_view->in_focus ? 1 : 0) != (in_focus ? 1 : 0);
Packit 15f964
Packit 15f964
		cal_view->in_focus = in_focus;
Packit 15f964
Packit 15f964
		if (focus_changed && in_focus) {
Packit 15f964
			/* Currently focused view changed. Any events within the common time
Packit 15f964
			   range are not shown in the newly focused view, thus make sure it'll
Packit 15f964
			   contain all what it should have. */
Packit 15f964
			ECalModel *model;
Packit 15f964
Packit 15f964
			model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
			/* This may not cause any queries to backends with events,
Packit 15f964
			   because the time range should be always within the one
Packit 15f964
			   shown in the date picker. */
Packit 15f964
			cal_shell_content_resubscribe (cal_view, model);
Packit 15f964
Packit 15f964
			if (cal_shell_content->priv->task_table) {
Packit 15f964
				ETaskTable *task_table;
Packit 15f964
Packit 15f964
				task_table = E_TASK_TABLE (cal_shell_content->priv->task_table);
Packit 15f964
				cal_shell_content_resubscribe (cal_view, e_task_table_get_model (task_table));
Packit 15f964
			}
Packit 15f964
Packit 15f964
			if (cal_shell_content->priv->memo_table) {
Packit 15f964
				EMemoTable *memo_table;
Packit 15f964
Packit 15f964
				memo_table = E_MEMO_TABLE (cal_shell_content->priv->memo_table);
Packit 15f964
				cal_shell_content_resubscribe (cal_view, e_memo_table_get_model (memo_table));
Packit 15f964
			}
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
Packit 15f964
	cal_shell_content->priv->current_view = view_kind;
Packit 15f964
Packit 15f964
	g_object_notify (G_OBJECT (cal_shell_content), "current-view-id");
Packit 15f964
Packit 15f964
	gtk_widget_queue_draw (GTK_WIDGET (cal_shell_content->priv->views[cal_shell_content->priv->current_view]));
Packit 15f964
}
Packit 15f964
Packit 15f964
ECalViewKind
Packit 15f964
e_cal_shell_content_get_current_view_id (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), E_CAL_VIEW_KIND_LAST);
Packit 15f964
Packit 15f964
	return cal_shell_content->priv->current_view;
Packit 15f964
}
Packit 15f964
Packit 15f964
ECalendarView *
Packit 15f964
e_cal_shell_content_get_calendar_view (ECalShellContent *cal_shell_content,
Packit 15f964
				       ECalViewKind view_kind)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
	g_return_val_if_fail (view_kind >= E_CAL_VIEW_KIND_DAY && view_kind < E_CAL_VIEW_KIND_LAST, NULL);
Packit 15f964
Packit 15f964
	return cal_shell_content->priv->views[view_kind];
Packit 15f964
}
Packit 15f964
Packit 15f964
ECalendarView *
Packit 15f964
e_cal_shell_content_get_current_calendar_view (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	g_return_val_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content), NULL);
Packit 15f964
Packit 15f964
	return e_cal_shell_content_get_calendar_view (cal_shell_content,
Packit 15f964
		e_cal_shell_content_get_current_view_id (cal_shell_content));
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_save_state (ECalShellContent *cal_shell_content)
Packit 15f964
{
Packit 15f964
	ECalShellContentPrivate *priv;
Packit 15f964
Packit 15f964
	g_return_if_fail (cal_shell_content != NULL);
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	priv = cal_shell_content->priv;
Packit 15f964
Packit 15f964
	if (priv->task_table != NULL)
Packit 15f964
		cal_shell_content_save_table_state (
Packit 15f964
			E_SHELL_CONTENT (cal_shell_content),
Packit 15f964
			E_TABLE (priv->task_table));
Packit 15f964
Packit 15f964
	if (priv->memo_table != NULL)
Packit 15f964
		cal_shell_content_save_table_state (
Packit 15f964
			E_SHELL_CONTENT (cal_shell_content),
Packit 15f964
			E_TABLE (priv->memo_table));
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_get_current_range (ECalShellContent *cal_shell_content,
Packit 15f964
				       time_t *range_start,
Packit 15f964
				       time_t *range_end)
Packit 15f964
{
Packit 15f964
	icaltimezone *zone;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (range_start != NULL);
Packit 15f964
	g_return_if_fail (range_end != NULL);
Packit 15f964
Packit 15f964
	zone = e_cal_data_model_get_timezone (e_cal_base_shell_content_get_data_model (
Packit 15f964
		E_CAL_BASE_SHELL_CONTENT (cal_shell_content)));
Packit 15f964
Packit 15f964
	*range_start = cal_comp_gdate_to_timet (&(cal_shell_content->priv->view_start), zone);
Packit 15f964
	*range_end = cal_comp_gdate_to_timet (&(cal_shell_content->priv->view_end), zone);
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_get_current_range_dates (ECalShellContent *cal_shell_content,
Packit 15f964
					     GDate *range_start,
Packit 15f964
					     GDate *range_end)
Packit 15f964
{
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (range_start != NULL);
Packit 15f964
	g_return_if_fail (range_end != NULL);
Packit 15f964
Packit 15f964
	*range_start = cal_shell_content->priv->view_start;
Packit 15f964
	*range_end = cal_shell_content->priv->view_end;
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_move_view_range_relative (ECalShellContent *cal_shell_content,
Packit 15f964
					    gint direction)
Packit 15f964
{
Packit 15f964
	GDate start, end;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	g_return_if_fail (direction != 0);
Packit 15f964
Packit 15f964
	start = cal_shell_content->priv->view_start;
Packit 15f964
	end = cal_shell_content->priv->view_end;
Packit 15f964
Packit 15f964
	switch (cal_shell_content->priv->current_view) {
Packit 15f964
		case E_CAL_VIEW_KIND_DAY:
Packit 15f964
			if (direction > 0) {
Packit 15f964
				g_date_add_days (&start, direction);
Packit 15f964
				g_date_add_days (&end, direction);
Packit 15f964
			} else {
Packit 15f964
				g_date_subtract_days (&start, direction * -1);
Packit 15f964
				g_date_subtract_days (&end, direction * -1);
Packit 15f964
			}
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_WORKWEEK:
Packit 15f964
		case E_CAL_VIEW_KIND_WEEK:
Packit 15f964
			if (direction > 0) {
Packit 15f964
				g_date_add_days (&start, direction * 7);
Packit 15f964
				g_date_add_days (&end, direction * 7);
Packit 15f964
			} else {
Packit 15f964
				g_date_subtract_days (&start, direction * -7);
Packit 15f964
				g_date_subtract_days (&end, direction * -7);
Packit 15f964
			}
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_MONTH:
Packit 15f964
		case E_CAL_VIEW_KIND_LIST:
Packit 15f964
			if (g_date_get_day (&start) != 1) {
Packit 15f964
				g_date_add_months (&start, 1);
Packit 15f964
				g_date_set_day (&start, 1);
Packit 15f964
			}
Packit 15f964
			if (direction > 0)
Packit 15f964
				g_date_add_months (&start, direction);
Packit 15f964
			else
Packit 15f964
				g_date_subtract_months (&start, direction * -1);
Packit 15f964
			end = start;
Packit 15f964
			g_date_set_day (&end, g_date_get_days_in_month (g_date_get_month (&start), g_date_get_year (&start)));
Packit 15f964
			g_date_add_days (&end, 6);
Packit 15f964
			break;
Packit 15f964
		case E_CAL_VIEW_KIND_LAST:
Packit 15f964
			return;
Packit 15f964
	}
Packit 15f964
Packit 15f964
	e_cal_shell_content_change_view (cal_shell_content, cal_shell_content->priv->current_view, &start, &end, FALSE);
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_move_view_range (ECalShellContent *cal_shell_content,
Packit 15f964
				     ECalendarViewMoveType move_type,
Packit 15f964
				     time_t exact_date)
Packit 15f964
{
Packit 15f964
	ECalendar *calendar;
Packit 15f964
	ECalDataModel *data_model;
Packit 15f964
	EShellSidebar *shell_sidebar;
Packit 15f964
	EShellView *shell_view;
Packit 15f964
	struct icaltimetype tt;
Packit 15f964
	icaltimezone *zone;
Packit 15f964
	GDate date;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	shell_view = e_shell_content_get_shell_view (E_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	shell_sidebar = e_shell_view_get_shell_sidebar (shell_view);
Packit 15f964
	g_return_if_fail (E_IS_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
Packit 15f964
	calendar = e_cal_base_shell_sidebar_get_date_navigator (E_CAL_BASE_SHELL_SIDEBAR (shell_sidebar));
Packit 15f964
	g_return_if_fail (E_IS_CALENDAR (calendar));
Packit 15f964
	g_return_if_fail (e_calendar_get_item (calendar) != NULL);
Packit 15f964
Packit 15f964
	data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	zone = e_cal_data_model_get_timezone (data_model);
Packit 15f964
Packit 15f964
	switch (move_type) {
Packit 15f964
		case E_CALENDAR_VIEW_MOVE_PREVIOUS:
Packit 15f964
			cal_shell_content_move_view_range_relative (cal_shell_content, -1);
Packit 15f964
			break;
Packit 15f964
		case E_CALENDAR_VIEW_MOVE_NEXT:
Packit 15f964
			cal_shell_content_move_view_range_relative (cal_shell_content, +1);
Packit 15f964
			break;
Packit 15f964
		case E_CALENDAR_VIEW_MOVE_TO_TODAY:
Packit 15f964
			tt = icaltime_current_time_with_zone (zone);
Packit 15f964
			g_date_set_dmy (&date, tt.day, tt.month, tt.year);
Packit 15f964
			/* one-day selection takes care of the view range move with left view kind */
Packit 15f964
			e_calendar_item_set_selection (e_calendar_get_item (calendar), &date, &date);
Packit 15f964
			break;
Packit 15f964
		case E_CALENDAR_VIEW_MOVE_TO_EXACT_DAY:
Packit 15f964
			time_to_gdate_with_zone (&date, exact_date, zone);
Packit 15f964
			e_cal_shell_content_change_view (cal_shell_content, E_CAL_VIEW_KIND_DAY, &date, &date, FALSE);
Packit 15f964
			break;
Packit 15f964
	}
Packit 15f964
}
Packit 15f964
Packit 15f964
static void
Packit 15f964
cal_shell_content_update_model_filter (ECalDataModel *data_model,
Packit 15f964
				       ECalModel *model,
Packit 15f964
				       const gchar *filter,
Packit 15f964
				       time_t range_start,
Packit 15f964
				       time_t range_end)
Packit 15f964
{
Packit 15f964
	time_t tmp_start, tmp_end;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model));
Packit 15f964
	g_return_if_fail (E_IS_CAL_MODEL (model));
Packit 15f964
Packit 15f964
	e_cal_data_model_freeze_views_update (data_model);
Packit 15f964
	if (filter != NULL)
Packit 15f964
		e_cal_data_model_set_filter (data_model, filter);
Packit 15f964
	e_cal_model_set_time_range (model, range_start, range_end);
Packit 15f964
Packit 15f964
	if (!e_cal_data_model_get_subscriber_range (data_model, E_CAL_DATA_MODEL_SUBSCRIBER (model), &tmp_start, &tmp_end)) {
Packit 15f964
		e_cal_data_model_subscribe (data_model, E_CAL_DATA_MODEL_SUBSCRIBER (model), range_start, range_end);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	e_cal_data_model_thaw_views_update (data_model);
Packit 15f964
}
Packit 15f964
Packit 15f964
void
Packit 15f964
e_cal_shell_content_update_filters (ECalShellContent *cal_shell_content,
Packit 15f964
				    const gchar *cal_filter,
Packit 15f964
				    time_t start_range,
Packit 15f964
				    time_t end_range)
Packit 15f964
{
Packit 15f964
	ECalDataModel *data_model;
Packit 15f964
	ECalModel *model;
Packit 15f964
Packit 15f964
	g_return_if_fail (E_IS_CAL_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	if (!cal_filter)
Packit 15f964
		return;
Packit 15f964
Packit 15f964
	data_model = e_cal_base_shell_content_get_data_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
	model = e_cal_base_shell_content_get_model (E_CAL_BASE_SHELL_CONTENT (cal_shell_content));
Packit 15f964
Packit 15f964
	cal_shell_content_update_model_filter (data_model, model, cal_filter, start_range, end_range);
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->task_table) {
Packit 15f964
		ETaskTable *task_table;
Packit 15f964
		gchar *hide_completed_tasks_sexp;
Packit 15f964
Packit 15f964
		/* Set the query on the task pad. */
Packit 15f964
Packit 15f964
		task_table = E_TASK_TABLE (cal_shell_content->priv->task_table);
Packit 15f964
		model = e_task_table_get_model (task_table);
Packit 15f964
		data_model = e_cal_model_get_data_model (model);
Packit 15f964
Packit 15f964
		hide_completed_tasks_sexp = calendar_config_get_hide_completed_tasks_sexp (FALSE);
Packit 15f964
Packit 15f964
		if (hide_completed_tasks_sexp != NULL) {
Packit 15f964
			if (*cal_filter) {
Packit 15f964
				gchar *filter;
Packit 15f964
Packit 15f964
				filter = g_strdup_printf ("(and %s %s)", hide_completed_tasks_sexp, cal_filter);
Packit 15f964
				cal_shell_content_update_model_filter (data_model, model, filter, 0, 0);
Packit 15f964
				g_free (filter);
Packit 15f964
			} else {
Packit 15f964
				cal_shell_content_update_model_filter (data_model, model, hide_completed_tasks_sexp, 0, 0);
Packit 15f964
			}
Packit 15f964
		} else {
Packit 15f964
			cal_shell_content_update_model_filter (data_model, model, *cal_filter ? cal_filter : "#t", 0, 0);
Packit 15f964
		}
Packit 15f964
Packit 15f964
		g_free (hide_completed_tasks_sexp);
Packit 15f964
	}
Packit 15f964
Packit 15f964
	if (cal_shell_content->priv->memo_table) {
Packit 15f964
		EMemoTable *memo_table;
Packit 15f964
Packit 15f964
		/* Set the query on the memo pad. */
Packit 15f964
Packit 15f964
		memo_table = E_MEMO_TABLE (cal_shell_content->priv->memo_table);
Packit 15f964
		model = e_memo_table_get_model (memo_table);
Packit 15f964
		data_model = e_cal_model_get_data_model (model);
Packit 15f964
Packit 15f964
		if (start_range != 0 && end_range != 0) {
Packit 15f964
			icaltimezone *zone;
Packit 15f964
			const gchar *default_tzloc = NULL;
Packit 15f964
			time_t end = end_range;
Packit 15f964
			gchar *filter;
Packit 15f964
			gchar *iso_start;
Packit 15f964
			gchar *iso_end;
Packit 15f964
Packit 15f964
			zone = e_cal_data_model_get_timezone (data_model);
Packit 15f964
			if (zone && zone != icaltimezone_get_utc_timezone ())
Packit 15f964
				default_tzloc = icaltimezone_get_location (zone);
Packit 15f964
			if (!default_tzloc)
Packit 15f964
				default_tzloc = "";
Packit 15f964
Packit 15f964
			if (start_range != (time_t) 0 && end_range != (time_t) 0) {
Packit 15f964
				end = time_day_end_with_zone (end_range, zone);
Packit 15f964
			}
Packit 15f964
Packit 15f964
			iso_start = isodate_from_time_t (start_range);
Packit 15f964
			iso_end = isodate_from_time_t (end);
Packit 15f964
Packit 15f964
			filter = g_strdup_printf (
Packit 15f964
				"(and (or (not (has-start?)) "
Packit 15f964
				"(occur-in-time-range? (make-time \"%s\") "
Packit 15f964
				"(make-time \"%s\") \"%s\")) %s)",
Packit 15f964
				iso_start, iso_end, default_tzloc, cal_filter);
Packit 15f964
Packit 15f964
			cal_shell_content_update_model_filter (data_model, model, filter, 0, 0);
Packit 15f964
Packit 15f964
			g_free (filter);
Packit 15f964
			g_free (iso_start);
Packit 15f964
			g_free (iso_end);
Packit 15f964
		} else {
Packit 15f964
			cal_shell_content_update_model_filter (data_model, model, *cal_filter ? cal_filter : "#t", 0, 0);
Packit 15f964
		}
Packit 15f964
	}
Packit 15f964
}