diff options
Diffstat (limited to 'calendar/gui/e-cal-model.c')
-rw-r--r-- | calendar/gui/e-cal-model.c | 555 |
1 files changed, 356 insertions, 199 deletions
diff --git a/calendar/gui/e-cal-model.c b/calendar/gui/e-cal-model.c index ff6ae4172a..c582b0fb78 100644 --- a/calendar/gui/e-cal-model.c +++ b/calendar/gui/e-cal-model.c @@ -35,8 +35,16 @@ #include "e-cal-model.h" #include "itip-utils.h" #include "misc.h" +#include "e-util/e-binding.h" #include "e-util/e-util.h" -#include "calendar-config.h" + +#define E_CAL_MODEL_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_MODEL, ECalModelPrivate)) + +#define E_CAL_MODEL_COMPONENT_GET_PRIVATE(obj) \ + (G_TYPE_INSTANCE_GET_PRIVATE \ + ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentPrivate)) typedef struct { ECal *client; @@ -46,6 +54,8 @@ typedef struct { } ECalModelClient; struct _ECalModelPrivate { + EShellSettings *shell_settings; + /* The list of clients we are managing. Each element is of type ECalModelClient */ GList *clients; @@ -78,6 +88,9 @@ struct _ECalModelPrivate { /* Whether we display dates in 24-hour format. */ gboolean use_24_hour_format; + /* First day of the week: 0 (Monday) to 6 (Sunday) */ + gint week_start_day; + /* callback, to retrieve start time for newly added rows by click-to-add */ ECalModelDefaultTimeFunc get_default_time; gpointer get_default_time_user_data; @@ -93,13 +106,6 @@ struct _ECalModelPrivate { GMutex *notify_lock; }; -#define E_CAL_MODEL_COMPONENT_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE \ - ((obj), E_TYPE_CAL_MODEL_COMPONENT, ECalModelComponentPrivate)) - -static void e_cal_model_dispose (GObject *object); -static void e_cal_model_finalize (GObject *object); - static gint ecm_column_count (ETableModel *etm); static gint ecm_row_count (ETableModel *etm); static gpointer ecm_value_at (ETableModel *etm, gint col, gint row); @@ -119,7 +125,14 @@ static ECalModelClient *find_client_data (ECalModel *model, ECal *client); static void remove_client_objects (ECalModel *model, ECalModelClient *client_data); static void remove_client (ECalModel *model, ECalModelClient *client_data); -/* Signal IDs */ +enum { + PROP_0, + PROP_SHELL_SETTINGS, + PROP_TIMEZONE, + PROP_USE_24_HOUR_FORMAT, + PROP_WEEK_START_DAY +}; + enum { TIME_RANGE_CHANGED, ROW_APPENDED, @@ -129,19 +142,203 @@ enum { LAST_SIGNAL }; -static guint signals[LAST_SIGNAL] = { 0 }; +static gpointer parent_class; +static guint signals[LAST_SIGNAL]; G_DEFINE_TYPE (ECalModel, e_cal_model, E_TABLE_MODEL_TYPE) static void -e_cal_model_class_init (ECalModelClass *klass) +cal_model_set_shell_settings (ECalModel *cal_model, + EShellSettings *shell_settings) +{ + g_return_if_fail (E_IS_SHELL_SETTINGS (shell_settings)); + g_return_if_fail (cal_model->priv->shell_settings == NULL); + + cal_model->priv->shell_settings = g_object_ref (shell_settings); +} + +static void +cal_model_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_SETTINGS: + cal_model_set_shell_settings ( + E_CAL_MODEL (object), + g_value_get_object (value)); + return; + + case PROP_TIMEZONE: + e_cal_model_set_timezone ( + E_CAL_MODEL (object), + g_value_get_pointer (value)); + return; + + case PROP_USE_24_HOUR_FORMAT: + e_cal_model_set_use_24_hour_format ( + E_CAL_MODEL (object), + g_value_get_boolean (value)); + return; + + case PROP_WEEK_START_DAY: + e_cal_model_set_week_start_day ( + E_CAL_MODEL (object), + g_value_get_int (value)); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_model_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec) +{ + switch (property_id) { + case PROP_SHELL_SETTINGS: + g_value_set_object ( + value, + e_cal_model_get_shell_settings ( + E_CAL_MODEL (object))); + return; + + case PROP_TIMEZONE: + g_value_set_pointer ( + value, + e_cal_model_get_timezone ( + E_CAL_MODEL (object))); + return; + + case PROP_USE_24_HOUR_FORMAT: + g_value_set_boolean ( + value, + e_cal_model_get_use_24_hour_format ( + E_CAL_MODEL (object))); + return; + + case PROP_WEEK_START_DAY: + g_value_set_int ( + value, + e_cal_model_get_week_start_day ( + E_CAL_MODEL (object))); + return; + } + + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); +} + +static void +cal_model_dispose (GObject *object) { - GObjectClass *object_class = G_OBJECT_CLASS (klass); - ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass); + ECalModelPrivate *priv; + + priv = E_CAL_MODEL_GET_PRIVATE (object); + + if (priv->shell_settings != NULL) { + g_object_unref (priv->shell_settings); + priv->shell_settings = NULL; + } - object_class->dispose = e_cal_model_dispose; - object_class->finalize = e_cal_model_finalize; + if (priv->clients) { + while (priv->clients != NULL) { + ECalModelClient *client_data = (ECalModelClient *) priv->clients->data; + + g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + if (client_data->query) + g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, + 0, 0, NULL, NULL, object); + + priv->clients = g_list_remove (priv->clients, client_data); + + g_object_unref (client_data->client); + if (client_data->query) + g_object_unref (client_data->query); + g_free (client_data); + } + + priv->clients = NULL; + priv->default_client = NULL; + } + + /* Chain up to parent's dispose() method. */ + G_OBJECT_CLASS (parent_class)->dispose (object); +} +static void +cal_model_finalize (GObject *object) +{ + ECalModelPrivate *priv; + gint ii; + + priv = E_CAL_MODEL_GET_PRIVATE (object); + + g_free (priv->search_sexp); + g_free (priv->full_sexp); + + g_free (priv->default_category); + + for (ii = 0; ii < priv->objects->len; ii++) { + ECalModelComponent *comp_data; + + comp_data = g_ptr_array_index (priv->objects, ii); + if (comp_data == NULL) { + g_warning ("comp_data is null\n"); + continue; + } + e_cal_model_free_component_data (comp_data); + } + g_ptr_array_free (priv->objects, FALSE); + + g_mutex_free (priv->notify_lock); + + /* Chain up to parent's finalize() method. */ + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static void +cal_model_constructed (GObject *object) +{ + ECalModel *model; + EShellSettings *shell_settings; + + model = E_CAL_MODEL (object); + shell_settings = e_cal_model_get_shell_settings (model); + + e_binding_new ( + G_OBJECT (shell_settings), "cal-timezone", + G_OBJECT (model), "timezone"); + + e_binding_new ( + G_OBJECT (shell_settings), "cal-use-24-hour-format", + G_OBJECT (model), "use-24-hour-format"); + + e_binding_new ( + G_OBJECT (shell_settings), "cal-week-start-day", + G_OBJECT (model), "week-start-day"); +} + +static void +e_cal_model_class_init (ECalModelClass *class) +{ + GObjectClass *object_class; + ETableModelClass *etm_class; + + parent_class = g_type_class_peek_parent (class); + g_type_class_add_private (class, sizeof (ECalModelPrivate)); + + object_class = G_OBJECT_CLASS (class); + object_class->set_property = cal_model_set_property; + object_class->get_property = cal_model_get_property; + object_class->dispose = cal_model_dispose; + object_class->finalize = cal_model_finalize; + object_class->constructed = cal_model_constructed; + + etm_class = E_TABLE_MODEL_CLASS (class); etm_class->column_count = ecm_column_count; etm_class->row_count = ecm_row_count; etm_class->value_at = ecm_value_at; @@ -154,12 +351,54 @@ e_cal_model_class_init (ECalModelClass *klass) etm_class->value_is_empty = ecm_value_is_empty; etm_class->value_to_string = ecm_value_to_string; - klass->get_color_for_component = ecm_get_color_for_component; - klass->fill_component_from_model = NULL; + class->get_color_for_component = ecm_get_color_for_component; + class->fill_component_from_model = NULL; + + g_object_class_install_property ( + object_class, + PROP_SHELL_SETTINGS, + g_param_spec_object ( + "shell-settings", + _("Shell Settings"), + _("Application-wide settings"), + E_TYPE_SHELL_SETTINGS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property ( + object_class, + PROP_TIMEZONE, + g_param_spec_pointer ( + "timezone", + "Time Zone", + NULL, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_USE_24_HOUR_FORMAT, + g_param_spec_boolean ( + "use-24-hour-format", + "Use 24-Hour Format", + NULL, + TRUE, + G_PARAM_READWRITE)); + + g_object_class_install_property ( + object_class, + PROP_WEEK_START_DAY, + g_param_spec_int ( + "week-start-day", + "Week Start Day", + NULL, + 0, /* Monday */ + 6, /* Sunday */ + 0, + G_PARAM_READWRITE)); signals[TIME_RANGE_CHANGED] = g_signal_new ("time_range_changed", - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ECalModelClass, time_range_changed), NULL, NULL, @@ -168,7 +407,7 @@ e_cal_model_class_init (ECalModelClass *klass) signals[ROW_APPENDED] = g_signal_new ("row_appended", - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ECalModelClass, row_appended), NULL, NULL, @@ -177,7 +416,7 @@ e_cal_model_class_init (ECalModelClass *klass) signals[COMPS_DELETED] = g_signal_new ("comps_deleted", - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ECalModelClass, comps_deleted), NULL, NULL, @@ -186,7 +425,7 @@ e_cal_model_class_init (ECalModelClass *klass) signals[CAL_VIEW_PROGRESS] = g_signal_new ("cal_view_progress", - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ECalModelClass, cal_view_progress), NULL, NULL, @@ -194,7 +433,7 @@ e_cal_model_class_init (ECalModelClass *klass) G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT); signals[CAL_VIEW_DONE] = g_signal_new ("cal_view_done", - G_TYPE_FROM_CLASS (klass), + G_TYPE_FROM_CLASS (class), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (ECalModelClass, cal_view_done), NULL, NULL, @@ -206,112 +445,29 @@ e_cal_model_class_init (ECalModelClass *klass) static void e_cal_model_init (ECalModel *model) { - ECalModelPrivate *priv; - - priv = g_new0 (ECalModelPrivate, 1); - model->priv = priv; + model->priv = E_CAL_MODEL_GET_PRIVATE (model); /* match none by default */ - priv->start = -1; - priv->end = -1; - priv->search_sexp = NULL; - priv->full_sexp = g_strdup ("#f"); - - priv->objects = g_ptr_array_new (); - priv->kind = ICAL_NO_COMPONENT; - priv->flags = 0; - - priv->accounts = itip_addresses_get (); - - priv->use_24_hour_format = TRUE; - - priv->in_added = FALSE; - priv->in_modified = FALSE; - priv->in_removed = FALSE; - priv->notify_added = NULL; - priv->notify_modified = NULL; - priv->notify_removed = NULL; - priv->notify_lock = g_mutex_new (); -} - -static void -clear_objects_array (ECalModelPrivate *priv) -{ - gint i; - - for (i = 0; i < priv->objects->len; i++) { - ECalModelComponent *comp_data; - - comp_data = g_ptr_array_index (priv->objects, i); - if (comp_data == NULL) { - g_warning ("comp_data is null\n"); - continue; - } - e_cal_model_free_component_data (comp_data); - } - - g_ptr_array_set_size (priv->objects, 0); -} - -static void -e_cal_model_dispose (GObject *object) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) object; - - g_return_if_fail (E_IS_CAL_MODEL (model)); - - priv = model->priv; - - if (priv->clients) { - while (priv->clients != NULL) { - ECalModelClient *client_data = (ECalModelClient *) priv->clients->data; - - g_signal_handlers_disconnect_matched (client_data->client, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, model); - if (client_data->query) - g_signal_handlers_disconnect_matched (client_data->query, G_SIGNAL_MATCH_DATA, - 0, 0, NULL, NULL, model); - - priv->clients = g_list_remove (priv->clients, client_data); - - g_object_unref (client_data->client); - if (client_data->query) - g_object_unref (client_data->query); - g_free (client_data); - } + model->priv->start = -1; + model->priv->end = -1; + model->priv->search_sexp = NULL; + model->priv->full_sexp = g_strdup ("#f"); - priv->clients = NULL; - priv->default_client = NULL; - } + model->priv->objects = g_ptr_array_new (); + model->priv->kind = ICAL_NO_COMPONENT; + model->priv->flags = 0; - if (G_OBJECT_CLASS (e_cal_model_parent_class)->dispose) - G_OBJECT_CLASS (e_cal_model_parent_class)->dispose (object); -} + model->priv->accounts = itip_addresses_get (); -static void -e_cal_model_finalize (GObject *object) -{ - ECalModelPrivate *priv; - ECalModel *model = (ECalModel *) object; - - g_return_if_fail (E_IS_CAL_MODEL (model)); + model->priv->use_24_hour_format = TRUE; - priv = model->priv; - - g_free (priv->search_sexp); - g_free (priv->full_sexp); - - g_free (priv->default_category); - - clear_objects_array (priv); - g_ptr_array_free (priv->objects, FALSE); - g_mutex_free (priv->notify_lock); - - g_free (priv); - - if (G_OBJECT_CLASS (e_cal_model_parent_class)->finalize) - G_OBJECT_CLASS (e_cal_model_parent_class)->finalize (object); + model->priv->in_added = FALSE; + model->priv->in_modified = FALSE; + model->priv->in_removed = FALSE; + model->priv->notify_added = NULL; + model->priv->notify_modified = NULL; + model->priv->notify_removed = NULL; + model->priv->notify_lock = g_mutex_new (); } /* ETableModel methods */ @@ -1148,9 +1304,14 @@ ecm_get_color_for_component (ECalModel *model, ECalModelComponent *comp_data) return assigned_colors[first_empty].color; } -/** - * e_cal_model_get_component_kind - */ +EShellSettings * +e_cal_model_get_shell_settings (ECalModel *model) +{ + g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); + + return model->priv->shell_settings; +} + icalcomponent_kind e_cal_model_get_component_kind (ECalModel *model) { @@ -1162,9 +1323,6 @@ e_cal_model_get_component_kind (ECalModel *model) return priv->kind; } -/** - * e_cal_model_set_component_kind - */ void e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind) { @@ -1176,82 +1334,59 @@ e_cal_model_set_component_kind (ECalModel *model, icalcomponent_kind kind) priv->kind = kind; } -/** - * e_cal_model_get_flags - */ ECalModelFlags e_cal_model_get_flags (ECalModel *model) { - ECalModelPrivate *priv; - - g_return_val_if_fail (E_IS_CAL_MODEL (model), E_CAL_MODEL_FLAGS_INVALID); + g_return_val_if_fail (E_IS_CAL_MODEL (model), 0); - priv = model->priv; - return priv->flags; + return model->priv->flags; } -/** - * e_cal_model_set_flags - */ void e_cal_model_set_flags (ECalModel *model, ECalModelFlags flags) { - ECalModelPrivate *priv; - g_return_if_fail (E_IS_CAL_MODEL (model)); - priv = model->priv; - priv->flags = flags; + model->priv->flags = flags; } -/** - * e_cal_model_get_timezone - */ icaltimezone * e_cal_model_get_timezone (ECalModel *model) { g_return_val_if_fail (E_IS_CAL_MODEL (model), NULL); + return model->priv->zone; } -/** - * e_cal_model_set_timezone - */ void -e_cal_model_set_timezone (ECalModel *model, icaltimezone *zone) +e_cal_model_set_timezone (ECalModel *model, + icaltimezone *zone) { - ECalModelPrivate *priv; - g_return_if_fail (E_IS_CAL_MODEL (model)); - priv = model->priv; - if (priv->zone != zone) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - priv->zone = zone; + if (model->priv->zone == zone) + return; - /* the timezone affects the times shown for date fields, - so we need to redisplay everything */ - e_table_model_changed (E_TABLE_MODEL (model)); - } + e_table_model_pre_change (E_TABLE_MODEL (model)); + model->priv->zone = zone; + + /* the timezone affects the times shown for date fields, + so we need to redisplay everything */ + e_table_model_changed (E_TABLE_MODEL (model)); + + g_object_notify (G_OBJECT (model), "timezone"); } -/** - * e_cal_model_set_default_category - */ void -e_cal_model_set_default_category (ECalModel *model, const gchar *default_cat) +e_cal_model_set_default_category (ECalModel *model, + const gchar *default_category) { g_return_if_fail (E_IS_CAL_MODEL (model)); - if (model->priv->default_category) - g_free (model->priv->default_category); - - model->priv->default_category = g_strdup (default_cat); + g_free (model->priv->default_category); + model->priv->default_category = g_strdup (default_category); } -/** - * e_cal_model_get_use_24_hour_format - */ gboolean e_cal_model_get_use_24_hour_format (ECalModel *model) { @@ -1260,25 +1395,48 @@ e_cal_model_get_use_24_hour_format (ECalModel *model) return model->priv->use_24_hour_format; } -/** - * e_cal_model_set_use_24_hour_format - */ void -e_cal_model_set_use_24_hour_format (ECalModel *model, gboolean use24) +e_cal_model_set_use_24_hour_format (ECalModel *model, + gboolean use_24_hour_format) { g_return_if_fail (E_IS_CAL_MODEL (model)); - if (model->priv->use_24_hour_format != use24) { - e_table_model_pre_change (E_TABLE_MODEL (model)); - model->priv->use_24_hour_format = use24; - /* Get the views to redraw themselves. */ - e_table_model_changed (E_TABLE_MODEL (model)); - } + if (model->priv->use_24_hour_format == use_24_hour_format) + return; + + e_table_model_pre_change (E_TABLE_MODEL (model)); + model->priv->use_24_hour_format = use_24_hour_format; + + /* Get the views to redraw themselves. */ + e_table_model_changed (E_TABLE_MODEL (model)); + + g_object_notify (G_OBJECT (model), "use-24-hour-format"); +} + +gint +e_cal_model_get_week_start_day (ECalModel *model) +{ + g_return_val_if_fail (E_IS_CAL_MODEL (model), 0); + + return model->priv->week_start_day; +} + +void +e_cal_model_set_week_start_day (ECalModel *model, + gint week_start_day) +{ + g_return_if_fail (E_IS_CAL_MODEL (model)); + g_return_if_fail (week_start_day >= 0); + g_return_if_fail (week_start_day < 7); + + if (model->priv->week_start_day == week_start_day) + return; + + model->priv->week_start_day = week_start_day; + + g_object_notify (G_OBJECT (model), "week-start-day"); } -/** - * e_cal_model_get_default_client - */ ECal * e_cal_model_get_default_client (ECalModel *model) { @@ -1334,9 +1492,6 @@ e_cal_model_set_default_client (ECalModel *model, ECal *client) priv->default_client = client_data->client; } -/** - * e_cal_model_get_client_list - */ GList * e_cal_model_get_client_list (ECalModel *model) { @@ -1354,7 +1509,7 @@ e_cal_model_get_client_list (ECalModel *model) } /** - * e_cal_model_get_client_for_uri + * e_cal_model_get_client_for_uri: * @model: A calendar model. * @uri: Uri for the client to get. */ @@ -1486,14 +1641,16 @@ add_instance_cb (ECalComponent *comp, time_t instance_start, time_t instance_end return TRUE; } -/* We do this check since the calendar items are downloaded from the server in the open_method, - since the default timezone might not be set there */ +/* We do this check since the calendar items are downloaded from the server + * in the open_method, since the default timezone might not be set there. */ static void -ensure_dates_are_in_default_zone (icalcomponent *icalcomp) +ensure_dates_are_in_default_zone (ECalModel *model, + icalcomponent *icalcomp) { icaltimetype dt; - icaltimezone *zone = calendar_config_get_icaltimezone (); + icaltimezone *zone; + zone = e_cal_model_get_timezone (model); if (!zone) return; @@ -1557,7 +1714,7 @@ process_added (ECalView *query, GList *objects, ECalModel *model) e_cal_component_free_id (id); g_object_unref (comp); - ensure_dates_are_in_default_zone (l->data); + ensure_dates_are_in_default_zone (model, l->data); if (e_cal_util_component_has_recurrences (l->data) && (priv->flags & E_CAL_MODEL_FLAGS_EXPAND_RECURRENCES)) { RecurrenceExpansionData rdata; @@ -2440,17 +2597,17 @@ struct _ECalModelComponentPrivate { static void e_cal_model_component_finalize (GObject *object); -static GObjectClass *parent_class; +static GObjectClass *component_parent_class; /* Class initialization function for the calendar component object */ static void -e_cal_model_component_class_init (ECalModelComponentClass *klass) +e_cal_model_component_class_init (ECalModelComponentClass *class) { GObjectClass *object_class; - object_class = (GObjectClass *) klass; + object_class = (GObjectClass *) class; - parent_class = g_type_class_peek_parent (klass); + component_parent_class = g_type_class_peek_parent (class); object_class->finalize = e_cal_model_component_finalize; } @@ -2497,8 +2654,8 @@ e_cal_model_component_finalize (GObject *object) comp_data->color = NULL; } - if (G_OBJECT_CLASS (parent_class)->finalize) - (* G_OBJECT_CLASS (parent_class)->finalize) (object); + if (G_OBJECT_CLASS (component_parent_class)->finalize) + (* G_OBJECT_CLASS (component_parent_class)->finalize) (object); } /* Object initialization function for the calendar component object */ |