From 5aecbb16f274b4ad7768ec2baff73fd1cf2f11a5 Mon Sep 17 00:00:00 2001
From: Emmanuel Lepage Vallee <elv1313@gmail.com>
Date: Tue, 9 May 2017 03:25:08 -0400
Subject: [PATCH] phonedirectory: Add more explicit support for deduplicated
 RingId
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This commit complements the previous one. Now that Ring CMs are
properly deduplicated once their registeredName is validated,
disable the old entry in the debug model.

It also foward the deduplication signal to the RecentModel/Timeline
can also take notice. This greatly simplify the code.

Change-Id: I4e8839744d0eb12aa32f4bf6a8a50f7e0cc51d88
Reviewed-by: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
---
 src/phonedirectorymodel.cpp         | 43 +++++++++++++++++++++--------
 src/phonedirectorymodel.h           |  1 +
 src/private/phonedirectorymodel_p.h |  2 ++
 3 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/src/phonedirectorymodel.cpp b/src/phonedirectorymodel.cpp
index 8acf19ff..814c0aca 100644
--- a/src/phonedirectorymodel.cpp
+++ b/src/phonedirectorymodel.cpp
@@ -249,28 +249,36 @@ QVariant PhoneDirectoryModel::data(const QModelIndex& index, int role ) const
                return number->uid();
          }
          break;
+      case PhoneDirectoryModelPrivate::Columns::REGISTERED_NAME:
+         switch (role) {
+            case Qt::DisplayRole:
+            case Qt::ToolTipRole:
+               return number->registeredName();
+         }
+         break;
    }
    return QVariant();
 }
 
 int PhoneDirectoryModel::rowCount(const QModelIndex& parent ) const
 {
-   if (parent.isValid())
-      return 0;
-   return d_ptr->m_lNumbers.size();
+   return parent.isValid() ? 0 : d_ptr->m_lNumbers.size();
 }
 
 int PhoneDirectoryModel::columnCount(const QModelIndex& parent ) const
 {
-   Q_UNUSED(parent)
-   return 19;
+   return parent.isValid() ? 0 : 20;
 }
 
 Qt::ItemFlags PhoneDirectoryModel::flags(const QModelIndex& index ) const
 {
-   Q_UNUSED(index)
-
    const ContactMethod* number = d_ptr->m_lNumbers[index.row()];
+
+   // Mark the "old" duplicate as disabled. They are now zombies acting as
+   // proxies to the real contact methods.
+   if (number->isDuplicate())
+      return Qt::NoItemFlags;
+
    const bool enabled = !((index.column() == static_cast<int>(PhoneDirectoryModelPrivate::Columns::TRACKED)
       || static_cast<int>(PhoneDirectoryModelPrivate::Columns::PRESENT))
       && number->account() && (!number->account()->supportPresenceSubscribe()));
@@ -298,7 +306,7 @@ QVariant PhoneDirectoryModel::headerData(int section, Qt::Orientation orientatio
    Q_UNUSED(orientation)
    static const QString headers[] = {tr("URI"), tr("Type"), tr("Person"), tr("Account"), tr("State"), tr("Call count"), tr("Week count"),
    tr("Trimester count"), tr("Have Called"), tr("Last used"), tr("Name_count"),tr("Total (in seconds)"), tr("Popularity_index"),
-   tr("Bookmarked"), tr("Tracked"), tr("Has certificate"), tr("Present"), tr("Presence message"), tr("Uid") };
+   tr("Bookmarked"), tr("Tracked"), tr("Has certificate"), tr("Present"), tr("Presence message"), tr("Uid"), tr("Registered name") };
    if (role == Qt::DisplayRole) return headers[section];
    return QVariant();
 }
