/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Designer of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "pluginmanager_p.h"
#include "qdesigner_utils_p.h"
#include "qdesigner_qsettings_p.h"

#include <QtDesigner/QDesignerFormEditorInterface>
#include <QtDesigner/QDesignerCustomWidgetInterface>
#include <QtDesigner/QExtensionManager>
#include <QtDesigner/QDesignerLanguageExtension>

#include <QtCore/QDir>
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QSet>
#include <QtCore/QPluginLoader>
#include <QtCore/QLibrary>
#include <QtCore/QLibraryInfo>
#include <QtCore/qdebug.h>
#include <QtCore/QMap>
#include <QtCore/QSettings>
#include <QtCore/QCoreApplication>

#include <QtCore/QXmlStreamReader>
#include <QtCore/QXmlStreamAttributes>
#include <QtCore/QXmlStreamAttribute>

static const char *uiElementC = "ui";
static const char *languageAttributeC = "language";
static const char *widgetElementC = "widget";
static const char *displayNameAttributeC = "displayname";
static const char *classAttributeC = "class";
static const char *customwidgetElementC = "customwidget";
static const char *extendsElementC = "extends";
static const char *addPageMethodC = "addpagemethod";
static const char *propertySpecsC = "propertyspecifications";
static const char *stringPropertySpecC = "stringpropertyspecification";
static const char *stringPropertyNameAttrC = "name";
static const char *stringPropertyTypeAttrC = "type";
static const char *stringPropertyNoTrAttrC = "notr";
static const char *jambiLanguageC = "jambi";

enum { debugPluginManager = 0 };

/* Custom widgets: Loading custom widgets is a 2-step process: PluginManager
 * scans for its plugins in the constructor. At this point, it might not be safe
 * to immediately initialize the custom widgets it finds, because the rest of
 * Designer is not initialized yet.
 * Later on, in ensureInitialized(), the plugin instances (including static ones)
 * are iterated and the custom widget plugins are initialized and added to internal
 * list of custom widgets and parsed data. Should there be a parse error or a language
 * mismatch, it kicks out the respective custom widget. The m_initialized flag
 * is used to indicate the state.
 * Later, someone might call registerNewPlugins(), which agains clears the flag via
 * registerPlugin() and triggers the process again.
 * Also note that Jambi fakes a custom widget collection that changes its contents
 * every time the project is switched. So, custom widget plugins can actually
 * disappear, and the custom widget list must be cleared and refilled in
 * ensureInitialized() after registerNewPlugins. */

QT_BEGIN_NAMESPACE

static QStringList unique(const QStringList &lst)
{
    const QSet<QString> s = QSet<QString>::fromList(lst);
    return s.toList();
}

QStringList QDesignerPluginManager::defaultPluginPaths()
{
    QStringList result;

    const QStringList path_list = QCoreApplication::libraryPaths();

    const QString designer = QLatin1String("designer");
    foreach (const QString &path, path_list) {
        QString libPath = path;
        libPath += QDir::separator();
        libPath += designer;
        result.append(libPath);
    }

    QString homeLibPath = QDir::homePath();
    homeLibPath += QDir::separator();
    homeLibPath += QLatin1String(".designer");
    homeLibPath += QDir::separator();
    homeLibPath += QLatin1String("plugins");

    result.append(homeLibPath);
    return result;
}

// Figure out the language designer is running. ToDo: Introduce some
// Language name API to QDesignerLanguageExtension?

static inline QString getDesignerLanguage(QDesignerFormEditorInterface *core)
{
    if (QDesignerLanguageExtension *lang = qt_extension<QDesignerLanguageExtension *>(core->extensionManager(), core)) {
        if (lang->uiExtension() == QLatin1String("jui"))
            return QLatin1String(jambiLanguageC);
        return QLatin1String("unknown");
    }
    return QLatin1String("c++");
}

// ----------------  QDesignerCustomWidgetSharedData

class QDesignerCustomWidgetSharedData : public QSharedData {
public:
    // Type of a string property
    typedef QPair<qdesigner_internal::TextPropertyValidationMode, bool> StringPropertyType;
    typedef QHash<QString, StringPropertyType> StringPropertyTypeMap;

    explicit QDesignerCustomWidgetSharedData(const QString &thePluginPath) : pluginPath(thePluginPath) {}
    void clearXML();

