1/* 2 * Copyright (C) 2011 Collabora Ltd. 3 * Copyright (C) 2011 Philip Withnall 4 * 5 * This library is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation, either version 2.1 of the License, or 8 * (at your option) any later version. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with this library. If not, see <http://www.gnu.org/licenses/>. 17 * 18 * Authors: 19 * Raul Gutierrez Segales <raul.gutierrez.segales@collabora.co.uk> 20 * Travis Reitter <travis.reitter@collabora.co.uk> 21 * Philip Withnall <philip@tecnocode.co.uk> 22 */ 23 24using Gee; 25using GLib; 26 27/** 28 * Role a contact has in an organisation. 29 * 30 * This represents the role a {@link Persona} or {@link Individual} has in a 31 * single given organisation, such as a company. 32 * 33 * @since 0.4.0 34 */ 35public class Folks.Role : Object 36{ 37 private string _organisation_name = ""; 38 /** 39 * The name of the organisation in which the role is held. 40 */ 41 public string organisation_name 42 { 43 get { return this._organisation_name; } 44 set { this._organisation_name = (value != null ? value : ""); } 45 } 46 47 private string _title = ""; 48 /** 49 * The title of the position held. 50 * 51 * For example: “Director, Ministry of Silly Walks” 52 */ 53 public string title 54 { 55 get { return this._title; } 56 set { this._title = (value != null ? value : ""); } 57 } 58 59 private string _role = ""; 60 /** 61 * The role of the position. 62 * 63 * For example: “Programmer” 64 * 65 * @since 0.6.0 66 */ 67 public string role 68 { 69 get { return this._role; } 70 set { this._role = (value != null ? value : ""); } 71 } 72 73 private string _uid = ""; 74 /** 75 * The UID that distinguishes this role. 76 */ 77 [Version (deprecated = true, deprecated_since = "0.6.5", 78 replacement = "AbstractFieldDetails.id")] 79 public string uid 80 { 81 get { return _uid; } 82 set { _uid = (value != null ? value : ""); } 83 } 84 85 /** 86 * Default constructor. 87 * 88 * @param title title of the position 89 * @param organisation_name organisation where the role is hold 90 * @param uid a Unique ID associated to this Role 91 * @return a new Role 92 * 93 * @since 0.4.0 94 */ 95 public Role (string? title = null, 96 string? organisation_name = null, string? uid = null) 97 { 98 Object (uid: uid, 99 title: title, 100 organisation_name: organisation_name); 101 } 102 103 /** 104 * Whether none of the components is set. 105 * 106 * @return ``true`` if all the components are the empty string, ``false`` 107 * otherwise. 108 * 109 * @since 0.6.7 110 */ 111 public bool is_empty () 112 { 113 return this.organisation_name == "" && 114 this.title == "" && 115 this.role == ""; 116 } 117 118 /** 119 * Compare if two roles are equal. Roles are equal if their titles and 120 * organisation names are equal. 121 * 122 * @param a a role to compare 123 * @param b another role to compare 124 * @return ``true`` if the roles are equal, ``false`` otherwise 125 */ 126 public static bool equal (Role a, Role b) 127 { 128 return (a.title == b.title) && 129 (a.role == b.role) && 130 (a.organisation_name == b.organisation_name); 131 } 132 133 /** 134 * Hash function for the class. Suitable for use as a hash table key. 135 * 136 * @param r a role to hash 137 * @return hash value for the role instance 138 */ 139 public static uint hash (Role r) 140 { 141 return r.organisation_name.hash () ^ r.title.hash () ^ r.role.hash (); 142 } 143 144 /** 145 * Formatted version of this role. 146 * 147 * @since 0.4.0 148 */ 149 public string to_string () 150 { 151 var str = _("Title: %s, Organisation: %s, Role: %s"); 152 return str.printf (this.title, this.organisation_name, this.role); 153 } 154} 155 156/** 157 * Object representing details of a contact in an organisation which can have 158 * some parameters associated with it. 159 * 160 * See {@link Folks.AbstractFieldDetails}. 161 * 162 * @since 0.6.0 163 */ 164public class Folks.RoleFieldDetails : AbstractFieldDetails<Role> 165{ 166 private string _id = ""; 167 /** 168 * {@inheritDoc} 169 */ 170 public override string id 171 { 172 get { return this._id; } 173 set 174 { 175 this._id = (value != null ? value : ""); 176 177 /* Keep the Role.uid sync'd from our id */ 178 if (this._id != this.value.uid) 179 this.value.uid = this._id; 180 } 181 } 182 183 /** 184 * Create a new RoleFieldDetails. 185 * 186 * @param value the non-empty {@link Role} of the field 187 * @param parameters initial parameters. See 188 * {@link AbstractFieldDetails.parameters}. A ``null`` value is equivalent to an 189 * empty map of parameters. 190 * 191 * @return a new RoleFieldDetails 192 * 193 * @since 0.6.0 194 */ 195 public RoleFieldDetails (Role value, 196 MultiMap<string, string>? parameters = null) 197 { 198 if (value.is_empty ()) 199 { 200 warning ("Empty role passed to RoleFieldDetails."); 201 } 202 203 /* We keep id and value.uid synchronised in both directions. */ 204 Object (value: value, 205 parameters: parameters, 206 id: value.uid); 207 } 208 209 construct 210 { 211 /* Keep the Role.uid sync'd to our id */ 212 this.value.notify["uid"].connect ((s, p) => 213 { 214 if (this.id != this.value.uid) 215 this.id = this.value.uid; 216 }); 217 } 218 219 /** 220 * {@inheritDoc} 221 * 222 * @since 0.6.0 223 */ 224 public override bool equal (AbstractFieldDetails<Role> that) 225 { 226 var _that_fd = that as RoleFieldDetails; 227 if (_that_fd == null) 228 return false; 229 RoleFieldDetails that_fd = (!) _that_fd; 230 231 if (!base.parameters_equal (that)) 232 return false; 233 234 return Role.equal (this.value, that_fd.value); 235 } 236 237 /** 238 * {@inheritDoc} 239 * 240 * @since 0.6.0 241 */ 242 public override uint hash () 243 { 244 return str_hash (this.value.to_string ()); 245 } 246} 247 248/** 249 * This interfaces represents the list of roles a {@link Persona} and 250 * {@link Individual} might have. 251 * 252 * @since 0.4.0 253 */ 254public interface Folks.RoleDetails : Object 255{ 256 /** 257 * The roles of the contact. 258 * 259 * @since 0.6.0 260 */ 261 public abstract Set<RoleFieldDetails> roles { get; set; } 262 263 /** 264 * Change the contact's roles. 265 * 266 * It's preferred to call this rather than setting {@link RoleDetails.roles} 267 * directly, as this method gives error notification and will only return once 268 * the roles have been written to the relevant backing store (or the 269 * operation's failed). 270 * 271 * @param roles the set of roles 272 * @throws PropertyError if setting the roles failed 273 * @since 0.6.2 274 */ 275 public virtual async void change_roles (Set<RoleFieldDetails> roles) 276 throws PropertyError 277 { 278 /* Default implementation. */ 279 throw new PropertyError.NOT_WRITEABLE ( 280 _("Roles are not writeable on this contact.")); 281 } 282} 283