QContactActionDescriptor MobBaseAction::actionDescriptor() const
{
    QContactActionDescriptor ret;
    ret.setActionName(m_actionName);
    ret.setVendorName(m_vendorName);
    ret.setImplementationVersion(m_implementationVersion);
    return ret;
}
//returns whether the actionDescription is supported by this action
bool MobBaseAction::actionDescriptionSupported(const QContactActionDescriptor& descriptor) const
{
    bool supported(false);
    
    if ((descriptor.actionName() == m_actionName) && (descriptor.vendorName() == m_vendorName) && (descriptor.implementationVersion() == m_implementationVersion))
        supported = true;
    else
        supported = false; 
    
    return supported;       
}
/*! Returns the hash value for \a key. */
uint qHash(const QContactActionDescriptor& key)
{
    uint ret = 0;

    ret += QT_PREPEND_NAMESPACE(qHash)(key.serviceName())
            + QT_PREPEND_NAMESPACE(qHash)(key.actionName())
            + QT_PREPEND_NAMESPACE(qHash)(key.d->m_identifier)
            + QT_PREPEND_NAMESPACE(qHash)(key.implementationVersion())
            + QT_PREPEND_NAMESPACE(qHash)(key.d->m_factory);

    return ret;
}
/*!
  Returns a list of identifiers of the available actions which are provided by the service provider with the given \a serviceName.
  If \a serviceName is empty, actions from all service providers and of any implementation version are returned.
 */
QStringList QContactAction::availableActions(const QString& serviceName)
{
    // SLOW naive implementation...
    QSet<QString> ret;
    QList<QContactActionDescriptor> actionDescriptors = QContactActionManager::instance()->actionDescriptors();
    for (int i = 0; i < actionDescriptors.size(); i++) {
        QContactActionDescriptor descriptor = actionDescriptors.at(i);
        if (serviceName.isEmpty() || serviceName == descriptor.serviceName()) {
            ret.insert(descriptor.actionName());
        }
    }

    return ret.toList();
}
void tst_QContactActions::testDescriptor()
{
    // first, test retrieving an invalid action
    QContactAction* invalidAction = QContactAction::action(QContactActionDescriptor());
    QVERIFY(invalidAction == 0); // should be null.

    QContact c;
    QContactEmailAddress e;
    e.setEmailAddress("*****@*****.**");
    c.saveDetail(&e);
    QContactPhoneNumber p;
    p.setNumber("12345");
    c.saveDetail(&p);

    QVERIFY(QContactAction::availableActions().contains("SendEmail"));
    QVERIFY(QContactAction::availableActions("tst_qcontactactions:sendemailaction").contains("SendEmail"));

    QContactActionDescriptor sendEmailDescriptor;
    QContactActionDescriptor multiActionOneDescriptor;
    QContactActionDescriptor multiActionTwoDescriptor;

    QList<QContactActionDescriptor> descrs = QContactAction::actionDescriptors();
    QContactAction* sendEmailAction = 0;
    for (int i = 0; i < descrs.size(); i++) {
        QContactActionDescriptor temp = descrs.at(i);
        if (temp.actionName() == QString("SendEmail")) {
            sendEmailAction = QContactAction::action(temp);
            QVERIFY(c.availableActions().contains(temp)); // has an email address, so should be available
            QVERIFY(temp.supportsContact(c));
            sendEmailDescriptor = temp;
        } else if (temp.actionName() == QString("call")) {
            if (temp.metaData(QString(QLatin1String("Provider"))) == QString(QLatin1String("sip"))) {
                multiActionOneDescriptor = temp;
            } else {
                multiActionTwoDescriptor = temp;
            }
        }
    }

    QVERIFY(sendEmailDescriptor.isValid());
    QVERIFY(multiActionOneDescriptor.isValid());
    QVERIFY(multiActionTwoDescriptor.isValid());

    QVERIFY(sendEmailAction != 0);
    delete sendEmailAction;

    // now test equivalence.  The send email action descriptor should
    // have a different action name to both multi action one and two.
    QVERIFY(sendEmailDescriptor.actionName() != multiActionOneDescriptor.actionName());
    QVERIFY(sendEmailDescriptor.actionName() != multiActionTwoDescriptor.actionName());
    QVERIFY(sendEmailDescriptor != multiActionOneDescriptor);
    QVERIFY(sendEmailDescriptor != multiActionTwoDescriptor);

    // multi action one and two should have the same action name, service
    // name and implementation (minor) version.  BUT they have different
    // implementations (Provider is different) so they should NOT be equal.
    QVERIFY(multiActionOneDescriptor.actionName() == multiActionTwoDescriptor.actionName());
    QVERIFY(multiActionOneDescriptor.serviceName() == multiActionTwoDescriptor.serviceName());
    QVERIFY(multiActionOneDescriptor.implementationVersion() == multiActionTwoDescriptor.implementationVersion());
    QVERIFY(multiActionOneDescriptor != multiActionTwoDescriptor);

    // verify that the meta data is reported correctly
    QVERIFY(multiActionOneDescriptor.metaData("Provider") != multiActionTwoDescriptor.metaData("Provider"));
}
void tst_QContactActions::contactFunctions()
{
    QContact c;  // empty contact.
    QContact c2; // contact with email saved.
    QContact c3; // two emails
    QContact c4; // two emails, plus a preference
    QContact c5; // two emails, plus a preference for an unsupported detail
    QContactEmailAddress e2;
    QContactEmailAddress e;
    e.setEmailAddress("*****@*****.**");
    c2.saveDetail(&e);
    e2.setEmailAddress("*****@*****.**");

    c3.saveDetail(&e);
    c3.saveDetail(&e2);
    c4.saveDetail(&e);
    c4.saveDetail(&e2);
    c5.saveDetail(&e2); // reverse order for c5
    c5.saveDetail(&e);

    c4.setPreferredDetail("SendEmail", e2);
    c5.setPreferredDetail("SendEmail", c5.detail<QContactDisplayLabel>());

    // Get our descriptor
    QContactActionDescriptor descriptor = QContactAction::actionDescriptors("SendEmail").value(0);
    QVERIFY(descriptor.actionName() == "SendEmail");

    // available actions:
    // empty contact
    QList<QContactActionDescriptor> availableActions = c.availableActions(QString());
    QVERIFY(availableActions.isEmpty());  // should not contain SendEmail
    // contact with email
    availableActions = c2.availableActions(QString());
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));

    // try various combinations of version and name
    availableActions = c2.availableActions();
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));
    availableActions = c2.availableActions("tst_qcontactactions:sendemailaction");
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    availableActions = c2.availableActions(QString());
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));

    // Again with c3
    availableActions = c3.availableActions(QString());
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));

    // try various combinations of version and name
    availableActions = c3.availableActions();
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));
    availableActions = c3.availableActions("tst_qcontactactions:sendemailaction");
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));
    availableActions = c3.availableActions(QString());
    QVERIFY(!availableActions.isEmpty()); // should contain SendEmail
    QVERIFY(availableActions.contains(descriptor));
}