I have made the following changes intended for :
  CE:MW:Shared / nemo-qml-plugins

Please review and accept or decline.
BOSS has already run some checks on this request.
See the "Messages from BOSS" section below.

https://build.pub.meego.com//request/show/6840

Thank You,
Marko Saukko

[This message was auto-generated]

---

Request # 6840:

Messages from BOSS:

State: review at 2012-10-01T03:39:32 by bossbot

Reviews:
       accepted by bossbot : Prechecks succeeded.
       new for CE-maintainers : Please replace this text with a review and 
approve/reject the review (not the SR). BOSS will take care of the rest

Changes:
  submit: Project:MTF:MW / nemo-qml-plugins -> CE:MW:Shared / nemo-qml-plugins
  
changes files:
--------------
--- nemo-qml-plugins.changes
+++ nemo-qml-plugins.changes
@@ -0,0 +1,6 @@
+* Mon Oct 1 2012 Robin Burchell <[email protected]> - 0.0.7
+- Fixes NEMO#147: Balanced thumbnail directory (from Antti Seppäl)
+- Add API for listing details relevant to IM accounts (from Robin)
+- Emit all changed signals when a contact is updated (from John Brooks)
+- Add API for searching contacts (from Nicola De Filippo)
+

old:
----
  nemo-qml-plugins-0.0.6.tar.bz2

new:
----
  nemo-qml-plugins-0.0.7.tar.bz2

spec files:
-----------
--- nemo-qml-plugins.spec
+++ nemo-qml-plugins.spec
@@ -1,6 +1,6 @@
 # 
 # Do NOT Edit the Auto-generated Part!
-# Generated by: spectacle version 0.24.1
+# Generated by: spectacle version 0.25
 # 
 
 Name:       nemo-qml-plugins
@@ -9,7 +9,7 @@
 # << macros
 
 Summary:    Nemo QML plugins source package.
-Version:    0.0.6
+Version:    0.0.7
 Release:    1
 Group:      System/Libraries
 License:    BSD

other changes:
--------------

++++++ nemo-qml-plugins-0.0.6.tar.bz2 -> nemo-qml-plugins-0.0.7.tar.bz2
--- contacts/seasideperson.cpp
+++ contacts/seasideperson.cpp
@@ -42,265 +42,6 @@
 
 #include "seasideperson.h"
 
-#if 0
-    case AvatarRole:
-    {
-        QContactAvatar avatar = mContact.detail<QContactAvatar>();
-        if(!avatar.imageUrl().isEmpty()) {
-            return QUrl(avatar.imageUrl()).toString();
-        }
-        return QString();
-    }
-    case ThumbnailRole:
-    {
-        QContactThumbnail thumb = mContact.detail<QContactThumbnail>();
-        return thumb.thumbnail();
-    }
-    case FavoriteRole:
-    {
-        QContactFavorite fav = mContact.detail<QContactFavorite>();
-        if(!fav.isEmpty())
-            return QVariant(fav.isFavorite());
-        return false;
-    }
-    case OnlineAccountUriRole:
-    {
-        QStringList list;
-        foreach (const QContactOnlineAccount& account,
-                 mContact.details<QContactOnlineAccount>()){
-            if(!account.accountUri().isNull())
-                list << account.accountUri();
-        }
-        return list;
-    }
-    case OnlineServiceProviderRole:
-    {
-        QStringList list;
-        foreach (const QContactOnlineAccount& account,
-                 mContact.details<QContactOnlineAccount>()){
-            if(!account.serviceProvider().isNull())
-                list << account.serviceProvider();
-        }
-        return list;
-    }
-    case IsSelfRole:
-    {
-        if (isSelfContact(mContact.id().localId()))
-            return true;
-        return false;
-    }
-    case EmailAddressRole:
-    {
-        QStringList list;
-        foreach (const QContactEmailAddress& email,
-                 mContact.details<QContactEmailAddress>()){
-            if(!email.emailAddress().isNull())
-                list << email.emailAddress();
-        }
-        return list;
-    }
-    case EmailContextRole:
-    {
-        QStringList list;
-        foreach (const QContactEmailAddress& email,
-                 mContact.details<QContactEmailAddress>()) {
-            if (email.contexts().count() > 0)
-                list << email.contexts().at(0);
-        }
-        return list;
-    }
-    case PhoneNumberRole:
-    {
-        QStringList list;
-        foreach (const QContactPhoneNumber& phone,
-                 mContact.details<QContactPhoneNumber>()){
-            if(!phone.number().isNull())
-                list << phone.number();
-        }
-        return list;
-    }
-    case PhoneContextRole:
-    {
-        QStringList list;
-        foreach (const QContactPhoneNumber& phone,
-                 mContact.details<QContactPhoneNumber>()) {
-            if (phone.contexts().count() > 0)
-                list << phone.contexts().at(0);
-            else if (phone.subTypes().count() > 0)
-                list << phone.subTypes().at(0);
-        }
-        return list;
-    }
-    case AddressRole:
-    {
-        QStringList list;
-        QStringList fieldOrder = priv->localeHelper->getAddressFieldOrder();
-
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()) {
-            QString aStr;
-            QString temp;
-            QString addy = address.street();
-            QStringList streetList = addy.split("\n");
-
-            for (int i = 0; i < fieldOrder.size(); ++i) {
-                temp = "";
-                if (fieldOrder.at(i) == "street") {
-                    if (streetList.count() == 2)
-                        temp += streetList.at(0);
-                    else
-                        temp += addy;
-                } else if (fieldOrder.at(i) == "street2") {
-                    if (streetList.count() == 2)
-                        temp += streetList.at(1);
-                }
-                else if (fieldOrder.at(i) == "locale")
-                    temp += address.locality();
-                else if (fieldOrder.at(i) == "region")
-                    temp += address.region();
-                else if (fieldOrder.at(i) == "zip")
-                    temp += address.postcode();
-                else if (fieldOrder.at(i) == "country")
-                    temp += address.country();
-
-                if (i > 0)
-                    aStr += "\n" + temp.trimmed();
-                else
-                    aStr += temp.trimmed();
-            }
-
-            if (aStr == "")
-                aStr = address.street() + "\n" + address.locality() + "\n" +
-                       address.region() + "\n" + address.postcode() + "\n" +
-                       address.country();
-           list << aStr;
-        }
-        return list;
-    }
-    case AddressStreetRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()){
-            if(!address.street().isEmpty())
-                list << address.street();
-        }
-        return list;
-    }
-    case AddressLocaleRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()) {
-            if(!address.locality().isNull())
-                list << address.locality();
-        }
-        return list;
-    }
-    case AddressRegionRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()) {
-            if(!address.region().isNull())
-                list << address.region();
-        }
-        return list;
-    }
-    case AddressCountryRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()) {
-            if(!address.country().isNull())
-                list << address.country();
-        }
-        return list;
-    }
-    case AddressPostcodeRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>())
-            list << address.postcode();
-        return list;
-    }
-
-    case AddressContextRole:
-    {
-        QStringList list;
-        foreach (const QContactAddress& address,
-                 mContact.details<QContactAddress>()) {
-            if (address.contexts().count() > 0)
-                list << address.contexts().at(0);
-        }
-        return list;
-    }
-    case PresenceRole:
-    {
-        foreach (const QContactPresence& qp,
-                 mContact.details<QContactPresence>()) {
-            if(!qp.isEmpty())
-                if(qp.presenceState() == QContactPresence::PresenceAvailable)
-                    return qp.presenceState();
-        }
-        foreach (const QContactPresence& qp,
-                 mContact.details<QContactPresence>()) {
-            if(!qp.isEmpty())
-                if(qp.presenceState() == QContactPresence::PresenceBusy)
-                    return qp.presenceState();
-        }
-        return QContactPresence::PresenceUnknown;
-    }
-
-    case UuidRole:
-    {
-        QContactGuid guid = mContact.detail<QContactGuid>();
-        if(!guid.guid().isNull())
-            return guid.guid();
-        return QString();
-    }
-
-    case WebUrlRole:
-    {
-        QStringList list;
-       foreach(const QContactUrl &url, mContact.details<QContactUrl>()){
-        if(!url.isEmpty())
-            list << url.url();
-       }
-        return QStringList(list);
-    }
-
-    case WebContextRole:
-    {
-        QStringList list;
-       foreach(const QContactUrl &url, mContact.details<QContactUrl>()){
-        if(!url.contexts().isEmpty())
-            list << url.contexts();
-       }
-        return list;
-    }
-
-    case NotesRole:
-    {
-        QContactNote note = mContact.detail<QContactNote>();
-        if(!note.isEmpty())
-            return note.note();
-        return QString();
-    }
-    case FirstCharacterRole:
-    {
-        if (isSelfContact(mContact.id().localId()))
-            return QString(tr("#"));
-
-        return priv->localeHelper->getBinForString(data(row,
-                    DisplayLabelRole).toString());
-    }
-    case DisplayLabelRole: {
-    }
-
-#endif
-
 SeasidePerson::SeasidePerson(QObject *parent)
     : QObject(parent)
 {
@@ -545,6 +286,25 @@
     emit emailAddressesChanged();
 }
 
