Merge remote branch 'origin/2.0'

Conflicts:
	src/plugins/projectexplorer/taskwindow.cpp
	src/shared/proparser/profileevaluator.cpp
This commit is contained in:
con
2010-06-10 15:00:16 +02:00
57 changed files with 423 additions and 246 deletions

View File

@@ -76,7 +76,7 @@
</snippet> </snippet>
<snippet description="with targets">PropertyAction { targets: [<tab>name</tab>]; properties: "<tab>name</tab>" } <snippet description="with targets">PropertyAction { targets: [<tab>name</tab>]; properties: "<tab>name</tab>" }
</snippet> </snippet>
<snippet description="with target">PropertyAction { target: "<tab>name</tab>"; property: "<tab>name</tab>"; value: <tab>value</tab> } <snippet description="with target">PropertyAction { target: <tab>name</tab>; property: "<tab>name</tab>"; value: <tab>value</tab> }
</snippet> </snippet>
<snippet>PauseAnimation { duration: <tab>200</tab> } <snippet>PauseAnimation { duration: <tab>200</tab> }
</snippet> </snippet>

View File

@@ -53,7 +53,7 @@ const Interpreter::Value *Evaluate::operator()(AST::Node *ast)
const Value *result = reference(ast); const Value *result = reference(ast);
if (const Reference *ref = value_cast<const Reference *>(result)) if (const Reference *ref = value_cast<const Reference *>(result))
result = ref->value(_context); result = _context->lookupReference(ref);
if (! result) if (! result)
result = _engine->undefinedValue(); result = _engine->undefinedValue();

View File

@@ -1510,6 +1510,18 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QString
return objectValue; return objectValue;
} }
const Value *Context::lookupReference(const Reference *reference)
{
if (_referenceStack.contains(reference))
return 0;
_referenceStack.append(reference);
const Value *v = reference->value(this);
_referenceStack.removeLast();
return v;
}
const Value *Context::property(const ObjectValue *object, const QString &name) const const Value *Context::property(const ObjectValue *object, const QString &name) const
{ {
const Properties properties = _properties.value(object); const Properties properties = _properties.value(object);
@@ -1659,7 +1671,7 @@ const ObjectValue *ObjectValue::prototype(Context *context) const
const ObjectValue *prototypeObject = value_cast<const ObjectValue *>(_prototype); const ObjectValue *prototypeObject = value_cast<const ObjectValue *>(_prototype);
if (! prototypeObject) { if (! prototypeObject) {
if (const Reference *prototypeReference = value_cast<const Reference *>(_prototype)) { if (const Reference *prototypeReference = value_cast<const Reference *>(_prototype)) {
prototypeObject = value_cast<const ObjectValue *>(prototypeReference->value(context)); prototypeObject = value_cast<const ObjectValue *>(context->lookupReference(prototypeReference));
} }
} }
return prototypeObject; return prototypeObject;

View File

@@ -294,6 +294,7 @@ public:
const Value *lookup(const QString &name); const Value *lookup(const QString &name);
const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName); const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName);
const ObjectValue *lookupType(const Document *doc, const QStringList &qmlTypeName); const ObjectValue *lookupType(const Document *doc, const QStringList &qmlTypeName);
const Value *lookupReference(const Reference *reference);
const Value *property(const ObjectValue *object, const QString &name) const; const Value *property(const ObjectValue *object, const QString &name) const;
void setProperty(const ObjectValue *object, const QString &name, const Value *value); void setProperty(const ObjectValue *object, const QString &name, const Value *value);
@@ -314,6 +315,7 @@ private:
ScopeChain _scopeChain; ScopeChain _scopeChain;
int _qmlScopeObjectIndex; int _qmlScopeObjectIndex;
bool _qmlScopeObjectSet; bool _qmlScopeObjectSet;
QList<const Reference *> _referenceStack;
}; };
class QMLJS_EXPORT Reference: public Value class QMLJS_EXPORT Reference: public Value
@@ -323,14 +325,16 @@ public:
virtual ~Reference(); virtual ~Reference();
Engine *engine() const; Engine *engine() const;
virtual const Value *value(Context *context) const;
// Value interface // Value interface
virtual const Reference *asReference() const; virtual const Reference *asReference() const;
virtual void accept(ValueVisitor *) const; virtual void accept(ValueVisitor *) const;
private: private:
virtual const Value *value(Context *context) const;
Engine *_engine; Engine *_engine;
friend class Context;
}; };
class QMLJS_EXPORT ColorValue: public Value class QMLJS_EXPORT ColorValue: public Value
@@ -754,9 +758,9 @@ public:
AST::UiQualifiedId *qmlTypeName() const; AST::UiQualifiedId *qmlTypeName() const;
private:
virtual const Value *value(Context *context) const; virtual const Value *value(Context *context) const;
private:
AST::UiQualifiedId *_qmlTypeName; AST::UiQualifiedId *_qmlTypeName;
const Document *_doc; const Document *_doc;
}; };
@@ -769,6 +773,7 @@ public:
ASTVariableReference(AST::VariableDeclaration *ast, Engine *engine); ASTVariableReference(AST::VariableDeclaration *ast, Engine *engine);
virtual ~ASTVariableReference(); virtual ~ASTVariableReference();
private:
virtual const Value *value(Context *context) const; virtual const Value *value(Context *context) const;
}; };
@@ -804,6 +809,8 @@ public:
QString onChangedSlotName() const { return _onChangedSlotName; } QString onChangedSlotName() const { return _onChangedSlotName; }
virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
private:
virtual const Value *value(Context *context) const; virtual const Value *value(Context *context) const;
}; };
@@ -821,6 +828,8 @@ public:
QString slotName() const { return _slotName; } QString slotName() const { return _slotName; }
virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; virtual bool getSourceLocation(QString *fileName, int *line, int *column) const;
private:
virtual const Value *value(Context *context) const; virtual const Value *value(Context *context) const;
}; };

View File

@@ -80,7 +80,8 @@ CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, const QString
m_buildTarget(target), m_buildTarget(target),
m_workingDirectory(workingDirectory), m_workingDirectory(workingDirectory),
m_title(title), m_title(title),
m_baseEnvironmentBase(CMakeRunConfiguration::BuildEnvironmentBase) m_baseEnvironmentBase(CMakeRunConfiguration::BuildEnvironmentBase),
m_enabled(true)
{ {
ctor(); ctor();
} }
@@ -94,7 +95,8 @@ CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, CMakeRunConfig
m_title(source->m_title), m_title(source->m_title),
m_arguments(source->m_arguments), m_arguments(source->m_arguments),
m_userEnvironmentChanges(source->m_userEnvironmentChanges), m_userEnvironmentChanges(source->m_userEnvironmentChanges),
m_baseEnvironmentBase(source->m_baseEnvironmentBase) m_baseEnvironmentBase(source->m_baseEnvironmentBase),
m_enabled(source->m_enabled)
{ {
ctor(); ctor();
} }
@@ -293,9 +295,21 @@ ProjectExplorer::ToolChain::ToolChainType CMakeRunConfiguration::toolChainType()
return bc->toolChainType(); return bc->toolChainType();
} }
void CMakeRunConfiguration::setEnabled(bool b)
{
if (m_enabled == b)
return;
m_enabled = b;
emit isEnabledChanged(isEnabled());
setDisplayName(m_title + (m_enabled ? "" : tr(" (disabled)")));
}
bool CMakeRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *bc) const
{
return m_enabled && LocalApplicationRunConfiguration::isEnabled(bc);
}
// Configuration widget // Configuration widget
CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *cmakeRunConfiguration, QWidget *parent) CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *cmakeRunConfiguration, QWidget *parent)
: QWidget(parent), m_ignoreChange(false), m_cmakeRunConfiguration(cmakeRunConfiguration) : QWidget(parent), m_ignoreChange(false), m_cmakeRunConfiguration(cmakeRunConfiguration)
{ {

View File

@@ -81,6 +81,11 @@ public:
QVariantMap toMap() const; QVariantMap toMap() const;
void setEnabled(bool b);
bool isEnabled(ProjectExplorer::BuildConfiguration *bc) const;
using LocalApplicationRunConfiguration::isEnabled;
signals: signals:
void baseEnvironmentChanged(); void baseEnvironmentChanged();
void userEnvironmentChangesChanged(const QList<ProjectExplorer::EnvironmentItem> &diff); void userEnvironmentChangesChanged(const QList<ProjectExplorer::EnvironmentItem> &diff);
@@ -115,6 +120,7 @@ private:
QString m_arguments; QString m_arguments;
QList<ProjectExplorer::EnvironmentItem> m_userEnvironmentChanges; QList<ProjectExplorer::EnvironmentItem> m_userEnvironmentChanges;
BaseEnvironmentBase m_baseEnvironmentBase; BaseEnvironmentBase m_baseEnvironmentBase;
bool m_enabled;
}; };
class CMakeRunConfigurationWidget : public QWidget class CMakeRunConfigurationWidget : public QWidget

View File

