Commit 47155f85 authored by Kai Koehne's avatar Kai Koehne
Browse files

New qml based .qmproject file format

parent 10f48384
#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)
#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
HEADERS += $$PWD/qmlprojectitem.h \
$$PWD/filefilteritems.h
SOURCES += $$PWD/qmlprojectitem.cpp \
$$PWD/filefilteritems.cpp
#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"
#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
TEMPLATE = subdirs
SUBDIRS += qmleditor qmldesigner
SUBDIRS += qmleditor qmldesigner qmlprojectmanager
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
#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"
TEMPLATE = subdirs
SUBDIRS += fileformat
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment