void ExamplePluginInfo::query()
{
    TransferMethodInfo info;
    QStringList capabilities;

    // Capabilites ie. what mimetypes this plugin supports
    capabilities << QLatin1String("image/*")
                 << QLatin1String("text/vcard");

    // TODO: Translations for 3rd party plugins is not yet supported by Sailfish OS.
    //       Adding support there later, but for now just use what ever non-translated
    //       string here. This string will be visible in the share method list.
    info.displayName     = "Example Display Name";

    // Method ID is a unique identifier for this plugin. It is used to identify which share plugin should be
    // used for starting the sharing.
    info.methodId        = QLatin1String("Example-Share-Method-ID");

    // Path to the Sharing UI which this plugin provides.
    info.shareUIPath     = QLatin1String("/usr/share/nemo-transferengine/plugins/ExampleShareUI.qml");

    // Pass information about capabilities. This info is used for filtering share plugins
    // which don't support defined types. For example, this plugin won't appear in the
    // share method list, if someone tries to share content which isn't image or vcard type,
    info.capabilitities  = capabilities;

    m_infoList << info;

    // Let the world know that this plugin is ready
    m_ready = true;
    emit infoReady();
}
void WhatsappPluginInfo::query()
{
    TransferMethodInfo info;

    QStringList capabilities;
    capabilities << QLatin1String("*");

    info.displayName     = QLatin1String("Mitakuuluu");
    info.userName        = QLatin1String("");
    info.accountId       = 0;
    info.methodId        = QLatin1String("whatsapp-share-ui-plugin");
    info.shareUIPath     = QLatin1String("/usr/share/harbour-mitakuuluu/qml/ShareUI.qml");
    info.capabilitities  = capabilities;
    infoList.clear();
    infoList << info;

    Q_EMIT infoReady();
}
void TableConstraintsLoader::consColNamesRecordFetched(const FetchResult &result)
{
    if(result.hasError){
        emit loadError(result.taskName, result.exception);
        return;
    }

    int rowId=result.taskName.mid(result.taskName.lastIndexOf('_')+1).toInt();
    Q_ASSERT(rowId>0 && rowId<=constraints.size());

    QString rColumns=result.oneRow.at(0);
    constraints[rowId-1].rColumns=rColumns;

    fkSubqueryCount--;
    Q_ASSERT(fkSubqueryCount>=0);
    if(fkSubqueryCount==0){
        emit infoReady(constraints, this->checkConstraints);
    }
}
void TablespaceQuotaInfoLoader::fetchCompleted(const QString &)
{
    emit infoReady(quotas);
}
void TableConstraintsLoader::fetchCompleted(const QString &/*taskName*/)
{
    if(fkSubqueryCount==0){
        emit infoReady(constraints, this->checkConstraints);
    }
}
void TableExternalInfoLoader::locationsFetchCompleted(const QString &)
{
    emit infoReady(info);
}
void TransferEnginePrivate::enabledPluginsCheck()
{
    Q_Q(TransferEngine);
    if (m_fileWatcherTimer->isActive()) {
        m_fileWatcherTimer->stop();
    }

    if (m_infoObjects.count() > 0) {
        qWarning() << Q_FUNC_INFO << "Already quering account info" << m_infoObjects.count();
        return;
    }

    // First clear old data
    m_enabledPlugins.clear();
    qDeleteAll(m_infoObjects);
    m_infoObjects.clear();

    QPluginLoader loader;
    loader.setLoadHints(QLibrary::ResolveAllSymbolsHint | QLibrary::ExportExternalSymbolsHint);

    // Handle the case if all the plugins have been removed.
    QStringList plugins = pluginList();
    if (plugins.isEmpty()) {
        emit q->transferMethodListChanged();
        return;
    }

    // We have plugins
    Q_FOREACH(QString plugin, plugins) {
        loader.setFileName(plugin);
        TransferPluginInterface *interface =
                qobject_cast<TransferPluginInterface*>(loader.instance());

        if (interface && interface->enabled()) {

            TransferPluginInfo *info = interface->infoObject();
            if (!info) {
                qWarning() << Q_FUNC_INFO << "NULL Info object!";
                continue;
            }

            if (info->ready()) {
                if (info->info().count() > 0) {
                    m_enabledPlugins << info->info();
                } else {
                    // Plugin has nothing to provide, just ignore it
                    delete info;
                }
            } else {
                // These object will be cleaned in pluginInfoReady() slot.
                m_infoObjects << info;
                connect(info, SIGNAL(infoReady()), this, SLOT(pluginInfoReady()));
                connect(info, SIGNAL(infoError(QString)), this, SLOT(pluginInfoError(QString)));
                info->query();
            }
        }

        if (!interface) {
            qWarning() << Q_FUNC_INFO << loader.errorString();
        }
    }