/* * 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; }
const char *icaltime_get_tzid(const struct icaltimetype t) { if (t.zone != NULL) { return icaltimezone_get_tzid((icaltimezone *) t.zone); } else { return NULL; } }
/** * 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; }
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); }
/** * 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; }
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; }
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; }
/* 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; }
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()); }