1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the core module of the Qt Toolkit.
7
** This file may be distributed under the terms of the Q Public License
8
** as defined by Trolltech AS of Norway and appearing in the file
9
** LICENSE.QPL included in the packaging of this file.
11
** This file may be distributed and/or modified under the terms of the
12
** GNU General Public License version 2 as published by the Free Software
13
** Foundation and appearing in the file LICENSE.GPL included in the
14
** packaging of this file.
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
17
** information about Qt Commercial License Agreements.
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
21
** Contact info@trolltech.com if any conditions of this licensing are
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27
****************************************************************************/
29
#include "qfactoryloader_p.h"
30
#include "qfactoryinterface.h"
33
#include <qsettings.h>
37
#include "qpluginloader.h"
38
#include "private/qobject_p.h"
39
#include "private/qcoreapplication_p.h"
41
class QFactoryLoaderPrivate : public QObjectPrivate
43
Q_DECLARE_PUBLIC(QFactoryLoader)
45
QFactoryLoaderPrivate(){}
48
QList<QLibraryPrivate*> libraryList;
49
QMap<QString,QLibraryPrivate*> keyMap;
53
QFactoryLoader::QFactoryLoader(const char *iid,
54
const QStringList &paths, const QString &suffix,
55
Qt::CaseSensitivity cs)
56
: QObject(*new QFactoryLoaderPrivate)
58
QCoreApplicationPrivate::moveToMainThread(this);
62
QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));
64
for (int i = 0; i < paths.count(); ++i) {
65
QString path = paths.at(i) + suffix;
66
if (!QDir(path).exists(QLatin1String(".")))
68
QStringList plugins = QDir(path).entryList(QDir::Files);
69
QLibraryPrivate *library = 0;
70
for (int j = 0; j < plugins.count(); ++j) {
71
QString fileName = QDir::cleanPath(path + QLatin1Char('/') + plugins.at(j));
72
library = QLibraryPrivate::findOrCreate(QFileInfo(fileName).canonicalFilePath());
73
if (!library->isPlugin()) {
77
QString regkey = QString::fromLatin1("Qt Factory Cache %1.%2/%3:/%4")
78
.arg((QT_VERSION & 0xff0000) >> 16)
79
.arg((QT_VERSION & 0xff00) >> 8)
80
.arg(QLatin1String(iid))
82
QStringList reg, keys;
83
reg = settings.value(regkey).toStringList();
84
if (reg.count() && library->lastModified == reg[0]) {
88
if (!library->loadPlugin()) {
92
QObject *instance = library->instance();
93
QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instance);
94
if (instance && factory && instance->qt_metacast(iid))
95
keys = factory->keys();
99
reg << library->lastModified;
101
settings.setValue(regkey, reg);
103
if (keys.isEmpty()) {
107
d->libraryList += library;
108
for (int k = 0; k < keys.count(); ++k) {
109
// first come first serve, unless the first
110
// library was built with a future Qt version,
111
// whereas the new one has a Qt version that fits
113
QString key = keys.at(k);
116
QLibraryPrivate *previous = d->keyMap.value(key);
117
if (!previous || (previous->qt_version > QT_VERSION && library->qt_version <= QT_VERSION)) {
118
d->keyMap[key] = library;
119
d->keyList += keys.at(k);
126
QFactoryLoader::~QFactoryLoader()
129
for (int i = 0; i < d->libraryList.count(); ++i)
130
d->libraryList.at(i)->release();
133
QStringList QFactoryLoader::keys() const
135
Q_D(const QFactoryLoader);
136
QMutexLocker locker(&d->mutex);
137
QStringList keys = d->keyList;
138
QObjectList instances = QPluginLoader::staticInstances();
139
for (int i = 0; i < instances.count(); ++i)
140
if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
141
if (instances.at(i)->qt_metacast(d->iid))
142
keys += factory->keys();
146
QObject *QFactoryLoader::instance(const QString &key) const
148
Q_D(const QFactoryLoader);
149
QMutexLocker locker(&d->mutex);
150
QObjectList instances = QPluginLoader::staticInstances();
151
for (int i = 0; i < instances.count(); ++i)
152
if (QFactoryInterface *factory = qobject_cast<QFactoryInterface*>(instances.at(i)))
153
if (instances.at(i)->qt_metacast(d->iid) && factory->keys().contains(key, Qt::CaseInsensitive))
154
return instances.at(i);
156
if (QLibraryPrivate* library = d->keyMap.value(key)) {
157
if (library->instance || library->loadPlugin()) {
158
if (QObject *obj = library->instance()) {
159
if (obj && !obj->parent())
160
QCoreApplicationPrivate::moveToMainThread(obj);