/*
 * Matches a location to a system timezone definition via a fuzzy
 * search and returns the matching TZID, or NULL if none found.
 *
 * Currently simply strips a suffix introduced by a hyphen,
 * as in "America/Denver-(Standard)".
 */
static const gchar *
e_cal_match_location (const gchar *location)
{
	icaltimezone *icomp;
	const gchar *tail;
	gsize len;
	gchar *buffer;

	icomp = icaltimezone_get_builtin_timezone (location);
	if (icomp) {
		return icaltimezone_get_tzid (icomp);
	}

	/* try a bit harder by stripping trailing suffix */
	tail = strrchr (location, '-');
	len = tail ? (tail - location) : strlen (location);
	buffer = g_malloc (len + 1);

	if (buffer) {
		memcpy (buffer, location, len);
		buffer[len] = 0;
		icomp = icaltimezone_get_builtin_timezone (buffer);
		g_free (buffer);
		if (icomp) {
			return icaltimezone_get_tzid (icomp);
		}
	}

	return NULL;
}
Example #2
0
const char *icaltime_get_tzid(const struct icaltimetype t)
{
    if (t.zone != NULL) {
        return icaltimezone_get_tzid((icaltimezone *) t.zone);
    } else {
        return NULL;
    }
}
Example #3
0
/**
 * e_cal_util_event_dates_match:
 * @icalcomp1: An #icalcomponent.
 * @icalcomp2: An #icalcomponent.
 *
 * Compare the dates of two #icalcomponent's to check if they match.
 *
 * Returns: TRUE if the dates of both components match, FALSE otherwise.
 */