+// TODO: merge with LIST_PROPERTY_FROM_DETAIL_FIELD
+#define LIST_PROPERTY_FROM_FIELD_NAME(detailType, fieldName) \
+    QStringList list; \
+    \
+    foreach (const detailType &detail, mContact.details<detailType>()) { \
+        if (detail.hasValue(fieldName)) \
+            list << detail.value(fieldName); \
+    } \
+    return list;
+
+QStringList SeasidePerson::accountUris() const
+{
+    LIST_PROPERTY_FROM_FIELD_NAME(QContactOnlineAccount, 
QContactOnlineAccount::FieldAccountUri)
+}
+
+QStringList SeasidePerson::accountPaths() const
+{
+    LIST_PROPERTY_FROM_FIELD_NAME(QContactOnlineAccount, "AccountPath") // 
QContactOnlineAccount__FieldAccountPath
+}
 
 QContact SeasidePerson::contact() const
 {
@@ -553,8 +313,21 @@
 
 void SeasidePerson::setContact(const QContact &contact)
 {
+    mContact = contact;
+
     // TODO: this should difference the two contacts, and emit the proper
     // signals
-    mContact = contact;
+    emit firstNameChanged();
+    emit lastNameChanged();
+    emit companyNameChanged();
+    emit favoriteChanged();
+    emit avatarPathChanged();
+    emit birthdayChanged();
+    emit phoneNumbersChanged();
+    emit emailAddressesChanged();
+    emit accountUrisChanged();
+    emit accountPathsChanged();
+
+    recalculateDisplayLabel();
 }
 
--- contacts/seasideperson.h
+++ contacts/seasideperson.h
@@ -88,6 +88,12 @@
     QStringList emailAddresses() const;
     void setEmailAddresses(const QStringList &emailAddresses);
 
+    Q_PROPERTY(QStringList accountUris READ accountUris NOTIFY 
accountUrisChanged)
+    QStringList accountUris() const;
+
+    Q_PROPERTY(QStringList accountPaths READ accountPaths NOTIFY 
accountPathsChanged)
+    QStringList accountPaths() const;
+
     QContact contact() const;
     void setContact(const QContact &contact);
 
@@ -104,6 +110,8 @@
     void birthdayChanged();
     void phoneNumbersChanged();
     void emailAddressesChanged();
+    void accountUrisChanged();
+    void accountPathsChanged();
 
 private:
     // TODO: private class
@@ -112,44 +120,8 @@
     QString mDisplayLabel;
 
     friend class SeasidePeopleModelPriv;
-    /*
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    void Changed();
-    */
 };
 
 Q_DECLARE_METATYPE(SeasidePerson *);
 
-// uuid, presence, self contact
-
-/*
-        BirthdayRole,
-        OnlineAccountUriRole,
-        OnlineServiceProviderRole,
-        EmailAddressRole,
-        EmailContextRole,
-        PhoneNumberRole,
-        PhoneContextRole,
-        AddressRole,
-        AddressStreetRole,
-        AddressLocaleRole,
-        AddressRegionRole,
-        AddressCountryRole,
-        AddressPostcodeRole,
-        AddressContextRole,
-        WebUrlRole,
-        WebContextRole,
-        NotesRole,
-        FirstCharacterRole,
-        DisplayLabelRole
-*/
-
 #endif // SEASIDEPERSON_H
--- contacts/seasideproxymodel.cpp
+++ contacts/seasideproxymodel.cpp
@@ -20,6 +20,7 @@
 public:
     SeasideProxyModel::FilterType filterType;
     LocaleUtils *localeHelper;
+    QString searchPattern;
 };
 
 SeasideProxyModel::SeasideProxyModel(QObject *parent)
@@ -46,6 +47,13 @@
     invalidateFilter();
 }
 
+void SeasideProxyModel::search(const QString &pattern)
+{
+    priv->searchPattern = pattern;
+    invalidateFilter();
+}
+
+
 int SeasideProxyModel::getSourceRow(int row) const
 {
     return mapToSource(index(row, 0)).row();
@@ -65,6 +73,41 @@
     if (person->id() == model->manager()->selfContactId())
         return false;
 
+    if (!priv->searchPattern.isEmpty()) {
+        // split the display label and filter into words. search forwards
+        // over the display label components for each filter word, making
+        // sure to find all filter words before considering it a match.
+        //
+        // TODO: i18n will require different splitting for thai and possibly
+        // other locales, see MBreakIterator
+        //
+        // TODO: for performance, we may want to consider keeping a cached
+        // version of the parts comprising a display label -
+        // QStringList SeasidePerson::displayLabelParts?
+        QStringList labelList = person->displayLabel().split(" ");
+        QStringList filterList = priv->searchPattern.split(" ");
+        int j = 0;
+        for (int i = 0; i < filterList.size(); i++) {
+            bool found = false;
+            for (; j < labelList.size(); j++) {
+                // TODO: for good i18n, we need to search insensitively taking
+                // diacritics into account, QString's functions alone aren't 
good
+                // enough
+                if (labelList.at(j).startsWith(filterList.at(i), 
Qt::CaseInsensitive)) {
+                    found = true;
+                    j++;
+                    break;
+                }
+            }
+
+            // if the current filter word wasn't found in the search
+            // string, then it wasn't a match. we require all words
+            // to match.
+            if (!found)
+                return false;
+        }
+    }
+
     if (priv->filterType == FilterAll) {
         // TODO: this should not be here
         qDebug("fastscroll: emitting countChanged");
--- contacts/seasideproxymodel.h
+++ contacts/seasideproxymodel.h
@@ -34,6 +34,9 @@
     };
 
     Q_INVOKABLE virtual void setFilter(FilterType filter);
+
+    Q_INVOKABLE virtual void search(const QString &pattern);
+
     Q_INVOKABLE int getSourceRow(int row) const;
 
     // for fastscroll support
--- thumbnailer/nemothumbnailprovider.cpp
+++ thumbnailer/nemothumbnailprovider.cpp
@@ -54,19 +54,38 @@
     return QDesktopServices::storageLocation(QDesktopServices::CacheLocation) 
+ ".nemothumbs";
 }
 
+static inline QString rawCachePath()
+{
+    return cachePath() + QDir::separator() + "raw";
+}
+
 static void setupCache()
 {
     // the syscalls make baby jesus cry; but this protects us against sins 
like users
     QDir d(cachePath());
     if (!d.exists())
         d.mkpath(cachePath());
-    if (!d.exists("raw"))
-        d.mkdir("raw");
+    d.mkdir("raw");
 
     // in the future, we might store a nicer UI version which can blend in 
with our UI better, but
     // we'll always want the raw version.
 }
 
+static QString cacheFileName(const QByteArray &hashKey, bool makePath = false)
+{
+    QString subfolder = QString(hashKey.left(2));
+    if (makePath) {
+        QDir d(rawCachePath());
+        d.mkdir(subfolder);
+    }
+
+    return rawCachePath() +
+           QDir::separator() +
+           subfolder +
+           QDir::separator() +
+           hashKey;
+}
+
 static QByteArray cacheKey(const QString &id, const QSize &requestedSize)
 {
     QByteArray baId = id.toLatin1(); // is there a more efficient way than a 
copy?
@@ -82,7 +101,7 @@
 
 static QImage attemptCachedServe(const QString &id, const QByteArray &hashKey)
 {
-    QFile fi(cachePath() + QDir::separator() + "raw" + QDir::separator() + 
hashKey);
+    QFile fi(cacheFileName(hashKey));
     QFileInfo info(fi);
     if (info.exists() && info.lastModified() >= QFileInfo(id).lastModified()) {
         if (fi.open(QIODevice::ReadOnly)) {
@@ -98,7 +117,7 @@
 
 static void writeCacheFile(const QByteArray &hashKey, const QImage &img)
 {
-    QFile fi(cachePath() + QDir::separator() + "raw" + QDir::separator() + 
hashKey);
+    QFile fi(cacheFileName(hashKey, true));
     if (!fi.open(QIODevice::WriteOnly)) {
         qWarning() << "Couldn't cache to " << fi.fileName();
         return;

++++++ nemo-qml-plugins.yaml
--- nemo-qml-plugins.yaml
+++ nemo-qml-plugins.yaml
@@ -2,7 +2,7 @@
 Summary: Nemo QML plugins source package.
 Group: System/Libraries
 Description: Do not install this, install the subpackaged plugins.
-Version: 0.0.6
+Version: 0.0.7
 Release: 1
 Sources:
     - "%{name}-%{version}.tar.bz2"



Reply via email to