aboutsummaryrefslogblamecommitdiffstats
path: root/calendar/gui/e-cal-model-calendar.c
blob: 73ecaf3e9408a3e3633896bf603ab3c490d1753b (plain) (tree)






































                                                                                      





                                                                                   


                                                                                            









                                                                                           
                                                                








                                                            




                                                            

                                                                                




































































































































































































































































                                                                                                                 
































































































                                                                                             

















                                                                                                                               







                                                              
/* Evolution calendar - Data model for ETable
 *
 * Copyright (C) 2000 Ximian, Inc.
 * Copyright (C) 2000 Ximian, Inc.
 *
 * Authors: Rodrigo Moya <rodrigo@ximian.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

#include <config.h>
#include <string.h>
#include <libgnome/gnome-i18n.h>
#include <gal/util/e-util.h>
#include "e-cal-model-calendar.h"
#include "e-cell-date-edit-text.h"
#include "misc.h"

struct _ECalModelCalendarPrivate {
};

static void ecmc_class_init (ECalModelCalendarClass *klass);
static void ecmc_init (ECalModelCalendar *model, ECalModelCalendarClass *klass);
static void ecmc_finalize (GObject *object);
static int ecmc_column_count (ETableModel *etm);
static void *ecmc_value_at (ETableModel *etm, int col, int row);
static void ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value);
static gboolean ecmc_is_cell_editable (ETableModel *etm, int col, int row);
static void *ecmc_duplicate_value (ETableModel *etm, int col, const void *value);
static void ecmc_free_value (ETableModel *etm, int col, void *value);
static void *ecmc_initialize_value (ETableModel *etm, int col);
static gboolean ecmc_value_is_empty (ETableModel *etm, int col, const void *value);
static char *ecmc_value_to_string (ETableModel *etm, int col, const void *value);

static void ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
                        ECalModel *source_model, gint row);

static GObjectClass *parent_class = NULL;

E_MAKE_TYPE (e_cal_model_calendar, "ECalModelCalendar", ECalModelCalendar, ecmc_class_init,
         ecmc_init, E_TYPE_CAL_MODEL);

static void
ecmc_class_init (ECalModelCalendarClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
    ETableModelClass *etm_class = E_TABLE_MODEL_CLASS (klass);
    ECalModelClass *model_class = E_CAL_MODEL_CLASS (klass);

    parent_class = g_type_class_peek_parent (klass);

    object_class->finalize = ecmc_finalize;

    etm_class->column_count = ecmc_column_count;
    etm_class->value_at = ecmc_value_at;
    etm_class->set_value_at = ecmc_set_value_at;
    etm_class->is_cell_editable = ecmc_is_cell_editable;
    etm_class->duplicate_value = ecmc_duplicate_value;
    etm_class->free_value = ecmc_free_value;
    etm_class->initialize_value = ecmc_initialize_value;
    etm_class->value_is_empty = ecmc_value_is_empty;
    etm_class->value_to_string = ecmc_value_to_string;

    model_class->fill_component_from_model = ecmc_fill_component_from_model;
}

static void
ecmc_init (ECalModelCalendar *model, ECalModelCalendarClass *klass)
{
    ECalModelCalendarPrivate *priv;

    priv = g_new0 (ECalModelCalendarPrivate, 1);
    model->priv = priv;

    e_cal_model_set_component_kind (E_CAL_MODEL (model), ICAL_VEVENT_COMPONENT);
}

static void
ecmc_finalize (GObject *object)
{
    ECalModelCalendarPrivate *priv;
    ECalModelCalendar *model = (ECalModelCalendar *) object;

    g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));

    priv = model->priv;
    if (priv) {
        g_free (priv);
        model->priv = NULL;
    }

    if (parent_class->finalize)
        parent_class->finalize (object);
}

/* ETableModel methods */
static int
ecmc_column_count (ETableModel *etm)
{
    return E_CAL_MODEL_CALENDAR_FIELD_LAST;
}