gboolean
e_cal_util_event_dates_match (icalcomponent *icalcomp1,
                              icalcomponent *icalcomp2)
{
	struct icaltimetype c1_dtstart, c1_dtend, c2_dtstart, c2_dtend;

	g_return_val_if_fail (icalcomp1 != NULL, FALSE);
	g_return_val_if_fail (icalcomp2 != NULL, FALSE);

	c1_dtstart = icalcomponent_get_dtstart (icalcomp1);
	c1_dtend = icalcomponent_get_dtend (icalcomp1);
	c2_dtstart = icalcomponent_get_dtstart (icalcomp2);
	c2_dtend = icalcomponent_get_dtend (icalcomp2);

	/* if either value is NULL, they must both be NULL to match */
	if (icaltime_is_valid_time (c1_dtstart) || icaltime_is_valid_time (c2_dtstart)) {
		if (!(icaltime_is_valid_time (c1_dtstart) && icaltime_is_valid_time (c2_dtstart)))
			return FALSE;
	} else {
		if (icaltime_compare (c1_dtstart, c2_dtstart))
			return FALSE;
	}

	if (icaltime_is_valid_time (c1_dtend) || icaltime_is_valid_time (c2_dtend)) {
		if (!(icaltime_is_valid_time (c1_dtend) && icaltime_is_valid_time (c2_dtend)))
			return FALSE;
	} else {
		if (icaltime_compare (c1_dtend, c2_dtend))
			return FALSE;
	}

	/* now match the timezones */
	if (!(!c1_dtstart.zone && !c2_dtstart.zone) ||
	    (c1_dtstart.zone && c2_dtstart.zone &&
	     !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtstart.zone),
		      icaltimezone_get_tzid ((icaltimezone *) c2_dtstart.zone))))
		return FALSE;

	if (!(!c1_dtend.zone && !c2_dtend.zone) ||
	    (c1_dtend.zone && c2_dtend.zone &&
	     !strcmp (icaltimezone_get_tzid ((icaltimezone *) c1_dtend.zone),
		      icaltimezone_get_tzid ((icaltimezone *) c2_dtend.zone))))
		return FALSE;

	return TRUE;
}
void calDateTime::FromIcalTime(icaltimetype const* icalt, calITimezone * tz)
{
    icaltimetype t = *icalt;
    mIsValid = (icaltime_is_null_time(t) ||
                icaltime_is_valid_time(t) ? true : false);

    mIsDate = t.is_date ? true : false;
    if (mIsDate) {
        t.hour = 0;
        t.minute = 0;
        t.second = 0;
    }

    if (mIsValid) {
        t = icaltime_normalize(t);
    }

    mYear = static_cast<int16_t>(t.year);
    mMonth = static_cast<int16_t>(t.month - 1);
    mDay = static_cast<int16_t>(t.day);
    mHour = static_cast<int16_t>(t.hour);
    mMinute = static_cast<int16_t>(t.minute);
    mSecond = static_cast<int16_t>(t.second);

    if (tz) {
        mTimezone = tz;
    } else {
        mTimezone = cal::detectTimezone(t, nullptr);
    }
#if defined(DEBUG)
    if (mTimezone) {
        if (t.is_utc) {
            nsCOMPtr<calITimezone> ctz = cal::UTC();
            NS_ASSERTION(SameCOMIdentity(mTimezone, ctz), "UTC mismatch!");
        } else if (!t.zone) {
            nsAutoCString tzid;
            mTimezone->GetTzid(tzid);
            if (tzid.EqualsLiteral("floating")) {
                nsCOMPtr<calITimezone> ctz = cal::floating();
                NS_ASSERTION(SameCOMIdentity(mTimezone, ctz), "floating mismatch!");
            }
        } else {
            nsAutoCString tzid;
            mTimezone->GetTzid(tzid);
            NS_ASSERTION(tzid.Equals(icaltimezone_get_tzid(const_cast<icaltimezone *>(t.zone))),
                         "tzid mismatch!");
        }
    }
#endif

    mWeekday = static_cast<int16_t>(icaltime_day_of_week(t) - 1);
    mYearday = static_cast<int16_t>(icaltime_day_of_year(t));

    // mNativeTime: not moving the existing date to UTC,
    // but merely representing it a UTC-based way.
    t.is_date = 0;
    mNativeTime = IcaltimeToPRTime(&t, icaltimezone_get_utc_timezone());
}
gint
main (gint argc,
      gchar **argv)
{
	ECal *cal;
	gchar *uri = NULL;
	icalproperty *property;
	icalcomponent *component;
	icaltimezone *zone;
	icaltimezone *zone_final;

	g_type_init ();

	cal = ecal_test_utils_cal_new_temp (&uri, E_CAL_SOURCE_TYPE_EVENT);
	ecal_test_utils_cal_open (cal, FALSE);

	/* Build up new timezone */
	component = icalcomponent_new_vtimezone ();
	property = icalproperty_new_tzid (TZID_NEW);
	icalcomponent_add_property (component, property);
	property = icalproperty_new_tzname (TZNAME_NEW);
	icalcomponent_add_property (component, property);
	zone = icaltimezone_new ();
	icaltimezone_set_component (zone, component);

	/* add */
	ecal_test_utils_cal_add_timezone (cal, zone);

	/* verify */
	zone_final = ecal_test_utils_cal_get_timezone (cal, TZID_NEW);
	g_assert (!g_strcmp0 (icaltimezone_get_tzid (zone),
			icaltimezone_get_tzid (zone_final)));
	g_assert (!g_strcmp0 (icaltimezone_get_tznames (zone),
			icaltimezone_get_tznames (zone_final)));

	ecal_test_utils_cal_remove (cal);
	icaltimezone_free (zone, TRUE);

	return 0;
}
nsresult calIcalProperty::setDatetime_(calIcalComponent * parent,
                                       icalproperty * prop,
                                       calIDateTime * dt)
{
    NS_ENSURE_ARG_POINTER(prop);
    NS_ENSURE_ARG_POINTER(dt);

    nsresult rv;
    nsCOMPtr<calIDateTimeLibical> icaldt = do_QueryInterface(dt, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    icaltimetype itt;
    icaldt->ToIcalTime(&itt);

    if (parent) {
        if (!itt.is_utc) {
            nsCOMPtr<calITimezone> tz;
            rv = dt->GetTimezone(getter_AddRefs(tz));
            NS_ENSURE_SUCCESS(rv, rv);
            if (itt.zone) {
                rv = parent->getParentVCalendarOrThis()->AddTimezoneReference(tz);
                NS_ENSURE_SUCCESS(rv, rv);
                icalparameter * const param = icalparameter_new_from_value_string(
                    ICAL_TZID_PARAMETER, icaltimezone_get_tzid(const_cast<icaltimezone *>(itt.zone)));
                icalproperty_set_parameter(prop, param);
            } else { // either floating or phantom:
                bool b = false;
                if (NS_FAILED(tz->GetIsFloating(&b)) || !b) {
                    // restore the same phantom TZID:
                    nsAutoCString tzid;
                    rv = tz->GetTzid(tzid);
                    NS_ENSURE_SUCCESS(rv, rv);
                    icalparameter * const param = icalparameter_new_from_value_string(ICAL_TZID_PARAMETER,
                                                                                      tzid.get());
                    icalproperty_set_parameter(prop, param);
                }
            }
        }
    } else if (!itt.is_date && !itt.is_utc && itt.zone) {
        // no parent to add the CTIMEZONE to: coerce DATETIMEs to UTC, DATEs to floating
        icaltimezone_convert_time(&itt,
                                  const_cast<icaltimezone *>(itt.zone),
                                  icaltimezone_get_utc_timezone());
        itt.zone = icaltimezone_get_utc_timezone();
        itt.is_utc = 1;
    }

    icalvalue * const val = icalvalue_new_datetime(itt);
    CAL_ENSURE_MEMORY(val);
    icalproperty_set_value(prop, val);
    return NS_OK;
}
const char* ictt_as_string(struct icaltimetype t)
{
    const char *zone = icaltimezone_get_tzid((icaltimezone *)t.zone);

    if (icaltime_is_utc(t))
	sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d Z UTC",
	t.year,t.month,t.day, t.hour,t.minute,t.second);
    else
	sprintf(ictt_str,"%02d-%02d-%02d %02d:%02d:%02d %s",
	t.year,t.month,t.day, t.hour,t.minute,t.second,
	zone == NULL? "(floating)": zone);

    return ictt_str;
}
static gchar *
test_timezones (ECal *client)
{
	icaltimezone *zone;
	GError *error = NULL;
	if (!e_cal_get_timezone (client, "UTC", &zone, &error))
	{
		cl_printf (client, "Could not get the timezone\n");
	}

	printf ("\n\nTime Zones : \n%s *** %s", icaltimezone_get_display_name (zone), icaltimezone_get_tzid (zone));
	printf ("\n\nTime Zones : \n%s", icaltimezone_get_location (zone));

	return NULL;
}
/** Returns a single builtin timezone, given its TZID. */
icaltimezone*
icaltimezone_get_builtin_timezone_from_tzid (const char *tzid)
{
    int num_slashes = 0;
    const char *p, *zone_tzid;
    icaltimezone *zone;

    if (!tzid || !tzid[0])
	return NULL;

    /* Check that the TZID starts with our unique prefix. */
    if (strncmp (tzid, TZID_PREFIX, TZID_PREFIX_LEN))
	return NULL;

    /* Get the location, which is after the 3rd '/' character. */
    p = tzid;
    for (p = tzid; *p; p++) {
	if (*p == '/') {
	    num_slashes++;
	    if (num_slashes == 3)
		break;
	}
    }

    if (num_slashes != 3)
	return NULL;

    p++;

    /* Now we can use the function to get the builtin timezone from the
       location string. */
    zone = icaltimezone_get_builtin_timezone (p);
    if (!zone)
	return NULL;

    /* Check that the builtin TZID matches exactly. We don't want to return
       a different version of the VTIMEZONE. */
    zone_tzid = icaltimezone_get_tzid (zone);
    if (!strcmp (zone_tzid, tzid))
	return zone;
    else
	return NULL;
}
Example #10
0
static void task_set_due_date (JanaTask *self, JanaTime *time)
{
	ECalComponent *comp;
	icaltimetype *itime;
	ECalComponentDateTime dt;

	g_object_get (time, "icaltime", &itime, NULL);
	dt.value = itime;

	if (icaltime_is_utc (*itime))
		dt.tzid = "UTC";
	else
		dt.tzid = (const char *)icaltimezone_get_tzid (
			(icaltimezone *)itime->zone);

	g_object_get (self, "ecalcomp", &comp, NULL);
	e_cal_component_set_due (comp, &dt);
	g_object_unref (comp);
}
Example #11
0
/**
 * build_component_from_details:
 * @summary:
 * @initial_date:
 * @final_date:
 *
 * Create a component with the provided details
 *
 * Returns: (Transfer full): an {@link ECalComponent} object
 **/
