--- /dev/null
+/*
+ * Copyright (C) 2011, Jamie Thompson
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib.h>
+#include <glib/glist.h>
+#include <libosso.h>
+#include <libosso-abook/osso-abook.h>
+#include <libebook/e-book.h>
+#include <evolution-data-server-1.4/libebook/e-vcard.h>
+#include <evolution-data-server-1.4/libebook/e-contact.h>
+
+#include "NumberToNameLookup.h"
+
+#include <stdexcept>
+
+#include <QDebug>
+
+NumberToNameLookup::NumberToNameLookup()
+{
+ GError *gError(NULL);
+
+ // Initialize osso
+ osso_context_t *osso_context(osso_initialize ("qwerkisync", "0.1", true, NULL));
+ if (NULL == osso_context)
+ throw std::runtime_error("Error initializing osso");
+
+ try
+ {
+ // Init abook
+ if (!osso_abook_init_with_name("qwerkisync", osso_context))
+ throw std::runtime_error("Error initializing libosso-abook");
+
+ EBook *ebook(e_book_new_system_addressbook (&gError));
+ if (NULL == ebook)
+ {
+ QString error(QString("Error opening system address book: %1").arg(gError->message));
+ g_error_free(gError);
+ throw std::runtime_error(error.toStdString());
+ }
+
+ if (!e_book_open (ebook, true, &gError))
+ {
+ QString error(QString("Error opening system address book: %1").arg(gError->message));
+ g_error_free(gError);
+ throw std::runtime_error(error.toStdString());
+ }
+
+ EBookQuery *query(e_book_query_any_field_contains (""));
+
+ try
+ {
+ GList *contacts(NULL);
+ if (!e_book_get_contacts (ebook, query, &contacts, &gError))
+ {
+ QString error(QString("Error getting contacts: %1").arg(gError->message));
+ g_error_free(gError);
+ throw std::runtime_error(error.toStdString());
+ }
+
+ m_ContactDetails.reserve(g_list_length(contacts));
+
+ qDebug() << g_list_length(contacts) << " contacts.";
+
+ // Loop over each contact...
+ for (GList *currentContact(contacts); NULL != currentContact; currentContact = currentContact->next)
+ {
+ // Now work out the current name for the contact and add it to the lookup
+ EContactName *contactName = (EContactName*)e_contact_get((EContact*)currentContact->data, E_CONTACT_NAME);
+ char *completeName(e_contact_name_to_string(contactName));
+ qDebug() << completeName;
+
+ // Looking at each number they have...
+ GList * attrs(e_contact_get_attributes(E_CONTACT(currentContact->data), E_CONTACT_FIRST_PHONE_ID));
+ for (GList *attr(attrs); NULL != attr; attr = attr->next)
+ {
+ for(GList *val(e_vcard_attribute_get_values((EVCardAttribute *)attr->data)); NULL != val; val = val->next)
+ {
+ const gchar *number((char*)val->data);
+ if (NULL == number)
+ continue; // Ignore missing numbers
+
+ const char *remote_ebook_uid_string((const char *)e_contact_get_const (E_CONTACT (currentContact->data), E_CONTACT_UID));
+ if (NULL != remote_ebook_uid_string)
+ {
+ // This is what we really need for new events
+ uint remote_ebook_uid(QString(remote_ebook_uid_string).toUInt());
+
+ m_ContactDetails.insert(QString(number), QPair<uint, QString>(remote_ebook_uid, QString(completeName)));
+
+ qDebug() << "Number: " << number << ", ID: " << remote_ebook_uid << ", completeName: " << completeName;
+ }
+ }
+ }
+ g_list_free(attrs);
+
+ g_free(completeName);
+ e_contact_name_free(contactName);
+
+ // I hate C-style APIs.
+ g_object_unref(currentContact);
+ }
+
+ // I *really* hate C-style APIs.
+ g_list_free(contacts);
+ }
+ catch(...)
+ {
+ e_book_query_unref(query);
+ throw;
+ }
+
+ // Will wrap e_book_* in a class some other time (oh for 'finally' in C++).
+ e_book_query_unref(query);
+ }
+ catch(...)
+ {
+ osso_deinitialize (osso_context);
+ throw;
+ }
+
+ // Will wrap osso_* in a class some other time (oh for 'finally' in C++).
+ osso_deinitialize (osso_context);
+
+// foreach(QString key, ContactDetails.keys())
+// {
+// qDebug() << key << ", " << ContactDetails.value(key).first << ", " << ContactDetails.value(key).second << endl;
+// }
+}