    QString pluginPath;

    QString xmlClassName;
    QString xmlDisplayName;
    QString xmlLanguage;
    QString xmlAddPageMethod;
    QString xmlExtends;

    StringPropertyTypeMap xmlStringPropertyTypeMap;
};

void QDesignerCustomWidgetSharedData::clearXML()
{
    xmlClassName.clear();
    xmlDisplayName.clear();
    xmlLanguage.clear();
    xmlAddPageMethod.clear();
    xmlExtends.clear();
    xmlStringPropertyTypeMap.clear();
}

// ----------------  QDesignerCustomWidgetData

QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QString &pluginPath) :
    m_d(new QDesignerCustomWidgetSharedData(pluginPath))
{
}

QDesignerCustomWidgetData::QDesignerCustomWidgetData(const QDesignerCustomWidgetData &o) :
     m_d(o.m_d)
{
}

QDesignerCustomWidgetData& QDesignerCustomWidgetData::operator=(const QDesignerCustomWidgetData &o)
{
    m_d.operator=(o.m_d);
    return *this;
}

QDesignerCustomWidgetData::~QDesignerCustomWidgetData()
{
}

bool QDesignerCustomWidgetData::isNull() const
{
    return m_d->xmlClassName.isEmpty() || m_d->pluginPath.isEmpty();
}

QString QDesignerCustomWidgetData::xmlClassName() const
{
    return m_d->xmlClassName;
}

QString QDesignerCustomWidgetData::xmlLanguage() const
{
    return m_d->xmlLanguage;
}

QString QDesignerCustomWidgetData::xmlAddPageMethod() const
{
    return m_d->xmlAddPageMethod;
}

QString QDesignerCustomWidgetData::xmlExtends() const
{
    return m_d->xmlExtends;
}

QString QDesignerCustomWidgetData::xmlDisplayName() const
{
    return m_d->xmlDisplayName;
}

QString QDesignerCustomWidgetData::pluginPath() const
{
    return m_d->pluginPath;
}

bool QDesignerCustomWidgetData::xmlStringPropertyType(const QString &name, StringPropertyType *type) const
{
    QDesignerCustomWidgetSharedData::StringPropertyTypeMap::const_iterator it = m_d->xmlStringPropertyTypeMap.constFind(name);
    if (it == m_d->xmlStringPropertyTypeMap.constEnd()) {
        *type = StringPropertyType(qdesigner_internal::ValidationRichText, true);
        return false;
    }
    *type = it.value();
    return true;
}

// Wind a QXmlStreamReader  until it finds an element. Returns index or one of FindResult
enum FindResult { FindError = -2, ElementNotFound = -1 };

static int findElement(const QStringList &desiredElts, QXmlStreamReader &sr)
{
    while (true) {
        switch(sr.readNext()) {
        case QXmlStreamReader::EndDocument:
            return ElementNotFound;
        case QXmlStreamReader::Invalid:
            return FindError;
        case QXmlStreamReader::StartElement: {
            const int index = desiredElts.indexOf(sr.name().toString().toLower());
            if (index >= 0)
                return index;
        }
            break;
        default:
            break;
        }
    }
    return FindError;
}

static inline QString msgXmlError(const QString &name, const QString &errorMessage)
{
    return QDesignerPluginManager::tr("An XML error was encountered when parsing the XML of the custom widget %1: %2").arg(name, errorMessage);
}

static inline QString msgAttributeMissing(const QString &name)
{
    return QDesignerPluginManager::tr("A required attribute ('%1') is missing.").arg(name);
}

static qdesigner_internal::TextPropertyValidationMode typeStringToType(const QString &v, bool *ok)
{
    *ok = true;
    if (v  == QLatin1String("multiline"))
        return qdesigner_internal::ValidationMultiLine;
    if (v  == QLatin1String("richtext"))
        return qdesigner_internal::ValidationRichText;
    if (v  == QLatin1String("stylesheet"))
        return qdesigner_internal::ValidationStyleSheet;
    if (v  == QLatin1String("singleline"))
        return qdesigner_internal::ValidationSingleLine;
    if (v  == QLatin1String("objectname"))
        return qdesigner_internal::ValidationObjectName;
    if (v  == QLatin1String("objectnamescope"))
        return qdesigner_internal::ValidationObjectNameScope;
    if (v  == QLatin1String("url"))
        return qdesigner_internal::ValidationURL;
    *ok = false;
    return qdesigner_internal::ValidationRichText;
}