ECalComponent*
build_component_from_details (const gchar *summary,
                              GDateTime   *initial_date,
                              GDateTime   *final_date)
{
  ECalComponent *event;
  ECalComponentDateTime dt;
  ECalComponentText summ;
  icaltimezone *zone;
  gboolean all_day;

  event = e_cal_component_new ();
  e_cal_component_set_new_vtype (event, E_CAL_COMPONENT_EVENT);

  /*
   * Check if the event is all day. Notice that it can be all day even
   * without the final date.
   */
  all_day = datetime_is_date (initial_date) && (final_date ? datetime_is_date (final_date) : TRUE);

  /*
   * When the event is all day, we consider UTC timezone by default. Otherwise,
   * we always use the system timezone to create new events
   */
  if (all_day)
    {
      zone = icaltimezone_get_utc_timezone ();
    }
  else
    {
      gchar *system_tz = e_cal_system_timezone_get_location ();

      zone = icaltimezone_get_builtin_timezone (system_tz);

      g_free (system_tz);
    }

  /* Start date */
  dt.value = datetime_to_icaltime (initial_date);
  icaltime_set_timezone (dt.value, zone);
  dt.value->is_date = all_day;
  dt.tzid = icaltimezone_get_tzid (zone);
  e_cal_component_set_dtstart (event, &dt);

  g_free (dt.value);

  /* End date */
  if (!final_date)
    final_date = g_date_time_add_days (initial_date, 1);

  dt.value = datetime_to_icaltime (final_date);
  icaltime_set_timezone (dt.value, zone);
  dt.value->is_date = all_day;
  dt.tzid = icaltimezone_get_tzid (zone);
  e_cal_component_set_dtend (event, &dt);

  g_free (dt.value);

  /* Summary */
  summ.altrep = NULL;
  summ.value = summary;
  e_cal_component_set_summary (event, &summ);

  e_cal_component_commit_sequence (event);

  return event;
}
Example #12
0
static GtkWidget *
ical_get_preview (icalcomponent *icalcomp)
{
	GtkWidget *preview;
	GtkTreeView *tree_view;
	GtkTreeSelection *selection;
	GtkListStore *store;
	GtkTreeIter iter;
	GHashTable *timezones;
	icalcomponent *subcomp;
	icaltimezone *users_zone;

	if (!icalcomp || !is_icalcomp_usable (icalcomp))
		return NULL;

	store = gtk_list_store_new (4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, E_TYPE_CAL_COMPONENT);

	timezones = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, free_zone_cb);
	users_zone = get_users_timezone ();

	/* get timezones first */
	for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_VTIMEZONE_COMPONENT);
	     subcomp;
	     subcomp = icalcomponent_get_next_component (icalcomp,  ICAL_VTIMEZONE_COMPONENT)) {
		icaltimezone *zone = icaltimezone_new ();
		if (!icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp)) || !icaltimezone_get_tzid (zone)) {
			icaltimezone_free (zone, 1);
		} else {
			g_hash_table_insert (timezones, (gchar *) icaltimezone_get_tzid (zone), zone);
		}
	}

	/* then each component */
	for (subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT);
	     subcomp;
	     subcomp = icalcomponent_get_next_component (icalcomp,  ICAL_ANY_COMPONENT)) {
		icalcomponent_kind kind = icalcomponent_isa (subcomp);

		if (kind == ICAL_VEVENT_COMPONENT ||
		    kind == ICAL_VTODO_COMPONENT ||
		    kind == ICAL_VJOURNAL_COMPONENT) {
			ECalComponent *comp = e_cal_component_new ();
			ECalComponentText summary = { 0 };
			ECalComponentDateTime dt = { 0 };
			gchar *formatted_dt;

			if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp))) {
				g_object_unref (comp);
				continue;
			}

			e_cal_component_get_summary (comp, &summary);
			e_cal_component_get_dtstart (comp, &dt);
			formatted_dt = format_dt (&dt, timezones, users_zone);

			gtk_list_store_append (store, &iter);
			gtk_list_store_set (
				store, &iter,
				0, kind == ICAL_VEVENT_COMPONENT ? (e_cal_component_has_attendees (comp) ? C_("iCalImp", "Meeting") : C_("iCalImp", "Event")) :
				kind == ICAL_VTODO_COMPONENT ? C_("iCalImp", "Task") :
				kind == ICAL_VJOURNAL_COMPONENT ? C_("iCalImp", "Memo") : "??? Other ???",
				1, formatted_dt ? formatted_dt : "",
				2, summary.value && *summary.value ? summary.value : summary.altrep && *summary.altrep ? summary.altrep : "",
				3, comp,
				-1);

			g_free (formatted_dt);
			e_cal_component_free_datetime (&dt);
			g_object_unref (comp);
		}
	}

	if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
		g_object_unref (store);
		g_hash_table_destroy (timezones);
		return NULL;
	}

	preview = e_web_view_preview_new ();
	gtk_widget_show (preview);

	g_object_set_data_full (G_OBJECT (preview), "iCalImp-timezones", timezones, (GDestroyNotify) g_hash_table_destroy);
	g_object_set_data (G_OBJECT (preview), "iCalImp-userszone", users_zone);

	tree_view = e_web_view_preview_get_tree_view (E_WEB_VIEW_PREVIEW (preview));
	g_return_val_if_fail (tree_view != NULL, NULL);

	gtk_tree_view_set_model (tree_view, GTK_TREE_MODEL (store));
	g_object_unref (store);

	/* Translators: Column header for a component type; it can be Event, Task or Memo */
	gtk_tree_view_insert_column_with_attributes (
		tree_view, -1, C_("iCalImp", "Type"),
		gtk_cell_renderer_text_new (), "text", 0, NULL);

	/* Translators: Column header for a component start date/time */
	gtk_tree_view_insert_column_with_attributes (
		tree_view, -1, C_("iCalImp", "Start"),
		gtk_cell_renderer_text_new (), "text", 1, NULL);

	/* Translators: Column header for a component summary */
	gtk_tree_view_insert_column_with_attributes (
		tree_view, -1, C_("iCalImp", "Summary"),
		gtk_cell_renderer_text_new (), "text", 2, NULL);

	if (gtk_tree_model_iter_n_children (GTK_TREE_MODEL (store), NULL) > 1)
		e_web_view_preview_show_tree_view (E_WEB_VIEW_PREVIEW (preview));

	selection = gtk_tree_view_get_selection (tree_view);
	gtk_tree_selection_select_iter (selection, &iter);
	g_signal_connect (
		selection, "changed",
		G_CALLBACK (preview_selection_changed_cb), preview);

	preview_selection_changed_cb (selection, E_WEB_VIEW_PREVIEW (preview));

	return preview;
}
/**
 * e_cal_client_check_timezones:
 * @comp:     a VCALENDAR containing a list of
 *            VTIMEZONE and arbitrary other components, in
 *            arbitrary order: these other components are
 *            modified by this call
 * @comps: (element-type icalcomponent) (allow-none): a list of #icalcomponent
 * instances which also have to be patched; may be %NULL
 * @tzlookup: a callback function which is called to retrieve
 *            a calendar's VTIMEZONE definition; the returned
 *            definition is *not* freed by e_cal_client_check_timezones()
 *            (to be compatible with e_cal_get_timezone());
 *            NULL indicates that no such timezone exists
 *            or an error occurred
 * @ecalclient: an arbitrary pointer which is passed through to
 *            the @tzlookup function
 * @cancellable: a #GCancellable to use in @tzlookup function
 * @error:    an error description in case of a failure
 *
 * This function cleans up VEVENT, VJOURNAL, VTODO and VTIMEZONE
 * items which are to be imported into Evolution.
 *
 * Using VTIMEZONE definitions is problematic because they cannot be
 * updated properly when timezone definitions change. They are also
 * incomplete (for compatibility reason only one set of rules for
 * summer saving changes can be included, even if different rules
 * apply in different years). This function looks for matches of the
 * used TZIDs against system timezones and replaces such TZIDs with
 * the corresponding system timezone. This works for TZIDs containing
 * a location (found via a fuzzy string search) and for Outlook TZIDs
 * (via a hard-coded lookup table).
 *
 * Some programs generate broken meeting invitations with TZID, but
 * without including the corresponding VTIMEZONE. Importing such
 * invitations unchanged causes problems later on (meeting displayed
 * incorrectly, e_cal_get_component_as_string() fails). The situation
 * where this occurred in the past (found by a SyncEvolution user) is
 * now handled via the location based mapping.
 *
 * If this mapping fails, this function also deals with VTIMEZONE
 * conflicts: such conflicts occur when the calendar already contains
 * an old VTIMEZONE definition with the same TZID, but different
 * summer saving rules. Replacing the VTIMEZONE potentially breaks
 * displaying of old events, whereas not replacing it breaks the new
 * events (the behavior in Evolution <= 2.22.1).
 *
 * The way this problem is resolved is by renaming the new VTIMEZONE
 * definition until the TZID is unique. A running count is appended to
 * the TZID. All items referencing the renamed TZID are adapted
 * accordingly.
 *
 * Returns: %TRUE if successful, %FALSE otherwise.
 *
 * Since: 3.2
 **/
