Qt 4.8
qdeclarativeimport.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qdeclarativeimport_p.h"
43 
44 #include <QtCore/qdebug.h>
45 #include <QtCore/qdir.h>
46 #include <QtCore/qfileinfo.h>
47 #include <QtCore/qpluginloader.h>
48 #include <QtCore/qlibraryinfo.h>
49 #include <QtCore/qalgorithms.h>
50 #include <QtDeclarative/qdeclarativeextensioninterface.h>
51 #include <private/qdeclarativeglobal_p.h>
52 #include <private/qdeclarativetypenamecache_p.h>
53 #include <private/qdeclarativeengine_p.h>
54 
55 #ifdef Q_OS_SYMBIAN
56 #include "private/qcore_symbian_p.h"
57 #endif
58 
60 
61 DEFINE_BOOL_CONFIG_OPTION(qmlImportTrace, QML_IMPORT_TRACE)
62 DEFINE_BOOL_CONFIG_OPTION(qmlCheckTypes, QML_CHECK_TYPES)
63 
64 static bool greaterThan(const QString &s1, const QString &s2)
65 {
66  return s1 > s2;
67 }
68 
70 Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes); // stores the uri
71 
73 {
74 public:
81 
82 
83  bool find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor,
84  QDeclarativeType** type_return, QUrl* url_return,
85  QUrl *base = 0, bool *typeRecursionDetected = 0);
86  bool find(QDeclarativeTypeLoader *typeLoader, const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
87  QUrl* url_return, QUrl *base = 0, QString *errorString = 0);
88 };
89 
91 public:
94 
95  bool importExtension(const QString &absoluteFilePath, const QString &uri,
98 
99  QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database);
100  bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
101  const QString& uri_arg, const QString& prefix,
102  int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType,
103  QDeclarativeImportDatabase *database, QString *errorString);
104  bool find(const QByteArray& type, int *vmajor, int *vminor,
105  QDeclarativeType** type_return, QUrl* url_return, QString *errorString);
106 
107  QDeclarativeImportedNamespace *findNamespace(const QString& type);
108 
110  int ref;
111 
116 };
117 
127 : d(copy.d)
128 {
129  ++d->ref;
130 }
131 
134 {
135  ++copy.d->ref;
136  if (--d->ref == 0)
137  delete d;
138  d = copy.d;
139  return *this;
140 }
141 
143  : d(new QDeclarativeImportsPrivate(0)){
144 }
145 
147  : d(new QDeclarativeImportsPrivate(typeLoader)){
148 }
149 
151 {
152  if (--d->ref == 0)
153  delete d;
154 }
155 
160 {
161  d->base = url;
162 }
163 
168 {
169  return d->base;
170 }
171 
175 {
176  if (!cache)
177  cache = new QDeclarativeTypeNameCache(engine);
178 
180 
181  for (int ii = 0; ii < set.uris.count(); ++ii) {
182  QByteArray base = set.uris.at(ii).toUtf8() + '/';
183  int major = set.majversions.at(ii);
184  int minor = set.minversions.at(ii);
185 
186  foreach (QDeclarativeType *type, types) {
187  if (type->qmlTypeName().startsWith(base) &&
188  type->qmlTypeName().lastIndexOf('/') == (base.length() - 1) &&
189  type->availableInVersion(major,minor))
190  {
191  QString name = QString::fromUtf8(type->qmlTypeName().mid(base.length()));
192 
193  cache->add(name, type);
194  }
195  }
196  }
197 
198  return cache;
199 }
200 
202 {
204 
206  iter != d->set.end(); ++iter) {
207 
208  QDeclarativeTypeNameCache::Data *d = cache->data(iter.key());
209  if (d) {
210  if (!d->typeNamespace)
211  cacheForNamespace(engine, *(*iter), d->typeNamespace);
212  } else {
213  QDeclarativeTypeNameCache *nc = cacheForNamespace(engine, *(*iter), 0);
214  cache->add(iter.key(), nc);
215  nc->release();
216  }
217  }
218 
219  cacheForNamespace(engine, set, cache);
220 }
221 
240  QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
242 {
244  if (ns) {
245  if (ns_return)
246  *ns_return = ns;
247  return true;
248  }
249  if (type_return || url_return) {
250  if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
251  if (qmlImportTrace()) {
252  if (type_return && *type_return && url_return && !url_return->isEmpty())
253  qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
254  << type << " => " << (*type_return)->typeName() << " " << *url_return;
255  if (type_return && *type_return)
256  qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
257  << type << " => " << (*type_return)->typeName();
258  if (url_return && !url_return->isEmpty())
259  qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: "
260  << type << " => " << *url_return;
261  }
262  return true;
263  }
264  }
265  return false;
266 }
267 
282  QDeclarativeType** type_return, QUrl* url_return,
283  int *vmaj, int *vmin) const
284 {
286  return ns->find(d->typeLoader,type,vmaj,vmin,type_return,url_return);
287 }
288 
289 bool QDeclarativeImportedNamespace::find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray& type, int *vmajor, int *vminor,
290  QDeclarativeType** type_return, QUrl* url_return,
291  QUrl *base, bool *typeRecursionDetected)
292 {
293  int vmaj = majversions.at(i);
294  int vmin = minversions.at(i);
295 
296  QByteArray qt = uris.at(i).toUtf8();
297  qt += '/';
298  qt += type;
299 
301  if (t) {
302  if (vmajor) *vmajor = vmaj;
303  if (vminor) *vminor = vmin;
304  if (type_return)
305  *type_return = t;
306  return true;
307  }
308 
309  QDeclarativeDirComponents qmldircomponents = qmlDirComponents.at(i);
310 
311  bool typeWasDeclaredInQmldir = false;
312  if (!qmldircomponents.isEmpty()) {
313  const QString typeName = QString::fromUtf8(type);
314  foreach (const QDeclarativeDirParser::Component &c, qmldircomponents) {
315  if (c.typeName == typeName) {
316  typeWasDeclaredInQmldir = true;
317 
318  // importing version -1 means import ALL versions
319  if ((vmaj == -1) || (c.majorVersion < vmaj || (c.majorVersion == vmaj && vmin >= c.minorVersion))) {
320  QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
321  QUrl candidate = url.resolved(QUrl(c.fileName));
322  if (c.internal && base) {
323  if (base->resolved(QUrl(c.fileName)) != candidate)
324  continue; // failed attempt to access an internal type
325  }
326  if (base && *base == candidate) {
327  if (typeRecursionDetected)
328  *typeRecursionDetected = true;
329  continue; // no recursion
330  }
331  if (url_return)
332  *url_return = candidate;
333  return true;
334  }
335  }
336  }
337  }
338 
339  if (!typeWasDeclaredInQmldir && !isLibrary.at(i)) {
340  // XXX search non-files too! (eg. zip files, see QT-524)
341  QUrl url = QUrl(urls.at(i) + QLatin1Char('/') + QString::fromUtf8(type) + QLatin1String(".qml"));
343  if (!typeLoader->absoluteFilePath(file).isEmpty()) {
344  if (base && *base == url) { // no recursion
345  if (typeRecursionDetected)
346  *typeRecursionDetected = true;
347  } else {
348  if (url_return)
349  *url_return = url;
350  return true;
351  }
352  }
353  }
354  return false;
355 }
356 
358  : ref(1), typeLoader(loader){
359 }
360 
362 {
363  foreach (QDeclarativeImportedNamespace* s, set.values())
364  delete s;
365 }
366 
367 bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri,
368  QDeclarativeImportDatabase *database,
370 {
372  const QDeclarativeDirParser *qmldirParser = typeLoader->qmlDirParser(absoluteFilePath);
373  if (qmldirParser->hasError()) {
374  if (errorString) {
375  const QList<QDeclarativeError> qmldirErrors = qmldirParser->errors(uri);
376  for (int i = 0; i < qmldirErrors.size(); ++i)
377  *errorString += qmldirErrors.at(i).description();
378  }
379  return false;
380  }
381 
382  if (! qmlDirFilesForWhichPluginsHaveBeenLoaded.contains(absoluteFilePath)) {
384 
385  QDir dir = QFileInfo(absoluteFilePath).dir();
386  foreach (const QDeclarativeDirParser::Plugin &plugin, qmldirParser->plugins()) {
387 
388  QString resolvedFilePath = database->resolvePlugin(dir, plugin.path, plugin.name);
389 #if defined(QT_LIBINFIX) && defined(Q_OS_SYMBIAN)
390  if (resolvedFilePath.isEmpty()) {
391  // In case of libinfixed build, attempt to load libinfixed version, too.
392  QString infixedPluginName = plugin.name + QLatin1String(QT_LIBINFIX);
393  resolvedFilePath = database->resolvePlugin(dir, plugin.path, infixedPluginName);
394  }
395 #endif
396  if (!resolvedFilePath.isEmpty()) {
397  if (!database->importPlugin(resolvedFilePath, uri, errorString)) {
398  if (errorString)
399  *errorString = QDeclarativeImportDatabase::tr("plugin cannot be loaded for module \"%1\": %2").arg(uri).arg(*errorString);
400  return false;
401  }
402  } else {
403  if (errorString)
404  *errorString = QDeclarativeImportDatabase::tr("module \"%1\" plugin \"%2\" not found").arg(uri).arg(plugin.name);
405  return false;
406  }
407  }
408  }
409 
410  if (components)
411  *components = qmldirParser->components();
412 
413  return true;
414 }
415 
417 {
418  QString dir = dir_arg;
419  if (dir.endsWith(QLatin1Char('/')) || dir.endsWith(QLatin1Char('\\')))
420  dir.chop(1);
421 
422  QStringList paths = database->fileImportPath;
423  qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents.
424 
425  QString stableRelativePath = dir;
426  foreach(const QString &path, paths) {
427  if (dir.startsWith(path)) {
428  stableRelativePath = dir.mid(path.length()+1);
429  break;
430  }
431  }
432 
433  stableRelativePath.replace(QLatin1Char('\\'), QLatin1Char('/'));
434 
435  // remove optional versioning in dot notation from uri
436  int lastSlash = stableRelativePath.lastIndexOf(QLatin1Char('/'));
437  if (lastSlash >= 0) {
438  int versionDot = stableRelativePath.indexOf(QLatin1Char('.'), lastSlash);
439  if (versionDot >= 0)
440  stableRelativePath = stableRelativePath.left(versionDot);
441  }
442 
443  stableRelativePath.replace(QLatin1Char('/'), QLatin1Char('.'));
444  return stableRelativePath;
445 }
446 
447 bool QDeclarativeImportsPrivate::add(const QDeclarativeDirComponents &qmldircomponentsnetwork,
448  const QString& uri_arg, const QString& prefix, int vmaj, int vmin,
451 {
453  QDeclarativeDirComponents qmldircomponents = qmldircomponentsnetwork;
454  QString uri = uri_arg;
456  if (prefix.isEmpty()) {
457  s = &unqualifiedset;
458  } else {
459  s = set.value(prefix);
460  if (!s)
461  set.insert(prefix,(s=new QDeclarativeImportedNamespace));
462  }
463 
464  bool appendInstead = false;
465  if (importType == QDeclarativeScriptParser::Import::Implicit) {
466  //Treat same as a File import, but lower precedence
467  appendInstead = true;
469  }
470 
471  QString url = uri;
472  bool versionFound = false;
473  if (importType == QDeclarativeScriptParser::Import::Library) {
474  url.replace(QLatin1Char('.'), QLatin1Char('/'));
475  bool found = false;
476  QString dir;
477  QString qmldir;
478 
479  // step 1: search for extension with fully encoded version number
480  if (vmaj >= 0 && vmin >= 0) {
481  foreach (const QString &p, database->fileImportPath) {
482  dir = p+QLatin1Char('/')+url;
483  qmldir = dir+QString(QLatin1String(".%1.%2")).arg(vmaj).arg(vmin)+QLatin1String("/qmldir");
484 
485  QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
486  if (!absoluteFilePath.isEmpty()) {
487  found = true;
488 
489  QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
490  url = QUrl::fromLocalFile(absolutePath).toString();
491  uri = resolvedUri(dir, database);
492  if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
493  return false;
494  break;
495  }
496  }
497  }
498  // step 2: search for extension with encoded version major
499  if (vmaj >= 0 && vmin >= 0) {
500  foreach (const QString &p, database->fileImportPath) {
501  dir = p+QLatin1Char('/')+url;
502  qmldir = dir+QString(QLatin1String(".%1")).arg(vmaj)+QLatin1String("/qmldir");
503 
504  QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
505  if (!absoluteFilePath.isEmpty()) {
506  found = true;
507 
508  QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
509  url = QUrl::fromLocalFile(absolutePath).toString();
510  uri = resolvedUri(dir, database);
511  if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
512  return false;
513  break;
514  }
515  }
516  }
517  if (!found) {
518  // step 3: search for extension without version number
519 
520  foreach (const QString &p, database->fileImportPath) {
521  dir = p+QLatin1Char('/')+url;
522  qmldir = dir+QLatin1String("/qmldir");
523 
524  QString absoluteFilePath = typeLoader->absoluteFilePath(qmldir);
525  if (!absoluteFilePath.isEmpty()) {
526  found = true;
527 
528  QString absolutePath = absoluteFilePath.left(absoluteFilePath.lastIndexOf(QLatin1Char('/')));
529  url = QUrl::fromLocalFile(absolutePath).toString();
530  uri = resolvedUri(dir, database);
531  if (!importExtension(absoluteFilePath, uri, database, &qmldircomponents, errorString))
532  return false;
533  break;
534  }
535  }
536  }
537 
538  if (QDeclarativeMetaType::isModule(uri.toUtf8(), vmaj, vmin))
539  versionFound = true;
540 
541  //Load any type->file mappings registered for this uri
542  qmldircomponents << QDeclarativeMetaType::qmlComponents(uri.toUtf8(), vmaj, vmin);
543 
544  if (!versionFound && qmldircomponents.isEmpty()) {
545  if (errorString) {
546  bool anyversion = QDeclarativeMetaType::isModule(uri.toUtf8(), -1, -1);
547  if (anyversion)
548  *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
549  else
550  *errorString = QDeclarativeImportDatabase::tr("module \"%1\" is not installed").arg(uri_arg);
551  }
552  return false;
553  }
554  } else {
555 
556  if (importType == QDeclarativeScriptParser::Import::File && qmldircomponents.isEmpty()) {
557  QUrl importUrl = base.resolved(QUrl(uri + QLatin1String("/qmldir")));
558  QString localFileOrQrc = QDeclarativeEnginePrivate::urlToLocalFileOrQrc(importUrl);
559  if (!localFileOrQrc.isEmpty()) {
561  QFileInfo dirinfo(dir);
562  if (dir.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
563  if (errorString)
564  *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri_arg);
565  return false; // local import dirs must exist
566  }
568  if (uri.endsWith(QLatin1Char('/')))
569  uri.chop(1);
570  if (!typeLoader->absoluteFilePath(localFileOrQrc).isEmpty()) {
571  if (!importExtension(localFileOrQrc,uri,database,&qmldircomponents,errorString))
572  return false;
573  }
574  } else {
575  if (prefix.isEmpty()) {
576  // directory must at least exist for valid import
578  QFileInfo dirinfo(localFileOrQrc);
579  if (localFileOrQrc.isEmpty() || !dirinfo.exists() || !dirinfo.isDir()) {
580  if (errorString) {
581  if (localFileOrQrc.isEmpty())
582  *errorString = QDeclarativeImportDatabase::tr("import \"%1\" has no qmldir and no namespace").arg(uri);
583  else
584  *errorString = QDeclarativeImportDatabase::tr("\"%1\": no such directory").arg(uri);
585  }
586  return false;
587  }
588  }
589  }
590  }
591 
592  url = base.resolved(QUrl(url)).toString();
593  if (url.endsWith(QLatin1Char('/')))
594  url.chop(1);
595  }
596 
597  if (!versionFound && vmaj > -1 && vmin > -1 && !qmldircomponents.isEmpty()) {
599  int lowest_maj = INT_MAX;
600  int lowest_min = INT_MAX;
601  int highest_maj = INT_MIN;
602  int highest_min = INT_MIN;
603  for (; it != qmldircomponents.end(); ++it) {
604  if (it->majorVersion > highest_maj || (it->majorVersion == highest_maj && it->minorVersion > highest_min)) {
605  highest_maj = it->majorVersion;
606  highest_min = it->minorVersion;
607  }
608  if (it->majorVersion < lowest_maj || (it->majorVersion == lowest_maj && it->minorVersion < lowest_min)) {
609  lowest_maj = it->majorVersion;
610  lowest_min = it->minorVersion;
611  }
612  }
613  if (lowest_maj > vmaj || (lowest_maj == vmaj && lowest_min > vmin)
614  || highest_maj < vmaj || (highest_maj == vmaj && highest_min < vmin))
615  {
616  *errorString = QDeclarativeImportDatabase::tr("module \"%1\" version %2.%3 is not installed").arg(uri_arg).arg(vmaj).arg(vmin);
617  return false;
618  }
619  }
620 
621  if (appendInstead) {
622  s->uris.append(uri);
623  s->urls.append(url);
624  s->majversions.append(vmaj);
625  s->minversions.append(vmin);
627  s->qmlDirComponents.append(qmldircomponents);
628  } else {
629  s->uris.prepend(uri);
630  s->urls.prepend(url);
631  s->majversions.prepend(vmaj);
632  s->minversions.prepend(vmin);
634  s->qmlDirComponents.prepend(qmldircomponents);
635  }
636  return true;
637 }
638 
639 bool QDeclarativeImportsPrivate::find(const QByteArray& type, int *vmajor, int *vminor, QDeclarativeType** type_return,
640  QUrl* url_return, QString *errorString)
641 {
644  int slash = type.indexOf('/');
645  if (slash >= 0) {
646  QString namespaceName = QString::fromUtf8(type.left(slash));
647  s = set.value(namespaceName);
648  if (!s) {
649  if (errorString)
650  *errorString = QDeclarativeImportDatabase::tr("- %1 is not a namespace").arg(namespaceName);
651  return false;
652  }
653  int nslash = type.indexOf('/',slash+1);
654  if (nslash > 0) {
655  if (errorString)
656  *errorString = QDeclarativeImportDatabase::tr("- nested namespaces not allowed");
657  return false;
658  }
659  } else {
660  s = &unqualifiedset;
661  }
662  QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower)
663  if (s) {
664  if (s->find(typeLoader, unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errorString))
665  return true;
666  if (s->urls.count() == 1 && !s->isLibrary[0] && url_return && s != &unqualifiedset) {
667  // qualified, and only 1 url
668  *url_return = QUrl(s->urls[0]+QLatin1Char('/')).resolved(QUrl(QString::fromUtf8(unqualifiedtype) + QLatin1String(".qml")));
669  return true;
670  }
671  }
672 
673  return false;
674 }
675 
677 {
678  return set.value(type);
679 }
680 
682  QUrl* url_return, QUrl *base, QString *errorString)
683 {
684  bool typeRecursionDetected = false;
685  for (int i=0; i<urls.count(); ++i) {
686  if (find_helper(typeLoader, i, type, vmajor, vminor, type_return, url_return, base, &typeRecursionDetected)) {
687  if (qmlCheckTypes()) {
688  // check for type clashes
689  for (int j = i+1; j<urls.count(); ++j) {
690  if (find_helper(typeLoader, j, type, vmajor, vminor, 0, 0, base)) {
691  if (errorString) {
692  QString u1 = urls.at(i);
693  QString u2 = urls.at(j);
694  if (base) {
695  QString b = base->toString();
696  int slash = b.lastIndexOf(QLatin1Char('/'));
697  if (slash >= 0) {
698  b = b.left(slash+1);
699  QString l = b.left(slash);
700  if (u1.startsWith(b))
701  u1 = u1.mid(b.count());
702  else if (u1 == l)
703  u1 = QDeclarativeImportDatabase::tr("local directory");
704  if (u2.startsWith(b))
705  u2 = u2.mid(b.count());
706  else if (u2 == l)
707  u2 = QDeclarativeImportDatabase::tr("local directory");
708  }
709  }
710 
711  if (u1 != u2)
712  *errorString
713  = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 and in %2")
714  .arg(u1).arg(u2);
715  else
716  *errorString
717  = QDeclarativeImportDatabase::tr("is ambiguous. Found in %1 in version %2.%3 and %4.%5")
718  .arg(u1)
719  .arg(majversions.at(i)).arg(minversions.at(i))
720  .arg(majversions.at(j)).arg(minversions.at(j));
721  }
722  return false;
723  }
724  }
725  }
726  return true;
727  }
728  }
729  if (errorString) {
730  if (typeRecursionDetected)
731  *errorString = QDeclarativeImportDatabase::tr("is instantiated recursively");
732  else
733  *errorString = QDeclarativeImportDatabase::tr("is not a type");
734  }
735  return false;
736 }
737 
747 : engine(e)
748 {
750 
751  // Search order is applicationDirPath(), $QML_IMPORT_PATH, QLibraryInfo::ImportsPath
752 
753 #ifndef QT_NO_SETTINGS
755 
756 #if defined(Q_OS_SYMBIAN)
757  // Append imports path for all available drives in Symbian
758  if (installImportsPath.at(1) != QChar(QLatin1Char(':'))) {
759  QString tempPath = installImportsPath;
760  if (tempPath.at(tempPath.length() - 1) != QDir::separator()) {
761  tempPath += QDir::separator();
762  }
763  RFs& fs = qt_s60GetRFs();
764  TPtrC tempPathPtr(reinterpret_cast<const TText*> (tempPath.constData()));
765  // Symbian searches should start from Y:. Fix start drive otherwise TFindFile starts from the session drive
766  _LIT(KStartDir, "Y:");
767  TFileName dirPath(KStartDir);
768  dirPath.Append(tempPathPtr);
769  TFindFile finder(fs);
770  TInt err = finder.FindByDir(tempPathPtr, dirPath);
771  while (err == KErrNone) {
772  QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()),
773  finder.File().Length());
774  foundDir = QDir(foundDir).canonicalPath();
775  addImportPath(foundDir);
776  err = finder.Find();
777  }
778  // TFindFile found the directories in the order we want, but addImportPath reverses it.
779  // Reverse the order again to get it right.
781  } else {
782  addImportPath(installImportsPath);
783  }
784 #else
785  addImportPath(installImportsPath);
786 #endif
787 
788 #endif // QT_NO_SETTINGS
789 
790  // env import paths
791  QByteArray envImportPath = qgetenv("QML_IMPORT_PATH");
792  if (!envImportPath.isEmpty()) {
793 #if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
794  QLatin1Char pathSep(';');
795 #else
796  QLatin1Char pathSep(':');
797 #endif
798  QStringList paths = QString::fromLatin1(envImportPath).split(pathSep, QString::SkipEmptyParts);
799  for (int ii = paths.count() - 1; ii >= 0; --ii)
800  addImportPath(paths.at(ii));
801  }
802 
804 }
805 
807 {
808 }
809 
828  const QString& uri, const QString& prefix, int vmaj, int vmin,
830  const QDeclarativeDirComponents &qmldircomponentsnetwork,
832 {
833  if (qmlImportTrace())
834  qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: "
835  << uri << " " << vmaj << '.' << vmin << " "
836  << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File")
837  << " as " << prefix;
838 
839  return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
840 }
841 
853 QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
854  const QString &baseName, const QStringList &suffixes,
855  const QString &prefix)
856 {
857  QStringList searchPaths = filePluginPath;
858  bool qmldirPluginPathIsRelative = QDir::isRelativePath(qmldirPluginPath);
859  if (!qmldirPluginPathIsRelative)
860  searchPaths.prepend(qmldirPluginPath);
861 
862  foreach (const QString &pluginPath, searchPaths) {
863 
864  QString resolvedPath;
865 
866  if (pluginPath == QLatin1String(".")) {
867  if (qmldirPluginPathIsRelative)
868  resolvedPath = qmldirPath.absoluteFilePath(qmldirPluginPath);
869  else
870  resolvedPath = qmldirPath.absolutePath();
871  } else {
872  resolvedPath = pluginPath;
873  }
874 
875  // hack for resources, should probably go away
876  if (resolvedPath.startsWith(QLatin1Char(':')))
877  resolvedPath = QCoreApplication::applicationDirPath();
878 
879  QDir dir(resolvedPath);
880  foreach (const QString &suffix, suffixes) {
881  QString pluginFileName = prefix;
882 
883  pluginFileName += baseName;
884  pluginFileName += suffix;
885 
886  QFileInfo fileInfo(dir, pluginFileName);
887 
888  if (fileInfo.exists())
889  return fileInfo.absoluteFilePath();
890  }
891  }
892 
893  if (qmlImportTrace())
894  qDebug() << "QDeclarativeImportDatabase::resolvePlugin: Could not resolve plugin" << baseName
895  << "in" << qmldirPath.absolutePath();
896 
897  return QString();
898 }
899 
920 QString QDeclarativeImportDatabase::resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath,
921  const QString &baseName)
922 {
923 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
924  return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
925  QStringList()
926 # ifdef QT_DEBUG
927  << QLatin1String("d.dll") // try a qmake-style debug build first
928 # endif
929  << QLatin1String(".dll"));
930 #elif defined(Q_OS_SYMBIAN)
931  return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
932  QStringList()
933  << QLatin1String(".dll")
934  << QLatin1String(".qtplugin"));
935 #else
936 
937 # if defined(Q_OS_DARWIN)
938 
939  return resolvePlugin(qmldirPath, qmldirPluginPath, baseName,
940  QStringList()
941 # ifdef QT_DEBUG
942  << QLatin1String("_debug.dylib") // try a qmake-style debug build first
943  << QLatin1String(".dylib")
944 # else
945  << QLatin1String(".dylib")
946  << QLatin1String("_debug.dylib") // try a qmake-style debug build after
947 # endif
948  << QLatin1String(".so")
949  << QLatin1String(".bundle"),
950  QLatin1String("lib"));
951 # else // Generic Unix
952  QStringList validSuffixList;
953 
954 # if defined(Q_OS_HPUX)
955 /*
956  See "HP-UX Linker and Libraries User's Guide", section "Link-time Differences between PA-RISC and IPF":
957  "In PA-RISC (PA-32 and PA-64) shared libraries are suffixed with .sl. In IPF (32-bit and 64-bit),
958  the shared libraries are suffixed with .so. For compatibility, the IPF linker also supports the .sl suffix."
959  */
960  validSuffixList << QLatin1String(".sl");
961 # if defined __ia64
962  validSuffixList << QLatin1String(".so");
963 # endif
964 # elif defined(Q_OS_AIX)
965  validSuffixList << QLatin1String(".a") << QLatin1String(".so");
966 # elif defined(Q_OS_UNIX)
967  validSuffixList << QLatin1String(".so");
968 # endif
969 
970  // Examples of valid library names:
971  // libfoo.so
972 
973  return resolvePlugin(qmldirPath, qmldirPluginPath, baseName, validSuffixList, QLatin1String("lib"));
974 # endif
975 
976 #endif
977 }
978 
983 {
984  return filePluginPath;
985 }
986 
991 {
992  filePluginPath = paths;
993 }
994 
999 {
1000  if (qmlImportTrace())
1001  qDebug().nospace() << "QDeclarativeImportDatabase::addPluginPath: " << path;
1002 
1003  QUrl url = QUrl(path);
1004  if (url.isRelative() || url.scheme() == QLatin1String("file")
1005  || (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
1006  QDir dir = QDir(path);
1008  } else {
1009  filePluginPath.prepend(path);
1010  }
1011 }
1012 
1017 {
1018  if (qmlImportTrace())
1019  qDebug().nospace() << "QDeclarativeImportDatabase::addImportPath: " << path;
1020 
1021  if (path.isEmpty())
1022  return;
1023 
1024  QUrl url = QUrl(path);
1025  QString cPath;
1026 
1027  if (url.isRelative() || url.scheme() == QLatin1String("file")
1028  || (url.scheme().length() == 1 && QFile::exists(path)) ) { // windows path
1029  QDir dir = QDir(path);
1030  cPath = dir.canonicalPath();
1031  } else {
1032  cPath = path;
1033  cPath.replace(QLatin1Char('\\'), QLatin1Char('/'));
1034  }
1035 
1036  if (!cPath.isEmpty()
1037  && !fileImportPath.contains(cPath))
1038  fileImportPath.prepend(cPath);
1039 }
1040 
1045 {
1046  return fileImportPath;
1047 }
1048 
1053 {
1054  fileImportPath = paths;
1055 }
1056 
1061 {
1062  if (qmlImportTrace())
1063  qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;
1064 
1065 #ifndef QT_NO_LIBRARY
1066  QFileInfo fileInfo(filePath);
1067  const QString absoluteFilePath = fileInfo.absoluteFilePath();
1068 
1069  bool engineInitialized = initializedPlugins.contains(absoluteFilePath);
1070  bool typesRegistered = qmlEnginePluginsWithRegisteredTypes()->contains(absoluteFilePath);
1071 
1072  if (typesRegistered) {
1073  Q_ASSERT_X(qmlEnginePluginsWithRegisteredTypes()->value(absoluteFilePath) == uri,
1074  "QDeclarativeImportDatabase::importExtension",
1075  "Internal error: Plugin imported previously with different uri");
1076  }
1077 
1078  if (!engineInitialized || !typesRegistered) {
1079  if (!QDeclarative_isFileCaseCorrect(absoluteFilePath)) {
1080  if (errorString)
1081  *errorString = tr("File name case mismatch for \"%1\"").arg(absoluteFilePath);
1082  return false;
1083  }
1084  QPluginLoader loader(absoluteFilePath);
1085 
1086  if (!loader.load()) {
1087  if (errorString)
1088  *errorString = loader.errorString();
1089  return false;
1090  }
1091 
1092  if (QDeclarativeExtensionInterface *iface = qobject_cast<QDeclarativeExtensionInterface *>(loader.instance())) {
1093 
1094  const QByteArray bytes = uri.toUtf8();
1095  const char *moduleId = bytes.constData();
1096  if (!typesRegistered) {
1097 
1098  // ### this code should probably be protected with a mutex.
1099  qmlEnginePluginsWithRegisteredTypes()->insert(absoluteFilePath, uri);
1100  iface->registerTypes(moduleId);
1101  }
1102  if (!engineInitialized) {
1103  // things on the engine (eg. adding new global objects) have to be done for every engine.
1104 
1105  // protect against double initialization
1106  initializedPlugins.insert(absoluteFilePath);
1107  iface->initializeEngine(engine, moduleId);
1108  }
1109  } else {
1110  if (errorString)
1111  *errorString = loader.errorString();
1112  return false;
1113  }
1114  }
1115 
1116  return true;
1117 #else
1118  return false;
1119 #endif
1120 }
1121 
1122 
The QDir class provides access to directory structures and their contents.
Definition: qdir.h:58
static QString urlToLocalFileOrQrc(const QUrl &url)
double d
Definition: qnumeric_p.h:62
static bool isModule(const QByteArray &module, int versionMajor, int versionMinor)
Q_CORE_EXPORT QByteArray qgetenv(const char *varName)
QDeclarativeImports & operator=(const QDeclarativeImports &)
The QHash::const_iterator class provides an STL-style const iterator for QHash and QMultiHash...
Definition: qhash.h:395
int type
Definition: qmetatype.cpp:239
unsigned char c[8]
Definition: qnumeric_p.h:62
bool add(const QDeclarativeDirComponents &qmldircomponentsnetwork, const QString &uri_arg, const QString &prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, QDeclarativeImportDatabase *database, QString *errorString)
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QString errorString() const
Returns a text string with the description of the last error that occurred.
QString absoluteFilePath(const QString &fileName) const
Returns the absolute path name of a file in the directory.
Definition: qdir.cpp:701
QDeclarativeImportDatabase(QDeclarativeEngine *)
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
#define add(aName)
QDir dir() const
Returns the path of the object&#39;s parent directory as a QDir object.
Definition: qfileinfo.cpp:861
QString toString(FormattingOptions options=None) const
Returns the human-displayable string representation of the URL.
Definition: qurl.cpp:5896
static bool greaterThan(const QString &s1, const QString &s2)
#define it(className, varName)
bool load()
Loads the plugin and returns true if the plugin was loaded successfully; otherwise returns false...
bool addImport(QDeclarativeImportDatabase *, const QString &uri, const QString &prefix, int vmaj, int vmin, QDeclarativeScriptParser::Import::Type importType, const QDeclarativeDirComponents &qmldircomponentsnetwork, QString *errorString)
Adds information to imports such that subsequent calls to resolveType() will resolve types qualified ...
QByteArray toUtf8() const Q_REQUIRED_RESULT
Returns a UTF-8 representation of the string as a QByteArray.
Definition: qstring.cpp:4074
QList< QDeclarativeError > errors(const QString &uri) const
QString & replace(int i, int len, QChar after)
Definition: qstring.cpp:2005
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
void chop(int n)
Removes n characters from the end of the string.
Definition: qstring.cpp:4623
bool isEmpty() const
Returns true if the URL has no data; otherwise returns false.
Definition: qurl.cpp:4317
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
static QList< QDeclarativeType * > qmlTypes()
Returns the list of registered QML types.
QString resolvedUri(const QString &dir_arg, QDeclarativeImportDatabase *database)
QSet< QString > qmlDirFilesForWhichPluginsHaveBeenLoaded
iterator begin()
Returns an STL-style iterator pointing to the first item in the list.
Definition: qlist.h:267
void add(const QString &, int)
static QDeclarativeType * qmlType(const QByteArray &, int, int)
Returns the type (if any) of URI-qualified named name in version specified by version_major and versi...
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
Q_GLOBAL_STATIC(StringStringMap, qmlEnginePluginsWithRegisteredTypes)
bool importPlugin(const QString &filePath, const QString &uri, QString *errorString)
QString absoluteFilePath() const
Returns an absolute path including the file name.
Definition: qfileinfo.cpp:534
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool exists() const
Returns true if the file exists; otherwise returns false.
Definition: qfileinfo.cpp:675
bool resolveType(const QByteArray &type, QDeclarativeType **type_return, QUrl *url_return, int *version_major, int *version_minor, QDeclarativeImportedNamespace **ns_return, QString *errorString=0) const
The given (namespace qualified) type is resolved to either.
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
static bool isRelativePath(const QString &path)
Returns true if path is relative; returns false if it is absolute.
Definition: qdir.cpp:2210
The QUrl class provides a convenient interface for working with URLs.
Definition: qurl.h:61
The QString class provides a Unicode character string.
Definition: qstring.h:83
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
bool startsWith(const QByteArray &a) const
Returns true if this byte array starts with byte array ba; otherwise returns false.
static QChar separator()
Returns the native directory separator: "/" under Unix (including Mac OS X) and "\\" under Windows...
Definition: qdir.cpp:1831
static const uint base
Definition: qurl.cpp:268
bool find(QDeclarativeTypeLoader *typeLoader, const QByteArray &type, int *vmajor, int *vminor, QDeclarativeType **type_return, QUrl *url_return, QUrl *base=0, QString *errorString=0)
bool isRelative() const
Returns true if the URL is relative; otherwise returns false.
Definition: qurl.cpp:5880
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QHash< QString, QDeclarativeImportedNamespace *> set
The QDeclarativeImports class encapsulates one QML document&#39;s import statements.
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
Q_GUI_EXPORT QString errorString(EGLint code=eglGetError())
Definition: qegl.cpp:743
bool exists() const
Returns true if the file specified by fileName() exists; otherwise returns false. ...
Definition: qfile.cpp:626
Q_CORE_EXPORT void qDebug(const char *,...)
bool QDeclarative_isFileCaseCorrect(const QString &fileName)
Returns true if the case of fileName is equivalent to the file case of fileName on disk...
static QString toString(Register *reg, int type, bool *ok=0)
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
static QString applicationDirPath()
Returns the directory that contains the application executable.
QUrl baseUrl() const
Returns the base URL to be used for all relative file imports added.
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QList< Component > components() const
int lastIndexOf(char c, int from=-1) const
Returns the index position of the last occurrence of character ch in the byte array, searching backward from index position from.
QStringList pluginPathList() const
static QDeclarativeDirComponents qmlComponents(const QByteArray &module, int version_major, int version_minor)
Returns the component(s) that have been registered for the module specified by uri and the version sp...
QString left(int n) const Q_REQUIRED_RESULT
Returns a substring that contains the n leftmost characters of the string.
Definition: qstring.cpp:3664
const char * typeName
Definition: qmetatype.cpp:239
bool contains(const T &value) const
Definition: qset.h:91
void addPluginPath(const QString &path)
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
QString absolutePath() const
Returns the absolute path (a path that starts with "/" or with a drive specification), which may contain symbolic links, but never contains redundant ".", ".." or multiple separators.
Definition: qdir.cpp:619
QDeclarativeImportsPrivate * d
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:270
const char * name
void setImportPathList(const QStringList &paths)
void prepend(const T &t)
Inserts value at the beginning of the list.
Definition: qlist.h:541
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
QString description() const
Returns the error description.
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
const_iterator insert(const T &value)
Definition: qset.h:179
QDeclarativeImportsPrivate(QDeclarativeTypeLoader *loader)
static QDeclarativeTypeNameCache * cacheForNamespace(QDeclarativeEngine *engine, const QDeclarativeImportedNamespace &set, QDeclarativeTypeNameCache *cache)
#define DEFINE_BOOL_CONFIG_OPTION(name, var)
const QDeclarativeDirParser * qmlDirParser(const QString &absoluteFilePath)
Return a QDeclarativeDirParser for absoluteFilePath.
Q_OUTOFLINE_TEMPLATE void qReverse(RandomAccessIterator begin, RandomAccessIterator end)
Definition: qalgorithms.h:399
QByteArray qmlTypeName() const
QBool contains(const QString &str, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the list contains the string str; otherwise returns false.
Definition: qstringlist.h:172
#define QT_DEBUG
Definition: qglobal.h:1746
QByteArray left(int len) const
Returns a byte array that contains the leftmost len bytes of this byte array.
quint16 values[128]
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
int count() const
Definition: qstring.h:103
QString resolvePlugin(const QDir &qmldirPath, const QString &qmldirPluginPath, const QString &baseName, const QStringList &suffixes, const QString &prefix=QString())
Returns the result of the merge of baseName with path, suffixes, and prefix.
int length() const
Same as size().
Definition: qbytearray.h:356
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
void setPluginPathList(const QStringList &paths)
void populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *) const
QString scheme() const
Returns the scheme of the URL.
Definition: qurl.cpp:4550
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
QString arg(qlonglong a, int fieldwidth=0, int base=10, const QChar &fillChar=QLatin1Char(' ')) const Q_REQUIRED_RESULT
Definition: qstring.cpp:7186
void addImportPath(const QString &dir)
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the hash...
Definition: qhash.h:467
static const struct @32 types[]
QStringList importPathList() const
The QDeclarativeEngine class provides an environment for instantiating QML components.
int lastIndexOf(QChar c, int from=-1, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:3000
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
QDeclarativeImportedNamespace * findNamespace(const QString &type)
static QString location(LibraryLocation)
Returns the location specified by loc.
QByteArray suffix
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
QString canonicalPath() const
Returns the canonical path, i.e.
Definition: qdir.cpp:642
bool find_helper(QDeclarativeTypeLoader *typeLoader, int i, const QByteArray &type, int *vmajor, int *vminor, QDeclarativeType **type_return, QUrl *url_return, QUrl *base=0, bool *typeRecursionDetected=0)
QFactoryLoader * l
iterator begin()
Returns an STL-style iterator pointing to the first item in the hash.
Definition: qhash.h:464
QDeclarativeTypeNameCache * typeNamespace
bool importExtension(const QString &absoluteFilePath, const QString &uri, QDeclarativeImportDatabase *database, QDeclarativeDirComponents *components, QString *errorString)
void setBaseUrl(const QUrl &url)
Sets the base URL to be used for all relative file imports added.
static QUrl fromLocalFile(const QString &localfile)
Returns a QUrl representation of localFile, interpreted as a local file.
Definition: qurl.cpp:6374
QString absoluteFilePath(const QString &path)
Returns the absolute filename of path via a directory cache for files named "qmldir", "*.qml", "*.js" Returns a empty string if the path does not exist.
bool isEmpty() const
Returns true if the byte array has size 0; otherwise returns false.
Definition: qbytearray.h:421
QStringList split(const QString &sep, SplitBehavior behavior=KeepEmptyParts, Qt::CaseSensitivity cs=Qt::CaseSensitive) const Q_REQUIRED_RESULT
Splits the string into substrings wherever sep occurs, and returns the list of those strings...
Definition: qstring.cpp:6526
QObject * instance()
Returns the root component object of the plugin.
QDeclarativeImportedNamespace unqualifiedset
QDeclarativeTypeLoader * typeLoader
bool find(const QByteArray &type, int *vmajor, int *vminor, QDeclarativeType **type_return, QUrl *url_return, QString *errorString)
Data * data(const QString &) const
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition: qurl.cpp:5819
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
QMap< QString, QString > StringStringMap
#define qPrintable(string)
Definition: qglobal.h:1750
QList< QDeclarativeDirComponents > qmlDirComponents
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
#define INT_MAX
bool availableInVersion(int vmajor, int vminor) const
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition: qstring.h:712
QList< Plugin > plugins() const
The QDeclarativeImportDatabase class manages the QML imports for a QDeclarativeEngine.
The QPluginLoader class loads a plugin at run-time.
Definition: qpluginloader.h:62