static  bool parsePropertySpecs(QXmlStreamReader &sr,
                                   QDesignerCustomWidgetSharedData::StringPropertyTypeMap *rc,
                                   QString *errorMessage)
{
    const QString propertySpecs = QLatin1String(propertySpecsC);
    const QString stringPropertySpec = QLatin1String(stringPropertySpecC);
    const QString stringPropertyTypeAttr = QLatin1String(stringPropertyTypeAttrC);
    const QString stringPropertyNoTrAttr = QLatin1String(stringPropertyNoTrAttrC);
    const QString stringPropertyNameAttr = QLatin1String(stringPropertyNameAttrC);

    while (!sr.atEnd()) {
        switch(sr.readNext()) {
        case QXmlStreamReader::StartElement: {
            if (sr.name() != stringPropertySpec) {
                *errorMessage = QDesignerPluginManager::tr("An invalid property specification ('%1') was encountered. Supported types: %2").arg(sr.name().toString(), stringPropertySpec);
                return false;
            }
            const QXmlStreamAttributes atts = sr.attributes();
            const QString name = atts.value(stringPropertyNameAttr).toString();
            const QString type = atts.value(stringPropertyTypeAttr).toString();
            const QString notrS = atts.value(stringPropertyNoTrAttr).toString(); //Optional

            if (type.isEmpty()) {
                *errorMessage = msgAttributeMissing(stringPropertyTypeAttr);
                return false;
            }
            if (name.isEmpty()) {
                *errorMessage = msgAttributeMissing(stringPropertyNameAttr);
                return false;
            }
            bool typeOk;
            const bool noTr = notrS == QLatin1String("true") || notrS == QLatin1String("1");
            QDesignerCustomWidgetSharedData::StringPropertyType v(typeStringToType(type, &typeOk), !noTr);
            if (!typeOk) {
                *errorMessage = QDesignerPluginManager::tr("'%1' is not a valid string property specification.").arg(type);
                return false;
            }
            rc->insert(name, v);
        }
            break;
        case QXmlStreamReader::EndElement: // Outer </stringproperties>
            if (sr.name() == propertySpecs)
                return true;
        default:
            break;
        }
    }
    return true;
}

QDesignerCustomWidgetData::ParseResult
                       QDesignerCustomWidgetData::parseXml(const QString &xml, const QString &name, QString *errorMessage)
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO << name;

    QDesignerCustomWidgetSharedData &data =  *m_d;
    data.clearXML();

    QXmlStreamReader sr(xml);

    bool foundUI = false;
    bool foundWidget = false;
    ParseResult rc = ParseOk;
    // Parse for the (optional) <ui> or the first <widget> element
    QStringList elements;
    elements.push_back(QLatin1String(uiElementC));
    elements.push_back(QLatin1String(widgetElementC));
    for (int i = 0; i < 2 && !foundWidget; i++) {
        switch (findElement(elements, sr)) {
        case FindError:
            *errorMessage = msgXmlError(name, sr.errorString());
            return ParseError;
        case ElementNotFound:
            *errorMessage = QDesignerPluginManager::tr("The XML of the custom widget %1 does not contain any of the elements <widget> or <ui>.").arg(name);
            return ParseError;
        case 0: { // <ui>
            const QXmlStreamAttributes attributes = sr.attributes();
            data.xmlLanguage = attributes.value(QLatin1String(languageAttributeC)).toString();
            data.xmlDisplayName = attributes.value(QLatin1String(displayNameAttributeC)).toString();
            foundUI = true;
        }
            break;
        case 1: // <widget>: Do some sanity checks
            data.xmlClassName = sr.attributes().value(QLatin1String(classAttributeC)).toString();
            if (data.xmlClassName.isEmpty()) {
                *errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 is missing.").arg(name);
                rc = ParseWarning;
            } else {
                if (data.xmlClassName != name) {
                    *errorMessage = QDesignerPluginManager::tr("The class attribute for the class %1 does not match the class name %2.").arg(data.xmlClassName, name);
                    rc = ParseWarning;
                }
            }
            foundWidget = true;
            break;
        }
    }
    // Parse out the <customwidget> element which might be present if  <ui> was there
    if (!foundUI)
        return rc;
    elements.clear();
    elements.push_back(QLatin1String(customwidgetElementC));
    switch (findElement(elements, sr)) {
    case FindError:
        *errorMessage = msgXmlError(name, sr.errorString());
        return ParseError;
    case ElementNotFound:
        return rc;
    default:
        break;
    }
    // Find <extends>, <addPageMethod>, <stringproperties>
    elements.clear();
    elements.push_back(QLatin1String(extendsElementC));
    elements.push_back(QLatin1String(addPageMethodC));
    elements.push_back(QLatin1String(propertySpecsC));
    while (true) {
        switch (findElement(elements, sr)) {
        case FindError:
            *errorMessage = msgXmlError(name, sr.errorString());
            return ParseError;
        case ElementNotFound:
            return rc;
        case 0: // <extends>
            data.xmlExtends = sr.readElementText();
            if (sr.tokenType() != QXmlStreamReader::EndElement) {
                *errorMessage = msgXmlError(name, sr.errorString());
                return ParseError;
            }
            break;
        case 1: // <addPageMethod>
            data.xmlAddPageMethod = sr.readElementText();
            if (sr.tokenType() != QXmlStreamReader::EndElement) {
                *errorMessage = msgXmlError(name, sr.errorString());
                return ParseError;
            }
            break;
        case 2: // <stringproperties>
            if (!parsePropertySpecs(sr, &m_d->xmlStringPropertyTypeMap, errorMessage)) {
                *errorMessage = msgXmlError(name, *errorMessage);
                return ParseError;
            }
            break;
        }
    }
    return rc;
}

