forked from qt-creator/qt-creator
New qml based .qmproject file format
This commit is contained in:
121
src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
Normal file
121
src/plugins/qmlprojectmanager/fileformat/filefilteritems.cpp
Normal file
@@ -0,0 +1,121 @@
|
||||
#include "filefilteritems.h"
|
||||
#include <qdebug.h>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
FileFilterBaseItem::FileFilterBaseItem(QObject *parent) :
|
||||
QmlProjectContentItem(parent),
|
||||
m_recursive(false)
|
||||
{
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::directory() const
|
||||
{
|
||||
return m_rootDir;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setDirectory(const QString &dirPath)
|
||||
{
|
||||
if (m_rootDir == dirPath)
|
||||
return;
|
||||
m_rootDir = dirPath;
|
||||
emit directoryChanged();
|
||||
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setDefaultDirectory(const QString &dirPath)
|
||||
{
|
||||
if (m_defaultDir == dirPath)
|
||||
return;
|
||||
m_defaultDir = dirPath;
|
||||
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::filter() const
|
||||
{
|
||||
return m_filter;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setFilter(const QString &filter)
|
||||
{
|
||||
if (filter == m_filter)
|
||||
return;
|
||||
m_filter = filter;
|
||||
m_regex.setPattern(m_filter);
|
||||
m_regex.setPatternSyntax(QRegExp::Wildcard);
|
||||
|
||||
emit filterChanged();
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
bool FileFilterBaseItem::recursive() const
|
||||
{
|
||||
return m_recursive;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::setRecursive(bool recursive)
|
||||
{
|
||||
if (recursive == m_recursive)
|
||||
return;
|
||||
m_recursive = recursive;
|
||||
updateFileList();
|
||||
}
|
||||
|
||||
QStringList FileFilterBaseItem::files() const
|
||||
{
|
||||
return m_files.toList();
|
||||
}
|
||||
|
||||
QString FileFilterBaseItem::absoluteDir() const
|
||||
{
|
||||
QString absoluteDir;
|
||||
if (QFileInfo(m_rootDir).isAbsolute()) {
|
||||
absoluteDir = m_rootDir;
|
||||
} else if (!m_defaultDir.isEmpty()) {
|
||||
absoluteDir = m_defaultDir + QLatin1Char('/') + m_rootDir;
|
||||
}
|
||||
|
||||
return absoluteDir;
|
||||
}
|
||||
|
||||
void FileFilterBaseItem::updateFileList()
|
||||
{
|
||||
const QString dir = absoluteDir();
|
||||
if (dir.isEmpty())
|
||||
return;
|
||||
|
||||
const QSet<QString> newFiles = filesInSubTree(QDir(m_defaultDir), QDir(dir));
|
||||
if (newFiles != m_files) {
|
||||
m_files = newFiles;
|
||||
emit filesChanged();
|
||||
}
|
||||
}
|
||||
|
||||
QSet<QString> FileFilterBaseItem::filesInSubTree(const QDir &rootDir, const QDir &dir)
|
||||
{
|
||||
QSet<QString> fileSet;
|
||||
|
||||
foreach (const QFileInfo &file, dir.entryInfoList(QDir::Files)) {
|
||||
if (m_regex.exactMatch(file.fileName()))
|
||||
fileSet.insert(rootDir.relativeFilePath(file.absoluteFilePath()));
|
||||
}
|
||||
|
||||
if (m_recursive) {
|
||||
foreach (const QFileInfo &subDir, dir.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot)) {
|
||||
fileSet += filesInSubTree(rootDir, QDir(subDir.absoluteFilePath()));
|
||||
}
|
||||
}
|
||||
return fileSet;
|
||||
}
|
||||
|
||||
QmlFileFilterItem::QmlFileFilterItem(QObject *parent)
|
||||
: FileFilterBaseItem(parent)
|
||||
{
|
||||
setFilter(QLatin1String("*.qml"));
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
QML_DEFINE_TYPE(QmlProject,1,0,QmlFiles,QmlProjectManager::QmlFileFilterItem)
|
||||
72
src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
Normal file
72
src/plugins/qmlprojectmanager/fileformat/filefilteritems.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef FILEFILTERITEMS_H
|
||||
#define FILEFILTERITEMS_H
|
||||
|
||||
#include <QDir>
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
#include <qml.h>
|
||||
|
||||
#include "qmlprojectitem.h"
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class FileFilterBaseItem : public QmlProjectContentItem {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString directory READ directory WRITE setDirectory NOTIFY directoryChanged)
|
||||
Q_PROPERTY(bool recursive READ recursive WRITE setRecursive NOTIFY recursiveChanged)
|
||||
|
||||
Q_PROPERTY(QList<QString> files READ files NOTIFY filesChanged)
|
||||
|
||||
public:
|
||||
FileFilterBaseItem(QObject *parent = 0);
|
||||
|
||||
QString directory() const;
|
||||
void setDirectory(const QString &directoryPath);
|
||||
|
||||
void setDefaultDirectory(const QString &directoryPath);
|
||||
|
||||
QString filter() const;
|
||||
void setFilter(const QString &filter);
|
||||
|
||||
bool recursive() const;
|
||||
void setRecursive(bool recursive);
|
||||
|
||||
virtual QStringList files() const;
|
||||
|
||||
signals:
|
||||
void directoryChanged();
|
||||
void recursiveChanged();
|
||||
void filterChanged();
|
||||
void filesChanged();
|
||||
|
||||
private:
|
||||
QString absoluteDir() const;
|
||||
|
||||
void updateFileList();
|
||||
QSet<QString> filesInSubTree(const QDir &rootDir, const QDir &dir);
|
||||
|
||||
QString m_rootDir;
|
||||
QString m_defaultDir;
|
||||
|
||||
QString m_filter;
|
||||
QRegExp m_regex;
|
||||
bool m_recursive;
|
||||
|
||||
QSet<QString> m_files;
|
||||
|
||||
friend class ProjectItem;
|
||||
};
|
||||
|
||||
class QmlFileFilterItem : public FileFilterBaseItem {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlFileFilterItem(QObject *parent = 0);
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
QML_DECLARE_TYPE(QmlProjectManager::QmlFileFilterItem)
|
||||
|
||||
#endif // FILEFILTERITEMS_HPROJECTITEM_H
|
||||
4
src/plugins/qmlprojectmanager/fileformat/fileformat.pri
Normal file
4
src/plugins/qmlprojectmanager/fileformat/fileformat.pri
Normal file
@@ -0,0 +1,4 @@
|
||||
HEADERS += $$PWD/qmlprojectitem.h \
|
||||
$$PWD/filefilteritems.h
|
||||
SOURCES += $$PWD/qmlprojectitem.cpp \
|
||||
$$PWD/filefilteritems.cpp
|
||||
101
src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
Normal file
101
src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
#include "qmlprojectitem.h"
|
||||
#include "filefilteritems.h"
|
||||
#include <qdebug.h>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectItemPrivate : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QString sourceDirectory;
|
||||
|
||||
QList<QmlFileFilterItem*> qmlFileFilters() const;
|
||||
|
||||
// content property
|
||||
QmlConcreteList<QmlProjectContentItem*> content;
|
||||
};
|
||||
|
||||
QList<QmlFileFilterItem*> QmlProjectItemPrivate::qmlFileFilters() const
|
||||
{
|
||||
QList<QmlFileFilterItem*> qmlFilters;
|
||||
for (int i = 0; i < content.size(); ++i) {
|
||||
QmlProjectContentItem *contentElement = content.at(i);
|
||||
QmlFileFilterItem *qmlFileFilter = qobject_cast<QmlFileFilterItem*>(contentElement);
|
||||
if (qmlFileFilter) {
|
||||
qmlFilters << qmlFileFilter;
|
||||
}
|
||||
}
|
||||
return qmlFilters;
|
||||
}
|
||||
|
||||
QmlProjectItem::QmlProjectItem(QObject *parent) :
|
||||
QObject(parent),
|
||||
d_ptr(new QmlProjectItemPrivate)
|
||||
{
|
||||
// Q_D(QmlProjectItem);
|
||||
//
|
||||
// QmlFileFilter *defaultQmlFilter = new QmlFileFilter(this);
|
||||
// d->content.append(defaultQmlFilter);
|
||||
}
|
||||
|
||||
QmlProjectItem::~QmlProjectItem()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
QmlList<QmlProjectContentItem*> *QmlProjectItem::content()
|
||||
{
|
||||
Q_D(QmlProjectItem);
|
||||
return &d->content;
|
||||
}
|
||||
|
||||
QString QmlProjectItem::sourceDirectory() const
|
||||
{
|
||||
const Q_D(QmlProjectItem);
|
||||
return d->sourceDirectory;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setSourceDirectory(const QString &directoryPath)
|
||||
{
|
||||
Q_D(QmlProjectItem);
|
||||
|
||||
if (d->sourceDirectory == directoryPath)
|
||||
return;
|
||||
|
||||
d->sourceDirectory = directoryPath;
|
||||
|
||||
for (int i = 0; i < d->content.size(); ++i) {
|
||||
QmlProjectContentItem *contentElement = d->content.at(i);
|
||||
FileFilterBaseItem *fileFilter = qobject_cast<FileFilterBaseItem*>(contentElement);
|
||||
if (fileFilter)
|
||||
fileFilter->setDefaultDirectory(directoryPath);
|
||||
}
|
||||
|
||||
emit sourceDirectoryChanged();
|
||||
}
|
||||
|
||||
QStringList QmlProjectItem::qmlFiles() const
|
||||
{
|
||||
const Q_D(QmlProjectItem);
|
||||
QStringList qmlFiles;
|
||||
|
||||
for (int i = 0; i < d->content.size(); ++i) {
|
||||
QmlProjectContentItem *contentElement = d->content.at(i);
|
||||
QmlFileFilterItem *qmlFileFilter = qobject_cast<QmlFileFilterItem*>(contentElement);
|
||||
if (qmlFileFilter) {
|
||||
foreach (const QString &file, qmlFileFilter->files()) {
|
||||
if (!qmlFiles.contains(file))
|
||||
qmlFiles << file;
|
||||
}
|
||||
}
|
||||
}
|
||||
return qmlFiles;
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
QML_DEFINE_NOCREATE_TYPE(QmlProjectManager::QmlProjectContentItem)
|
||||
QML_DEFINE_TYPE(QmlProject,1,0,Project,QmlProjectManager::QmlProjectItem)
|
||||
|
||||
#include "qmlprojectitem.moc"
|
||||
55
src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
Normal file
55
src/plugins/qmlprojectmanager/fileformat/qmlprojectitem.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef PROJECTITEM_H
|
||||
#define PROJECTITEM_H
|
||||
|
||||
#include <QObject>
|
||||
#include <qml.h>
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
class QmlProjectContentItem : public QObject {
|
||||
// base class for all elements that should be direct children of Project element
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QmlProjectContentItem(QObject *parent = 0) : QObject(parent) {}
|
||||
};
|
||||
|
||||
class QmlProjectItemPrivate;
|
||||
|
||||
class QmlProjectItem : public QObject {
|
||||
Q_OBJECT
|
||||
Q_DECLARE_PRIVATE(QmlProjectItem)
|
||||
Q_DISABLE_COPY(QmlProjectItem)
|
||||
|
||||
Q_PROPERTY(QmlList<QmlProjectManager::QmlProjectContentItem*> *content READ content DESIGNABLE false)
|
||||
Q_PROPERTY(QString sourceDirectory READ sourceDirectory NOTIFY sourceDirectoryChanged)
|
||||
|
||||
Q_CLASSINFO("DefaultProperty", "content");
|
||||
|
||||
public:
|
||||
QmlProjectItem(QObject *parent = 0);
|
||||
~QmlProjectItem();
|
||||
|
||||
QmlList<QmlProjectContentItem*> *content();
|
||||
|
||||
QString sourceDirectory() const;
|
||||
void setSourceDirectory(const QString &directoryPath);
|
||||
|
||||
QStringList qmlFiles() const;
|
||||
|
||||
signals:
|
||||
void sourceDirectoryChanged();
|
||||
|
||||
protected:
|
||||
QmlProjectItemPrivate *d_ptr;
|
||||
|
||||
};
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
QML_DECLARE_TYPE(QmlProjectManager::QmlProjectItem);
|
||||
QML_DECLARE_TYPE(QmlProjectManager::QmlProjectContentItem);
|
||||
Q_DECLARE_METATYPE(QList<QmlProjectManager::QmlProjectContentItem *>);
|
||||
|
||||
|
||||
#endif // PROJECTITEM_H
|
||||
@@ -1,3 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += qmleditor qmldesigner
|
||||
SUBDIRS += qmleditor qmldesigner qmlprojectmanager
|
||||
|
||||
21
tests/auto/qml/qmlprojectmanager/fileformat/fileformat.pro
Normal file
21
tests/auto/qml/qmlprojectmanager/fileformat/fileformat.pro
Normal file
@@ -0,0 +1,21 @@
|
||||
TEMPLATE = app
|
||||
|
||||
CONFIG += qt warn_on console depend_includepath
|
||||
CONFIG -= app_bundle
|
||||
|
||||
QT += testlib \
|
||||
script \
|
||||
declarative
|
||||
|
||||
PLUGIN_DIR=../../../../../src/plugins/qmlprojectmanager
|
||||
|
||||
include($$PLUGIN_DIR/fileformat/fileformat.pri)
|
||||
|
||||
INCLUDEPATH += $$PLUGIN_DIR/fileformat
|
||||
|
||||
TARGET=tst_$$TARGET
|
||||
|
||||
DEFINES += SRCDIR=\\\"$$PWD\\\"
|
||||
|
||||
TEMPLATE = app
|
||||
SOURCES += tst_fileformat.cpp
|
||||
141
tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp
Normal file
141
tests/auto/qml/qmlprojectmanager/fileformat/tst_fileformat.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
#include "qmlprojectitem.h"
|
||||
#include "filefilteritems.h"
|
||||
#include <QmlComponent>
|
||||
#include <QmlContext>
|
||||
#include <QmlEngine>
|
||||
#include <QtTest>
|
||||
|
||||
using namespace QmlProjectManager;
|
||||
|
||||
class TestProject : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestProject();
|
||||
|
||||
private slots:
|
||||
void testQmlFileFilter();
|
||||
};
|
||||
|
||||
TestProject::TestProject()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString testDataDir = QLatin1String(SRCDIR "/data");
|
||||
|
||||
void TestProject::testQmlFileFilter()
|
||||
{
|
||||
//
|
||||
// search for qml files in local directory
|
||||
//
|
||||
QString projectFile = QLatin1String(
|
||||
"import QmlProject 1.0\n"
|
||||
"Project {\n"
|
||||
" QmlFiles {"
|
||||
" }"
|
||||
"}\n");
|
||||
|
||||
{
|
||||
QmlEngine engine;
|
||||
QmlComponent component(&engine);
|
||||
component.setData(projectFile.toUtf8(), QUrl());
|
||||
if (!component.isReady())
|
||||
qDebug() << component.errorsString();
|
||||
QVERIFY(component.isReady());
|
||||
|
||||
QmlProjectItem *project = qobject_cast<QmlProjectItem*>(component.create());
|
||||
QVERIFY(project);
|
||||
|
||||
project->setSourceDirectory(testDataDir);
|
||||
|
||||
QStringList expectedFiles(QStringList() << "file1.qml" << "file2.qml");
|
||||
QCOMPARE(project->qmlFiles().toSet(), expectedFiles.toSet());
|
||||
}
|
||||
|
||||
//
|
||||
// search for all qml files in all subdirectories
|
||||
//
|
||||
projectFile = QLatin1String(
|
||||
"import QmlProject 1.0\n"
|
||||
"Project {\n"
|
||||
" QmlFiles {\n"
|
||||
" recursive: true\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
{
|
||||
QmlEngine engine;
|
||||
QmlComponent component(&engine);
|
||||
component.setData(projectFile.toUtf8(), QUrl());
|
||||
QVERIFY(component.isReady());
|
||||
|
||||
QmlProjectItem *project = qobject_cast<QmlProjectItem*>(component.create());
|
||||
QVERIFY(project);
|
||||
|
||||
project->setSourceDirectory(testDataDir);
|
||||
|
||||
QStringList expectedFiles(QStringList() << "file1.qml" << "file2.qml" << "subdir/file3.qml");
|
||||
QCOMPARE(project->qmlFiles().toSet(), expectedFiles.toSet());
|
||||
}
|
||||
|
||||
//
|
||||
// search for all qml files in subdirectory
|
||||
//
|
||||
projectFile = QLatin1String(
|
||||
"import QmlProject 1.0\n"
|
||||
"Project {\n"
|
||||
" QmlFiles {\n"
|
||||
" directory: \"subdir\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
{
|
||||
QmlEngine engine;
|
||||
QmlComponent component(&engine);
|
||||
component.setData(projectFile.toUtf8(), QUrl());
|
||||
QVERIFY(component.isReady());
|
||||
|
||||
QmlProjectItem *project = qobject_cast<QmlProjectItem*>(component.create());
|
||||
QVERIFY(project);
|
||||
|
||||
project->setSourceDirectory(testDataDir);
|
||||
|
||||
QStringList expectedFiles(QStringList() << "subdir/file3.qml");
|
||||
QCOMPARE(project->qmlFiles().toSet(), expectedFiles.toSet());
|
||||
}
|
||||
|
||||
//
|
||||
// combination
|
||||
//
|
||||
projectFile = QLatin1String(
|
||||
"import QmlProject 1.0\n"
|
||||
"Project {\n"
|
||||
" QmlFiles {\n"
|
||||
" }"
|
||||
" QmlFiles {\n"
|
||||
" directory: \"subdir\"\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
|
||||
{
|
||||
QmlEngine engine;
|
||||
QmlComponent component(&engine);
|
||||
component.setData(projectFile.toUtf8(), QUrl());
|
||||
qDebug() << component.errorsString();
|
||||
QVERIFY(component.isReady());
|
||||
|
||||
QmlProjectItem *project = qobject_cast<QmlProjectItem*>(component.create());
|
||||
QVERIFY(project);
|
||||
|
||||
project->setSourceDirectory(testDataDir);
|
||||
|
||||
QStringList expectedFiles(QStringList() << "file1.qml" << "file2.qml" << "subdir/file3.qml");
|
||||
QCOMPARE(project->qmlFiles().size(), 3);
|
||||
QCOMPARE(project->qmlFiles().toSet(), expectedFiles.toSet());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(TestProject);
|
||||
#include "tst_fileformat.moc"
|
||||
3
tests/auto/qml/qmlprojectmanager/qmlprojectmanager.pro
Normal file
3
tests/auto/qml/qmlprojectmanager/qmlprojectmanager.pro
Normal file
@@ -0,0 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS += fileformat
|
||||
Reference in New Issue
Block a user