diff --git a/scripts/snapshots/cleanup_snapshots.sh b/scripts/snapshots/cleanup_snapshots.sh index f239cc1af0e2fd831c6f556cc5b26ca5912e0cd1..db283edd4418fa71447dbbf0c6c55225bf5c3501 100755 --- a/scripts/snapshots/cleanup_snapshots.sh +++ b/scripts/snapshots/cleanup_snapshots.sh @@ -2,8 +2,8 @@ ## Open script-dir-homed subshell ( -ABS_SCRIPT_DIR=`pwd`/`dirname "$0"` -cd "${ABS_SCRIPT_DIR}" +ABS_SCRIPT_DIR=$(cd $(dirname $(which "$0")) && pwd) +cd "${ABS_SCRIPT_DIR}" || exit 1 ## Internal config diff --git a/shared/proparser/profileevaluator.cpp b/shared/proparser/profileevaluator.cpp index b7c296420af09942bdcb6a4b5e7a71906abb3939..ea280b45b4dace722a69496d8376d7d07f5b09bb 100644 --- a/shared/proparser/profileevaluator.cpp +++ b/shared/proparser/profileevaluator.cpp @@ -530,11 +530,15 @@ bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block) if (!m_skipLevel) { m_prevCondition = m_condition; m_condition = ConditionFalse; + } else { + Q_ASSERT(m_condition != ConditionTrue); } } else if (block->blockKind() & ProBlock::ScopeContentsKind) { m_updateCondition = false; if (m_condition != ConditionTrue) ++m_skipLevel; + else + Q_ASSERT(!m_skipLevel); } return true; } @@ -542,8 +546,14 @@ bool ProFileEvaluator::Private::visitBeginProBlock(ProBlock *block) bool ProFileEvaluator::Private::visitEndProBlock(ProBlock *block) { if (block->blockKind() & ProBlock::ScopeContentsKind) { - if (m_skipLevel) + if (m_skipLevel) { + Q_ASSERT(m_condition != ConditionTrue); --m_skipLevel; + } else { + // Conditionals contained inside this block may have changed the state. + // So we reset it here to make an else following us do the right thing. + m_condition = ConditionTrue; + } } return true; } @@ -572,8 +582,12 @@ bool ProFileEvaluator::Private::visitProCondition(ProCondition *cond) { if (!m_skipLevel) { if (cond->text().toLower() == QLatin1String("else")) { + // The state ConditionElse makes sure that subsequential elses are ignored. + // That's braindead, but qmake is like that. if (m_prevCondition == ConditionTrue) m_condition = ConditionElse; + else if (m_prevCondition == ConditionFalse) + m_condition = ConditionTrue; } else if (m_condition == ConditionFalse) { if (isActiveConfig(cond->text(), true) ^ m_invertNext) m_condition = ConditionTrue; @@ -807,7 +821,7 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value) bool ProFileEvaluator::Private::visitProFunction(ProFunction *func) { - if (!m_skipLevel && (!m_updateCondition || m_condition == ConditionFalse)) { + if (!m_updateCondition || m_condition == ConditionFalse) { QString text = func->text(); int lparen = text.indexOf(QLatin1Char('(')); int rparen = text.lastIndexOf(QLatin1Char(')')); @@ -815,10 +829,12 @@ bool ProFileEvaluator::Private::visitProFunction(ProFunction *func) QString arguments = text.mid(lparen + 1, rparen - lparen - 1); QString funcName = text.left(lparen); m_lineNo = func->lineNumber(); - bool result = false; - if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result)) + bool result; + if (!evaluateConditionalFunction(funcName.trimmed(), arguments, &result)) { + m_invertNext = false; return false; - if (result ^ m_invertNext) + } + if (!m_skipLevel && (result ^ m_invertNext)) m_condition = ConditionTrue; } m_invertNext = false; @@ -1556,7 +1572,7 @@ QStringList ProFileEvaluator::Private::evaluateExpandFunction(const QString &fun } break; case 0: - q->logMessage(format("'%1' is not a function").arg(func)); + q->logMessage(format("'%1' is not a recognized replace function").arg(func)); break; default: q->logMessage(format("Function '%1' is not implemented").arg(func)); @@ -1577,26 +1593,67 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct for (int i = 0; i < argumentsList.count(); ++i) args += expandVariableReferences(argumentsList[i]).join(sep); - enum ConditionFunc { CF_CONFIG = 1, CF_CONTAINS, CF_COUNT, CF_EXISTS, CF_INCLUDE, - CF_LOAD, CF_ISEMPTY, CF_SYSTEM, CF_MESSAGE}; + enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, + T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, + T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE, + T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_MESSAGE, T_IF }; static QHash<QString, int> *functions = 0; if (!functions) { functions = new QHash<QString, int>; - functions->insert(QLatin1String("load"), CF_LOAD); //v - functions->insert(QLatin1String("include"), CF_INCLUDE); //v - functions->insert(QLatin1String("message"), CF_MESSAGE); //v - functions->insert(QLatin1String("warning"), CF_MESSAGE); //v - functions->insert(QLatin1String("error"), CF_MESSAGE); //v + functions->insert(QLatin1String("requires"), T_REQUIRES); + functions->insert(QLatin1String("greaterThan"), T_GREATERTHAN); + functions->insert(QLatin1String("lessThan"), T_LESSTHAN); + functions->insert(QLatin1String("equals"), T_EQUALS); + functions->insert(QLatin1String("isEqual"), T_EQUALS); + functions->insert(QLatin1String("exists"), T_EXISTS); + functions->insert(QLatin1String("export"), T_EXPORT); + functions->insert(QLatin1String("clear"), T_CLEAR); + functions->insert(QLatin1String("unset"), T_UNSET); + functions->insert(QLatin1String("eval"), T_EVAL); + functions->insert(QLatin1String("CONFIG"), T_CONFIG); + functions->insert(QLatin1String("if"), T_IF); + functions->insert(QLatin1String("isActiveConfig"), T_CONFIG); + functions->insert(QLatin1String("system"), T_SYSTEM); + functions->insert(QLatin1String("return"), T_RETURN); + functions->insert(QLatin1String("break"), T_BREAK); + functions->insert(QLatin1String("next"), T_NEXT); + functions->insert(QLatin1String("defined"), T_DEFINED); + functions->insert(QLatin1String("contains"), T_CONTAINS); + functions->insert(QLatin1String("infile"), T_INFILE); + functions->insert(QLatin1String("count"), T_COUNT); + functions->insert(QLatin1String("isEmpty"), T_ISEMPTY); + functions->insert(QLatin1String("load"), T_LOAD); //v + functions->insert(QLatin1String("include"), T_INCLUDE); //v + functions->insert(QLatin1String("debug"), T_DEBUG); + functions->insert(QLatin1String("message"), T_MESSAGE); //v + functions->insert(QLatin1String("warning"), T_MESSAGE); //v + functions->insert(QLatin1String("error"), T_MESSAGE); //v } bool cond = false; bool ok = true; - ConditionFunc func_t = (ConditionFunc)functions->value(function); + TestFunc func_t = (TestFunc)functions->value(function); switch (func_t) { - case CF_CONFIG: { +#if 0 + case T_INFILE: + case T_REQUIRES: + case T_GREATERTHAN: + case T_LESSTHAN: + case T_EQUALS: + case T_EXPORT: + case T_CLEAR: + case T_UNSET: + case T_EVAL: + case T_IF: + case T_RETURN: + case T_BREAK: + case T_NEXT: + case T_DEFINED: +#endif + case T_CONFIG: { if (args.count() < 1 || args.count() > 2) { q->logMessage(format("CONFIG(config) requires one or two arguments.")); ok = false; @@ -1618,7 +1675,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct } break; } - case CF_CONTAINS: { + case T_CONTAINS: { if (args.count() < 2 || args.count() > 3) { q->logMessage(format("contains(var, val) requires two or three arguments.")); ok = false; @@ -1650,9 +1707,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct break; } - case CF_COUNT: { + case T_COUNT: { if (args.count() != 2 && args.count() != 3) { - q->logMessage(format("count(var, count) requires two or three arguments.")); + q->logMessage(format("count(var, count, op=\"equals\") requires two or three arguments.")); ok = false; break; } @@ -1677,7 +1734,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct cond = values(args.first()).count() == args[1].toInt(); break; } - case CF_INCLUDE: { + case T_INCLUDE: { + if (m_skipLevel && !m_cumulative) + break; QString parseInto; if (args.count() == 2) { parseInto = args[1]; @@ -1693,7 +1752,9 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct ok = evaluateFile(fileName, &ok); break; } - case CF_LOAD: { + case T_LOAD: { + if (m_skipLevel && !m_cumulative) + break; QString parseInto; bool ignore_error = false; if (args.count() == 2) { @@ -1707,13 +1768,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct ok = evaluateFeatureFile( args.first(), &cond); break; } - case CF_MESSAGE: { + case T_DEBUG: + // Yup - do nothing. Nothing is going to enable debug output anyway. + break; + case T_MESSAGE: { if (args.count() != 1) { q->logMessage(format("%1(message) requires one argument.").arg(function)); ok = false; break; } - QString msg = args.first(); + QString msg = fixEnvVariables(args.first()); if (function == QLatin1String("error")) { QStringList parents; foreach (ProFile *proFile, m_profileStack) @@ -1730,7 +1794,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct } break; } - case CF_SYSTEM: { +#if 0 // Way too dangerous to enable. + case T_SYSTEM: { if (args.count() != 1) { q->logMessage(format("system(exec) requires one argument.")); ok = false; @@ -1739,7 +1804,8 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct ok = system(args.first().toLatin1().constData()) == 0; break; } - case CF_ISEMPTY: { +#endif + case T_ISEMPTY: { if (args.count() != 1) { q->logMessage(format("isEmpty(var) requires one argument.")); ok = false; @@ -1754,7 +1820,7 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct } break; } - case CF_EXISTS: { + case T_EXISTS: { if (args.count() != 1) { q->logMessage(format("exists(file) requires one argument.")); ok = false; @@ -1778,6 +1844,13 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct break; } + case 0: + // This is too chatty currently (missing defineTest and defineReplace) + //q->logMessage(format("'%1' is not a recognized test function").arg(function)); + break; + default: + q->logMessage(format("Function '%1' is not implemented").arg(function)); + break; } if (result) @@ -1975,7 +2048,13 @@ bool ProFileEvaluator::Private::evaluateFeatureFile(const QString &fileName, boo break; } } - return fn.isEmpty() ? false : evaluateFile(fn, result); + if (fn.isEmpty()) + return false; + bool cumulative = m_cumulative; + m_cumulative = false; + bool ok = evaluateFile(fn, result); + m_cumulative = cumulative; + return ok; } void ProFileEvaluator::Private::expandPatternHelper(const QString &relName, const QString &absName, @@ -2085,14 +2164,23 @@ bool ProFileEvaluator::contains(const QString &variableName) const return d->m_valuemap.contains(variableName); } +inline QStringList fixEnvVariables(const QStringList &x) +{ + QStringList ret; + foreach (const QString &str, x) + ret << Option::fixString(str, Option::FixEnvVars); + return ret; +} + + QStringList ProFileEvaluator::values(const QString &variableName) const { - return d->values(variableName); + return fixEnvVariables(d->values(variableName)); } QStringList ProFileEvaluator::values(const QString &variableName, const ProFile *pro) const { - return d->values(variableName, pro); + return fixEnvVariables(d->values(variableName, pro)); } ProFileEvaluator::TemplateType ProFileEvaluator::templateType() diff --git a/shared/proparser/proparserutils.h b/shared/proparser/proparserutils.h index daab115a4476345da7c6136cf252595dedc9adc6..6705ffad39f33a8bdf0a939dae89313c7ad4f4c7 100644 --- a/shared/proparser/proparserutils.h +++ b/shared/proparser/proparserutils.h @@ -173,7 +173,12 @@ static QStringList replaceInList(const QStringList &varList, const QRegExp ®e } */ -inline QStringList splitPathList(const QString paths) +inline QString fixEnvVariables(const QString &x) +{ + return Option::fixString(x, Option::FixEnvVars); +} + +inline QStringList splitPathList(const QString &paths) { return paths.split(Option::dirlist_sep); } diff --git a/src/app/Info.plist b/src/app/Info.plist index dbd50d35ee1b61224c66145c055aa5138ef5ae37..43dd8e772f514308145eaf421f6ea8fddc86bdec 100644 --- a/src/app/Info.plist +++ b/src/app/Info.plist @@ -182,8 +182,8 @@ <key>CFBundleIdentifier</key> <string>com.nokia.qtcreator</string> <key>CFBundleVersion</key> - <string>0.9.1</string> + <string>0.9.2</string> <key>CFBundleShortVersionString</key> - <string>0.9.1</string> + <string>0.9.2</string> </dict> </plist> diff --git a/src/libs/cplusplus/CppDocument.h b/src/libs/cplusplus/CppDocument.h index 57efe4fe33f85995fdd89d869dda4ee3ee6a1735..98b5ed1a2ade01217d61dc954b38e6bee3e14239 100644 --- a/src/libs/cplusplus/CppDocument.h +++ b/src/libs/cplusplus/CppDocument.h @@ -138,10 +138,10 @@ public: QString fileName() const { return _fileName; } - int line() const + unsigned line() const { return _line; } - int column() const + unsigned column() const { return _column; } QString text() const @@ -150,8 +150,8 @@ public: private: int _level; QString _fileName; - int _line; - int _column; + unsigned _line; + unsigned _column; QString _text; }; diff --git a/src/libs/cplusplus/TypeOfExpression.cpp b/src/libs/cplusplus/TypeOfExpression.cpp index ba088a056ec8d42a7f2ade49903429edf3a40e6d..46c2042d0f3f44262e277a8e769bc6bfa0b3589f 100644 --- a/src/libs/cplusplus/TypeOfExpression.cpp +++ b/src/libs/cplusplus/TypeOfExpression.cpp @@ -70,6 +70,12 @@ QList<TypeOfExpression::Result> TypeOfExpression::operator()(const QString &expr return resolveExpression(m_ast); } +QString TypeOfExpression::preprocess(const QString &expression, + Document::Ptr document) const +{ + return preprocessedExpression(expression, m_snapshot, document); +} + ExpressionAST *TypeOfExpression::ast() const { return m_ast; diff --git a/src/libs/cplusplus/TypeOfExpression.h b/src/libs/cplusplus/TypeOfExpression.h index 34ad0943e40248a4e431b9c5ee57cefc3074792f..c0eafb2e37f047258c50fa61ea9b6bc66c745357 100644 --- a/src/libs/cplusplus/TypeOfExpression.h +++ b/src/libs/cplusplus/TypeOfExpression.h @@ -84,6 +84,8 @@ public: Symbol *lastVisibleSymbol, PreprocessMode mode = NoPreprocess); + QString preprocess(const QString &expression, Document::Ptr document) const; + /** * Returns the AST of the last evaluated expression. */ diff --git a/src/plugins/bineditor/BinEditor.pluginspec b/src/plugins/bineditor/BinEditor.pluginspec index 4c79a18f251869d5c232cff4c4c5ec3f7023d583..499dc23e10be7308fad35662934eca0d8b309ef6 100644 --- a/src/plugins/bineditor/BinEditor.pluginspec +++ b/src/plugins/bineditor/BinEditor.pluginspec @@ -1,11 +1,11 @@ -<plugin name="BinEditor" version="0.9.1" compatVersion="0.9.1"> +<plugin name="BinEditor" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Binary editor component.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/bookmarks/Bookmarks.pluginspec b/src/plugins/bookmarks/Bookmarks.pluginspec index e6ef924e483020feb3374b5182fd7bfc85713512..35f196fb9cb8c930d58a10c7cc7c85699fa2ece1 100644 --- a/src/plugins/bookmarks/Bookmarks.pluginspec +++ b/src/plugins/bookmarks/Bookmarks.pluginspec @@ -1,12 +1,12 @@ -<plugin name="Bookmarks" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Bookmarks" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Bookmarks in text editors.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec index 84eefae0ee83a7d2fa7f948cc529bba8578ddc51..567839e781bfaeb23c69f5b91198afffbe7e3724 100644 --- a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec +++ b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec @@ -1,14 +1,14 @@ -<plugin name="CMakeProjectManager" version="0.9.1" compatVersion="0.9.1"> +<plugin name="CMakeProjectManager" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>### TODO</license> <description>CMake support</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="CppTools" version="0.9.1"/> - <dependency name="CppEditor" version="0.9.1"/> - <dependency name="Help" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="CppTools" version="0.9.2"/> + <dependency name="CppEditor" version="0.9.2"/> + <dependency name="Help" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/coreplugin/Core.pluginspec b/src/plugins/coreplugin/Core.pluginspec index ef7a7e38f0a3b30c04d92f12d7f4ad0aa220ac42..e771f21ec2f7f4589789f1d3106caef94a9e1525 100644 --- a/src/plugins/coreplugin/Core.pluginspec +++ b/src/plugins/coreplugin/Core.pluginspec @@ -1,4 +1,4 @@ -<plugin name="Core" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Core" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h index 41e00202e53ae384d55d47bb83b9f5246b946a14..857dd5be370f5908167db3e9743736b665cdb52c 100644 --- a/src/plugins/coreplugin/coreconstants.h +++ b/src/plugins/coreplugin/coreconstants.h @@ -41,7 +41,7 @@ namespace Constants { #define IDE_VERSION_MAJOR 0 #define IDE_VERSION_MINOR 9 -#define IDE_VERSION_RELEASE 1 +#define IDE_VERSION_RELEASE 2 #define STRINGIFY_INTERNAL(x) #x #define STRINGIFY(x) STRINGIFY_INTERNAL(x) diff --git a/src/plugins/cpaster/CodePaster.pluginspec b/src/plugins/cpaster/CodePaster.pluginspec index 7f3e1261af8b9d0edda97306e3a2997396f23613..4d03eff8e3ef8c884603f3fa02663dbe20464436 100644 --- a/src/plugins/cpaster/CodePaster.pluginspec +++ b/src/plugins/cpaster/CodePaster.pluginspec @@ -1,12 +1,12 @@ -<plugin name="CodePaster" version="0.9.1" compatVersion="0.9.1"> +<plugin name="CodePaster" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Codepaster plugin for pushing/fetching diff from server</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/cppeditor/CppEditor.pluginspec b/src/plugins/cppeditor/CppEditor.pluginspec index 992f655d95b46a63f56e52d2f3f21b649976dd8d..c7fcd714e4f46a19add1e1c0f2586b7c9d673f4c 100644 --- a/src/plugins/cppeditor/CppEditor.pluginspec +++ b/src/plugins/cppeditor/CppEditor.pluginspec @@ -1,12 +1,12 @@ -<plugin name="CppEditor" version="0.9.1" compatVersion="0.9.1"> +<plugin name="CppEditor" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>C/C++ editor component.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="CppTools" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="CppTools" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/cppeditor/cpphoverhandler.cpp b/src/plugins/cppeditor/cpphoverhandler.cpp index 3ffff7701de31478b0923eac72ddbac2d2144ac9..f4060d0b60fbb9ebb3b92ba2d3d9d9abaef5806f 100644 --- a/src/plugins/cppeditor/cpphoverhandler.cpp +++ b/src/plugins/cppeditor/cpphoverhandler.cpp @@ -53,6 +53,7 @@ #include <cplusplus/ExpressionUnderCursor.h> #include <cplusplus/Overview.h> #include <cplusplus/TypeOfExpression.h> +#include <cplusplus/SimpleLexer.h> #include <QtGui/QToolTip> #include <QtGui/QTextCursor> @@ -188,29 +189,36 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in if (!edit) return; + const Snapshot documents = m_modelManager->snapshot(); + const QString fileName = editor->file()->fileName(); + Document::Ptr doc = documents.value(fileName); + if (! doc) + return; // nothing to do + QTextCursor tc(edit->document()); tc.setPosition(pos); + const unsigned lineNumber = tc.block().blockNumber() + 1; - const Snapshot documents = m_modelManager->snapshot(); + // Find the last symbol up to the cursor position + int line = 0, column = 0; + editor->convertPosition(tc.position(), &line, &column); + Symbol *lastSymbol = doc->findSymbolAt(line, column); - const int lineNumber = tc.block().blockNumber() + 1; - const QString fileName = editor->file()->fileName(); - Document::Ptr doc = documents.value(fileName); - if (doc) { - foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) { - if (m.line() == lineNumber) { - m_toolTip = m.text(); - break; - } + TypeOfExpression typeOfExpression; + typeOfExpression.setSnapshot(documents); + + foreach (Document::DiagnosticMessage m, doc->diagnosticMessages()) { + if (m.line() == lineNumber) { + m_toolTip = m.text(); + break; } + } - if (m_toolTip.isEmpty()) { - unsigned lineno = tc.blockNumber() + 1; - foreach (const Document::Include &incl, doc->includes()) { - if (lineno == incl.line()) { - m_toolTip = incl.fileName(); - break; - } + if (m_toolTip.isEmpty()) { + foreach (const Document::Include &incl, doc->includes()) { + if (incl.line() == lineNumber) { + m_toolTip = incl.fileName(); + break; } } } @@ -233,43 +241,34 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in ExpressionUnderCursor expressionUnderCursor; const QString expression = expressionUnderCursor(tc); - if (doc) { - // Find the last symbol up to the cursor position - int line = 0, column = 0; - editor->convertPosition(tc.position(), &line, &column); - Symbol *lastSymbol = doc->findSymbolAt(line, column); - - TypeOfExpression typeOfExpression; - typeOfExpression.setSnapshot(documents); - QList<TypeOfExpression::Result> types = typeOfExpression(expression, doc, lastSymbol); - - if (!types.isEmpty()) { - FullySpecifiedType firstType = types.first().first; - FullySpecifiedType docType = firstType; - - if (const PointerType *pt = firstType->asPointerType()) { - docType = pt->elementType(); - } else if (const ReferenceType *rt = firstType->asReferenceType()) { - docType = rt->elementType(); - } - - - m_helpId = buildHelpId(docType, types.first().second); - QString displayName = buildHelpId(firstType, types.first().second); - - if (!firstType->isClass() && !firstType->isNamedType()) { - Overview overview; - overview.setShowArgumentNames(true); - overview.setShowReturnTypes(true); - m_toolTip = overview.prettyType(firstType, displayName); - } else { - m_toolTip = m_helpId; - } + const QList<TypeOfExpression::Result> types = + typeOfExpression(expression, doc, lastSymbol); + + if (!types.isEmpty()) { + FullySpecifiedType firstType = types.first().first; + FullySpecifiedType docType = firstType; + + if (const PointerType *pt = firstType->asPointerType()) { + docType = pt->elementType(); + } else if (const ReferenceType *rt = firstType->asReferenceType()) { + docType = rt->elementType(); + } + + m_helpId = buildHelpId(docType, types.first().second); + QString displayName = buildHelpId(firstType, types.first().second); + + if (!firstType->isClass() && !firstType->isNamedType()) { + Overview overview; + overview.setShowArgumentNames(true); + overview.setShowReturnTypes(true); + m_toolTip = overview.prettyType(firstType, displayName); + } else { + m_toolTip = m_helpId; } } } - if (doc && m_toolTip.isEmpty()) { + if (m_toolTip.isEmpty()) { foreach (const Document::MacroUse &use, doc->macroUses()) { if (use.contains(pos)) { m_toolTip = use.macro().toString(); @@ -285,12 +284,15 @@ void CppHoverHandler::updateHelpIdAndTooltip(TextEditor::ITextEditor *editor, in m_helpEngineNeedsSetup = false; } + if (! m_toolTip.isEmpty()) + m_toolTip = Qt::escape(m_toolTip); + if (!m_helpId.isEmpty() && !m_helpEngine->linksForIdentifier(m_helpId).isEmpty()) { m_toolTip = QString(QLatin1String("<table><tr><td valign=middle><nobr>%1</td>" "<td><img src=\":/cppeditor/images/f1.svg\"></td></tr></table>")) - .arg(Qt::escape(m_toolTip)); + .arg(m_toolTip); editor->setContextHelpId(m_helpId); } else if (!m_toolTip.isEmpty()) { - m_toolTip = QString(QLatin1String("<nobr>%1")).arg(Qt::escape(m_toolTip)); + m_toolTip = QString(QLatin1String("<nobr>%1")).arg(m_toolTip); } } diff --git a/src/plugins/cpptools/CppTools.pluginspec b/src/plugins/cpptools/CppTools.pluginspec index 08690446e2509af859f8eb7036328561e7db2244..1ddf66645445b390c52acb736b9bdd93565406f1 100644 --- a/src/plugins/cpptools/CppTools.pluginspec +++ b/src/plugins/cpptools/CppTools.pluginspec @@ -1,12 +1,12 @@ -<plugin name="CppTools" version="0.9.1" compatVersion="0.9.1"> +<plugin name="CppTools" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Tools for analyzing C/C++ code.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="QuickOpen" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="QuickOpen" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec index 399ac3c231a921520f40f22a2af3639af9ecbe88..b646c0bca2027f51f5a657fc1437a12536efb5b2 100644 --- a/src/plugins/debugger/Debugger.pluginspec +++ b/src/plugins/debugger/Debugger.pluginspec @@ -1,13 +1,13 @@ -<plugin name="Debugger" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Debugger" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Debugger integration.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="CppEditor" version="0.9.1"/><!-- Debugger plugin adds items to the editor's context menu --> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> - <dependency name="Find" version="0.9.1"/> + <dependency name="CppEditor" version="0.9.2"/><!-- Debugger plugin adds items to the editor's context menu --> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="Find" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/designer/Designer.pluginspec b/src/plugins/designer/Designer.pluginspec index bc57324c4fb0af539d9815654be755bd7b2f723b..7428e6df6603910520dced12d9824aa4ef088ad6 100644 --- a/src/plugins/designer/Designer.pluginspec +++ b/src/plugins/designer/Designer.pluginspec @@ -1,12 +1,12 @@ -<plugin name="Designer" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Designer" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Qt Designer integration.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> <!-- For compiling with CPP support enabled --> - <dependency name="CppEditor" version="0.9.1"/> + <dependency name="CppEditor" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/designer/workbenchintegration.cpp b/src/plugins/designer/workbenchintegration.cpp index 8483c2f1d9a265276fb5f8eaabac525b6fc56823..0291bd210580d76f0b7e196b816a2b80916dd025 100644 --- a/src/plugins/designer/workbenchintegration.cpp +++ b/src/plugins/designer/workbenchintegration.cpp @@ -59,6 +59,7 @@ #include <QtCore/QDebug> enum { debugSlotNavigation = 0 }; +enum { indentation = 4 }; using namespace Designer::Internal; using namespace CPlusPlus; @@ -75,6 +76,12 @@ static QString msgClassNotFound(const QString &uiClassName, const QList<Document return WorkbenchIntegration::tr("The class definition of '%1' could not be found in %2.").arg(uiClassName, files); } +static inline CppTools::CppModelManagerInterface *cppModelManagerInstance() +{ + Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); + return core->pluginManager()->getObject<CppTools::CppModelManagerInterface>(); +} + WorkbenchIntegration::WorkbenchIntegration(QDesignerFormEditorInterface *core, FormEditorW *parent) : qdesigner_internal::QDesignerIntegration(core, ::qobject_cast<QObject*>(parent)), m_few(parent) @@ -101,18 +108,13 @@ QWidget *WorkbenchIntegration::containerWindow(QWidget * /*widget*/) const return fw->integrationContainer(); } -static QList<Document::Ptr> findDocumentsIncluding(const QString &fileName, bool checkFileNameOnly) +static QList<Document::Ptr> findDocumentsIncluding(const CPlusPlus::Snapshot &docTable, + const QString &fileName, bool checkFileNameOnly) { - Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); - CppTools::CppModelManagerInterface *cppModelManager = - core->pluginManager()->getObject<CppTools::CppModelManagerInterface>(); - QList<Document::Ptr> docList; - // take all docs - CPlusPlus::Snapshot docTable = cppModelManager->snapshot(); - foreach (Document::Ptr doc, docTable) { // we go through all documents - QStringList includes = doc->includedFiles(); - foreach (QString include, includes) { + foreach (const Document::Ptr &doc, docTable) { // we go through all documents + const QStringList includes = doc->includedFiles(); + foreach (const QString &include, includes) { if (checkFileNameOnly) { const QFileInfo fi(include); if (fi.fileName() == fileName) { // we are only interested in docs which includes fileName only @@ -127,78 +129,79 @@ static QList<Document::Ptr> findDocumentsIncluding(const QString &fileName, bool return docList; } -static Class *findClass(Namespace *parentNameSpace, const QString &uiClassName, QString *namespaceName) -{ - // construct proper ui class name, take into account namespaced ui class name - QString className1; - QString className2; - int indexOfScope = uiClassName.lastIndexOf(QLatin1String("::")); - if (indexOfScope < 0) { - className1 = QLatin1String("Ui::") + uiClassName; - className2 = QLatin1String("Ui_") + uiClassName; - } else { - className1 = uiClassName.left(indexOfScope + 2) + QLatin1String("Ui::") + uiClassName.mid(indexOfScope + 2); - className2 = uiClassName.left(indexOfScope + 2) + QLatin1String("Ui_") + uiClassName.mid(indexOfScope + 2); - } +// Check for a class name where haystack is a member class of an object. +// So, haystack can be shorter (can have some namespaces omitted because of a +// "using namespace" declaration, for example, comparing +// "foo::Ui::form", against "using namespace foo; Ui::form". - for (unsigned i = 0; i < parentNameSpace->memberCount(); i++) { // we go through all namespace members - if (Class *cl = parentNameSpace->memberAt(i)->asClass()) { // we have found a class - we are interested in classes only - Overview o; - QString className = o.prettyName(cl->name()); - for (unsigned j = 0; j < cl->memberCount(); j++) { // we go through class members - const Declaration *decl = cl->memberAt(j)->asDeclaration(); - if (decl) { // we want to know if the class contains a member (so we look into a declaration) of uiClassName type - NamedType *nt = decl->type()->asNamedType(); +static bool matchMemberClassName(const QString &needle, const QString &hayStack) +{ + if (needle == hayStack) + return true; + if (!needle.endsWith(hayStack)) + return false; + // Check if there really is a separator "::" + const int separatorPos = needle.size() - hayStack.size() - 1; + return separatorPos > 1 && needle.at(separatorPos) == QLatin1Char(':'); +} +// Find class definition in namespace +static const Class *findClass(const Namespace *parentNameSpace, const QString &className, QString *namespaceName) +{ + if (debugSlotNavigation) + qDebug() << Q_FUNC_INFO << className; + + const Overview o; + const unsigned namespaceMemberCount = parentNameSpace->memberCount(); + for (unsigned i = 0; i < namespaceMemberCount; i++) { // we go through all namespace members + const Symbol *sym = parentNameSpace->memberAt(i); + // we have found a class - we are interested in classes only + if (const Class *cl = sym->asClass()) { + const unsigned classMemberCount = cl->memberCount(); + for (unsigned j = 0; j < classMemberCount; j++) // we go through class members + if (const Declaration *decl = cl->memberAt(j)->asDeclaration()) { + // we want to know if the class contains a member (so we look into + // a declaration) of uiClassName type + const NamedType *nt = decl->type()->asNamedType(); // handle pointers to member variables if (PointerType *pt = decl->type()->asPointerType()) nt = pt->elementType()->asNamedType(); - if (nt) { - Overview typeOverview; - const QString memberClass = typeOverview.prettyName(nt->name()); - if (memberClass == className1 || memberClass == className2) // names match + if (nt && matchMemberClassName(className, o.prettyName(nt->name()))) return cl; - // memberClass can be shorter (can have some namespaces cut because of e.g. "using namespace" declaration) - if (memberClass == className1.right(memberClass.length())) { // memberClass lenght <= className length - const QString namespacePrefix = className1.left(className1.length() - memberClass.length()); - if (namespacePrefix.right(2) == QLatin1String("::")) - return cl; - } - // the same as above but for className2 - if (memberClass == className2.right(memberClass.length())) { // memberClass lenght <= className length - const QString namespacePrefix = className2.left(className1.length() - memberClass.length()); - if (namespacePrefix.right(2) == QLatin1String("::")) - return cl; - } - } + } // decl + } else { + // Check namespaces + if (const Namespace *ns = sym->asNamespace()) { + QString tempNS = *namespaceName; + tempNS += o.prettyName(ns->name()); + tempNS += QLatin1String("::"); + if (const Class *cl = findClass(ns, className, &tempNS)) { + *namespaceName = tempNS; + return cl; } - } - } else if (Namespace *ns = parentNameSpace->memberAt(i)->asNamespace()) { - Overview o; - QString tempNS = *namespaceName + o.prettyName(ns->name()) + QLatin1String("::"); - Class *cl = findClass(ns, uiClassName, &tempNS); - if (cl) { - *namespaceName = tempNS; - return cl; - } - } - } + } // member is namespave + } // member is no class + } // for members return 0; } -static Function *findDeclaration(Class *cl, const QString &functionName) +static const Function *findDeclaration(const Class *cl, const QString &functionName) { const QString funName = QString::fromUtf8(QMetaObject::normalizedSignature(functionName.toUtf8())); - for (unsigned j = 0; j < cl->memberCount(); j++) { // go through all members - const Declaration *decl = cl->memberAt(j)->asDeclaration(); - if (decl) { // we are interested only in declarations (can be decl of method or of a field) - Function *fun = decl->type()->asFunction(); - if (fun) { // we are only interested in declarations of methods - Overview overview; - QString memberFunction = overview.prettyName(fun->name()) + QLatin1Char('('); - for (uint i = 0; i < fun->argumentCount(); i++) { // we build argument types string - Argument *arg = fun->argumentAt(i)->asArgument(); + const unsigned mCount = cl->memberCount(); + // we are interested only in declarations (can be decl of method or of a field) + // we are only interested in declarations of methods + const Overview overview; + for (unsigned j = 0; j < mCount; j++) { // go through all members + if (const Declaration *decl = cl->memberAt(j)->asDeclaration()) + if (const Function *fun = decl->type()->asFunction()) { + // Format signature + QString memberFunction = overview.prettyName(fun->name()); + memberFunction += QLatin1Char('('); + const uint aCount = fun->argumentCount(); + for (uint i = 0; i < aCount; i++) { // we build argument types string + const Argument *arg = fun->argumentAt(i)->asArgument(); if (i > 0) memberFunction += QLatin1Char(','); memberFunction += overview.prettyType(arg->type()); @@ -209,19 +212,18 @@ static Function *findDeclaration(Class *cl, const QString &functionName) if (memberFunction == funName) // we match function names and argument lists return fun; } - } } return 0; } // TODO: remove me, see below -static bool isCompatible(Name *name, Name *otherName) +static bool isCompatible(const Name *name, const Name *otherName) { - if (NameId *nameId = name->asNameId()) { - if (TemplateNameId *otherTemplId = otherName->asTemplateNameId()) + if (const NameId *nameId = name->asNameId()) { + if (const TemplateNameId *otherTemplId = otherName->asTemplateNameId()) return nameId->identifier()->isEqualTo(otherTemplId->identifier()); - } else if (TemplateNameId *templId = name->asTemplateNameId()) { - if (NameId *otherNameId = otherName->asNameId()) + } else if (const TemplateNameId *templId = name->asTemplateNameId()) { + if (const NameId *otherNameId = otherName->asNameId()) return templId->identifier()->isEqualTo(otherNameId->identifier()); } @@ -229,7 +231,7 @@ static bool isCompatible(Name *name, Name *otherName) } // TODO: remove me, see below -static bool isCompatible(Function *definition, Symbol *declaration, QualifiedNameId *declarationName) +static bool isCompatible(const Function *definition, const Symbol *declaration, const QualifiedNameId *declarationName) { Function *declTy = declaration->type()->asFunction(); if (! declTy) @@ -269,11 +271,9 @@ static bool isCompatible(Function *definition, Symbol *declaration, QualifiedNam } // TODO: remove me, this is taken from cppeditor.cpp. Find some common place for this method -static Document::Ptr findDefinition(Function *functionDeclaration, int *line) +static Document::Ptr findDefinition(const Function *functionDeclaration, int *line) { - Core::ICore *core = ExtensionSystem::PluginManager::instance()->getObject<Core::ICore>(); - CppTools::CppModelManagerInterface *cppModelManager = - core->pluginManager()->getObject<CppTools::CppModelManagerInterface>(); + CppTools::CppModelManagerInterface *cppModelManager = cppModelManagerInstance(); if (!cppModelManager) return Document::Ptr(); @@ -286,7 +286,8 @@ static Document::Ptr findDefinition(Function *functionDeclaration, int *line) if (QualifiedNameId *q = scopeOwnerName->asQualifiedNameId()) { for (unsigned i = 0; i < q->nameCount(); ++i) { qualifiedName.prepend(q->nameAt(i)); - } + +} } else { qualifiedName.prepend(scopeOwnerName); } @@ -299,7 +300,6 @@ static Document::Ptr findDefinition(Function *functionDeclaration, int *line) Control control; QualifiedNameId *q = control.qualifiedNameId(&qualifiedName[0], qualifiedName.size()); LookupContext context(&control); - const Snapshot documents = cppModelManager->snapshot(); foreach (Document::Ptr doc, documents) { QList<Scope *> visibleScopes; @@ -368,71 +368,80 @@ static int findClassEndPosition(const QString &headerContents, int classStartPos return -1; } -static void addDeclaration(const QString &docFileName, Class *cl, const QString &functionName) +static inline ITextEditable *editableAt(const QString &fileName, int line, int column) +{ + return qobject_cast<ITextEditable *>(TextEditor::BaseTextEditor::openEditorAt(fileName, line, column)); +} + +static void addDeclaration(const QString &docFileName, const Class *cl, const QString &functionName) { - // functionName comes already with argument names (if designer managed to do that) - for (unsigned j = 0; j < cl->memberCount(); j++) { // go through all members - const Declaration *decl = cl->memberAt(j)->asDeclaration(); - if (decl) { // we want to find any method which is a private slot (then we don't need to add "private slots:" statement) - Function *fun = decl->type()->asFunction(); - if (fun) { // we are only interested in declarations of methods + QString declaration = QLatin1String("void "); + declaration += functionName; + declaration += QLatin1String(";\n"); + + // functionName comes already with argument names (if designer managed to + // do that). First, let's try to find any method which is a private slot + // (then we don't need to add "private slots:" statement) + const unsigned mCount = cl->memberCount(); + for (unsigned j = 0; j < mCount; j++) { // go through all members + if (const Declaration *decl = cl->memberAt(j)->asDeclaration()) + if (const Function *fun = decl->type()->asFunction()) { + // we are only interested in declarations of methods. + // fun->column() returns always 0, what can cause trouble in case in one + // line if there is: "private slots: void foo();" if (fun->isSlot() && fun->isPrivate()) { - ITextEditable *editable = qobject_cast<ITextEditable *>( - TextEditor::BaseTextEditor::openEditorAt(docFileName, fun->line(), fun->column())); - // fun->column() raturns always 0, what can cause trouble in case in one - // line there is: "private slots: void foo();" - if (editable) { - editable->insert(QLatin1String("void ") + functionName + QLatin1String(";\n ")); - } + if (ITextEditable *editable = editableAt(docFileName, fun->line(), fun->column())) + editable->insert(declaration + QLatin1String(" ")); return; } } - } } // We didn't find any method under "private slots:", let's add "private slots:". Below code // adds "private slots:" by the end of the class definition. - ITextEditable *editable = qobject_cast<ITextEditable *>( - TextEditor::BaseTextEditor::openEditorAt(docFileName, cl->line(), cl->column())); - if (editable) { + if (ITextEditable *editable = editableAt(docFileName, cl->line(), cl->column())) { int classEndPosition = findClassEndPosition(editable->contents(), editable->position()); if (classEndPosition >= 0) { int line, column; editable->convertPosition(classEndPosition, &line, &column); // converts back position into a line and column editable->gotoLine(line, column); // go to position (we should be just before closing } of the class) - editable->insert(QLatin1String("\nprivate slots:\n ") - + QLatin1String("void ") + functionName + QLatin1String(";\n")); + editable->insert(QLatin1String("\nprivate slots:\n ") + declaration); } } } -static Document::Ptr addDefinition(const QString &headerFileName, const QString &className, - const QString &functionName, int *line) +static Document::Ptr addDefinition(const CPlusPlus::Snapshot &docTable, + const QString &headerFileName, const QString &className, + const QString &functionName, int *line) { + QString definition = QLatin1String("\nvoid "); + definition += className; + definition += QLatin1String("::"); + definition += functionName; + definition += QLatin1String("\n{\n"); + definition += QString(indentation, QLatin1Char(' ')); + definition += QLatin1String("\n}\n"); + // we find all documents which include headerFileName - QList<Document::Ptr> docList = findDocumentsIncluding(headerFileName, false); + const QList<Document::Ptr> docList = findDocumentsIncluding(docTable, headerFileName, false); if (docList.isEmpty()) return Document::Ptr(); QFileInfo headerFI(headerFileName); const QString headerBaseName = headerFI.baseName(); const QString headerAbsolutePath = headerFI.absolutePath(); - foreach (Document::Ptr doc, docList) { - QFileInfo sourceFI(doc->fileName()); + foreach (const Document::Ptr &doc, docList) { + const QFileInfo sourceFI(doc->fileName()); // we take only those documents which has the same filename and path (maybe we don't need to compare the path???) if (headerBaseName == sourceFI.baseName() && headerAbsolutePath == sourceFI.absolutePath()) { - ITextEditable *editable = qobject_cast<ITextEditable *>( - TextEditor::BaseTextEditor::openEditorAt(doc->fileName(), 0)); - if (editable) { + if (ITextEditable *editable = editableAt(doc->fileName(), 0, 0)) { const QString contents = editable->contents(); int column; editable->convertPosition(contents.length(), line, &column); editable->gotoLine(*line, column); - editable->insert(QLatin1String("\nvoid ") + className + QLatin1String("::") + - functionName + QLatin1String("\n {\n\n }\n")); + editable->insert(definition); *line += 1; - } return doc; } @@ -440,33 +449,84 @@ static Document::Ptr addDefinition(const QString &headerFileName, const QString return Document::Ptr(); } +// Insert the parameter names into a signature, "void foo(bool)" -> +// "void foo(bool checked)" static QString addParameterNames(const QString &functionSignature, const QStringList ¶meterNames) { - QString functionName = functionSignature.left(functionSignature.indexOf(QLatin1Char('(')) + 1); - QString argumentsString = functionSignature.mid(functionSignature.indexOf(QLatin1Char('(')) + 1); - argumentsString = argumentsString.left(argumentsString.indexOf(QLatin1Char(')'))); + const int firstParen = functionSignature.indexOf(QLatin1Char('(')); + QString functionName = functionSignature.left(firstParen + 1); + QString argumentsString = functionSignature.mid(firstParen + 1); + const int lastParen = argumentsString.lastIndexOf(QLatin1Char(')')); + if (lastParen != -1) + argumentsString.truncate(lastParen); const QStringList arguments = argumentsString.split(QLatin1Char(','), QString::SkipEmptyParts); - for (int i = 0; i < arguments.count(); ++i) { + const int pCount = parameterNames.count(); + const int aCount = arguments.count(); + for (int i = 0; i < aCount; ++i) { if (i > 0) functionName += QLatin1String(", "); functionName += arguments.at(i); - if (i < parameterNames.count()) - functionName += QLatin1Char(' ') + parameterNames.at(i); + if (i < pCount) { + functionName += QLatin1Char(' '); + functionName += parameterNames.at(i); + } } functionName += QLatin1Char(')'); return functionName; } +// Recursively find a class definition in the document passed on or in its +// included files (going down [maxIncludeDepth] includes) and return a pair +// of <Class*, Document>. + +typedef QPair<const Class *, Document::Ptr> ClassDocumentPtrPair; + +static ClassDocumentPtrPair + findClassRecursively(const CPlusPlus::Snapshot &docTable, + const Document::Ptr &doc, const QString &className, + unsigned maxIncludeDepth, QString *namespaceName) +{ + if (debugSlotNavigation) + qDebug() << Q_FUNC_INFO << doc->fileName() << maxIncludeDepth; + // Check document + if (const Class *cl = findClass(doc->globalNamespace(), className, namespaceName)) + return ClassDocumentPtrPair(cl, doc); + if (maxIncludeDepth) { + // Check the includes + const unsigned recursionMaxIncludeDepth = maxIncludeDepth - 1u; + foreach (const QString &include, doc->includedFiles()) { + const CPlusPlus::Snapshot::const_iterator it = docTable.constFind(include); + if (it != docTable.constEnd()) { + const Document::Ptr includeDoc = it.value(); + const ClassDocumentPtrPair irc = findClassRecursively(docTable, it.value(), className, recursionMaxIncludeDepth, namespaceName); + if (irc.first) + return irc; + } + } + } + return ClassDocumentPtrPair(0, Document::Ptr()); +} void WorkbenchIntegration::slotNavigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames) { QString errorMessage; if (!navigateToSlot(objectName, signalSignature, parameterNames, &errorMessage) && !errorMessage.isEmpty()) { - QMessageBox::critical(m_few->designerEditor()->topLevel(), tr("Error finding source file"), errorMessage); + QMessageBox::warning(m_few->designerEditor()->topLevel(), tr("Error finding/adding a slot."), errorMessage); } } +// Build name of the class as generated by uic, insert Ui namespace +// "foo::bar::form" -> "foo::bar::Ui::form" + +static inline QString uiClassName(QString formObjectName) +{ + const int indexOfScope = formObjectName.lastIndexOf(QLatin1String("::")); + const int uiNameSpaceInsertionPos = indexOfScope >= 0 ? indexOfScope : 0; + formObjectName.insert(uiNameSpaceInsertionPos, QLatin1String("Ui::")); + return formObjectName; +} + bool WorkbenchIntegration::navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames, @@ -482,7 +542,10 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName, const QFileInfo fi(currentUiFile); const QString uicedName = QLatin1String("ui_") + fi.baseName() + QLatin1String(".h"); - QList<Document::Ptr> docList = findDocumentsIncluding(uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file + // take all docs + + const CPlusPlus::Snapshot docTable = cppModelManagerInstance()->snapshot(); + QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file if (debugSlotNavigation) qDebug() << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size(); @@ -493,44 +556,63 @@ bool WorkbenchIntegration::navigateToSlot(const QString &objectName, QDesignerFormWindowInterface *fwi = m_few->activeFormWindow()->formWindow(); - const QString uiClassName = fwi->mainContainer()->objectName(); + const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); if (debugSlotNavigation) - qDebug() << "Checking docs for " << uiClassName; + qDebug() << "Checking docs for " << uiClass; + + // Find the class definition in the file itself or in the directly + // included files (order 1). + QString namespaceName; + const Class *cl; + Document::Ptr doc; + + foreach (const Document::Ptr &d, docList) { + const ClassDocumentPtrPair cd = findClassRecursively(docTable, d, uiClass, 1u , &namespaceName); + if (cd.first) { + cl = cd.first; + doc = cd.second; + break; + } + } + if (!cl) { + *errorMessage = msgClassNotFound(uiClass, docList); + return false; + } - foreach (const Document::Ptr &doc, docList) { - QString namespaceName; // namespace of the class found - Class *cl = findClass(doc->globalNamespace(), uiClassName, &namespaceName); - if (cl) { - Overview o; - const QString className = namespaceName + o.prettyName(cl->name()); - - QString functionName = QLatin1String("on_") + objectName + QLatin1Char('_') + signalSignature; - QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); - Function *fun = findDeclaration(cl, functionName); - int line = 0; - Document::Ptr sourceDoc; - if (!fun) { - // add function declaration to cl - addDeclaration(doc->fileName(), cl, functionNameWithParameterNames); - - // add function definition to cpp file - sourceDoc = addDefinition(doc->fileName(), className, functionNameWithParameterNames, &line); - } else { - sourceDoc = findDefinition(fun, &line); - if (!sourceDoc) { - // add function definition to cpp file - sourceDoc = addDefinition(doc->fileName(), className, functionNameWithParameterNames, &line); - } - } - if (sourceDoc) { - // jump to function definition - TextEditor::BaseTextEditor::openEditorAt(sourceDoc->fileName(), line); - } - return true; + Overview o; + const QString className = namespaceName + o.prettyName(cl->name()); + + const QString functionName = QLatin1String("on_") + objectName + QLatin1Char('_') + signalSignature; + const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); + + if (debugSlotNavigation) + qDebug() << "Found " << uiClass << doc->fileName() << " checking " << functionName << functionNameWithParameterNames; + + int line = 0; + Document::Ptr sourceDoc; + + if (const Function *fun = findDeclaration(cl, functionName)) { + sourceDoc = findDefinition(fun, &line); + if (!sourceDoc) { + // add function definition to cpp file + sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } + } else { + // add function declaration to cl + addDeclaration(doc->fileName(), cl, functionNameWithParameterNames); + + // add function definition to cpp file + sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } - *errorMessage = msgClassNotFound(uiClassName, docList); - return false; -} + if (!sourceDoc) { + *errorMessage = tr("Unable to add the method definition."); + return false; + } + + // jump to function definition, position within code + TextEditor::BaseTextEditor::openEditorAt(sourceDoc->fileName(), line + 2, indentation); + + return true; +} diff --git a/src/plugins/find/Find.pluginspec b/src/plugins/find/Find.pluginspec index 2dd9dba1a8c8a50485d4b54f7affa7c1686db7d8..f0e00617e10a41aa35cfd013e921f93f1a6c4bbf 100644 --- a/src/plugins/find/Find.pluginspec +++ b/src/plugins/find/Find.pluginspec @@ -1,10 +1,10 @@ -<plugin name="Find" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Find" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Provides the find widget and the hooks for find implementations.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/git/ScmGit.pluginspec b/src/plugins/git/ScmGit.pluginspec index 53f6184b80c6e65d75afb4e3352492a0ba798ba3..21c0c39ab60b76d0b100155091a6128993c006a1 100644 --- a/src/plugins/git/ScmGit.pluginspec +++ b/src/plugins/git/ScmGit.pluginspec @@ -1,13 +1,13 @@ -<plugin name="ScmGit" version="0.9.1" compatVersion="0.9.1"> +<plugin name="ScmGit" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Git integration.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> - <dependency name="VCSBase" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="VCSBase" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/helloworld/HelloWorld.pluginspec b/src/plugins/helloworld/HelloWorld.pluginspec index dab4cbfd3c898915adf6787ae4d3d4376b328406..54743ced9a3ee4bc91b70fe2a7b878f96dff2e37 100644 --- a/src/plugins/helloworld/HelloWorld.pluginspec +++ b/src/plugins/helloworld/HelloWorld.pluginspec @@ -1,10 +1,10 @@ -<plugin name="HelloWorld" version="0.9.1" compatVersion="0.9.1"> +<plugin name="HelloWorld" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Hello World sample plugin.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/help/Help.pluginspec b/src/plugins/help/Help.pluginspec index dfd438522a3812b3b442b6b32e0622ab0c786a75..50c5863b8c9ad356f986e57e95818c37f6359a4a 100644 --- a/src/plugins/help/Help.pluginspec +++ b/src/plugins/help/Help.pluginspec @@ -1,12 +1,12 @@ -<plugin name="Help" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Help" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Help system.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="Find" version="0.9.1"/> - <dependency name="QuickOpen" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="Find" version="0.9.2"/> + <dependency name="QuickOpen" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/perforce/Perforce.pluginspec b/src/plugins/perforce/Perforce.pluginspec index 496e420c36e6745ece4fd6e5491b8e0580aeb868..21df190d99a19344698994eed9e9d3522a733ebc 100644 --- a/src/plugins/perforce/Perforce.pluginspec +++ b/src/plugins/perforce/Perforce.pluginspec @@ -1,13 +1,13 @@ -<plugin name="Perforce" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Perforce" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Perforce integration.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> - <dependency name="VCSBase" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="VCSBase" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/projectexplorer/ProjectExplorer.pluginspec b/src/plugins/projectexplorer/ProjectExplorer.pluginspec index a60bbdf294923214eaea87e9e2e962bcf6220446..aaecd57de93cc54616887fd2e90df5bc1b06aaaa 100644 --- a/src/plugins/projectexplorer/ProjectExplorer.pluginspec +++ b/src/plugins/projectexplorer/ProjectExplorer.pluginspec @@ -1,13 +1,13 @@ -<plugin name="ProjectExplorer" version="0.9.1" compatVersion="0.9.1"> +<plugin name="ProjectExplorer" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>ProjectExplorer framework that can be extended with different kind of project types.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="Find" version="0.9.1"/> - <dependency name="QuickOpen" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="Find" version="0.9.2"/> + <dependency name="QuickOpen" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec index c5d09426de0d4f9f9f65954e7db5c6ed6914e1b7..c928239ed8b3af5d820656f5afeb380a0e53d607 100644 --- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec +++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec @@ -1,14 +1,14 @@ -<plugin name="Qt4ProjectManager" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Qt4ProjectManager" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Provides project type for Qt 4 pro files and tools.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="CppTools" version="0.9.1"/> - <dependency name="CppEditor" version="0.9.1"/> - <dependency name="Help" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="CppTools" version="0.9.2"/> + <dependency name="CppEditor" version="0.9.2"/> + <dependency name="Help" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 3c3de8fd0e03b6607712b4ca863c0c0b29ede738..f1b9b956021ec94c7bed16aa8ba68b5028190b81 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -1075,7 +1075,7 @@ void QtVersion::updateMkSpec() const if (line.startsWith("QMAKESPEC_ORIGINAL")) { const QList<QByteArray> &temp = line.split('='); if (temp.size() == 2) { - mkspec = temp.at(1); + mkspec = temp.at(1).trimmed(); } break; } diff --git a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec index f303e35e4544bb3aa967fdcdbd22e8cc2be0b784..1cb3129b81e9949cf4fd37a9d4868c5b50479802 100644 --- a/src/plugins/qtscripteditor/QtScriptEditor.pluginspec +++ b/src/plugins/qtscripteditor/QtScriptEditor.pluginspec @@ -1,11 +1,11 @@ -<plugin name="QtScriptEditor" version="0.9.1" compatVersion="0.9.1"> +<plugin name="QtScriptEditor" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Editor for QtScript.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/quickopen/QuickOpen.pluginspec b/src/plugins/quickopen/QuickOpen.pluginspec index 088f2affc951589d8bbfa5efc90b2bbc574ea783..85d9a5cc4761fdcc35d4ff0b88b41fa4cd77149a 100644 --- a/src/plugins/quickopen/QuickOpen.pluginspec +++ b/src/plugins/quickopen/QuickOpen.pluginspec @@ -1,10 +1,10 @@ -<plugin name="QuickOpen" version="0.9.1" compatVersion="0.9.1"> +<plugin name="QuickOpen" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Provides the QuickOpen widget and the hooks for QuickOpen filter implementations.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/regexp/RegExp.pluginspec b/src/plugins/regexp/RegExp.pluginspec index c284def7f3af425402d3c87767bfae1e25a33678..e0c4ac44c20cebb559b2ecedab379a9263c8c0c0 100644 --- a/src/plugins/regexp/RegExp.pluginspec +++ b/src/plugins/regexp/RegExp.pluginspec @@ -1,10 +1,10 @@ -<plugin name="RegExp" version="0.9.1" compatVersion="0.9.1"> +<plugin name="RegExp" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Regular Expression test widget.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/resourceeditor/ResourceEditor.pluginspec b/src/plugins/resourceeditor/ResourceEditor.pluginspec index e46b249dbf4eba3efebda6e171ee1cf3eb01572e..fc7911e67cd55e4185c7b4a0f071c5d462d466f7 100644 --- a/src/plugins/resourceeditor/ResourceEditor.pluginspec +++ b/src/plugins/resourceeditor/ResourceEditor.pluginspec @@ -1,10 +1,10 @@ -<plugin name="ResourceEditor" version="0.9.1" compatVersion="0.9.1"> +<plugin name="ResourceEditor" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Editor for qrc files.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/snippets/Snippets.pluginspec b/src/plugins/snippets/Snippets.pluginspec index 9128dc76e9acbc0124d68f5da2c384cc292de399..f7e0a18c2a0280b8c65515fe8b211db8e9314782 100644 --- a/src/plugins/snippets/Snippets.pluginspec +++ b/src/plugins/snippets/Snippets.pluginspec @@ -1,12 +1,12 @@ -<plugin name="Snippets" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Snippets" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Code snippet plugin.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/subversion/Subversion.pluginspec b/src/plugins/subversion/Subversion.pluginspec index bddb93aba6c8e5697ee15c54bd5d67555ef1fed2..4e9c76c118deea7e9b10883b8d1642afbdf13f4a 100644 --- a/src/plugins/subversion/Subversion.pluginspec +++ b/src/plugins/subversion/Subversion.pluginspec @@ -1,13 +1,13 @@ -<plugin name="Subversion" version="0.9.1" compatVersion="0.9.1"> +<plugin name="Subversion" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Subversion integration.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> - <dependency name="Core" version="0.9.1"/> - <dependency name="VCSBase" version="0.9.1"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="VCSBase" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/texteditor/TextEditor.pluginspec b/src/plugins/texteditor/TextEditor.pluginspec index 5c9506925cf1e5d75cca81340b404889d2ad644b..5f7d9a66ce71a4cb1ea3d1e2f3f99ef5c5870d1b 100644 --- a/src/plugins/texteditor/TextEditor.pluginspec +++ b/src/plugins/texteditor/TextEditor.pluginspec @@ -1,12 +1,12 @@ -<plugin name="TextEditor" version="0.9.1" compatVersion="0.9.1"> +<plugin name="TextEditor" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Text editor framework and the implementation of the basic text editor.</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="Find" version="0.9.1"/> - <dependency name="QuickOpen" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="Find" version="0.9.2"/> + <dependency name="QuickOpen" version="0.9.2"/> </dependencyList> </plugin> diff --git a/src/plugins/texteditor/basetexteditor.cpp b/src/plugins/texteditor/basetexteditor.cpp index 48de83d5ef2fb77b3552e6021a0bc2fbd9dc8766..ea4f665a7e9576bfce30f26c6d38dd2a1772f051 100644 --- a/src/plugins/texteditor/basetexteditor.cpp +++ b/src/plugins/texteditor/basetexteditor.cpp @@ -1603,7 +1603,6 @@ namespace TextEditor { int firstColumn; int lastColumn; }; - } } diff --git a/src/plugins/texteditor/completionwidget.cpp b/src/plugins/texteditor/completionwidget.cpp index 661cda0c3220c219f014ec236a88465a6588efa1..f9057d390781aadd2c20c4cc2811007db9a92160 100644 --- a/src/plugins/texteditor/completionwidget.cpp +++ b/src/plugins/texteditor/completionwidget.cpp @@ -39,8 +39,9 @@ #include <utils/qtcassert.h> #include <QtCore/QEvent> -#include <QtGui/QKeyEvent> #include <QtGui/QApplication> +#include <QtGui/QDesktopWidget> +#include <QtGui/QKeyEvent> #include <QtGui/QVBoxLayout> #include <limits.h> @@ -130,6 +131,8 @@ CompletionWidget::CompletionWidget(CompletionSupport *support, ITextEditable *ed layout->addWidget(this); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + m_popupFrame->setMinimumSize(1, 1); + setMinimumSize(1, 1); } bool CompletionWidget::event(QEvent *e) @@ -227,20 +230,15 @@ void CompletionWidget::setCompletionItems(const QList<TextEditor::CompletionItem void CompletionWidget::showCompletions(int startPos) { - const QPoint &pos = m_editor->cursorRect(startPos).bottomLeft(); - m_popupFrame->move(pos.x() - 16, pos.y()); - m_popupFrame->setMinimumSize(1, 1); - setMinimumSize(1, 1); - - updateSize(); - + updatePositionAndSize(startPos); m_popupFrame->show(); show(); setFocus(); } -void CompletionWidget::updateSize() +void CompletionWidget::updatePositionAndSize(int startPos) { + // Determine size by calculating the space of the visible items int visibleItems = m_model->rowCount(); if (visibleItems > NUMBER_OF_VISIBLE_ITEMS) visibleItems = NUMBER_OF_VISIBLE_ITEMS; @@ -254,10 +252,25 @@ void CompletionWidget::updateSize() shint = tmp; } - const int width = (shint.width() + (m_popupFrame->frameWidth() * 2) + 30); - const int height = (shint.height() * visibleItems) + m_popupFrame->frameWidth() * 2; + const int frameWidth = m_popupFrame->frameWidth(); + const int width = shint.width() + frameWidth * 2 + 30; + const int height = shint.height() * visibleItems + frameWidth * 2; + + // Determine the position, keeping the popup on the screen + const QRect cursorRect = m_editor->cursorRect(startPos); + const QDesktopWidget *desktop = QApplication::desktop(); + const QRect screen = desktop->availableGeometry(desktop->screenNumber(this)); + + QPoint pos = cursorRect.bottomLeft(); + pos.rx() -= 16 + frameWidth; // Space for the icons + + if (pos.y() + height > screen.bottom()) + pos.setY(cursorRect.top() - height); + + if (pos.x() + width > screen.right()) + pos.setX(screen.right() - width); - m_popupFrame->resize(width, height); + m_popupFrame->setGeometry(pos.x(), pos.y(), width, height); } void CompletionWidget::completionActivated(const QModelIndex &index) diff --git a/src/plugins/texteditor/completionwidget.h b/src/plugins/texteditor/completionwidget.h index c1fb28fc1cf17f7df58f7c287393f13417e45c38..b124d2e257acaee4aca879370247b08e7a9b3b8e 100644 --- a/src/plugins/texteditor/completionwidget.h +++ b/src/plugins/texteditor/completionwidget.h @@ -74,7 +74,7 @@ private slots: void completionActivated(const QModelIndex &index); private: - void updateSize(); + void updatePositionAndSize(int startPos); QPointer<QFrame> m_popupFrame; bool m_blockFocusOut; diff --git a/src/plugins/vcsbase/VCSBase.pluginspec b/src/plugins/vcsbase/VCSBase.pluginspec index 1f9cd30dd2dbd43f1b0b7166de11d19ec191d9e7..87e3ae9eac8268c08a888c67a27c9e97f779fbfa 100644 --- a/src/plugins/vcsbase/VCSBase.pluginspec +++ b/src/plugins/vcsbase/VCSBase.pluginspec @@ -1,12 +1,12 @@ -<plugin name="VCSBase" version="0.9.1" compatVersion="0.9.1"> +<plugin name="VCSBase" version="0.9.2" compatVersion="0.9.2"> <vendor>Nokia Corporation</vendor> <copyright>(C) 2008 Nokia Corporation</copyright> <license>Nokia Beta Version License</license> <description>Version Control System Base Plugin</description> <url>http://www.trolltech.com/</url> <dependencyList> - <dependency name="Core" version="0.9.1"/> - <dependency name="TextEditor" version="0.9.1"/> - <dependency name="ProjectExplorer" version="0.9.1"/> + <dependency name="Core" version="0.9.2"/> + <dependency name="TextEditor" version="0.9.2"/> + <dependency name="ProjectExplorer" version="0.9.2"/> </dependencyList> </plugin>