/* * Copyright (C) 2010 Collabora Ltd. * Copyright (C) 2011 Philip Withnall * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2.1 of the License, or * (at your option) any later version. * * This library 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . * * Authors: * Marco Barisione * Raul Gutierrez Segales * Philip Withnall */ using GLib; using Gee; /** * Object representing a postal mail address. * The components of the address are never null, an empty string * indicates that a property is not set. */ public class Folks.PostalAddress : Object { private string _po_box = ""; /** * The PO Box. * * The PO Box (also known as Postal office box or Postal box). */ public string po_box { get { return _po_box; } construct set { _po_box = (value != null ? value : ""); } } private string _extension = ""; /** * The address extension. * * Any additional part of the address, for instance a flat number. */ public string extension { get { return _extension; } construct set { _extension = (value != null ? value : ""); } } private string _street = ""; /** * The street name and number. * * The street name including the optional building number. * The number can be before or after the street name based on the * language and country. */ public string street { get { return _street; } construct set { _street = (value != null ? value : ""); } } private string _locality = ""; /** * The locality. * * The locality, for instance the city name. */ public string locality { get { return _locality; } construct set { _locality = (value != null ? value : ""); } } private string _region = ""; /** * The region. * * The region, for instance the name of the state or province. */ public string region { get { return _region; } construct set { _region = (value != null ? value : ""); } } private string _postal_code = ""; /** * The postal code. * * The postal code (also known as post code, postcode or ZIP code). */ public string postal_code { get { return _postal_code; } construct set { _postal_code = (value != null ? value : ""); } } private string _country = ""; /** * The country. * * The name of the country. */ public string country { get { return _country; } construct set { _country = (value != null ? value : ""); } } private string _address_format = ""; /** * The address format. * * The two letter country code that determines the format or exact * meaning of the other fields. */ public string address_format { get { return _address_format; } construct set { _address_format = (value != null ? value : ""); } } private string _uid = ""; /** * The UID of the Postal Address (if any). */ [Deprecated (since = "0.6.5", replacement = "AbstractFieldDetails.id")] public string uid { get { return _uid; } construct set { _uid = (value != null ? value : ""); } } /** * Create a PostalAddress. * * You can pass `null` if a component is not set. * * @param po_box the PO Box * @param extension the address extension * @param street the street name and number * @param locality the locality (city, town or village) name * @param region the region (state or province) name * @param postal_code the postal code * @param country the country name * @param address_format the address format * @param types set of types for the address (such as "personal" or "work") * @param uid external UID for the address instance * @since 0.5.1 */ public PostalAddress (string? po_box, string? extension, string? street, string? locality, string? region, string? postal_code, string? country, string? address_format, string? uid) { Object (po_box: po_box, extension: extension, street: street, locality: locality, region: region, postal_code: postal_code, country: country, address_format: address_format, uid: uid); } /** * Whether none of the components is set. * * @return `true` if all the components are the empty string, `false` * otherwise. * * @since 0.6.7 */ public bool is_empty () { return this.po_box == "" && this.extension == "" && this.street == "" && this.locality == "" && this.region == "" && this.postal_code == "" && this.country == "" && this.address_format == ""; } /** * Compare if two postal addresses are equal. Addresses are equal if all their * components are equal (where `null` compares equal only with `null`) and * they have the same set of types (or both have no types). * * This does not factor in the {@link PostalAddress.uid}. * * @param with another postal address to compare with * @return `true` if the addresses are equal, `false` otherwise */ public bool equal (PostalAddress with) { if (this.po_box != with.po_box || this.extension != with.extension || this.street != with.street || this.locality != with.locality || this.region != with.region || this.postal_code != with.postal_code || this.country != with.country || this.address_format != with.address_format) return false; return true; } /** * Get a formatted version of the address. The format is localised, and by * default is comma-separated. * * @return a formatted address. * * @since 0.4.0 */ public string to_string () { var str = _("%s, %s, %s, %s, %s, %s, %s"); return str.printf (this.po_box, this.extension, this.street, this.locality, this.region, this.postal_code, this.country); } } /** * Object representing a PostalAddress value that can have some parameters * associated with it. * * See {@link Folks.AbstractFieldDetails} for details on common parameter names * and values. * * @since 0.6.0 */ public class Folks.PostalAddressFieldDetails : AbstractFieldDetails { private string _id; /** * {@inheritDoc} */ public override string id { get { return this._id; } set { this._id = (value != null ? value : ""); /* Keep the PostalAddress.uid sync'd from our id */ if (this._id != this.value.uid) this.value.uid = this._id; } } /** * Create a new PostalAddressFieldDetails. * * @param value the value of the field, a non-empty {@link PostalAddress} * @param parameters initial parameters. See * {@link AbstractFieldDetails.parameters}. A `null` value is equivalent to an * empty map of parameters. * * * @return a new PostalAddressFieldDetails * * @since 0.6.0 */ public PostalAddressFieldDetails (PostalAddress value, MultiMap? parameters = null) { if (value.is_empty ()) { warning ("Empty postal address passed to PostalAddressFieldDetails."); } /* We keep id and value.uid synchronised in both directions. */ Object (value: value, parameters: parameters, id: value.uid); } construct { /* Keep the PostalAddress.uid sync'd to our id */ this.value.notify["uid"].connect ((s, p) => { if (this.id != this.value.uid) this.id = this.value.uid; }); } /** * {@inheritDoc} * * @since 0.6.0 */ public override bool equal (AbstractFieldDetails that) { if (!base.parameters_equal (that)) return false; /* This is fairly-dumb but smart matching is an i10n nightmare. */ return this.value.to_string () == that.value.to_string (); } /** * {@inheritDoc} * * @since 0.6.0 */ public override uint hash () { /* This is basic because smart matching is very hard (see equal()). */ return str_hash (this.value.to_string ()); } } /** * Interface for classes that can provide postal addresses, such as * {@link Persona} and {@link Individual}. */ public interface Folks.PostalAddressDetails : Object { /** * The postal addresses of the contact. * * A list of postal addresses associated to the contact. * * @since 0.5.1 */ public abstract Set postal_addresses { get; set; } /** * Change the contact's postal addresses. * * It's preferred to call this rather than setting * {@link PostalAddressDetails.postal_addresses} directly, as this method * gives error notification and will only return once the addresses have been * written to the relevant backing store (or the operation's failed). * * @param postal_addresses the set of postal addresses * @throws PropertyError if setting the addresses failed * @since 0.6.2 */ public virtual async void change_postal_addresses ( Set postal_addresses) throws PropertyError { /* Default implementation. */ throw new PropertyError.NOT_WRITEABLE ( _("Postal addresses are not writeable on this contact.")); } }