diff --git a/share/qtcreator/snippets/qml.xml b/share/qtcreator/snippets/qml.xml index cc81a722493e0376966dba286728664e297ab492..07d4a616bfe50a0f65d2224c1046e9e46b3d3821 100644 --- a/share/qtcreator/snippets/qml.xml +++ b/share/qtcreator/snippets/qml.xml @@ -76,7 +76,7 @@ </snippet> <snippet description="with targets">PropertyAction { targets: [<tab>name</tab>]; properties: "<tab>name</tab>" } </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>PauseAnimation { duration: <tab>200</tab> } </snippet> diff --git a/src/libs/qmljs/qmljsevaluate.cpp b/src/libs/qmljs/qmljsevaluate.cpp index d7a7129216a245d4bfe4d35b209e094f643be911..2b6821e755b482d61952ffb9c8e56c9d2051fa9a 100644 --- a/src/libs/qmljs/qmljsevaluate.cpp +++ b/src/libs/qmljs/qmljsevaluate.cpp @@ -53,7 +53,7 @@ const Interpreter::Value *Evaluate::operator()(AST::Node *ast) const Value *result = reference(ast); if (const Reference *ref = value_cast<const Reference *>(result)) - result = ref->value(_context); + result = _context->lookupReference(ref); if (! result) result = _engine->undefinedValue(); diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 0718eb95250af814ee46adf35c906ddcdd4667a9..4f222c3f31486d30c8f889ff9a0a67669ad134f0 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -1510,6 +1510,18 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QString 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 Properties properties = _properties.value(object); @@ -1659,7 +1671,7 @@ const ObjectValue *ObjectValue::prototype(Context *context) const const ObjectValue *prototypeObject = value_cast<const ObjectValue *>(_prototype); if (! prototypeObject) { 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; diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 4c7d183b3c661f9f1516f6ff88c6065ac085407a..d17df9406b8dd9ecdcccbd4e4f1d3c8ccb572e80 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -294,6 +294,7 @@ public: const Value *lookup(const QString &name); const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *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; void setProperty(const ObjectValue *object, const QString &name, const Value *value); @@ -314,6 +315,7 @@ private: ScopeChain _scopeChain; int _qmlScopeObjectIndex; bool _qmlScopeObjectSet; + QList<const Reference *> _referenceStack; }; class QMLJS_EXPORT Reference: public Value @@ -323,14 +325,16 @@ public: virtual ~Reference(); Engine *engine() const; - virtual const Value *value(Context *context) const; // Value interface virtual const Reference *asReference() const; virtual void accept(ValueVisitor *) const; private: + virtual const Value *value(Context *context) const; + Engine *_engine; + friend class Context; }; class QMLJS_EXPORT ColorValue: public Value @@ -754,9 +758,9 @@ public: AST::UiQualifiedId *qmlTypeName() const; +private: virtual const Value *value(Context *context) const; -private: AST::UiQualifiedId *_qmlTypeName; const Document *_doc; }; @@ -769,6 +773,7 @@ public: ASTVariableReference(AST::VariableDeclaration *ast, Engine *engine); virtual ~ASTVariableReference(); +private: virtual const Value *value(Context *context) const; }; @@ -804,6 +809,8 @@ public: QString onChangedSlotName() const { return _onChangedSlotName; } virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; + +private: virtual const Value *value(Context *context) const; }; @@ -821,6 +828,8 @@ public: QString slotName() const { return _slotName; } virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; + +private: virtual const Value *value(Context *context) const; }; diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp index f45a479008cc7adcb8fc379d902ca05048bd4c27..3d1c180ae0131d20f2aedc81e7525d416524b56e 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.cpp @@ -80,7 +80,8 @@ CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, const QString m_buildTarget(target), m_workingDirectory(workingDirectory), m_title(title), - m_baseEnvironmentBase(CMakeRunConfiguration::BuildEnvironmentBase) + m_baseEnvironmentBase(CMakeRunConfiguration::BuildEnvironmentBase), + m_enabled(true) { ctor(); } @@ -94,7 +95,8 @@ CMakeRunConfiguration::CMakeRunConfiguration(CMakeTarget *parent, CMakeRunConfig m_title(source->m_title), m_arguments(source->m_arguments), m_userEnvironmentChanges(source->m_userEnvironmentChanges), - m_baseEnvironmentBase(source->m_baseEnvironmentBase) + m_baseEnvironmentBase(source->m_baseEnvironmentBase), + m_enabled(source->m_enabled) { ctor(); } @@ -293,9 +295,21 @@ ProjectExplorer::ToolChain::ToolChainType CMakeRunConfiguration::toolChainType() return bc->toolChainType(); } -// Configuration widget +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 CMakeRunConfigurationWidget::CMakeRunConfigurationWidget(CMakeRunConfiguration *cmakeRunConfiguration, QWidget *parent) : QWidget(parent), m_ignoreChange(false), m_cmakeRunConfiguration(cmakeRunConfiguration) { diff --git a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h index c856f0bcc7cd8a9a3a37ad6bb9f2977b84d88851..c4f49c5da22fa657cab20e438bfddec619d609c0 100644 --- a/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakerunconfiguration.h @@ -81,6 +81,11 @@ public: QVariantMap toMap() const; + void setEnabled(bool b); + + bool isEnabled(ProjectExplorer::BuildConfiguration *bc) const; + using LocalApplicationRunConfiguration::isEnabled; + signals: void baseEnvironmentChanged(); void userEnvironmentChangesChanged(const QList<ProjectExplorer::EnvironmentItem> &diff); @@ -115,6 +120,7 @@ private: QString m_arguments; QList<ProjectExplorer::EnvironmentItem> m_userEnvironmentChanges; BaseEnvironmentBase m_baseEnvironmentBase; + bool m_enabled; }; class CMakeRunConfigurationWidget : public QWidget diff --git a/src/plugins/cmakeprojectmanager/cmaketarget.cpp b/src/plugins/cmakeprojectmanager/cmaketarget.cpp index 9e45ee2cdc031ae75e931a377897ac340e603ee3..f0feff5e31bc3a1192d4b7d2299765896bb886d5 100644 --- a/src/plugins/cmakeprojectmanager/cmaketarget.cpp +++ b/src/plugins/cmakeprojectmanager/cmaketarget.cpp @@ -120,6 +120,7 @@ void CMakeTarget::updateRunConfigurations() foreach (CMakeRunConfiguration *rc, list) { rc->setExecutable(ct.executable); rc->setWorkingDirectory(ct.workingDirectory); + rc->setEnabled(true); } existingRunConfigurations.remove(ct.title); } else { @@ -131,7 +132,10 @@ void CMakeTarget::updateRunConfigurations() existingRunConfigurations.constBegin(); for( ; it != existingRunConfigurations.constEnd(); ++it) { 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()) { // Oh no, no run configuration, diff --git a/src/plugins/coreplugin/basefilewizard.cpp b/src/plugins/coreplugin/basefilewizard.cpp index 4c1309ddfb9b417b3b20f3b5291c2731a9eca92a..14d7b213c9aa7ea15a167c9e221dd87579c7b24e 100644 --- a/src/plugins/coreplugin/basefilewizard.cpp +++ b/src/plugins/coreplugin/basefilewizard.cpp @@ -38,6 +38,7 @@ #include <extensionsystem/pluginmanager.h> #include <utils/filewizarddialog.h> #include <utils/qtcassert.h> +#include <utils/stringutils.h> #include <QtCore/QDir> #include <QtCore/QFile> @@ -540,7 +541,7 @@ QStringList BaseFileWizard::runWizard(const QString &path, QWidget *parent) foreach (const GeneratedFile &generatedFile, files) result.push_back(generatedFile.path()); - switch (promptOverwrite(path, result, &errorMessage)) { + switch (promptOverwrite(result, &errorMessage)) { case OverwriteCanceled: return QStringList(); case OverwriteError: @@ -615,29 +616,34 @@ bool BaseFileWizard::postGenerateOpenEditors(const GeneratedFiles &l, QString *e return true; } -BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QString &location, - const QStringList &files, +BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QStringList &files, QString *errorMessage) const { if (debugWizard) - qDebug() << Q_FUNC_INFO << location << files; + qDebug() << Q_FUNC_INFO << files; - bool existingFilesFound = false; + QStringList existingFiles; bool oddStuffFound = false; static const QString readOnlyMsg = tr(" [read only]"); static const QString directoryMsg = tr(" [directory]"); static const QString symLinkMsg = tr(" [symbolic link]"); + 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, files) { + foreach (const QString &fileName, existingFiles) { const QFileInfo fi(fileName); if (fi.exists()) { - existingFilesFound = true; if (!fileNamesMsgPart.isEmpty()) fileNamesMsgPart += QLatin1String(", "); - fileNamesMsgPart += fi.fileName(); + fileNamesMsgPart += fileName.mid(commonExistingPath.size() + 1); do { if (fi.isDir()) { oddStuffFound = true; @@ -657,17 +663,17 @@ BaseFileWizard::OverwriteResult BaseFileWizard::promptOverwrite(const QString &l } } - if (!existingFilesFound) + if (existingFiles.isEmpty()) return OverwriteOk; 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; } const QString messageFormat = tr("The following files already exist in the directory %1:\n" "%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(), tr("Existing files"), message, QMessageBox::Yes | QMessageBox::No, diff --git a/src/plugins/coreplugin/basefilewizard.h b/src/plugins/coreplugin/basefilewizard.h index 9a03410eeeb8d93cbdbe024e2f7e4c15a2712042..e1f5a369d5defeaac6b8dc489186befdf3afc51e 100644 --- a/src/plugins/coreplugin/basefilewizard.h +++ b/src/plugins/coreplugin/basefilewizard.h @@ -210,8 +210,7 @@ protected: // 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. enum OverwriteResult { OverwriteOk, OverwriteError, OverwriteCanceled }; - OverwriteResult promptOverwrite(const QString &location, - const QStringList &files, + OverwriteResult promptOverwrite(const QStringList &files, QString *errorMessage) const; // Utility to open the editors for the files whose attribute is set accordingly. diff --git a/src/plugins/coreplugin/coreimpl.cpp b/src/plugins/coreplugin/coreimpl.cpp index c6da6362d44e25685f6ab00ef70fada45530f034..d072e8df091840d722b3f010bcd6f486248b3248 100644 --- a/src/plugins/coreplugin/coreimpl.cpp +++ b/src/plugins/coreplugin/coreimpl.cpp @@ -61,6 +61,11 @@ CoreImpl::CoreImpl(MainWindow *mainwindow) m_mainwindow = mainwindow; } +CoreImpl::~CoreImpl() +{ + m_instance = 0; +} + QStringList CoreImpl::showNewItemDialog(const QString &title, const QList<IWizard *> &wizards, const QString &defaultLocation) diff --git a/src/plugins/coreplugin/coreimpl.h b/src/plugins/coreplugin/coreimpl.h index d04defd31814283e0c7476dab3ff47d02b30f58a..50a8a673fbd101768c84fa20aa25832d2d1e1250 100644 --- a/src/plugins/coreplugin/coreimpl.h +++ b/src/plugins/coreplugin/coreimpl.h @@ -42,7 +42,7 @@ class CoreImpl : public ICore public: CoreImpl(MainWindow *mainwindow); - ~CoreImpl() {} + ~CoreImpl(); QStringList showNewItemDialog(const QString &title, const QList<IWizard *> &wizards, diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp index db06060a8bad15d858afba014db39df5c8d888e6..8f2d50863d0084b7dcc4f3fad4d1414a19c70fb5 100644 --- a/src/plugins/coreplugin/fileiconprovider.cpp +++ b/src/plugins/coreplugin/fileiconprovider.cpp @@ -90,7 +90,6 @@ struct FileIconProviderPrivate { // Mapping of file suffix to icon. StringIconPairList m_cache; - QFileIconProvider m_systemIconProvider; QIcon m_unknownFileIcon; // singleton pattern @@ -140,25 +139,15 @@ QIcon FileIconProvider::icon(const QFileInfo &fileInfo) const } // Get icon from OS. #if defined(Q_WS_WIN) || defined(Q_WS_MAC) - return d->m_systemIconProvider.icon(fileInfo); + return QFileIconProvider::icon(fileInfo); #else // File icons are unknown on linux systems. return (fileInfo.isDir()) ? - d->m_systemIconProvider.icon(fileInfo) : + QFileIconProvider::icon(fileInfo) : d->m_unknownFileIcon; #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. See platform note in class documentation about recommended usage. diff --git a/src/plugins/coreplugin/fileiconprovider.h b/src/plugins/coreplugin/fileiconprovider.h index 31fef66ea89680bf77c026e8696fda429699cad9..b834459ae19c87e19422d435e887dea50467c69e 100644 --- a/src/plugins/coreplugin/fileiconprovider.h +++ b/src/plugins/coreplugin/fileiconprovider.h @@ -56,9 +56,8 @@ public: virtual ~FileIconProvider(); // Implement QFileIconProvider - virtual QIcon icon(IconType type) const; virtual QIcon icon(const QFileInfo &info) const; - virtual QString type(const QFileInfo &info) const; + using QFileIconProvider::icon; // Register additional overlay icons static QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size); diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp index 0387ed91408cdce782afd1177fa1e6dcc24d5a7b..1a944fa4932c0a1f071873e52aeb8abf4e7720ac 100644 --- a/src/plugins/cppeditor/cppeditor.cpp +++ b/src/plugins/cppeditor/cppeditor.cpp @@ -704,50 +704,6 @@ void CPPEditor::createToolBar(CPPEditorEditable *editable) static_cast<QHBoxLayout*>(w->layout())->insertWidget(0, m_methodCombo, 1); } -void CPPEditor::inAllRenameSelections(EditOperation operation, - const QTextEdit::ExtraSelection ¤tRenameSelection, - 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() { if (m_currentRenameSelection == -1) { diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h index 357707a34d757322dea2c03bfee31f6a030ac54b..dabb54799b887dc7eaf845ba18d9117a4441ae6f 100644 --- a/src/plugins/cppeditor/cppeditor.h +++ b/src/plugins/cppeditor/cppeditor.h @@ -268,15 +268,6 @@ private: void createToolBar(CPPEditorEditable *editable); - enum EditOperation { - DeleteChar, - DeletePreviousChar, - InsertText - }; - void inAllRenameSelections(EditOperation operation, - const QTextEdit::ExtraSelection ¤tRenameSelection, - QTextCursor cursor, - const QString &text = QString()); void startRename(); void finishRename(); void abortRename(); diff --git a/src/plugins/projectexplorer/abstractprocessstep.cpp b/src/plugins/projectexplorer/abstractprocessstep.cpp index 55d94dd474e2aa35fe80d1309af555e55c08a1a1..a6d5c13bd9f8355512066d82ab044ae4ab4f69dd 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.cpp +++ b/src/plugins/projectexplorer/abstractprocessstep.cpp @@ -82,8 +82,8 @@ void AbstractProcessStep::setOutputParser(ProjectExplorer::IOutputParser *parser m_outputParserChain = parser; if (m_outputParserChain) { - connect(parser, SIGNAL(addOutput(QString)), - this, SLOT(outputAdded(QString))); + connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(outputAdded(QString, QTextCharFormat))); connect(parser, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(taskAdded(ProjectExplorer::Task))); } @@ -199,22 +199,34 @@ void AbstractProcessStep::run(QFutureInterface<bool> &fi) 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) { - if (status == QProcess::NormalExit && exitCode == 0) - emit addOutput(tr("<font color=\"#0000ff\">The process \"%1\" exited normally.</font>").arg(m_command)); - else if (status == QProcess::NormalExit) - emit addOutput(tr("<font color=\"#ff0000\"><b>The process \"%1\" exited with code %2.</b></font>").arg(m_command, m_process->exitCode())); - else - emit addOutput(tr("<font color=\"#ff0000\"><b>The process \"%1\" crashed.</b></font>").arg(m_command)); + QTextCharFormat textCharFormat; + if (status == QProcess::NormalExit && exitCode == 0) { + textCharFormat.setForeground(Qt::blue); + emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), textCharFormat); + } else if (status == QProcess::NormalExit) { + 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() { - 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) @@ -235,7 +247,8 @@ void AbstractProcessStep::stdOutput(const QString &line) { if (m_outputParserChain) m_outputParserChain->stdOutput(line); - emit addOutput(Qt::escape(line)); + QTextCharFormat textCharFormat; + emit addOutput(Qt::escape(line), textCharFormat); } void AbstractProcessStep::processReadyReadStdError() @@ -251,7 +264,9 @@ void AbstractProcessStep::stdError(const QString &line) { if (m_outputParserChain) 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() @@ -312,9 +327,9 @@ void AbstractProcessStep::taskAdded(const ProjectExplorer::Task &task) 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) diff --git a/src/plugins/projectexplorer/abstractprocessstep.h b/src/plugins/projectexplorer/abstractprocessstep.h index 98399fdab2b00273120eaf928964fe19fb2a2cf8..de4498a8f431d0bdb38b0e637c990d97884a07fa 100644 --- a/src/plugins/projectexplorer/abstractprocessstep.h +++ b/src/plugins/projectexplorer/abstractprocessstep.h @@ -147,8 +147,8 @@ private slots: void checkForCancel(); void taskAdded(const ProjectExplorer::Task &task); - void outputAdded(const QString &string); + void outputAdded(const QString &string, const QTextCharFormat &format); private: QTimer *m_timer; QFutureInterface<bool> *m_futureInterface; diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index f538d8d47a5c8e2150b6336ace1012ca89a7e97c..2a2ef6ec1d936b782d8bf16898afdfbbc2945c6a 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -180,7 +180,9 @@ void BuildManager::finish() 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() @@ -196,6 +198,7 @@ void BuildManager::clearBuildQueue() m_buildQueue.clear(); m_running = false; m_previousBuildStepProject = 0; + m_currentBuildStep = 0; m_progressFutureInterface->reportCanceled(); m_progressFutureInterface->reportFinished(); @@ -282,9 +285,9 @@ void BuildManager::addToTaskWindow(const ProjectExplorer::Task &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() @@ -294,8 +297,8 @@ void BuildManager::nextBuildQueue() disconnect(m_currentBuildStep, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(addToTaskWindow(ProjectExplorer::Task))); - disconnect(m_currentBuildStep, SIGNAL(addOutput(QString)), - this, SLOT(addToOutputWindow(QString))); + disconnect(m_currentBuildStep, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(addToOutputWindow(QString, QTextCharFormat))); ++m_progress; m_progressFutureInterface->setProgressValueAndText(m_progress*100, msgProgress(m_progress, m_maxProgress)); @@ -306,8 +309,10 @@ void BuildManager::nextBuildQueue() // Build Failure const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->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)); - addToOutputWindow(tr("<font color=\"#ff0000\">When executing build step '%1'</font>").arg(m_currentBuildStep->displayName())); + QTextCharFormat textCharFormat; + 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 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) { const QString projectName = m_currentBuildStep->buildConfiguration()->target()->project()->displayName(); - addToOutputWindow(tr("<b>Running build steps for project %2...</b>") - .arg(projectName)); + QTextCharFormat textCharFormat; + textCharFormat.setFontWeight(QFont::Bold); + addToOutputWindow(tr("Running build steps for project %2...") + .arg(projectName), textCharFormat); m_previousBuildStepProject = m_currentBuildStep->buildConfiguration()->target()->project(); } m_watcher.setFuture(QtConcurrent::run(&BuildStep::run, m_currentBuildStep)); @@ -347,6 +354,7 @@ void BuildManager::nextStep() m_previousBuildStepProject = 0; m_progressFutureInterface->reportFinished(); m_progressWatcher.setFuture(QFuture<void>()); + m_currentBuildStep = 0; delete m_progressFutureInterface; m_progressFutureInterface = 0; m_maxProgress = 0; @@ -363,8 +371,8 @@ bool BuildManager::buildQueueAppend(QList<BuildStep *> steps) BuildStep *bs = steps.at(i); connect(bs, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(addToTaskWindow(ProjectExplorer::Task))); - connect(bs, SIGNAL(addOutput(QString)), - this, SLOT(addToOutputWindow(QString))); + connect(bs, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(addToOutputWindow(QString, QTextCharFormat))); init = bs->init(); if (!init) break; @@ -376,16 +384,18 @@ bool BuildManager::buildQueueAppend(QList<BuildStep *> steps) // print something for the user const QString projectName = bs->buildConfiguration()->target()->project()->displayName(); const QString targetName = bs->buildConfiguration()->target()->displayName(); - addToOutputWindow(tr("<font color=\"#ff0000\">Error while building project %1 (target: %2)</font>").arg(projectName, targetName)); - addToOutputWindow(tr("<font color=\"#ff0000\">When executing build step '%1'</font>").arg(bs->displayName())); + QTextCharFormat textCharFormat; + 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 for (int j = 0; j <= i; ++j) { BuildStep *bs = steps.at(j); disconnect(bs, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(addToTaskWindow(ProjectExplorer::Task))); - disconnect(bs, SIGNAL(addOutput(QString)), - this, SLOT(addToOutputWindow(QString))); + disconnect(bs, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(addToOutputWindow(QString, QTextCharFormat))); } return false; } diff --git a/src/plugins/projectexplorer/buildmanager.h b/src/plugins/projectexplorer/buildmanager.h index dda5c10c31357f8d167b1047e162950c9c6d27db..648790b0f02f515373d706c0a7e9beda3352f762 100644 --- a/src/plugins/projectexplorer/buildmanager.h +++ b/src/plugins/projectexplorer/buildmanager.h @@ -95,7 +95,7 @@ signals: private slots: void addToTaskWindow(const ProjectExplorer::Task &task); - void addToOutputWindow(const QString &string); + void addToOutputWindow(const QString &string, const QTextCharFormat &textCharFormat); void nextBuildQueue(); void progressChanged(); diff --git a/src/plugins/projectexplorer/buildstep.h b/src/plugins/projectexplorer/buildstep.h index fb92427e6ccd66d7c240bd9590852f047c5f2f29..9a8739ce2d5f3e5beb95d3f0285db263eccfe76b 100644 --- a/src/plugins/projectexplorer/buildstep.h +++ b/src/plugins/projectexplorer/buildstep.h @@ -105,8 +105,8 @@ signals: void addTask(const ProjectExplorer::Task &task); // The string is added to the generated output, usually in the output // window. - // It should be in html format, that is properly escaped - void addOutput(const QString &string); + // It should be in plain text, with the format in the parameter + void addOutput(const QString &string, const QTextCharFormat &textCharFormat); private: BuildConfiguration *m_buildConfiguration; diff --git a/src/plugins/projectexplorer/compileoutputwindow.cpp b/src/plugins/projectexplorer/compileoutputwindow.cpp index 8bbfe18e6511ef74814b51df0057268ef9d05a98..a0856c76753cdc6b915f83c1c98dcee0e7997318 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.cpp +++ b/src/plugins/projectexplorer/compileoutputwindow.cpp @@ -52,6 +52,8 @@ CompileOutputWindow::CompileOutputWindow(BuildManager * /*bm*/) Aggregation::Aggregate *agg = new Aggregation::Aggregate; agg->add(m_textEdit); agg->add(new Find::BaseTextFind(m_textEdit)); + + qRegisterMetaType<QTextCharFormat>("QTextCharFormat"); } bool CompileOutputWindow::hasFocus() @@ -74,9 +76,16 @@ QWidget *CompileOutputWindow::outputWidget(QWidget *) 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() diff --git a/src/plugins/projectexplorer/compileoutputwindow.h b/src/plugins/projectexplorer/compileoutputwindow.h index e74d4e4ec2afc10e041bae8ebd02b38b3e584884..1bdd118c5042a65c654a6fa7fc8fcb55aaae8e22 100644 --- a/src/plugins/projectexplorer/compileoutputwindow.h +++ b/src/plugins/projectexplorer/compileoutputwindow.h @@ -31,6 +31,8 @@ #define COMPILEOUTPUTWINDOW_H #include <coreplugin/ioutputpane.h> +#include <QtGui/QColor> +#include <QtGui/QTextCharFormat> QT_BEGIN_NAMESPACE class QPlainTextEdit; @@ -54,7 +56,7 @@ public: int priorityInStatusBar() const; void clearContents(); void visibilityChanged(bool visible); - void appendText(const QString &text); + void appendText(const QString &text, const QTextCharFormat &textCharFormat); bool canFocus(); bool hasFocus(); void setFocus(); diff --git a/src/plugins/projectexplorer/debugginghelper.cpp b/src/plugins/projectexplorer/debugginghelper.cpp index 495996e4506c8353df7805e6fbc557659b9f0fc8..9c091557c0193581028a5d516f179ed3a07af06d 100644 --- a/src/plugins/projectexplorer/debugginghelper.cpp +++ b/src/plugins/projectexplorer/debugginghelper.cpp @@ -113,6 +113,8 @@ QStringList DebuggingHelperLibrary::debuggingHelperLibraryLocationsByInstallData QString DebuggingHelperLibrary::debuggingHelperLibraryByInstallData(const QString &qtInstallData) { + if (!Core::ICore::instance()) + return QString(); const QString dumperSourcePath = Core::ICore::instance()->resourcePath() + QLatin1String("/gdbmacros/"); QDateTime lastModified = QFileInfo(dumperSourcePath + "gdbmacros.cpp").lastModified(); // We pretend that the lastmodified of gdbmacros.cpp is 5 minutes before what the file system says diff --git a/src/plugins/projectexplorer/gnumakeparser.cpp b/src/plugins/projectexplorer/gnumakeparser.cpp index 92025f3ff3ae7a2a6c1592dbb0fc04ebe10fdaeb..62fe2b107d388eaa4cd8e488754f6f1c0ebdfede 100644 --- a/src/plugins/projectexplorer/gnumakeparser.cpp +++ b/src/plugins/projectexplorer/gnumakeparser.cpp @@ -110,14 +110,14 @@ void GnuMakeParser::stdError(const QString &line) void GnuMakeParser::addDirectory(const QString &dir) { - if (dir.isEmpty() || m_directories.contains(dir)) + if (dir.isEmpty()) return; m_directories.append(dir); } void GnuMakeParser::removeDirectory(const QString &dir) { - m_directories.removeAll(dir); + m_directories.removeOne(dir); } void GnuMakeParser::taskAdded(const Task &task) diff --git a/src/plugins/projectexplorer/ioutputparser.cpp b/src/plugins/projectexplorer/ioutputparser.cpp index 0974c661b4b1ca9623179ac63f1c238c7eaea4f6..ca5b8ba6eb928d926e21a058b064c05c8e4f05a5 100644 --- a/src/plugins/projectexplorer/ioutputparser.cpp +++ b/src/plugins/projectexplorer/ioutputparser.cpp @@ -50,8 +50,8 @@ void IOutputParser::appendOutputParser(IOutputParser *parser) } m_parser = parser; - connect(parser, SIGNAL(addOutput(QString)), - this, SLOT(outputAdded(QString)), Qt::DirectConnection); + connect(parser, SIGNAL(addOutput(QString, QTextCharFormat)), + this, SLOT(outputAdded(QString, QTextCharFormat)), Qt::DirectConnection); connect(parser, SIGNAL(addTask(ProjectExplorer::Task)), this, SLOT(taskAdded(ProjectExplorer::Task)), Qt::DirectConnection); } @@ -59,6 +59,10 @@ void IOutputParser::appendOutputParser(IOutputParser *parser) IOutputParser *IOutputParser::takeOutputParserChain() { 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; return parser; } @@ -80,9 +84,9 @@ void IOutputParser::stdError(const QString &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) diff --git a/src/plugins/projectexplorer/ioutputparser.h b/src/plugins/projectexplorer/ioutputparser.h index da761334604b7e12906a424baac7ceaa4f2a3e62..058b5a75b2917b3b59345a70f771afa428113b85 100644 --- a/src/plugins/projectexplorer/ioutputparser.h +++ b/src/plugins/projectexplorer/ioutputparser.h @@ -67,14 +67,14 @@ signals: /// added to the output. /// Note: This is additional information. There is no need to add each /// line! - void addOutput(const QString &string); + void addOutput(const QString &string, const QTextCharFormat &format); /// Should be emitted for each task seen in the output. void addTask(const ProjectExplorer::Task &task); public slots: /// Subparsers have their addOutput signal connected to this slot. /// 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. /// This method can be overwritten to change the task. virtual void taskAdded(const ProjectExplorer::Task &task); diff --git a/src/plugins/projectexplorer/outputparser_test.cpp b/src/plugins/projectexplorer/outputparser_test.cpp index 28a83b50011a1e5a246bfa1e15e2dc3e43b663dc..2214aa0128eaadba51f6f846c9ce8680843e9dcc 100644 --- a/src/plugins/projectexplorer/outputparser_test.cpp +++ b/src/plugins/projectexplorer/outputparser_test.cpp @@ -104,7 +104,8 @@ void OutputParserTester::testOutputMangling(const QString &input, { reset(); - childParser()->outputAdded(input); + QTextCharFormat textCharFormat; + childParser()->outputAdded(input, textCharFormat); QCOMPARE(m_receivedOutput, output); QVERIFY(m_receivedStdErrChildLine.isNull()); @@ -139,8 +140,9 @@ void OutputParserTester::appendOutputParser(IOutputParser *parser) 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()) m_receivedOutput.append(QChar('\n')); m_receivedOutput.append(line); diff --git a/src/plugins/projectexplorer/outputparser_test.h b/src/plugins/projectexplorer/outputparser_test.h index 8241766bb5bb6602fcdeeb17548401558ad35d2f..5d3a4d2d0b1b18fc32e0bbd3facba0dc46a3d63c 100644 --- a/src/plugins/projectexplorer/outputparser_test.h +++ b/src/plugins/projectexplorer/outputparser_test.h @@ -71,7 +71,7 @@ public: void appendOutputParser(IOutputParser *parser); private slots: - void outputAdded(const QString &line); + void outputAdded(const QString &line, const QTextCharFormat &textCharFormat); void taskAdded(const ProjectExplorer::Task &task); private: diff --git a/src/plugins/projectexplorer/projectexplorersettingspage.ui b/src/plugins/projectexplorer/projectexplorersettingspage.ui index 109626f89a936974f68c6a7f13db2b357f01fd60..a08005b5f3ab3bf3bcc449a6ab500fb9f553ffce 100644 --- a/src/plugins/projectexplorer/projectexplorersettingspage.ui +++ b/src/plugins/projectexplorer/projectexplorersettingspage.ui @@ -101,7 +101,7 @@ <item> <widget class="QLabel" name="jomLabel"> <property name="text"> - <string><i>jom</i> is a drop-in replacement for <i>nmake</i> which distributes the compilation process to multiple CPU cores. For more details, see the <a href="http://qt.gitorious.org/qt-labs/jom/">jom Homepage</a>. Disable it if you experience problems with your builds.</string> + <string><i>jom</i> is a drop-in replacement for <i>nmake</i> which distributes the compilation process to multiple CPU cores. The latest binary is available at <a href="ftp://ftp.qt.nokia.com/jom/">ftp://ftp.qt.nokia.com/jom/</a>. Disable it if you experience problems with your builds.</string> </property> <property name="wordWrap"> <bool>true</bool> diff --git a/src/plugins/projectexplorer/taskwindow.cpp b/src/plugins/projectexplorer/taskwindow.cpp index 159df5d8673b5336adb24adbc5f5d264b1c4f388..36fc04e9f147019b1a120da8cc1858c5e4bf804d 100644 --- a/src/plugins/projectexplorer/taskwindow.cpp +++ b/src/plugins/projectexplorer/taskwindow.cpp @@ -129,6 +129,9 @@ public: QIcon taskTypeIcon(Task::TaskType t) const; + int taskCount(); + int errorTaskCount(); + private: QHash<QString,QString> m_categories; // category id -> display name QList<Task> m_tasks; // all tasks (in order of insertion) @@ -138,6 +141,9 @@ private: int m_maxSizeOfFileName; const QIcon m_errorIcon; const QIcon m_warningIcon; + int m_taskCount; + int m_errorTaskCount; + int m_sizeOfLineNumber; }; class TaskFilterModel : public QSortFilterProxyModel @@ -203,8 +209,22 @@ void TaskView::keyPressEvent(QKeyEvent *e) TaskModel::TaskModel() : m_maxSizeOfFileName(0), 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 @@ -239,9 +259,13 @@ void TaskModel::addTask(const Task &task) { Q_ASSERT(m_categories.keys().contains(task.category)); - QList<Task> tasksInCategory = m_tasksInCategory.value(task.category); - tasksInCategory.append(task); - m_tasksInCategory.insert(task.category, tasksInCategory); + if (m_tasksInCategory.contains(task.category)) { + m_tasksInCategory[task.category].append(task); + } else { + QList<Task> temp; + temp.append(task); + m_tasksInCategory.insert(task.category, temp); + } beginInsertRows(QModelIndex(), m_tasks.size(), m_tasks.size()); m_tasks.append(task); @@ -255,6 +279,9 @@ void TaskModel::addTask(const Task &task) filename = task.file.mid(pos +1); m_maxSizeOfFileName = qMax(m_maxSizeOfFileName, fm.width(filename)); + ++m_taskCount; + if (task.type == Task::Error) + ++m_errorTaskCount; } void TaskModel::removeTask(const Task &task) @@ -263,6 +290,9 @@ void TaskModel::removeTask(const Task &task) int index = m_tasks.indexOf(task); beginRemoveRows(QModelIndex(), index, index); m_tasks.removeAt(index); + --m_taskCount; + if (task.type == Task::Error) + --m_errorTaskCount; endRemoveRows(); } } @@ -275,24 +305,41 @@ void TaskModel::clearTasks(const QString &categoryId) beginRemoveRows(QModelIndex(), 0, m_tasks.size() -1); m_tasks.clear(); m_tasksInCategory.clear(); + m_taskCount = 0; + m_errorTaskCount = 0; endRemoveRows(); m_maxSizeOfFileName = 0; } else { - // TODO: Optimize this for consecutive rows - foreach (const Task &task, m_tasksInCategory.value(categoryId)) { - int index = m_tasks.indexOf(task); - Q_ASSERT(index >= 0); - beginRemoveRows(QModelIndex(), index, index); + int index = 0; + int start = 0; + int subErrorTaskCount = 0; + while (index < m_tasks.size()) { + 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); + + for (int i = start; i < index; ++i) { + m_tasksInCategory[categoryId].removeOne(m_tasks.at(i)); + } - m_tasks.removeAt(index); + m_tasks.erase(m_tasks.begin() + start, m_tasks.begin() + index); - QList<Task> tasksInCategory = m_tasksInCategory.value(categoryId); - tasksInCategory.removeOne(task); - m_tasksInCategory.insert(categoryId, tasksInCategory); + m_taskCount -= index - start; + m_errorTaskCount -= subErrorTaskCount; endRemoveRows(); + index = start; } - // what to do with m_maxSizeOfFileName ? } } @@ -366,9 +413,12 @@ int TaskModel::sizeOfFile() int TaskModel::sizeOfLineNumber() { - QFont font; - QFontMetrics fm(font); - return fm.width("8888"); + if (m_sizeOfLineNumber == 0) { + QFont font; + QFontMetrics fm(font); + m_sizeOfLineNumber = fm.width("8888"); + } + return m_sizeOfLineNumber; } void TaskModel::setFileNotFound(const QModelIndex &idx, bool b) @@ -674,21 +724,14 @@ void TaskWindow::filterCategoryTriggered(QAction *action) 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; - - foreach (const Task &task, d->m_model->tasks(categoryId)) { - if (task.type == Task::Error) - ++ errorTaskCount; - } - - return errorTaskCount; + return d->m_model->errorTaskCount(); } int TaskWindow::priorityInStatusBar() const diff --git a/src/plugins/projectexplorer/taskwindow.h b/src/plugins/projectexplorer/taskwindow.h index 9352bd98f74ce98e3037bef489cb0907b7c68c47..50441e7595eef3fe9b08fe877fc113c47ccb6081 100644 --- a/src/plugins/projectexplorer/taskwindow.h +++ b/src/plugins/projectexplorer/taskwindow.h @@ -95,8 +95,8 @@ public: void removeTask(const Task &task); void clearTasks(const QString &categoryId = QString()); - int taskCount(const QString &categoryId = QString()) const; - int errorTaskCount(const QString &categoryId = QString()) const; + int taskCount() const; + int errorTaskCount() const; // IOutputPane diff --git a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp index ba2896d8ceb907ce5478294c2236ebcb186889e6..10287437a07a254a02d456af60aabb147ed45223 100644 --- a/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp +++ b/src/plugins/qmldesigner/components/formeditor/formeditorscene.cpp @@ -223,10 +223,6 @@ void FormEditorScene::dragLeaveEvent(QGraphicsSceneDragDropEvent * event) currentTool()->dragLeaveEvent(event); return; - - if (m_dragNode.isValid()) { - m_dragNode.destroy(); - } } void FormEditorScene::dragMoveEvent(QGraphicsSceneDragDropEvent * event) diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp index 7e67256099dcce738f449026920f41e4b356af9a..1672e9947feeece656ba641b67086fd2d0228ff0 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.cpp @@ -38,6 +38,10 @@ #include <QDebug> #include <QPainter> +#ifdef Q_OS_WIN +#include <private/qwidget_p.h> +#endif + namespace QmlDesigner { namespace QmlDesignerItemLibraryDragAndDrop { @@ -54,7 +58,20 @@ void CustomDragAndDropIcon::startDrag() raise(); 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(); +#endif } void CustomDragAndDropIcon::mouseReleaseEvent(QMouseEvent *event) @@ -108,7 +125,8 @@ void CustomDragAndDropIcon::mouseMoveEvent(QMouseEvent *event) leave(); // trigger animation if we leave a widget that accepted // 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 { if (CustomDragAndDrop::isAccepted()) // create DragMoveEvents if the current widget // 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->setPreview(preview); instance()->m_widget->startDrag(); - } bool CustomDragAndDrop::customDragActive() diff --git a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h index 263af4c1859b4c192b21305cd899d2c824158175..4350f635dbb6fa711cee2f2be53916a842f78567 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h +++ b/src/plugins/qmldesigner/components/itemlibrary/customdraganddrop.h @@ -54,6 +54,7 @@ public: void enter(); void leave(); void startDrag(); + void grabMouseSafely(); public slots: void animateDrag(int frame); diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp index a812f298680e33435c7e6903ff2785c9f2f3133d..48164c5f9eef22cb6ae513513953e24bb80dfd40 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.cpp @@ -153,6 +153,7 @@ ItemLibrary::ItemLibrary(QWidget *parent) : QDeclarativeItem *rootItem = qobject_cast<QDeclarativeItem*>(m_d->m_itemsView->rootObject()); connect(rootItem, SIGNAL(itemSelected(int)), this, SLOT(showItemInfo(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())); /* create Resources view and its model */ @@ -318,4 +319,14 @@ void ItemLibrary::showItemInfo(int /*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); +} + } diff --git a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h index 26637e5a40074b550edf1703bd1f043dd3eb64fb..0eff37dee910e7e35f924c9f96ec8f4faa422a28 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h +++ b/src/plugins/qmldesigner/components/itemlibrary/itemlibrary.h @@ -61,8 +61,12 @@ public Q_SLOTS: void startDragAndDrop(int itemLibId); void showItemInfo(int itemLibId); +protected: + void wheelEvent(QWheelEvent *event); + signals: void itemActivated(const QString& itemName); + void scrollItemsView(QVariant delta); void resetItemsView(); private: diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml index 002a003d694db4d8fb59b4496cbc2e24e3e6deaa..6b47b38c77848551c79db408eab81232233e8e0f 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsView.qml @@ -60,6 +60,10 @@ Rectangle { // public + function scrollView(delta) { + scrollbar.scroll(-delta / style.scrollbarWheelDeltaFactor) + } + function resetView() { expandAllEntries() scrollbar.reset() diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml index 13242e3ae37eee5dc807a299ade8810c0660e5de..1cdae226dcb244a06de36e5c01a85c7a83102d8b 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/ItemsViewStyle.qml @@ -41,6 +41,7 @@ Item { property string scrollbarGradientMiddleColor: "#656565" property string scrollbarGradientEndColor: "#888888" property int scrollbarClickScrollAmount: 40 + property int scrollbarWheelDeltaFactor: 4 property string itemNameTextColor: "#FFFFFF" diff --git a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml index a882c2fa140b0804b86d9a2e67fbef4d0fc19d9d..34dca1c30aac20ac87aa4bb5892e7eee595998a7 100644 --- a/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml +++ b/src/plugins/qmldesigner/components/itemlibrary/qml/Scrollbar.qml @@ -38,6 +38,10 @@ Item { property variant flickable + function scroll(delta) { + handle.y = Math.max(0, Math.min(scrollHeight, handle.y + delta)) + } + function reset() { handle.y = 0 } @@ -100,7 +104,7 @@ Item { anchors.right: parent.right anchors.top: parent.top anchors.bottom: handle.top - onClicked: handle.y = Math.max(0, handle.y - style.scrollbarClickScrollAmount) + onClicked: scroll(-style.scrollbarClickScrollAmount) } Item { @@ -151,6 +155,6 @@ Item { anchors.right: parent.right anchors.top: handle.bottom anchors.bottom: parent.bottom - onClicked: handle.y = Math.min(scrollHeight, handle.y + style.scrollbarClickScrollAmount) + onClicked: scroll(style.scrollbarClickScrollAmount) } } diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp index 6e45efb7f8991a4dd1c67eb1d92909dea3333eab..a95e1be6282b9c337f9744ebaaf2865a5d30c584 100644 --- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp +++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp @@ -636,6 +636,8 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, context->enterScope(astNode); QSet<QString> modelPropertyNames = QSet<QString>::fromList(modelNode.propertyNames()); + if (!modelNode.id().isEmpty()) + modelPropertyNames.insert(QLatin1String("id")); QList<UiObjectMember *> defaultPropertyItems; for (UiObjectMemberList *iter = astInitializer->members; iter; iter = iter->next) { @@ -744,7 +746,10 @@ void TextToModelMerger::syncNode(ModelNode &modelNode, AbstractProperty modelProperty = modelNode.property(modelPropertyName); // property deleted. - differenceHandler.propertyAbsentFromQml(modelProperty); + if (modelPropertyName == QLatin1String("id")) + differenceHandler.idsDiffer(modelNode, QString()); + else + differenceHandler.propertyAbsentFromQml(modelProperty); } context->leaveScope(); diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 1cbf524fe6305b625c2374e644c865825d4fd2f2..0e65e689fdf3cac24afc642a2e9fee462d74d8a6 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -258,7 +258,7 @@ bool QmlProject::fromMap(const QVariantMap &map) refresh(Everything); // 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) runConfig->changeCurrentFile(0); diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index da51b8bc591811592d141807eee8bd50ecd1bca2..3b959f83af023b2a768f511780df1c3d43843039 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -85,12 +85,7 @@ bool QmlProjectRunConfiguration::isEnabled(ProjectExplorer::BuildConfiguration * { Q_UNUSED(bc); - if (!QFile::exists(mainScript()) - || !Core::ICore::instance()->mimeDatabase()->findByFile(mainScript()).matchesType(QLatin1String("application/x-qml"))) - { - return false; - } - return true; + return m_isEnabled; } void QmlProjectRunConfiguration::ctor() @@ -326,15 +321,17 @@ void QmlProjectRunConfiguration::changeCurrentFile(Core::IEditor *editor) bool enable = false; if (editor) { 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; - } 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. foreach(const QString& filename, m_projectTarget->qmlProject()->files()) { const QFileInfo fi(filename); 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; enable = true; diff --git a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui index 9f03d493557ab5546e66d5c78e71cd75d7d3fe7c..616c897e0f705596309cd2ee48505440c49b4e94 100644 --- a/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui +++ b/src/plugins/qt4projectmanager/gettingstartedwelcomepagewidget.ui @@ -62,7 +62,6 @@ </item> <item row="1" column="0"> <widget class="Utils::WelcomeModeTreeWidget" name="tutorialTreeWidget" native="true"> - <zorder></zorder> </widget> </item> </layout> diff --git a/src/plugins/qt4projectmanager/makestep.cpp b/src/plugins/qt4projectmanager/makestep.cpp index fb3184ac82bc8c3a791e882e77b6cf7c8dea9ecb..02eaf9832ff666f7ba107b3603bb7b66c098a4c9 100644 --- a/src/plugins/qt4projectmanager/makestep.cpp +++ b/src/plugins/qt4projectmanager/makestep.cpp @@ -135,8 +135,9 @@ bool MakeStep::init() // Try to detect command in environment const QString tmp = environment.searchInPath(makeCmd); if (tmp.isEmpty()) { - emit addOutput(tr("<font color=\"#ff0000\">Could not find make command: %1 "\ - "in the build environment</font>").arg(makeCmd)); + QTextCharFormat textCharFormat; + textCharFormat.setForeground(Qt::red); + emit addOutput(tr("Could not find make command: %1 in the build environment").arg(makeCmd), textCharFormat); return false; } makeCmd = tmp; diff --git a/src/plugins/qt4projectmanager/profilereader.cpp b/src/plugins/qt4projectmanager/profilereader.cpp index 3781fc37d057ba98342cee419e01f17bf080a3c4..ecd53ee51c88946fff9beb499448f2c2ce635023 100644 --- a/src/plugins/qt4projectmanager/profilereader.cpp +++ b/src/plugins/qt4projectmanager/profilereader.cpp @@ -48,7 +48,8 @@ ProFileReader::~ProFileReader() bool ProFileReader::readProFile(const QString &fileName) { if (ProFile *pro = parsedProFile(fileName)) { - aboutToEval(pro); + m_ignoreLevel = 0; + aboutToEval(0, pro, EvalIncludeFile); bool ok = accept(pro); pro->deref(); return ok; @@ -56,15 +57,23 @@ bool ProFileReader::readProFile(const QString &fileName) 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_proFiles.append(pro); pro->ref(); } } +void ProFileReader::doneWithEval(ProFile *) +{ + if (m_ignoreLevel) + m_ignoreLevel--; +} + QList<ProFile*> ProFileReader::includeFiles() const { QString qmakeMkSpecDir = QFileInfo(propertyValue("QMAKE_MKSPECS")).absoluteFilePath(); diff --git a/src/plugins/qt4projectmanager/profilereader.h b/src/plugins/qt4projectmanager/profilereader.h index b749bc3e569455525a0bf536e2123da1aa672c5d..1019be7870af6c07622e0dc1261bdb973f7bb071 100644 --- a/src/plugins/qt4projectmanager/profilereader.h +++ b/src/plugins/qt4projectmanager/profilereader.h @@ -58,7 +58,8 @@ signals: void errorFound(const QString &error); 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 fileMessage(const QString &msg); virtual void errorMessage(const QString &msg); @@ -66,6 +67,7 @@ private: private: QMap<QString, ProFile *> m_includeFiles; QList<ProFile *> m_proFiles; + int m_ignoreLevel; }; class ProFileCacheManager : public QObject diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 9b42e389bd66023a89365268e04d1024eb6d5809..12629bf29618c3e19e73ba0b7c7692f0fea7e5d8 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -198,13 +198,17 @@ void QMakeStep::run(QFutureInterface<bool> &fi) canContinue = false; } 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); return; } 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); return; } diff --git a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp index 192e039635ea75c0ca76e47fd538765ec5974bf9..ffd6750e53e92635fe76f7866bfb52f0346a3450 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/maemopackagecreationstep.cpp @@ -114,7 +114,8 @@ bool MaemoPackageCreationStep::createPackage() if (!packagingNeeded()) return true; - emit addOutput(tr("Creating package file ...")); + QTextCharFormat textCharFormat; + emit addOutput(tr("Creating package file ..."), textCharFormat); QFile configFile(targetRoot() % QLatin1String("/config.sh")); if (!configFile.open(QIODevice::ReadOnly)) { raiseError(tr("Cannot open MADDE config file '%1'.") @@ -214,14 +215,15 @@ bool MaemoPackageCreationStep::createPackage() return false; } - emit addOutput(tr("Package created.")); + emit addOutput(tr("Package created."), textCharFormat); m_packageContents->setUnModified(); return true; } 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; #ifdef Q_OS_WIN perl = maddeRoot() + QLatin1String("/bin/perl.exe "); @@ -332,7 +334,8 @@ QString MaemoPackageCreationStep::nativePath(const QFile &file) const void MaemoPackageCreationStep::raiseError(const QString &shortMsg, 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, TASK_CATEGORY_BUILDSYSTEM)); } diff --git a/src/plugins/qt4projectmanager/qt4nodes.cpp b/src/plugins/qt4projectmanager/qt4nodes.cpp index 1c524d70f2ef00f1f331c57eb3da06673b306254..a04d22189eac15d737f9d9c04376bbc623eee039 100644 --- a/src/plugins/qt4projectmanager/qt4nodes.cpp +++ b/src/plugins/qt4projectmanager/qt4nodes.cpp @@ -530,9 +530,9 @@ void Qt4PriFileNode::update(ProFile *includeFileExact, ProFileReader *readerExac newFilePaths += readerCumulative->absoluteFileValues(qmakeVariable, projectDir, vPathsCumulative, includeFileCumlative); } - newFilePaths.removeDuplicates(); if (!newFilePaths.isEmpty()) { + newFilePaths.removeDuplicates(); InternalNode *subfolder = new InternalNode; subfolder->type = type; subfolder->icon = fileTypes.at(i).icon; @@ -1502,16 +1502,15 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const const QString subDirKey = subDirVar + QLatin1String(".subdir"); const QString subDirFileKey = subDirVar + QLatin1String(".file"); if (reader->contains(subDirKey)) - realDir = QFileInfo(reader->value(subDirKey)).filePath(); + realDir = reader->value(subDirKey); else if (reader->contains(subDirFileKey)) - realDir = QFileInfo(reader->value(subDirFileKey)).filePath(); + realDir = reader->value(subDirFileKey); else realDir = subDirVar; QFileInfo info(realDir); - if (!info.isAbsolute()) { + if (!info.isAbsolute()) info.setFile(m_projectDir + QLatin1Char('/') + realDir); - realDir = m_projectDir + QLatin1Char('/') + realDir; - } + realDir = info.filePath(); QString realFile; if (info.isDir()) { @@ -1521,14 +1520,14 @@ QStringList Qt4ProFileNode::subDirsPaths(ProFileReader *reader) const } if (QFile::exists(realFile)) { - if (!subProjectPaths.contains(realFile)) - subProjectPaths << realFile; + subProjectPaths << realFile; } else { m_project->proFileParseError(tr("Could not find .pro file for sub dir '%1' in '%2'") .arg(subDirVar).arg(realDir)); } } + subProjectPaths.removeDuplicates(); return subProjectPaths; } diff --git a/src/plugins/texteditor/icompletioncollector.cpp b/src/plugins/texteditor/icompletioncollector.cpp index 0d4dd1296673f4c5fc38bd370a083349122097d4..c6f6713aed7c971599d80b4078aec4dc6e51f619 100644 --- a/src/plugins/texteditor/icompletioncollector.cpp +++ b/src/plugins/texteditor/icompletioncollector.cpp @@ -41,7 +41,7 @@ using namespace TextEditor::Internal; namespace TextEditor { namespace Internal { -struct ICompletionCollectorPrivate +class ICompletionCollectorPrivate { public: CompletionSettings m_completionSettings; diff --git a/src/shared/proparser/ioutils.cpp b/src/shared/proparser/ioutils.cpp index 8a2c9112d28ba65d3187101948172d9c55aa7d01..f43c29aa9ae9a2df78c7e9f7bfe2f67a207b59eb 100644 --- a/src/shared/proparser/ioutils.cpp +++ b/src/shared/proparser/ioutils.cpp @@ -52,7 +52,7 @@ IoUtils::FileType IoUtils::fileType(const QString &fileName) return (attr & FILE_ATTRIBUTE_DIRECTORY) ? FileIsDir : FileIsRegular; #else struct ::stat st; - if (::stat(fileName.toLatin1().constData(), &st)) // latin1 symmetric to the file reader + if (::stat(fileName.toLocal8Bit().constData(), &st)) return FileNotFound; return S_ISDIR(st.st_mode) ? FileIsDir : FileIsRegular; #endif diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index c33069b90d692734650f8ee0d236b33f74769013..a9217a1ac2db2ce8ee706201228818917f321c52 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -140,7 +140,7 @@ ProFileOption::ProFileOption() dirlist_sep = QLatin1Char(':'); dir_sep = QLatin1Char('/'); #endif - qmakespec = QString::fromLatin1(qgetenv("QMAKESPEC").data()); + qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").data()); #if defined(Q_OS_WIN32) target_mode = TARG_WIN_MODE; @@ -292,6 +292,7 @@ public: VisitReturn evaluateConditionalFunction(const ProString &function, const ProStringList &args); ProFile *parsedProFile(const QString &fileName, bool cache, const QString &contents = QString()); + bool evaluateFileDirect(const QString &fileName, ProFileEvaluator::EvalFileType type); bool evaluateFile(const QString &fileName); bool evaluateFeatureFile(const QString &fileName, QHash<ProString, ProStringList> *values = 0, FunctionDefs *defs = 0); @@ -572,7 +573,7 @@ bool ProFileEvaluator::Private::read(ProFile *pro) return false; } - QString content(QString::fromLatin1(file.readAll())); // yes, really latin1 + QString content(QString::fromLocal8Bit(file.readAll())); file.close(); m_lineNo = 1; m_profileStack.push(pro); @@ -2138,10 +2139,10 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::visitProFile(P if (m_option->qmakespec_name == QLatin1String("default")) { #ifdef Q_OS_UNIX 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) m_option->qmakespec_name = - IoUtils::fileName(QString::fromLatin1(buffer, l)).toString(); + IoUtils::fileName(QString::fromLocal8Bit(buffer, l)).toString(); #else // 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 @@ -2542,7 +2543,7 @@ ProStringList ProFileEvaluator::Private::expandVariableReferences( ProStringList replacement; if (var_type == ENVIRON) { replacement = split_value_list(QString::fromLocal8Bit(qgetenv( - var.toQString(m_tmp1).toLatin1().constData()))); + var.toQString(m_tmp1).toLocal8Bit().constData()))); } else if (var_type == PROPERTY) { replacement << ProString(propertyValue(var.toQString(m_tmp1)), NoHash); } else if (var_type == FUNCTION) { @@ -3050,9 +3051,9 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( logMessage(format("system(execute) requires one or two arguments.")); } else { char buff[256]; - FILE *proc = QT_POPEN((QLatin1String("cd ") + FILE *proc = QT_POPEN(QString(QLatin1String("cd ") + IoUtils::shellQuote(currentDirectory()) - + QLatin1String(" && ") + args[0]).toLatin1(), "r"); + + QLatin1String(" && ") + args[0]).toLocal8Bit(), "r"); bool singleLine = true; if (args.count() > 1) singleLine = isTrue(args.at(1), m_tmp2); @@ -3066,7 +3067,7 @@ ProStringList ProFileEvaluator::Private::evaluateExpandFunction( buff[i] = ' '; } buff[read_in] = '\0'; - output += QLatin1String(buff); + output += QString::fromLocal8Bit(buff); } ret += split_value_list(output); if (proc) @@ -3634,7 +3635,7 @@ ProFileEvaluator::Private::VisitReturn ProFileEvaluator::Private::evaluateCondit } return returnBool(system((QLatin1String("cd ") + IoUtils::shellQuote(currentDirectory()) - + QLatin1String(" && ") + args.at(0)).toLatin1().constData()) == 0); + + QLatin1String(" && ") + args.at(0)).toLocal8Bit().constData()) == 0); } #endif 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_arch: what = name.machine; break; } - ret = QString::fromLatin1(what); + ret = QString::fromLocal8Bit(what); } } #endif @@ -3913,19 +3914,14 @@ ProFile *ProFileEvaluator::Private::parsedProFile(const QString &fileName, bool return pro; } -bool ProFileEvaluator::Private::evaluateFile(const QString &fileName) +bool ProFileEvaluator::Private::evaluateFileDirect( + const QString &fileName, ProFileEvaluator::EvalFileType type) { - if (fileName.isEmpty()) - return false; - foreach (const ProFile *pf, m_profileStack) - if (pf->fileName() == fileName) { - errorMessage(format("circular inclusion of %1").arg(fileName)); - return false; - } int lineNo = m_lineNo; if (ProFile *pro = parsedProFile(fileName, true)) { - q->aboutToEval(pro); + q->aboutToEval(currentProFile(), pro, type); bool ok = (visitProFile(pro) == ReturnTrue); + q->doneWithEval(currentProFile()); pro->deref(); m_lineNo = lineNo; return ok; @@ -3935,6 +3931,18 @@ bool ProFileEvaluator::Private::evaluateFile(const QString &fileName) } } +bool ProFileEvaluator::Private::evaluateFile(const QString &fileName) +{ + if (fileName.isEmpty()) + return false; + foreach (const ProFile *pf, m_profileStack) + if (pf->fileName() == fileName) { + errorMessage(format("circular inclusion of %1").arg(fileName)); + return false; + } + return evaluateFileDirect(fileName, ProFileEvaluator::EvalIncludeFile); +} + bool ProFileEvaluator::Private::evaluateFeatureFile( const QString &fileName, QHash<ProString, ProStringList> *values, FunctionDefs *funcs) { @@ -3980,15 +3988,8 @@ bool ProFileEvaluator::Private::evaluateFeatureFile( bool cumulative = m_cumulative; m_cumulative = false; - // Don't use evaluateFile() here to avoid calling aboutToEval(). // The path is fully normalized already. - bool ok = false; - int lineNo = m_lineNo; - if (ProFile *pro = parsedProFile(fn, true)) { - ok = (visitProFile(pro) == ReturnTrue); - pro->deref(); - } - m_lineNo = lineNo; + bool ok = evaluateFileDirect(fn, ProFileEvaluator::EvalFeatureFile); m_cumulative = cumulative; return ok; @@ -4174,7 +4175,11 @@ QString ProFileEvaluator::propertyValue(const QString &name) const return d->propertyValue(name); } -void ProFileEvaluator::aboutToEval(ProFile *) +void ProFileEvaluator::aboutToEval(ProFile *, ProFile *, EvalFileType) +{ +} + +void ProFileEvaluator::doneWithEval(ProFile *) { } diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 60890f5f3d960cc938e20858791db4fa807562a3..d956cc1d4111906e57f84e26cbfb939fd2a82f7b 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -99,7 +99,9 @@ public: QString propertyValue(const QString &val) const; // 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 errorMessage(const QString &msg); // .pro parse errors virtual void fileMessage(const QString &msg); // error() and message() from .pro file diff --git a/tests/auto/qml/qmldesigner/coretests/testcore.cpp b/tests/auto/qml/qmldesigner/coretests/testcore.cpp index 89429e2a92cdb48e7a819392c3f0b7607c1a9c37..b3a36212ce4c1213a038ee9f8741e4b4e4fa35b7 100644 --- a/tests/auto/qml/qmldesigner/coretests/testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/testcore.cpp @@ -5426,6 +5426,38 @@ void TestCore::testRewriterChangeId() 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() { const char* qmlString = "import Qt 4.7\nRectangle { x: 10; y: 10 }"; diff --git a/tests/auto/qml/qmldesigner/coretests/testcore.h b/tests/auto/qml/qmldesigner/coretests/testcore.h index f3cbc8ebe8e6ae725d0165015d6eab96202f6f88..685a1e6a729b01cf7169cf8a140c79e1b678fefe 100644 --- a/tests/auto/qml/qmldesigner/coretests/testcore.h +++ b/tests/auto/qml/qmldesigner/coretests/testcore.h @@ -87,6 +87,7 @@ private slots: void testRewriterView(); void testRewriterErrors(); void testRewriterChangeId(); + void testRewriterRemoveId(); void testRewriterChangeValueProperty(); void testRewriterRemoveValueProperty(); void testRewriterSignalProperty(); diff --git a/tests/auto/qml/qmldesigner/coretests/testrewriterview.cpp b/tests/auto/qml/qmldesigner/coretests/testrewriterview.cpp index b12c164a6de808a31e7799b8cb7000d1637261c2..eb3cf27b80b1d8a3ef7e8c8a630c5af9c99add6d 100644 --- a/tests/auto/qml/qmldesigner/coretests/testrewriterview.cpp +++ b/tests/auto/qml/qmldesigner/coretests/testrewriterview.cpp @@ -83,7 +83,9 @@ VariantProperty TestModelToTextMerger::findAddedVariantProperty(const VariantPro return VariantProperty(); } -TestRewriterView::TestRewriterView(QObject *parent) : RewriterView(RewriterView::Validate, parent) +TestRewriterView::TestRewriterView(QObject *parent, + DifferenceHandling differenceHandling) + : RewriterView(differenceHandling, parent) { } diff --git a/tests/auto/qml/qmldesigner/coretests/testrewriterview.h b/tests/auto/qml/qmldesigner/coretests/testrewriterview.h index 0fa319f21994b111e6c63b2009e248060f1b9df4..c313fe5bed9cb6e1764a5374d34978b64e50ed94 100644 --- a/tests/auto/qml/qmldesigner/coretests/testrewriterview.h +++ b/tests/auto/qml/qmldesigner/coretests/testrewriterview.h @@ -53,7 +53,8 @@ class TestRewriterView : public RewriterView Q_OBJECT public: - TestRewriterView(QObject *parent = 0); + TestRewriterView(QObject *parent = 0, + DifferenceHandling differenceHandling = RewriterView::Validate); Internal::TestModelToTextMerger *modelToTextMerger() const; Internal::TextToModelMerger *textToModelMerger() const;