summaryrefslogtreecommitdiff
path: root/src/modules/ecordova
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-10-29 17:06:29 -0200
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-10-29 17:06:29 -0200
commit308b29c3203d711474f1e7cd6b61ae96827d3e5e (patch)
tree4d36aa90a6e44620a8cfe30264d1ac0d5e3f1176 /src/modules/ecordova
parent74f70e020995860f8427633b5872c70ed27e0c0d (diff)
ecordova: Moved to tizen modules
Diffstat (limited to 'src/modules/ecordova')
-rw-r--r--src/modules/ecordova/linux/ecordova_filetransfer.c647
-rw-r--r--src/modules/ecordova/linux/ecordova_filetransfer_private.h21
-rw-r--r--src/modules/ecordova/tizen/ecordova_batterystatus.c196
-rw-r--r--src/modules/ecordova/tizen/ecordova_batterystatus_private.h19
-rw-r--r--src/modules/ecordova/tizen/ecordova_contact.c1117
-rw-r--r--src/modules/ecordova/tizen/ecordova_contact_private.h38
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactaddress.c312
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactaddress_private.h25
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactfield.c415
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactfield_private.h58
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactname.c257
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactname_private.h25
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactorganization.c232
-rw-r--r--src/modules/ecordova/tizen/ecordova_contactorganization_private.h25
-rw-r--r--src/modules/ecordova/tizen/ecordova_contacts.c519
-rw-r--r--src/modules/ecordova/tizen/ecordova_contacts_private.h16
-rw-r--r--src/modules/ecordova/tizen/ecordova_contacts_record_utils.c121
-rw-r--r--src/modules/ecordova/tizen/ecordova_contacts_record_utils.h20
-rw-r--r--src/modules/ecordova/tizen/ecordova_device.c107
-rw-r--r--src/modules/ecordova/tizen/ecordova_device_private.h20
-rw-r--r--src/modules/ecordova/tizen/ecordova_devicemotion.c176
-rw-r--r--src/modules/ecordova/tizen/ecordova_devicemotion_private.h20
-rw-r--r--src/modules/ecordova/tizen/ecordova_deviceorientation.c180
-rw-r--r--src/modules/ecordova/tizen/ecordova_deviceorientation_private.h20
-rw-r--r--src/modules/ecordova/tizen/ecordova_geolocation.c282
-rw-r--r--src/modules/ecordova/tizen/ecordova_geolocation_private.h19
-rw-r--r--src/modules/ecordova/tizen/ecordova_globalization.c1122
-rw-r--r--src/modules/ecordova/tizen/ecordova_globalization_private.h16
-rw-r--r--src/modules/ecordova/tizen/ecordova_inappbrowser.c78
-rw-r--r--src/modules/ecordova/tizen/ecordova_inappbrowser_private.h16
-rw-r--r--src/modules/ecordova/tizen/ecordova_networkinformation.c98
-rw-r--r--src/modules/ecordova/tizen/ecordova_networkinformation_private.h19
-rw-r--r--src/modules/ecordova/tizen/ecordova_systeminfo.c139
-rw-r--r--src/modules/ecordova/tizen/ecordova_systeminfo_private.h19
-rw-r--r--src/modules/ecordova/tizen/ecordova_tizen.c17
-rw-r--r--src/modules/ecordova/tizen/ecordova_vibration.c66
-rw-r--r--src/modules/ecordova/tizen/ecordova_vibration_private.h16
37 files changed, 6492 insertions, 1 deletions
diff --git a/src/modules/ecordova/linux/ecordova_filetransfer.c b/src/modules/ecordova/linux/ecordova_filetransfer.c
new file mode 100644
index 0000000000..72bb4f040b
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filetransfer.c
@@ -0,0 +1,647 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_filetransfer_private.h"
6#include "ecordova_directoryentry_private.h"
7
8#include <Ecore_Con.h>
9
10#ifdef _WIN32
11# ifdef DLL_EXPORT
12# define EAPI __declspec(dllexport)
13# else
14# define EAPI
15# endif /* ! DLL_EXPORT */
16#else
17# ifdef __GNUC__
18# if __GNUC__ >= 4
19# define EAPI __attribute__ ((visibility("default")))
20# else
21# define EAPI
22# endif
23# else
24# define EAPI
25# endif
26#endif /* ! _WIN32 */
27
28/* logging support */
29extern int _ecordova_log_dom;
30
31#define CRI(...) EINA_LOG_DOM_CRIT(_ecordova_log_dom, __VA_ARGS__)
32#define ERR(...) EINA_LOG_DOM_ERR(_ecordova_log_dom, __VA_ARGS__)
33#define WRN(...) EINA_LOG_DOM_WARN(_ecordova_log_dom, __VA_ARGS__)
34#define INF(...) EINA_LOG_DOM_INFO(_ecordova_log_dom, __VA_ARGS__)
35#define DBG(...) EINA_LOG_DOM_DBG(_ecordova_log_dom, __VA_ARGS__)
36
37#define MY_CLASS ECORDOVA_FILETRANSFER_CLASS
38#define MY_CLASS_NAME "Ecordova_FileTransfer"
39
40struct _Ecordova_FileTransfer_Job
41{
42 char *source;
43 char *target;
44 Ecore_File_Download_Job *download;
45 Ecore_Thread *upload;
46 int upload_error;
47 char *upload_buffer;
48 long int upload_length;
49 Ecore_Con_Url *upload_con_url;
50 Ecore_Event_Handler *progress_event_hanbler;
51 Ecore_Event_Handler *complete_event_hanbler;
52 Ecordova_FileTransfer_UploadOptions upload_options;
53};
54
55static int _download_progress_cb(void *, const char *, long int, long int, long int, long int);
56static void _download_completion_cb(void *, const char *, int);
57static void _clear(Ecordova_FileTransfer_Data *);
58static void _abort_error_notify(Ecordova_FileTransfer_Data *);
59static void _status_error_notify(Ecordova_FileTransfer_Data *, int);
60static void _file_error_notify(Ecordova_FileTransfer_Data *, int);
61static void _connection_error_notify(Ecordova_FileTransfer_Data *);
62static void _already_in_progress_error_notify(Ecordova_FileTransfer_Data *, const char *, const char *);
63static void _upload_cb(void *, Ecore_Thread *);
64static void _upload_progress_notify(size_t, size_t, Eo *, Ecore_Thread *);
65static void _upload_progress_cb(void *, Ecore_Thread *, void *);
66static void _upload_end_cb(void *, Ecore_Thread *);
67static void _upload_abort_cb(void *, Ecore_Thread *);
68static void _progress_notify(Ecordova_FileTransfer_Data *, Ecordova_ProgressEvent *);
69static Ecordova_FileTransfer_Job *_job_new(const char *, const char *);
70static void _job_free(Ecordova_FileTransfer_Job **);
71static Eina_Bool _url_progress_cb(void *, int, void *);
72static Eina_Bool _url_complete_cb(void *, int, void *);
73
74static Eo_Base *
75_ecordova_filetransfer_eo_base_constructor(Eo *obj,
76 Ecordova_FileTransfer_Data *pd)
77{
78 DBG("(%p)", obj);
79
80 pd->obj = obj;
81 pd->job = NULL;
82
83 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
84}
85
86static void
87_ecordova_filetransfer_constructor(Eo *obj EINA_UNUSED,
88 Ecordova_FileTransfer_Data *pd EINA_UNUSED)
89{
90 DBG("(%p)", obj);
91}
92
93static void
94_ecordova_filetransfer_eo_base_destructor(Eo *obj,
95 Ecordova_FileTransfer_Data *pd)
96{
97 DBG("(%p)", obj);
98
99 _clear(pd);
100
101 eo_do_super(obj, MY_CLASS, eo_destructor());
102}
103
104static void
105_ecordova_filetransfer_upload(Eo *obj EINA_UNUSED,
106 Ecordova_FileTransfer_Data *pd EINA_UNUSED,
107 const char *file_url EINA_UNUSED,
108 const char *server,
109 Ecordova_FileTransfer_UploadOptions *options EINA_UNUSED,
110 Eina_Bool trust_all_hosts EINA_UNUSED)
111{
112 DBG("(%p)", obj);
113 EINA_SAFETY_ON_NULL_RETURN(file_url);
114 EINA_SAFETY_ON_NULL_RETURN(server);
115
116 if (pd->job)
117 {
118 _already_in_progress_error_notify(pd, file_url, server);
119 return;
120 }
121
122 bool is_http = strncmp(server, "http://", 7) == 0;
123 bool is_https = strncmp(server, "https://", 8) == 0;
124
125 if (!is_http && !is_https)
126 {
127 ERR("%s", "Invalid server address");
128 Ecordova_FileTransfer_Error error = {
129 .code = ECORDOVA_FILETRANSFER_ERRORCODE_INVALID_URL_ERR,
130 .source = file_url,
131 .target = server,
132 .http_status = 0,
133 .body = NULL,
134 .exception = "Invalid server address"
135 };
136 eo_do(pd->obj,
137 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
138 return;
139 }
140
141 pd->job = _job_new(file_url, server);
142 pd->job->upload = ecore_thread_feedback_run(_upload_cb,
143 _upload_progress_cb,
144 _upload_end_cb,
145 _upload_abort_cb,
146 pd,
147 EINA_FALSE);
148}
149
150static void
151_ecordova_filetransfer_download(Eo *obj,
152 Ecordova_FileTransfer_Data *pd,
153 const char *source,
154 const char *target,
155 Eina_Bool trust_all_hosts EINA_UNUSED,
156 Eina_Hash *options)
157{
158 DBG("(%p)", obj);
159 EINA_SAFETY_ON_NULL_RETURN(source);
160 EINA_SAFETY_ON_NULL_RETURN(target);
161
162 if (pd->job)
163 {
164 _already_in_progress_error_notify(pd, source, target);
165 return;
166 }
167
168 Ecordova_FileTransfer_Job *job = _job_new(source, target);
169
170 Eina_Bool ret;
171 if (options)
172 ret = ecore_file_download_full(source,
173 target,
174 _download_completion_cb,
175 _download_progress_cb,
176 pd,
177 &job->download,
178 options);
179 else
180 ret = ecore_file_download(source,
181 target,
182 _download_completion_cb,
183 _download_progress_cb,
184 pd,
185 &job->download);
186
187 if (!ret)
188 {
189 _job_free(&job);
190 ERR("%s", "An error occurred downloading the file");
191 Ecordova_FileTransfer_Error error = {
192 .code = ECORDOVA_FILETRANSFER_ERRORCODE_ABORT_ERR,
193 .source = source,
194 .target = target,
195 .http_status = 0,
196 .body = NULL,
197 .exception = "An error occurred downloading the file"
198 };
199 eo_do(obj, eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
200 return;
201 }
202
203 pd->job = job;
204}
205
206static void
207_ecordova_filetransfer_abort(Eo *obj, Ecordova_FileTransfer_Data *pd)
208{
209 DBG("(%p)", obj);
210
211 if (!pd->job) return;
212
213 if (pd->job->download)
214 ecore_file_download_abort(pd->job->download);
215 else
216 ecore_thread_cancel(pd->job->upload);
217}
218
219static int
220_download_progress_cb(void *data,
221 const char *file EINA_UNUSED,
222 long int dltotal,
223 long int dlnow,
224 long int ultotal EINA_UNUSED,
225 long int ulnow EINA_UNUSED)
226{
227 Ecordova_FileTransfer_Data *pd = data;
228 DBG("(%p)", pd->obj);
229 Ecordova_ProgressEvent event = {
230 .type = "download",
231 .cancelable = true,
232 .length_computable = true,
233 .loaded = dlnow,
234 .total = dltotal,
235 .target = pd->obj
236 };
237 _progress_notify(pd, &event);
238 return ECORE_FILE_PROGRESS_CONTINUE;
239}
240
241static void
242_download_completion_cb(void *data, const char *file, int status)
243{
244 Ecordova_FileTransfer_Data *pd = data;
245 DBG("(%p)", pd->obj);
246 if (1 == status)
247 _abort_error_notify(pd);
248 else if (200 != status)
249 _status_error_notify(pd, status);
250 else
251 {
252 char *path, *name, *native;
253 split_path(NULL, file, &path, &name, &native);
254
255 Ecordova_FileEntry *file_entry = eo_add(ECORDOVA_FILEENTRY_CLASS, NULL,
256 ecordova_fileentry_constructor(name, path, NULL, native)); // TODO: filesystem?
257 eo_do(pd->obj,
258 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_DOWNLOAD_SUCCESS, file_entry));
259 eo_unref(file_entry);
260
261 free(path);
262 free(name);
263 free(native);
264 }
265
266 _clear(pd);
267}
268
269static void
270_clear(Ecordova_FileTransfer_Data *pd)
271{
272 DBG("(%p)", pd->obj);
273 _job_free(&pd->job);
274}
275
276static void
277_upload_cb(void *data, Ecore_Thread *thread)
278{
279 Ecordova_FileTransfer_Data *pd = data;
280 DBG("(%p)", pd->obj);
281
282 if (ecore_thread_check(thread))
283 {
284 pd->job->upload_error = 1;
285 return;
286 }
287
288 FILE *stream = fopen(pd->job->source, "rb");
289 if (!stream)
290 {
291 pd->job->upload_error = errno;
292 return;
293 }
294
295 int error = fseek(stream, 0L, SEEK_END);
296 if (error)
297 {
298 pd->job->upload_error = errno;
299 goto on_error;
300 }
301
302 pd->job->upload_length = ftell(stream);
303 if (pd->job->upload_length < 0)
304 {
305 pd->job->upload_error = errno;
306 goto on_error;
307 }
308
309 error = fseek(stream, 0L, SEEK_SET);
310 {
311 pd->job->upload_error = errno;
312 goto on_error;
313 }
314
315 _upload_progress_notify(0, pd->job->upload_length, pd->obj, thread);
316
317 pd->job->upload_buffer = malloc(pd->job->upload_length);
318 if (!pd->job->upload_buffer)
319 {
320 pd->job->upload_error = errno;
321 goto on_error;
322 }
323
324 long int total_read = 0;
325 while (total_read < pd->job->upload_length)
326 {
327 size_t read = fread(&pd->job->upload_buffer[total_read],
328 sizeof(char),
329 pd->job->upload_length - total_read,
330 stream);
331 total_read += read;
332
333 _upload_progress_notify(0, pd->job->upload_length, pd->obj, thread);
334 if (ecore_thread_check(thread))
335 {
336 pd->job->upload_error = 1;
337 break;
338 }
339 }
340
341on_error:
342 fclose(stream);
343}
344
345static void
346_upload_progress_notify(size_t uploaded,
347 size_t total,
348 Eo *obj,
349 Ecore_Thread *thread)
350{
351 DBG("(%p)", obj);
352
353 Ecordova_ProgressEvent *progress = malloc(sizeof(Ecordova_ProgressEvent));
354 *progress = (Ecordova_ProgressEvent)
355 {
356 .type = "upload",
357 .length_computable = EINA_TRUE,
358 .loaded = uploaded,
359 .total = total,
360 .target = obj
361 };
362 if (!ecore_thread_feedback(thread, progress))
363 free(progress);
364}
365
366static void
367_upload_progress_cb(void *data,
368 Ecore_Thread *thread EINA_UNUSED,
369 void *msg_data)
370{
371 Ecordova_FileTransfer_Data *pd = data;
372 DBG("(%p)", pd->obj);
373 Ecordova_ProgressEvent *event = msg_data;
374 _progress_notify(pd, event);
375 free(event);
376}
377
378static void
379_upload_end_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
380{
381 Ecordova_FileTransfer_Data *pd = data;
382 DBG("(%p)", pd->obj);
383
384 if (1 == pd->job->upload_error)
385 _abort_error_notify(pd);
386 else if (pd->job->upload_error)
387 _file_error_notify(pd, pd->job->upload_error);
388 else
389 {
390 pd->job->upload_con_url = ecore_con_url_custom_new(pd->job->target,
391 pd->job->upload_options.http_method);
392 if (!pd->job->upload_con_url)
393 {
394 _connection_error_notify(pd);
395 goto on_error;
396 }
397
398 pd->job->complete_event_hanbler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _url_complete_cb, pd);
399 pd->job->progress_event_hanbler = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _url_progress_cb, pd);
400 if (!pd->job->complete_event_hanbler || !pd->job->progress_event_hanbler)
401 {
402 _connection_error_notify(pd);
403 goto on_error;
404 }
405
406 if (pd->job->upload_options.headers)
407 {
408 Eina_Iterator *it = eina_hash_iterator_tuple_new(pd->job->upload_options.headers);
409 Eina_Hash_Tuple *tuple;
410 EINA_ITERATOR_FOREACH(it, tuple)
411 ecore_con_url_additional_header_add(pd->job->upload_con_url, tuple->key, tuple->data);
412 eina_iterator_free(it);
413 }
414
415 Eina_Bool ret = ecore_con_url_post(pd->job->upload_con_url,
416 pd->job->upload_buffer,
417 pd->job->upload_length,
418 pd->job->upload_options.mime_type);
419 if (!ret)
420 {
421 _connection_error_notify(pd);
422 goto on_error;
423 }
424
425 return;
426 }
427
428on_error:
429 _clear(pd);
430}
431
432static void
433_upload_abort_cb(void *data, Ecore_Thread *thread EINA_UNUSED)
434{
435 Ecordova_FileTransfer_Data *pd = data;
436 DBG("(%p)", pd->obj);
437
438 _abort_error_notify(pd);
439 _clear(pd);
440}
441
442static void
443_progress_notify(Ecordova_FileTransfer_Data *pd,
444 Ecordova_ProgressEvent *event)
445{
446 eo_do(pd->obj,
447 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ON_PROGRESS, event));
448}
449
450static Ecordova_FileTransfer_Job *
451_job_new(const char *source, const char *target)
452{
453 Ecordova_FileTransfer_Job *job = calloc(1, sizeof(Ecordova_FileTransfer_Job));
454 job->source = strdup(source);
455 job->target = strdup(target);
456 job->upload_options = (Ecordova_FileTransfer_UploadOptions){
457 .file_key = "file",
458 .file_name = "image.jpg",
459 .http_method = "POST",
460 .mime_type = "image/jpeg",
461 .chunked_mode = EINA_TRUE
462 };
463 return job;
464}
465
466static void
467_job_free(Ecordova_FileTransfer_Job **job)
468{
469 if (!*job) return;
470
471 if ((*job)->upload_con_url)
472 {
473 if ((*job)->progress_event_hanbler)
474 ecore_event_handler_del((*job)->progress_event_hanbler);
475 if ((*job)->complete_event_hanbler)
476 ecore_event_handler_del((*job)->complete_event_hanbler);
477 ecore_con_url_free((*job)->upload_con_url);
478 }
479 free((*job)->upload_buffer);
480 free((*job)->source);
481 free((*job)->target);
482 free(*job);
483 *job = NULL;
484}
485
486static Eina_Bool
487_url_progress_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
488{
489 Ecore_Con_Event_Url_Progress *url_progress = event_info;
490 Ecordova_FileTransfer_Data *pd = data;
491
492 Ecordova_ProgressEvent event = {
493 .type = "upload",
494 .cancelable = false,
495 .length_computable = true,
496 .loaded = url_progress->up.now,
497 .total = url_progress->up.total,
498 .target = pd->obj
499 };
500 _progress_notify(pd, &event);
501
502 return EINA_TRUE;
503}
504
505static Eina_Bool
506_url_complete_cb(void *data, int type EINA_UNUSED, void *event_info)
507{
508 Ecore_Con_Event_Url_Complete *url_complete = event_info;
509 Ecordova_FileTransfer_Data *pd = data;
510
511 if (200 != url_complete->status)
512 _status_error_notify(pd, url_complete->status);
513 else
514 {
515 Eina_Hash *headers_hash = NULL;
516 const Eina_List *headers = ecore_con_url_response_headers_get(url_complete->url_con);
517 if (eina_list_count(headers))
518 {
519 headers_hash = eina_hash_string_superfast_new(free);
520 const char *header_line;
521 const Eina_List *it;
522 EINA_LIST_FOREACH(headers, it, header_line)
523 {
524 const char *separator = strchr(header_line, ':');
525 if (!separator) continue;
526
527 size_t key_len = separator - header_line + 1;
528 char key[key_len];
529 strncpy(key, header_line, key_len);
530 key[key_len - 1] = '\0';
531
532 if (*(++separator) == ' ')
533 ++separator;
534 char *value = strdup(separator);
535 eina_hash_add(headers_hash, key, value);
536 }
537 }
538
539 Ecordova_FileTransfer_UploadResult result = {
540 .bytes_sent = pd->job->upload_length,
541 .response_code = url_complete->status,
542 .headers = headers_hash,
543 .response = NULL // TODO: Get the HTTP response
544 };
545 eo_do(pd->obj,
546 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_UPLOAD_SUCCESS,
547 &result));
548 if (headers_hash)
549 eina_hash_free(headers_hash);
550 }
551
552 _clear(pd);
553 return EINA_TRUE;
554}
555
556static void
557_abort_error_notify(Ecordova_FileTransfer_Data *pd)
558{
559 INF("%s", "Aborted");
560 Ecordova_FileTransfer_Error error = {
561 .code = ECORDOVA_FILETRANSFER_ERRORCODE_ABORT_ERR,
562 .source = pd->job->source,
563 .target = pd->job->target,
564 .http_status = 0,
565 .body = NULL,
566 .exception = "Aborted"
567 };
568 eo_do(pd->obj,
569 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
570}
571
572static void
573_status_error_notify(Ecordova_FileTransfer_Data *pd, int status)
574{
575 ERR("Error status: %d", status);
576 Ecordova_FileTransfer_Error error = {
577 // TODO: translate other errors checking first which protocol it is.
578 .code = 404 == status ? ECORDOVA_FILETRANSFER_ERRORCODE_FILE_NOT_FOUND_ERR :
579 ECORDOVA_FILETRANSFER_ERRORCODE_ABORT_ERR,
580 .source = pd->job->source,
581 .target = pd->job->target,
582 .http_status = status,
583 .body = NULL,
584 .exception = "Error"
585 };
586 eo_do(pd->obj,
587 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
588}
589
590static void
591_file_error_notify(Ecordova_FileTransfer_Data *pd, int code)
592{
593 ERR("Error code: %d", code);
594 Ecordova_FileTransfer_Error error = {
595 .code = ECORDOVA_FILETRANSFER_ERRORCODE_FILE_NOT_FOUND_ERR,
596 .source = pd->job->source,
597 .target = pd->job->target,
598 .http_status = 0,
599 .body = NULL,
600 .exception = "Internal error"
601 };
602 eo_do(pd->obj,
603 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
604}
605
606static void
607_connection_error_notify(Ecordova_FileTransfer_Data *pd)
608{
609 ERR("%s", "Connection error");
610 Ecordova_FileTransfer_Error error = {
611 .code = ECORDOVA_FILETRANSFER_ERRORCODE_CONNECTION_ERR,
612 .source = pd->job->source,
613 .target = pd->job->target,
614 .http_status = 0,
615 .body = NULL,
616 .exception = "Connection error"
617 };
618 eo_do(pd->obj,
619 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
620}
621
622static void
623_already_in_progress_error_notify(Ecordova_FileTransfer_Data *pd,
624 const char *source,
625 const char *target)
626{
627 ERR("%s", "A job is already in progress");
628 Ecordova_FileTransfer_Error error = {
629 .code = ECORDOVA_FILETRANSFER_ERRORCODE_ABORT_ERR,
630 .source = source,
631 .target = target,
632 .http_status = 0,
633 .body = NULL,
634 .exception = "A job is already in progress"
635 };
636 eo_do(pd->obj,
637 eo_event_callback_call(ECORDOVA_FILETRANSFER_EVENT_ERROR, &error));
638}
639
640#undef EOAPI
641#define EOAPI EAPI
642
643#include "undefs.h"
644
645#define ecordova_filetransfer_class_get ecordova_filetransfer_impl_class_get
646
647#include "ecordova_filetransfer.eo.c"
diff --git a/src/modules/ecordova/linux/ecordova_filetransfer_private.h b/src/modules/ecordova/linux/ecordova_filetransfer_private.h
new file mode 100644
index 0000000000..b17fe85e9a
--- /dev/null
+++ b/src/modules/ecordova/linux/ecordova_filetransfer_private.h
@@ -0,0 +1,21 @@
1#ifndef _ECORDOVA_FILETRANSFER_PRIVATE_H
2#define _ECORDOVA_FILETRANSFER_PRIVATE_H
3
4#include "ecordova_private.h"
5
6#include <Ecore_File.h>
7
8typedef struct _Ecordova_FileTransfer_Data Ecordova_FileTransfer_Data;
9
10typedef struct _Ecordova_FileTransfer_Job Ecordova_FileTransfer_Job;
11
12/**
13 * Ecordova.FileTransfer private data
14 */
15struct _Ecordova_FileTransfer_Data
16{
17 Eo *obj;
18 Ecordova_FileTransfer_Job *job;
19};
20
21#endif
diff --git a/src/modules/ecordova/tizen/ecordova_batterystatus.c b/src/modules/ecordova/tizen/ecordova_batterystatus.c
new file mode 100644
index 0000000000..a864e733df
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_batterystatus.c
@@ -0,0 +1,196 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_batterystatus_private.h"
6#include "ecordova_systeminfo.eo.h"
7
8#include <vconf.h>
9
10#include <stdbool.h>
11#include <stdint.h>
12#include <stdlib.h>
13
14#define MY_CLASS ECORDOVA_BATTERYSTATUS_CLASS
15#define MY_CLASS_NAME "Ecordova_BatteryStatus"
16
17#define STATUS_CRITICAL 5
18#define STATUS_LOW 20
19
20static Eina_Bool _add_cb(void *, Eo *, const Eo_Event_Description *, void *);
21static Eina_Bool _del_cb(void *, Eo *, const Eo_Event_Description *, void *);
22static void _start(Ecordova_BatteryStatus_Data *);
23static void _stop(Ecordova_BatteryStatus_Data *);
24static Eina_Bool _on_battery_changed(void *, Eo *, const Eo_Event_Description *, void *);
25static bool _fetch_level(int *);
26static bool _fetch_charging_is(Eina_Bool *);
27
28static Eo_Base *
29_ecordova_batterystatus_eo_base_constructor(Eo *obj,
30 Ecordova_BatteryStatus_Data *pd)
31{
32 DBG("(%p)", obj);
33
34 pd->obj = obj;
35
36 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
37}
38
39static void
40_ecordova_batterystatus_constructor(Eo *obj,
41 Ecordova_BatteryStatus_Data *pd)
42{
43 DBG("(%p)", obj);
44
45 eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_ADD, _add_cb, pd));
46 eo_do(obj, eo_event_callback_add(EO_EV_CALLBACK_DEL, _del_cb, pd));
47}
48
49static void
50_ecordova_batterystatus_eo_base_destructor(Eo *obj,
51 Ecordova_BatteryStatus_Data *pd)
52{
53 DBG("(%p)", obj);
54
55 if (pd->callback_ref_count)
56 _stop(pd);
57
58 eo_do(obj, eo_event_callback_del(EO_EV_CALLBACK_ADD, _add_cb, pd));
59 eo_do(obj, eo_event_callback_del(EO_EV_CALLBACK_DEL, _del_cb, pd));
60
61 eo_do_super(obj, MY_CLASS, eo_destructor());
62}
63
64static Eina_Bool
65_add_cb(void *data,
66 Eo *obj EINA_UNUSED,
67 const Eo_Event_Description *desc,
68 void *event_info)
69{
70 Ecordova_BatteryStatus_Data *pd = (Ecordova_BatteryStatus_Data*)data;
71 const Eo_Callback_Array_Item *array = (const Eo_Callback_Array_Item*)event_info;
72
73 for (size_t i = 0; (desc = array[i].desc); ++i)
74 {
75 if (ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_STATUS == desc ||
76 ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_CRITICAL == desc ||
77 ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_LOW == desc)
78 {
79 ++pd->callback_ref_count;
80 if (1 == pd->callback_ref_count)
81 _start(pd);
82 }
83 }
84
85 return EO_CALLBACK_CONTINUE;
86}
87
88static Eina_Bool
89_del_cb(void *data,
90 Eo *obj EINA_UNUSED,
91 const Eo_Event_Description *desc,
92 void *event_info)
93{
94 Ecordova_BatteryStatus_Data *pd = (Ecordova_BatteryStatus_Data*)data;
95 const Eo_Callback_Array_Item *array = (const Eo_Callback_Array_Item*)event_info;
96
97 for (size_t i = 0; (desc = array[i].desc); ++i)
98 {
99 if (ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_STATUS == desc ||
100 ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_CRITICAL == desc ||
101 ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_LOW == desc)
102 --pd->callback_ref_count;
103 }
104
105 if (0 == pd->callback_ref_count)
106 _stop(pd);
107
108 return EO_CALLBACK_CONTINUE;
109}
110
111static void
112_start(Ecordova_BatteryStatus_Data *pd)
113{
114 eo_do(_ecordova_systeminfo,
115 eo_event_callback_add(ECORDOVA_SYSTEMINFO_EVENT_BATTERY_CHANGED,
116 _on_battery_changed,
117 pd));
118}
119
120static void
121_stop(Ecordova_BatteryStatus_Data *pd)
122{
123 free(pd->info);
124 pd->info = NULL;
125
126 eo_do(_ecordova_systeminfo,
127 eo_event_callback_del(ECORDOVA_SYSTEMINFO_EVENT_BATTERY_CHANGED,
128 _on_battery_changed,
129 pd));
130}
131
132static bool
133_fetch_level(int *level)
134{
135 int value = 0;
136 bool ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CAPACITY, &value) == 0;
137 if (ret)
138 ERR("%s", "Failed to get battery capacity");
139
140 *level = value;
141 return ret;
142}
143
144static bool
145_fetch_charging_is(Eina_Bool *charging_is)
146{
147 int value = 0;
148 int ret = vconf_get_int(VCONFKEY_SYSMAN_BATTERY_CHARGE_NOW, &value) == 0;
149 if (!ret)
150 ERR("%s", "Failed to get battery change");
151
152 *charging_is = (0 != value) ? EINA_TRUE : EINA_FALSE;
153 return ret;
154}
155
156static Eina_Bool
157_on_battery_changed(void *data,
158 Eo *obj EINA_UNUSED,
159 const Eo_Event_Description *desc EINA_UNUSED,
160 void *event_info EINA_UNUSED)
161{
162 Ecordova_BatteryStatus_Data *pd = (Ecordova_BatteryStatus_Data*)data;
163
164 Ecordova_BatteryStatus_EventInfo info;
165 if (!_fetch_level(&info.level) ||
166 !_fetch_charging_is(&info.plugged_is))
167 return EO_CALLBACK_CONTINUE;
168
169 if (!pd->info ||
170 pd->info->level != info.level ||
171 pd->info->plugged_is != info.plugged_is)
172 {
173 eo_do(pd->obj, eo_event_callback_call
174 (ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_STATUS, &info));
175
176 if (!info.plugged_is)
177 {
178 if ((!pd->info || pd->info->level > STATUS_CRITICAL) &&
179 info.level <= STATUS_CRITICAL)
180 eo_do(pd->obj, eo_event_callback_call
181 (ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_CRITICAL, &info));
182 else
183 if ((!pd->info || pd->info->level > STATUS_LOW) &&
184 info.level <= STATUS_LOW)
185 eo_do(pd->obj, eo_event_callback_call
186 (ECORDOVA_BATTERYSTATUS_EVENT_BATTERY_LOW, &info));
187 }
188
189 if (!pd->info)
190 pd->info = malloc(sizeof(Ecordova_BatteryStatus_EventInfo));
191 *pd->info = info;
192 }
193 return EO_CALLBACK_CONTINUE;
194}
195
196#include "ecordova_batterystatus.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_batterystatus_private.h b/src/modules/ecordova/tizen/ecordova_batterystatus_private.h
new file mode 100644
index 0000000000..f9ced32f04
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_batterystatus_private.h
@@ -0,0 +1,19 @@
1#ifndef _ECORDOVA_BATTERYSTATUS_PRIVATE_H
2#define _ECORDOVA_BATTERYSTATUS_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_batterystatus.eo.h"
6
7typedef struct _Ecordova_BatteryStatus_Data Ecordova_BatteryStatus_Data;
8
9/**
10 * Ecordova.BatteryStatus private data
11 */
12struct _Ecordova_BatteryStatus_Data
13{
14 Eo *obj;
15 int callback_ref_count;
16 Ecordova_BatteryStatus_EventInfo *info;
17};
18
19#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contact.c b/src/modules/ecordova/tizen/ecordova_contact.c
new file mode 100644
index 0000000000..9b986c09e5
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contact.c
@@ -0,0 +1,1117 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contact_private.h"
6
7#include "ecordova_contactname_private.h"
8#include "ecordova_contactfield_private.h"
9#include "ecordova_contacts_record_utils.h"
10#include "ecordova_contactaddress_private.h"
11#include "ecordova_contactorganization_private.h"
12
13#include <contacts.h>
14
15#include <assert.h>
16#include <stdbool.h>
17#include <stdint.h>
18#include <stdlib.h>
19
20#define MY_CLASS ECORDOVA_CONTACT_CLASS
21#define MY_CLASS_NAME "Ecordova_Contact"
22
23static Ecordova_ContactName *_contactname_copy(Ecordova_ContactName *);
24static Eina_Array *_contactfield_array_copy(Eina_Array *);
25static Eina_Array *_contactaddress_array_copy(Eina_Array *);
26static Eina_Array *_contactorganization_array_copy(Eina_Array *);
27static void _contactfield_array_free(Eina_Array *);
28static void _contactaddress_array_free(Eina_Array *);
29static void _contactorganization_array_free(Eina_Array *);
30static bool _ecordova_contactfields_import(Eina_Array *, contacts_record_h, const Ecordova_ContactField_Metadata);
31static bool _ecordova_contactfields_export(Eina_Array *, contacts_record_h, const Ecordova_ContactField_Metadata);
32static bool _ecordova_contactaddresses_import(Eina_Array *, contacts_record_h);
33static bool _ecordova_contactaddresses_export(Eina_Array *, contacts_record_h);
34static bool _ecordova_contactorganizations_import(Eina_Array *, contacts_record_h);
35static bool _ecordova_contactorganizations_export(Eina_Array *, contacts_record_h);
36static void _contactfield_array_clear_id(Eina_Array *);
37static void _contactaddress_array_clear_id(Eina_Array *);
38static void _contactorganization_array_clear_id(Eina_Array *);
39
40static Eo_Base *
41_ecordova_contact_eo_base_constructor(Eo *obj, Ecordova_Contact_Data *pd)
42{
43 DBG("(%p)", obj);
44
45 pd->obj = obj;
46 pd->record = NULL;
47 int ret = contacts_record_create(_contacts_contact._uri, &pd->record);
48 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
49 pd->name = eo_add(ECORDOVA_CONTACTNAME_CLASS, NULL);
50 pd->phone_numbers = eina_array_new(1);
51 pd->emails = eina_array_new(1);
52 pd->addresses = eina_array_new(1);
53 pd->ims = eina_array_new(1);
54 pd->organizations = eina_array_new(1);
55 pd->photos = eina_array_new(1);
56 pd->categories = eina_array_new(1);
57 pd->urls = eina_array_new(1);
58
59 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
60}
61
62static void
63_ecordova_contact_eo_base_destructor(Eo *obj, Ecordova_Contact_Data *pd)
64{
65 DBG("(%p)", obj);
66
67 eo_unref(pd->name);
68 _contactfield_array_free(pd->phone_numbers);
69 _contactfield_array_free(pd->emails);
70 _contactaddress_array_free(pd->addresses);
71 _contactfield_array_free(pd->ims);
72 _contactorganization_array_free(pd->organizations);
73 _contactfield_array_free(pd->photos);
74 _contactfield_array_free(pd->categories);
75 _contactfield_array_free(pd->urls);
76
77 int ret = contacts_record_destroy(pd->record, true);
78 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
79
80 eo_do_super(obj, MY_CLASS, eo_destructor());
81}
82
83static void
84_ecordova_contact_remove(Eo *obj, Ecordova_Contact_Data *pd)
85{
86 if (!pd->id)
87 {
88 ERR("%s", "No id");
89 goto on_error;
90 }
91
92 int ret = contacts_db_delete_record(_contacts_contact._uri, pd->id);
93 if (CONTACTS_ERROR_NONE != ret)
94 {
95 ERR("Error deleting record id: %d", pd->id);
96 goto on_error;
97 }
98
99 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACT_EVENT_REMOVE_SUCCESS, NULL));
100 return;
101
102on_error:
103 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACT_EVENT_ERROR, NULL));
104}
105
106static Ecordova_Contact *
107_ecordova_contact_clone(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
108{
109 Ecordova_Contact *cloned = eo_add(ECORDOVA_CONTACTNAME_CLASS, NULL);
110 EINA_SAFETY_ON_NULL_RETURN_VAL(cloned, NULL);
111
112 if (!ecordova_contact_export(obj, pd->record))
113 goto on_error;
114
115 if (!ecordova_contact_import(cloned, pd->record))
116 goto on_error;
117
118 Ecordova_Contact_Data *cloned_pd = eo_data_scope_get(cloned, ECORDOVA_CONTACT_CLASS);
119 EINA_SAFETY_ON_NULL_GOTO(cloned_pd, on_error);
120
121 cloned_pd->id = 0;
122 _contactfield_array_clear_id(pd->phone_numbers);
123 _contactfield_array_clear_id(pd->emails);
124 _contactaddress_array_clear_id(pd->addresses);
125 _contactfield_array_clear_id(pd->ims);
126 _contactorganization_array_clear_id(pd->organizations);
127 _contactfield_array_clear_id(pd->photos);
128 _contactfield_array_clear_id(pd->categories);
129 _contactfield_array_clear_id(pd->urls);
130
131 return cloned;
132
133on_error:
134 eo_unref(cloned);
135 return NULL;
136}
137
138static void
139_ecordova_contact_save(Eo *obj, Ecordova_Contact_Data *pd)
140{
141 int ret;
142
143 // TODO: export records in a background thread
144 if (!ecordova_contact_export(obj, pd->record))
145 {
146 ERR("%s", "Exporting record");
147 goto on_error;
148 }
149
150 if (pd->id)
151 {
152 ret = contacts_db_update_record(pd->record);
153
154 if (CONTACTS_ERROR_NONE != ret)
155 {
156 ERR("Error updating record: %d", ret);
157 goto on_error;
158 }
159 }
160 else
161 {
162 ret = contacts_db_insert_record(pd->record, &pd->id);
163 if (CONTACTS_ERROR_NONE != ret)
164 {
165 ERR("Error inserting record: %d", ret);
166 goto on_error;
167 }
168
169 // must get the inserted record so we can properly update it further
170 contacts_record_h contacts_record = NULL;
171 ret = contacts_db_get_record(_contacts_contact._uri, pd->id, &contacts_record);
172 if (CONTACTS_ERROR_NONE != ret)
173 {
174 ERR("Error getting record: %d", ret);
175 goto on_error;
176 }
177
178 ret = contacts_record_destroy(pd->record, true);
179 if (CONTACTS_ERROR_NONE != ret)
180 {
181 ERR("Error destroying record: %d", ret);
182 goto on_error;
183 }
184
185 pd->record = contacts_record;
186 }
187
188 // TODO: Check if it's necessary to update children records
189
190 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACT_EVENT_SAVE_SUCCESS, NULL));
191 return;
192
193on_error:
194 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACT_EVENT_ERROR, NULL));
195}
196
197static int
198_ecordova_contact_id_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
199{
200 return pd->id;
201}
202
203static const char *
204_ecordova_contact_display_name_get(Eo *obj EINA_UNUSED,
205 Ecordova_Contact_Data *pd)
206{
207 const char *value = NULL;
208 get_str_p(pd->record, _contacts_contact.display_name, &value);
209 return value;
210}
211
212static void
213_ecordova_contact_display_name_set(Eo *obj EINA_UNUSED,
214 Ecordova_Contact_Data *pd,
215 const char *value)
216{
217 set_str(pd->record, _contacts_contact.display_name, value);
218}
219
220static Ecordova_ContactName *
221_ecordova_contact_name_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
222{
223 return pd->name;
224}
225
226static void
227_ecordova_contact_name_set(Eo *obj EINA_UNUSED,
228 Ecordova_Contact_Data *pd,
229 Ecordova_ContactName *name)
230{
231 if (pd->name) eo_unref(pd->name);
232 pd->name = _contactname_copy(name);
233}
234
235static const char *
236_ecordova_contact_nickname_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
237{
238 int ret;
239 int count = 0;
240 ret = contacts_record_get_child_record_count(pd->record,
241 _contacts_contact.nickname,
242 &count);
243 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
244
245 if (0 == count) return NULL;
246
247 contacts_record_h child_record = NULL;
248 ret = contacts_record_get_child_record_at_p(pd->record,
249 _contacts_contact.nickname,
250 0,
251 &child_record);
252 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
253
254 const char *value = NULL;
255 get_str_p(child_record, _contacts_nickname.name, &value);
256 return value;
257}
258
259static void
260_ecordova_contact_nickname_set(Eo *obj EINA_UNUSED,
261 Ecordova_Contact_Data *pd,
262 const char *value)
263{
264 int ret;
265 contacts_record_h child_record = NULL;
266 ret = contacts_record_create(_contacts_nickname._uri, &child_record);
267 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
268
269 if (!set_str(child_record, _contacts_nickname.name, value))
270 goto on_error;
271
272 if (!clear_all_contact_record(pd->record, _contacts_contact.nickname))
273 goto on_error;
274
275 ret = contacts_record_add_child_record(pd->record,
276 _contacts_contact.nickname,
277 child_record);
278 EINA_SAFETY_ON_FALSE_GOTO(CONTACTS_ERROR_NONE == ret, on_error);
279 return;
280
281on_error:
282 ret = contacts_record_destroy(child_record, true);
283 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
284}
285
286static Eina_Array *
287_ecordova_contact_phone_numbers_get(Eo *obj EINA_UNUSED,
288 Ecordova_Contact_Data *pd)
289{
290 return pd->phone_numbers;
291}
292
293static void
294_ecordova_contact_phone_numbers_set(Eo *obj EINA_UNUSED,
295 Ecordova_Contact_Data *pd,
296 Eina_Array *phone_numbers)
297{
298 _contactfield_array_free(pd->phone_numbers);
299 pd->phone_numbers = _contactfield_array_copy(phone_numbers);
300}
301
302static Eina_Array *
303_ecordova_contact_emails_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
304{
305 return pd->emails;
306}
307
308static void
309_ecordova_contact_emails_set(Eo *obj EINA_UNUSED,
310 Ecordova_Contact_Data *pd,
311 Eina_Array *emails)
312{
313 _contactfield_array_free(pd->emails);
314 pd->emails = _contactfield_array_copy(emails);
315}
316
317static Eina_Array *
318_ecordova_contact_addresses_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
319{
320 return pd->addresses;
321}
322
323static void
324_ecordova_contact_addresses_set(Eo *obj EINA_UNUSED,
325 Ecordova_Contact_Data *pd,
326 Eina_Array *addresses)
327{
328 _contactaddress_array_free(pd->addresses);
329 pd->addresses = _contactaddress_array_copy(addresses);
330}
331
332static Eina_Array *
333_ecordova_contact_ims_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
334{
335 return pd->ims;
336}
337
338static void
339_ecordova_contact_ims_set(Eo *obj EINA_UNUSED,
340 Ecordova_Contact_Data *pd,
341 Eina_Array *ims)
342{
343 _contactfield_array_free(pd->ims);
344 pd->ims = _contactfield_array_copy(ims);
345}
346
347static Eina_Array *
348_ecordova_contact_organizations_get(Eo *obj EINA_UNUSED,
349 Ecordova_Contact_Data *pd)
350{
351 return pd->organizations;
352}
353
354static void
355_ecordova_contact_organizations_set(Eo *obj EINA_UNUSED,
356 Ecordova_Contact_Data *pd,
357 Eina_Array *organizations)
358{
359 _contactorganization_array_free(pd->organizations);
360 pd->organizations = _contactorganization_array_copy(organizations);
361}
362
363static time_t
364_ecordova_contact_birthday_get(Eo *obj EINA_UNUSED,
365 Ecordova_Contact_Data *pd EINA_UNUSED)
366{
367 // TODO: get birthday
368 return 0;
369}
370
371static void
372_ecordova_contact_birthday_set(Eo *obj EINA_UNUSED,
373 Ecordova_Contact_Data *pd EINA_UNUSED,
374 time_t birthday EINA_UNUSED)
375{
376 // TODO: set birthday
377}
378
379static const char *
380_ecordova_contact_note_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
381{
382 int ret;
383 int count = 0;
384 ret = contacts_record_get_child_record_count(pd->record,
385 _contacts_contact.note,
386 &count);
387 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
388
389 if (0 == count)
390 return NULL;
391
392 contacts_record_h child_record = NULL;
393 ret = contacts_record_get_child_record_at_p(pd->record,
394 _contacts_contact.note,
395 0,
396 &child_record);
397 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
398
399 const char *value = NULL;
400 get_str_p(child_record, _contacts_note.note, &value);
401 return value;
402}
403
404static void
405_ecordova_contact_note_set(Eo *obj EINA_UNUSED,
406 Ecordova_Contact_Data *pd,
407 const char *value)
408{
409 int ret;
410 contacts_record_h child_record = NULL;
411 ret = contacts_record_create(_contacts_note._uri, &child_record);
412 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
413
414 if (!set_str(child_record, _contacts_note.note, value))
415 goto on_error;
416
417 if (!clear_all_contact_record(pd->record, _contacts_contact.note))
418 goto on_error;
419
420 ret = contacts_record_add_child_record(pd->record,
421 _contacts_contact.note,
422 child_record);
423 EINA_SAFETY_ON_FALSE_GOTO(CONTACTS_ERROR_NONE == ret, on_error);
424 return;
425
426on_error:
427 ret = contacts_record_destroy(child_record, true);
428 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
429}
430
431static Eina_Array *
432_ecordova_contact_photos_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
433{
434 return pd->photos;
435}
436
437static void
438_ecordova_contact_photos_set(Eo *obj EINA_UNUSED,
439 Ecordova_Contact_Data *pd,
440 Eina_Array *photos)
441{
442 _contactfield_array_free(pd->photos);
443 pd->photos = _contactfield_array_copy(photos);
444}
445
446static Eina_Array *
447_ecordova_contact_categories_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
448{
449 return pd->categories;
450}
451
452static void
453_ecordova_contact_categories_set(Eo *obj EINA_UNUSED,
454 Ecordova_Contact_Data *pd,
455 Eina_Array *categories)
456{
457 _contactfield_array_free(pd->categories);
458 pd->categories = _contactfield_array_copy(categories);
459}
460
461static Eina_Array *
462_ecordova_contact_urls_get(Eo *obj EINA_UNUSED, Ecordova_Contact_Data *pd)
463{
464 return pd->urls;
465}
466
467static void
468_ecordova_contact_urls_set(Eo *obj EINA_UNUSED,
469 Ecordova_Contact_Data *pd,
470 Eina_Array *urls)
471{
472 _contactfield_array_free(pd->urls);
473 pd->urls = _contactfield_array_copy(urls);
474}
475
476static Ecordova_ContactName *
477_contactname_copy(Ecordova_ContactName *name)
478{
479 if (!name)
480 return eo_add(ECORDOVA_CONTACTNAME_CLASS, NULL);
481
482 return ecordova_contactname_clone(name);
483}
484
485static Ecordova_ContactAddress *
486_contactaddress_copy(Ecordova_ContactAddress *address)
487{
488 if (!address)
489 return NULL;
490
491 Eina_Bool pref = EINA_FALSE;
492 const char *type = NULL;
493 const char *formatted = NULL;
494 const char *street_address = NULL;
495 const char *locality = NULL;
496 const char *region = NULL;
497 const char *postal_code = NULL;
498 const char *country = NULL;
499 eo_do(address,
500 pref = ecordova_contactaddress_pref_get(),
501 type = ecordova_contactaddress_type_get(),
502 formatted = ecordova_contactaddress_formatted_get(),
503 street_address = ecordova_contactaddress_street_address_get(),
504 locality = ecordova_contactaddress_locality_get(),
505 region = ecordova_contactaddress_region_get(),
506 postal_code = ecordova_contactaddress_postal_code_get(),
507 country = ecordova_contactaddress_country_get());
508
509 return eo_add(ECORDOVA_CONTACTADDRESS_CLASS,
510 NULL,
511 ecordova_contactaddress_constructor(pref,
512 type,
513 formatted,
514 street_address,
515 locality,
516 region,
517 postal_code,
518 country));
519}
520
521static Ecordova_ContactField *
522_contactfield_copy(Ecordova_ContactField *field)
523{
524 if (!field)
525 return NULL;
526
527 const char *type = NULL;
528 const char *value = NULL;
529 Eina_Bool pref = EINA_FALSE;
530 eo_do(field,
531 type = ecordova_contactfield_type_get(),
532 value = ecordova_contactfield_value_get(),
533 pref = ecordova_contactfield_pref_get());
534
535 return eo_add(ECORDOVA_CONTACTFIELD_CLASS, NULL,
536 ecordova_contactfield_constructor(type, value, pref));
537}
538
539static Ecordova_ContactOrganization *
540_contactorganization_copy(Ecordova_ContactOrganization *organization)
541{
542 if (!organization)
543 return NULL;
544
545 Eina_Bool pref = EINA_FALSE;
546 const char *type = NULL;
547 const char *name = NULL;
548 const char *dept = NULL;
549 const char *title = NULL;
550 eo_do(organization,
551 pref = ecordova_contactorganization_pref_get(),
552 type = ecordova_contactorganization_type_get(),
553 name = ecordova_contactorganization_name_get(),
554 dept = ecordova_contactorganization_dept_get(),
555 title = ecordova_contactorganization_title_get());
556
557 return eo_add(ECORDOVA_CONTACTORGANIZATION_CLASS,
558 NULL,
559 ecordova_contactorganization_constructor(pref,
560 type,
561 name,
562 dept,
563 title));
564}
565
566static Eina_Array *
567_contactfield_array_copy(Eina_Array *fields)
568{
569 Eina_Array *result = eina_array_new(1);
570 if (!fields)
571 return result;
572
573 size_t i;
574 Ecordova_ContactField *field;
575 Eina_Array_Iterator it;
576 EINA_ARRAY_ITER_NEXT(fields, i, field, it)
577 eina_array_push(result, _contactfield_copy(field));
578 return result;
579}
580
581static Eina_Array *
582_contactaddress_array_copy(Eina_Array *addresses)
583{
584 Eina_Array *result = eina_array_new(1);
585 if (!addresses)
586 return result;
587
588 size_t i;
589 Ecordova_ContactAddress *address;
590 Eina_Array_Iterator it;
591 EINA_ARRAY_ITER_NEXT(addresses, i, address, it)
592 eina_array_push(result, _contactaddress_copy(address));
593 return result;
594}
595
596static Eina_Array *
597_contactorganization_array_copy(Eina_Array *organizations)
598{
599 Eina_Array *result = eina_array_new(1);
600 if (!organizations)
601 return result;
602
603 size_t i;
604 Ecordova_ContactOrganization *organization;
605 Eina_Array_Iterator it;
606 EINA_ARRAY_ITER_NEXT(organizations, i, organization, it)
607 eina_array_push(result, _contactorganization_copy(organization));
608 return result;
609}
610
611static void
612_contactfield_array_free(Eina_Array *fields)
613{
614 if (!fields)
615 return;
616
617 size_t i;
618 Ecordova_ContactField *field;
619 Eina_Array_Iterator it;
620 EINA_ARRAY_ITER_NEXT(fields, i, field, it)
621 eo_unref(field);
622 eina_array_free(fields);
623}
624
625static void
626_contactaddress_array_free(Eina_Array *addresses)
627{
628 if (!addresses)
629 return;
630
631 size_t i;
632 Ecordova_ContactAddress *address;
633 Eina_Array_Iterator it;
634 EINA_ARRAY_ITER_NEXT(addresses, i, address, it)
635 eo_unref(address);
636 eina_array_free(addresses);
637}
638
639static void
640_contactorganization_array_free(Eina_Array *organizations)
641{
642 if (!organizations)
643 return;
644
645 size_t i;
646 Ecordova_ContactOrganization *organization;
647 Eina_Array_Iterator it;
648 EINA_ARRAY_ITER_NEXT(organizations, i, organization, it)
649 eo_unref(organization);
650 eina_array_free(organizations);
651}
652
653static void
654_contactfield_array_clear_id(Eina_Array *fields)
655{
656 if (!fields)
657 return;
658
659 size_t i;
660 Ecordova_ContactField *field;
661 Eina_Array_Iterator it;
662 EINA_ARRAY_ITER_NEXT(fields, i, field, it)
663 {
664 Ecordova_ContactField_Data *pd =
665 eo_data_scope_get(field, ECORDOVA_CONTACTFIELD_CLASS);
666 EINA_SAFETY_ON_NULL_RETURN(pd);
667
668 pd->id = 0;
669 }
670}
671
672static void
673_contactaddress_array_clear_id(Eina_Array *addresses)
674{
675 if (!addresses)
676 return;
677
678 size_t i;
679 Ecordova_ContactAddress *address;
680 Eina_Array_Iterator it;
681 EINA_ARRAY_ITER_NEXT(addresses, i, address, it)
682 {
683 Ecordova_ContactAddress_Data *pd =
684 eo_data_scope_get(address, ECORDOVA_CONTACTADDRESS_CLASS);
685 EINA_SAFETY_ON_NULL_RETURN(pd);
686
687 pd->id = 0;
688 }
689}
690
691static void
692_contactorganization_array_clear_id(Eina_Array *organizations)
693{
694 if (!organizations)
695 return;
696
697 size_t i;
698 Ecordova_ContactOrganization *organization;
699 Eina_Array_Iterator it;
700 EINA_ARRAY_ITER_NEXT(organizations, i, organization, it)
701 {
702 Ecordova_ContactOrganization_Data *pd =
703 eo_data_scope_get(organization, ECORDOVA_CONTACTORGANIZATION_CLASS);
704 EINA_SAFETY_ON_NULL_RETURN(pd);
705
706 pd->id = 0;
707 }
708}
709
710static const Ecordova_ContactField_Metadata
711_contact_number_metadata = {
712 .uri = &_contacts_number._uri,
713 .ids = {
714 [ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID] = &_contacts_contact.number,
715 [ECORDOVA_CONTACTFIELD_PROPERTY_ID] = &_contacts_number.id,
716 [ECORDOVA_CONTACTFIELD_PROPERTY_TYPE] = &_contacts_number.type,
717 [ECORDOVA_CONTACTFIELD_PROPERTY_LABEL] = &_contacts_number.label,
718 [ECORDOVA_CONTACTFIELD_PROPERTY_VALUE] = &_contacts_number.number,
719 [ECORDOVA_CONTACTFIELD_PROPERTY_PREF] = &_contacts_number.is_default},
720 .type2label = ecordova_contactnumber_type2label,
721 .label2type = ecordova_contactnumber_label2type
722};
723
724static const Ecordova_ContactField_Metadata
725_contact_email_metadata = {
726 .uri = &_contacts_email._uri,
727 .ids = {
728 [ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID] = &_contacts_contact.email,
729 [ECORDOVA_CONTACTFIELD_PROPERTY_ID] = &_contacts_email.id,
730 [ECORDOVA_CONTACTFIELD_PROPERTY_TYPE] = &_contacts_email.type,
731 [ECORDOVA_CONTACTFIELD_PROPERTY_LABEL] = &_contacts_email.label,
732 [ECORDOVA_CONTACTFIELD_PROPERTY_VALUE] = &_contacts_email.email,
733 [ECORDOVA_CONTACTFIELD_PROPERTY_PREF] = &_contacts_email.is_default},
734 .type2label = ecordova_contactemail_type2label,
735 .label2type = ecordova_contactemail_label2type
736};
737
738static const Ecordova_ContactField_Metadata
739_contact_messenger_metadata = {
740 .uri = &_contacts_messenger._uri,
741 .ids = {
742 [ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID] = &_contacts_contact.messenger,
743 [ECORDOVA_CONTACTFIELD_PROPERTY_ID] = &_contacts_messenger.id,
744 [ECORDOVA_CONTACTFIELD_PROPERTY_TYPE] = &_contacts_messenger.type,
745 [ECORDOVA_CONTACTFIELD_PROPERTY_LABEL] = &_contacts_messenger.label,
746 [ECORDOVA_CONTACTFIELD_PROPERTY_VALUE] = &_contacts_messenger.im_id,
747 [ECORDOVA_CONTACTFIELD_PROPERTY_PREF] = NULL},
748 .type2label = ecordova_contactmessenger_type2label,
749 .label2type = ecordova_contactmessenger_label2type
750};
751
752static const Ecordova_ContactField_Metadata
753_contact_image_metadata = {
754 .uri = &_contacts_image._uri,
755 .ids = {
756 [ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID] = &_contacts_contact.image,
757 [ECORDOVA_CONTACTFIELD_PROPERTY_ID] = &_contacts_image.id,
758 [ECORDOVA_CONTACTFIELD_PROPERTY_TYPE] = &_contacts_image.type,
759 [ECORDOVA_CONTACTFIELD_PROPERTY_LABEL] = &_contacts_image.label,
760 [ECORDOVA_CONTACTFIELD_PROPERTY_VALUE] = &_contacts_image.path,
761 [ECORDOVA_CONTACTFIELD_PROPERTY_PREF] = &_contacts_image.is_default},
762 .type2label = ecordova_contactimage_type2label,
763 .label2type = ecordova_contactimage_label2type
764};
765
766static const Ecordova_ContactField_Metadata
767_contact_url_metadata = {
768 .uri = &_contacts_url._uri,
769 .ids = {
770 [ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID] = &_contacts_contact.url,
771 [ECORDOVA_CONTACTFIELD_PROPERTY_ID] = &_contacts_url.id,
772 [ECORDOVA_CONTACTFIELD_PROPERTY_TYPE] = &_contacts_url.type,
773 [ECORDOVA_CONTACTFIELD_PROPERTY_LABEL] = &_contacts_url.label,
774 [ECORDOVA_CONTACTFIELD_PROPERTY_VALUE] = &_contacts_url.url,
775 [ECORDOVA_CONTACTFIELD_PROPERTY_PREF] = NULL},
776 .type2label = ecordova_contacturl_type2label,
777 .label2type = ecordova_contacturl_label2type
778};
779
780bool
781ecordova_contact_import(Ecordova_Contact *obj,
782 contacts_record_h contacts_record)
783{
784 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
785 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
786
787 Ecordova_Contact_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACT_CLASS);
788 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
789
790 int ret;
791
792 ret = contacts_record_destroy(pd->record, true);
793 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
794 ret = contacts_record_clone(contacts_record, &pd->record);
795 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
796
797 ret = contacts_record_get_int(pd->record, _contacts_contact.id, &pd->id);
798 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
799
800 // name
801 DBG("%s", "Importing name");
802 if (!ecordova_contactname_import(pd->name, pd->record))
803 return false;
804
805 // phone_numbers
806 DBG("%s", "Importing phone_numbers");
807 if (!_ecordova_contactfields_import(pd->phone_numbers,
808 pd->record,
809 _contact_number_metadata))
810 return false;
811
812 // emails
813 DBG("%s", "Importing emails");
814 if (!_ecordova_contactfields_import(pd->emails,
815 pd->record,
816 _contact_email_metadata))
817 return false;
818
819 // addresses
820 DBG("%s", "Importing addresses");
821 if (!_ecordova_contactaddresses_import(pd->addresses, pd->record))
822 return false;
823
824 // ims
825 DBG("%s", "Importing ims");
826 if (!_ecordova_contactfields_import(pd->ims,
827 pd->record,
828 _contact_messenger_metadata))
829 return false;
830
831 // organizations
832 DBG("%s", "Importing organizations");
833 if (!_ecordova_contactorganizations_import(pd->organizations, pd->record))
834 return false;
835
836 // photos
837 DBG("%s", "Importing photos");
838 if (!_ecordova_contactfields_import(pd->photos,
839 pd->record,
840 _contact_image_metadata))
841 return false;
842
843 // TODO: categories
844
845 // urls
846 DBG("%s", "Importing urls");
847 if (!_ecordova_contactfields_import(pd->urls,
848 pd->record,
849 _contact_url_metadata))
850 return false;
851
852 return true;
853}
854
855bool
856ecordova_contact_export(Ecordova_Contact *obj,
857 contacts_record_h contacts_record)
858{
859 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
860 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
861
862 Ecordova_Contact_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACT_CLASS);
863 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
864
865 // name
866 if (!clear_all_contact_record(contacts_record, _contacts_contact.name) ||
867 !ecordova_contactname_export(pd->name, contacts_record))
868 return false;
869
870 // phone_numbers
871 if (!_ecordova_contactfields_export(pd->phone_numbers,
872 contacts_record,
873 _contact_number_metadata))
874 return false;
875
876 // emails
877 if (!_ecordova_contactfields_export(pd->emails,
878 contacts_record,
879 _contact_email_metadata))
880 return false;
881
882 // addresses
883 if (!_ecordova_contactaddresses_export(pd->addresses, contacts_record))
884 return false;
885
886 // ims
887 if (!_ecordova_contactfields_export(pd->ims,
888 contacts_record,
889 _contact_messenger_metadata))
890 return false;
891
892 // organizations
893 if (!_ecordova_contactorganizations_export(pd->organizations, contacts_record))
894 return false;
895
896 // photos
897 if (!_ecordova_contactfields_export(pd->photos,
898 contacts_record,
899 _contact_image_metadata))
900 return false;
901
902 // TODO: categories
903
904 // urls
905 if (!_ecordova_contactfields_export(pd->urls,
906 contacts_record,
907 _contact_url_metadata))
908 return false;
909
910 return true;
911}
912
913static bool
914_ecordova_contactfields_import(Eina_Array *fields,
915 contacts_record_h contacts_record,
916 const Ecordova_ContactField_Metadata metadata)
917{
918 int ret;
919 int count = 0;
920 ret = contacts_record_get_child_record_count(contacts_record,
921 *metadata.ids[ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID],
922 &count);
923 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
924
925 DBG("Importing %d children", count);
926 for (int index = 0; index < count; ++index)
927 {
928 contacts_record_h child_record = NULL;
929 ret = contacts_record_get_child_record_at_p(contacts_record,
930 *metadata.ids[ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID],
931 index,
932 &child_record);
933 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
934
935 Ecordova_ContactField *field = eo_add(ECORDOVA_CONTACTFIELD_CLASS, NULL);
936 if (!ecordova_contactfield_import(field, child_record, metadata))
937 {
938 eo_unref(field);
939 return false;
940 }
941
942 Eina_Bool ret = eina_array_push(fields, field);
943 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, false);
944 }
945
946 return true;
947}
948
949static bool
950_ecordova_contactfields_export(Eina_Array *fields,
951 contacts_record_h contacts_record,
952 const Ecordova_ContactField_Metadata metadata)
953{
954 if (!clear_all_contact_record(contacts_record,
955 *metadata.ids[ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID]))
956 return false;
957
958 Ecordova_ContactField *field;
959 Eina_Array_Iterator iterator;
960 unsigned int i;
961 EINA_ARRAY_ITER_NEXT(fields, i, field, iterator)
962 {
963 contacts_record_h record = NULL;
964 int ret = contacts_record_create(*metadata.uri, &record);
965 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
966
967 if (!ecordova_contactfield_export(field, record, metadata))
968 {
969 ret = contacts_record_destroy(record, true);
970 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
971 return false;
972 }
973
974 ret = contacts_record_add_child_record(contacts_record,
975 *metadata.ids[ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID],
976 record);
977 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
978 }
979
980 return true;
981}
982
983static bool
984_ecordova_contactaddresses_import(Eina_Array *fields,
985 contacts_record_h contacts_record)
986{
987 int ret;
988 int count = 0;
989 ret = contacts_record_get_child_record_count(contacts_record,
990 _contacts_contact.address,
991 &count);
992 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
993
994 DBG("Importing %d addresses", count);
995 for (int index = 0; index < count; ++index)
996 {
997 contacts_record_h child_record = NULL;
998 ret = contacts_record_get_child_record_at_p(contacts_record,
999 _contacts_contact.address,
1000 index,
1001 &child_record);
1002 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1003
1004 Ecordova_ContactAddress *address = eo_add(ECORDOVA_CONTACTADDRESS_CLASS, NULL);
1005 if (!ecordova_contactaddress_import(address, child_record))
1006 {
1007 eo_unref(address);
1008 return false;
1009 }
1010
1011 Eina_Bool ret = eina_array_push(fields, address);
1012 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, false);
1013 }
1014
1015 return true;
1016}
1017
1018static bool
1019_ecordova_contactaddresses_export(Eina_Array *addresses,
1020 contacts_record_h contacts_record)
1021{
1022 if (!clear_all_contact_record(contacts_record, _contacts_contact.address))
1023 return false;
1024
1025 Ecordova_ContactAddress *address;
1026 Eina_Array_Iterator iterator;
1027 unsigned int i;
1028 EINA_ARRAY_ITER_NEXT(addresses, i, address, iterator)
1029 {
1030 contacts_record_h record = NULL;
1031 int ret = contacts_record_create(_contacts_address._uri, &record);
1032 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1033
1034 if (!ecordova_contactaddress_export(address, record))
1035 {
1036 ret = contacts_record_destroy(record, true);
1037 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1038 return false;
1039 }
1040
1041 ret = contacts_record_add_child_record(contacts_record,
1042 _contacts_contact.address,
1043 record);
1044 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1045 }
1046
1047 return true;
1048}
1049
1050static bool
1051_ecordova_contactorganizations_import(Eina_Array *organizations,
1052 contacts_record_h contacts_record)
1053{
1054 int ret;
1055 int count = 0;
1056 ret = contacts_record_get_child_record_count(contacts_record,
1057 _contacts_contact.company,
1058 &count);
1059 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1060
1061 DBG("Importing %d organizations", count);
1062 for (int index = 0; index < count; ++index)
1063 {
1064 contacts_record_h child_record = NULL;
1065 ret = contacts_record_get_child_record_at_p(contacts_record,
1066 _contacts_contact.company,
1067 index,
1068 &child_record);
1069 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1070
1071 Ecordova_ContactOrganization *organization = eo_add(ECORDOVA_CONTACTORGANIZATION_CLASS, NULL);
1072 if (!ecordova_contactorganization_import(organization, child_record))
1073 {
1074 eo_unref(organization);
1075 return false;
1076 }
1077
1078 Eina_Bool ret = eina_array_push(organizations, organization);
1079 EINA_SAFETY_ON_FALSE_RETURN_VAL(ret, false);
1080 }
1081
1082 return true;
1083}
1084
1085static bool
1086_ecordova_contactorganizations_export(Eina_Array *organizations,
1087 contacts_record_h contacts_record)
1088{
1089 if (!clear_all_contact_record(contacts_record, _contacts_contact.company))
1090 return false;
1091
1092 Ecordova_ContactOrganization *organization;
1093 Eina_Array_Iterator iterator;
1094 unsigned int i;
1095 EINA_ARRAY_ITER_NEXT(organizations, i, organization, iterator)
1096 {
1097 contacts_record_h record = NULL;
1098 int ret = contacts_record_create(_contacts_company._uri, &record);
1099 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1100
1101 if (!ecordova_contactaddress_export(organization, record))
1102 {
1103 ret = contacts_record_destroy(record, true);
1104 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1105 return false;
1106 }
1107
1108 ret = contacts_record_add_child_record(contacts_record,
1109 _contacts_contact.company,
1110 record);
1111 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
1112 }
1113
1114 return true;
1115}
1116
1117#include "ecordova_contact.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_contact_private.h b/src/modules/ecordova/tizen/ecordova_contact_private.h
new file mode 100644
index 0000000000..4a1ddc8deb
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contact_private.h
@@ -0,0 +1,38 @@
1#ifndef _ECORDOVA_CONTACT_PRIVATE_H
2#define _ECORDOVA_CONTACT_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_contactaddress.eo.h"
6#include "ecordova_contactfield.eo.h"
7#include "ecordova_contactname.eo.h"
8#include "ecordova_contactorganization.eo.h"
9#include "ecordova_contact.eo.h"
10
11#include <contacts.h>
12#include <stdbool.h>
13
14typedef struct _Ecordova_Contact_Data Ecordova_Contact_Data;
15
16/**
17 * Ecordova.Contact private data
18 */
19struct _Ecordova_Contact_Data
20{
21 Eo *obj;
22 contacts_record_h record;
23 int id;
24 Ecordova_ContactName *name;
25 Eina_Array *phone_numbers;
26 Eina_Array *emails;
27 Eina_Array *addresses;
28 Eina_Array *ims;
29 Eina_Array *organizations;
30 Eina_Array *photos;
31 Eina_Array *categories;
32 Eina_Array *urls;
33};
34
35bool ecordova_contact_import(Ecordova_Contact *, contacts_record_h);
36bool ecordova_contact_export(Ecordova_Contact *, contacts_record_h);
37
38#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contactaddress.c b/src/modules/ecordova/tizen/ecordova_contactaddress.c
new file mode 100644
index 0000000000..23918f2432
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactaddress.c
@@ -0,0 +1,312 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contactaddress_private.h"
6#include "ecordova_contacts_record_utils.h"
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <stdlib.h>
11
12#define MY_CLASS ECORDOVA_CONTACTADDRESS_CLASS
13#define MY_CLASS_NAME "Ecordova_ContactAddress"
14
15static Eo_Base *
16_ecordova_contactaddress_eo_base_constructor(Eo *obj,
17 Ecordova_ContactAddress_Data *pd)
18{
19 DBG("(%p)", obj);
20
21 pd->obj = obj;
22 pd->id = 0;
23 pd->record = NULL;
24 int ret = contacts_record_create(_contacts_address._uri, &pd->record);
25 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
26
27 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
28}
29
30static void
31_ecordova_contactaddress_constructor(Eo *obj,
32 Ecordova_ContactAddress_Data *pd EINA_UNUSED,
33 Eina_Bool pref,
34 const char *type,
35 const char *formatted,
36 const char *street_address,
37 const char *locality,
38 const char *region,
39 const char *postal_code,
40 const char *country)
41{
42 DBG("(%p)", obj);
43 eo_do(obj,
44 ecordova_contactaddress_pref_set(pref),
45 ecordova_contactaddress_type_set(type),
46 ecordova_contactaddress_formatted_set(formatted),
47 ecordova_contactaddress_street_address_set(street_address),
48 ecordova_contactaddress_locality_set(locality),
49 ecordova_contactaddress_region_set(region),
50 ecordova_contactaddress_postal_code_set(postal_code),
51 ecordova_contactaddress_country_set(country));
52}
53
54static void
55_ecordova_contactaddress_eo_base_destructor(Eo *obj,
56 Ecordova_ContactAddress_Data *pd)
57{
58 DBG("(%p)", obj);
59
60 int ret = contacts_record_destroy(pd->record, true);
61 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
62
63 eo_do_super(obj, MY_CLASS, eo_destructor());
64}
65
66static int
67_ecordova_contactaddress_id_get(Eo *obj EINA_UNUSED,
68 Ecordova_ContactAddress_Data *pd)
69{
70 return pd->id;
71}
72
73static Eina_Bool
74_ecordova_contactaddress_pref_get(Eo *obj EINA_UNUSED,
75 Ecordova_ContactAddress_Data *pd)
76{
77 Eina_Bool value = EINA_FALSE;
78 get_bool(pd->record, _contacts_address.is_default, &value);
79 return value;
80}
81
82static void
83_ecordova_contactaddress_pref_set(Eo *obj EINA_UNUSED,
84 Ecordova_ContactAddress_Data *pd,
85 Eina_Bool value)
86{
87 set_bool(pd->record, _contacts_address.is_default, value);
88}
89
90static const char *
91_ecordova_contactaddress_type_get(Eo *obj EINA_UNUSED,
92 Ecordova_ContactAddress_Data *pd)
93{
94 int type;
95 if (!get_int(pd->record, _contacts_address.type, &type))
96 return NULL;
97
98 switch (type)
99 {
100 case CONTACTS_ADDRESS_TYPE_HOME:
101 return "Home";
102 case CONTACTS_ADDRESS_TYPE_WORK:
103 return "Work";
104 case CONTACTS_ADDRESS_TYPE_DOM:
105 return "Dom";
106 case CONTACTS_ADDRESS_TYPE_INTL:
107 return "Intl";
108 case CONTACTS_ADDRESS_TYPE_POSTAL:
109 return "Postal";
110 case CONTACTS_ADDRESS_TYPE_PARCEL:
111 return "Parcel";
112 case CONTACTS_ADDRESS_TYPE_OTHER:
113 case CONTACTS_ADDRESS_TYPE_CUSTOM:
114 default:
115 {
116 const char *custom = NULL;
117 get_str_p(pd->record, _contacts_address.label, &custom);
118 return custom;
119 }
120 }
121}
122
123static void
124_ecordova_contactaddress_type_set(Eo *obj EINA_UNUSED,
125 Ecordova_ContactAddress_Data *pd,
126 const char *value)
127{
128 int type = CONTACTS_ADDRESS_TYPE_OTHER;
129 if (!value || strlen(value) == 0)
130 type = CONTACTS_ADDRESS_TYPE_OTHER;
131 else
132 if (strcasecmp(value, "Home"))
133 type = CONTACTS_ADDRESS_TYPE_HOME;
134 else if (strcasecmp(value, "Work"))
135 type = CONTACTS_ADDRESS_TYPE_WORK;
136 else if (strcasecmp(value, "Dom"))
137 type = CONTACTS_ADDRESS_TYPE_DOM;
138 else if (strcasecmp(value, "Intl"))
139 type = CONTACTS_ADDRESS_TYPE_INTL;
140 else if (strcasecmp(value, "Postal"))
141 type = CONTACTS_ADDRESS_TYPE_POSTAL;
142 else if (strcasecmp(value, "Parcel"))
143 type = CONTACTS_ADDRESS_TYPE_PARCEL;
144 else
145 type = CONTACTS_ADDRESS_TYPE_CUSTOM;
146
147 set_int(pd->record, _contacts_address.type, type);
148 if (strlen(value) != 0)
149 set_str(pd->record, _contacts_address.label, value);
150}
151
152static const char *
153_ecordova_contactaddress_formatted_get(Eo *obj EINA_UNUSED,
154 Ecordova_ContactAddress_Data *pd EINA_UNUSED)
155{
156 // TODO: mount the formatted address
157 ERR("%s", "Not implemented");
158 return NULL;
159}
160
161static void
162_ecordova_contactaddress_formatted_set(Eo *obj EINA_UNUSED,
163 Ecordova_ContactAddress_Data *pd EINA_UNUSED,
164 const char *formatted EINA_UNUSED)
165{
166 ERR("%s", "Not implemented");
167}
168
169static const char *
170_ecordova_contactaddress_street_address_get(Eo *obj EINA_UNUSED,
171 Ecordova_ContactAddress_Data *pd)
172{
173 const char *value = NULL;
174 get_str_p(pd->record, _contacts_address.street, &value);
175 return value;
176}
177
178static void
179_ecordova_contactaddress_street_address_set(Eo *obj EINA_UNUSED,
180 Ecordova_ContactAddress_Data *pd,
181 const char *value)
182{
183 set_str(pd->record, _contacts_address.street, value);
184}
185
186static const char *
187_ecordova_contactaddress_locality_get(Eo *obj EINA_UNUSED,
188 Ecordova_ContactAddress_Data *pd)
189{
190 const char *value = NULL;
191 get_str_p(pd->record, _contacts_address.locality, &value);
192 return value;
193}
194
195static void
196_ecordova_contactaddress_locality_set(Eo *obj EINA_UNUSED,
197 Ecordova_ContactAddress_Data *pd,
198 const char *value)
199{
200 set_str(pd->record, _contacts_address.locality, value);
201}
202
203static const char *
204_ecordova_contactaddress_region_get(Eo *obj EINA_UNUSED,
205 Ecordova_ContactAddress_Data *pd)
206{
207 const char *value = NULL;
208 get_str_p(pd->record, _contacts_address.region, &value);
209 return value;
210}
211
212static void
213_ecordova_contactaddress_region_set(Eo *obj EINA_UNUSED,
214 Ecordova_ContactAddress_Data *pd,
215 const char *value)
216{
217 set_str(pd->record, _contacts_address.region, value);
218}
219
220static const char *
221_ecordova_contactaddress_postal_code_get(Eo *obj EINA_UNUSED,
222 Ecordova_ContactAddress_Data *pd)
223{
224 const char *value = NULL;
225 get_str_p(pd->record, _contacts_address.postal_code, &value);
226 return value;
227}
228
229static void
230_ecordova_contactaddress_postal_code_set(Eo *obj EINA_UNUSED,
231 Ecordova_ContactAddress_Data *pd,
232 const char *value)
233{
234 set_str(pd->record, _contacts_address.postal_code, value);
235}
236
237static const char *
238_ecordova_contactaddress_country_get(Eo *obj EINA_UNUSED,
239 Ecordova_ContactAddress_Data *pd)
240{
241 const char *value = NULL;
242 get_str_p(pd->record, _contacts_address.country, &value);
243 return value;
244}
245
246static void
247_ecordova_contactaddress_country_set(Eo *obj EINA_UNUSED,
248 Ecordova_ContactAddress_Data *pd,
249 const char *value)
250{
251 set_str(pd->record, _contacts_address.country, value);
252}
253
254bool
255ecordova_contactaddress_import(Ecordova_ContactAddress *obj,
256 contacts_record_h child_record)
257{
258 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
259 EINA_SAFETY_ON_NULL_RETURN_VAL(child_record, false);
260
261 Ecordova_ContactAddress_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTADDRESS_CLASS);
262 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
263
264 int ret = contacts_record_destroy(pd->record, true);
265 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
266 ret = contacts_record_clone(child_record, &pd->record);
267 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
268
269 return get_int(child_record, _contacts_address.id, &pd->id);
270}
271
272bool
273ecordova_contactaddress_export(Ecordova_ContactAddress *obj,
274 contacts_record_h contacts_record)
275{
276 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
277 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
278
279 Ecordova_ContactAddress_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTADDRESS_CLASS);
280 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
281
282 contacts_record_h child_record = NULL;
283 int ret = contacts_record_clone(pd->record, &child_record);
284 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
285
286 ret = contacts_record_add_child_record(contacts_record,
287 _contacts_contact.address,
288 child_record);
289 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
290
291 return true;
292}
293
294Ecordova_ContactAddress *
295ecordova_contactaddress_clone(Ecordova_ContactAddress *other)
296{
297 Ecordova_ContactAddress *cloned = eo_add(ECORDOVA_CONTACTADDRESS_CLASS, NULL);
298
299 Ecordova_ContactAddress_Data *cloned_pd = eo_data_scope_get(cloned, ECORDOVA_CONTACTADDRESS_CLASS);
300 EINA_SAFETY_ON_NULL_RETURN_VAL(cloned_pd, NULL);
301 Ecordova_ContactAddress_Data *other_pd = eo_data_scope_get(other, ECORDOVA_CONTACTADDRESS_CLASS);
302 EINA_SAFETY_ON_NULL_RETURN_VAL(other_pd, NULL);
303
304 int ret = contacts_record_destroy(cloned_pd->record, true);
305 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
306 ret = contacts_record_clone(other_pd->record, &cloned_pd->record);
307 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
308
309 return cloned;
310}
311
312#include "ecordova_contactaddress.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_contactaddress_private.h b/src/modules/ecordova/tizen/ecordova_contactaddress_private.h
new file mode 100644
index 0000000000..56715d34f1
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactaddress_private.h
@@ -0,0 +1,25 @@
1#ifndef _ECORDOVA_CONTACTADDRESS_PRIVATE_H
2#define _ECORDOVA_CONTACTADDRESS_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_contactaddress.eo.h"
6
7#include <contacts.h>
8
9typedef struct _Ecordova_ContactAddress_Data Ecordova_ContactAddress_Data;
10
11/**
12 * Ecordova.ContactAddress private data
13 */
14struct _Ecordova_ContactAddress_Data
15{
16 Eo *obj;
17 int id;
18 contacts_record_h record;
19};
20
21bool ecordova_contactaddress_import(Ecordova_ContactAddress *, contacts_record_h);
22bool ecordova_contactaddress_export(Ecordova_ContactAddress *, contacts_record_h);
23Ecordova_ContactAddress *ecordova_contactaddress_clone(Ecordova_ContactAddress *);
24
25#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contactfield.c b/src/modules/ecordova/tizen/ecordova_contactfield.c
new file mode 100644
index 0000000000..8397a1944d
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactfield.c
@@ -0,0 +1,415 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contactfield_private.h"
6#include "ecordova_contacts_record_utils.h"
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <stdlib.h>
11
12#define MY_CLASS ECORDOVA_CONTACTFIELD_CLASS
13#define MY_CLASS_NAME "Ecordova_ContactField"
14
15static Eo_Base *
16_ecordova_contactfield_eo_base_constructor(Eo *obj,
17 Ecordova_ContactField_Data *pd)
18{
19 DBG("(%p)", obj);
20
21 pd->obj = obj;
22
23 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
24}
25
26static void
27_ecordova_contactfield_constructor(Eo *obj,
28 Ecordova_ContactField_Data *pd,
29 const char *type,
30 const char *value,
31 Eina_Bool pref)
32{
33 DBG("(%p)", obj);
34 pd->id = 0;
35 pd->type = type ? strdup(type) : NULL;
36 pd->value = value ? strdup(value) : NULL;
37 pd->pref = pref;
38}
39
40static void
41_ecordova_contactfield_eo_base_destructor(Eo *obj,
42 Ecordova_ContactField_Data *pd)
43{
44 DBG("(%p)", obj);
45
46 free(pd->type);
47 free(pd->value);
48
49 eo_do_super(obj, MY_CLASS, eo_destructor());
50}
51
52static int
53_ecordova_contactfield_id_get(Eo *obj EINA_UNUSED,
54 Ecordova_ContactField_Data *pd)
55{
56 return pd->id;
57}
58
59static const char *
60_ecordova_contactfield_type_get(Eo *obj EINA_UNUSED,
61 Ecordova_ContactField_Data *pd)
62{
63 return pd->type;
64}
65
66static void
67_ecordova_contactfield_type_set(Eo *obj EINA_UNUSED,
68 Ecordova_ContactField_Data *pd,
69 const char *type)
70{
71 free(pd->type);
72 pd->type = type ? strdup(type) : NULL;
73}
74
75static const char *
76_ecordova_contactfield_value_get(Eo *obj EINA_UNUSED,
77 Ecordova_ContactField_Data *pd)
78{
79 return pd->value;
80}
81
82static void
83_ecordova_contactfield_value_set(Eo *obj EINA_UNUSED,
84 Ecordova_ContactField_Data *pd,
85 const char *value)
86{
87 free(pd->value);
88 pd->value = value ? strdup(value) : NULL;
89}
90
91static Eina_Bool
92_ecordova_contactfield_pref_get(Eo *obj EINA_UNUSED,
93 Ecordova_ContactField_Data *pd)
94{
95 return pd->pref;
96}
97
98static void
99_ecordova_contactfield_pref_set(Eo *obj EINA_UNUSED,
100 Ecordova_ContactField_Data *pd,
101 Eina_Bool pref)
102{
103 pd->pref = pref;
104}
105
106bool
107ecordova_contactfield_import(Ecordova_ContactField *obj,
108 contacts_record_h record,
109 const Ecordova_ContactField_Metadata metadata)
110{
111 DBG("%p", obj);
112 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
113 EINA_SAFETY_ON_NULL_RETURN_VAL(record, false);
114
115 Ecordova_ContactField_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTFIELD_CLASS);
116 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
117
118 int type = 0;
119 const char* label = NULL;
120 if (!get_int(record,
121 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_TYPE],
122 &type) ||
123 !get_str_p(record,
124 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_LABEL],
125 &label))
126 return false;
127
128 pd->type = metadata.type2label(type, label);
129
130 if (!get_int(record,
131 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_ID],
132 &pd->id) ||
133 !get_str(record,
134 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_VALUE],
135 &pd->value))
136 return false;
137
138 if (metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_PREF] &&
139 !get_bool(record,
140 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_PREF],
141 &pd->pref))
142 return false;
143
144 return true;
145}
146
147bool
148ecordova_contactfield_export(Ecordova_ContactField *obj,
149 contacts_record_h record,
150 const Ecordova_ContactField_Metadata metadata)
151{
152 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
153 EINA_SAFETY_ON_NULL_RETURN_VAL(record, false);
154
155 Ecordova_ContactField_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTFIELD_CLASS);
156 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
157
158 int type = metadata.label2type(pd->type);
159 if (!set_int(record,
160 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_TYPE],
161 type))
162 return false;
163
164 if (pd->type &&
165 !set_str(record,
166 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_LABEL],
167 pd->type))
168 return false;
169
170 if (!set_str(record,
171 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_VALUE],
172 pd->value))
173 return false;
174
175 if (metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_PREF] &&
176 !set_bool(record,
177 *metadata.ids[ECORDOVA_CONTACTFIELD_PROPERTY_PREF],
178 pd->pref))
179 return false;
180
181 return true;
182}
183
184char *
185ecordova_contactnumber_type2label(int type, const char *custom)
186{
187 switch (type)
188 {
189 case CONTACTS_NUMBER_TYPE_HOME:
190 return strdup("Home");
191 case CONTACTS_NUMBER_TYPE_WORK:
192 return strdup("Work");
193 case CONTACTS_NUMBER_TYPE_VOICE:
194 return strdup("Voice");
195 case CONTACTS_NUMBER_TYPE_FAX:
196 return strdup("Fax");
197 case CONTACTS_NUMBER_TYPE_MSG:
198 return strdup("Msg");
199 case CONTACTS_NUMBER_TYPE_CELL:
200 return strdup("Cell");
201 case CONTACTS_NUMBER_TYPE_PAGER:
202 return strdup("Pager");
203 case CONTACTS_NUMBER_TYPE_BBS:
204 return strdup("BBS");
205 case CONTACTS_NUMBER_TYPE_MODEM:
206 return strdup("Modem");
207 case CONTACTS_NUMBER_TYPE_CAR:
208 return strdup("Car");
209 case CONTACTS_NUMBER_TYPE_ISDN:
210 return strdup("ISDN");
211 case CONTACTS_NUMBER_TYPE_VIDEO:
212 return strdup("Video");
213 case CONTACTS_NUMBER_TYPE_PCS:
214 return strdup("Pcs");
215 case CONTACTS_NUMBER_TYPE_COMPANY_MAIN:
216 return strdup("Company_Main");
217 case CONTACTS_NUMBER_TYPE_RADIO:
218 return strdup("Radio");
219 case CONTACTS_NUMBER_TYPE_MAIN:
220 return strdup("Main");
221 case CONTACTS_NUMBER_TYPE_ASSISTANT:
222 return strdup("Assistant");
223 case CONTACTS_NUMBER_TYPE_OTHER:
224 case CONTACTS_NUMBER_TYPE_CUSTOM:
225 default:
226 if (custom)
227 return strdup(custom);
228 return NULL;
229 }
230}
231
232int
233ecordova_contactnumber_label2type(const char *label)
234{
235 if (!label)
236 return CONTACTS_NUMBER_TYPE_OTHER;
237 if (strcasecmp(label, "Home") == 0)
238 return CONTACTS_NUMBER_TYPE_HOME;
239 if (strcasecmp(label, "Work") == 0)
240 return CONTACTS_NUMBER_TYPE_WORK;
241 if (strcasecmp(label, "Voice") == 0)
242 return CONTACTS_NUMBER_TYPE_VOICE;
243 if (strcasecmp(label, "Fax") == 0)
244 return CONTACTS_NUMBER_TYPE_FAX;
245 if (strcasecmp(label, "Msg") == 0)
246 return CONTACTS_NUMBER_TYPE_MSG;
247 if (strcasecmp(label, "Cell") == 0)
248 return CONTACTS_NUMBER_TYPE_CELL;
249 if (strcasecmp(label, "Pager") == 0)
250 return CONTACTS_NUMBER_TYPE_PAGER;
251 if (strcasecmp(label, "BBS") == 0)
252 return CONTACTS_NUMBER_TYPE_BBS;
253 if (strcasecmp(label, "Modem") == 0)
254 return CONTACTS_NUMBER_TYPE_MODEM;
255 if (strcasecmp(label, "Car") == 0)
256 return CONTACTS_NUMBER_TYPE_CAR;
257 if (strcasecmp(label, "ISDN") == 0)
258 return CONTACTS_NUMBER_TYPE_ISDN;
259 if (strcasecmp(label, "Video") == 0)
260 return CONTACTS_NUMBER_TYPE_VIDEO;
261 if (strcasecmp(label, "Pcs") == 0)
262 return CONTACTS_NUMBER_TYPE_PCS;
263 if (strcasecmp(label, "Company_Main") == 0)
264 return CONTACTS_NUMBER_TYPE_COMPANY_MAIN;
265 if (strcasecmp(label, "Radio") == 0)
266 return CONTACTS_NUMBER_TYPE_RADIO;
267 if (strcasecmp(label, "Main") == 0)
268 return CONTACTS_NUMBER_TYPE_MAIN;
269 if (strcasecmp(label, "Assistant") == 0)
270 return CONTACTS_NUMBER_TYPE_ASSISTANT;
271
272 return CONTACTS_NUMBER_TYPE_CUSTOM;
273}
274
275char *
276ecordova_contactemail_type2label(int type, const char *custom)
277{
278 switch (type)
279 {
280 case CONTACTS_EMAIL_TYPE_HOME:
281 return strdup("Home");
282 case CONTACTS_EMAIL_TYPE_WORK:
283 return strdup("Work");
284 case CONTACTS_EMAIL_TYPE_MOBILE:
285 return strdup("Mobile");
286 case CONTACTS_EMAIL_TYPE_OTHER:
287 case CONTACTS_EMAIL_TYPE_CUSTOM:
288 default:
289 if (custom)
290 return strdup(custom);
291 return NULL;
292 }
293}
294
295int
296ecordova_contactemail_label2type(const char *label)
297{
298 if (!label)
299 return CONTACTS_EMAIL_TYPE_OTHER;
300 if (strcasecmp(label, "Home") == 0)
301 return CONTACTS_EMAIL_TYPE_HOME;
302 if (strcasecmp(label, "Work") == 0)
303 return CONTACTS_EMAIL_TYPE_WORK;
304 if (strcasecmp(label, "Mobile") == 0)
305 return CONTACTS_EMAIL_TYPE_MOBILE;
306
307 return CONTACTS_EMAIL_TYPE_CUSTOM;
308}
309
310char *
311ecordova_contactmessenger_type2label(int type, const char *custom)
312{
313 switch (type)
314 {
315 case CONTACTS_MESSENGER_TYPE_GOOGLE:
316 return strdup("Google");
317 case CONTACTS_MESSENGER_TYPE_WLM:
318 return strdup("Wlm");
319 case CONTACTS_MESSENGER_TYPE_YAHOO:
320 return strdup("Yahoo");
321 case CONTACTS_MESSENGER_TYPE_FACEBOOK:
322 return strdup("Facebook");
323 case CONTACTS_MESSENGER_TYPE_ICQ:
324 return strdup("Icq");
325 case CONTACTS_MESSENGER_TYPE_AIM:
326 return strdup("Aim");
327 case CONTACTS_MESSENGER_TYPE_QQ:
328 return strdup("Qq");
329 case CONTACTS_MESSENGER_TYPE_JABBER:
330 return strdup("Jabber");
331 case CONTACTS_MESSENGER_TYPE_SKYPE:
332 return strdup("Skype");
333 case CONTACTS_MESSENGER_TYPE_IRC:
334 return strdup("IRC");
335 case CONTACTS_MESSENGER_TYPE_OTHER:
336 case CONTACTS_MESSENGER_TYPE_CUSTOM:
337 default:
338 if (custom)
339 return strdup(custom);
340 return NULL;
341 }
342}
343
344int
345ecordova_contactmessenger_label2type(const char *label)
346{
347 if (!label)
348 return CONTACTS_MESSENGER_TYPE_OTHER;
349 if (strcasecmp(label, "Google") == 0)
350 return CONTACTS_MESSENGER_TYPE_GOOGLE;
351 if (strcasecmp(label, "Wlm") == 0)
352 return CONTACTS_MESSENGER_TYPE_WLM;
353 if (strcasecmp(label, "Yahoo") == 0)
354 return CONTACTS_MESSENGER_TYPE_YAHOO;
355 if (strcasecmp(label, "Facebook") == 0)
356 return CONTACTS_MESSENGER_TYPE_FACEBOOK;
357 if (strcasecmp(label, "Icq") == 0)
358 return CONTACTS_MESSENGER_TYPE_ICQ;
359 if (strcasecmp(label, "Aim") == 0)
360 return CONTACTS_MESSENGER_TYPE_AIM;
361 if (strcasecmp(label, "Qq") == 0)
362 return CONTACTS_MESSENGER_TYPE_QQ;
363 if (strcasecmp(label, "Jabber") == 0)
364 return CONTACTS_MESSENGER_TYPE_JABBER;
365 if (strcasecmp(label, "Skype") == 0)
366 return CONTACTS_MESSENGER_TYPE_SKYPE;
367 if (strcasecmp(label, "IRC") == 0)
368 return CONTACTS_MESSENGER_TYPE_IRC;
369
370 return CONTACTS_MESSENGER_TYPE_CUSTOM;
371}
372
373char *
374ecordova_contactimage_type2label(int type EINA_UNUSED, const char *custom)
375{
376 return custom ? strdup(custom) : NULL;
377}
378
379int
380ecordova_contactimage_label2type(const char *label EINA_UNUSED)
381{
382 return 0;
383}
384
385char *
386ecordova_contacturl_type2label(int type, const char *custom)
387{
388 switch (type)
389 {
390 case CONTACTS_URL_TYPE_HOME:
391 return strdup("Home");
392 case CONTACTS_URL_TYPE_WORK:
393 return strdup("Work");
394 case CONTACTS_URL_TYPE_OTHER:
395 case CONTACTS_URL_TYPE_CUSTOM:
396 default:
397 if (custom)
398 return strdup(custom);
399 return NULL;
400 }
401}
402
403int
404ecordova_contacturl_label2type(const char *label)
405{
406 if (!label)
407 return CONTACTS_URL_TYPE_OTHER;
408 if (strcasecmp(label, "Home") == 0)
409 return CONTACTS_URL_TYPE_HOME;
410 if (strcasecmp(label, "Work") == 0)
411 return CONTACTS_URL_TYPE_WORK;
412 return CONTACTS_URL_TYPE_CUSTOM;
413}
414
415#include "ecordova_contactfield.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_contactfield_private.h b/src/modules/ecordova/tizen/ecordova_contactfield_private.h
new file mode 100644
index 0000000000..408a40addc
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactfield_private.h
@@ -0,0 +1,58 @@
1#ifndef _ECORDOVA_CONTACTFIELD_PRIVATE_H
2#define _ECORDOVA_CONTACTFIELD_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_contactfield.eo.h"
6
7#include <contacts.h>
8#include <stdbool.h>
9
10typedef enum _Ecordova_ContactField_Property
11{
12 ECORDOVA_CONTACTFIELD_PARENT_PROPERTY_ID,
13 ECORDOVA_CONTACTFIELD_PROPERTY_ID,
14 ECORDOVA_CONTACTFIELD_PROPERTY_TYPE,
15 ECORDOVA_CONTACTFIELD_PROPERTY_LABEL,
16 ECORDOVA_CONTACTFIELD_PROPERTY_VALUE,
17 ECORDOVA_CONTACTFIELD_PROPERTY_PREF,
18 ECORDOVA_CONTACTFIELD_PROPERTY_COUNT
19} Ecordova_ContactField_Property;
20
21typedef struct _Ecordova_ContactField_Metadata
22{
23 const char * const *uri;
24 const unsigned int *ids[ECORDOVA_CONTACTFIELD_PROPERTY_COUNT];
25 char *(*type2label)(int type, const char *custom);
26 int(*label2type)(const char *label);
27} Ecordova_ContactField_Metadata;
28
29typedef struct _Ecordova_ContactField_Data Ecordova_ContactField_Data;
30
31/**
32 * Ecordova.ContactField private data
33 */
34struct _Ecordova_ContactField_Data
35{
36 Eo *obj;
37 int id;
38 char *type;
39 char *value;
40 Eina_Bool pref;
41 Ecordova_ContactField_Metadata metadata;
42};
43
44bool ecordova_contactfield_import(Ecordova_ContactField *, contacts_record_h, const Ecordova_ContactField_Metadata);
45bool ecordova_contactfield_export(Ecordova_ContactField *, contacts_record_h, const Ecordova_ContactField_Metadata);
46
47char *ecordova_contactnumber_type2label(int, const char *);
48int ecordova_contactnumber_label2type(const char *);
49char *ecordova_contactemail_type2label(int, const char *);
50int ecordova_contactemail_label2type(const char *);
51char *ecordova_contactmessenger_type2label(int, const char *);
52int ecordova_contactmessenger_label2type(const char *);
53char *ecordova_contactimage_type2label(int, const char *);
54int ecordova_contactimage_label2type(const char *);
55char *ecordova_contacturl_type2label(int, const char *);
56int ecordova_contacturl_label2type(const char *);
57
58#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contactname.c b/src/modules/ecordova/tizen/ecordova_contactname.c
new file mode 100644
index 0000000000..87cdcbfaaf
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactname.c
@@ -0,0 +1,257 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contactname_private.h"
6#include "ecordova_contact_private.h"
7#include "ecordova_contacts_record_utils.h"
8#include "ecordova_contactname.eo.h"
9
10#include <stdbool.h>
11#include <stdint.h>
12#include <stdlib.h>
13
14#define MY_CLASS ECORDOVA_CONTACTNAME_CLASS
15#define MY_CLASS_NAME "Ecordova_ContactName"
16
17static Eo_Base *
18_ecordova_contactname_eo_base_constructor(Eo *obj,
19 Ecordova_ContactName_Data *pd)
20{
21 DBG("(%p)", obj);
22
23 pd->obj = obj;
24 pd->record = NULL;
25 int ret = contacts_record_create(_contacts_name._uri, &pd->record);
26 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
27
28 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
29}
30
31static void
32_ecordova_contactname_constructor(Eo *obj,
33 Ecordova_ContactName_Data *pd EINA_UNUSED,
34 const char *formatted,
35 const char *family_name,
36 const char *given_name,
37 const char *middle,
38 const char *prefix,
39 const char *suffix)
40{
41 DBG("(%p)", obj);
42 eo_do(obj,
43 ecordova_contactname_formatted_set(formatted),
44 ecordova_contactname_family_name_set(family_name),
45 ecordova_contactname_given_name_set(given_name),
46 ecordova_contactname_middle_set(middle),
47 ecordova_contactname_prefix_set(prefix),
48 ecordova_contactname_suffix_set(suffix));
49}
50
51static void
52_ecordova_contactname_eo_base_destructor(Eo *obj, Ecordova_ContactName_Data *pd)
53{
54 DBG("(%p)", obj);
55
56 int ret = contacts_record_destroy(pd->record, true);
57 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
58
59 eo_do_super(obj, MY_CLASS, eo_destructor());
60}
61
62static const char *
63_ecordova_contactname_formatted_get(Eo *obj,
64 Ecordova_ContactName_Data *pd EINA_UNUSED)
65{
66 Eo *parent = NULL;
67 eo_do(obj, parent = eo_parent_get());
68 EINA_SAFETY_ON_NULL_RETURN_VAL(parent, NULL);
69
70 Ecordova_Contact_Data *parent_pd = eo_data_scope_get(parent, ECORDOVA_CONTACT_CLASS);
71 EINA_SAFETY_ON_NULL_RETURN_VAL(parent_pd, NULL);
72
73 const char *value = NULL;
74 get_str_p(parent_pd->record, _contacts_contact.display_name, &value);
75 return value;
76}
77
78static void
79_ecordova_contactname_formatted_set(Eo *obj,
80 Ecordova_ContactName_Data *pd EINA_UNUSED,
81 const char *value)
82{
83 Eo *parent = NULL;
84 eo_do(obj, parent = eo_parent_get());
85 EINA_SAFETY_ON_NULL_RETURN(parent);
86
87 Ecordova_Contact_Data *parent_pd = eo_data_scope_get(parent, ECORDOVA_CONTACT_CLASS);
88 EINA_SAFETY_ON_NULL_RETURN(parent_pd);
89
90 set_str(parent_pd->record, _contacts_contact.display_name, value);
91}
92
93static const char *
94_ecordova_contactname_family_name_get(Eo *obj EINA_UNUSED,
95 Ecordova_ContactName_Data *pd)
96{
97 const char *value = NULL;
98 get_str_p(pd->record, _contacts_name.last, &value);
99 return value;
100}
101
102static void
103_ecordova_contactname_family_name_set(Eo *obj EINA_UNUSED,
104 Ecordova_ContactName_Data *pd,
105 const char *value)
106{
107 set_str(pd->record, _contacts_name.last, value);
108}
109
110static const char *
111_ecordova_contactname_given_name_get(Eo *obj EINA_UNUSED,
112 Ecordova_ContactName_Data *pd)
113{
114 const char *value = NULL;
115 get_str_p(pd->record, _contacts_name.first, &value);
116 return value;
117}
118
119static void
120_ecordova_contactname_given_name_set(Eo *obj EINA_UNUSED,
121 Ecordova_ContactName_Data *pd,
122 const char *value)
123{
124 set_str(pd->record, _contacts_name.first, value);
125}
126
127static const char *
128_ecordova_contactname_middle_get(Eo *obj EINA_UNUSED,
129 Ecordova_ContactName_Data *pd)
130{
131 const char *value = NULL;
132 get_str_p(pd->record, _contacts_name.addition, &value);
133 return value;
134}
135
136static void
137_ecordova_contactname_middle_set(Eo *obj EINA_UNUSED,
138 Ecordova_ContactName_Data *pd,
139 const char *value)
140{
141 set_str(pd->record, _contacts_name.addition, value);
142}
143
144static const char *
145_ecordova_contactname_prefix_get(Eo *obj EINA_UNUSED,
146 Ecordova_ContactName_Data *pd)
147{
148 const char *value = NULL;
149 get_str_p(pd->record, _contacts_name.prefix, &value);
150 return value;
151}
152
153static void
154_ecordova_contactname_prefix_set(Eo *obj EINA_UNUSED,
155 Ecordova_ContactName_Data *pd,
156 const char *value)
157{
158 set_str(pd->record, _contacts_name.prefix, value);
159}
160
161static const char *
162_ecordova_contactname_suffix_get(Eo *obj EINA_UNUSED,
163 Ecordova_ContactName_Data *pd)
164{
165 const char *value = NULL;
166 get_str_p(pd->record, _contacts_name.suffix, &value);
167 return value;
168}
169
170static void
171_ecordova_contactname_suffix_set(Eo *obj EINA_UNUSED,
172 Ecordova_ContactName_Data *pd,
173 const char *value)
174{
175 set_str(pd->record, _contacts_name.suffix, value);
176}
177
178bool
179ecordova_contactname_import(Ecordova_ContactName *obj,
180 contacts_record_h contacts_record)
181{
182 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
183 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
184
185 Ecordova_ContactName_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTNAME_CLASS);
186 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
187
188 int ret;
189
190 int count = 0;
191 ret = contacts_record_get_child_record_count(contacts_record,
192 _contacts_contact.name,
193 &count);
194 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
195 EINA_SAFETY_ON_FALSE_RETURN_VAL(count == 1, false);
196
197 contacts_record_h contactname_record = NULL;
198 ret = contacts_record_get_child_record_at_p(contacts_record,
199 _contacts_contact.name,
200 0,
201 &contactname_record);
202 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
203
204 ret = contacts_record_destroy(pd->record, true);
205 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
206 ret = contacts_record_clone(contactname_record, &pd->record);
207 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
208
209 // TODO: check display name
210
211 return true;
212}
213
214bool
215ecordova_contactname_export(Ecordova_ContactName *obj,
216 contacts_record_h contacts_record)
217{
218 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
219 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
220
221 Ecordova_ContactName_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTNAME_CLASS);
222 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
223
224 contacts_record_h contactname_record = NULL;
225 int ret = contacts_record_clone(pd->record, &contactname_record);
226 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
227
228 ret = contacts_record_add_child_record(contacts_record,
229 _contacts_contact.name,
230 contactname_record);
231 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
232
233 // TODO: check display name
234
235 return true;
236}
237
238Ecordova_ContactName *
239ecordova_contactname_clone(Ecordova_ContactName *other)
240{
241 Ecordova_ContactName *cloned = eo_add(ECORDOVA_CONTACTNAME_CLASS, NULL);
242
243 Ecordova_ContactName_Data *cloned_pd = eo_data_scope_get(cloned, ECORDOVA_CONTACTNAME_CLASS);
244 EINA_SAFETY_ON_NULL_RETURN_VAL(cloned_pd, NULL);
245 Ecordova_ContactName_Data *other_pd = eo_data_scope_get(other, ECORDOVA_CONTACTNAME_CLASS);
246 EINA_SAFETY_ON_NULL_RETURN_VAL(other_pd, NULL);
247
248 int ret = contacts_record_destroy(cloned_pd->record, true);
249 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
250 ret = contacts_record_clone(other_pd->record, &cloned_pd->record);
251 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
252
253 return cloned;
254}
255
256
257#include "ecordova_contactname.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_contactname_private.h b/src/modules/ecordova/tizen/ecordova_contactname_private.h
new file mode 100644
index 0000000000..ccdcd61cb8
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactname_private.h
@@ -0,0 +1,25 @@
1#ifndef _ECORDOVA_CONTACTNAME_PRIVATE_H
2#define _ECORDOVA_CONTACTNAME_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_contactname.eo.h"
6
7#include <contacts.h>
8#include <stdbool.h>
9
10typedef struct _Ecordova_ContactName_Data Ecordova_ContactName_Data;
11
12/**
13 * Ecordova.ContactName private data
14 */
15struct _Ecordova_ContactName_Data
16{
17 Eo *obj;
18 contacts_record_h record;
19};
20
21bool ecordova_contactname_import(Ecordova_ContactName *, contacts_record_h);
22bool ecordova_contactname_export(Ecordova_ContactName *, contacts_record_h);
23Ecordova_ContactName *ecordova_contactname_clone(Ecordova_ContactName *);
24
25#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contactorganization.c b/src/modules/ecordova/tizen/ecordova_contactorganization.c
new file mode 100644
index 0000000000..50cbde09cf
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactorganization.c
@@ -0,0 +1,232 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contactorganization_private.h"
6#include "ecordova_contacts_record_utils.h"
7
8#include <stdbool.h>
9#include <stdint.h>
10#include <stdlib.h>
11
12#define MY_CLASS ECORDOVA_CONTACTORGANIZATION_CLASS
13#define MY_CLASS_NAME "Ecordova_ContactOrganization"
14
15static Eo_Base *
16_ecordova_contactorganization_eo_base_constructor(Eo *obj,
17 Ecordova_ContactOrganization_Data *pd)
18{
19 DBG("(%p)", obj);
20
21 pd->obj = obj;
22 pd->id = 0;
23 pd->record = NULL;
24 int ret = contacts_record_create(_contacts_company._uri, &pd->record);
25 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
26
27 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
28}
29
30static void
31_ecordova_contactorganization_constructor(Eo *obj,
32 Ecordova_ContactOrganization_Data *pd EINA_UNUSED,
33 Eina_Bool pref EINA_UNUSED,
34 const char *type,
35 const char *name,
36 const char *dept,
37 const char *title)
38{
39 DBG("(%p)", obj);
40 eo_do(obj,
41 ecordova_contactorganization_type_set(type),
42 ecordova_contactorganization_name_set(name),
43 ecordova_contactorganization_dept_set(dept),
44 ecordova_contactorganization_title_set(title));
45}
46
47static void
48_ecordova_contactorganization_eo_base_destructor(Eo *obj,
49 Ecordova_ContactOrganization_Data *pd)
50{
51 DBG("(%p)", obj);
52
53 int ret = contacts_record_destroy(pd->record, true);
54 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
55
56 eo_do_super(obj, MY_CLASS, eo_destructor());
57}
58
59static int
60_ecordova_contactorganization_id_get(Eo *obj EINA_UNUSED,
61 Ecordova_ContactOrganization_Data *pd)
62{
63 return pd->id;
64}
65
66static Eina_Bool
67_ecordova_contactorganization_pref_get(Eo *obj EINA_UNUSED,
68 Ecordova_ContactOrganization_Data *pd EINA_UNUSED)
69{
70 ERR("%s", "Not implemented");
71 return EINA_FALSE;
72}
73
74static void
75_ecordova_contactorganization_pref_set(Eo *obj EINA_UNUSED,
76 Ecordova_ContactOrganization_Data *pd EINA_UNUSED,
77 Eina_Bool pref EINA_UNUSED)
78{
79 ERR("%s", "Not implemented");
80}
81
82static const char *
83_ecordova_contactorganization_type_get(Eo *obj EINA_UNUSED,
84 Ecordova_ContactOrganization_Data *pd)
85{
86 int type;
87 if (!get_int(pd->record, _contacts_company.type, &type))
88 return NULL;
89
90 switch (type)
91 {
92 case CONTACTS_COMPANY_TYPE_WORK:
93 return "Work";
94 case CONTACTS_COMPANY_TYPE_OTHER:
95 case CONTACTS_COMPANY_TYPE_CUSTOM:
96 default:
97 {
98 const char *custom = NULL;
99 get_str_p(pd->record, _contacts_company.label, &custom);
100 return custom;
101 }
102 }
103}
104
105static void
106_ecordova_contactorganization_type_set(Eo *obj EINA_UNUSED,
107 Ecordova_ContactOrganization_Data *pd,
108 const char *value)
109{
110 int type = CONTACTS_COMPANY_TYPE_OTHER;
111 if (!value || strlen(value) == 0)
112 type = CONTACTS_COMPANY_TYPE_OTHER;
113 else if (strcasecmp(value, "Work"))
114 type = CONTACTS_COMPANY_TYPE_WORK;
115 else
116 type = CONTACTS_COMPANY_TYPE_CUSTOM;
117
118 set_int(pd->record, _contacts_company.type, type);
119 if (strlen(value) != 0)
120 set_str(pd->record, _contacts_company.label, value);
121}
122
123static const char *
124_ecordova_contactorganization_name_get(Eo *obj EINA_UNUSED,
125 Ecordova_ContactOrganization_Data *pd)
126{
127 const char *value = NULL;
128 get_str_p(pd->record, _contacts_company.name, &value);
129 return value;
130}
131
132static void
133_ecordova_contactorganization_name_set(Eo *obj EINA_UNUSED,
134 Ecordova_ContactOrganization_Data *pd,
135 const char *value)
136{
137 set_str(pd->record, _contacts_company.name, value);
138}
139
140static const char *
141_ecordova_contactorganization_dept_get(Eo *obj EINA_UNUSED,
142 Ecordova_ContactOrganization_Data *pd)
143{
144 const char *value = NULL;
145 get_str_p(pd->record, _contacts_company.department, &value);
146 return value;
147}
148
149static void
150_ecordova_contactorganization_dept_set(Eo *obj EINA_UNUSED,
151 Ecordova_ContactOrganization_Data *pd,
152 const char *value)
153{
154 set_str(pd->record, _contacts_company.department, value);
155}
156
157static const char *
158_ecordova_contactorganization_title_get(Eo *obj EINA_UNUSED,
159 Ecordova_ContactOrganization_Data *pd)
160{
161 const char *value = NULL;
162 get_str_p(pd->record, _contacts_company.job_title, &value);
163 return value;
164}
165
166static void
167_ecordova_contactorganization_title_set(Eo *obj EINA_UNUSED,
168 Ecordova_ContactOrganization_Data *pd,
169 const char *value)
170{
171 set_str(pd->record, _contacts_company.job_title, value);
172}
173
174bool
175ecordova_contactorganization_import(Ecordova_ContactOrganization *obj,
176 contacts_record_h child_record)
177{
178 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
179 EINA_SAFETY_ON_NULL_RETURN_VAL(child_record, false);
180
181 Ecordova_ContactOrganization_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTORGANIZATION_CLASS);
182 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
183
184 int ret = contacts_record_destroy(pd->record, true);
185 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
186 ret = contacts_record_clone(child_record, &pd->record);
187 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
188
189 return get_int(child_record, _contacts_company.id, &pd->id);
190}
191
192bool
193ecordova_contactorganization_export(Ecordova_ContactOrganization *obj,
194 contacts_record_h contacts_record)
195{
196 EINA_SAFETY_ON_NULL_RETURN_VAL(obj, false);
197 EINA_SAFETY_ON_NULL_RETURN_VAL(contacts_record, false);
198
199 Ecordova_ContactOrganization_Data *pd = eo_data_scope_get(obj, ECORDOVA_CONTACTORGANIZATION_CLASS);
200 EINA_SAFETY_ON_NULL_RETURN_VAL(pd, false);
201
202 contacts_record_h child_record = NULL;
203 int ret = contacts_record_clone(pd->record, &child_record);
204 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
205
206 ret = contacts_record_add_child_record(contacts_record,
207 _contacts_contact.company,
208 child_record);
209 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, false);
210
211 return true;
212}
213
214Ecordova_ContactOrganization *
215ecordova_contactorganization_clone(Ecordova_ContactOrganization *other)
216{
217 Ecordova_ContactOrganization *cloned = eo_add(ECORDOVA_CONTACTORGANIZATION_CLASS, NULL);
218
219 Ecordova_ContactOrganization_Data *cloned_pd = eo_data_scope_get(cloned, ECORDOVA_CONTACTORGANIZATION_CLASS);
220 EINA_SAFETY_ON_NULL_RETURN_VAL(cloned_pd, NULL);
221 Ecordova_ContactOrganization_Data *other_pd = eo_data_scope_get(other, ECORDOVA_CONTACTORGANIZATION_CLASS);
222 EINA_SAFETY_ON_NULL_RETURN_VAL(other_pd, NULL);
223
224 int ret = contacts_record_destroy(cloned_pd->record, true);
225 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
226 ret = contacts_record_clone(other_pd->record, &cloned_pd->record);
227 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
228
229 return cloned;
230}
231
232#include "ecordova_contactorganization.eo.c"
diff --git a/src/modules/ecordova/tizen/ecordova_contactorganization_private.h b/src/modules/ecordova/tizen/ecordova_contactorganization_private.h
new file mode 100644
index 0000000000..643b11792d
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contactorganization_private.h
@@ -0,0 +1,25 @@
1#ifndef _ECORDOVA_CONTACTORGANIZATION_PRIVATE_H
2#define _ECORDOVA_CONTACTORGANIZATION_PRIVATE_H
3
4#include "ecordova_private.h"
5#include "ecordova_contactorganization.eo.h"
6
7#include <contacts.h>
8
9typedef struct _Ecordova_ContactOrganization_Data Ecordova_ContactOrganization_Data;
10
11/**
12 * Ecordova.ContactOrganization private data
13 */
14struct _Ecordova_ContactOrganization_Data
15{
16 Eo *obj;
17 int id;
18 contacts_record_h record;
19};
20
21bool ecordova_contactorganization_import(Ecordova_ContactOrganization *, contacts_record_h);
22bool ecordova_contactorganization_export(Ecordova_ContactOrganization *, contacts_record_h);
23Ecordova_ContactOrganization *ecordova_contactorganization_clone(Ecordova_ContactOrganization *);
24
25#endif
diff --git a/src/modules/ecordova/tizen/ecordova_contacts.c b/src/modules/ecordova/tizen/ecordova_contacts.c
new file mode 100644
index 0000000000..c914ec08fb
--- /dev/null
+++ b/src/modules/ecordova/tizen/ecordova_contacts.c
@@ -0,0 +1,519 @@
1#ifdef HAVE_CONFIG_H
2# include <config.h>
3#endif
4
5#include "ecordova_contacts_private.h"
6#include "ecordova_contact_private.h"
7#include "ecordova_contacts_record_utils.h"
8
9#include <contacts.h>
10
11#include <stdbool.h>
12#include <stdint.h>
13#include <stdlib.h>
14
15#define MY_CLASS ECORDOVA_CONTACTS_CLASS
16#define MY_CLASS_NAME "Ecordova_Contacts"
17
18typedef enum Contacts_Search_Id {
19 SEARCH_CONTACT,
20 SEARCH_ADDRESS,
21 SEARCH_EVENT,
22 SEARCH_COMPANY,
23 SEARCH_EMAIL,
24 SEARCH_NAME,
25 SEARCH_NICKNAME,
26 SEARCH_MESSENGER,
27 SEARCH_NOTE,
28 SEARCH_NUMBER,
29 SEARCH_URL,
30 SEARCH_IMAGE,
31 SEARCH_ID_COUNT
32} Contacts_Search_Id;
33
34static contacts_filter_h _filter_get(contacts_filter_h *, const char *);
35static contacts_list_h _get_records(const Eina_List *, const Ecordova_Contacts_FindOptions *);
36static bool _search_records(contacts_filter_h, const char *, contacts_list_h *, Eina_Bool);
37static bool _populate_list(contacts_list_h, Eina_Hash *, contacts_filter_h, const char *, int, Eina_Bool);
38
39static Eo_Base *
40_ecordova_contacts_eo_base_constructor(Eo *obj, Ecordova_Contacts_Data *pd)
41{
42 DBG("(%p)", obj);
43
44 pd->obj = obj;
45
46 return eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
47}
48
49static void
50_ecordova_contacts_constructor(Eo *obj EINA_UNUSED,
51 Ecordova_Contacts_Data *pd EINA_UNUSED)
52{
53 DBG("(%p)", obj);
54}
55
56static void
57_ecordova_contacts_eo_base_destructor(Eo *obj,
58 Ecordova_Contacts_Data *pd EINA_UNUSED)
59{
60 DBG("(%p)", obj);
61
62 eo_do_super(obj, MY_CLASS, eo_destructor());
63}
64
65static void
66_ecordova_contacts_find(Eo *obj,
67 Ecordova_Contacts_Data *pd EINA_UNUSED,
68 const Eina_List *fields,
69 const Ecordova_Contacts_FindOptions *options)
70{
71 DBG("(%p)", obj);
72 if (!fields)
73 {
74 Ecordova_Contacts_Error error = ECORDOVA_CONTACTS_ERROR_INVALID_ARGUMENT_ERROR;
75 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_ERROR, &error));
76 return;
77 }
78
79 // TODO: load all records in a background thread
80
81 contacts_list_h list = NULL;
82
83 const char *field = eina_list_data_get(fields);
84 if (strcmp("*", field) == 0)
85 {
86 int ret = contacts_db_get_all_records(_contacts_contact._uri, 0, 0, &list);
87 if (CONTACTS_ERROR_NONE != ret)
88 {
89 ERR("%s returned %d", "contacts_db_get_all_records", ret);
90 Ecordova_Contacts_Error error = ECORDOVA_CONTACTS_ERROR_UNKNOWN_ERROR;
91 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_ERROR, &error));
92 return;
93 }
94 }
95 else
96 {
97 if (!options)
98 {
99 ERR("%s", "options cannot be NULL");
100 Ecordova_Contacts_Error error = ECORDOVA_CONTACTS_ERROR_INVALID_ARGUMENT_ERROR;
101 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_ERROR, &error));
102 return;
103 }
104
105 if (!options->filter)
106 {
107 ERR("%s", "options.filter cannot be NULL");
108 Ecordova_Contacts_Error error = ECORDOVA_CONTACTS_ERROR_INVALID_ARGUMENT_ERROR;
109 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_ERROR, &error));
110 return;
111 }
112
113 list = _get_records(fields, options);
114 if (!list)
115 {
116 Ecordova_Contacts_Error error = ECORDOVA_CONTACTS_ERROR_INVALID_ARGUMENT_ERROR;
117 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_ERROR, &error));
118 return;
119 }
120 }
121
122 Eina_Array *contacts = eina_array_new(1);
123 do
124 {
125 contacts_record_h record = NULL;
126 int ret = contacts_list_get_current_record_p(list, &record);
127 if (CONTACTS_ERROR_NONE != ret || !record)
128 {
129 WRN("contacts_list_get_current_record_p returned %d", ret);
130 break;
131 }
132
133 Ecordova_Contact *contact = eo_add(ECORDOVA_CONTACT_CLASS, NULL);
134 if (!ecordova_contact_import(contact, record))
135 {
136 WRN("%s", "Error importing contact record");
137 eo_unref(contact);
138 continue;
139 }
140
141 eina_array_push(contacts, contact);
142
143 } while (contacts_list_next(list) == CONTACTS_ERROR_NONE);
144
145 eo_do(obj, eo_event_callback_call(ECORDOVA_CONTACTS_EVENT_FIND_SUCCESS, contacts));
146
147 int ret;
148 size_t i;
149 Ecordova_Contact *contact;
150 Eina_Array_Iterator it;
151
152 EINA_ARRAY_ITER_NEXT(contacts, i, contact, it)
153 eo_unref(contact);
154 eina_array_free(contacts);
155
156 ret = contacts_list_destroy(list, true);
157 EINA_SAFETY_ON_FALSE_RETURN(CONTACTS_ERROR_NONE == ret);
158}
159
160static void
161_ecordova_contacts_contact_pick(Eo *obj EINA_UNUSED,
162 Ecordova_Contacts_Data *pd EINA_UNUSED)
163{
164 // TODO: pick_contact UI
165}
166
167static Ecordova_Contact *
168_ecordova_contacts_create(Eo *obj EINA_UNUSED,
169 Ecordova_Contacts_Data *pd EINA_UNUSED,
170 Ecordova_Contact *other EINA_UNUSED)
171{
172 // TODO: clone 'other' if it's not NULL
173 return eo_add(ECORDOVA_CONTACT_CLASS, NULL);
174}
175
176static contacts_filter_h
177_filter_get(contacts_filter_h *filter, const char *uri)
178{
179 if (NULL == *filter)
180 {
181 int ret = contacts_filter_create(uri, filter);
182 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
183 }
184 else
185 {
186 int ret = contacts_filter_add_operator(*filter, CONTACTS_FILTER_OPERATOR_OR);
187 EINA_SAFETY_ON_FALSE_RETURN_VAL(CONTACTS_ERROR_NONE == ret, NULL);
188 }
189
190 return *filter;
191}
192
193static contacts_list_h
194_get_records(const Eina_List *fields,
195 const Ecordova_Contacts_FindOptions *options)
196{
197 contacts_list_h list = NULL;
198
199 typedef struct
200 {
201 const char *field;
202 unsigned int property_id;
203 enum {INT_FIELD, STRING_FIELD, BIRTHDAY_FIELD, ADDRESSES_FIELD} type;
204 Contacts_Search_Id search_id;
205 } Search_Metadata;
206
207 Search_Metadata search_metadata[] = {
208 {"id", _contacts_contact.id, INT_FIELD, SEARCH_CONTACT},
209 {"display_name", _contacts_contact.display_name, STRING_FIELD, SEARCH_CONTACT},
210 {"formatted", _contacts_contact.display_name, STRING_FIELD, SEARCH_CONTACT},
211 {"name", _contacts_contact.display_name, STRING_FIELD, SEARCH_CONTACT},
212 {"given_name", _contacts_name.first, STRING_FIELD, SEARCH_NAME},
213 {"family_name", _contacts_name.last, STRING_FIELD, SEARCH_NAME},
214 {"honorific_prefix", _contacts_name.prefix, STRING_FIELD, SEARCH_NAME},
215 {"honorific_suffix", _contacts_name.suffix, STRING_FIELD, SEARCH_NAME},
216 {"middle_name", _contacts_name.addition, STRING_FIELD, SEARCH_NAME},
217 {"country", _contacts_address.country, STRING_FIELD, SEARCH_ADDRESS},