GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gncAddress.c
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 [email protected] *
20  * *
21 \********************************************************************/
22 
23 /*
24  * Copyright (C) 2001 Derek Atkins
25  * Author: Derek Atkins <[email protected]>
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 
39 {
40  QofInstance inst;
41 
42  QofBook * book;
43  QofInstance * parent;
44  gboolean dirty;
45  char * name;
46  char * addr1;
47  char * addr2;
48  char * addr3;
49  char * addr4;
50  char * phone;
51  char * fax;
52  char * email;
53 };
54 
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 G_INLINE_FUNC void mark_address (GncAddress *address);
65 void mark_address (GncAddress *address)
66 {
67  address->dirty = TRUE;
68 
69  qof_event_gen (QOF_INSTANCE(address), QOF_EVENT_MODIFY, address->parent);
70  qof_event_gen (address->parent, QOF_EVENT_MODIFY, NULL);
71 }
72 
73 enum
74 {
75  PROP_0,
76  PROP_NAME,
77  PROP_ADDR1,
78  PROP_ADDR2,
79  PROP_ADDR3,
80  PROP_ADDR4,
81  PROP_PHONE,
82  PROP_FAX,
83  PROP_EMAIL
84 };
85 
86 /* GObject Initialization */
87 G_DEFINE_TYPE(GncAddress, gnc_address, QOF_TYPE_INSTANCE);
88 
89 static void
90 gnc_address_init(GncAddress* addr)
91 {
92 }
93 
94 static void
95 gnc_address_dispose(GObject *addrp)
96 {
97  G_OBJECT_CLASS(gnc_address_parent_class)->dispose(addrp);
98 }
99 
100 static void
101 gnc_address_finalize(GObject* addrp)
102 {
103  G_OBJECT_CLASS(gnc_address_parent_class)->finalize(addrp);
104 }
105 
106 static void
107 gnc_address_get_property (GObject *object,
108  guint prop_id,
109  GValue *value,
110  GParamSpec *pspec)
111 {
112  GncAddress *address;
113 
114  g_return_if_fail(GNC_IS_ADDRESS(object));
115 
116  address = GNC_ADDRESS(object);
117  switch (prop_id)
118  {
119  case PROP_NAME:
120  g_value_set_string(value, address->name);
121  break;
122  case PROP_ADDR1:
123  g_value_set_string(value, address->addr1);
124  break;
125  case PROP_ADDR2:
126  g_value_set_string(value, address->addr2);
127  break;
128  case PROP_ADDR3:
129  g_value_set_string(value, address->addr3);
130  break;
131  case PROP_ADDR4:
132  g_value_set_string(value, address->addr4);
133  break;
134  case PROP_PHONE:
135  g_value_set_string(value, address->phone);
136  break;
137  case PROP_FAX:
138  g_value_set_string(value, address->fax);
139  break;
140  case PROP_EMAIL:
141  g_value_set_string(value, address->email);
142  break;
143  default:
144  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
145  break;
146  }
147 }
148 
149 static void
150 gnc_address_set_property (GObject *object,
151  guint prop_id,
152  const GValue *value,
153  GParamSpec *pspec)
154 {
155  GncAddress *address;
156 
157  g_return_if_fail(GNC_IS_ADDRESS(object));
158 
159  address = GNC_ADDRESS(object);
160  switch (prop_id)
161  {
162  case PROP_NAME:
163  gncAddressSetName(address, g_value_get_string(value));
164  break;
165  case PROP_ADDR1:
166  gncAddressSetAddr1(address, g_value_get_string(value));
167  break;
168  case PROP_ADDR2:
169  gncAddressSetAddr2(address, g_value_get_string(value));
170  break;
171  case PROP_ADDR3:
172  gncAddressSetAddr3(address, g_value_get_string(value));
173  break;
174  case PROP_ADDR4:
175  gncAddressSetAddr4(address, g_value_get_string(value));
176  break;
177  case PROP_PHONE:
178  gncAddressSetPhone(address, g_value_get_string(value));
179  break;
180  case PROP_FAX:
181  gncAddressSetFax(address, g_value_get_string(value));
182  break;
183  case PROP_EMAIL:
184  gncAddressSetEmail(address, g_value_get_string(value));
185  break;
186  default:
187  G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
188  break;
189  }
190 }
191 
198 static GList*
199 impl_get_typed_referring_object_list(const QofInstance* inst, const QofInstance* ref)
200 {
201  /* Refers to nothing. The parent field doesn't really count since the parent knows which address
202  belongs to it. */
203  return NULL;
204 }
205 
206 static void
207 gnc_address_class_init (GncAddressClass *klass)
208 {
209  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
210  QofInstanceClass* qof_class = QOF_INSTANCE_CLASS(klass);
211 
212  gobject_class->dispose = gnc_address_dispose;
213  gobject_class->finalize = gnc_address_finalize;
214  gobject_class->set_property = gnc_address_set_property;
215  gobject_class->get_property = gnc_address_get_property;
216 
217  qof_class->get_display_name = NULL;
218  qof_class->refers_to_object = NULL;
219  qof_class->get_typed_referring_object_list = impl_get_typed_referring_object_list;
220 
221  g_object_class_install_property
222  (gobject_class,
223  PROP_NAME,
224  g_param_spec_string ("name",
225  "Address Name",
226  "The address name is an arbitrary string "
227  "assigned by the user. It is intended to "
228  "a short string to identify the address.",
229  NULL,
230  G_PARAM_READWRITE));
231 
232  g_object_class_install_property
233  (gobject_class,
234  PROP_ADDR1,
235  g_param_spec_string ("addr1",
236  "Address Line 1",
237  "The address line 1 is an arbitrary string "
238  "assigned by the user. It is the first "
239  "line of the address.",
240  NULL,
241  G_PARAM_READWRITE));
242 
243  g_object_class_install_property
244  (gobject_class,
245  PROP_ADDR2,
246  g_param_spec_string ("addr2",
247  "Address Line 2",
248  "The address line 2 is an arbitrary string "
249  "assigned by the user. It is the second "
250  "line of the address.",
251  NULL,
252  G_PARAM_READWRITE));
253 
254  g_object_class_install_property
255  (gobject_class,
256  PROP_ADDR3,
257  g_param_spec_string ("addr3",
258  "Address Line 3",
259  "The address line 3 is an arbitrary string "
260  "assigned by the user. It is the third "
261  "line of the address.",
262  NULL,
263  G_PARAM_READWRITE));
264 
265  g_object_class_install_property
266  (gobject_class,
267  PROP_ADDR4,
268  g_param_spec_string ("addr4",
269  "Address Line 4",
270  "The address line 4 is an arbitrary string "
271  "assigned by the user. It is the fourth "
272  "line of the address.",
273  NULL,
274  G_PARAM_READWRITE));
275 
276  g_object_class_install_property
277  (gobject_class,
278  PROP_PHONE,
279  g_param_spec_string ("phone",
280  "Phone",
281  "The phone number is the number at this address.",
282  NULL,
283  G_PARAM_READWRITE));
284 
285  g_object_class_install_property
286  (gobject_class,
287  PROP_FAX,
288  g_param_spec_string ("fax",
289  "Fax",
290  "The fax number at this address.",
291  NULL,
292  G_PARAM_READWRITE));
293 
294  g_object_class_install_property
295  (gobject_class,
296  PROP_EMAIL,
297  g_param_spec_string ("email",
298  "E-mail address",
299  "The e-mail address at this address.",
300  NULL,
301  G_PARAM_READWRITE));
302 }
303 
304 /* Create/Destroy functions */
305 
306 GncAddress *
307 gncAddressCreate (QofBook *book, QofInstance *prnt)
308 {
309  GncAddress *addr;
310 
311  if (!book) return NULL;
312 
313  addr = g_object_new (GNC_TYPE_ADDRESS, NULL);
314  qof_instance_init_data(&addr->inst, GNC_ID_ADDRESS, book);
315  addr->book = book;
316  addr->dirty = FALSE;
317  addr->parent = prnt;
318 
319  addr->name = CACHE_INSERT ("");
320  addr->addr1 = CACHE_INSERT ("");
321  addr->addr2 = CACHE_INSERT ("");
322  addr->addr3 = CACHE_INSERT ("");
323  addr->addr4 = CACHE_INSERT ("");
324  addr->phone = CACHE_INSERT ("");
325  addr->fax = CACHE_INSERT ("");
326  addr->email = CACHE_INSERT ("");
327 
328  return addr;
329 }
330 
331 static GncAddress *
332 qofAddressCreate (QofBook *book)
333 {
334  /* The address will get set later by another function */
335  return gncAddressCreate(book, NULL);
336 }
337 
338 static void
339 qofAddressSetOwner(GncAddress *addr, QofInstance *ent)
340 {
341  if (!addr || !ent)
342  {
343  return;
344  }
345  if (addr->parent == NULL)
346  {
347  addr->parent = ent;
348  }
349 }
350 
351 static QofInstance*
352 qofAddressGetOwner(const GncAddress *addr)
353 {
354 
355  if (!addr)
356  {
357  return NULL;
358  }
359  return addr->parent;
360 }
361 
362 void
363 gncAddressDestroy (GncAddress *addr)
364 {
365  if (!addr) return;
366  qof_instance_set_destroying(addr, TRUE);
367  gncAddressCommitEdit (addr);
368 }
369 
370 static void
371 gncAddressFree (GncAddress *addr)
372 {
373  if (!addr) return;
374 
375  qof_event_gen (&addr->inst, QOF_EVENT_DESTROY, NULL);
376 
377  CACHE_REMOVE (addr->name);
378  CACHE_REMOVE (addr->addr1);
379  CACHE_REMOVE (addr->addr2);
380  CACHE_REMOVE (addr->addr3);
381  CACHE_REMOVE (addr->addr4);
382  CACHE_REMOVE (addr->phone);
383  CACHE_REMOVE (addr->fax);
384  CACHE_REMOVE (addr->email);
385 
386  /* qof_instance_release (&addr->inst); */
387  g_object_unref (addr);
388 }
389 
390 
391 /* Set functions */
392 
393 #define SET_STR(obj, member, str) { \
394  char * tmp; \
395  \
396  if (member == str) return; \
397  if (!g_strcmp0 (member, str)) return; \
398  gncAddressBeginEdit (obj); \
399  tmp = CACHE_INSERT (str); \
400  CACHE_REMOVE (member); \
401  member = tmp; \
402  }
403 
404 void gncAddressSetName (GncAddress *addr, const char *name)
405 {
406  if (!addr) return;
407  if (!name) return;
408  SET_STR(addr, addr->name, name);
409  mark_address (addr);
410  gncAddressCommitEdit (addr);
411 }
412 
413 void gncAddressSetAddr1 (GncAddress *addr, const char *addr1)
414 {
415  if (!addr) return;
416  if (!addr1) return;
417  SET_STR(addr, addr->addr1, addr1);
418  mark_address (addr);
419  gncAddressCommitEdit (addr);
420 }
421 
422 void gncAddressSetAddr2 (GncAddress *addr, const char *addr2)
423 {
424  if (!addr) return;
425  if (!addr2) return;
426  SET_STR(addr, addr->addr2, addr2);
427  mark_address (addr);
428  gncAddressCommitEdit (addr);
429 }
430 
431 void gncAddressSetAddr3 (GncAddress *addr, const char *addr3)
432 {
433  if (!addr) return;
434  if (!addr3) return;
435  SET_STR(addr, addr->addr3, addr3);
436  mark_address (addr);
437  gncAddressCommitEdit (addr);
438 }
439 
440 void gncAddressSetAddr4 (GncAddress *addr, const char *addr4)
441 {
442  if (!addr) return;
443  if (!addr4) return;
444  SET_STR(addr, addr->addr4, addr4);
445  mark_address (addr);
446  gncAddressCommitEdit (addr);
447 }
448 
449 void gncAddressSetPhone (GncAddress *addr, const char *phone)
450 {
451  if (!addr) return;
452  if (!phone) return;
453  SET_STR(addr, addr->phone, phone);
454  mark_address (addr);
455  gncAddressCommitEdit (addr);
456 }
457 
458 void gncAddressSetFax (GncAddress *addr, const char *fax)
459 {
460  if (!addr) return;
461  if (!fax) return;
462  SET_STR(addr, addr->fax, fax);
463  mark_address (addr);
464  gncAddressCommitEdit (addr);
465 }
466 
467 void gncAddressSetEmail (GncAddress *addr, const char *email)
468 {
469  if (!addr) return;
470  if (!email) return;
471  SET_STR(addr, addr->email, email);
472  mark_address (addr);
473  gncAddressCommitEdit (addr);
474 }
475 
476 void gncAddressBeginEdit (GncAddress *addr)
477 {
478  qof_begin_edit (&addr->inst);
479 }
480 
481 static void gncAddressOnError (QofInstance *inst, QofBackendError errcode)
482 {
483  PERR("Address QofBackend Failure: %d", errcode);
484  gnc_engine_signal_commit_error( errcode );
485 }
486 
487 static void gncAddressOnDone (QofInstance *addr) { }
488 
489 static void address_free (QofInstance *inst)
490 {
491  GncAddress *addr = (GncAddress *) inst;
492  gncAddressFree (addr);
493 }
494 
495 void gncAddressCommitEdit (GncAddress *addr)
496 {
497  /* GnuCash 2.6.3 and earlier didn't handle address kvp's... */
498  if (!kvp_frame_is_empty (addr->inst.kvp_data))
499  gnc_features_set_used (qof_instance_get_book (QOF_INSTANCE (addr)), GNC_FEATURE_KVP_EXTRA_DATA);
500 
501  if (!qof_commit_edit (QOF_INSTANCE(addr))) return;
502  qof_commit_edit_part2 (&addr->inst, gncAddressOnError,
503  gncAddressOnDone, address_free);
504 }
505 
506 
507 /* Get Functions */
508 
509 const char * gncAddressGetName (const GncAddress *addr)
510 {
511  if (!addr) return NULL;
512  return addr->name;
513 }
514 
515 const char * gncAddressGetAddr1 (const GncAddress *addr)
516 {
517  if (!addr) return NULL;
518  return addr->addr1;
519 }
520 
521 const char * gncAddressGetAddr2 (const GncAddress *addr)
522 {
523  if (!addr) return NULL;
524  return addr->addr2;
525 }
526 
527 const char * gncAddressGetAddr3 (const GncAddress *addr)
528 {
529  if (!addr) return NULL;
530  return addr->addr3;
531 }
532 
533 const char * gncAddressGetAddr4 (const GncAddress *addr)
534 {
535  if (!addr) return NULL;
536  return addr->addr4;
537 }
538 
539 const char * gncAddressGetPhone (const GncAddress *addr)
540 {
541  if (!addr) return NULL;
542  return addr->phone;
543 }
544 
545 const char * gncAddressGetFax (const GncAddress *addr)
546 {
547  if (!addr) return NULL;
548  return addr->fax;
549 }
550 
551 const char * gncAddressGetEmail (const GncAddress *addr)
552 {
553  if (!addr) return NULL;
554  return addr->email;
555 }
556 
557 gboolean gncAddressIsDirty (const GncAddress *addr)
558 {
559  if (!addr) return FALSE;
560  return addr->dirty;
561 }
562 
563 void gncAddressClearDirty (GncAddress *addr)
564 {
565  if (!addr) return;
566  addr->dirty = FALSE;
567 }
568 
569 int gncAddressCompare (const GncAddress *a, const GncAddress *b)
570 {
571  if (!a && !b) return 0;
572  if (!a && b) return 1;
573  if (a && !b) return -1;
574 
575  return g_strcmp0 (a->name, b->name);
576 }
577 
578 gboolean
580 {
581  if (a == NULL && b == NULL) return TRUE;
582  if (a == NULL || b == NULL) return FALSE;
583 
584  g_return_val_if_fail(GNC_IS_ADDRESS(a), FALSE);
585  g_return_val_if_fail(GNC_IS_ADDRESS(b), FALSE);
586 
587  if (g_strcmp0(a->name, b->name) != 0)
588  {
589  PWARN("names differ: %s vs %s", a->name, b->name);
590  return FALSE;
591  }
592  if (g_strcmp0(a->addr1, b->addr1) != 0)
593  {
594  PWARN("address lines 1 differ: %s vs %s", a->addr1, b->addr1);
595  return FALSE;
596  }
597  if (g_strcmp0(a->addr2, b->addr2) != 0)
598  {
599  PWARN("address lines 2 differ: %s vs %s", a->addr2, b->addr1);
600  return FALSE;
601  }
602  if (g_strcmp0(a->addr3, b->addr3) != 0)
603  {
604  PWARN("address lines 3 differ: %s vs %s", a->addr3, b->addr3);
605  return FALSE;
606  }
607  if (g_strcmp0(a->addr4, b->addr4) != 0)
608  {
609  PWARN("address lines 4 differ: %s vs %s", a->addr4, b->addr4);
610  return FALSE;
611  }
612  if (g_strcmp0(a->phone, b->phone) != 0)
613  {
614  PWARN("phone numbers differ: %s vs %s", a->phone, b->phone);
615  return FALSE;
616  }
617  if (g_strcmp0(a->fax, b->fax) != 0)
618  {
619  PWARN("fax numbers differ: %s vs %s", a->fax, b->fax);
620  return FALSE;
621  }
622  if (g_strcmp0(a->email, b->email) != 0)
623  {
624  PWARN("email addresses differ: %s vs %s", a->email, b->email);
625  return FALSE;
626  }
627 
628  return TRUE;
629 }
630 
631 static QofObject GncAddressDesc =
632 {
633  DI(.interface_version = ) QOF_OBJECT_VERSION,
634  DI(.e_type = ) GNC_ID_ADDRESS,
635  DI(.type_label = ) "Address",
636  DI(.create = ) (gpointer)qofAddressCreate,
637  DI(.book_begin = ) NULL,
638  DI(.book_end = ) NULL,
639  DI(.is_dirty = ) qof_collection_is_dirty,
640  DI(.mark_clean = ) qof_collection_mark_clean,
641  DI(.foreach = ) qof_collection_foreach,
642  DI(.printable = ) NULL,
643  DI(.version_cmp = ) (int (*)(gpointer, gpointer)) qof_instance_version_cmp,
644 };
645 
646 gboolean gncAddressRegister (void)
647 {
648  static QofParam params[] =
649  {
650 
651  { ADDRESS_NAME, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetName, (QofSetterFunc)gncAddressSetName },
652  { ADDRESS_ONE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr1, (QofSetterFunc)gncAddressSetAddr1 },
653  { ADDRESS_TWO, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr2, (QofSetterFunc)gncAddressSetAddr2 },
654  { ADDRESS_THREE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr3, (QofSetterFunc)gncAddressSetAddr3 },
655  { ADDRESS_FOUR, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetAddr4, (QofSetterFunc)gncAddressSetAddr4 },
656  { ADDRESS_PHONE, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetPhone, (QofSetterFunc)gncAddressSetPhone },
657  { ADDRESS_FAX, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetFax, (QofSetterFunc)gncAddressSetFax },
658  { ADDRESS_EMAIL, QOF_TYPE_STRING, (QofAccessFunc)gncAddressGetEmail, (QofSetterFunc)gncAddressSetEmail },
659  { ADDRESS_OWNER, QOF_TYPE_CHOICE, (QofAccessFunc)qofAddressGetOwner, (QofSetterFunc)qofAddressSetOwner },
660  { QOF_PARAM_BOOK, QOF_ID_BOOK, (QofAccessFunc)qof_instance_get_book, NULL },
661  { QOF_PARAM_GUID, QOF_TYPE_GUID, (QofAccessFunc)qof_instance_get_guid, NULL },
662  { NULL },
663  };
664 
665  qof_class_register (GNC_ID_ADDRESS, (QofSortFunc)gncAddressCompare, params);
666  if (!qof_choice_add_class(GNC_ID_CUSTOMER, GNC_ID_ADDRESS, ADDRESS_OWNER))
667  {
668  return FALSE;
669  }
670 
671  return qof_object_register(&GncAddressDesc);
672 }
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
const GncGUID * qof_instance_get_guid(gconstpointer)
QofBook * qof_instance_get_book(gconstpointer)
gboolean qof_collection_is_dirty(const QofCollection *col)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
Definition: qofbackend.h:59
gboolean kvp_frame_is_empty(const KvpFrame *frame)
void gnc_features_set_used(QofBook *book, const gchar *feature)
Definition: gnc-features.c:131
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_fcn, const QofParam *params)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
Definition: qofclass.h:177
#define QOF_OBJECT_VERSION
Definition: qofobject.h:64
gboolean qof_commit_edit(QofInstance *inst)
#define PERR(format, args...)
Definition: qoflog.h:237
#define QOF_PARAM_BOOK
Definition: qofquery.h:109
int gncAddressCompare(const GncAddress *a, const GncAddress *b)
compare two addresses
Definition: gncAddress.c:569
void qof_collection_foreach(const QofCollection *, QofInstanceForeachCB, gpointer user_data)
#define PWARN(format, args...)
Definition: qoflog.h:243
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
gboolean qof_begin_edit(QofInstance *inst)
int(* QofSortFunc)(gconstpointer, gconstpointer)
Definition: qofclass.h:222
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
void qof_collection_mark_clean(QofCollection *)
gboolean gncAddressEqual(const GncAddress *a, const GncAddress *b)
Deeply compare two addresses.
Definition: gncAddress.c:579
gboolean qof_choice_add_class(const char *choice, char *add, char *param_name)
Add the choices for this parameter to the object.
void(* QofSetterFunc)(gpointer, gpointer)
Definition: qofclass.h:184
gboolean qof_object_register(const QofObject *object)
an Address object
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
#define QOF_TYPE_CHOICE
Identify an object as containing a choice.
Definition: qofchoice.h:108
const gchar * QofLogModule
Definition: qofid.h:89
Utility functions for file access.