src/declarative/qml/qdeclarativeimport.cpp
changeset 37 758a864f9613
parent 33 3e2da88830cd
equal deleted inserted replaced
36:ef0373b55136 37:758a864f9613
   107     QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
   107     QSet<QString> qmlDirFilesForWhichPluginsHaveBeenLoaded;
   108     QDeclarativeImportedNamespace unqualifiedset;
   108     QDeclarativeImportedNamespace unqualifiedset;
   109     QHash<QString,QDeclarativeImportedNamespace* > set;
   109     QHash<QString,QDeclarativeImportedNamespace* > set;
   110 };
   110 };
   111 
   111 
       
   112 /*!
       
   113 \class QDeclarativeImports
       
   114 \brief The QDeclarativeImports class encapsulates one QML document's import statements.
       
   115 \internal
       
   116 */
   112 QDeclarativeImports::QDeclarativeImports(const QDeclarativeImports &copy) 
   117 QDeclarativeImports::QDeclarativeImports(const QDeclarativeImports &copy) 
   113 : d(copy.d)
   118 : d(copy.d)
   114 {
   119 {
   115     ++d->ref;
   120     ++d->ref;
   116 }
   121 }
   179     }
   184     }
   180 
   185 
   181     return cache;
   186     return cache;
   182 }
   187 }
   183 
   188 
   184 void QDeclarativeImports::cache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
   189 void QDeclarativeImports::populateCache(QDeclarativeTypeNameCache *cache, QDeclarativeEngine *engine) const
   185 {
   190 {
   186     const QDeclarativeImportedNamespace &set = d->unqualifiedset;
   191     const QDeclarativeImportedNamespace &set = d->unqualifiedset;
   187 
   192 
   188     for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
   193     for (QHash<QString,QDeclarativeImportedNamespace* >::ConstIterator iter = d->set.begin();
   189          iter != d->set.end(); ++iter) {
   194          iter != d->set.end(); ++iter) {
   199         }
   204         }
   200     }
   205     }
   201 
   206 
   202     cacheForNamespace(engine, set, cache);
   207     cacheForNamespace(engine, set, cache);
   203 }
   208 }
       
   209 
       
   210 /*!
       
   211   \internal
       
   212 
       
   213   The given (namespace qualified) \a type is resolved to either
       
   214   \list
       
   215   \o a QDeclarativeImportedNamespace stored at \a ns_return,
       
   216   \o a QDeclarativeType stored at \a type_return, or
       
   217   \o a component located at \a url_return.
       
   218   \endlist
       
   219 
       
   220   If any return pointer is 0, the corresponding search is not done.
       
   221 
       
   222   \sa addImport()
       
   223 */
       
   224 bool QDeclarativeImports::resolveType(const QByteArray& type, 
       
   225                                       QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
       
   226                                       QDeclarativeImportedNamespace** ns_return, QString *errorString) const
       
   227 {
       
   228     QDeclarativeImportedNamespace* ns = d->findNamespace(QString::fromUtf8(type));
       
   229     if (ns) {
       
   230         if (ns_return)
       
   231             *ns_return = ns;
       
   232         return true;
       
   233     }
       
   234     if (type_return || url_return) {
       
   235         if (d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
       
   236             if (qmlImportTrace()) {
       
   237                 if (type_return && *type_return && url_return && !url_return->isEmpty())
       
   238                     qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
       
   239                                        << type << " => " << (*type_return)->typeName() << " " << *url_return;
       
   240                 if (type_return && *type_return)
       
   241                     qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
       
   242                                        << type << " => " << (*type_return)->typeName();
       
   243                 if (url_return && !url_return->isEmpty())
       
   244                     qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::resolveType: " 
       
   245                                        << type << " => " << *url_return;
       
   246             }
       
   247             return true;
       
   248         }
       
   249     }
       
   250     return false;
       
   251 }
       
   252 
       
   253 /*!
       
   254   \internal
       
   255 
       
   256   Searching \e only in the namespace \a ns (previously returned in a call to
       
   257   resolveType(), \a type is found and returned to either
       
   258   a QDeclarativeType stored at \a type_return, or
       
   259   a component located at \a url_return.
       
   260 
       
   261   If either return pointer is 0, the corresponding search is not done.
       
   262 */
       
   263 bool QDeclarativeImports::resolveType(QDeclarativeImportedNamespace* ns, const QByteArray& type, 
       
   264                                       QDeclarativeType** type_return, QUrl* url_return, 
       
   265                                       int *vmaj, int *vmin) const
       
   266 {
       
   267     return ns->find(type,vmaj,vmin,type_return,url_return);
       
   268 }
       
   269 
   204 bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
   270 bool QDeclarativeImportedNamespace::find_helper(int i, const QByteArray& type, int *vmajor, int *vminor,
   205                                  QDeclarativeType** type_return, QUrl* url_return,
   271                                  QDeclarativeType** type_return, QUrl* url_return,
   206                                  QUrl *base, bool *typeRecursionDetected)
   272                                  QUrl *base, bool *typeRecursionDetected)
   207 {
   273 {
   208     int vmaj = majversions.at(i);
   274     int vmaj = majversions.at(i);
   278     foreach (QDeclarativeImportedNamespace* s, set.values())
   344     foreach (QDeclarativeImportedNamespace* s, set.values())
   279         delete s;
   345         delete s;
   280 }
   346 }
   281 
   347 
   282 bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, 
   348 bool QDeclarativeImportsPrivate::importExtension(const QString &absoluteFilePath, const QString &uri, 
   283                                                   QDeclarativeImportDatabase *database, 
   349                                                  QDeclarativeImportDatabase *database, 
   284                                                   QDeclarativeDirComponents* components, QString *errorString) 
   350                                                  QDeclarativeDirComponents* components, QString *errorString) 
   285 {
   351 {
   286     QFile file(absoluteFilePath);
   352     QFile file(absoluteFilePath);
   287     QString filecontent;
   353     QString filecontent;
   288     if (file.open(QFile::ReadOnly)) {
   354     if (file.open(QFile::ReadOnly)) {
   289         filecontent = QString::fromUtf8(file.readAll());
   355         filecontent = QString::fromUtf8(file.readAll());
   290         if (qmlImportTrace())
   356         if (qmlImportTrace())
   291             qDebug() << "QDeclarativeImportDatabase::add: loaded" << absoluteFilePath;
   357             qDebug().nospace() << "QDeclarativeImports(" << qPrintable(base.toString()) << "::importExtension: "
       
   358                                << "loaded " << absoluteFilePath;
   292     } else {
   359     } else {
   293         if (errorString)
   360         if (errorString)
   294             *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
   361             *errorString = QDeclarativeImportDatabase::tr("module \"%1\" definition \"%2\" not readable").arg(uri).arg(absoluteFilePath);
   295         return false;
   362         return false;
   296     }
   363     }
   336 
   403 
   337     QStringList paths = database->fileImportPath;
   404     QStringList paths = database->fileImportPath;
   338     qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents.
   405     qSort(paths.begin(), paths.end(), greaterThan); // Ensure subdirs preceed their parents.
   339 
   406 
   340     QString stableRelativePath = dir;
   407     QString stableRelativePath = dir;
   341     foreach( QString path, paths) {
   408     foreach(const QString &path, paths) {
   342         if (dir.startsWith(path)) {
   409         if (dir.startsWith(path)) {
   343             stableRelativePath = dir.mid(path.length()+1);
   410             stableRelativePath = dir.mid(path.length()+1);
   344             break;
   411             break;
   345         }
   412         }
   346     }
   413     }
   574             *errorString = QDeclarativeImportDatabase::tr("is not a type");
   641             *errorString = QDeclarativeImportDatabase::tr("is not a type");
   575     }
   642     }
   576     return false;
   643     return false;
   577 }
   644 }
   578 
   645 
       
   646 /*!
       
   647 \class QDeclarativeImportDatabase
       
   648 \brief The QDeclarativeImportDatabase class manages the QML imports for a QDeclarativeEngine.
       
   649 */
   579 QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e)
   650 QDeclarativeImportDatabase::QDeclarativeImportDatabase(QDeclarativeEngine *e)
   580 : engine(e)
   651 : engine(e)
   581 {
   652 {
   582     filePluginPath << QLatin1String(".");
   653     filePluginPath << QLatin1String(".");
   583 
   654 
   617   The \a prefix may be empty, in which case the import location is considered for
   688   The \a prefix may be empty, in which case the import location is considered for
   618   unqualified types.
   689   unqualified types.
   619 
   690 
   620   The base URL must already have been set with Import::setBaseUrl().
   691   The base URL must already have been set with Import::setBaseUrl().
   621 */
   692 */
   622 bool QDeclarativeImportDatabase::addToImport(QDeclarativeImports* imports, 
   693 bool QDeclarativeImports::addImport(QDeclarativeImportDatabase *importDb, 
   623                                              const QDeclarativeDirComponents &qmldircomponentsnetwork, 
   694                                     const QString& uri, const QString& prefix, int vmaj, int vmin, 
   624                                              const QString& uri, const QString& prefix, int vmaj, int vmin, 
   695                                     QDeclarativeScriptParser::Import::Type importType, 
   625                                              QDeclarativeScriptParser::Import::Type importType, 
   696                                     const QDeclarativeDirComponents &qmldircomponentsnetwork, 
   626                                              QString *errorString) 
   697                                     QString *errorString) 
   627 {
   698 {
   628     if (qmlImportTrace())
   699     if (qmlImportTrace())
   629         qDebug().nospace() << "QDeclarativeImportDatabase::addToImport " << imports << " " << uri << " " 
   700         qDebug().nospace() << "QDeclarativeImports(" << qPrintable(baseUrl().toString()) << ")" << "::addImport: " 
   630                            << vmaj << '.' << vmin << " " 
   701                            << uri << " " << vmaj << '.' << vmin << " " 
   631                            << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") 
   702                            << (importType==QDeclarativeScriptParser::Import::Library? "Library" : "File") 
   632                            << " as " << prefix;
   703                            << " as " << prefix;
   633 
   704 
   634     bool ok = imports->d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, this, errorString);
   705     return d->add(qmldircomponentsnetwork, uri, prefix, vmaj, vmin, importType, importDb, errorString);
   635     return ok;
       
   636 }
       
   637 
       
   638 /*!
       
   639   \internal
       
   640 
       
   641   Using the given \a imports, the given (namespace qualified) \a type is resolved to either
       
   642   a QDeclarativeImportedNamespace stored at \a ns_return,
       
   643   a QDeclarativeType stored at \a type_return, or
       
   644   a component located at \a url_return.
       
   645 
       
   646   If any return pointer is 0, the corresponding search is not done.
       
   647 
       
   648   \sa addToImport()
       
   649 */
       
   650 bool QDeclarativeImportDatabase::resolveType(const QDeclarativeImports& imports, const QByteArray& type, 
       
   651                                              QDeclarativeType** type_return, QUrl* url_return, int *vmaj, int *vmin,
       
   652                                              QDeclarativeImportedNamespace** ns_return, QString *errorString) const
       
   653 {
       
   654     QDeclarativeImportedNamespace* ns = imports.d->findNamespace(QString::fromUtf8(type));
       
   655     if (ns) {
       
   656         if (ns_return)
       
   657             *ns_return = ns;
       
   658         return true;
       
   659     }
       
   660     if (type_return || url_return) {
       
   661         if (imports.d->find(type,vmaj,vmin,type_return,url_return, errorString)) {
       
   662             if (qmlImportTrace()) {
       
   663                 if (type_return && *type_return && url_return && !url_return->isEmpty())
       
   664                     qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << (*type_return)->typeName() << *url_return;
       
   665                 if (type_return && *type_return)
       
   666                     qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << (*type_return)->typeName();
       
   667                 if (url_return && !url_return->isEmpty())
       
   668                     qDebug() << "QDeclarativeImportDatabase::resolveType" << type << '=' << *url_return;
       
   669             }
       
   670             return true;
       
   671         }
       
   672     }
       
   673     return false;
       
   674 }
       
   675 
       
   676 /*!
       
   677   \internal
       
   678 
       
   679   Searching \e only in the namespace \a ns (previously returned in a call to
       
   680   resolveType(), \a type is found and returned to either
       
   681   a QDeclarativeType stored at \a type_return, or
       
   682   a component located at \a url_return.
       
   683 
       
   684   If either return pointer is 0, the corresponding search is not done.
       
   685 */
       
   686 bool QDeclarativeImportDatabase::resolveTypeInNamespace(QDeclarativeImportedNamespace* ns, const QByteArray& type, 
       
   687                                                         QDeclarativeType** type_return, QUrl* url_return, 
       
   688                                                         int *vmaj, int *vmin) const
       
   689 {
       
   690     return ns->find(type,vmaj,vmin,type_return,url_return);
       
   691 }
   706 }
   692 
   707 
   693 /*!
   708 /*!
   694   \internal
   709   \internal
   695 
   710 
   832 }
   847 }
   833 
   848 
   834 void QDeclarativeImportDatabase::addPluginPath(const QString& path)
   849 void QDeclarativeImportDatabase::addPluginPath(const QString& path)
   835 {
   850 {
   836     if (qmlImportTrace())
   851     if (qmlImportTrace())
   837         qDebug() << "QDeclarativeImportDatabase::addPluginPath" << path;
   852         qDebug().nospace() << "QDeclarativeImportDatabase::addPluginPath: " << path;
   838 
   853 
   839     QUrl url = QUrl(path);
   854     QUrl url = QUrl(path);
   840     if (url.isRelative() || url.scheme() == QLatin1String("file")) {
   855     if (url.isRelative() || url.scheme() == QLatin1String("file")) {
   841         QDir dir = QDir(path);
   856         QDir dir = QDir(path);
   842         filePluginPath.prepend(dir.canonicalPath());
   857         filePluginPath.prepend(dir.canonicalPath());
   846 }
   861 }
   847 
   862 
   848 void QDeclarativeImportDatabase::addImportPath(const QString& path)
   863 void QDeclarativeImportDatabase::addImportPath(const QString& path)
   849 {
   864 {
   850     if (qmlImportTrace())
   865     if (qmlImportTrace())
   851         qDebug() << "QDeclarativeImportDatabase::addImportPath" << path;
   866         qDebug().nospace() << "QDeclarativeImportDatabase::addImportPath: " << path;
   852 
   867 
   853     if (path.isEmpty())
   868     if (path.isEmpty())
   854         return;
   869         return;
   855 
   870 
   856     QUrl url = QUrl(path);
   871     QUrl url = QUrl(path);
   880 
   895 
   881 
   896 
   882 bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
   897 bool QDeclarativeImportDatabase::importPlugin(const QString &filePath, const QString &uri, QString *errorString)
   883 {
   898 {
   884     if (qmlImportTrace())
   899     if (qmlImportTrace())
   885         qDebug() << "QDeclarativeImportDatabase::importPlugin" << uri << "from" << filePath;
   900         qDebug().nospace() << "QDeclarativeImportDatabase::importPlugin: " << uri << " from " << filePath;
   886 
   901 
   887     QFileInfo fileInfo(filePath);
   902     QFileInfo fileInfo(filePath);
   888     const QString absoluteFilePath = fileInfo.absoluteFilePath();
   903     const QString absoluteFilePath = fileInfo.absoluteFilePath();
   889 
   904 
   890     bool engineInitialized = initializedPlugins.contains(absoluteFilePath);
   905     bool engineInitialized = initializedPlugins.contains(absoluteFilePath);