@@ -314,12 +322,12 @@ void PhoneDirectoryModelPrivate::setAccount(ContactMethod* number, Account* acco
    number->setAccount(account);
 
    if (!hasAtSign) {
-      NumberWrapper* wrap = m_hDirectory[strippedUri];
+      const QString extendedUri = strippedUri+'@'+account->hostname();
+      NumberWrapper* wrap = m_hDirectory[extendedUri];
 
       //Let make sure none is created in the future for nothing
       if (!wrap) {
          //It won't be a duplicate as none exist for this URI
-         const QString extendedUri = strippedUri+'@'+account->hostname();
          wrap = new NumberWrapper();
          m_hDirectory    [extendedUri] = wrap;
          m_hSortedNumbers[extendedUri] = wrap;
@@ -456,6 +464,7 @@ ContactMethod* PhoneDirectoryModel::getNumber(const URI& uri, const QString& typ
    connect(number,SIGNAL(changed()),d_ptr.data(),SLOT(slotChanged()));
    connect(number,&ContactMethod::lastUsedChanged,d_ptr.data(), &PhoneDirectoryModelPrivate::slotLastUsedChanged);
    connect(number,&ContactMethod::contactChanged ,d_ptr.data(), &PhoneDirectoryModelPrivate::slotContactChanged);
+   connect(number,&ContactMethod::rebased ,d_ptr.data(), &PhoneDirectoryModelPrivate::slotContactMethodMerged);
 
     // add the new cm into the historic.
     for (auto col : CategorizedHistoryModel::instance().collections(CollectionInterface::SupportedFeatures::ADD)) {
@@ -587,6 +596,7 @@ ContactMethod* PhoneDirectoryModel::getNumber(const QString& uri, Person* contac
    connect(number,SIGNAL(changed()),d_ptr.data(),SLOT(slotChanged()));
    connect(number,&ContactMethod::lastUsedChanged,d_ptr.data(), &PhoneDirectoryModelPrivate::slotLastUsedChanged);
    connect(number,&ContactMethod::contactChanged ,d_ptr.data(), &PhoneDirectoryModelPrivate::slotContactChanged );
+   connect(number,&ContactMethod::rebased ,d_ptr.data(), &PhoneDirectoryModelPrivate::slotContactMethodMerged);
    if (!wrap) {
       wrap = new NumberWrapper();
       d_ptr->m_hDirectory    [strippedUri] = wrap;
@@ -731,10 +741,21 @@ void PhoneDirectoryModelPrivate::slotChanged()
       if (idx<0)
          qDebug() << "Invalid slotChanged() index!" << idx;
 #endif
-      emit q_ptr->dataChanged(q_ptr->index(idx,0),q_ptr->index(idx,static_cast<int>(Columns::UID)));
+      emit q_ptr->dataChanged(q_ptr->index(idx,0),q_ptr->index(idx,static_cast<int>(Columns::REGISTERED_NAME)));
    }
 }
 
+/// Remove
+void PhoneDirectoryModelPrivate::slotContactMethodMerged(ContactMethod* other)
+{
+    // Other == cm when the person they depend on got merged. As a CM is an
+    // "person-lite" this still counts as most code paths care about both. Not
+    // this, so lets ignore the merged persons.
+    auto cm = qobject_cast<ContactMethod*>(sender());
+    if (other != cm)
+        emit q_ptr->contactMethodMerged(cm, other);
+}
+
 void PhoneDirectoryModelPrivate::slotLastUsedChanged(time_t t)
 {
    ContactMethod* cm = qobject_cast<ContactMethod*>(QObject::sender());
diff --git a/src/phonedirectorymodel.h b/src/phonedirectorymodel.h
index f31ddef8..a94f05a6 100644
--- a/src/phonedirectorymodel.h
+++ b/src/phonedirectorymodel.h
@@ -112,5 +112,6 @@ Q_SIGNALS:
    void lastUsedChanged(ContactMethod* cm, time_t t);
    void contactChanged(ContactMethod* cm, Person* newContact, Person* oldContact);
    void incomingMessage(ContactMethod* cm, const QMap<QString, QString>& payloads);
+   void contactMethodMerged(ContactMethod* cm, ContactMethod* into);
 };
 Q_DECLARE_METATYPE(PhoneDirectoryModel*)
diff --git a/src/private/phonedirectorymodel_p.h b/src/private/phonedirectorymodel_p.h
index 8fe4afe8..3607b3ca 100644
--- a/src/private/phonedirectorymodel_p.h
+++ b/src/private/phonedirectorymodel_p.h
@@ -74,6 +74,7 @@ public:
       PRESENT          = 16,
       PRESENCE_MESSAGE = 17,
       UID              = 18,
+      REGISTERED_NAME  = 19,
    };
 
 
@@ -104,6 +105,7 @@ private Q_SLOTS:
    void slotContactChanged(Person* newContact, Person* oldContact);
    void slotIncomingAccountMessage(const QString& account, const QString& from, const MapStringString& payloads);
    void slotRegisteredNameFound(const Account* account, NameDirectory::LookupStatus status, const QString& address, const QString& name);
+   void slotContactMethodMerged(ContactMethod* other);
 
    //From DBus
    void slotNewBuddySubscription(const QString& uri, const QString& accountId, bool status, const QString& message);
-- 
GitLab