1 /*
2 *  RAL -- Rubrica Addressbook Library
3 *  file: address.c
4 *
5 *  Copyright (C) Nicola Fragale <nicolafragale@libero.it>
6 *
7 *  This program is free software; you can redistribute it and/or modify
8 *  it under the terms of the GNU General Public License as published by
9 *  the Free Software Foundation; either version 3 of the License
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 
21 #include <time.h>
22 #include <glib.h>
23 #include <glib-object.h>
24 #include <glib/gi18n-lib.h>
25 
26 #include "address.h"
27 #include "lookup.h"
28 #include "utils.h"
29 
30 /* Property enumeration */
31 enum {
32   ADDRESS_PROP_0,
33   ADDRESS_TYPE,
34   ADDRESS_STREET,
35   ADDRESS_NUMBER,
36   ADDRESS_CITY,
37   ADDRESS_ZIP,
38   ADDRESS_PROVINCE,
39   ADDRESS_STATE,
40   ADDRESS_COUNTRY
41 };
42 
43 
44 struct _RAddressPrivate {
45   gint   type;
46   gchar* street;
47   gchar* number;
48   gchar* city;
49   gchar* zip;
50   gchar* province;
51   gchar* state;
52   gchar* country;
53 
54   gboolean dispose_has_run;
55 };
56 
57 
58 static RLookupTable table[] = {
59   {"pref",       N_("preferred"),          R_ADDRESS_PREF      },
60   {"home",       N_("residence"),          R_ADDRESS_HOME      },
61   {"work",       N_("work"),               R_ADDRESS_WORK      },
62   {"parcel",     N_("parcel"),             R_ADDRESS_PARCEL    },
63   {"postal",     N_("postal"),             R_ADDRESS_POSTAL    },
64   {"intl",       N_("international"),      R_ADDRESS_INTL      },
65   {"dom",        N_("domestic"),           R_ADDRESS_DOM       },
66   {"registered", N_("registered office"),  R_ADDRESS_COMPANY   },
67   {"subsidiary", N_("subsidiary company"), R_ADDRESS_SUBSIDIARY},
68   {"other",      N_("other"),              R_ADDRESS_OTHER     },
69   {"unknown",    N_("unknown"),            R_ADDRESS_UNKNOWN   },
70   {NULL,      NULL,                        R_ADDRESS_INVALID   },
71 };
72 
73 
74 static void r_address_class_init   (RAddressClass* klass);
75 static void r_address_init         (RAddress* obj);
76 
77 static void r_address_dispose      (RAddress* obj);
78 static void r_address_finalize     (RAddress* obj);
79 
80 static void r_address_set_property (GObject* obj, guint property_id,
81 				    const GValue* value, GParamSpec* spec);
82 static void r_address_get_property (GObject* obj, guint property_id,
83 				    GValue* value, GParamSpec* spec);
84 
85 
86 GType
r_address_get_type()87 r_address_get_type()
88 {
89   static GType address_type = 0;
90 
91   if (!address_type)
92     {
93       static const GTypeInfo address_info =
94 	{
95 	  sizeof(RAddressClass),
96 	  NULL,
97 	  NULL,
98 	  (GClassInitFunc) r_address_class_init,
99 	  NULL,
100 	  NULL,
101 	  sizeof(RAddress),
102 	  0,
103 	  (GInstanceInitFunc) r_address_init
104 	};
105 
106       address_type = g_type_register_static (G_TYPE_OBJECT,
107 					     "RAddress", &address_info, 0);
108     }
109 
110   return address_type;
111 }
112 
113 
114 static void
r_address_class_init(RAddressClass * klass)115 r_address_class_init(RAddressClass* klass)
116 {
117   GObjectClass *class;
118   GParamSpec* pspec;
119 
120   class  = G_OBJECT_CLASS (klass);
121 
122   class->dispose  = (GObjectFinalizeFunc) r_address_dispose;
123   class->finalize = (GObjectFinalizeFunc) r_address_finalize;
124 
125   class->set_property = r_address_set_property;
126   class->get_property = r_address_get_property;
127 
128   /* class property
129    */
130 
131   /**
132    * RAddress:address-type:
133    *
134    * defines the address's type. See #RAddressType for valid values
135    */
136   pspec = g_param_spec_int("address-type",
137 			   "address's type",
138 			   "store the address's type, i.e. "
139 			   "R_ADDRESS_PREF or R_ADDRESS_WORK",
140 			   R_ADDRESS_PREF,
141 			   R_ADDRESS_INVALID,
142 			   R_ADDRESS_UNKNOWN,
143 			   G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
144   g_object_class_install_property(class, ADDRESS_TYPE, pspec);
145 
146 
147   /**
148    * RAddress:street:
149    *
150    * the address's street
151    */
152   pspec = g_param_spec_string("street",
153 			      "address's street",
154 			      "the address's street",
155 			      NULL,
156 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
157   g_object_class_install_property(class, ADDRESS_STREET, pspec);
158 
159   /**
160    * RAddress:address-number:
161    *
162    * the street number
163    */
164   pspec = g_param_spec_string("street-number",
165 			      "the street number",
166 			      "the street number",
167 			      NULL,
168 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
169   g_object_class_install_property(class, ADDRESS_NUMBER, pspec);
170 
171   /**
172    * RAddress:city:
173    *
174    * the address's city
175    */
176   pspec = g_param_spec_string("city",
177 			      "the address's city",
178 			      "the address's city",
179 			      NULL,
180 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
181   g_object_class_install_property(class, ADDRESS_CITY, pspec);
182 
183   /**
184    * RAddress:zip:
185    *
186    * the postal code
187    */
188   pspec = g_param_spec_string("zip",
189 			      "postal code",
190 			      "the postal code",
191 			      NULL,
192 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
193   g_object_class_install_property(class, ADDRESS_ZIP, pspec);
194 
195   /**
196    * RAddress:province:
197    *
198    * the address's province (example: Rm (Rome), Mi (Milan) , Na (Naples) ...)
199    */
200   pspec = g_param_spec_string("province",
201 			      "province",
202 			      "the address's province",
203 			      NULL,
204 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
205   g_object_class_install_property(class, ADDRESS_PROVINCE, pspec);
206 
207   /**
208    * RAddress:state:
209    *
210    * the address's state (examples: UE, USA, ...)
211    */
212   pspec = g_param_spec_string("state",
213 			      "the state",
214 			      "the state",
215 			      NULL,
216 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
217   g_object_class_install_property(class, ADDRESS_STATE, pspec);
218 
219   /**
220    * RAddress:country:
221    *
222    * the address's country (example: Italy, France, ...)
223    */
224   pspec = g_param_spec_string("country",
225 			      "the country",
226 			      "the country",
227 			      NULL,
228 			      G_PARAM_CONSTRUCT | G_PARAM_READWRITE);
229   g_object_class_install_property(class, ADDRESS_COUNTRY, pspec);
230 
231 }
232 
233 
234 static void
r_address_init(RAddress * self)235 r_address_init(RAddress* self)
236 {
237   self->priv = g_new(RAddressPrivate, 1);
238   self->priv->dispose_has_run = FALSE;
239 
240   self->priv->street   = NULL;
241   self->priv->number   = NULL;
242   self->priv->city     = NULL;
243   self->priv->zip      = NULL;
244   self->priv->province = NULL;
245   self->priv->state    = NULL;
246   self->priv->country  = NULL;
247 }
248 
249 
250 
251 static void
r_address_dispose(RAddress * self)252 r_address_dispose (RAddress* self)
253 {
254   g_return_if_fail(IS_R_ADDRESS(self));
255 
256   if (self->priv->dispose_has_run)
257     return;
258 
259   self->priv->dispose_has_run = TRUE;
260 }
261 
262 
263 static void
r_address_finalize(RAddress * self)264 r_address_finalize (RAddress* self)
265 {
266   g_return_if_fail(IS_R_ADDRESS(self));
267 
268   r_utils_free_string(self->priv->street);
269   r_utils_free_string(self->priv->number);
270   r_utils_free_string(self->priv->city);
271   r_utils_free_string(self->priv->zip);
272   r_utils_free_string(self->priv->province);
273   r_utils_free_string(self->priv->state);
274   r_utils_free_string(self->priv->country);
275 
276   g_free(self->priv);
277   self->priv = NULL;
278 }
279 
280 
281 static void
r_address_set_property(GObject * obj,guint property_id,const GValue * value,GParamSpec * spec)282 r_address_set_property (GObject* obj, guint property_id,
283 			const GValue* value, GParamSpec* spec)
284 {
285   RAddress* self = (RAddress*) obj;
286 
287   switch (property_id)
288     {
289     case ADDRESS_TYPE:
290       self->priv->type = g_value_get_int(value);
291       break;
292 
293     case ADDRESS_STREET:
294       g_free(self->priv->street);
295       self->priv->street = g_value_dup_string(value);
296       break;
297 
298     case ADDRESS_NUMBER:
299       g_free(self->priv->number);
300       self->priv->number = g_value_dup_string(value);
301       break;
302 
303     case ADDRESS_CITY:
304       g_free(self->priv->city);
305       self->priv->city = g_value_dup_string(value);
306       break;
307 
308     case ADDRESS_ZIP:
309       g_free(self->priv->zip);
310       self->priv->zip = g_value_dup_string(value);
311       break;
312 
313     case ADDRESS_PROVINCE:
314       g_free(self->priv->province);
315       self->priv->province = g_value_dup_string(value);
316       break;
317 
318     case ADDRESS_STATE:
319       g_free(self->priv->state);
320       self->priv->state = g_value_dup_string(value);
321       break;
322 
323     case ADDRESS_COUNTRY:
324       g_free(self->priv->country);
325       self->priv->country = g_value_dup_string(value);
326       break;
327 
328     default:
329       break;
330     }
331 }
332 
333 
334 static void
r_address_get_property(GObject * obj,guint property_id,GValue * value,GParamSpec * spec)335 r_address_get_property (GObject* obj, guint property_id,
336 			GValue* value, GParamSpec* spec)
337 {
338   RAddress* self = (RAddress*) obj;
339 
340   switch (property_id)
341     {
342     case ADDRESS_TYPE:
343       g_value_set_int(value, self->priv->type);
344       break;
345 
346     case ADDRESS_STREET:
347       g_value_set_string(value, self->priv->street);
348       break;
349 
350     case ADDRESS_NUMBER:
351       g_value_set_string(value, self->priv->number);
352       break;
353 
354     case ADDRESS_CITY:
355       g_value_set_string(value, self->priv->city);
356       break;
357 
358     case ADDRESS_ZIP:
359       g_value_set_string(value, self->priv->zip);
360       break;
361 
362     case ADDRESS_PROVINCE:
363       g_value_set_string(value, self->priv->province);
364       break;
365 
366     case ADDRESS_STATE:
367       g_value_set_string(value, self->priv->state);
368       break;
369 
370     case ADDRESS_COUNTRY:
371       g_value_set_string(value, self->priv->country);
372       break;
373 
374     default:
375       break;
376     }
377 }
378 
379 
380 
381 
382 /* **************** Public
383  */
384 
385 
386 /**
387  * r_address_new
388  *
389  * create a new #RAddress
390  *
391  * Returns: a #RAddress*
392  */
393 RAddress*
r_address_new(void)394 r_address_new(void)
395 {
396   RAddress* address;
397 
398   address = g_object_new(r_address_get_type(), NULL);
399 
400   return address;
401 }
402 
403 
404 /**
405  * r_address_free
406  * @address: a #RAddress
407  *
408  * free the #RAddress*
409  */
410 void
r_address_free(RAddress * address)411 r_address_free(RAddress* address)
412 {
413   g_return_if_fail(IS_R_ADDRESS(address));
414 
415   g_object_unref(address);
416 }
417 
418 
419 
420 /**
421  * r_address_have_data
422  * @address: a #RAddress
423  *
424  * check if address has some property setted
425  *
426  * returns: %TRUE if address has property setted, %FALSE otherwise
427  */
428 gboolean
r_address_have_data(RAddress * address)429 r_address_have_data (RAddress* address)
430 {
431   g_return_val_if_fail(IS_R_ADDRESS(address), FALSE);
432 
433   if (address->priv->type    || address->priv->street   ||
434       address-> priv->number || address->priv->city     ||
435       address->priv->zip     || address->priv->province ||
436       address->priv->state   || address->priv->country)
437     return TRUE;
438 
439   return FALSE;
440 }
441 
442 
443 
444 /**
445  * r_address_check
446  * @address: a #RAddress
447  * @property: an #RAddress's property
448  * @value: the property's value (if set)
449  *
450  * check if the given property is set.
451  *
452  * returns: %FALSE if the property is %NULL, otherwise it return %TRUE and
453  * the content of the property is copied into value
454  **/
455 gboolean
r_address_check(RAddress * address,const gchar * property,gchar ** value)456 r_address_check (RAddress* address, const gchar* property, gchar** value)
457 {
458   gchar* tmp;
459 
460   g_return_val_if_fail(IS_R_ADDRESS(address), FALSE);
461 
462   g_object_get(address, property, &tmp, NULL);
463 
464   if (tmp)
465     {
466       if (value)
467 	*value = tmp;
468 
469       return TRUE;
470     }
471 
472   return FALSE;
473 }
474 
475 
476 
477 /**
478  * r_address_copy
479  * @address: a #RAddress
480  *
481  * copy the given #RAddress
482  *
483  * Returns: a new allocated #RAddress
484  */
485 RAddress*
r_address_copy(RAddress * address)486 r_address_copy  (RAddress* address)
487 {
488   RAddress* new;
489   RAddressType type;
490   gchar *street, *number, *city;
491   gchar *zip, *province, *state, *country;
492 
493   g_return_val_if_fail(IS_R_ADDRESS(address), NULL);
494 
495   new = r_address_new();
496 
497   g_object_get(G_OBJECT(address), "address-type", &type, "street", &street,
498 	       "street-number", &number, "city", &city, "zip", &zip,
499 	       "province", &province, "state", &state,
500 	       "country", &country, NULL);
501 
502   g_object_set(G_OBJECT(new), "address-type", type, "street", street,
503 	       "street-number", number, "city", city, "zip", zip,
504 	       "province", province, "state", state,
505 	       "country", country, NULL);
506 
507   return new;
508 }
509 
510 
511 /**
512  * r_address_search
513  * @address: a #RAddress
514  * @str: a const gchar*
515  *
516  * search the string (or substring) str into the #RAddress
517  *
518  * Returns: %TRUE if str was found, %FALSE otherwise
519  */
520 gboolean
r_address_search(RAddress * address,const gchar * str)521 r_address_search (RAddress* address, const gchar* str)
522 {
523   g_return_val_if_fail(IS_R_ADDRESS(address), FALSE);
524   g_return_val_if_fail(str != NULL, FALSE);
525 
526   if (g_strrstr(address->priv->street, str))
527     return TRUE;
528 
529   if (g_strrstr(address->priv->number, str))
530     return TRUE;
531 
532   if (g_strrstr(address->priv->city, str))
533     return TRUE;
534 
535   if (g_strrstr(address->priv->zip, str))
536     return TRUE;
537 
538   if (g_strrstr(address->priv->province, str))
539     return TRUE;
540 
541   if (g_strrstr(address->priv->state, str))
542     return TRUE;
543 
544   if (g_strrstr(address->priv->country, str))
545     return TRUE;
546 
547   return FALSE;
548 }
549 
550 
551 /**
552  * r_address_lookup_enum2str
553  * @type: a #RAddressType
554  *
555  * find in the private lookup table the string associated with the given type
556  *
557  * Returns: a gchar*
558  */
559 gchar*
r_address_lookup_enum2str(RAddressType type)560 r_address_lookup_enum2str (RAddressType type)
561 {
562   return r_lookup_table_enum2str(table, type);
563 }
564 
565 
566 /**
567  * r_address_lookup_str2enum
568  * @type: a gchar*
569  *
570  *  find in the private lookup table the #RAddressType associated
571  *  with the given string
572  *
573  * Returns: a #RAddressType value or R_ADDRESS_UNKNOWN
574  */
575 RAddressType
r_address_lookup_str2enum(gchar * str)576 r_address_lookup_str2enum (gchar* str)
577 {
578   return (RAddressType) r_lookup_table_str2enum(table, str);
579 }
580 
581 
582 
583 /**
584  * r_address_lookup_enum2lbl
585  * @type: a #RAddressType
586  *
587  * find in the private lookup table the translated string associated
588  * with the given type
589  *
590  * Returns: a gchar*
591  */
592 gchar*
r_address_lookup_enum2lbl(RAddressType type)593 r_address_lookup_enum2lbl (RAddressType type)
594 {
595   return r_lookup_table_enum2lbl(table, type);
596 }
597 
598 
599 
600 /**
601  * r_address_lookup_str2lbl
602  * @type: a gchar*
603  *
604  *  find in the private lookup table the #RAddressType associated
605  *  with the given string
606  *
607  * Returns: a #RAddressType value or R_ADDRESS_UNKNOWN
608  */gchar*
r_address_lookup_str2lbl(gchar * str)609 r_address_lookup_str2lbl (gchar* str)
610 {
611   return r_lookup_table_str2lbl(table, str);
612 }
613 
614 
615 
616