summaryrefslogtreecommitdiff
path: root/src/plugins/cpptools
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cpptools')
-rw-r--r--src/plugins/cpptools/CppTools.pluginspec.in (renamed from src/plugins/cpptools/CppTools.pluginspec)10
-rw-r--r--src/plugins/cpptools/completionsettingspage.cpp13
-rw-r--r--src/plugins/cpptools/completionsettingspage.h2
-rw-r--r--src/plugins/cpptools/cppcodecompletion.cpp45
-rw-r--r--src/plugins/cpptools/cppcodecompletion.h4
-rw-r--r--src/plugins/cpptools/cppcodeformatter.cpp74
-rw-r--r--src/plugins/cpptools/cppcodeformatter.h5
-rw-r--r--src/plugins/cpptools/cppfilesettingspage.cpp17
-rw-r--r--src/plugins/cpptools/cpptools.pri2
-rw-r--r--src/plugins/cpptools/cpptools.pro4
-rw-r--r--src/plugins/cpptools/cpptoolsplugin.cpp3
-rw-r--r--src/plugins/cpptools/insertionpointlocator.h2
-rw-r--r--src/plugins/cpptools/uicodecompletionsupport.cpp197
-rw-r--r--src/plugins/cpptools/uicodecompletionsupport.h70
14 files changed, 405 insertions, 43 deletions
diff --git a/src/plugins/cpptools/CppTools.pluginspec b/src/plugins/cpptools/CppTools.pluginspec.in
index c7bd234c28..704a64f450 100644
--- a/src/plugins/cpptools/CppTools.pluginspec
+++ b/src/plugins/cpptools/CppTools.pluginspec.in
@@ -1,4 +1,4 @@
-<plugin name="CppTools" version="2.0.95" compatVersion="2.0.95">
+<plugin name=\"CppTools\" version=\"$$QTCREATOR_VERSION\" compatVersion=\"$$QTCREATOR_VERSION\">
<vendor>Nokia Corporation</vendor>
<copyright>(C) 2010 Nokia Corporation</copyright>
<license>
@@ -14,9 +14,9 @@ Alternatively, this plugin may be used under the terms of the GNU Lesser General
<description>Tools for analyzing C/C++ code.</description>
<url>http://qt.nokia.com</url>
<dependencyList>
- <dependency name="TextEditor" version="2.0.95"/>
- <dependency name="ProjectExplorer" version="2.0.95"/>
- <dependency name="Locator" version="2.0.95"/>
- <dependency name="Find" version="2.0.95"/>
+ <dependency name=\"TextEditor\" version=\"$$QTCREATOR_VERSION\"/>
+ <dependency name=\"ProjectExplorer\" version=\"$$QTCREATOR_VERSION\"/>
+ <dependency name=\"Locator\" version=\"$$QTCREATOR_VERSION\"/>
+ <dependency name=\"Find\" version=\"$$QTCREATOR_VERSION\"/>
</dependencyList>
</plugin>
diff --git a/src/plugins/cpptools/completionsettingspage.cpp b/src/plugins/cpptools/completionsettingspage.cpp
index 8e74bfed09..5df367d82f 100644
--- a/src/plugins/cpptools/completionsettingspage.cpp
+++ b/src/plugins/cpptools/completionsettingspage.cpp
@@ -44,7 +44,7 @@
using namespace CppTools::Internal;
CompletionSettingsPage::CompletionSettingsPage()
- : m_page(new Ui_CompletionSettingsPage)
+ : m_page(0)
{
}
@@ -66,6 +66,7 @@ QString CompletionSettingsPage::displayName() const
QWidget *CompletionSettingsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
+ m_page = new Ui_CompletionSettingsPage;
m_page->setupUi(w);
const TextEditor::CompletionSettings &settings =
@@ -117,6 +118,8 @@ QWidget *CompletionSettingsPage::createPage(QWidget *parent)
void CompletionSettingsPage::apply()
{
+ if (!m_page) // page was never shown
+ return;
TextEditor::CompletionSettings settings;
settings.m_caseSensitivity = caseSensitivity();
settings.m_completionTrigger = completionTrigger();
@@ -155,3 +158,11 @@ TextEditor::CompletionTrigger CompletionSettingsPage::completionTrigger() const
return TextEditor::AutomaticCompletion;
}
}
+
+void CompletionSettingsPage::finish()
+{
+ if (!m_page) // page was never shown
+ return;
+ delete m_page;
+ m_page = 0;
+}
diff --git a/src/plugins/cpptools/completionsettingspage.h b/src/plugins/cpptools/completionsettingspage.h
index 4cf2135f1d..f2927677cf 100644
--- a/src/plugins/cpptools/completionsettingspage.h
+++ b/src/plugins/cpptools/completionsettingspage.h
@@ -59,7 +59,7 @@ public:
QWidget *createPage(QWidget *parent);
void apply();
- void finish() { }
+ void finish();
virtual bool matches(const QString &) const;
private:
diff --git a/src/plugins/cpptools/cppcodecompletion.cpp b/src/plugins/cpptools/cppcodecompletion.cpp
index 7e0d2502d2..9e3a5a534f 100644
--- a/src/plugins/cpptools/cppcodecompletion.cpp
+++ b/src/plugins/cpptools/cppcodecompletion.cpp
@@ -56,6 +56,8 @@
#include <cplusplus/BackwardsScanner.h>
#include <cplusplus/LookupContext.h>
+#include <cppeditor/cppeditorconstants.h>
+
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <coreplugin/editormanager/editormanager.h>
@@ -63,6 +65,7 @@
#include <texteditor/itexteditor.h>
#include <texteditor/itexteditable.h>
#include <texteditor/basetexteditor.h>
+#include <texteditor/snippets/snippet.h>
#include <projectexplorer/projectexplorer.h>
#include <utils/faketooltip.h>
@@ -466,7 +469,8 @@ CppCodeCompletion::CppCodeCompletion(CppModelManager *manager)
m_automaticCompletion(false),
m_completionOperator(T_EOF_SYMBOL),
m_objcEnabled(true),
- m_snippetsParser(Core::ICore::instance()->resourcePath() + QLatin1String("/snippets/cpp.xml"))
+ m_snippetProvider(CppEditor::Constants::CPP_SNIPPETS_GROUP_ID,
+ QIcon(QLatin1String(":/texteditor/images/snippet.png")))
{
}
@@ -715,6 +719,31 @@ int CppCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
{
int index = startCompletionHelper(editor);
if (index != -1) {
+ if (m_automaticCompletion) {
+ const int pos = editor->position();
+ const QChar ch = editor->characterAt(pos);
+ if (! (ch.isLetterOrNumber() || ch == QLatin1Char('_'))) {
+ for (int i = pos - 1;; --i) {
+ const QChar ch = editor->characterAt(i);
+ if (ch.isLetterOrNumber() || ch == QLatin1Char('_')) {
+ const QString wordUnderCursor = editor->textAt(i, pos - i);
+ if (wordUnderCursor.at(0).isLetter() || wordUnderCursor.at(0) == QLatin1Char('_')) {
+ foreach (const TextEditor::CompletionItem &i, m_completions) {
+ if (i.text == wordUnderCursor) {
+ cleanup();
+ return -1;
+ }
+ }
+ } else {
+ cleanup();
+ return -1;
+ }
+ } else
+ break;
+ }
+ }
+ }
+
if (m_completionOperator != T_EOF_SYMBOL)
qSort(m_completions.begin(), m_completions.end(), completionItemLessThan);
@@ -755,12 +784,12 @@ void CppCodeCompletion::completeObjCMsgSend(ClassOrNamespace *binding,
Symbol *arg = method->argumentAt(i);
text += selectorName->nameAt(i)->identifier()->chars();
text += QLatin1Char(':');
- text += QChar::ObjectReplacementCharacter;
+ text += TextEditor::Snippet::kVariableDelimiter;
text += QLatin1Char('(');
text += oo(arg->type());
text += QLatin1Char(')');
text += oo(arg->name());
- text += QChar::ObjectReplacementCharacter;
+ text += TextEditor::Snippet::kVariableDelimiter;
}
} else {
text = selectorName->identifier()->chars();
@@ -1922,6 +1951,11 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item, QChar t
}
#endif
} else if (! function->isAmbiguous()) {
+ // When the user typed the opening parenthesis, he'll likely also type the closing one,
+ // in which case it would be annoying if we put the cursor after the already automatically
+ // inserted closing parenthesis.
+ const bool skipClosingParenthesis = typedChar != QLatin1Char('(');
+
if (completionSettings().m_spaceAfterFunctionName)
extraChars += QLatin1Char(' ');
extraChars += QLatin1Char('(');
@@ -1941,7 +1975,7 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item, QChar t
}
// If the function takes no arguments, automatically place the closing parenthesis
- if (item.duplicateCount == 0 && ! function->hasArguments()) {
+ if (item.duplicateCount == 0 && ! function->hasArguments() && skipClosingParenthesis) {
extraChars += QLatin1Char(')');
if (endWithSemicolon) {
extraChars += semicolon;
@@ -2062,8 +2096,7 @@ bool CppCodeCompletion::objcKeywordsWanted() const
void CppCodeCompletion::addSnippets()
{
- static const QIcon icon(QLatin1String(":/texteditor/images/snippet.png"));
- m_completions.append(m_snippetsParser.execute(this, icon));
+ m_completions.append(m_snippetProvider.getSnippets(this));
}
#include "cppcodecompletion.moc"
diff --git a/src/plugins/cpptools/cppcodecompletion.h b/src/plugins/cpptools/cppcodecompletion.h
index 7ac11c2821..46bb3945d8 100644
--- a/src/plugins/cpptools/cppcodecompletion.h
+++ b/src/plugins/cpptools/cppcodecompletion.h
@@ -41,7 +41,7 @@
#include <cplusplus/TypeOfExpression.h>
#include <texteditor/icompletioncollector.h>
-#include <texteditor/snippetsparser.h>
+#include <texteditor/snippets/snippetcollector.h>
#include <QtCore/QObject>
#include <QtCore/QPointer>
@@ -157,7 +157,7 @@ private:
unsigned m_completionOperator;
bool m_objcEnabled;
- TextEditor::SnippetsParser m_snippetsParser;
+ TextEditor::SnippetCollector m_snippetProvider;
CPlusPlus::Icons m_icons;
CPlusPlus::Overview overview;
diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index 281ce0c943..fdb179f3a4 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -386,6 +386,12 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
default: leave(); continue;
} break;
+ case label:
+ switch (kind) {
+ case T_COLON: leave(); break;
+ default: leave(); continue; // shouldn't happen
+ } break;
+
case multiline_comment_start:
case multiline_comment_cont:
if (kind != T_COMMENT && kind != T_DOXY_COMMENT) {
@@ -714,6 +720,10 @@ bool CodeFormatter::tryDeclaration()
enter(qt_like_macro);
return true;
}
+ if (m_tokens.size() > 1 && m_tokens.at(1).kind() == T_COLON) {
+ enter(label);
+ return true;
+ }
}
// fallthrough
case T_CHAR:
@@ -1042,12 +1052,13 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
{
const State &parentState = state();
const Token &tk = currentToken();
- const int tokenPosition = column(tk.begin());
const bool firstToken = (tokenIndex() == 0);
const bool lastToken = (tokenIndex() == tokenCount() - 1);
- int nextTokenStart = 0;
- if (!lastToken)
- nextTokenStart = column(tokenAt(tokenIndex() + 1).begin());
+ const int tokenPosition = column(tk.begin());
+ const int nextTokenPosition = lastToken ? tokenPosition + tk.length()
+ : column(tokenAt(tokenIndex() + 1).begin());
+ const int spaceOrNextTokenPosition = lastToken ? tokenPosition + tk.length() + 1
+ : nextTokenPosition;
if (shouldClearPaddingOnEnter(newState))
*paddingDepth = 0;
@@ -1071,7 +1082,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
case template_param:
if (!lastToken)
- *paddingDepth = tokenPosition-*indentDepth + tk.length();
+ *paddingDepth = nextTokenPosition-*indentDepth;
else {
if (*paddingDepth == 0)
*paddingDepth = 2*m_indentSize;
@@ -1108,24 +1119,24 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
case arglist_open:
case condition_paren_open:
if (!lastToken)
- *paddingDepth = tokenPosition-*indentDepth + 1;
+ *paddingDepth = nextTokenPosition-*indentDepth;
else
*paddingDepth += m_indentSize;
break;
case ternary_op:
if (!lastToken)
- *paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
+ *paddingDepth = spaceOrNextTokenPosition-*indentDepth;
else
*paddingDepth += m_indentSize;
break;
case stream_op:
- *paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
+ *paddingDepth = spaceOrNextTokenPosition-*indentDepth;
break;
case stream_op_cont:
if (firstToken)
- *savedPaddingDepth = *paddingDepth = tokenPosition-*indentDepth + tk.length() + 1;
+ *savedPaddingDepth = *paddingDepth = spaceOrNextTokenPosition-*indentDepth;
break;
case member_init_open:
@@ -1163,7 +1174,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
*indentDepth += m_indentSize;
if (followedByData) {
- *paddingDepth = column(tokenAt(tokenIndex() + 1).begin()) - *indentDepth;
+ *paddingDepth = nextTokenPosition-*indentDepth;
}
break;
}
@@ -1192,7 +1203,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
if (!lastToken) {
if (parentState.type == initializer)
*savedPaddingDepth = tokenPosition-*indentDepth;
- *paddingDepth = nextTokenStart-*indentDepth;
+ *paddingDepth = nextTokenPosition-*indentDepth;
} else {
// avoid existing continuation indents
if (parentState.type == initializer)
@@ -1202,7 +1213,11 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
break;
case block_open:
- if (parentState.type != case_cont)
+ // case_cont already adds some indent, revert it for a block
+ if (parentState.type == case_cont && !m_indentSubstatementBraces)
+ *indentDepth = *savedIndentDepth = parentState.savedIndentDepth;
+
+ if (m_indentSubstatementStatements)
*indentDepth += m_indentSize;
break;
@@ -1212,10 +1227,10 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
*savedPaddingDepth = *paddingDepth;
// fixed extra indent when continuing 'if (', but not for 'else if ('
- if (tokenPosition <= *indentDepth + m_indentSize)
+ if (nextTokenPosition-*indentDepth <= m_indentSize)
*paddingDepth = 2*m_indentSize;
else
- *paddingDepth = tokenPosition-*indentDepth + 1;
+ *paddingDepth = nextTokenPosition-*indentDepth;
break;
case substatement:
@@ -1235,11 +1250,11 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
} break;
case for_statement_paren_open:
- *paddingDepth = tokenPosition + 1 - *indentDepth;
+ *paddingDepth = nextTokenPosition - *indentDepth;
break;
case multiline_comment_start:
- *indentDepth = tokenPosition + 2;
+ *indentDepth = tokenPosition + 2; // nextTokenPosition won't work
break;
case multiline_comment_cont:
@@ -1306,6 +1321,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
case T_LBRACE: {
if (topState.type == case_cont) {
*indentDepth = topState.savedIndentDepth;
+ if (m_indentSubstatementBraces)
+ *indentDepth += m_indentSize;
*paddingDepth = 0;
// function definition - argument list is expression state
} else if (topState.type == expression && previousState.type == declaration_start) {
@@ -1336,8 +1353,8 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
}
case T_RBRACE: {
if (topState.type == block_open && previousState.type == case_cont) {
- *indentDepth = previousState.savedIndentDepth;
- *paddingDepth = previousState.savedPaddingDepth;
+ *indentDepth = topState.savedIndentDepth;
+ *paddingDepth = topState.savedPaddingDepth;
break;
}
for (int i = 0; state(i).type != topmost_intro; ++i) {
@@ -1369,10 +1386,16 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
// }
// break;
case T_DEFAULT:
- case T_CASE:
+ case T_CASE: {
+ int lastSubstatementIndent = 0;
for (int i = 0; state(i).type != topmost_intro; ++i) {
const int type = state(i).type;
- if (type == switch_statement || type == case_cont) {
+ if (type == substatement_open) {
+ lastSubstatementIndent = state(i).savedIndentDepth;
+ } else if (type == switch_statement) {
+ *indentDepth = lastSubstatementIndent;
+ break;
+ } else if (type == case_cont) {
*indentDepth = state(i).savedIndentDepth;
break;
} else if (type == topmost_intro) {
@@ -1380,6 +1403,7 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
}
}
break;
+ }
case T_PUBLIC:
case T_PRIVATE:
case T_PROTECTED:
@@ -1418,6 +1442,16 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
*indentDepth = 0;
}
break;
+ case T_IDENTIFIER:
+ if (topState.type == substatement
+ || topState.type == substatement_open
+ || topState.type == case_cont
+ || topState.type == block_open
+ || topState.type == defun_open) {
+ if (tokens.size() > 1 && tokens.at(1).kind() == T_COLON) // label?
+ *indentDepth = 0;
+ }
+ break;
}
}
diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h
index 2034d8771d..a556ced7d5 100644
--- a/src/plugins/cpptools/cppcodeformatter.h
+++ b/src/plugins/cpptools/cppcodeformatter.h
@@ -54,7 +54,7 @@ namespace TextEditor {
class TabSettings;
}
-namespace CppTools {
+namespace CppTools {
namespace Internal {
class CppCodeFormatterData;
}
@@ -116,6 +116,7 @@ public: // must be public to make Q_GADGET introspection work
cpp_macro_cont, // Subsequent lines of a multi-line C preprocessor macro definition.
cpp_macro_conditional, // Special marker used for separating saved from current state when dealing with #ifdef
qt_like_macro, // after an identifier starting with Q_ or QT_ at the beginning of the line
+ label, // after an identifier followed by a colon
defun_open, // Brace that opens a top-level function definition.
using_start, // right after the "using" token
@@ -173,7 +174,7 @@ public: // must be public to make Q_GADGET introspection work
assign_open, // after an assignment token
expression, // after a '=' in a declaration_start once we're sure it's not '= {'
- initializer, // after a '=' in a declaration start
+ initializer // after a '=' in a declaration start
};
Q_ENUMS(StateType)
diff --git a/src/plugins/cpptools/cppfilesettingspage.cpp b/src/plugins/cpptools/cppfilesettingspage.cpp
index 401c6bcb47..35f74d672a 100644
--- a/src/plugins/cpptools/cppfilesettingspage.cpp
+++ b/src/plugins/cpptools/cppfilesettingspage.cpp
@@ -49,6 +49,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QDate>
#include <QtCore/QLocale>
+#include <QtCore/QTextCodec>
#include <QtCore/QTextStream>
#include <QtGui/QFileDialog>
@@ -120,6 +121,14 @@ static bool keyWordReplacement(const QString &keyWord,
*value = QString::number(QDate::currentDate().year());
return true;
}
+ if (keyWord == QLatin1String("%MONTH%")) {
+ *value = QString::number(QDate::currentDate().month());
+ return true;
+ }
+ if (keyWord == QLatin1String("%DAY%")) {
+ *value = QString::number(QDate::currentDate().day());
+ return true;
+ }
if (keyWord == QLatin1String("%CLASS%")) {
*value = className;
return true;
@@ -204,7 +213,13 @@ QString CppFileSettings::licenseTemplate(const QString &fileName, const QString
qWarning("Unable to open the license template %s: %s", qPrintable(path), qPrintable(file.errorString()));
return QString();
}
- QString license = QString::fromUtf8(file.readAll());
+
+ QTextCodec *codec = Core::EditorManager::instance()->defaultTextEncoding();
+ QTextStream licenseStream(&file);
+ licenseStream.setCodec(codec);
+ licenseStream.setAutoDetectUnicode(true);
+ QString license = licenseStream.readAll();
+
parseLicenseTemplatePlaceholders(&license, fileName, className);
// Ensure exactly one additional new line separating stuff
const QChar newLine = QLatin1Char('\n');
diff --git a/src/plugins/cpptools/cpptools.pri b/src/plugins/cpptools/cpptools.pri
index 1dffbfc556..5732e896e7 100644
--- a/src/plugins/cpptools/cpptools.pri
+++ b/src/plugins/cpptools/cpptools.pri
@@ -1,3 +1,3 @@
include(cpptools_dependencies.pri)
-LIBS *= -l$$qtLibraryTarget(CppTools)
+LIBS *= -l$$qtLibraryName(CppTools)
diff --git a/src/plugins/cpptools/cpptools.pro b/src/plugins/cpptools/cpptools.pro
index 8062333db7..57507f3612 100644
--- a/src/plugins/cpptools/cpptools.pro
+++ b/src/plugins/cpptools/cpptools.pro
@@ -26,6 +26,7 @@ HEADERS += completionsettingspage.h \
cppfindreferences.h \
cppcodeformatter.h \
symbolsfindfilter.h \
+ uicodecompletionsupport.h \
insertionpointlocator.h \
cpprefactoringchanges.h
@@ -45,10 +46,9 @@ SOURCES += completionsettingspage.cpp \
cppfindreferences.cpp \
cppcodeformatter.cpp \
symbolsfindfilter.cpp \
+ uicodecompletionsupport.cpp \
insertionpointlocator.cpp \
cpprefactoringchanges.cpp
FORMS += completionsettingspage.ui \
cppfilesettingspage.ui
-
-OTHER_FILES += CppTools.pluginspec
diff --git a/src/plugins/cpptools/cpptoolsplugin.cpp b/src/plugins/cpptools/cpptoolsplugin.cpp
index 22419d23dd..947675e624 100644
--- a/src/plugins/cpptools/cpptoolsplugin.cpp
+++ b/src/plugins/cpptools/cpptoolsplugin.cpp
@@ -51,6 +51,7 @@
#include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/uniqueidmanager.h>
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/vcsmanager.h>
@@ -105,7 +106,7 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
// Objects
m_modelManager = new CppModelManager(this);
- Core::VCSManager *vcsManager = core->vcsManager();
+ Core::VcsManager *vcsManager = core->vcsManager();
Core::FileManager *fileManager = core->fileManager();
connect(vcsManager, SIGNAL(repositoryChanged(QString)),
m_modelManager, SLOT(updateModifiedSourceFiles()));
diff --git a/src/plugins/cpptools/insertionpointlocator.h b/src/plugins/cpptools/insertionpointlocator.h
index bc250fcb8e..f475041fa2 100644
--- a/src/plugins/cpptools/insertionpointlocator.h
+++ b/src/plugins/cpptools/insertionpointlocator.h
@@ -98,7 +98,7 @@ public:
PublicSlot = Public | SlotBit,
ProtectedSlot = Protected | SlotBit,
- PrivateSlot = Private | SlotBit,
+ PrivateSlot = Private | SlotBit
};
public:
diff --git a/src/plugins/cpptools/uicodecompletionsupport.cpp b/src/plugins/cpptools/uicodecompletionsupport.cpp
new file mode 100644
index 0000000000..dc226b09a3
--- /dev/null
+++ b/src/plugins/cpptools/uicodecompletionsupport.cpp
@@ -0,0 +1,197 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+#include "uicodecompletionsupport.h"
+#include <QtCore/QProcess>
+
+enum { debug = 0 };
+
+using namespace CppTools;
+
+UiCodeModelSupport::UiCodeModelSupport(CppTools::CppModelManagerInterface *modelmanager,
+ const QString &source,
+ const QString &uiHeaderFile)
+ : CppTools::AbstractEditorSupport(modelmanager),
+ m_sourceName(source),
+ m_fileName(uiHeaderFile),
+ m_updateIncludingFiles(false),
+ m_initialized(false)
+{
+ if (debug)
+ qDebug()<<"ctor UiCodeModelSupport for"<<m_sourceName<<uiHeaderFile;
+}
+
+UiCodeModelSupport::~UiCodeModelSupport()
+{
+ if (debug)
+ qDebug()<<"dtor ~UiCodeModelSupport for"<<m_sourceName;
+}
+
+void UiCodeModelSupport::init() const
+{
+ m_initialized = true;
+ QDateTime sourceTime = QFileInfo(m_sourceName).lastModified();
+ QFileInfo uiHeaderFileInfo(m_fileName);
+ QDateTime uiHeaderTime = uiHeaderFileInfo.exists() ? uiHeaderFileInfo.lastModified() : QDateTime();
+ if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
+ QFile file(m_fileName);
+ if (file.open(QFile::ReadOnly)) {
+ if (debug)
+ qDebug()<<"ui*h file is more recent then source file, using information from ui*h file"<<m_fileName;
+ QTextStream stream(&file);
+ m_contents = stream.readAll().toUtf8();
+ m_cacheTime = uiHeaderTime;
+ return;
+ }
+ }
+
+ if (debug)
+ qDebug()<<"ui*h file not found, or not recent enough, trying to create it on the fly";
+ QFile file(m_sourceName);
+ if (file.open(QFile::ReadOnly)) {
+ QTextStream stream(&file);
+ const QString contents = stream.readAll();
+ if (runUic(contents)) {
+ if (debug)
+ qDebug()<<"created on the fly";
+ return;
+ } else {
+ // uic run was unsuccesfull
+ if (debug)
+ qDebug()<<"uic run wasn't succesfull";
+ m_cacheTime = QDateTime ();
+ m_contents = QByteArray();
+ // and if the header file wasn't there, next time we need to update
+ // all of the files that include this header
+ if (!uiHeaderFileInfo.exists())
+ m_updateIncludingFiles = true;
+ return;
+ }
+ } else {
+ if (debug)
+ qDebug()<<"Could open "<<m_sourceName<<"needed for the cpp model";
+ m_contents = QByteArray();
+ }
+}
+
+QByteArray UiCodeModelSupport::contents() const
+{
+ if (!m_initialized)
+ init();
+
+ return m_contents;
+}
+
+QString UiCodeModelSupport::fileName() const
+{
+ return m_fileName;
+}
+
+void UiCodeModelSupport::setFileName(const QString &name)
+{
+ if (m_fileName == name && m_cacheTime.isValid())
+ return;
+
+ if (debug)
+ qDebug() << "UiCodeModelSupport::setFileName"<<name;
+
+ m_fileName = name;
+ m_contents.clear();
+ m_cacheTime = QDateTime();
+ init();
+}
+
+bool UiCodeModelSupport::runUic(const QString &ui) const
+{
+ QProcess process;
+ const QString uic = uicCommand();
+ process.setEnvironment(environment());
+
+ if (debug)
+ qDebug() << "UiCodeModelSupport::runUic " << uic << " on " << ui.size() << " bytes";
+ process.start(uic, QStringList(), QIODevice::ReadWrite);
+ if (!process.waitForStarted())
+ return false;
+ process.write(ui.toUtf8());
+ process.closeWriteChannel();
+ if (process.waitForFinished() && process.exitStatus() == QProcess::NormalExit && process.exitCode() == 0) {
+ m_contents = process.readAllStandardOutput();
+ m_cacheTime = QDateTime::currentDateTime();
+ if (debug)
+ qDebug() << "ok" << m_contents.size() << "bytes.";
+ return true;
+ } else {
+ if (debug)
+ qDebug() << "failed" << process.readAllStandardError();
+ process.kill();
+ }
+ return false;
+}
+
+void UiCodeModelSupport::updateFromEditor(const QString &formEditorContents)
+{
+ if (runUic(formEditorContents)) {
+ updateDocument();
+ }
+}
+
+void UiCodeModelSupport::updateFromBuild()
+{
+ if (debug)
+ qDebug()<<"UiCodeModelSupport::updateFromBuild() for file"<<m_sourceName;
+ // This is mostly a fall back for the cases when uic couldn't be run
+ // it pays special attention to the case where a ui_*h was newly created
+ QDateTime sourceTime = QFileInfo(m_sourceName).lastModified();
+ if (m_cacheTime.isValid() && m_cacheTime >= sourceTime) {
+ if (debug)
+ qDebug()<<"Cache is still more recent then source";
+ return;
+ } else {
+ QFileInfo fi(m_fileName);
+ QDateTime uiHeaderTime = fi.exists() ? fi.lastModified() : QDateTime();
+ if (uiHeaderTime.isValid() && (uiHeaderTime > sourceTime)) {
+ if (m_cacheTime >= uiHeaderTime)
+ return;
+ if (debug)
+ qDebug()<<"found ui*h updating from it";
+
+ QFile file(m_fileName);
+ if (file.open(QFile::ReadOnly)) {
+ QTextStream stream(&file);
+ m_contents = stream.readAll().toUtf8();
+ m_cacheTime = uiHeaderTime;
+ updateDocument();
+ return;
+ }
+ }
+ if (debug)
+ qDebug()<<"ui*h not found or not more recent then source not changing anything";
+ }
+}
+
diff --git a/src/plugins/cpptools/uicodecompletionsupport.h b/src/plugins/cpptools/uicodecompletionsupport.h
new file mode 100644
index 0000000000..b03294960d
--- /dev/null
+++ b/src/plugins/cpptools/uicodecompletionsupport.h
@@ -0,0 +1,70 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+
+
+#ifndef UICODECOMPLETIONSUPPORT_H
+#define UICODECOMPLETIONSUPPORT_H
+
+#include "cppmodelmanagerinterface.h"
+#include "cpptools_global.h"
+
+#include <QtCore/QDateTime>
+
+namespace CppTools {
+
+class CPPTOOLS_EXPORT UiCodeModelSupport : public CppTools::AbstractEditorSupport
+{
+public:
+ UiCodeModelSupport(CppTools::CppModelManagerInterface *modelmanager,
+ const QString &sourceFile,
+ const QString &uiHeaderFile);
+ ~UiCodeModelSupport();
+ void setFileName(const QString &name);
+ void setSourceName(const QString &name);
+ virtual QByteArray contents() const;
+ virtual QString fileName() const;
+ void updateFromEditor(const QString &formEditorContents);
+ void updateFromBuild();
+protected:
+ virtual QString uicCommand() const = 0;
+ virtual QStringList environment() const = 0;
+private:
+ void init() const;
+ bool runUic(const QString &ui) const;
+ QString m_sourceName;
+ QString m_fileName;
+ mutable bool m_updateIncludingFiles;
+ mutable bool m_initialized;
+ mutable QByteArray m_contents;
+ mutable QDateTime m_cacheTime;
+};
+
+} // CppTools
+
+#endif // UICODECOMPLETIONSUPPORT_H