gboolean
e_cal_client_check_timezones (icalcomponent *comp,
                              GList *comps,
                              icaltimezone *(*tzlookup) (const gchar *tzid,
                                                         gconstpointer ecalclient,
                                                         GCancellable *cancellable,
                                                         GError **error),
                              gconstpointer ecalclient,
                              GCancellable *cancellable,
                              GError **error)
{
	gboolean success = TRUE;
	icalcomponent *subcomp = NULL;
	icaltimezone *zone = icaltimezone_new ();
	gchar *key = NULL, *value = NULL;
	gchar *buffer = NULL;
	gchar *zonestr = NULL;
	gchar *tzid = NULL;
	GList *l;

	/* a hash from old to new tzid; strings dynamically allocated */
	GHashTable *mapping = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);

	/* a hash of all system time zone IDs which have to be added; strings are shared with mapping hash */
	GHashTable *systemtzids = g_hash_table_new (g_str_hash, g_str_equal);

	*error = NULL;

	if (!mapping || !zone) {
		goto nomem;
	}

	/* iterate over all VTIMEZONE definitions */
	subcomp = icalcomponent_get_first_component (comp, ICAL_VTIMEZONE_COMPONENT);
	while (subcomp) {
		if (icaltimezone_set_component (zone, subcomp)) {
			g_free (tzid);
			tzid = g_strdup (icaltimezone_get_tzid (zone));
			if (tzid) {
				const gchar *newtzid = e_cal_match_tzid (tzid);
				if (newtzid) {
					/* matched against system time zone */
					g_free (key);
					key = g_strdup (tzid);
					if (!key) {
						goto nomem;
					}

					g_free (value);
					value = g_strdup (newtzid);
					if (!value) {
						goto nomem;
					}

					g_hash_table_insert (mapping, key, value);
					g_hash_table_insert (systemtzids, value, NULL);
					key = value = NULL;
				} else {
					gint counter;

					zonestr = icalcomponent_as_ical_string_r (subcomp);

					/* check for collisions with existing timezones */
					for (counter = 0;
					     counter < 100 /* sanity limit */;
					     counter++) {
						icaltimezone *existing_zone;

						if (counter) {
							g_free (value);
							value = g_strdup_printf ("%s %d", tzid, counter);
						}
						existing_zone = tzlookup (counter ? value : tzid, ecalclient, cancellable, error);
						if (!existing_zone) {
							if (*error) {
								goto failed;
							} else {
								break;
							}
						}
						g_free (buffer);
						buffer = icalcomponent_as_ical_string_r (icaltimezone_get_component (existing_zone));

						if (counter) {
							gchar *fulltzid = g_strdup_printf ("TZID:%s", value);
							gsize baselen = strlen ("TZID:") + strlen (tzid);
							gsize fulllen = strlen (fulltzid);
							gchar *tzidprop;
							/*
							 * Map TZID with counter suffix back to basename.
							 */
							tzidprop = strstr (buffer, fulltzid);
							if (tzidprop) {
								memmove (
									tzidprop + baselen,
									tzidprop + fulllen,
									strlen (tzidprop + fulllen) + 1);
							}
							g_free (fulltzid);
						}

						/*
						 * If the strings are identical, then the
						 * VTIMEZONE definitions are identical.  If
						 * they are not identical, then VTIMEZONE
						 * definitions might still be semantically
						 * correct and we waste some space by
						 * needlesly duplicating the VTIMEZONE. This
						 * is expected to occur rarely (if at all) in
						 * practice.
						 */
						if (!strcmp (zonestr, buffer)) {
							break;
						}
					}

					if (!counter) {
						/* does not exist, nothing to do */
					} else {
						/* timezone renamed */
						icalproperty *prop = icalcomponent_get_first_property (subcomp, ICAL_TZID_PROPERTY);
						while (prop) {
							icalproperty_set_value_from_string (prop, value, "NO");
							prop = icalcomponent_get_next_property (subcomp, ICAL_ANY_PROPERTY);
						}
						g_free (key);
						key = g_strdup (tzid);
						g_hash_table_insert (mapping, key, value);
						key = value = NULL;
					}
				}
			}
		}

		subcomp = icalcomponent_get_next_component (comp, ICAL_VTIMEZONE_COMPONENT);
	}

	/*
	 * now replace all TZID parameters in place
	 */
	subcomp = icalcomponent_get_first_component (comp, ICAL_ANY_COMPONENT);
	while (subcomp) {
		/*
		 * Leave VTIMEZONE unchanged, iterate over properties of
		 * everything else.
		 *
		 * Note that no attempt is made to remove unused VTIMEZONE
		 * definitions. That would just make the code more complex for
		 * little additional gain. However, newly used time zones are
		 * added below.
		 */
		patch_tzids (subcomp, mapping);
		subcomp = icalcomponent_get_next_component (comp, ICAL_ANY_COMPONENT);
	}

	for (l = comps; l; l = l->next) {
		patch_tzids (l->data, mapping);
	}

	/*
	 * add system time zones that we mapped to: adding them ensures
	 * that the VCALENDAR remains consistent
	 */
	g_hash_table_foreach (systemtzids, addsystemtz, comp);

	goto done;
 nomem:
	/* set gerror for "out of memory" if possible, otherwise abort via g_error() */
	*error = g_error_new (E_CLIENT_ERROR, E_CLIENT_ERROR_OTHER_ERROR, "out of memory");
	if (!*error) {
		g_error ("e_cal_check_timezones(): out of memory, cannot proceed - sorry!");
	}
 failed:
	/* gerror should have been set already */
	success = FALSE;
 done:
	if (mapping) {
		g_hash_table_destroy (mapping);
	}
	if (systemtzids) {
		g_hash_table_destroy (systemtzids);
	}
	if (zone) {
		icaltimezone_free (zone, 1);
	}
	g_free (tzid);
	g_free (zonestr);
	g_free (buffer);
	g_free (key);
	g_free (value);

	return success;
}
static gboolean
get_result_metas_cb (GcalShellSearchProvider  *search_provider,
                     GDBusMethodInvocation    *invocation,
                     gchar                   **results,
                     GcalShellSearchProvider2 *skel)
{
  GcalShellSearchProviderPrivate *priv;
  gint i;
  gchar *uuid, *desc;
  const gchar* location;

  g_autoptr(GTimeZone) tz;
  g_autoptr (GDateTime) datetime;
  g_autoptr (GDateTime) local_datetime;
  ECalComponentDateTime dtstart;
  gchar *start_date;

  ECalComponentText summary;
  GdkRGBA color;
  GVariantBuilder abuilder, builder;
  GVariant *icon_variant;
  GcalEventData *data;
  GdkPixbuf *gicon;

  priv = search_provider->priv;

  g_variant_builder_init (&abuilder, G_VARIANT_TYPE ("aa{sv}"));
  for (i = 0; i < g_strv_length (results); i++)
    {
      uuid = results[i];
      data = g_hash_table_lookup (priv->events, uuid);

      g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}"));
      g_variant_builder_add (&builder, "{sv}", "id", g_variant_new_string (uuid));

      e_cal_component_get_summary (data->event_component, &summary);
      g_variant_builder_add (&builder, "{sv}", "name", g_variant_new_string (summary.value));

      get_color_name_from_source (data->source, &color);
      gicon = get_circle_pixbuf_from_color (&color, 128);
      icon_variant = g_icon_serialize (G_ICON (gicon));
      g_variant_builder_add (&builder, "{sv}", "icon", icon_variant);
      g_object_unref (gicon);
      g_variant_unref (icon_variant);

      e_cal_component_get_dtstart (data->event_component, &dtstart);

      if (dtstart.tzid != NULL)
        tz = g_time_zone_new (dtstart.tzid);
      else if (dtstart.value->zone != NULL)
        tz = g_time_zone_new (icaltimezone_get_tzid ((icaltimezone*) dtstart.value->zone));
      else
        tz = g_time_zone_new_local ();

      datetime = g_date_time_new (tz,
                                  dtstart.value->year, dtstart.value->month, dtstart.value->day,
                                  dtstart.value->hour, dtstart.value->minute, dtstart.value->second);
      local_datetime = g_date_time_to_local (datetime);

      /* FIXME: respect 24h time format */
      start_date = g_date_time_format (local_datetime,
                                       (dtstart.value->is_date == 1) ? "%x" : "%c");
      e_cal_component_free_datetime (&dtstart);

      e_cal_component_get_location (data->event_component, &location);
      if (location != NULL)
        desc = g_strconcat (start_date, ". ", location, NULL);
      else
        desc = g_strdup (start_date);

      g_variant_builder_add (&builder, "{sv}", "description", g_variant_new_string (desc));
      g_free (start_date);
      g_free (desc);

      g_variant_builder_add_value (&abuilder, g_variant_builder_end (&builder));
    }
  g_dbus_method_invocation_return_value (invocation, g_variant_new ("(aa{sv})", &abuilder));

  return TRUE;
}
nsresult calIcalProperty::getDatetime_(calIcalComponent * parent,
                                       icalproperty * prop,
                                       calIDateTime ** dtp)
{
    icalvalue * const val = icalproperty_get_value(prop);
    icalvalue_kind const valkind = icalvalue_isa(val);
    if (valkind != ICAL_DATETIME_VALUE && valkind != ICAL_DATE_VALUE) {
        return NS_ERROR_UNEXPECTED;
    }
    icaltimetype itt = icalvalue_get_datetime(val);

    char const* tzid_ = nullptr;
    if (!itt.is_utc) {
        if (itt.zone) {
            tzid_ = icaltimezone_get_tzid(const_cast<icaltimezone *>(itt.zone));
        } else {
            // Need to get the tzid param. Unfortunatly, libical tends to return raw
            // ics strings, with quotes and everything. That's not what we want. Need
            // to work around.
            icalparameter * const tzparam = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
            if (tzparam) {
                tzid_ = icalparameter_get_xvalue(tzparam);
            }
        }
    }

    nsCOMPtr<calITimezone> tz;
    if (tzid_) {
        nsDependentCString const tzid(tzid_);
        calIcalComponent * comp = nullptr;
        if (parent) {
            comp = parent->getParentVCalendarOrThis();
        }
        // look up parent if timezone is already referenced:
        if (comp) {
            comp->mReferencedTimezones.Get(tzid, getter_AddRefs(tz));
        }
        if (!tz) {
            if (parent) {
                // passed tz provider has precedence over timezone service:
                calITimezoneProvider * const tzProvider = parent->getTzProvider();
                if (tzProvider) {
                    tzProvider->GetTimezone(tzid, getter_AddRefs(tz));
                    NS_ASSERTION(tz, tzid_);
                }
            }
            if (!tz) {
                // look up tz in tz service.
                // this hides errors from incorrect ics files, which could state
                // a TZID that is not present in the ics file.
                // The other way round, it makes this product more error tolerant.
                nsresult rv = cal::getTimezoneService()->GetTimezone(tzid, getter_AddRefs(tz));

                if (NS_FAILED(rv) || !tz) {
                    icaltimezone const* zone = itt.zone;
                    if (!zone && comp) {
                        // look up parent VCALENDAR for VTIMEZONE:
                        zone = icalcomponent_get_timezone(comp->mComponent, tzid_);
                        NS_ASSERTION(zone, tzid_);
                    }
                    if (zone) {
                        // We need to decouple this (inner) VTIMEZONE from the parent VCALENDAR to avoid
                        // running into circular references (referenced timezones):
                        icaltimezone * const clonedZone = icaltimezone_new();
                        CAL_ENSURE_MEMORY(clonedZone);
                        icalcomponent * const clonedZoneComp =
                            icalcomponent_new_clone(icaltimezone_get_component(const_cast<icaltimezone *>(zone)));
                        if (!clonedZoneComp) {
                            icaltimezone_free(clonedZone, 1 /* free struct */);
                            CAL_ENSURE_MEMORY(clonedZoneComp);
                        }
                        if (!icaltimezone_set_component(clonedZone, clonedZoneComp)) {
                            icaltimezone_free(clonedZone, 1 /* free struct */);
                            return NS_ERROR_INVALID_ARG;
                        }
                        nsCOMPtr<calIIcalComponent> const tzComp(new calIcalComponent(clonedZone, clonedZoneComp));
                        CAL_ENSURE_MEMORY(tzComp);
                        tz = new calTimezone(tzid, tzComp);
                        CAL_ENSURE_MEMORY(tz);
                    } else { // install phantom timezone, so the data could be repaired:
                        tz = new calTimezone(tzid, nullptr);
                        CAL_ENSURE_MEMORY(tz);
                    }
                }
            }
            if (comp && tz) {
                // assure timezone is known:
                comp->AddTimezoneReference(tz);
            }
        }
        if (tz) {
            // correct itt which would else appear floating:
            itt.zone = cal::getIcalTimezone(tz);
            itt.is_utc = 0;
        } else {
            cal::logMissingTimezone(tzid_);
        }
    }
    *dtp = new calDateTime(&itt, tz);
    CAL_ENSURE_MEMORY(*dtp);
    NS_ADDREF(*dtp);
    return NS_OK;
}
Example #16
0
icaltimezone *
calendar_config_get_icaltimezone (void)
{
	char *location;
	icaltimezone *zone = NULL;

	calendar_config_init ();

	location = calendar_config_get_timezone ();
	if (location) {
		icalcomponent *icalcomp, *dl_comp;

		zone = icaltimezone_get_builtin_timezone (location);
		icalcomp = icaltimezone_get_component (zone);


		if (!(dl_comp = icalcomponent_get_first_component (icalcomp, ICAL_XDAYLIGHT_COMPONENT))) {
			g_free (location);
			return zone;
		}

		if (!calendar_config_get_daylight_saving () && zone) {
			icalcomponent *zone_comp, *s_comp;
			icalproperty *tz_prop, *offset_to;
			icaltimezone *st_zone = NULL;
			int offset;
			char *n_tzid, *tzid;

			tzid = icaltimezone_get_tzid (zone);
			n_tzid = g_strconcat (tzid, "-(Standard)", NULL);

			if (!custom_zones) {
				custom_zones = g_hash_table_new (g_str_hash, g_str_equal);
			} else if ((st_zone = g_hash_table_lookup (custom_zones, n_tzid))) {
				g_free (n_tzid);
				g_free (location);
				return st_zone;
			}

			zone_comp = icalcomponent_new_clone (icalcomp);
			s_comp = icalcomponent_get_first_component (zone_comp, ICAL_XSTANDARD_COMPONENT);

			if (!s_comp) {
				g_free (n_tzid);
				icalcomponent_free (zone_comp);
				g_free (location);
				return zone;
			}

			offset_to = icalcomponent_get_first_property (s_comp, ICAL_TZOFFSETTO_PROPERTY);
			offset = icalproperty_get_tzoffsetto (offset_to);

			set_standard_offsets (zone_comp, offset);

			tz_prop = icalcomponent_get_first_property (zone_comp, ICAL_TZID_PROPERTY);
			if (tz_prop) {
				icalcomponent_remove_property (zone_comp, tz_prop);
			}

			tz_prop = icalproperty_new_tzid (n_tzid);
			icalcomponent_add_property (zone_comp, tz_prop);

			st_zone = icaltimezone_new ();
			icaltimezone_set_component (st_zone, zone_comp);

			zone = st_zone;
			g_hash_table_insert (custom_zones, n_tzid, zone);
		}

		g_free (location);
	}
	return zone;
}
Example #17
0
/* Pilot syncing callbacks */
static gint
pre_sync (GnomePilotConduit *conduit,
	  GnomePilotDBInfo *dbi,
	  EMemoConduitContext *ctxt)
{
	GnomePilotConduitSyncAbs *abs_conduit;
	GList *l;
	int len;
	unsigned char *buf;
	char *filename, *change_id;
	icalcomponent *icalcomp;
	gint num_records, add_records = 0, mod_records = 0, del_records = 0;
#ifdef PILOT_LINK_0_12
	pi_buffer_t * buffer;
#endif

	abs_conduit = GNOME_PILOT_CONDUIT_SYNC_ABS (conduit);

	LOG (g_message ( "---------------------------------------------------------\n" ));
	LOG (g_message ( "pre_sync: Memo Conduit v.%s", CONDUIT_VERSION ));
	g_message ("Memo Conduit v.%s", CONDUIT_VERSION);

	ctxt->dbi = dbi;
	ctxt->client = NULL;

	if (start_calendar_server (ctxt) != 0) {
		WARN(_("Could not start evolution-data-server"));
		gnome_pilot_conduit_error (conduit, _("Could not start evolution-data-server"));
		return -1;
	}

	/* Get the timezone */
	ctxt->timezone = get_default_timezone ();
	if (ctxt->timezone == NULL)
		return -1;
	LOG (g_message ( "  Using timezone: %s", icaltimezone_get_tzid (ctxt->timezone) ));

	/* Set the default timezone on the backend. */
	if (ctxt->timezone && !e_cal_set_default_timezone (ctxt->client, ctxt->timezone, NULL))
		return -1;

	/* Get the default component */
	if (!e_cal_get_default_object (ctxt->client, &icalcomp, NULL))
		return -1;

	ctxt->default_comp = e_cal_component_new ();
	if (!e_cal_component_set_icalcomponent (ctxt->default_comp, icalcomp)) {
		g_object_unref (ctxt->default_comp);
		icalcomponent_free (icalcomp);
		return -1;
	}

	/* Load the uid <--> pilot id map */
	filename = map_name (ctxt);
	e_pilot_map_read (filename, &ctxt->map);
	g_free (filename);

	/* Get the local database */
	if (!e_cal_get_object_list_as_comp (ctxt->client, "#t", &ctxt->comps, NULL))
		return -1;

	/* Count and hash the changes */
	change_id = g_strdup_printf ("pilot-sync-evolution-memo-%d", ctxt->cfg->pilot_id);
	if (!e_cal_get_changes (ctxt->client, change_id, &ctxt->changed, NULL))
		return -1;

	ctxt->changed_hash = g_hash_table_new (g_str_hash, g_str_equal);
	g_free (change_id);

	for (l = ctxt->changed; l != NULL; l = l->next) {
		ECalChange *ccc = l->data;
		const char *uid;

		e_cal_component_get_uid (ccc->comp, &uid);
		if (!e_pilot_map_uid_is_archived (ctxt->map, uid)) {

			g_hash_table_insert (ctxt->changed_hash, g_strdup (uid), ccc);

			switch (ccc->type) {
			case E_CAL_CHANGE_ADDED:
				add_records++;
				break;
			case E_CAL_CHANGE_MODIFIED:
				mod_records++;
				break;
			case E_CAL_CHANGE_DELETED:
				del_records++;
				break;
			}
		} else if (ccc->type == E_CAL_CHANGE_DELETED) {
			e_pilot_map_remove_by_uid (ctxt->map, uid);
		}
	}

	/* Set the count information */
	num_records = g_list_length (ctxt->comps);
	gnome_pilot_conduit_sync_abs_set_num_local_records(abs_conduit, num_records);
	gnome_pilot_conduit_sync_abs_set_num_new_local_records (abs_conduit, add_records);
	gnome_pilot_conduit_sync_abs_set_num_updated_local_records (abs_conduit, mod_records);
	gnome_pilot_conduit_sync_abs_set_num_deleted_local_records(abs_conduit, del_records);

	g_message("num_records: %d\nadd_records: %d\nmod_records: %d\ndel_records: %d\n",
		num_records, add_records, mod_records, del_records);

#ifdef PILOT_LINK_0_12
	buffer = pi_buffer_new(DLP_BUF_SIZE);
	if(buffer == NULL){
		pi_set_error(dbi->pilot_socket, PI_ERR_GENERIC_MEMORY);
		return -1;
	}

 	len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
				DLP_BUF_SIZE,
				buffer);