// ---------------- QDesignerPluginManagerPrivate

class QDesignerPluginManagerPrivate {
    public:
    typedef QPair<QString, QString> ClassNamePropertyNameKey;

    QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core);

    void clearCustomWidgets();
    bool addCustomWidget(QDesignerCustomWidgetInterface *c,
                         const QString &pluginPath,
                         const QString &designerLanguage);
    void addCustomWidgets(const QObject *o,
                          const QString &pluginPath,
                          const QString &designerLanguage);

    QDesignerFormEditorInterface *m_core;
    QStringList m_pluginPaths;
    QStringList m_registeredPlugins;
    // TODO: QPluginLoader also caches invalid plugins -> This seems to be dead code
    QStringList m_disabledPlugins;

    typedef QMap<QString, QString> FailedPluginMap;
    FailedPluginMap m_failedPlugins;

    // Synced lists of custom widgets and their data. Note that the list
    // must be ordered for collections to appear in order.
    QList<QDesignerCustomWidgetInterface *> m_customWidgets;
    QList<QDesignerCustomWidgetData> m_customWidgetData;

    QStringList defaultPluginPaths() const;

    bool m_initialized;
};

QDesignerPluginManagerPrivate::QDesignerPluginManagerPrivate(QDesignerFormEditorInterface *core) :
   m_core(core),
   m_initialized(false)
{
}

void QDesignerPluginManagerPrivate::clearCustomWidgets()
{
    m_customWidgets.clear();
    m_customWidgetData.clear();
}

// Add a custom widget to the list if it parses correctly
// and is of the right language
bool QDesignerPluginManagerPrivate::addCustomWidget(QDesignerCustomWidgetInterface *c,
                                                    const QString &pluginPath,
                                                    const QString &designerLanguage)
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO << c->name();

    if (!c->isInitialized())
        c->initialize(m_core);
    // Parse the XML even if the plugin is initialized as Jambi might play tricks here
    QDesignerCustomWidgetData data(pluginPath);
    const QString domXml = c->domXml();
    if (!domXml.isEmpty()) { // Legacy: Empty XML means: Do not show up in widget box.
        QString errorMessage;
        const QDesignerCustomWidgetData::ParseResult pr = data.parseXml(domXml, c->name(), &errorMessage);
        switch (pr) {
            case QDesignerCustomWidgetData::ParseOk:
            break;
            case QDesignerCustomWidgetData::ParseWarning:
            qdesigner_internal::designerWarning(errorMessage);
            break;
            case QDesignerCustomWidgetData::ParseError:
            qdesigner_internal::designerWarning(errorMessage);
            return false;
        }
        // Does the language match?
        const QString pluginLanguage = data.xmlLanguage();
        if (!pluginLanguage.isEmpty() && pluginLanguage.compare(designerLanguage, Qt::CaseInsensitive))
            return false;
    }
    m_customWidgets.push_back(c);
    m_customWidgetData.push_back(data);
    return true;
}

