/*
* 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."));
}
}