#else
	buf = (unsigned char*)g_malloc (0xffff);
	len = dlp_ReadAppBlock (dbi->pilot_socket, dbi->db_handle, 0,
			      (unsigned char *)buf, 0xffff);
#endif
	if (len < 0) {
		WARN (_("Could not read pilot's Memo application block"));
		WARN ("dlp_ReadAppBlock(...) = %d", len);
		gnome_pilot_conduit_error (conduit,
					   _("Could not read pilot's Memo application block"));
		return -1;
	}
#ifdef PILOT_LINK_0_12
	buf = g_new0 (unsigned char,buffer->used);
	memcpy(buf, buffer->data, buffer->used);
 	unpack_MemoAppInfo (&(ctxt->ai), buf, len);
	pi_buffer_free(buffer);
#else
	unpack_MemoAppInfo (&(ctxt->ai), buf, len);
#endif

	g_free (buf);

	lastDesktopUniqueID = 128;

	check_for_slow_setting (conduit, ctxt);
	if (ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyToPilot
	    || ctxt->cfg->sync_type == GnomePilotConduitSyncTypeCopyFromPilot)
		ctxt->map->write_touched_only = TRUE;

	return 0;
}
Example #18
0
void calDateTime::FromIcalTime(icaltimetype const* icalt, calITimezone * tz)
{
    icaltimetype t = *icalt;
    mIsValid = (icaltime_is_null_time(t) ||
                icaltime_is_valid_time(t) ? PR_TRUE : PR_FALSE);

    mIsDate = t.is_date ? PR_TRUE : PR_FALSE;
    if (mIsDate) {
        t.hour = 0;
        t.minute = 0;
        t.second = 0;
    }

    if (mIsValid) {
        t = icaltime_normalize(t);
    }

    mYear = static_cast<PRInt16>(t.year);
    mMonth = static_cast<PRInt16>(t.month - 1);
    mDay = static_cast<PRInt16>(t.day);
    mHour = static_cast<PRInt16>(t.hour);
    mMinute = static_cast<PRInt16>(t.minute);
    mSecond = static_cast<PRInt16>(t.second);

    if (tz) {
        mTimezone = tz;
    } else {
        mTimezone = cal::detectTimezone(t, nsnull);
    }
#if defined(DEBUG)
    if (mTimezone) {
        if (t.is_utc) {
#if 1
            nsCOMPtr<calITimezone> utc_tz;
            nsCOMPtr<calITimezoneService> tzSvc =
              do_GetService(CAL_TIMEZONESERVICE_CONTRACTID);
            tzSvc->GetUTC(getter_AddRefs(utc_tz));
            NS_ASSERTION(SameCOMIdentity(mTimezone, utc_tz), "UTC mismatch!");
#else
            NS_ASSERTION(SameCOMIdentity(mTimezone, cal::UTC()), "UTC mismatch!");
#endif
        } else if (!t.zone) {
#if 1
            nsCOMPtr<calITimezone> float_tz;
            nsCOMPtr<calITimezoneService> tzSvc =
              do_GetService(CAL_TIMEZONESERVICE_CONTRACTID);
            tzSvc->GetFloating(getter_AddRefs(float_tz));
            NS_ASSERTION(SameCOMIdentity(mTimezone, float_tz), "floating mismatch!");
#else
            NS_ASSERTION(SameCOMIdentity(mTimezone, cal::floating()), "floating mismatch!");
#endif
        } else {
            nsCAutoString tzid;
            mTimezone->GetTzid(tzid);
            NS_ASSERTION(tzid.Equals(icaltimezone_get_tzid(const_cast<icaltimezone *>(t.zone))),
                         "tzid mismatch!");
        }
    }
#endif

    mWeekday = static_cast<PRInt16>(icaltime_day_of_week(t) - 1);
    mYearday = static_cast<PRInt16>(icaltime_day_of_year(t));

    // mNativeTime: not moving the existing date to UTC,
    // but merely representing it a UTC-based way.
    t.is_date = 0;
    mNativeTime = IcaltimeToPRTime(&t, icaltimezone_get_utc_timezone());
}