// Check the plugin interface for either a custom widget or a collection and
// add all contained custom widgets.
void QDesignerPluginManagerPrivate::addCustomWidgets(const QObject *o,
                                                     const QString &pluginPath,
                                                     const QString &designerLanguage)
{
    if (QDesignerCustomWidgetInterface *c = qobject_cast<QDesignerCustomWidgetInterface*>(o)) {
        addCustomWidget(c, pluginPath, designerLanguage);
        return;
    }
    if (const QDesignerCustomWidgetCollectionInterface *coll = qobject_cast<QDesignerCustomWidgetCollectionInterface*>(o)) {
        foreach(QDesignerCustomWidgetInterface *c, coll->customWidgets())
            addCustomWidget(c, pluginPath, designerLanguage);
    }
}


// ---------------- QDesignerPluginManager
// As of 4.4, the header will be distributed with the Eclipse plugin.

QDesignerPluginManager::QDesignerPluginManager(QDesignerFormEditorInterface *core) :
    QObject(core),
    m_d(new QDesignerPluginManagerPrivate(core))
{
    m_d->m_pluginPaths = defaultPluginPaths();
    const QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
    m_d->m_disabledPlugins = unique(settings.value(QLatin1String("PluginManager/DisabledPlugins")).toStringList());

    // Register plugins
    updateRegisteredPlugins();

    if (debugPluginManager)
        qDebug() << "QDesignerPluginManager::disabled: " <<  m_d->m_disabledPlugins << " static " << m_d->m_customWidgets.size();
}

QDesignerPluginManager::~QDesignerPluginManager()
{
    syncSettings();
    delete m_d;
}

QDesignerFormEditorInterface *QDesignerPluginManager::core() const
{
    return m_d->m_core;
}

QStringList QDesignerPluginManager::findPlugins(const QString &path)
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO << path;
    const QDir dir(path);
    if (!dir.exists())
        return QStringList();

    const QFileInfoList infoList = dir.entryInfoList(QDir::Files);
    if (infoList.empty())
        return QStringList();

    // Load symbolic links but make sure all file names are unique as not
    // to fall for something like 'libplugin.so.1 -> libplugin.so'
    QStringList result;
    const QFileInfoList::const_iterator icend = infoList.constEnd();
    for (QFileInfoList::const_iterator it = infoList.constBegin(); it != icend; ++it) {
        QString fileName;
        if (it->isSymLink()) {
            const QFileInfo linkTarget = QFileInfo(it->symLinkTarget());
            if (linkTarget.exists() && linkTarget.isFile())
                fileName = linkTarget.absoluteFilePath();
        } else {
            fileName = it->absoluteFilePath();
        }
        if (!fileName.isEmpty() && QLibrary::isLibrary(fileName) && !result.contains(fileName))
            result += fileName;
    }
    return result;
}

void QDesignerPluginManager::setDisabledPlugins(const QStringList &disabled_plugins)
{
    m_d->m_disabledPlugins = disabled_plugins;
    updateRegisteredPlugins();
}

void QDesignerPluginManager::setPluginPaths(const QStringList &plugin_paths)
{
    m_d->m_pluginPaths = plugin_paths;
    updateRegisteredPlugins();
}

QStringList QDesignerPluginManager::disabledPlugins() const
{
    return m_d->m_disabledPlugins;
}

QStringList QDesignerPluginManager::failedPlugins() const
{
    return m_d->m_failedPlugins.keys();
}

QString QDesignerPluginManager::failureReason(const QString &pluginName) const
{
    return m_d->m_failedPlugins.value(pluginName);
}

QStringList QDesignerPluginManager::registeredPlugins() const
{
    return m_d->m_registeredPlugins;
}

QStringList QDesignerPluginManager::pluginPaths() const
{
    return m_d->m_pluginPaths;
}

