diff --git a/coreapi/friend.c b/coreapi/friend.c index 6001c1a47..6ed7df80f 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -784,10 +784,56 @@ bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) { vcard = linphone_vcard_new(); linphone_vcard_set_full_name(vcard, fullName); - fr->vcard = vcard; + linphone_friend_set_vcard(fr, vcard); return TRUE; } +LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { + LinphoneAddress* linphone_address = NULL; + LinphoneFriend *fr; + const char *name = NULL; + MSList *sipAddresses = NULL; + + if (vcard == NULL) { + ms_error("Cannot create friend from null vcard"); + return NULL; + } + name = linphone_vcard_get_full_name(vcard); + sipAddresses = linphone_vcard_get_sip_addresses(vcard); + + fr = linphone_friend_new(); + linphone_friend_set_vcard(fr, vcard); + + if (sipAddresses) { + const char *sipAddress = (const char *)sipAddresses->data; + linphone_address = linphone_address_new(sipAddress); + if (linphone_address) { + linphone_friend_set_address(fr, linphone_address); + linphone_address_destroy(linphone_address); + } + } + linphone_friend_set_name(fr, name); + + return fr; +} + +int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file) { + MSList *vcards = linphone_vcard_new_from_vcard4_file(vcard_file); + int count = 0; + + while (vcards != NULL && vcards->data != NULL) { + LinphoneVCard *vcard = (LinphoneVCard *)vcards->data; + LinphoneFriend *lf = linphone_friend_new_from_vcard(vcard); + if (lf) { + linphone_core_add_friend(lc, lf); + count++; + } + vcards = ms_list_next(vcards); + } + + return count; +} + BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriend); BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriend, belle_sip_object_t, diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index ed3aa2b3a..3682546ff 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -434,6 +434,22 @@ LINPHONE_PUBLIC void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard * @return true if the vCard has been created, false if it wasn't possible (for exemple if name and the friend's SIP URI are null or if the friend's SIP URI doesn't have a display name), or if there is already one vcard */ LINPHONE_PUBLIC bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name); + +/** + * Contructor same as linphone_friend_new() + linphone_friend_set_address() + * @param vcard a VCard object + * @return a new #LinphoneFriend with \link linphone_friend_get_vcard() vcard initialized \endlink + */ +LINPHONE_PUBLIC LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard); + +/** + * Creates and adds LinphoneFriend objects to LinphoneCore from a file that contains the vcard(s) to parse + * @param[in] lc the LinphoneCore object + * @param[in] vcard_file the path to a file that contains the vcard(s) to parse + * @return the amount of linphone friends created + */ +LINPHONE_PUBLIC int linphone_core_import_friends_from_vcard4_file(LinphoneCore *lc, const char *vcard_file); + /** * @} */ diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 343f9063b..4d1a135b3 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vcard.h" #include "belcard/belcard.hpp" +#include "belcard/belcard_parser.hpp" struct _LinphoneVCard { shared_ptr belcard; @@ -35,13 +36,41 @@ extern "C" void linphone_vcard_free(LinphoneVCard *vcard) { ms_free(vcard); } +extern "C" MSList* linphone_vcard_new_from_vcard4_file(const char *filename) { + MSList *result = NULL; + if (filename) { + if (ortp_file_exist(filename) == 0) { + belcard::BelCardParser *parser = new belcard::BelCardParser(); + shared_ptr belCards = parser->parseFile(filename); + for (auto it = belCards->getCards().begin(); it != belCards->getCards().end(); ++it) { + shared_ptr belcard = (*it); + LinphoneVCard *vcard = linphone_vcard_new(); + vcard->belcard = belcard; + result = ms_list_append(result, vcard); + } + } + } + return result; +} + extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name) { shared_ptr fn = belcard::BelCardGeneric::create(); fn->setValue(name); vcard->belcard->setFullName(fn); } -extern "C" const char* linphone_vcard_get_full_name(LinphoneVCard *vcard) { +extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard) { const char *result = vcard->belcard->getFullName() ? vcard->belcard->getFullName()->getValue().c_str() : NULL; return result; +} + +extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard) { + MSList *result = NULL; + for (auto it = vcard->belcard->getImpp().begin(); it != vcard->belcard->getImpp().end(); ++it) { + const char *value = (*it)->getValue().c_str(); + if (strncmp(value, "sip:", 4) == 0) { + result = ms_list_append(result, (char *)value); + } + } + return result; } \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 7a2fbd42f..eaaab647a 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -35,9 +35,12 @@ typedef struct _LinphoneVCard LinphoneVCard; LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vcard); +LINPHONE_PUBLIC MSList* linphone_vcard_new_from_vcard4_file(const char *file); LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vcard, const char *name); -LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(LinphoneVCard *vcard); +LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vcard); + +LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vcard); #ifdef __cplusplus } diff --git a/gtk/main.c b/gtk/main.c index ba91fd3b3..68522578f 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1832,6 +1832,21 @@ void linphone_gtk_show_keypad_checked(GtkCheckMenuItem *check_menu_item) { } } +void linphone_gtk_import_contacts(void) { + GtkWidget *mw = linphone_gtk_get_main_window(); + GtkWidget *dialog; + dialog = gtk_file_chooser_dialog_new ("Open File", (GtkWindow *)mw, GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL); + if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) { + LinphoneCore *lc = linphone_gtk_get_core(); + char *filename; + filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); + linphone_core_import_friends_from_vcard4_file(lc, filename); + g_free (filename); + linphone_gtk_show_friends(); + } + gtk_widget_destroy (dialog); +} + gboolean linphone_gtk_keypad_destroyed_handler(void) { GtkWidget *mw = linphone_gtk_get_main_window(); GtkWidget *show_keypad_item = linphone_gtk_get_widget(mw, "show_keypad_menu_item"); diff --git a/gtk/main.ui b/gtk/main.ui index 98dc3400a..2c8ce2d50 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -228,6 +228,21 @@ False + + + True + False + Import contacts + True + + + + + + True + False + + gtk-quit