forked from qt-creator/qt-creator
QmlProject: Add mainFile property
The mainFile property of QmlProject is the default file to run. People have still the opportunity to override this in their run settings, though. The wizard generated code was updated accordingly. Note that this makes projects generated by the wizard incompatible with QtCreator 2.1! Task-number: QTCREATORBUG-3249
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<export module="QmlProject" version="1.1" type="Project"/>
|
||||
</exports>
|
||||
<property name="sourceDirectory" type="string"/>
|
||||
<property name="mainFile" type="string"/>
|
||||
<property name="importPaths" type="string" isList="true"/>
|
||||
<property name="content" type="QmlProjectItem" isList="true"/>
|
||||
</type>
|
||||
|
||||
@@ -11,6 +11,7 @@ public:
|
||||
QString sourceDirectory;
|
||||
QStringList importPaths;
|
||||
QStringList absoluteImportPaths;
|
||||
QString mainFile;
|
||||
|
||||
QList<QmlFileFilterItem*> qmlFileFilters() const;
|
||||
|
||||
@@ -148,6 +149,21 @@ bool QmlProjectItem::matchesFile(const QString &filePath) const
|
||||
return false;
|
||||
}
|
||||
|
||||
QString QmlProjectItem::mainFile() const
|
||||
{
|
||||
Q_D(const QmlProjectItem);
|
||||
return d->mainFile;
|
||||
}
|
||||
|
||||
void QmlProjectItem::setMainFile(const QString &mainFilePath)
|
||||
{
|
||||
Q_D(QmlProjectItem);
|
||||
if (mainFilePath == d->mainFile)
|
||||
return;
|
||||
d->mainFile = mainFilePath;
|
||||
emit mainFileChanged();
|
||||
}
|
||||
|
||||
} // namespace QmlProjectManager
|
||||
|
||||
#include "qmlprojectitem.moc"
|
||||
|
||||
@@ -25,6 +25,7 @@ class QmlProjectItem : public QObject {
|
||||
Q_PROPERTY(QDeclarativeListProperty<QmlProjectManager::QmlProjectContentItem> content READ content DESIGNABLE false)
|
||||
Q_PROPERTY(QString sourceDirectory READ sourceDirectory NOTIFY sourceDirectoryChanged)
|
||||
Q_PROPERTY(QStringList importPaths READ importPaths WRITE setImportPaths NOTIFY importPathsChanged)
|
||||
Q_PROPERTY(QString mainFile READ mainFile WRITE setMainFile NOTIFY mainFileChanged)
|
||||
|
||||
Q_CLASSINFO("DefaultProperty", "content");
|
||||
|
||||
@@ -43,10 +44,15 @@ public:
|
||||
QStringList files() const;
|
||||
bool matchesFile(const QString &filePath) const;
|
||||
|
||||
QString mainFile() const;
|
||||
void setMainFile(const QString &mainFilePath);
|
||||
|
||||
|
||||
signals:
|
||||
void qmlFilesChanged(const QSet<QString> &, const QSet<QString> &);
|
||||
void sourceDirectoryChanged();
|
||||
void importPathsChanged();
|
||||
void mainFileChanged();
|
||||
|
||||
protected:
|
||||
QmlProjectItemPrivate *d_ptr;
|
||||
|
||||
@@ -158,6 +158,13 @@ QStringList QmlProject::files() const
|
||||
return files;
|
||||
}
|
||||
|
||||
QString QmlProject::mainFile() const
|
||||
{
|
||||
if (m_projectItem)
|
||||
return m_projectItem.data()->mainFile();
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool QmlProject::validProjectFile() const
|
||||
{
|
||||
return !m_projectItem.isNull();
|
||||
|
||||
@@ -95,6 +95,7 @@ public:
|
||||
|
||||
QDir projectDir() const;
|
||||
QStringList files() const;
|
||||
QString mainFile() const;
|
||||
QStringList importPaths() const;
|
||||
|
||||
bool addFiles(const QStringList &filePaths);
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "qmlprojectconstants.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <projectexplorer/customwizard/customwizard.h>
|
||||
#include <qt4projectmanager/qt4projectmanagerconstants.h>
|
||||
|
||||
@@ -39,6 +40,7 @@
|
||||
#include <QtGui/QPainter>
|
||||
#include <QtGui/QPixmap>
|
||||
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QTextStream>
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
@@ -141,12 +143,16 @@ Core::GeneratedFiles QmlProjectApplicationWizard::generateFiles(const QWizard *w
|
||||
|
||||
out
|
||||
//: Comment added to generated .qmlproject file
|
||||
<< "/* " << tr("File generated by QtCreator", "qmlproject Template") << " */" << endl
|
||||
<< "/* "
|
||||
<< tr("File generated by QtCreator, version %1",
|
||||
"qmlproject Template").arg(Core::Constants::IDE_VERSION_LONG) << " */" << endl
|
||||
<< endl
|
||||
<< "import QmlProject 1.0" << endl
|
||||
<< "import QmlProject 1.1" << endl
|
||||
<< endl
|
||||
<< "Project {" << endl
|
||||
//: Comment added to generated .qmlproject file
|
||||
<< " mainFile: \"" << QDir(projectPath).relativeFilePath(mainFileName) << "\"" << endl
|
||||
<< endl
|
||||
<< " /* " << tr("Include .qml, .js, and image files from current directory and subdirectories", "qmlproject Template") << " */" << endl
|
||||
<< " QmlFiles {" << endl
|
||||
<< " directory: \".\"" << endl
|
||||
|
||||
@@ -50,7 +50,7 @@ using namespace QmlProjectManager::Internal;
|
||||
|
||||
namespace QmlProjectManager {
|
||||
|
||||
const char * const M_CURRENT_FILE = "CurrentFile";
|
||||
const char * const M_CURRENT_FILE = "CurrentFile";
|
||||
|
||||
QmlProjectRunConfiguration::QmlProjectRunConfiguration(QmlProjectTarget *parent) :
|
||||
ProjectExplorer::RunConfiguration(parent, QLatin1String(Constants::QML_RC_ID)),
|
||||
@@ -67,12 +67,13 @@ QmlProjectRunConfiguration::QmlProjectRunConfiguration(QmlProjectTarget *parent,
|
||||
QmlProjectRunConfiguration *source) :
|
||||
ProjectExplorer::RunConfiguration(parent, source),
|
||||
m_qtVersionId(source->m_qtVersionId),
|
||||
m_scriptFile(source->m_scriptFile),
|
||||
m_qmlViewerArgs(source->m_qmlViewerArgs),
|
||||
m_projectTarget(parent),
|
||||
m_usingCurrentFile(source->m_usingCurrentFile),
|
||||
m_userEnvironmentChanges(source->m_userEnvironmentChanges)
|
||||
{
|
||||
ctor();
|
||||
setMainScript(source->m_scriptFile);
|
||||
updateQtVersions();
|
||||
}
|
||||
|
||||
@@ -191,29 +192,57 @@ ProjectExplorer::OutputFormatter *QmlProjectRunConfiguration::createOutputFormat
|
||||
return new Qt4ProjectManager::QtOutputFormatter(qmlTarget()->qmlProject());
|
||||
}
|
||||
|
||||
QString QmlProjectRunConfiguration::mainScript() const
|
||||
QmlProjectRunConfiguration::MainScriptSource QmlProjectRunConfiguration::mainScriptSource() const
|
||||
{
|
||||
if (m_usingCurrentFile)
|
||||
return m_currentFileFilename;
|
||||
|
||||
return m_mainScriptFilename;
|
||||
if (m_usingCurrentFile) {
|
||||
return FileInEditor;
|
||||
}
|
||||
if (!m_mainScriptFilename.isEmpty()) {
|
||||
return FileInSettings;
|
||||
}
|
||||
return FileInProjectFile;
|
||||
}
|
||||
|
||||
void QmlProjectRunConfiguration::setMainScript(const QString &scriptFile)
|
||||
/**
|
||||
Returns absolute path to main script file.
|
||||
*/
|
||||
QString QmlProjectRunConfiguration::mainScript() const
|
||||
{
|
||||
m_scriptFile = scriptFile;
|
||||
// replace with locale-agnostic string
|
||||
if (m_scriptFile == CURRENT_FILE)
|
||||
m_scriptFile = M_CURRENT_FILE;
|
||||
|
||||
if (m_scriptFile.isEmpty() || m_scriptFile == M_CURRENT_FILE) {
|
||||
m_usingCurrentFile = true;
|
||||
changeCurrentFile(Core::EditorManager::instance()->currentEditor());
|
||||
} else {
|
||||
m_usingCurrentFile = false;
|
||||
m_mainScriptFilename = qmlTarget()->qmlProject()->projectDir().absoluteFilePath(scriptFile);
|
||||
updateEnabled();
|
||||
if (m_usingCurrentFile) {
|
||||
return m_currentFileFilename;
|
||||
}
|
||||
|
||||
if (!m_mainScriptFilename.isEmpty()) {
|
||||
return m_mainScriptFilename;
|
||||
}
|
||||
|
||||
QString path = qmlTarget()->qmlProject()->mainFile();
|
||||
if (QFileInfo(path).isAbsolute()) {
|
||||
return path;
|
||||
} else {
|
||||
return qmlTarget()->qmlProject()->projectDir().absoluteFilePath(path);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProjectRunConfiguration::setScriptSource(MainScriptSource source,
|
||||
const QString &settingsPath)
|
||||
{
|
||||
if (source == FileInEditor) { m_scriptFile.clear();
|
||||
m_mainScriptFilename.clear();
|
||||
m_usingCurrentFile = true;
|
||||
} else if (source == FileInProjectFile) {
|
||||
m_scriptFile.clear();
|
||||
m_mainScriptFilename.clear();
|
||||
m_usingCurrentFile = false;
|
||||
} else { // FileInSettings
|
||||
m_scriptFile = settingsPath;
|
||||
m_mainScriptFilename
|
||||
= qmlTarget()->qmlProject()->projectDir().absoluteFilePath(m_scriptFile);
|
||||
m_usingCurrentFile = false;
|
||||
}
|
||||
updateEnabled();
|
||||
if (m_configurationWidget)
|
||||
m_configurationWidget.data()->updateFileComboBox();
|
||||
}
|
||||
|
||||
Utils::Environment QmlProjectRunConfiguration::environment() const
|
||||
@@ -245,7 +274,13 @@ bool QmlProjectRunConfiguration::fromMap(const QVariantMap &map)
|
||||
|
||||
|
||||
updateQtVersions();
|
||||
setMainScript(m_scriptFile);
|
||||
if (m_scriptFile == M_CURRENT_FILE) {
|
||||
setScriptSource(FileInEditor);
|
||||
} else if (m_scriptFile.isEmpty()) {
|
||||
setScriptSource(FileInProjectFile);
|
||||
} else {
|
||||
setScriptSource(FileInSettings, m_scriptFile);
|
||||
}
|
||||
|
||||
return RunConfiguration::fromMap(map);
|
||||
}
|
||||
@@ -284,7 +319,7 @@ void QmlProjectRunConfiguration::updateEnabled()
|
||||
}
|
||||
}
|
||||
} else { // use default one
|
||||
qmlFileFound = !m_mainScriptFilename.isEmpty();
|
||||
qmlFileFound = !mainScript().isEmpty();
|
||||
}
|
||||
|
||||
bool newValue = (QFileInfo(viewerPath()).exists()
|
||||
|
||||
@@ -81,8 +81,15 @@ public:
|
||||
int qtVersionId() const;
|
||||
Qt4ProjectManager::QtVersion *qtVersion() const;
|
||||
|
||||
enum MainScriptSource {
|
||||
FileInEditor,
|
||||
FileInProjectFile,
|
||||
FileInSettings
|
||||
};
|
||||
MainScriptSource mainScriptSource() const;
|
||||
void setScriptSource(MainScriptSource source, const QString &settingsPath = QString());
|
||||
|
||||
QString mainScript() const;
|
||||
void setMainScript(const QString &scriptFile);
|
||||
|
||||
Utils::Environment environment() const;
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
#include <QStringListModel>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
using Core::ICore;
|
||||
using Utils::DebuggerLanguageChooser;
|
||||
@@ -57,7 +57,7 @@ QmlProjectRunConfigurationWidget::QmlProjectRunConfigurationWidget(QmlProjectRun
|
||||
m_runConfiguration(rc),
|
||||
m_qtVersionComboBox(0),
|
||||
m_fileListCombo(0),
|
||||
m_fileListModel(new QStringListModel(this))
|
||||
m_fileListModel(new QStandardItemModel(this))
|
||||
{
|
||||
QVBoxLayout *layout = new QVBoxLayout(this);
|
||||
|
||||
@@ -76,7 +76,7 @@ QmlProjectRunConfigurationWidget::QmlProjectRunConfigurationWidget(QmlProjectRun
|
||||
m_fileListCombo = new QComboBox;
|
||||
m_fileListCombo->setModel(m_fileListModel);
|
||||
|
||||
connect(m_fileListCombo, SIGNAL(activated(QString)), this, SLOT(setMainScript(QString)));
|
||||
connect(m_fileListCombo, SIGNAL(activated(int)), this, SLOT(setMainScript(int)));
|
||||
connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(fileListChanged()),
|
||||
SLOT(updateFileComboBox()));
|
||||
|
||||
@@ -174,35 +174,73 @@ void QmlProjectRunConfigurationWidget::updateFileComboBox()
|
||||
{
|
||||
QmlProject *project = m_runConfiguration->qmlTarget()->qmlProject();
|
||||
QDir projectDir = project->projectDir();
|
||||
QStringList files;
|
||||
|
||||
files.append(CURRENT_FILE);
|
||||
int currentIndex = -1;
|
||||
m_fileListModel->clear();
|
||||
m_fileListModel->appendRow(new QStandardItem(CURRENT_FILE));
|
||||
QModelIndex currentIndex;
|
||||
QModelIndex fileInQmlProjectIndex;
|
||||
|
||||
const QString mainScriptInFilePath = projectDir.absoluteFilePath(project->mainFile());
|
||||
|
||||
QStringList sortedFiles = project->files();
|
||||
if (!sortedFiles.contains(mainScriptInFilePath))
|
||||
sortedFiles += mainScriptInFilePath;
|
||||
|
||||
// make paths relative to project directory
|
||||
QStringList relativeFiles;
|
||||
foreach (const QString &fn, sortedFiles) {
|
||||
relativeFiles += projectDir.relativeFilePath(fn);
|
||||
}
|
||||
sortedFiles = relativeFiles;
|
||||
|
||||
qStableSort(sortedFiles.begin(), sortedFiles.end(), caseInsensitiveLessThan);
|
||||
|
||||
QString mainScriptPath;
|
||||
if (m_runConfiguration->mainScriptSource() != QmlProjectRunConfiguration::FileInEditor)
|
||||
mainScriptPath = projectDir.relativeFilePath(m_runConfiguration->mainScript());
|
||||
|
||||
foreach (const QString &fn, sortedFiles) {
|
||||
QFileInfo fileInfo(fn);
|
||||
if (fileInfo.suffix() != QLatin1String("qml"))
|
||||
continue;
|
||||
|
||||
QString fileName = projectDir.relativeFilePath(fn);
|
||||
if (fileName == m_runConfiguration->m_scriptFile)
|
||||
currentIndex = files.size();
|
||||
QStandardItem *item = new QStandardItem(fn);
|
||||
m_fileListModel->appendRow(item);
|
||||
|
||||
files.append(fileName);
|
||||
if (mainScriptPath == fn)
|
||||
currentIndex = item->index();
|
||||
|
||||
if (mainScriptInFilePath == fn)
|
||||
fileInQmlProjectIndex = item->index();
|
||||
}
|
||||
m_fileListModel->setStringList(files);
|
||||
|
||||
if (currentIndex != -1)
|
||||
m_fileListCombo->setCurrentIndex(currentIndex);
|
||||
else
|
||||
if (currentIndex.isValid()) {
|
||||
m_fileListCombo->setCurrentIndex(currentIndex.row());
|
||||
} else {
|
||||
m_fileListCombo->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
if (fileInQmlProjectIndex.isValid()) {
|
||||
QFont font;
|
||||
font.setBold(true);
|
||||
m_fileListModel->setData(fileInQmlProjectIndex, font, Qt::FontRole);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProjectRunConfigurationWidget::setMainScript(const QString &file)
|
||||
void QmlProjectRunConfigurationWidget::setMainScript(int index)
|
||||
{
|
||||
m_runConfiguration->setMainScript(file);
|
||||
QmlProject *project = m_runConfiguration->qmlTarget()->qmlProject();
|
||||
QDir projectDir = project->projectDir();
|
||||
if (index == 0) {
|
||||
m_runConfiguration->setScriptSource(QmlProjectRunConfiguration::FileInEditor);
|
||||
} else {
|
||||
const QString path = m_fileListModel->data(m_fileListModel->index(index, 0)).toString();
|
||||
if (projectDir.relativeFilePath(project->mainFile()) == path) {
|
||||
m_runConfiguration->setScriptSource(QmlProjectRunConfiguration::FileInProjectFile);
|
||||
} else {
|
||||
m_runConfiguration->setScriptSource(QmlProjectRunConfiguration::FileInSettings, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProjectRunConfigurationWidget::onQtVersionSelectionChanged()
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <QWidget>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QComboBox);
|
||||
QT_FORWARD_DECLARE_CLASS(QStringListModel);
|
||||
QT_FORWARD_DECLARE_CLASS(QStandardItemModel);
|
||||
|
||||
namespace ProjectExplorer {
|
||||
|
||||
@@ -58,11 +58,11 @@ public:
|
||||
public slots:
|
||||
void updateQtVersionComboBox();
|
||||
void userEnvironmentChangesChanged();
|
||||
|
||||
private slots:
|
||||
void updateFileComboBox();
|
||||
|
||||
void setMainScript(const QString &file);
|
||||
private slots:
|
||||
|
||||
void setMainScript(int index);
|
||||
void onQtVersionSelectionChanged();
|
||||
void onViewerArgsChanged();
|
||||
void useCppDebuggerToggled(bool toggled);
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
|
||||
QComboBox *m_qtVersionComboBox;
|
||||
QComboBox *m_fileListCombo;
|
||||
QStringListModel *m_fileListModel;
|
||||
QStandardItemModel *m_fileListModel;
|
||||
|
||||
ProjectExplorer::EnvironmentWidget *m_environmentWidget;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,7 @@ private slots:
|
||||
void testFileFilter();
|
||||
void testMatchesFile();
|
||||
void testLibraryPaths();
|
||||
void testMainFile();
|
||||
};
|
||||
|
||||
tst_FileFormat::tst_FileFormat()
|
||||
@@ -334,6 +335,31 @@ void tst_FileFormat::testLibraryPaths()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_FileFormat::testMainFile()
|
||||
{
|
||||
//
|
||||
// search for qml files in local directory
|
||||
//
|
||||
QString projectFile = QLatin1String(
|
||||
"import QmlProject 1.1\n"
|
||||
"Project {\n"
|
||||
" mainFile: \"file1.qml\"\n"
|
||||
"}\n");
|
||||
|
||||
{
|
||||
QDeclarativeEngine engine;
|
||||
QDeclarativeComponent component(&engine);
|
||||
component.setData(projectFile.toUtf8(), QUrl());
|
||||
if (!component.isReady())
|
||||
qDebug() << component.errorString();
|
||||
QVERIFY(component.isReady());
|
||||
|
||||
QmlProjectItem *project = qobject_cast<QmlProjectItem*>(component.create());
|
||||
QVERIFY(project);
|
||||
|
||||
QCOMPARE(project->mainFile(), QString("file1.qml"));
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_FileFormat);
|
||||
#include "tst_fileformat.moc"
|
||||
|
||||
Reference in New Issue
Block a user