QObject *QDesignerPluginManager::instance(const QString &plugin) const
{
    if (m_d->m_disabledPlugins.contains(plugin))
        return 0;

    QPluginLoader loader(plugin);
    return loader.instance();
}

void QDesignerPluginManager::updateRegisteredPlugins()
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO;
    m_d->m_registeredPlugins.clear();
    foreach (const QString &path,  m_d->m_pluginPaths)
        registerPath(path);
}

bool QDesignerPluginManager::registerNewPlugins()
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO;

    const int before = m_d->m_registeredPlugins.size();
    foreach (const QString &path, m_d->m_pluginPaths)
        registerPath(path);
    const bool newPluginsFound = m_d->m_registeredPlugins.size() > before;
    // We force a re-initialize as Jambi collection might return
    // different widget lists when switching projects.
    m_d->m_initialized = false;
    ensureInitialized();

    return newPluginsFound;
}

void QDesignerPluginManager::registerPath(const QString &path)
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO << path;
    QStringList candidates = findPlugins(path);

    foreach (const QString &plugin, candidates)
        registerPlugin(plugin);
}

void QDesignerPluginManager::registerPlugin(const QString &plugin)
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO << plugin;
    if (m_d->m_disabledPlugins.contains(plugin))
        return;
    if (m_d->m_registeredPlugins.contains(plugin))
        return;

    QPluginLoader loader(plugin);
    if (loader.isLoaded() || loader.load()) {
        m_d->m_registeredPlugins += plugin;
        QDesignerPluginManagerPrivate::FailedPluginMap::iterator fit = m_d->m_failedPlugins.find(plugin);
        if (fit != m_d->m_failedPlugins.end())
            m_d->m_failedPlugins.erase(fit);
        return;
    }

    const QString errorMessage = loader.errorString();
    m_d->m_failedPlugins.insert(plugin, errorMessage);
}



bool QDesignerPluginManager::syncSettings()
{
    QSettings settings(qApp->organizationName(), QDesignerQSettings::settingsApplicationName());
    settings.beginGroup(QLatin1String("PluginManager"));
    settings.setValue(QLatin1String("DisabledPlugins"), m_d->m_disabledPlugins);
    settings.endGroup();
    return settings.status() == QSettings::NoError;
}

void QDesignerPluginManager::ensureInitialized()
{
    if (debugPluginManager)
        qDebug() << Q_FUNC_INFO <<  m_d->m_initialized << m_d->m_customWidgets.size();

    if (m_d->m_initialized)
        return;

    const QString designerLanguage = getDesignerLanguage(m_d->m_core);

    m_d->clearCustomWidgets();
    // Add the static custom widgets
    const QObjectList staticPluginObjects = QPluginLoader::staticInstances();
    if (!staticPluginObjects.empty()) {
        const QString staticPluginPath = QCoreApplication::applicationFilePath();
        foreach(QObject *o, staticPluginObjects)
            m_d->addCustomWidgets(o, staticPluginPath, designerLanguage);
    }
    foreach (const QString &plugin, m_d->m_registeredPlugins)
        if (QObject *o = instance(plugin))
            m_d->addCustomWidgets(o, plugin, designerLanguage);

    m_d->m_initialized = true;
}

QDesignerPluginManager::CustomWidgetList QDesignerPluginManager::registeredCustomWidgets() const
{
    const_cast<QDesignerPluginManager*>(this)->ensureInitialized();
    return m_d->m_customWidgets;
}

QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(QDesignerCustomWidgetInterface *w) const
{
    const int index = m_d->m_customWidgets.indexOf(w);
    if (index == -1)
        return QDesignerCustomWidgetData();
    return m_d->m_customWidgetData.at(index);
}

QDesignerCustomWidgetData QDesignerPluginManager::customWidgetData(const QString &name) const
{
    const int count = m_d->m_customWidgets.size();
    for (int i = 0; i < count; i++)
        if (m_d->m_customWidgets.at(i)->name() == name)
            return m_d->m_customWidgetData.at(i);
    return QDesignerCustomWidgetData();
}

QObjectList QDesignerPluginManager::instances() const
{
    QStringList plugins = registeredPlugins();

    QObjectList lst;
    foreach (const QString &plugin, plugins) {
        if (QObject *o = instance(plugin))
            lst.append(o);
    }

    return lst;
}

QT_END_NAMESPACE
