qtmobility/src/contacts/qcontactmanagerengine.cpp
changeset 15 1f895d8a5b2b
parent 14 6fbed849b4f4
--- a/qtmobility/src/contacts/qcontactmanagerengine.cpp	Wed Jun 23 19:08:38 2010 +0300
+++ b/qtmobility/src/contacts/qcontactmanagerengine.cpp	Tue Jul 06 15:12:50 2010 +0300
@@ -46,6 +46,8 @@
 #include "qcontactdetails.h"
 #include "qcontactsortorder.h"
 #include "qcontactfilters.h"
+#include "qcontactaction.h"
+#include "qcontactactiondescriptor.h"
 #include "qcontactabstractrequest.h"
 #include "qcontactabstractrequest_p.h"
 #include "qcontactrequests.h"
@@ -230,7 +232,7 @@
   Any operation error which occurs will be saved in \a error.
 
   The \a fetchHint parameter describes the optimization hints that a manager may take.
-  If the \a fetchHint is the default constructed hint, all existing details and relationships
+  If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences
   in the matching contacts will be returned.  A client should not make changes to a contact which has
   been retrieved using a fetch hint other than the default fetch hint.  Doing so will result in information
   loss when saving the contact back to the manager (as the "new" restricted contact will
@@ -256,7 +258,7 @@
   Any operation error which occurs will be saved in \a error.
 
   The \a fetchHint parameter describes the optimization hints that a manager may take.
-  If the \a fetchHint is the default constructed hint, all existing details and relationships
+  If the \a fetchHint is the default constructed hint, all existing details, relationships and action preferences
   in the matching contact will be returned.  A client should not make changes to a contact which has
   been retrieved using a fetch hint other than the default fetch hint.  Doing so will result in information
   loss when saving the contact back to the manager (as the "new" restricted contact will
@@ -490,8 +492,6 @@
 
 /*!
   Sets the contact display label of \a contact to the supplied \a displayLabel.
-
-  This function does not touch the database in any way, and is purely a convenience to allow engine implementations to set the display label.
  */
 void QContactManagerEngine::setContactDisplayLabel(QContact* contact, const QString& displayLabel)
 {
@@ -501,6 +501,22 @@
     contact->d->m_details.replace(0, dl);
 }
 
+/*!  
+  \deprecated
+
+  Returns a copy of \a contact with the contact display label set to the supplied \a displayLabel.
+
+  This function does not touch the database in any way, and is purely a convenience to allow engine implementations to set the display label.
+
+  This function has been deprecated - use the function with the same name that accepts different parameters.
+*/
+QContact QContactManagerEngine::setContactDisplayLabel(const QString& displayLabel, const QContact& contact)
+{
+    QContact newContact = contact;
+    setContactDisplayLabel(&newContact, displayLabel);
+    return newContact;
+}
+
 /*!
   Returns true if the given \a feature is supported by this engine for contacts of the given \a contactType
  */
@@ -517,6 +533,8 @@
 
   Some of the following transformations may be applied:
   \list
+   \o Any QContactActionFilters are transformed into the corresponding
+     QContactFilters returned by matching actions
    \o Any QContactInvalidFilters contained in a union filter will be removed
    \o Any default QContactFilters contained in an intersection filter will be removed
    \o Any QContactIntersectionFilters with a QContactInvalidFilter contained will be
@@ -534,6 +552,40 @@
 QContactFilter QContactManagerEngine::canonicalizedFilter(const QContactFilter &filter)
 {
     switch(filter.type()) {
+        case QContactFilter::ActionFilter:
+        {
+            // Find any matching actions, and do a union filter on their filter objects
+            QContactActionFilter af(filter);
+            QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion());
+
+            QList<QContactFilter> filters;
+            // There's a small wrinkle if there's a value specified in the action filter
+            // we have to adjust any contained QContactDetailFilters to have that value
+            // or test if a QContactDetailRangeFilter contains this value already
+            for (int j = 0; j < descriptors.count(); j++) {
+                QContactAction* action = QContactAction::action(descriptors.at(j));
+
+                // Action filters are not allowed to return action filters, at all
+                // it's too annoying to check for recursion
+                QContactFilter d = action->contactFilter(af.value());
+                delete action; // clean up.
+                if (!validateActionFilter(d))
+                    continue;
+
+                filters.append(d);
+            }
+
+            if (filters.count() == 0)
+                return QContactInvalidFilter();
+            if (filters.count() == 1)
+                return filters.first();
+
+            QContactUnionFilter f;
+            f.setFilters(filters);
+            return canonicalizedFilter(f);
+        }
+        // unreachable
+
         case QContactFilter::IntersectionFilter:
         {
             QContactIntersectionFilter f(filter);
@@ -1685,7 +1737,6 @@
 {
     switch(filter.type()) {
         case QContactFilter::InvalidFilter:
-        case QContactFilter::ActionFilter:
             return false;
 
         case QContactFilter::DefaultFilter:
@@ -2005,6 +2056,33 @@
             }
             break;
 
+        case QContactFilter::ActionFilter:
+            {
+                // Find any matching actions, and do a union filter on their filter objects
+                QContactActionFilter af(filter);
+                QList<QContactActionDescriptor> descriptors = QContactAction::actionDescriptors(af.actionName(), af.vendorName(), af.implementationVersion());
+
+                // There's a small wrinkle if there's a value specified in the action filter
+                // we have to adjust any contained QContactDetailFilters to have that value
+                // or test if a QContactDetailRangeFilter contains this value already
+                for (int j = 0; j < descriptors.count(); j++) {
+                    QContactAction* action = QContactAction::action(descriptors.at(j));
+
+                    // Action filters are not allowed to return action filters, at all
+                    // it's too annoying to check for recursion
+                    QContactFilter d = action->contactFilter(af.value());
+                    delete action; // clean up.
+                    if (!validateActionFilter(d))
+                        return false;
+
+                    // Check for values etc...
+                    if (testFilter(d, contact))
+                        return true;
+                }
+                // Fall through to end
+            }
+            break;
+
         case QContactFilter::IntersectionFilter:
             {
                 /* XXX In theory we could reorder the terms to put the native tests first */
@@ -2043,6 +2121,34 @@
 }
 
 /*!
+  Given a QContactFilter \a filter retrieved from a QContactAction,
+  check that it is valid and cannot cause infinite recursion.
+
+  In particular, a filter from a QContactAction cannot contain
+  any instances of a QContactActionFilter.
+
+  Returns true if \a filter seems ok, or false otherwise.
+ */
+
+bool QContactManagerEngine::validateActionFilter(const QContactFilter& filter)
+{
+    QList<QContactFilter> toVerify;
+    toVerify << filter;
+
+    while(toVerify.count() > 0) {
+        QContactFilter f = toVerify.takeFirst();
+        if (f.type() == QContactFilter::ActionFilter)
+            return false;
+        if (f.type() == QContactFilter::IntersectionFilter)
+            toVerify.append(QContactIntersectionFilter(f).filters());
+        if (f.type() == QContactFilter::UnionFilter)
+            toVerify.append(QContactUnionFilter(f).filters());
+    }
+
+    return true;
+}
+
+/*!
   Sets the cached relationships in the given \a contact to \a relationships
  */
 void QContactManagerEngine::setContactRelationships(QContact* contact, const QList<QContactRelationship>& relationships)