@@ -120,6 +120,7 @@ void CMakeTarget::updateRunConfigurations()
foreach (CMakeRunConfiguration *rc, list) { foreach (CMakeRunConfiguration *rc, list) {
rc->setExecutable(ct.executable); rc->setExecutable(ct.executable);
rc->setWorkingDirectory(ct.workingDirectory); rc->setWorkingDirectory(ct.workingDirectory);
rc->setEnabled(true);
} }
existingRunConfigurations.remove(ct.title); existingRunConfigurations.remove(ct.title);
} else { } else {
@@ -131,7 +132,10 @@ void CMakeTarget::updateRunConfigurations()
existingRunConfigurations.constBegin(); existingRunConfigurations.constBegin();
for( ; it != existingRunConfigurations.constEnd(); ++it) { for( ; it != existingRunConfigurations.constEnd(); ++it) {
CMakeRunConfiguration *rc = it.value(); CMakeRunConfiguration *rc = it.value();
removeRunConfiguration(rc); // The executables for those runconfigurations aren't build by the current buildconfiguration
// We just set a disable flag and show that in the display name
rc->setEnabled(false);
// removeRunConfiguration(rc);
} }
if (runConfigurations().isEmpty()) { if (runConfigurations().isEmpty()) {
// Oh no, no run configuration, // Oh no, no run configuration,

View File

@@ -38,6 +38,7 @@
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <utils/filewizarddialog.h> #include <utils/filewizarddialog.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stringutils.h>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QFile> #include <QtCore/QFile>
@@ -540,7 +541,7 @@ QStringList BaseFileWizard::runWizard(const QString &path, QWidget *parent)
foreach (const GeneratedFile &generatedFile, files) foreach (const GeneratedFile &generatedFile, files)
result.push_back(generatedFile.path()); result.push_back(generatedFile.path());
switch (promptOverwrite(path, result, &errorMessage)) { switch (promptOverwrite(result, &errorMessage)) {
case OverwriteCanceled: case OverwriteCanceled:
return QStringList(); return QStringList();
case OverwriteError: case OverwriteError:
@@ -615,29 +616,34 @@ bool BaseFileWizard::postGenerateOpenEditors(const GeneratedFiles &l, QString *e
return true; return true;
} }
BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QString &location, BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QStringList &files,
const QStringList &files,
QString *errorMessage) const QString *errorMessage) const
{ {
if (debugWizard) if (debugWizard)
qDebug() << Q_FUNC_INFO << location << files; qDebug() << Q_FUNC_INFO << files;
bool existingFilesFound = false; QStringList existingFiles;
bool oddStuffFound = false; bool oddStuffFound = false;
static const QString readOnlyMsg = tr(" [read only]"); static const QString readOnlyMsg = tr(" [read only]");
static const QString directoryMsg = tr(" [directory]"); static const QString directoryMsg = tr(" [directory]");
static const QString symLinkMsg = tr(" [symbolic link]"); static const QString symLinkMsg = tr(" [symbolic link]");
// Format a file list message as ( "<file1> [readonly], <file2> [directory]").
QString fileNamesMsgPart;
foreach (const QString &fileName, files) { foreach (const QString &fileName, files) {
const QFileInfo fi(fileName);
if (fi.exists())
existingFiles.append(fileName);
}
// Note: Generated files are using native separators, no need to convert.
const QString commonExistingPath = Utils::commonPath(existingFiles);
// Format a file list message as ( "<file1> [readonly], <file2> [directory]").
QString fileNamesMsgPart;
foreach (const QString &fileName, existingFiles) {
const QFileInfo fi(fileName); const QFileInfo fi(fileName);
if (fi.exists()) { if (fi.exists()) {
existingFilesFound = true;
if (!fileNamesMsgPart.isEmpty()) if (!fileNamesMsgPart.isEmpty())
fileNamesMsgPart += QLatin1String(", "); fileNamesMsgPart += QLatin1String(", ");
fileNamesMsgPart += fi.fileName(); fileNamesMsgPart += fileName.mid(commonExistingPath.size() + 1);
do { do {
if (fi.isDir()) { if (fi.isDir()) {
oddStuffFound = true; oddStuffFound = true;
@@ -657,17 +663,17 @@ BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QString &l
} }
} }
if (!existingFilesFound) if (existingFiles.isEmpty())
return OverwriteOk; return OverwriteOk;
if (oddStuffFound) { if (oddStuffFound) {
*errorMessage = tr("The project directory %1 contains files which cannot be overwritten:\n%2.").arg(location).arg(fileNamesMsgPart); *errorMessage = tr("The project directory %1 contains files which cannot be overwritten:\n%2.").arg(commonExistingPath).arg(fileNamesMsgPart);
return OverwriteError; return OverwriteError;
} }
const QString messageFormat = tr("The following files already exist in the directory %1:\n" const QString messageFormat = tr("The following files already exist in the directory %1:\n"
"%2.\nWould you like to overwrite them?"); "%2.\nWould you like to overwrite them?");
const QString message = messageFormat.arg(location).arg(fileNamesMsgPart); const QString message = messageFormat.arg(commonExistingPath).arg(fileNamesMsgPart);
const bool yes = (QMessageBox::question(Core::ICore::instance()->mainWindow(), const bool yes = (QMessageBox::question(Core::ICore::instance()->mainWindow(),
tr("Existing files"), message, tr("Existing files"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,

View File

@@ -210,8 +210,7 @@ protected:
// Utility that performs an overwrite check on a set of files. It checks if // Utility that performs an overwrite check on a set of files. It checks if
// the file exists, can be overwritten at all and prompts the user. // the file exists, can be overwritten at all and prompts the user.
enum OverwriteResult { OverwriteOk, OverwriteError, OverwriteCanceled }; enum OverwriteResult { OverwriteOk, OverwriteError, OverwriteCanceled };
OverwriteResult promptOverwrite(const QString &location, OverwriteResult promptOverwrite(const QStringList &files,
const QStringList &files,
QString *errorMessage) const; QString *errorMessage) const;
// Utility to open the editors for the files whose attribute is set accordingly. // Utility to open the editors for the files whose attribute is set accordingly.

View File

@@ -61,6 +61,11 @@ CoreImpl::CoreImpl(MainWindow *mainwindow)
m_mainwindow = mainwindow; m_mainwindow = mainwindow;
} }
CoreImpl::~CoreImpl()
{
m_instance = 0;
}
QStringList CoreImpl::showNewItemDialog(const QString &title, QStringList CoreImpl::showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards, const QList<IWizard *> &wizards,
const QString &defaultLocation) const QString &defaultLocation)

View File

@@ -42,7 +42,7 @@ class CoreImpl : public ICore
public: public:
CoreImpl(MainWindow *mainwindow); CoreImpl(MainWindow *mainwindow);
~CoreImpl() {} ~CoreImpl();
QStringList showNewItemDialog(const QString &title, QStringList showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards, const QList<IWizard *> &wizards,

View File

@@ -90,7 +90,6 @@ struct FileIconProviderPrivate {
// Mapping of file suffix to icon. // Mapping of file suffix to icon.
StringIconPairList m_cache; StringIconPairList m_cache;
QFileIconProvider m_systemIconProvider;
QIcon m_unknownFileIcon; QIcon m_unknownFileIcon;
// singleton pattern // singleton pattern
@@ -140,25 +139,15 @@ QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const
} }
// Get icon from OS. // Get icon from OS.
#if defined(Q_WS_WIN) || defined(Q_WS_MAC) #if defined(Q_WS_WIN) || defined(Q_WS_MAC)
return d->m_systemIconProvider.icon(fileInfo); return QFileIconProvider::icon(fileInfo);
#else #else
// File icons are unknown on linux systems. // File icons are unknown on linux systems.
return (fileInfo.isDir()) ? return (fileInfo.isDir()) ?
d->m_systemIconProvider.icon(fileInfo) : QFileIconProvider::icon(fileInfo) :
d->m_unknownFileIcon; d->m_unknownFileIcon;
#endif #endif
} }
QIcon FileIconProvider::icon(IconType type) const
{
return d->m_systemIconProvider.icon(type);
}
QString FileIconProvider::type(const QFileInfo &info) const
{
return d->m_systemIconProvider.type(info);
}
/*! /*!
Creates a pixmap with baseicon at size and overlays overlayIcon over it. Creates a pixmap with baseicon at size and overlays overlayIcon over it.
See platform note in class documentation about recommended usage. See platform note in class documentation about recommended usage.

View File

@@ -56,9 +56,8 @@ public:
virtual ~FileIconProvider(); virtual ~FileIconProvider();
// Implement QFileIconProvider // Implement QFileIconProvider
virtual QIcon icon(IconType type) const;
virtual QIcon icon(const QFileInfo &info) const; virtual QIcon icon(const QFileInfo &info) const;
virtual QString type(const QFileInfo &info) const; using QFileIconProvider::icon;
// Register additional overlay icons // Register additional overlay icons
static QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size); static QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size);

View File

@@ -704,50 +704,6 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable)
static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1); static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1);
} }
void CPPEditor::inAllRenameSelections(EditOperation operation,
const QTextEdit::ExtraSelection &currentRenameSelection,
QTextCursor cursor,
const QString &text)
{
cursor.beginEditBlock();
const int startOffset = cursor.selectionStart() - currentRenameSelection.cursor.anchor();
const int endOffset = cursor.selectionEnd() - currentRenameSelection.cursor.anchor();
const int length = endOffset - startOffset;
for (int i = 0; i < m_renameSelections.size(); ++i) {
QTextEdit::ExtraSelection &s = m_renameSelections[i];
int pos = s.cursor.anchor();
int endPos = s.cursor.position();
s.cursor.setPosition(pos + startOffset);
s.cursor.setPosition(pos + endOffset, QTextCursor::KeepAnchor);
switch (operation) {
case DeletePreviousChar:
s.cursor.deletePreviousChar();
endPos -= qMax(1, length);
break;
case DeleteChar:
s.cursor.deleteChar();
endPos -= qMax(1, length);
break;
case InsertText:
s.cursor.insertText(text);
endPos += text.length() - length;
break;
}
s.cursor.setPosition(pos);
s.cursor.setPosition(endPos, QTextCursor::KeepAnchor);
}
cursor.endEditBlock();
setExtraSelections(CodeSemanticsSelection, m_renameSelections);
setTextCursor(cursor);
}
void CPPEditor::paste() void CPPEditor::paste()
{ {
if (m_currentRenameSelection == -1) { if (m_currentRenameSelection == -1) {

View File

@@ -268,15 +268,6 @@ private:
void createToolBar(CPPEditorEditable *editable); void createToolBar(CPPEditorEditable *editable);
enum EditOperation {
DeleteChar,
DeletePreviousChar,
InsertText
};
void inAllRenameSelections(EditOperation operation,
const QTextEdit::ExtraSelection &currentRenameSelection,
QTextCursor cursor,
const QString &text = QString());
void startRename(); void startRename();
void finishRename(); void finishRename();
void abortRename(); void abortRename();

View File

@@ -82,8 +82,8 @@ void AbstractProcessStep::setOutputParser(ProjectExplorer::IOutputParser *parser
m_outputParserChain = parser; m_outputParserChain = parser;
if (m_outputParserChain) { if (m_outputParserChain) {
connect(parser, SIGNAL(addOutput(QString)), connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(outputAdded(QString))); this, SLOT(outputAdded(QString, QTextCharFormat)));
connect(parser, SIGNAL(addTask(ProjectExplorer::Task)), connect(parser, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(taskAdded(ProjectExplorer::Task))); this, SLOT(taskAdded(ProjectExplorer::Task)));
} }
@@ -199,22 +199,34 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi)
void AbstractProcessStep::processStarted() void AbstractProcessStep::processStarted()
{ {
emit addOutput(tr("<font color=\"#0000ff\">Starting: \"%1\" %2</font>\n").arg(m_command, Qt::escape(m_arguments.join(" ")))); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::blue);
emit addOutput(tr("Starting: \"%1\" %2\n").arg(m_command, m_arguments.join(" ")), textCharFormat);
} }
void AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status) void AbstractProcessStep::processFinished(int exitCode, QProcess::ExitStatus status)
{ {
if (status == QProcess::NormalExit && exitCode == 0) QTextCharFormat textCharFormat;
emit addOutput(tr("<font color=\"#0000ff\">The process \"%1\" exited normally.</font>").arg(m_command)); if (status == QProcess::NormalExit && exitCode == 0) {
else if (status == QProcess::NormalExit) textCharFormat.setForeground(Qt::blue);
emit addOutput(tr("<font color=\"#ff0000\"><b>The process \"%1\" exited with code %2.</b></font>").arg(m_command, m_process->exitCode())); emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), textCharFormat);
else } else if (status == QProcess::NormalExit) {
emit addOutput(tr("<font color=\"#ff0000\"><b>The process \"%1\" crashed.</b></font>").arg(m_command)); textCharFormat.setForeground(Qt::red);
textCharFormat.setFontWeight(QFont::Bold);
emit addOutput(tr("The process \"%1\" exited with code %2.").arg(m_command, m_process->exitCode()), textCharFormat);
} else {
textCharFormat.setForeground(Qt::red);
textCharFormat.setFontWeight(QFont::Bold);
emit addOutput(tr("The process \"%1\" crashed.").arg(m_command), textCharFormat);
}
} }
void AbstractProcessStep::processStartupFailed() void AbstractProcessStep::processStartupFailed()
{ {
emit addOutput(tr("<font color=\"#ff0000\"><b>Could not start process \"%1\"</b></font>").arg(m_command)); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::red);
textCharFormat.setFontWeight(QFont::Bold);
emit addOutput(tr("Could not start process \"%1\"").arg(m_command), textCharFormat);
} }
bool AbstractProcessStep::processSucceeded(int exitCode, QProcess::ExitStatus status) bool AbstractProcessStep::processSucceeded(int exitCode, QProcess::ExitStatus status)
@@ -235,7 +247,8 @@ void AbstractProcessStep::stdOutput(const QString &line)
{ {
if (m_outputParserChain) if (m_outputParserChain)
m_outputParserChain->stdOutput(line); m_outputParserChain->stdOutput(line);
emit addOutput(Qt::escape(line)); QTextCharFormat textCharFormat;
emit addOutput(Qt::escape(line), textCharFormat);
} }
void AbstractProcessStep::processReadyReadStdError() void AbstractProcessStep::processReadyReadStdError()
@@ -251,7 +264,9 @@ void AbstractProcessStep::stdError(const QString &line)
{ {
if (m_outputParserChain) if (m_outputParserChain)
m_outputParserChain->stdError(line); m_outputParserChain->stdError(line);
emit addOutput(QLatin1String("<font color=\"#ff0000\">") + Qt::escape(line) + QLatin1String("</font>")); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::red);
emit addOutput(line, textCharFormat);
} }
void AbstractProcessStep::checkForCancel() void AbstractProcessStep::checkForCancel()
@@ -312,9 +327,9 @@ void AbstractProcessStep::taskAdded(const ProjectExplorer::Task &task)
emit addTask(editable); emit addTask(editable);
} }
void AbstractProcessStep::outputAdded(const QString &string) void AbstractProcessStep::outputAdded(const QString &string, const QTextCharFormat &textCharFormat)
{ {
emit addOutput(string); emit addOutput(string, textCharFormat);
} }
void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus) void AbstractProcessStep::slotProcessFinished(int, QProcess::ExitStatus)

View File

@@ -147,8 +147,8 @@ private slots:
void checkForCancel(); void checkForCancel();
void taskAdded(const ProjectExplorer::Task &task); void taskAdded(const ProjectExplorer::Task &task);
void outputAdded(const QString &string);
void outputAdded(const QString &string, const QTextCharFormat &format);
private: private:
QTimer *m_timer; QTimer *m_timer;
QFutureInterface<bool> *m_futureInterface; QFutureInterface<bool> *m_futureInterface;

View File

@@ -180,7 +180,9 @@ void BuildManager::finish()
void BuildManager::emitCancelMessage() void BuildManager::emitCancelMessage()
{ {
emit addToOutputWindow(tr("<font color=\"#ff0000\">Canceled build.</font>")); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::red);
emit addToOutputWindow(tr("Canceled build."), textCharFormat);
} }
void BuildManager::clearBuildQueue() void BuildManager::clearBuildQueue()
@@ -196,6 +198,7 @@ void BuildManager::clearBuildQueue()
m_buildQueue.clear(); m_buildQueue.clear();
m_running = false; m_running = false;
m_previousBuildStepProject = 0; m_previousBuildStepProject = 0;
m_currentBuildStep = 0;
m_progressFutureInterface->reportCanceled(); m_progressFutureInterface->reportCanceled();
m_progressFutureInterface->reportFinished(); m_progressFutureInterface->reportFinished();
@@ -282,9 +285,9 @@ void BuildManager::addToTaskWindow(const ProjectExplorer::Task &task)
m_taskWindow->addTask(task); m_taskWindow->addTask(task);
} }
void BuildManager::addToOutputWindow(const QString &string) void BuildManager::addToOutputWindow(const QString &string, const QTextCharFormat &format)
{ {
m_outputWindow->appendText(string); m_outputWindow->appendText(string, format);
} }
void BuildManager::nextBuildQueue() void BuildManager::nextBuildQueue()
@@ -294,8 +297,8 @@ void BuildManager::nextBuildQueue()
disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::Task)), disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(addToTaskWindow(ProjectExplorer::Task))); this, SLOT(addToTaskWindow(ProjectExplorer::Task)));
disconnect(m_currentBuildStep, SIGNAL(addOutput(QString)), disconnect(m_currentBuildStep, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(addToOutputWindow(QString))); this, SLOT(addToOutputWindow(QString, QTextCharFormat)));
++m_progress; ++m_progress;
m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress)); m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress));
@@ -306,8 +309,10 @@ void BuildManager::nextBuildQueue()
// Build Failure // Build Failure
const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName(); const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName();
const QString targetName = m_currentBuildStep->buildConfiguration()->target()->displayName(); const QString targetName = m_currentBuildStep->buildConfiguration()->target()->displayName();
addToOutputWindow(tr("<font color=\"#ff0000\">Error while building project %1 (target: %2)</font>").arg(projectName, targetName)); QTextCharFormat textCharFormat;
addToOutputWindow(tr("<font color=\"#ff0000\">When executing build step '%1'</font>").arg(m_currentBuildStep->displayName())); textCharFormat.setForeground(Qt::red);
addToOutputWindow(tr("Error while building project %1 (target: %2)").arg(projectName, targetName), textCharFormat);
addToOutputWindow(tr("When executing build step '%1'").arg(m_currentBuildStep->displayName()), textCharFormat);
// NBS TODO fix in qtconcurrent // NBS TODO fix in qtconcurrent
m_progressFutureInterface->setProgressValueAndText(m_progress*100, tr("Error while building project %1 (target: %2)").arg(projectName, targetName)); m_progressFutureInterface->setProgressValueAndText(m_progress*100, tr("Error while building project %1 (target: %2)").arg(projectName, targetName));
} }
@@ -337,8 +342,10 @@ void BuildManager::nextStep()
if (m_currentBuildStep->buildConfiguration()->target()->project() != m_previousBuildStepProject) { if (m_currentBuildStep->buildConfiguration()->target()->project() != m_previousBuildStepProject) {
const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName(); const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName();
addToOutputWindow(tr("<b>Running build steps for project %2...</b>") QTextCharFormat textCharFormat;
.arg(projectName)); textCharFormat.setFontWeight(QFont::Bold);
addToOutputWindow(tr("Running build steps for project %2...")
.arg(projectName), textCharFormat);
m_previousBuildStepProject = m_currentBuildStep->buildConfiguration()->target()->project(); m_previousBuildStepProject = m_currentBuildStep->buildConfiguration()->target()->project();
} }
m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep)); m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep));
@@ -347,6 +354,7 @@ void BuildManager::nextStep()
m_previousBuildStepProject = 0; m_previousBuildStepProject = 0;
m_progressFutureInterface->reportFinished(); m_progressFutureInterface->reportFinished();
m_progressWatcher.setFuture(QFuture<void>()); m_progressWatcher.setFuture(QFuture<void>());
m_currentBuildStep = 0;
delete m_progressFutureInterface; delete m_progressFutureInterface;
m_progressFutureInterface = 0; m_progressFutureInterface = 0;
m_maxProgress = 0; m_maxProgress = 0;
@@ -363,8 +371,8 @@ bool BuildManager::buildQueueAppend(QList<BuildStep *> steps)
BuildStep *bs = steps.at(i); BuildStep *bs = steps.at(i);
connect(bs, SIGNAL(addTask(ProjectExplorer::Task)), connect(bs, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(addToTaskWindow(ProjectExplorer::Task))); this, SLOT(addToTaskWindow(ProjectExplorer::Task)));
connect(bs, SIGNAL(addOutput(QString)), connect(bs, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(addToOutputWindow(QString))); this, SLOT(addToOutputWindow(QString, QTextCharFormat)));
init = bs->init(); init = bs->init();
if (!init) if (!init)
break; break;
@@ -376,16 +384,18 @@ bool BuildManager::buildQueueAppend(QList<BuildStep *> steps)
// print something for the user // print something for the user
const QString projectName = bs->buildConfiguration()->target()->project()->displayName(); const QString projectName = bs->buildConfiguration()->target()->project()->displayName();
const QString targetName = bs->buildConfiguration()->target()->displayName(); const QString targetName = bs->buildConfiguration()->target()->displayName();
addToOutputWindow(tr("<font color=\"#ff0000\">Error while building project %1 (target: %2)</font>").arg(projectName, targetName)); QTextCharFormat textCharFormat;
addToOutputWindow(tr("<font color=\"#ff0000\">When executing build step '%1'</font>").arg(bs->displayName())); textCharFormat.setForeground(Qt::red);
addToOutputWindow(tr("Error while building project %1 (target: %2)").arg(projectName, targetName), textCharFormat);
addToOutputWindow(tr("When executing build step '%1'").arg(bs->displayName()), textCharFormat);
// disconnect the buildsteps again // disconnect the buildsteps again
for (int j = 0; j <= i; ++j) { for (int j = 0; j <= i; ++j) {
BuildStep *bs = steps.at(j); BuildStep *bs = steps.at(j);
disconnect(bs, SIGNAL(addTask(ProjectExplorer::Task)), disconnect(bs, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(addToTaskWindow(ProjectExplorer::Task))); this, SLOT(addToTaskWindow(ProjectExplorer::Task)));
disconnect(bs, SIGNAL(addOutput(QString)), disconnect(bs, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(addToOutputWindow(QString))); this, SLOT(addToOutputWindow(QString, QTextCharFormat)));
} }
return false; return false;
} }

View File

@@ -95,7 +95,7 @@ signals:
private slots: private slots:
void addToTaskWindow(const ProjectExplorer::Task &task); void addToTaskWindow(const ProjectExplorer::Task &task);
void addToOutputWindow(const QString &string); void addToOutputWindow(const QString &string, const QTextCharFormat &textCharFormat);
void nextBuildQueue(); void nextBuildQueue();
void progressChanged(); void progressChanged();

View File

@@ -105,8 +105,8 @@ signals:
void addTask(const ProjectExplorer::Task &task); void addTask(const ProjectExplorer::Task &task);
// The string is added to the generated output, usually in the output // The string is added to the generated output, usually in the output
// window. // window.
// It should be in html format, that is properly escaped // It should be in plain text, with the format in the parameter
void addOutput(const QString &string); void addOutput(const QString &string, const QTextCharFormat &textCharFormat);
private: private:
BuildConfiguration *m_buildConfiguration; BuildConfiguration *m_buildConfiguration;

View File

@@ -52,6 +52,8 @@ CompileOutputWindow::CompileOutputWindow(BuildManager * /*bm*/)
Aggregation::Aggregate *agg = new Aggregation::Aggregate; Aggregation::Aggregate *agg = new Aggregation::Aggregate;
agg->add(m_textEdit); agg->add(m_textEdit);
agg->add(new Find::BaseTextFind(m_textEdit)); agg->add(new Find::BaseTextFind(m_textEdit));
qRegisterMetaType<QTextCharFormat>("QTextCharFormat");
} }
bool CompileOutputWindow::hasFocus() bool CompileOutputWindow::hasFocus()
@@ -74,9 +76,16 @@ QWidget *CompileOutputWindow::outputWidget(QWidget *)
return m_textEdit; return m_textEdit;
} }
void CompileOutputWindow::appendText(const QString &text) void CompileOutputWindow::appendText(const QString &text, const QTextCharFormat &textCharFormat)
{ {
m_textEdit->appendHtml(text); QString textWithNewline = text;
if (!textWithNewline.endsWith("\n"))
textWithNewline.append("\n");
QTextCursor cursor = QTextCursor(m_textEdit->document());
cursor.movePosition(QTextCursor::End);
cursor.beginEditBlock();
cursor.insertText(textWithNewline, textCharFormat);
cursor.endEditBlock();
} }
void CompileOutputWindow::clearContents() void CompileOutputWindow::clearContents()

View File

@@ -31,6 +31,8 @@
#define COMPILEOUTPUTWINDOW_H #define COMPILEOUTPUTWINDOW_H
#include <coreplugin/ioutputpane.h> #include <coreplugin/ioutputpane.h>
#include <QtGui/QColor>
#include <QtGui/QTextCharFormat>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QPlainTextEdit; class QPlainTextEdit;
@@ -54,7 +56,7 @@ public:
int priorityInStatusBar() const; int priorityInStatusBar() const;
void clearContents(); void clearContents();
void visibilityChanged(bool visible); void visibilityChanged(bool visible);
void appendText(const QString &text); void appendText(const QString &text, const QTextCharFormat &textCharFormat);
bool canFocus(); bool canFocus();
bool hasFocus(); bool hasFocus();
void setFocus(); void setFocus();

View File

@@ -113,6 +113,8 @@ QStringList DebuggingHelperLibrary::debuggingHelperLibraryLocationsByInstallData
QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QString &qtInstallData) QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QString &qtInstallData)
{ {
if (!Core::ICore::instance())
return QString();
const QString dumperSourcePath = Core::ICore::instance()->resourcePath() + QLatin1String("/gdbmacros/"); const QString dumperSourcePath = Core::ICore::instance()->resourcePath() + QLatin1String("/gdbmacros/");
QDateTime lastModified = QFileInfo(dumperSourcePath + "gdbmacros.cpp").lastModified(); QDateTime lastModified = QFileInfo(dumperSourcePath + "gdbmacros.cpp").lastModified();
// We pretend that the lastmodified of gdbmacros.cpp is 5 minutes before what the file system says // We pretend that the lastmodified of gdbmacros.cpp is 5 minutes before what the file system says

View File

@@ -110,14 +110,14 @@ void GnuMakeParser::stdError(const QString &line)
void GnuMakeParser::addDirectory(const QString &dir) void GnuMakeParser::addDirectory(const QString &dir)
{ {
if (dir.isEmpty() || m_directories.contains(dir)) if (dir.isEmpty())
return; return;
m_directories.append(dir); m_directories.append(dir);
} }
void GnuMakeParser::removeDirectory(const QString &dir) void GnuMakeParser::removeDirectory(const QString &dir)
{ {
m_directories.removeAll(dir); m_directories.removeOne(dir);
} }
void GnuMakeParser::taskAdded(const Task &task) void GnuMakeParser::taskAdded(const Task &task)

View File

@@ -50,8 +50,8 @@ void IOutputParser::appendOutputParser(IOutputParser *parser)
} }
m_parser = parser; m_parser = parser;
connect(parser, SIGNAL(addOutput(QString)), connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(outputAdded(QString)), Qt::DirectConnection); this, SLOT(outputAdded(QString, QTextCharFormat)), Qt::DirectConnection);
connect(parser, SIGNAL(addTask(ProjectExplorer::Task)), connect(parser, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(taskAdded(ProjectExplorer::Task)), Qt::DirectConnection); this, SLOT(taskAdded(ProjectExplorer::Task)), Qt::DirectConnection);
} }
@@ -59,6 +59,10 @@ void IOutputParser::appendOutputParser(IOutputParser *parser)
IOutputParser *IOutputParser::takeOutputParserChain() IOutputParser *IOutputParser::takeOutputParserChain()
{ {
IOutputParser *parser = m_parser; IOutputParser *parser = m_parser;
disconnect(parser, SIGNAL(addOutput(QString, QTextCharFormat)),
this, SLOT(outputAdded(QString, QTextCharFormat)));
disconnect(parser, SIGNAL(addTask(ProjectExplorer::Task)),
this, SLOT(taskAdded(ProjectExplorer::Task)));
m_parser = 0; m_parser = 0;
return parser; return parser;
} }
@@ -80,9 +84,9 @@ void IOutputParser::stdError(const QString &line)
m_parser->stdError(line); m_parser->stdError(line);
} }
void IOutputParser::outputAdded(const QString &string) void IOutputParser::outputAdded(const QString &string, const QTextCharFormat &textCharFormat)
{ {
emit addOutput(string); emit addOutput(string, textCharFormat);
} }
void IOutputParser::taskAdded(const ProjectExplorer::Task &task) void IOutputParser::taskAdded(const ProjectExplorer::Task &task)

View File

@@ -67,14 +67,14 @@ signals:
/// added to the output. /// added to the output.
/// Note: This is additional information. There is no need to add each /// Note: This is additional information. There is no need to add each
/// line! /// line!
void addOutput(const QString &string); void addOutput(const QString &string, const QTextCharFormat &format);
/// Should be emitted for each task seen in the output. /// Should be emitted for each task seen in the output.
void addTask(const ProjectExplorer::Task &task); void addTask(const ProjectExplorer::Task &task);
public slots: public slots:
/// Subparsers have their addOutput signal connected to this slot. /// Subparsers have their addOutput signal connected to this slot.
/// This method can be overwritten to change the string. /// This method can be overwritten to change the string.
virtual void outputAdded(const QString &string); virtual void outputAdded(const QString &string, const QTextCharFormat &color);
/// Subparsers have their addTask signal connected to this slot. /// Subparsers have their addTask signal connected to this slot.
/// This method can be overwritten to change the task. /// This method can be overwritten to change the task.
virtual void taskAdded(const ProjectExplorer::Task &task); virtual void taskAdded(const ProjectExplorer::Task &task);

View File

@@ -104,7 +104,8 @@ void OutputParserTester::testOutputMangling(const QString &input,
{ {
reset(); reset();
childParser()->outputAdded(input); QTextCharFormat textCharFormat;
childParser()->outputAdded(input, textCharFormat);
QCOMPARE(m_receivedOutput, output); QCOMPARE(m_receivedOutput, output);
QVERIFY(m_receivedStdErrChildLine.isNull()); QVERIFY(m_receivedStdErrChildLine.isNull());
@@ -139,8 +140,9 @@ void OutputParserTester::appendOutputParser(IOutputParser *parser)
parser->appendOutputParser(this); parser->appendOutputParser(this);
} }
void OutputParserTester::outputAdded(const QString &line) void OutputParserTester::outputAdded(const QString &line, const QTextCharFormat &textCharFormat)
{ {
Q_UNUSED(textCharFormat);
if (!m_receivedOutput.isEmpty()) if (!m_receivedOutput.isEmpty())
m_receivedOutput.append(QChar('\n')); m_receivedOutput.append(QChar('\n'));
m_receivedOutput.append(line); m_receivedOutput.append(line);

View File

@@ -71,7 +71,7 @@ public:
void appendOutputParser(IOutputParser *parser); void appendOutputParser(IOutputParser *parser);
private slots: private slots:
void outputAdded(const QString &line); void outputAdded(const QString &line, const QTextCharFormat &textCharFormat);
void taskAdded(const ProjectExplorer::Task &task); void taskAdded(const ProjectExplorer::Task &task);
private: private:

View File

@@ -101,7 +101,7 @@
<item> <item>
<widget class="QLabel" name="jomLabel"> <widget class="QLabel" name="jomLabel">
<property name="text"> <property name="text">
<string>&lt;i&gt;jom&lt;/i&gt; is a drop-in replacement for &lt;i&gt;nmake&lt;/i&gt; which distributes the compilation process to multiple CPU cores. For more details, see the &lt;a href=&quot;http://qt.gitorious.org/qt-labs/jom/&quot;&gt;jom Homepage&lt;/a&gt;. Disable it if you experience problems with your builds.</string> <string>&lt;i&gt;jom&lt;/i&gt; is a drop-in replacement for &lt;i&gt;nmake&lt;/i&gt; which distributes the compilation process to multiple CPU cores. The latest binary is available at &lt;a href=&quot;ftp://ftp.qt.nokia.com/jom/&quot;&gt;ftp://ftp.qt.nokia.com/jom/&lt;/a&gt;. Disable it if you experience problems with your builds.</string>
</property> </property>
<property name="wordWrap"> <property name="wordWrap">
<bool>true</bool> <bool>true</bool>

View File

@@ -129,6 +129,9 @@ public:
QIcon taskTypeIcon(Task::TaskType t) const; QIcon taskTypeIcon(Task::TaskType t) const;
int taskCount();
int errorTaskCount();
private: private:
QHash<QString,QString> m_categories; // category id -> display name QHash<QString,QString> m_categories; // category id -> display name
QList<Task> m_tasks; // all tasks (in order of insertion) QList<Task> m_tasks; // all tasks (in order of insertion)
@@ -138,6 +141,9 @@ private:
int m_maxSizeOfFileName; int m_maxSizeOfFileName;
const QIcon m_errorIcon; const QIcon m_errorIcon;
const QIcon m_warningIcon; const QIcon m_warningIcon;
int m_taskCount;
int m_errorTaskCount;
int m_sizeOfLineNumber;
}; };
class TaskFilterModel : public QSortFilterProxyModel class TaskFilterModel : public QSortFilterProxyModel
@@ -203,8 +209,22 @@ void TaskView::keyPressEvent(QKeyEvent *e)
TaskModel::TaskModel() : TaskModel::TaskModel() :
m_maxSizeOfFileName(0), m_maxSizeOfFileName(0),
m_errorIcon(QLatin1String(":/projectexplorer/images/compile_error.png")), m_errorIcon(QLatin1String(":/projectexplorer/images/compile_error.png")),
m_warningIcon(QLatin1String(":/projectexplorer/images/compile_warning.png")) m_warningIcon(QLatin1String(":/projectexplorer/images/compile_warning.png")),
m_taskCount(0),
m_errorTaskCount(0),
m_sizeOfLineNumber(0)
{ {
}
int TaskModel::taskCount()
{
return m_taskCount;
}
int TaskModel::errorTaskCount()
{
return m_errorTaskCount;
} }
QIcon TaskModel::taskTypeIcon(Task::TaskType t) const QIcon TaskModel::taskTypeIcon(Task::TaskType t) const
@@ -239,9 +259,13 @@ void TaskModel::addTask(const Task &task)
{ {
Q_ASSERT(m_categories.keys().contains(task.category)); Q_ASSERT(m_categories.keys().contains(task.category));
QList<Task> tasksInCategory = m_tasksInCategory.value(task.category); if (m_tasksInCategory.contains(task.category)) {
tasksInCategory.append(task); m_tasksInCategory[task.category].append(task);
m_tasksInCategory.insert(task.category, tasksInCategory); } else {
QList<Task> temp;
temp.append(task);
m_tasksInCategory.insert(task.category, temp);
}
beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size()); beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size());
m_tasks.append(task); m_tasks.append(task);
@@ -255,6 +279,9 @@ void TaskModel::addTask(const Task &task)
filename = task.file.mid(pos +1); filename = task.file.mid(pos +1);
m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename)); m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename));
++m_taskCount;
if (task.type == Task::Error)
++m_errorTaskCount;
} }
void TaskModel::removeTask(const Task &task) void TaskModel::removeTask(const Task &task)
@@ -263,6 +290,9 @@ void TaskModel::removeTask(const Task &task)
int index = m_tasks.indexOf(task); int index = m_tasks.indexOf(task);
beginRemoveRows(QModelIndex(), index, index); beginRemoveRows(QModelIndex(), index, index);
m_tasks.removeAt(index); m_tasks.removeAt(index);
--m_taskCount;
if (task.type == Task::Error)
--m_errorTaskCount;
endRemoveRows(); endRemoveRows();
} }
} }
@@ -275,24 +305,41 @@ void TaskModel::clearTasks(const QString &categoryId)
beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1); beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1);
m_tasks.clear(); m_tasks.clear();
m_tasksInCategory.clear(); m_tasksInCategory.clear();
m_taskCount = 0;
m_errorTaskCount = 0;
endRemoveRows(); endRemoveRows();
m_maxSizeOfFileName = 0; m_maxSizeOfFileName = 0;
} else { } else {
// TODO: Optimize this for consecutive rows int index = 0;
foreach (const Task &task, m_tasksInCategory.value(categoryId)) { int start = 0;
int index = m_tasks.indexOf(task); int subErrorTaskCount = 0;
Q_ASSERT(index >= 0); while (index < m_tasks.size()) {
beginRemoveRows(QModelIndex(), index, index); while (index < m_tasks.size() && m_tasks.at(index).category != categoryId) {
++start;
++index;
}
if (index == m_tasks.size())
break;
while (index < m_tasks.size() && m_tasks.at(index).category == categoryId) {
if (m_tasks.at(index).type == Task::Error)
++subErrorTaskCount;
++index;
}
// Index is now on the first non category
beginRemoveRows(QModelIndex(), start, index - 1);
m_tasks.removeAt(index); for (int i = start; i < index; ++i) {
m_tasksInCategory[categoryId].removeOne(m_tasks.at(i));
QList<Task> tasksInCategory = m_tasksInCategory.value(categoryId);
tasksInCategory.removeOne(task);
m_tasksInCategory.insert(categoryId, tasksInCategory);
endRemoveRows();
} }
m_tasks.erase(m_tasks.begin() + start, m_tasks.begin() + index);
m_taskCount -= index - start;
m_errorTaskCount -= subErrorTaskCount;
endRemoveRows();
index = start;
}
// what to do with m_maxSizeOfFileName ? // what to do with m_maxSizeOfFileName ?
} }
} }
@@ -366,9 +413,12 @@ int TaskModel::sizeOfFile()
int TaskModel::sizeOfLineNumber() int TaskModel::sizeOfLineNumber()
{ {
if (m_sizeOfLineNumber == 0) {
QFont font; QFont font;
QFontMetrics fm(font); QFontMetrics fm(font);
return fm.width("8888"); m_sizeOfLineNumber = fm.width("8888");
}
return m_sizeOfLineNumber;
} }
void TaskModel::setFileNotFound(const QModelIndex &idx, bool b) void TaskModel::setFileNotFound(const QModelIndex &idx, bool b)
@@ -674,21 +724,14 @@ void TaskWindow::filterCategoryTriggered(QAction *action)
d->m_filter->setFilteredCategories(categories); d->m_filter->setFilteredCategories(categories);
} }
int TaskWindow::taskCount(const QString &categoryId) const int TaskWindow::taskCount() const
{ {
return d->m_model->tasks(categoryId).count(); return d->m_model->taskCount();
} }
int TaskWindow::errorTaskCount(const QString &categoryId) const int TaskWindow::errorTaskCount() const
{ {
int errorTaskCount = 0; return d->m_model->errorTaskCount();
foreach (const Task &task, d->m_model->tasks(categoryId)) {
if (task.type == Task::Error)
++ errorTaskCount;
}
return errorTaskCount;
} }
int TaskWindow::priorityInStatusBar() const int TaskWindow::priorityInStatusBar() const

View File

@@ -95,8 +95,8 @@ public:
void removeTask(const Task &task); void removeTask(const Task &task);
void clearTasks(const QString &categoryId = QString()); void clearTasks(const QString &categoryId = QString());
int taskCount(const QString &categoryId = QString()) const; int taskCount() const;
int errorTaskCount(const QString &categoryId = QString()) const; int errorTaskCount() const;
// IOutputPane // IOutputPane

View File

@@ -223,10 +223,6 @@ void FormEditorScene::dragLeaveEvent(QGraphicsSceneDragDropEvent * event)
currentTool()->dragLeaveEvent(event); currentTool()->dragLeaveEvent(event);
return; return;
if (m_dragNode.isValid()) {
m_dragNode.destroy();
}
} }
void FormEditorScene::dragMoveEvent(QGraphicsSceneDragDropEvent * event) void FormEditorScene::dragMoveEvent(QGraphicsSceneDragDropEvent * event)

View File

@@ -38,6 +38,10 @@
#include <QDebug> #include <QDebug>
#include <QPainter> #include <QPainter>
#ifdef Q_OS_WIN
#include <private/qwidget_p.h>
#endif
namespace QmlDesigner { namespace QmlDesigner {
namespace QmlDesignerItemLibraryDragAndDrop { namespace QmlDesignerItemLibraryDragAndDrop {
@@ -54,7 +58,20 @@ void CustomDragAndDropIcon::startDrag()
raise(); raise();
show(); show();
grabMouseSafely();
}
void CustomDragAndDropIcon::grabMouseSafely()
{
#ifdef Q_OS_WIN
// grabMouse calls SetWindowsHookEx() - this function causes a system-wide
// freeze if any other app on the system installs a hook and fails to
// process events.
QWidgetPrivate *p = qt_widget_private(this);
p->grabMouseWhileInWindow();
#else
grabMouse(); grabMouse();
#endif
} }
void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event) void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event)
@@ -108,7 +125,8 @@ void CustomDragAndDropIcon::mouseMoveEvent(QMouseEvent *event)
leave(); // trigger animation if we leave a widget that accepted leave(); // trigger animation if we leave a widget that accepted
// the drag enter event // the drag enter event
} }
grabMouse(); //enable the mouse grabber again - after the curser is set //enable the mouse grabber again - after the curser is set
grabMouseSafely();
} else { } else {
if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget
// accepted the DragEnter event // accepted the DragEnter event
@@ -231,7 +249,6 @@ void CustomDragAndDrop::startCustomDrag(const QPixmap icon, const QPixmap previe
instance()->m_widget->setIcon(icon); instance()->m_widget->setIcon(icon);
instance()->m_widget->setPreview(preview); instance()->m_widget->setPreview(preview);
instance()->m_widget->startDrag(); instance()->m_widget->startDrag();
} }
bool CustomDragAndDrop::customDragActive() bool CustomDragAndDrop::customDragActive()

View File

@@ -54,6 +54,7 @@ public:
void enter(); void enter();
void leave(); void leave();
void startDrag(); void startDrag();
void grabMouseSafely();
public slots: public slots:
void animateDrag(int frame); void animateDrag(int frame);

View File

@@ -153,6 +153,7 @@ ItemLibrary::ItemLibrary(QWidget *parent) :
QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_d->m_itemsView->rootObject()); QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_d->m_itemsView->rootObject());
connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int))); connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(int)));
connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int))); connect(rootItem, SIGNAL(itemDragged(int)), this, SLOT(startDragAndDrop(int)));
connect(this, SIGNAL(scrollItemsView(QVariant)), rootItem, SLOT(scrollView(QVariant)));
connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView())); connect(this, SIGNAL(resetItemsView()), rootItem, SLOT(resetView()));
/* create Resources view and its model */ /* create Resources view and its model */
@@ -318,4 +319,14 @@ void ItemLibrary::showItemInfo(int /*itemLibId*/)
// qDebug() << "showing item info about id" << itemLibId; // qDebug() << "showing item info about id" << itemLibId;
} }
void ItemLibrary::wheelEvent(QWheelEvent *event)
{
if (m_d->m_stackedWidget->currentIndex() == 0 &&
m_d->m_itemsView->rect().contains(event->pos())) {
emit scrollItemsView(event->delta());
event->accept();
} else
QFrame::wheelEvent(event);
}
} }

View File

@@ -61,8 +61,12 @@ public Q_SLOTS:
void startDragAndDrop(int itemLibId); void startDragAndDrop(int itemLibId);
void showItemInfo(int itemLibId); void showItemInfo(int itemLibId);
protected:
void wheelEvent(QWheelEvent *event);
signals: signals:
void itemActivated(const QString& itemName); void itemActivated(const QString& itemName);
void scrollItemsView(QVariant delta);
void resetItemsView(); void resetItemsView();
private: private:

View File

@@ -60,6 +60,10 @@ Rectangle {
// public // public
function scrollView(delta) {
scrollbar.scroll(-delta / style.scrollbarWheelDeltaFactor)
}
function resetView() { function resetView() {
expandAllEntries() expandAllEntries()
scrollbar.reset() scrollbar.reset()

View File

@@ -41,6 +41,7 @@ Item {
property string scrollbarGradientMiddleColor: "#656565" property string scrollbarGradientMiddleColor: "#656565"
property string scrollbarGradientEndColor: "#888888" property string scrollbarGradientEndColor: "#888888"
property int scrollbarClickScrollAmount: 40 property int scrollbarClickScrollAmount: 40
property int scrollbarWheelDeltaFactor: 4
property string itemNameTextColor: "#FFFFFF" property string itemNameTextColor: "#FFFFFF"

View File

@@ -38,6 +38,10 @@ Item {
property variant flickable property variant flickable
function scroll(delta) {
handle.y = Math.max(0, Math.min(scrollHeight, handle.y + delta))
}
function reset() { function reset() {
handle.y = 0 handle.y = 0
} }
@@ -100,7 +104,7 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: handle.top anchors.bottom: handle.top
onClicked: handle.y = Math.max(0, handle.y - style.scrollbarClickScrollAmount) onClicked: scroll(-style.scrollbarClickScrollAmount)
} }
Item { Item {
@@ -151,6 +155,6 @@ Item {
anchors.right: parent.right anchors.right: parent.right
anchors.top: handle.bottom anchors.top: handle.bottom
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
onClicked: handle.y = Math.min(scrollHeight, handle.y + style.scrollbarClickScrollAmount) onClicked: scroll(style.scrollbarClickScrollAmount)
} }
} }

View File

@@ -636,6 +636,8 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
context->enterScope(astNode); context->enterScope(astNode);
QSet<QString> modelPropertyNames = QSet<QString>::fromList(modelNode.propertyNames()); QSet<QString> modelPropertyNames = QSet<QString>::fromList(modelNode.propertyNames());
if (!modelNode.id().isEmpty())
modelPropertyNames.insert(QLatin1String("id"));
QList<UiObjectMember *> defaultPropertyItems; QList<UiObjectMember *> defaultPropertyItems;
for (UiObjectMemberList *iter = astInitializer->members; iter; iter = iter->next) { for (UiObjectMemberList *iter = astInitializer->members; iter; iter = iter->next) {
@@ -744,6 +746,9 @@ void TextToModelMerger::syncNode(ModelNode &modelNode,
AbstractProperty modelProperty = modelNode.property(modelPropertyName); AbstractProperty modelProperty = modelNode.property(modelPropertyName);
// property deleted. // property deleted.
if (modelPropertyName == QLatin1String("id"))
differenceHandler.idsDiffer(modelNode, QString());
else
differenceHandler.propertyAbsentFromQml(modelProperty); differenceHandler.propertyAbsentFromQml(modelProperty);
} }

View File

@@ -258,7 +258,7 @@ bool QmlProject::fromMap(const QVariantMap &map)
refresh(Everything); refresh(Everything);
// FIXME workaround to guarantee that run/debug actions are enabled if a valid file exists // FIXME workaround to guarantee that run/debug actions are enabled if a valid file exists
QmlProjectRunConfiguration *runConfig = static_cast<QmlProjectRunConfiguration*>(activeTarget()->activeRunConfiguration()); QmlProjectRunConfiguration *runConfig = qobject_cast<QmlProjectRunConfiguration*>(activeTarget()->activeRunConfiguration());
if (runConfig) if (runConfig)
runConfig->changeCurrentFile(0); runConfig->changeCurrentFile(0);

View File

@@ -85,12 +85,7 @@ bool QmlProjectRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration *
{ {
Q_UNUSED(bc); Q_UNUSED(bc);
if (!QFile::exists(mainScript()) return m_isEnabled;
|| !Core::ICore::instance()->mimeDatabase()->findByFile(mainScript()).matchesType(QLatin1String("application/x-qml")))
{
return false;
}
return true;
} }
void QmlProjectRunConfiguration::ctor() void QmlProjectRunConfiguration::ctor()
@@ -326,15 +321,17 @@ void QmlProjectRunConfiguration::changeCurrentFile(Core::IEditor *editor)
bool enable = false; bool enable = false;
if (editor) { if (editor) {
m_currentFileFilename = editor->file()->fileName(); m_currentFileFilename = editor->file()->fileName();
if (Core::ICore::instance()->mimeDatabase()->findByFile(mainScript()).matchesType(QLatin1String("application/x-qml"))) if (Core::ICore::instance()->mimeDatabase()->findByFile(mainScript()).type() == QLatin1String("application/x-qml"))
enable = true; enable = true;
} else { }
if (!editor
|| Core::ICore::instance()->mimeDatabase()->findByFile(mainScript()).type() == QLatin1String("application/x-qmlproject")) {
// find a qml file with lowercase filename. This is slow but only done in initialization/other border cases. // find a qml file with lowercase filename. This is slow but only done in initialization/other border cases.
foreach(const QString& filename, m_projectTarget->qmlProject()->files()) { foreach(const QString& filename, m_projectTarget->qmlProject()->files()) {
const QFileInfo fi(filename); const QFileInfo fi(filename);
if (!filename.isEmpty() && fi.baseName()[0].isLower() if (!filename.isEmpty() && fi.baseName()[0].isLower()
&& Core::ICore::instance()->mimeDatabase()->findByFile(fi).matchesType(QLatin1String("application/x-qml"))) && Core::ICore::instance()->mimeDatabase()->findByFile(fi).type() == QLatin1String("application/x-qml"))
{ {
m_currentFileFilename = filename; m_currentFileFilename = filename;
enable = true; enable = true;

View File

@@ -62,7 +62,6 @@
</item> </item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="Utils::WelcomeModeTreeWidget" name="tutorialTreeWidget" native="true"> <widget class="Utils::WelcomeModeTreeWidget" name="tutorialTreeWidget" native="true">
<zorder></zorder>
</widget> </widget>
</item> </item>
</layout> </layout>

View File

@@ -135,8 +135,9 @@ bool MakeStep::init()
// Try to detect command in environment // Try to detect command in environment
const QString tmp = environment.searchInPath(makeCmd); const QString tmp = environment.searchInPath(makeCmd);
if (tmp.isEmpty()) { if (tmp.isEmpty()) {
emit addOutput(tr("<font color=\"#ff0000\">Could not find make command: %1 "\ QTextCharFormat textCharFormat;
"in the build environment</font>").arg(makeCmd)); textCharFormat.setForeground(Qt::red);
emit addOutput(tr("Could not find make command: %1 in the build environment").arg(makeCmd), textCharFormat);
return false; return false;
} }
makeCmd = tmp; makeCmd = tmp;

View File

@@ -48,7 +48,8 @@ ProFileReader::~ProFileReader()
bool ProFileReader::readProFile(const QString &fileName) bool ProFileReader::readProFile(const QString &fileName)
{ {
if (ProFile *pro = parsedProFile(fileName)) { if (ProFile *pro = parsedProFile(fileName)) {
aboutToEval(pro); m_ignoreLevel = 0;
aboutToEval(0, pro, EvalIncludeFile);
bool ok = accept(pro); bool ok = accept(pro);
pro->deref(); pro->deref();
return ok; return ok;
@@ -56,15 +57,23 @@ bool ProFileReader::readProFile(const QString &fileName)
return false; return false;
} }
void ProFileReader::aboutToEval(ProFile *pro) void ProFileReader::aboutToEval(ProFile *, ProFile *pro, EvalFileType type)
{ {
if (!m_includeFiles.contains(pro->fileName())) { if (m_ignoreLevel || type == EvalFeatureFile) {
m_ignoreLevel++;
} else if (!m_includeFiles.contains(pro->fileName())) {
m_includeFiles.insert(pro->fileName(), pro); m_includeFiles.insert(pro->fileName(), pro);
m_proFiles.append(pro); m_proFiles.append(pro);
pro->ref(); pro->ref();
} }
} }
void ProFileReader::doneWithEval(ProFile *)
{
if (m_ignoreLevel)
m_ignoreLevel--;
}
QList<ProFile*> ProFileReader::includeFiles() const QList<ProFile*> ProFileReader::includeFiles() const
{ {
QString qmakeMkSpecDir = QFileInfo(propertyValue("QMAKE_MKSPECS")).absoluteFilePath(); QString qmakeMkSpecDir = QFileInfo(propertyValue("QMAKE_MKSPECS")).absoluteFilePath();

View File

@@ -58,7 +58,8 @@ signals:
void errorFound(const QString &error); void errorFound(const QString &error);
private: private:
virtual void aboutToEval(ProFile *proFile); virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type);
virtual void doneWithEval(ProFile *parent);
virtual void logMessage(const QString &msg); virtual void logMessage(const QString &msg);
virtual void fileMessage(const QString &msg); virtual void fileMessage(const QString &msg);
virtual void errorMessage(const QString &msg); virtual void errorMessage(const QString &msg);
@@ -66,6 +67,7 @@ private:
private: private:
QMap<QString, ProFile *> m_includeFiles; QMap<QString, ProFile *> m_includeFiles;
QList<ProFile *> m_proFiles; QList<ProFile *> m_proFiles;
int m_ignoreLevel;
}; };
class ProFileCacheManager : public QObject class ProFileCacheManager : public QObject

View File

@@ -198,13 +198,17 @@ void QMakeStep::run(QFutureInterface<bool> &fi)
canContinue = false; canContinue = false;
} }
if (!canContinue) { if (!canContinue) {
emit addOutput(tr("<font color=\"#0000ff\">Configuration is faulty, please check the Build Issues view for details.</font>")); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::blue);
emit addOutput(tr("Configuration is faulty, please check the Build Issues view for details."), textCharFormat);
fi.reportResult(false); fi.reportResult(false);
return; return;
} }
if (!m_needToRunQMake) { if (!m_needToRunQMake) {
emit addOutput(tr("<font color=\"#0000ff\">Configuration unchanged, skipping qmake step.</font>")); QTextCharFormat textCharFormat;
textCharFormat.setForeground(Qt::blue);
emit addOutput(tr("Configuration unchanged, skipping qmake step."), textCharFormat);
fi.reportResult(true); fi.reportResult(true);
return; return;
} }

View File

@@ -114,7 +114,8 @@ bool MaemoPackageCreationStep::createPackage()
if (!packagingNeeded()) if (!packagingNeeded())
return true; return true;
emit addOutput(tr("Creating package file ...")); QTextCharFormat textCharFormat;
emit addOutput(tr("Creating package file ..."), textCharFormat);
QFile configFile(targetRoot() % QLatin1String("/config.sh")); QFile configFile(targetRoot() % QLatin1String("/config.sh"));
if (!configFile.open(QIODevice::ReadOnly)) { if (!configFile.open(QIODevice::ReadOnly)) {
raiseError(tr("Cannot open MADDE config file '%1'.") raiseError(tr("Cannot open MADDE config file '%1'.")
@@ -214,14 +215,15 @@ bool MaemoPackageCreationStep::createPackage()
return false; return false;
} }
emit addOutput(tr("Package created.")); emit addOutput(tr("Package created."), textCharFormat);
m_packageContents->setUnModified(); m_packageContents->setUnModified();
return true; return true;
} }
bool MaemoPackageCreationStep::runCommand(QProcess &proc, const QString &command) bool MaemoPackageCreationStep::runCommand(QProcess &proc, const QString &command)
{ {
emit addOutput(tr("Package Creation: Running command '%1'.").arg(command)); QTextCharFormat textCharFormat;
emit addOutput(tr("Package Creation: Running command '%1'.").arg(command), textCharFormat);
QString perl; QString perl;
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
perl = maddeRoot() + QLatin1String("/bin/perl.exe "); perl = maddeRoot() + QLatin1String("/bin/perl.exe ");
@@ -332,7 +334,8 @@ QString MaemoPackageCreationStep::nativePath(const QFile &file) const
void MaemoPackageCreationStep::raiseError(const QString &shortMsg, void MaemoPackageCreationStep::raiseError(const QString &shortMsg,
const QString &detailedMsg) const QString &detailedMsg)
{ {
emit addOutput(detailedMsg.isNull() ? shortMsg : detailedMsg); QTextCharFormat textCharFormat;
emit addOutput(detailedMsg.isNull() ? shortMsg : detailedMsg, textCharFormat);
emit addTask(Task(Task::Error, shortMsg, QString(), -1, emit addTask(Task(Task::Error, shortMsg, QString(), -1,
TASK_CATEGORY_BUILDSYSTEM)); TASK_CATEGORY_BUILDSYSTEM));
} }

View File

@@ -530,9 +530,9 @@ void Qt4PriFileNode::update(ProFile *includeFileExact, ProFileReader *readerExac
newFilePaths += readerCumulative->absoluteFileValues(qmakeVariable, projectDir, vPathsCumulative, includeFileCumlative); newFilePaths += readerCumulative->absoluteFileValues(qmakeVariable, projectDir, vPathsCumulative, includeFileCumlative);
} }
newFilePaths.removeDuplicates();
if (!newFilePaths.isEmpty()) { if (!newFilePaths.isEmpty()) {
newFilePaths.removeDuplicates();
InternalNode *subfolder = new InternalNode; InternalNode *subfolder = new InternalNode;
subfolder->type = type; subfolder->type = type;
subfolder->icon = fileTypes.at(i).icon; subfolder->icon = fileTypes.at(i).icon;
@@ -1502,16 +1502,15 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const
const QString subDirKey = subDirVar + QLatin1String(".subdir"); const QString subDirKey = subDirVar + QLatin1String(".subdir");
const QString subDirFileKey = subDirVar + QLatin1String(".file"); const QString subDirFileKey = subDirVar + QLatin1String(".file");
if (reader->contains(subDirKey)) if (reader->contains(subDirKey))
realDir = QFileInfo(reader->value(subDirKey)).filePath(); realDir = reader->value(subDirKey);
else if (reader->contains(subDirFileKey)) else if (reader->contains(subDirFileKey))
realDir = QFileInfo(reader->value(subDirFileKey)).filePath(); realDir = reader->value(subDirFileKey);
else else
realDir = subDirVar; realDir = subDirVar;
QFileInfo info(realDir); QFileInfo info(realDir);
if (!info.isAbsolute()) { if (!info.isAbsolute())
info.setFile(m_projectDir + QLatin1Char('/') + realDir); info.setFile(m_projectDir + QLatin1Char('/') + realDir);
realDir = m_projectDir + QLatin1Char('/') + realDir; realDir = info.filePath();
}
QString realFile; QString realFile;
if (info.isDir()) { if (info.isDir()) {
@@ -1521,7 +1520,6 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const
} }
if (QFile::exists(realFile)) { if (QFile::exists(realFile)) {
if (!subProjectPaths.contains(realFile))
subProjectPaths << realFile; subProjectPaths << realFile;
} else { } else {
m_project->proFileParseError(tr("Could not find .pro file for sub dir '%1' in '%2'") m_project->proFileParseError(tr("Could not find .pro file for sub dir '%1' in '%2'")
@@ -1529,6 +1527,7 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const
} }
} }
subProjectPaths.removeDuplicates();
return subProjectPaths; return subProjectPaths;
} }

View File

@@ -41,7 +41,7 @@ using namespace TextEditor::Internal;
namespace TextEditor { namespace TextEditor {
namespace Internal { namespace Internal {
struct ICompletionCollectorPrivate class ICompletionCollectorPrivate
{ {
public: public:
CompletionSettings m_completionSettings; CompletionSettings m_completionSettings;

View File

@@ -52,7 +52,7 @@ IoUtils::FileType IoUtils::fileType(const QString &fileName)
return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular; return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular;
#else #else
struct ::stat st; struct ::stat st;
if (::stat(fileName.toLatin1().constData(), &st)) // latin1 symmetric to the file reader if (::stat(fileName.toLocal8Bit().constData(), &st))
return FileNotFound; return FileNotFound;
return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular; return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular;
#endif #endif

View File

@@ -140,7 +140,7 @@ ProFileOption::ProFileOption()
dirlist_sep = QLatin1Char(':'); dirlist_sep = QLatin1Char(':');
dir_sep = QLatin1Char('/'); dir_sep = QLatin1Char('/');
#endif #endif
qmakespec = QString::fromLatin1(qgetenv("QMAKESPEC").data()); qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").data());
#if defined(Q_OS_WIN32) #if defined(Q_OS_WIN32)
target_mode = TARG_WIN_MODE; target_mode = TARG_WIN_MODE;
@@ -292,6 +292,7 @@ public:
VisitReturn evaluateConditionalFunction(const ProString &function, const ProStringList &args); VisitReturn evaluateConditionalFunction(const ProString &function, const ProStringList &args);
ProFile *parsedProFile(const QString &fileName, bool cache, ProFile *parsedProFile(const QString &fileName, bool cache,
const QString &contents = QString()); const QString &contents = QString());
bool evaluateFileDirect(const QString &fileName, ProFileEvaluator::EvalFileType type);
bool evaluateFile(const QString &fileName); bool evaluateFile(const QString &fileName);
bool evaluateFeatureFile(const QString &fileName, bool evaluateFeatureFile(const QString &fileName,
QHash<ProString, ProStringList> *values = 0, FunctionDefs *defs = 0); QHash<ProString, ProStringList> *values = 0, FunctionDefs *defs = 0);
@@ -572,7 +573,7 @@ bool ProFileEvaluator::Private::read(ProFile *pro)
return false; return false;
} }
QString content(QString::fromLatin1(file.readAll())); // yes, really latin1 QString content(QString::fromLocal8Bit(file.readAll()));
file.close(); file.close();
m_lineNo = 1; m_lineNo = 1;
m_profileStack.push(pro); m_profileStack.push(pro);
@@ -2138,10 +2139,10 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(P
if (m_option->qmakespec_name == QLatin1String("default")) { if (m_option->qmakespec_name == QLatin1String("default")) {
#ifdef Q_OS_UNIX #ifdef Q_OS_UNIX
char buffer[1024]; char buffer[1024];
int l = ::readlink(m_option->qmakespec.toLatin1().constData(), buffer, 1024); int l = ::readlink(m_option->qmakespec.toLocal8Bit().constData(), buffer, 1024);
if (l != -1) if (l != -1)
m_option->qmakespec_name = m_option->qmakespec_name =
IoUtils::fileName(QString::fromLatin1(buffer, l)).toString(); IoUtils::fileName(QString::fromLocal8Bit(buffer, l)).toString();
#else #else
// We can't resolve symlinks as they do on Unix, so configure.exe puts // We can't resolve symlinks as they do on Unix, so configure.exe puts
// the source of the qmake.conf at the end of the default/qmake.conf in // the source of the qmake.conf at the end of the default/qmake.conf in
@@ -2542,7 +2543,7 @@ ProStringList ProFileEvaluator::Private::expandVariableReferences(
ProStringList replacement; ProStringList replacement;
if (var_type == ENVIRON) { if (var_type == ENVIRON) {
replacement = split_value_list(QString::fromLocal8Bit(qgetenv( replacement = split_value_list(QString::fromLocal8Bit(qgetenv(
var.toQString(m_tmp1).toLatin1().constData()))); var.toQString(m_tmp1).toLocal8Bit().constData())));
} else if (var_type == PROPERTY) { } else if (var_type == PROPERTY) {
replacement << ProString(propertyValue(var.toQString(m_tmp1)), NoHash); replacement << ProString(propertyValue(var.toQString(m_tmp1)), NoHash);
} else if (var_type == FUNCTION) { } else if (var_type == FUNCTION) {
@@ -3050,9 +3051,9 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
logMessage(format("system(execute) requires one or two arguments.")); logMessage(format("system(execute) requires one or two arguments."));
} else { } else {
char buff[256]; char buff[256];
FILE *proc = QT_POPEN((QLatin1String("cd ") FILE *proc = QT_POPEN(QString(QLatin1String("cd ")
+ IoUtils::shellQuote(currentDirectory()) + IoUtils::shellQuote(currentDirectory())
+ QLatin1String(" && ") + args[0]).toLatin1(), "r"); + QLatin1String(" && ") + args[0]).toLocal8Bit(), "r");
bool singleLine = true; bool singleLine = true;
if (args.count() > 1) if (args.count() > 1)
singleLine = isTrue(args.at(1), m_tmp2); singleLine = isTrue(args.at(1), m_tmp2);
@@ -3066,7 +3067,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction(
buff[i] = ' '; buff[i] = ' ';
} }
buff[read_in] = '\0'; buff[read_in] = '\0';
output += QLatin1String(buff); output += QString::fromLocal8Bit(buff);
} }
ret += split_value_list(output); ret += split_value_list(output);
if (proc) if (proc)
@@ -3634,7 +3635,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit
} }
return returnBool(system((QLatin1String("cd ") return returnBool(system((QLatin1String("cd ")
+ IoUtils::shellQuote(currentDirectory()) + IoUtils::shellQuote(currentDirectory())
+ QLatin1String(" && ") + args.at(0)).toLatin1().constData()) == 0); + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0);
} }
#endif #endif
case T_ISEMPTY: { case T_ISEMPTY: {
@@ -3832,7 +3833,7 @@ ProStringList ProFileEvaluator::Private::values(const ProString &variableName) c
case V_QMAKE_HOST_version_string: what = name.version; break; case V_QMAKE_HOST_version_string: what = name.version; break;
case V_QMAKE_HOST_arch: what = name.machine; break; case V_QMAKE_HOST_arch: what = name.machine; break;
} }
ret = QString::fromLatin1(what); ret = QString::fromLocal8Bit(what);
} }
} }
#endif #endif
@@ -3913,6 +3914,23 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool
return pro; return pro;
} }
bool ProFileEvaluator::Private::evaluateFileDirect(
const QString &fileName, ProFileEvaluator::EvalFileType type)
{
int lineNo = m_lineNo;
if (ProFile *pro = parsedProFile(fileName, true)) {
q->aboutToEval(currentProFile(), pro, type);
bool ok = (visitProFile(pro) == ReturnTrue);
q->doneWithEval(currentProFile());
pro->deref();
m_lineNo = lineNo;
return ok;
} else {
m_lineNo = lineNo;
return false;
}
}
bool ProFileEvaluator::Private::evaluateFile(const QString &fileName) bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
{ {
if (fileName.isEmpty()) if (fileName.isEmpty())
@@ -3922,17 +3940,7 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName)
errorMessage(format("circular inclusion of %1").arg(fileName)); errorMessage(format("circular inclusion of %1").arg(fileName));
return false; return false;
} }
int lineNo = m_lineNo; return evaluateFileDirect(fileName, ProFileEvaluator::EvalIncludeFile);
if (ProFile *pro = parsedProFile(fileName, true)) {
q->aboutToEval(pro);
bool ok = (visitProFile(pro) == ReturnTrue);
pro->deref();
m_lineNo = lineNo;
return ok;
} else {
m_lineNo = lineNo;
return false;
}
} }
bool ProFileEvaluator::Private::evaluateFeatureFile( bool ProFileEvaluator::Private::evaluateFeatureFile(
@@ -3980,15 +3988,8 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(
bool cumulative = m_cumulative; bool cumulative = m_cumulative;
m_cumulative = false; m_cumulative = false;
// Don't use evaluateFile() here to avoid calling aboutToEval().
// The path is fully normalized already. // The path is fully normalized already.
bool ok = false; bool ok = evaluateFileDirect(fn, ProFileEvaluator::EvalFeatureFile);
int lineNo = m_lineNo;
if (ProFile *pro = parsedProFile(fn, true)) {
ok = (visitProFile(pro) == ReturnTrue);
pro->deref();
}
m_lineNo = lineNo;
m_cumulative = cumulative; m_cumulative = cumulative;
return ok; return ok;
@@ -4174,7 +4175,11 @@ QString ProFileEvaluator::propertyValue(const QString &name) const
return d->propertyValue(name); return d->propertyValue(name);
} }
void ProFileEvaluator::aboutToEval(ProFile *) void ProFileEvaluator::aboutToEval(ProFile *, ProFile *, EvalFileType)
{
}
void ProFileEvaluator::doneWithEval(ProFile *)
{ {
} }

View File

@@ -99,7 +99,9 @@ public:
QString propertyValue(const QString &val) const; QString propertyValue(const QString &val) const;
// for our descendents // for our descendents
virtual void aboutToEval(ProFile *proFile); // only .pri, but not .prf. or .pro enum EvalFileType { EvalFeatureFile, EvalIncludeFile };
virtual void aboutToEval(ProFile *parent, ProFile *proFile, EvalFileType type);
virtual void doneWithEval(ProFile *parent);
virtual void logMessage(const QString &msg); virtual void logMessage(const QString &msg);
virtual void errorMessage(const QString &msg); // .pro parse errors virtual void errorMessage(const QString &msg); // .pro parse errors
virtual void fileMessage(const QString &msg); // error() and message() from .pro file virtual void fileMessage(const QString &msg); // error() and message() from .pro file

View File

@@ -5426,6 +5426,38 @@ void TestCore::testRewriterChangeId()
node.setId("myId"); node.setId("myId");
} }
void TestCore::testRewriterRemoveId()
{
const char* qmlString = "import Qt 4.7\nRectangle { id: rect }";
QPlainTextEdit textEdit;
textEdit.setPlainText(qmlString);
NotIndentingTextEditModifier textModifier(&textEdit);
QScopedPointer<Model> model(Model::create("Qt/Item"));
QVERIFY(model.data());
QScopedPointer<TestView> view(new TestView);
QVERIFY(view.data());
model->attachView(view.data());
QScopedPointer<TestRewriterView> testRewriterView(new TestRewriterView(0, TestRewriterView::Amend));
testRewriterView->setTextModifier(&textModifier);
model->attachView(testRewriterView.data());
ModelNode rootModelNode(view->rootModelNode());
QVERIFY(rootModelNode.isValid());
QCOMPARE(rootModelNode.id(), QString("rect"));
//
// remove id in text
//
const char* qmlString2 = "import Qt 4.7\nRectangle { }";
textEdit.setPlainText(qmlString2);
QCOMPARE(rootModelNode.id(), QString());
}
void TestCore::testRewriterChangeValueProperty() void TestCore::testRewriterChangeValueProperty()
{ {
const char* qmlString = "import Qt 4.7\nRectangle { x: 10; y: 10 }"; const char* qmlString = "import Qt 4.7\nRectangle { x: 10; y: 10 }";

View File

@@ -87,6 +87,7 @@ private slots:
void testRewriterView(); void testRewriterView();
void testRewriterErrors(); void testRewriterErrors();
void testRewriterChangeId(); void testRewriterChangeId();
void testRewriterRemoveId();
void testRewriterChangeValueProperty(); void testRewriterChangeValueProperty();
void testRewriterRemoveValueProperty(); void testRewriterRemoveValueProperty();
void testRewriterSignalProperty(); void testRewriterSignalProperty();

View File

@@ -83,7 +83,9 @@ VariantProperty TestModelToTextMerger::findAddedVariantProperty(const VariantPro
return VariantProperty(); return VariantProperty();
} }
TestRewriterView::TestRewriterView(QObject *parent) : RewriterView(RewriterView::Validate, parent) TestRewriterView::TestRewriterView(QObject *parent,
DifferenceHandling differenceHandling)
: RewriterView(differenceHandling, parent)
{ {
} }

View File

@@ -53,7 +53,8 @@ class TestRewriterView : public RewriterView
Q_OBJECT Q_OBJECT
public: public:
TestRewriterView(QObject *parent = 0); TestRewriterView(QObject *parent = 0,
DifferenceHandling differenceHandling = RewriterView::Validate);
Internal::TestModelToTextMerger *modelToTextMerger() const; Internal::TestModelToTextMerger *modelToTextMerger() const;
Internal::TextToModelMerger *textToModelMerger() const; Internal::TextToModelMerger *textToModelMerger() const;