static ECellDateEditValue *
get_dtend (ECalModelComponent *comp_data)
{
    struct icaltimetype tt_end;

    if (!comp_data->dtend) {
        icaltimezone *zone;

        tt_end = icalcomponent_get_dtend (comp_data->icalcomp);
        if (!icaltime_is_valid_time (tt_end))
            return NULL;

        comp_data->dtend = g_new0 (ECellDateEditValue, 1);
        comp_data->dtend->tt = tt_end;

        /* FIXME: handle errors */
        cal_client_get_timezone (comp_data->client,
                     icaltimezone_get_tzid (icaltimezone_get_builtin_timezone (tt_end.zone)),
                     &zone);
        comp_data->dtend->zone = zone;
    }

    return comp_data->dtend;
}

static void *
get_location (ECalModelComponent *comp_data)
{
    icalproperty *prop;

    prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY);
    if (prop)
        return (void *) icalproperty_get_location (prop);

    return NULL;
}

static void *
get_transparency (ECalModelComponent *comp_data)
{
    icalproperty *prop;

    prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY);
    if (prop) {
        const char *transp;

        transp = icalproperty_get_transp (prop);
        if (strcasecmp (transp, "TRANSPARENT") == 0)
            return _("Free");
        else if (strcasecmp (transp, "OPAQUE") == 0)
            return _("Busy");
    }

    return NULL;
}

static void *
ecmc_value_at (ETableModel *etm, int col, int row)
{
    ECalModelComponent *comp_data;
    ECalModelCalendarPrivate *priv;
    ECalModelCalendar *model = (ECalModelCalendar *) etm;

    g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), NULL);

    priv = model->priv;

    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);
    g_return_val_if_fail (row >= 0 && row < e_table_model_row_count (etm), NULL);

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->value_at (etm, col, row);

    comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
    if (!comp_data)
        return "";

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        return get_dtend (comp_data);
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        return get_location (comp_data);
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return get_transparency (comp_data);
    }

    return "";
}

static void
set_dtend (ECalModelComponent *comp_data, const void *value)
{
    icalproperty *prop;
    ECellDateEditValue *dv = (ECellDateEditValue *) value;

    prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_DTEND_PROPERTY);
    if (!dv) {
        if (prop) {
            icalcomponent_remove_property (comp_data->icalcomp, prop);
            icalproperty_free (prop);
        }
    } else
        icalcomponent_set_dtend (comp_data->icalcomp, dv->tt);
}

static void
set_location (ECalModelComponent *comp_data, const void *value)
{
    icalproperty *prop;

    prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_LOCATION_PROPERTY);

    if (string_is_empty (value)) {
        if (prop) {
            icalcomponent_remove_property (comp_data->icalcomp, prop);
            icalproperty_free (prop);
        }
    } else {
        if (prop)
            icalproperty_set_location (prop, (const char *) value);
        else {
            prop = icalproperty_new_location ((const char *) value);
            icalcomponent_add_property (comp_data->icalcomp, prop);
        }
    }
}

static void
set_transparency (ECalModelComponent *comp_data, const void *value)
{
    icalproperty *prop;

    prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_TRANSP_PROPERTY);

    if (string_is_empty (value)) {
        if (prop) {
            icalcomponent_remove_property (comp_data->icalcomp, prop);
            icalproperty_free (prop);
        }
    } else {
        const char *transp;

        if (strcasecmp (value, "FREE"))
            transp = "TRANSPARENT";
        else if (strcasecmp (value, "OPAQUE"))
            transp = "OPAQUE";
        else {
            if (prop) {
                icalcomponent_remove_property (comp_data->icalcomp, prop);
                icalproperty_free (prop);
            }

            return;
        }

        if (prop)
            icalproperty_set_transp (prop, transp);
        else {
            prop = icalproperty_new_transp (transp);
            icalcomponent_add_property (comp_data->icalcomp, prop);
        }
    }
}

static void
ecmc_set_value_at (ETableModel *etm, int col, int row, const void *value)
{
    ECalModelComponent *comp_data;
    ECalModelCalendar *model = (ECalModelCalendar *) etm;

    g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
    g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);
    g_return_if_fail (row >= 0 && row < e_table_model_row_count (etm));

    if (col < E_CAL_MODEL_FIELD_LAST) {
        E_TABLE_MODEL_CLASS (parent_class)->set_value_at (etm, col, row, value);
        return;
    }

    comp_data = e_cal_model_get_component_at (E_CAL_MODEL (model), row);
    if (!comp_data)
        return;

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        set_dtend (comp_data, value);
        break;
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
        set_location (comp_data, value);
        break;
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        set_transparency (comp_data, value);
        break;
    }

    if (cal_client_update_objects (comp_data->client, comp_data->icalcomp) != CAL_CLIENT_RESULT_SUCCESS)
        g_message ("ecmc_set_value_at(): Could not update the object!");
}

static gboolean
ecmc_is_cell_editable (ETableModel *etm, int col, int row)
{
    ECalModelCalendar *model = (ECalModelCalendar *) etm;

    g_return_val_if_fail (E_IS_CAL_MODEL_CALENDAR (model), FALSE);
    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, FALSE);

    /* FIXME: We can't check this as 'click-to-add' passes row 0. */
    /* g_return_val_if_fail (row >= 0 && row < e_table_model_get_row_count (etm), FALSE); */

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->is_cell_editable (etm, col, row);

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return TRUE;
    }

    return FALSE;
}

static void *
ecmc_duplicate_value (ETableModel *etm, int col, const void *value)
{
    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->duplicate_value (etm, col, value);

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        /* FIXME */
        break;
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return g_strdup (value);
    }

    return NULL;
}

static void
ecmc_free_value (ETableModel *etm, int col, void *value)
{
    g_return_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST);

    if (col < E_CAL_MODEL_FIELD_LAST) {
        E_TABLE_MODEL_CLASS (parent_class)->free_value (etm, col, value);
        return;
    }

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        if (value)
            g_free (value);
        break;
    }
}

static void *
ecmc_initialize_value (ETableModel *etm, int col)
{
    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->initialize_value (etm, col);

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        return NULL;
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return g_strdup ("");
    }

    return NULL;
}

static gboolean
ecmc_value_is_empty (ETableModel *etm, int col, const void *value)
{
    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, TRUE);

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->value_is_empty (etm, col, value);

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        return value ? FALSE : TRUE;
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return string_is_empty (value);
    }

    return TRUE;
}

static char *
ecmc_value_to_string (ETableModel *etm, int col, const void *value)
{
    g_return_val_if_fail (col >= 0 && col < E_CAL_MODEL_CALENDAR_FIELD_LAST, NULL);

    if (col < E_CAL_MODEL_FIELD_LAST)
        return E_TABLE_MODEL_CLASS (parent_class)->value_to_string (etm, col, value);

    switch (col) {
    case E_CAL_MODEL_CALENDAR_FIELD_DTEND :
        return e_cal_model_date_value_to_string (E_CAL_MODEL (etm), value);
    case E_CAL_MODEL_CALENDAR_FIELD_LOCATION :
    case E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY :
        return g_strdup (value);
    }

    return NULL;
}

/* ECalModel class methods */

static void
ecmc_fill_component_from_model (ECalModel *model, ECalModelComponent *comp_data,
                ECalModel *source_model, gint row)
{
    g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (model));
    g_return_if_fail (comp_data != NULL);
    g_return_if_fail (E_IS_CAL_MODEL_CALENDAR (source_model));

    set_dtend (comp_data,
           e_table_model_value_at (E_TABLE_MODEL (source_model), E_CAL_MODEL_CALENDAR_FIELD_DTEND, row));
    set_location (comp_data,
              e_table_model_value_at (E_TABLE_MODEL (source_model), E_CAL_MODEL_CALENDAR_FIELD_LOCATION, row));
    set_transparency (comp_data,
              e_table_model_value_at (E_TABLE_MODEL (source_model), E_CAL_MODEL_CALENDAR_FIELD_TRANSPARENCY, row));
}

/**
 * e_cal_model_calendar_new
 */
ECalModelCalendar *
e_cal_model_calendar_new (void)
{
    return g_object_new (E_TYPE_CAL_MODEL_CALENDAR, NULL);
}