1 /********************************************************************\
2  * gncAddress.c -- an Address object                                *
3  *                                                                  *
4  * This program is free software; you can redistribute it and/or    *
5  * modify it under the terms of the GNU General Public License as   *
6  * published by the Free Software Foundation; either version 2 of   *
7  * the License, or (at your option) any later version.              *
8  *                                                                  *
9  * This program is distributed in the hope that it will be useful,  *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
12  * GNU General Public License for more details.                     *
13  *                                                                  *
14  * You should have received a copy of the GNU General Public License*
15  * along with this program; if not, contact:                        *
16  *                                                                  *
17  * Free Software Foundation           Voice:  +1-617-542-5942       *
18  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
19  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
20  *                                                                  *
21 \********************************************************************/
22 
23 /*
24  * Copyright (C) 2001 Derek Atkins
25  * Author: Derek Atkins <warlord@MIT.EDU>
26  */
27 
28 #include <config.h>
29 
30 #include <glib.h>
31 #include <qofinstance-p.h>
32 
33 #include "gncAddress.h"
34 #include "gncAddressP.h"
35 #include "gncCustomerP.h"
36 #include "gnc-features.h"
37 
38 struct _gncAddress
39 {
40     QofInstance inst;
41 
42     QofBook *     book;
43     QofInstance * parent;
44     gboolean      dirty;
45     const char *  name;
46     const char *  addr1;
47     const char *  addr2;
48     const char *  addr3;
49     const char *  addr4;
50     const char *  phone;
51     const char *  fax;
52     const char *  email;
53 };
54 
55 struct _gncAddressClass
56 {
57     QofInstanceClass parent_class;
58 };
59 
60 static QofLogModule log_module = GNC_MOD_BUSINESS;
61 
62 #define _GNC_MOD_NAME	GNC_ADDRESS_MODULE_NAME
63 
64 static inline void mark_address (GncAddress *address);
mark_address(GncAddress * address)65 void mark_address (GncAddress *address)
66 {
67     address->dirty = TRUE;
68 
69     if (address->parent)
70         qof_instance_set_dirty(address->parent);
71     qof_event_gen (QOF_INSTANCE(address), QOF_EVENT_MODIFY, address->parent);
72     qof_event_gen (address->parent, QOF_EVENT_MODIFY, NULL);
73 }
74 
75 enum
76 {
77     PROP_0,
78     PROP_NAME,
79     PROP_ADDR1,
80     PROP_ADDR2,
81     PROP_ADDR3,
82     PROP_ADDR4,
83     PROP_PHONE,
84     PROP_FAX,
85     PROP_EMAIL
86 };
87 
88 /* GObject Initialization */
89 G_DEFINE_TYPE(GncAddress, gnc_address, QOF_TYPE_INSTANCE);
90 
91 static void
gnc_address_init(GncAddress * addr)92 gnc_address_init(GncAddress* addr)
93 {
94 }
95 
96 static void
gnc_address_dispose(GObject * addrp)97 gnc_address_dispose(GObject *addrp)
98 {
99     G_OBJECT_CLASS(gnc_address_parent_class)->dispose(addrp);
100 }
101 
102 static void
gnc_address_finalize(GObject * addrp)103 gnc_address_finalize(GObject* addrp)
104 {
105     G_OBJECT_CLASS(gnc_address_parent_class)->finalize(addrp);
106 }
107 
108 static void
gnc_address_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)109 gnc_address_get_property (GObject         *object,
110                           guint            prop_id,
111                           GValue          *value,
112                           GParamSpec      *pspec)
113 {
114     GncAddress *address;
115 
116     g_return_if_fail(GNC_IS_ADDRESS(object));
117 
118     address = GNC_ADDRESS(object);
119     switch (prop_id)
120     {
121     case PROP_NAME:
122         g_value_set_string(value, address->name);
123         break;
124     case PROP_ADDR1:
125         g_value_set_string(value, address->addr1);
126         break;
127     case PROP_ADDR2:
128         g_value_set_string(value, address->addr2);
129         break;
130     case PROP_ADDR3:
131         g_value_set_string(value, address->addr3);
132         break;
133     case PROP_ADDR4:
134         g_value_set_string(value, address->addr4);
135         break;
136     case PROP_PHONE:
137         g_value_set_string(value, address->phone);
138         break;
139     case PROP_FAX:
140         g_value_set_string(value, address->fax);
141         break;
142     case PROP_EMAIL:
143         g_value_set_string(value, address->email);
144         break;
145     default:
146         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
147         break;
148     }
149 }
150 
151 static void
gnc_address_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)152 gnc_address_set_property (GObject         *object,
153                           guint            prop_id,
154                           const GValue          *value,
155                           GParamSpec      *pspec)
156 {
157     GncAddress *address;
158 
159     g_return_if_fail(GNC_IS_ADDRESS(object));
160 
161     address = GNC_ADDRESS(object);
162     switch (prop_id)
163     {
164     case PROP_NAME:
165         gncAddressSetName(address, g_value_get_string(value));
166         break;
167     case PROP_ADDR1:
168         gncAddressSetAddr1(address, g_value_get_string(value));
169         break;
170     case PROP_ADDR2:
171         gncAddressSetAddr2(address, g_value_get_string(value));
172         break;
173     case PROP_ADDR3:
174         gncAddressSetAddr3(address, g_value_get_string(value));
175         break;
176     case PROP_ADDR4:
177         gncAddressSetAddr4(address, g_value_get_string(value));
178         break;
179     case PROP_PHONE:
180         gncAddressSetPhone(address, g_value_get_string(value));
181         break;
182     case PROP_FAX:
183         gncAddressSetFax(address, g_value_get_string(value));
184         break;
185     case PROP_EMAIL:
186         gncAddressSetEmail(address, g_value_get_string(value));
187         break;
188     default:
189         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
190         break;
191     }
192 }
193 
194 /** Returns a list of my type of object which refers to an object.  For example, when called as
195         qof_instance_get_typed_referring_object_list(taxtable, account);
196     it will return the list of taxtables which refer to a specific account.  The result should be the
197     same regardless of which taxtable object is used.  The list must be freed by the caller but the
198     objects on the list must not.
199  */
200 static GList*
impl_get_typed_referring_object_list(const QofInstance * inst,const QofInstance * ref)201 impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
202 {
203     /* Refers to nothing.  The parent field doesn't really count since the parent knows which address
204        belongs to it. */
205     return NULL;
206 }
207 
208 static void
gnc_address_class_init(GncAddressClass * klass)209 gnc_address_class_init (GncAddressClass *klass)
210 {
211     GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
212     QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
213 
214     gobject_class->dispose = gnc_address_dispose;
215     gobject_class->finalize = gnc_address_finalize;
216     gobject_class->set_property = gnc_address_set_property;
217     gobject_class->get_property = gnc_address_get_property;
218 
219     qof_class->get_display_name = NULL;
220     qof_class->refers_to_object = NULL;
221     qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
222 
223     g_object_class_install_property
224     (gobject_class,
225      PROP_NAME,
226      g_param_spec_string ("name",
227                           "Address Name",
228                           "The address name is an arbitrary string "
229                           "assigned by the user.  It is intended to "
230                           "a short string to identify the address.",
231                           NULL,
232                           G_PARAM_READWRITE));
233 
234     g_object_class_install_property
235     (gobject_class,
236      PROP_ADDR1,
237      g_param_spec_string ("addr1",
238                           "Address Line 1",
239                           "The address line 1 is an arbitrary string "
240                           "assigned by the user.  It is the first "
241                           "line of the address.",
242                           NULL,
243                           G_PARAM_READWRITE));
244 
245     g_object_class_install_property
246     (gobject_class,
247      PROP_ADDR2,
248      g_param_spec_string ("addr2",
249                           "Address Line 2",
250                           "The address line 2 is an arbitrary string "
251                           "assigned by the user.  It is the second "
252                           "line of the address.",
253                           NULL,
254                           G_PARAM_READWRITE));
255 
256     g_object_class_install_property
257     (gobject_class,
258      PROP_ADDR3,
259      g_param_spec_string ("addr3",
260                           "Address Line 3",
261                           "The address line 3 is an arbitrary string "
262                           "assigned by the user.  It is the third "
263                           "line of the address.",
264                           NULL,
265                           G_PARAM_READWRITE));
266 
267     g_object_class_install_property
268     (gobject_class,
269      PROP_ADDR4,
270      g_param_spec_string ("addr4",
271                           "Address Line 4",
272                           "The address line 4 is an arbitrary string "
273                           "assigned by the user.  It is the fourth "
274                           "line of the address.",
275                           NULL,
276                           G_PARAM_READWRITE));
277 
278     g_object_class_install_property
279     (gobject_class,
280      PROP_PHONE,
281      g_param_spec_string ("phone",
282                           "Phone",
283                           "The phone number is the number at this address.",
284                           NULL,
285                           G_PARAM_READWRITE));
286 
287     g_object_class_install_property
288     (gobject_class,
289      PROP_FAX,
290      g_param_spec_string ("fax",
291                           "Fax",
292                           "The fax number at this address.",
293                           NULL,
294                           G_PARAM_READWRITE));
295 
296     g_object_class_install_property
297     (gobject_class,
298      PROP_EMAIL,
299      g_param_spec_string ("email",
300                           "E-mail address",
301                           "The e-mail address at this address.",
302                           NULL,
303                           G_PARAM_READWRITE));
304 }
305 
306 /* Create/Destroy functions */
307 
308 GncAddress *
gncAddressCreate(QofBook * book,QofInstance * prnt)309 gncAddressCreate (QofBook *book, QofInstance *prnt)
310 {
311     GncAddress *addr;
312 
313     if (!book) return NULL;
314 
315     addr = g_object_new (GNC_TYPE_ADDRESS, NULL);
316     qof_instance_init_data(&addr->inst, GNC_ID_ADDRESS, book);
317     addr->book = book;
318     addr->dirty = FALSE;
319     addr->parent = prnt;
320 
321     addr->name = CACHE_INSERT ("");
322     addr->addr1 = CACHE_INSERT ("");
323     addr->addr2 = CACHE_INSERT ("");
324     addr->addr3 = CACHE_INSERT ("");
325     addr->addr4 = CACHE_INSERT ("");
326     addr->phone = CACHE_INSERT ("");
327     addr->fax = CACHE_INSERT ("");
328     addr->email = CACHE_INSERT ("");
329 
330     return addr;
331 }
332 
333 static GncAddress *
qofAddressCreate(QofBook * book)334 qofAddressCreate (QofBook *book)
335 {
336     /* The address will get set later by another function */
337     return gncAddressCreate(book, NULL);
338 }
339 
340 static void
qofAddressSetOwner(GncAddress * addr,QofInstance * ent)341 qofAddressSetOwner(GncAddress *addr, QofInstance *ent)
342 {
343     if (!addr || !ent)
344     {
345         return;
346     }
347     if (addr->parent == NULL)
348     {
349         addr->parent = ent;
350     }
351 }
352 
353 static QofInstance*
qofAddressGetOwner(const GncAddress * addr)354 qofAddressGetOwner(const GncAddress *addr)
355 {
356 
357     if (!addr)
358     {
359         return NULL;
360     }
361     return addr->parent;
362 }
363 
364 void
gncAddressDestroy(GncAddress * addr)365 gncAddressDestroy (GncAddress *addr)
366 {
367     if (!addr) return;
368     qof_instance_set_destroying(addr, TRUE);
369     gncAddressCommitEdit (addr);
370 }
371 
372 static void
gncAddressFree(GncAddress * addr)373 gncAddressFree (GncAddress *addr)
374 {
375     if (!addr) return;
376 
377     qof_event_gen (&addr->inst, QOF_EVENT_DESTROY, NULL);
378 
379     CACHE_REMOVE (addr->name);
380     CACHE_REMOVE (addr->addr1);
381     CACHE_REMOVE (addr->addr2);
382     CACHE_REMOVE (addr->addr3);
383     CACHE_REMOVE (addr->addr4);
384     CACHE_REMOVE (addr->phone);
385     CACHE_REMOVE (addr->fax);
386     CACHE_REMOVE (addr->email);
387 
388     /* qof_instance_release (&addr->inst); */
389     g_object_unref (addr);
390 }
391 
392 
393 /* Set functions */
394 
395 #define SET_STR(obj, member, str) { \
396 	if (member == str) return; \
397 	if (!g_strcmp0 (member, str)) return; \
398 	gncAddressBeginEdit (obj); \
399 	CACHE_REPLACE(member, str); \
400 	}
401 
gncAddressSetName(GncAddress * addr,const char * name)402 void gncAddressSetName (GncAddress *addr, const char *name)
403 {
404     if (!addr) return;
405     if (!name) return;
406     SET_STR(addr, addr->name, name);
407     mark_address (addr);
408     gncAddressCommitEdit (addr);
409 }
410 
gncAddressSetAddr1(GncAddress * addr,const char * addr1)411 void gncAddressSetAddr1 (GncAddress *addr, const char *addr1)
412 {
413     if (!addr) return;
414     if (!addr1) return;
415     SET_STR(addr, addr->addr1, addr1);
416     mark_address (addr);
417     gncAddressCommitEdit (addr);
418 }
419 
gncAddressSetAddr2(GncAddress * addr,const char * addr2)420 void gncAddressSetAddr2 (GncAddress *addr, const char *addr2)
421 {
422     if (!addr) return;
423     if (!addr2) return;
424     SET_STR(addr, addr->addr2, addr2);
425     mark_address (addr);
426     gncAddressCommitEdit (addr);
427 }
428 
gncAddressSetAddr3(GncAddress * addr,const char * addr3)429 void gncAddressSetAddr3 (GncAddress *addr, const char *addr3)
430 {
431     if (!addr) return;
432     if (!addr3) return;
433     SET_STR(addr, addr->addr3, addr3);
434     mark_address (addr);
435     gncAddressCommitEdit (addr);
436 }
437 
gncAddressSetAddr4(GncAddress * addr,const char * addr4)438 void gncAddressSetAddr4 (GncAddress *addr, const char *addr4)
439 {
440     if (!addr) return;
441     if (!addr4) return;
442     SET_STR(addr, addr->addr4, addr4);
443     mark_address (addr);
444     gncAddressCommitEdit (addr);
445 }
446 
gncAddressSetPhone(GncAddress * addr,const char * phone)447 void gncAddressSetPhone (GncAddress *addr, const char *phone)
448 {
449     if (!addr) return;
450     if (!phone) return;
451     SET_STR(addr, addr->phone, phone);
452     mark_address (addr);
453     gncAddressCommitEdit (addr);
454 }
455 
gncAddressSetFax(GncAddress * addr,const char * fax)456 void gncAddressSetFax (GncAddress *addr, const char *fax)
457 {
458     if (!addr) return;
459     if (!fax) return;
460     SET_STR(addr, addr->fax, fax);
461     mark_address (addr);
462     gncAddressCommitEdit (addr);
463 }
464 
gncAddressSetEmail(GncAddress * addr,const char * email)465 void gncAddressSetEmail (GncAddress *addr, const char *email)
466 {
467     if (!addr) return;
468     if (!email) return;
469     SET_STR(addr, addr->email, email);
470     mark_address (addr);
471     gncAddressCommitEdit (addr);
472 }
473 
gncAddressBeginEdit(GncAddress * addr)474 void gncAddressBeginEdit (GncAddress *addr)
475 {
476     qof_begin_edit (&addr->inst);
477 }
478 
gncAddressOnError(QofInstance * inst,QofBackendError errcode)479 static void gncAddressOnError (QofInstance *inst, QofBackendError errcode)
480 {
481     PERR("Address QofBackend Failure: %d", errcode);
482     gnc_engine_signal_commit_error( errcode );
483 }
484 
gncAddressOnDone(QofInstance * addr)485 static void gncAddressOnDone (QofInstance *addr) { }
486 
address_free(QofInstance * inst)487 static void address_free (QofInstance *inst)
488 {
489     GncAddress *addr = (GncAddress *) inst;
490     gncAddressFree (addr);
491 }
492 
gncAddressCommitEdit(GncAddress * addr)493 void gncAddressCommitEdit (GncAddress *addr)
494 {
495     /* GnuCash 2.6.3 and earlier didn't handle address kvp's... */
496      if (qof_instance_has_kvp(QOF_INSTANCE(addr)))
497         gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (addr)), GNC_FEATURE_KVP_EXTRA_DATA);
498 
499     if (!qof_commit_edit (QOF_INSTANCE(addr))) return;
500     qof_commit_edit_part2 (&addr->inst, gncAddressOnError,
501                            gncAddressOnDone, address_free);
502 }
503 
504 
505 /* Get Functions */
506 
gncAddressGetName(const GncAddress * addr)507 const char * gncAddressGetName (const GncAddress *addr)
508 {
509     if (!addr) return NULL;
510     return addr->name;
511 }
512 
gncAddressGetAddr1(const GncAddress * addr)513 const char * gncAddressGetAddr1 (const GncAddress *addr)
514 {
515     if (!addr) return NULL;
516     return addr->addr1;
517 }
518 
gncAddressGetAddr2(const GncAddress * addr)519 const char * gncAddressGetAddr2 (const GncAddress *addr)
520 {
521     if (!addr) return NULL;
522     return addr->addr2;
523 }
524 
gncAddressGetAddr3(const GncAddress * addr)525 const char * gncAddressGetAddr3 (const GncAddress *addr)
526 {
527     if (!addr) return NULL;
528     return addr->addr3;
529 }
530 
gncAddressGetAddr4(const GncAddress * addr)531 const char * gncAddressGetAddr4 (const GncAddress *addr)
532 {
533     if (!addr) return NULL;
534     return addr->addr4;
535 }
536 
gncAddressGetPhone(const GncAddress * addr)537 const char * gncAddressGetPhone (const GncAddress *addr)
538 {
539     if (!addr) return NULL;
540     return addr->phone;
541 }
542 
gncAddressGetFax(const GncAddress * addr)543 const char * gncAddressGetFax (const GncAddress *addr)
544 {
545     if (!addr) return NULL;
546     return addr->fax;
547 }
548 
gncAddressGetEmail(const GncAddress * addr)549 const char * gncAddressGetEmail (const GncAddress *addr)
550 {
551     if (!addr) return NULL;
552     return addr->email;
553 }
554 
gncAddressIsDirty(const GncAddress * addr)555 gboolean gncAddressIsDirty (const GncAddress *addr)
556 {
557     if (!addr) return FALSE;
558     return addr->dirty;
559 }
560 
gncAddressClearDirty(GncAddress * addr)561 void gncAddressClearDirty (GncAddress *addr)
562 {
563     if (!addr) return;
564     addr->dirty = FALSE;
565 }
566 
gncAddressCompare(const GncAddress * a,const GncAddress * b)567 int gncAddressCompare (const GncAddress *a, const GncAddress *b)
568 {
569     if (!a && !b) return 0;
570     if (!a && b) return 1;
571     if (a && !b) return -1;
572 
573     return g_strcmp0 (a->name, b->name);
574 }
575 
576 gboolean
gncAddressEqual(const GncAddress * a,const GncAddress * b)577 gncAddressEqual(const GncAddress* a, const GncAddress* b)
578 {
579     if (a == NULL && b == NULL) return TRUE;
580     if (a == NULL || b == NULL) return FALSE;
581 
582     g_return_val_if_fail(GNC_IS_ADDRESS(a), FALSE);
583     g_return_val_if_fail(GNC_IS_ADDRESS(b), FALSE);
584 
585     if (g_strcmp0(a->name, b->name) != 0)
586     {
587         PWARN("names differ: %s vs %s", a->name, b->name);
588         return FALSE;
589     }
590     if (g_strcmp0(a->addr1, b->addr1) != 0)
591     {
592         PWARN("address lines 1 differ: %s vs %s", a->addr1, b->addr1);
593         return FALSE;
594     }
595     if (g_strcmp0(a->addr2, b->addr2) != 0)
596     {
597         PWARN("address lines 2 differ: %s vs %s", a->addr2, b->addr1);
598         return FALSE;
599     }
600     if (g_strcmp0(a->addr3, b->addr3) != 0)
601     {
602         PWARN("address lines 3 differ: %s vs %s", a->addr3, b->addr3);
603         return FALSE;
604     }
605     if (g_strcmp0(a->addr4, b->addr4) != 0)
606     {
607         PWARN("address lines 4 differ: %s vs %s", a->addr4, b->addr4);
608         return FALSE;
609     }
610     if (g_strcmp0(a->phone, b->phone) != 0)
611     {
612         PWARN("phone numbers differ: %s vs %s", a->phone, b->phone);
613         return FALSE;
614     }
615     if (g_strcmp0(a->fax, b->fax) != 0)
616     {
617         PWARN("fax numbers differ: %s vs %s", a->fax, b->fax);
618         return FALSE;
619     }
620     if (g_strcmp0(a->email, b->email) != 0)
621     {
622         PWARN("email addresses differ: %s vs %s", a->email, b->email);
623         return FALSE;
624     }
625 
626     return TRUE;
627 }
628 
629 static QofObject GncAddressDesc =
630 {
631     DI(.interface_version = ) QOF_OBJECT_VERSION,
632     DI(.e_type            = ) GNC_ID_ADDRESS,
633     DI(.type_label        = ) "Address",
634     DI(.create            = ) (gpointer)qofAddressCreate,
635     DI(.book_begin        = ) NULL,
636     DI(.book_end          = ) NULL,
637     DI(.is_dirty          = ) qof_collection_is_dirty,
638     DI(.mark_clean        = ) qof_collection_mark_clean,
639     DI(.foreach           = ) qof_collection_foreach,
640     DI(.printable         = ) NULL,
641     DI(.version_cmp       = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
642 };
643 
gncAddressRegister(void)644 gboolean gncAddressRegister (void)
645 {
646     static QofParam params[] =
647     {
648 
649         { ADDRESS_NAME,  QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetName,  (QofSetterFunc)gncAddressSetName },
650         { ADDRESS_ONE,   QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr1, (QofSetterFunc)gncAddressSetAddr1 },
651         { ADDRESS_TWO,   QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr2, (QofSetterFunc)gncAddressSetAddr2 },
652         { ADDRESS_THREE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr3, (QofSetterFunc)gncAddressSetAddr3 },
653         { ADDRESS_FOUR,  QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr4, (QofSetterFunc)gncAddressSetAddr4 },
654         { ADDRESS_PHONE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetPhone, (QofSetterFunc)gncAddressSetPhone },
655         { ADDRESS_FAX,   QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetFax,   (QofSetterFunc)gncAddressSetFax },
656         { ADDRESS_EMAIL, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetEmail, (QofSetterFunc)gncAddressSetEmail },
657         { ADDRESS_OWNER, QOF_TYPE_CHOICE, (QofAccessFunc)qofAddressGetOwner, (QofSetterFunc)qofAddressSetOwner },
658         { QOF_PARAM_BOOK, QOF_ID_BOOK,   (QofAccessFunc)qof_instance_get_book, NULL },
659         { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
660         { NULL },
661     };
662 
663     qof_class_register (GNC_ID_ADDRESS, (QofSortFunc)gncAddressCompare, params);
664     if (!qof_choice_add_class(GNC_ID_CUSTOMER, GNC_ID_ADDRESS, ADDRESS_OWNER))
665     {
666         return FALSE;
667     }
668 
669     return qof_object_register(&GncAddressDesc);
670 }
671