diff --git a/src/abstractcontactbackend.cpp b/src/abstractcontactbackend.cpp index f9d00f681cd26663779a1f98c4fdb284c15bb4a3..fa838c0846a3e3a9104f4d6327baa2916695753e 100644 --- a/src/abstractcontactbackend.cpp +++ b/src/abstractcontactbackend.cpp @@ -39,115 +39,8 @@ AbstractContactBackend::AbstractContactBackend(QObject* par) : QObject(par?par:Q ///Destructor AbstractContactBackend::~AbstractContactBackend() { -// if (Call::contactBackend() == this) -// Call::setContactBackend(nullptr); -// foreach (Contact* c,m_ContactByUid) { -// delete c; -// } //TODO uncomment } -///Update slot -// ContactList AbstractContactBackend::update() -// { -// return update_slot(); - //TODO do something -// } - - -/***************************************************************************** - * * - * Model * - * * - ****************************************************************************/ - - -// bool AbstractContactBackend::setData( const QModelIndex& idx, const QVariant &value, int role) -// { -// Q_UNUSED(idx) -// Q_UNUSED(value) -// Q_UNUSED(role) -// return false; -// } - -// QVariant AbstractContactBackend::data( const QModelIndex& idx, int role) const -// { -// if (!idx.isValid()) -// return QVariant(); -// if (!idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) { -// const Contact* c = getContactList()[idx.row()]; -// if (c) -// return QVariant(c->formattedName()); -// } -// else if (idx.parent().isValid() && (role == Qt::DisplayRole || role == Qt::EditRole)) { -// const Contact* c = getContactList()[idx.parent().row()]; -// if (c) -// return QVariant(c->phoneNumbers()[idx.row()]->uri()); -// } -// return QVariant(); -// } - -// QVariant AbstractContactBackend::headerData(int section, Qt::Orientation orientation, int role) const -// { -// Q_UNUSED(section) -// if (orientation == Qt::Horizontal && role == Qt::DisplayRole) -// return QVariant(tr("Contacts")); -// return QVariant(); -// } - -// int AbstractContactBackend::rowCount( const QModelIndex& par ) const -// { -// if (!par.isValid()) { -// return getContactList().size(); -// } -// else if (!par.parent().isValid() && par.row() < getContactList().size()) { -// const Contact* c = getContactList()[par.row()]; -// if (c) { -// const int size = c->phoneNumbers().size(); -// return size==1?0:size; -// } -// } -// return 0; -// } - -// Qt::ItemFlags AbstractContactBackend::flags( const QModelIndex& idx ) const -// { -// if (!idx.isValid()) -// return Qt::NoItemFlags; -// return Qt::ItemIsEnabled | ((idx.parent().isValid())?Qt::ItemIsSelectable:Qt::ItemIsEnabled); -// } - -// int AbstractContactBackend::columnCount ( const QModelIndex& par) const -// { -// Q_UNUSED(par) -// return 1; -// } - -// QModelIndex AbstractContactBackend::parent( const QModelIndex& idx) const -// { -// if (!idx.isValid()) -// return QModelIndex(); -// CategorizedCompositeNode* modelItem = (CategorizedCompositeNode*)idx.internalPointer(); -// if (modelItem && modelItem->type() == CategorizedCompositeNode::Type::NUMBER) { -// int idx2 = getContactList().indexOf(((Contact::PhoneNumbers*)modelItem)->contact()); -// if (idx2 != -1) { -// return AbstractContactBackend::index(idx2,0,QModelIndex()); -// } -// } -// return QModelIndex(); -// } - -// QModelIndex AbstractContactBackend::index( int row, int column, const QModelIndex& par) const -// { -// if (!par.isValid() && getContactList().size() > row) { -// return createIndex(row,column,getContactList()[row]); -// } -// else if (par.isValid() && getContactList()[par.row()]->phoneNumbers().size() > row) { -// return createIndex(row,column,(CategorizedCompositeNode*)(&(getContactList()[par.row()]->phoneNumbers()))); -// } -// return QModelIndex(); -// } - - bool AbstractContactBackend::saveContacts(const QList<Contact*> contacts) { bool ret = true; diff --git a/src/abstractcontactbackend.h b/src/abstractcontactbackend.h index c41d4062b9297769fc50988985b607fac46d65c2..1bf3990d802bb81aed5216f1aa5d0fbec11742b7 100644 --- a/src/abstractcontactbackend.h +++ b/src/abstractcontactbackend.h @@ -57,16 +57,16 @@ public: virtual SupportedFeatures supportedFeatures() const =0; ///Edit 'contact', the implementation may be a GUI or somehting else - virtual void editContact ( Contact* contact ) = 0; + virtual bool editContact ( Contact* contact ) = 0; ///Add a new contact to the backend - virtual void addNewContact ( Contact* contact ) = 0; + virtual bool addNewContact ( Contact* contact ) = 0; ///Add a new phone number to an existing contact - virtual void addPhoneNumber( Contact* contact , PhoneNumber* number )=0; + virtual bool addPhoneNumber( Contact* contact , PhoneNumber* number )=0; Q_SIGNALS: - void collectionChanged(); + void reloaded(); void newContactAdded(Contact* c); }; diff --git a/src/contact.cpp b/src/contact.cpp index 7b1e418582d4f0d5deb37c3c6522c5a987eff24e..4999be7bd46c8b73efbe14fddc6750b39ffebe7f 100644 --- a/src/contact.cpp +++ b/src/contact.cpp @@ -107,7 +107,7 @@ const QString& Contact::preferredEmail() const } ///Get the unique identifier (used for drag and drop) -const QString& Contact::uid() const +const QByteArray& Contact::uid() const { return m_Uid; } @@ -191,7 +191,7 @@ void Contact::setPreferredEmail(const QString& name) } ///Set UID -void Contact::setUid(const QString& id) +void Contact::setUid(const QByteArray& id) { m_Uid = id; emit changed(); @@ -281,3 +281,16 @@ bool Contact::save() const { return m_pBackend->saveContact(this); } + +///Show an implementation dependant dialog to edit the contact +bool Contact::edit() +{ + return m_pBackend->editContact(this); +} + +///Add a new phone number to the backend +///@note The backend is expected to notify the Contact (asynchronously) when done +bool Contact::addPhoneNumber(PhoneNumber* n) +{ + return m_pBackend->addPhoneNumber(this,n); +} diff --git a/src/contact.h b/src/contact.h index ccb6d7faef72c06a9757e59ec9f194fc51aaed34..699fc1417ab874417b96046248cccdf136024080 100644 --- a/src/contact.h +++ b/src/contact.h @@ -68,7 +68,7 @@ public: Q_PROPERTY( QString secondName READ secondName WRITE setFamilyName ) Q_PROPERTY( QString formattedName READ formattedName WRITE setFormattedName ) Q_PROPERTY( QString organization READ organization WRITE setOrganization ) - Q_PROPERTY( QString uid READ uid WRITE setUid ) + Q_PROPERTY( QByteArray uid READ uid WRITE setUid ) Q_PROPERTY( QString preferredEmail READ preferredEmail WRITE setPreferredEmail ) // Q_PROPERTY( QPixmap* photo READ photo WRITE setPhoto ) Q_PROPERTY( QString group READ group WRITE setGroup ) @@ -77,6 +77,8 @@ public: //Mutator Q_INVOKABLE bool save() const; + Q_INVOKABLE bool edit() ; + Q_INVOKABLE bool addPhoneNumber(PhoneNumber* n); private: QString m_FirstName ; @@ -86,7 +88,7 @@ private: QString m_FormattedName ; QString m_PreferredEmail ; QString m_Organization ; - QString m_Uid ; + QByteArray m_Uid ; QString m_Group ; QString m_Department ; bool m_DisplayPhoto ; @@ -106,7 +108,7 @@ public: const QString& secondName () const; const QString& formattedName () const; const QString& organization () const; - const QString& uid () const; + const QByteArray& uid () const; const QString& preferredEmail () const; const QPixmap* photo () const; const QString& group () const; @@ -119,18 +121,18 @@ public: bool supportPresence () const; //Setters - void setPhoneNumbers ( PhoneNumbers ); - void setFormattedName ( const QString& name ); - void setNickName ( const QString& name ); - void setFirstName ( const QString& name ); - void setFamilyName ( const QString& name ); - void setOrganization ( const QString& name ); - void setPreferredEmail ( const QString& name ); - void setGroup ( const QString& name ); - void setDepartment ( const QString& name ); - void setUid ( const QString& id ); - void setPhoto ( QPixmap* photo ); - void setActive ( bool active ); + void setPhoneNumbers ( PhoneNumbers ); + void setFormattedName ( const QString& name ); + void setNickName ( const QString& name ); + void setFirstName ( const QString& name ); + void setFamilyName ( const QString& name ); + void setOrganization ( const QString& name ); + void setPreferredEmail ( const QString& name ); + void setGroup ( const QString& name ); + void setDepartment ( const QString& name ); + void setUid ( const QByteArray& id ); + void setPhoto ( QPixmap* photo ); + void setActive ( bool active ); private Q_SLOTS: void slotPresenceChanged(); diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp index ff6935818036e62eb31baa1cf2aaea0ad0a7c500..71bd814ac08adb5be3f27c95ce2ecc7afe5d919b 100644 --- a/src/contactmodel.cpp +++ b/src/contactmodel.cpp @@ -23,6 +23,7 @@ #include "contact.h" #include "call.h" #include "phonenumber.h" +#include "abstractcontactbackend.h" //Qt #include <QtCore/QHash> @@ -147,11 +148,17 @@ QModelIndex ContactModel::index( int row, int column, const QModelIndex& par) co return QModelIndex(); } +/***************************************************************************** + * * + * Mutator * + * * + ****************************************************************************/ + ///Find contact by UID -Contact* ContactModel::getContactByUid(const QString& uid) +Contact* ContactModel::getContactByUid(const QByteArray& uid) { - return m_ContactByUid[uid]; + return m_hContactsByUid[uid]; } ///Return if there is backends @@ -162,8 +169,14 @@ bool ContactModel::hasBackends() const bool ContactModel::addContact(Contact* c) { + if (!c) + return false; + beginInsertRows(QModelIndex(),m_lContacts.size()-1,m_lContacts.size()); m_lContacts << c; - m_ContactByUid[c->uid()] = c; + m_hContactsByUid[c->uid()] = c; + endInsertRows(); + emit layoutChanged(); + emit newContactAdded(c); return true; } @@ -178,3 +191,33 @@ const ContactList ContactModel::contacts() const { return m_lContacts; } + +void ContactModel::addBackend(AbstractContactBackend* backend) +{ + m_lBackends << backend; + connect(backend,SIGNAL(reloaded()),this,SLOT(slotReloaded())); + connect(backend,SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*))); +} + +bool ContactModel::addNewContact(Contact* c, AbstractContactBackend* backend) +{ + Q_UNUSED(backend); + return m_lBackends[0]->addNewContact(c); +} + + +/***************************************************************************** + * * + * Slot * + * * + ****************************************************************************/ + +void ContactModel::slotReloaded() +{ + emit reloaded(); +} + +void ContactModel::slotContactAdded(Contact* c) +{ + addContact(c); +} diff --git a/src/contactmodel.h b/src/contactmodel.h index 9d9cdc6e35f9c09c49bd892e3e4a859bd8a39f19..cb31285713d67ba1cac6889f2bb64e3ce4bfbc96 100644 --- a/src/contactmodel.h +++ b/src/contactmodel.h @@ -64,9 +64,10 @@ public: //Mutator bool addContact(Contact* c); void disableContact(Contact* c); + void addBackend(AbstractContactBackend* backend); //Getters - Contact* getContactByUid ( const QString& uid ); + Contact* getContactByUid ( const QByteArray& uid ); bool hasBackends () const; const ContactList contacts() const; @@ -83,33 +84,25 @@ public: //Singleton static ContactModel* instance(); -protected: -// virtual ContactList update_slot() = 0; - - //Helper -// QString getUserFromPhone (const QString &phoneNumber); - - //Attributes - QHash<QString,Contact*> m_ContactByUid ; - int m_UpdatesCounter; - private: //Attributes static ContactModel* m_spInstance; QList<AbstractContactBackend*> m_lBackends; + int m_UpdatesCounter; //Indexes QHash<QByteArray,Contact*> m_hContactsByUid; QVector<Contact*> m_lContacts; -// public Q_SLOTS: -// ContactList update(); +public Q_SLOTS: + bool addNewContact(Contact* c, AbstractContactBackend* backend = nullptr); -// private Q_SLOTS: -// void slotReloadModel(); +private Q_SLOTS: + void slotReloaded(); + void slotContactAdded(Contact* c); Q_SIGNALS: - void collectionChanged(); + void reloaded(); void newContactAdded(Contact* c); }; diff --git a/src/contactproxymodel.cpp b/src/contactproxymodel.cpp index c9e7068e098d76f51e0ea739e74cdf15a259ed53..0dbc34a8c008fa3b2623770f274bd8d98f1a38a7 100644 --- a/src/contactproxymodel.cpp +++ b/src/contactproxymodel.cpp @@ -24,7 +24,6 @@ #include <QtCore/QCoreApplication> //SFLPhone -#include "abstractcontactbackend.h" #include "callmodel.h" #include "historymodel.h" #include "phonenumber.h" @@ -136,14 +135,14 @@ void ContactTreeBinder::slotPhoneNumberCountAboutToChange(int count, int oldCoun } // -ContactProxyModel::ContactProxyModel(AbstractContactBackend* parent,int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()), -m_pModel(parent),m_Role(role),m_ShowAll(showAll),m_lCategoryCounter() +ContactProxyModel::ContactProxyModel(int role, bool showAll) : QAbstractItemModel(QCoreApplication::instance()), +m_Role(role),m_ShowAll(showAll),m_lCategoryCounter() { setObjectName("ContactProxyModel"); m_lCategoryCounter.reserve(32); m_lMimes << MIME_PLAIN_TEXT << MIME_PHONENUMBER; - connect(m_pModel,SIGNAL(collectionChanged()),this,SLOT(reloadCategories())); - connect(m_pModel,SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*))); + connect(ContactModel::instance(),SIGNAL(reloaded()),this,SLOT(reloadCategories())); + connect(ContactModel::instance(),SIGNAL(newContactAdded(Contact*)),this,SLOT(slotContactAdded(Contact*))); QHash<int, QByteArray> roles = roleNames(); roles.insert(ContactModel::Role::Organization ,QByteArray("organization") ); roles.insert(ContactModel::Role::Group ,QByteArray("group") ); @@ -467,7 +466,7 @@ QMimeData* ContactProxyModel::mimeData(const QModelIndexList &indexes) const if (ct->phoneNumbers().size() == 1) { mimeData->setData(MIME_PHONENUMBER , ct->phoneNumbers()[0]->toHash().toUtf8()); } - mimeData->setData(MIME_CONTACT , ct->uid().toUtf8()); + mimeData->setData(MIME_CONTACT , ct->uid()); } return mimeData; } break; diff --git a/src/contactproxymodel.h b/src/contactproxymodel.h index 6b315d3769d368c51e1c7cf11e73f77be1884ddd..0995a4ec38c4ae248f8077890173bf2c8eb60735 100644 --- a/src/contactproxymodel.h +++ b/src/contactproxymodel.h @@ -25,7 +25,7 @@ //SFLPhone #include "../lib/typedefs.h" #include "../lib/contact.h" -class AbstractContactBackend; +class ContactModel; class ContactTreeNode; class TopLevelItem; class ContactTreeBinder; @@ -37,10 +37,10 @@ class LIB_EXPORT ContactProxyModel : public QAbstractItemModel Q_OBJECT #pragma GCC diagnostic pop public: - friend class AbstractContactBackend; + friend class ContactModel; friend class ContactTreeNode; friend class ContactTreeBinder; - explicit ContactProxyModel(AbstractContactBackend* parent,int role = Qt::DisplayRole, bool showAll = false); + explicit ContactProxyModel(int role = Qt::DisplayRole, bool showAll = false); virtual ~ContactProxyModel(); //Setters @@ -70,7 +70,6 @@ private: //Attributes QHash<Contact*, time_t> m_hContactByDate ; - AbstractContactBackend* m_pModel ; QVector<TopLevelItem*> m_lCategoryCounter ; QHash<QString,TopLevelItem*> m_hCategories ; int m_Role ; diff --git a/src/phonedirectorymodel.cpp b/src/phonedirectorymodel.cpp index 20e3cd76eec60a49c5dcdd5243dcbe7e677402fc..5e901eb42e0ee69af6d142ce32a3657b61ebe3f8 100644 --- a/src/phonedirectorymodel.cpp +++ b/src/phonedirectorymodel.cpp @@ -406,7 +406,7 @@ PhoneNumber* PhoneDirectoryModel::fromHash(const QString& hash) if (fields.size() == 3) { const QString uri = fields[0]; Account* account = AccountListModel::instance()->getAccountById(fields[1]); - Contact* contact = ContactModel::instance()->getContactByUid(fields[2]); + Contact* contact = ContactModel::instance()->getContactByUid(fields[2].toUtf8()); return getNumber(uri,contact,account); } else if (fields.size() == 1) { diff --git a/src/transitionalcontactbackend.cpp b/src/transitionalcontactbackend.cpp index f9ac5bd786ef86e89534d6b092d2646befe35d67..24b0ff66473597750f7b8ada1db61c5bdbc0b215 100644 --- a/src/transitionalcontactbackend.cpp +++ b/src/transitionalcontactbackend.cpp @@ -51,20 +51,23 @@ bool TransitionalContactBackend::saveContact(const Contact* contact) return false; } -void TransitionalContactBackend::editContact( Contact* contact) +bool TransitionalContactBackend::editContact( Contact* contact) { Q_UNUSED(contact) + return false; } -void TransitionalContactBackend::addNewContact( Contact* contact) +bool TransitionalContactBackend::addNewContact( Contact* contact) { Q_UNUSED(contact) + return false; } -void TransitionalContactBackend::addPhoneNumber( Contact* contact , PhoneNumber* number ) +bool TransitionalContactBackend::addPhoneNumber( Contact* contact , PhoneNumber* number ) { Q_UNUSED(contact) Q_UNUSED(number) + return false; } diff --git a/src/transitionalcontactbackend.h b/src/transitionalcontactbackend.h index 4393b86237286d761a4490f1fbbcb7448fed92c0..cf35009e4325dbdd1ecaddb20254bcd458853b50 100644 --- a/src/transitionalcontactbackend.h +++ b/src/transitionalcontactbackend.h @@ -37,12 +37,12 @@ public: virtual bool saveContact(const Contact* contact); ///Edit 'contact', the implementation may be a GUI or somehting else - virtual void editContact ( Contact* contact ); + virtual bool editContact ( Contact* contact ); ///Add a new contact to the backend - virtual void addNewContact ( Contact* contact ); + virtual bool addNewContact ( Contact* contact ); ///Add a new phone number to an existing contact - virtual void addPhoneNumber( Contact* contact , PhoneNumber* number ); + virtual bool addPhoneNumber( Contact* contact , PhoneNumber* number ); SupportedFeatures supportedFeatures() const;