summaryrefslogtreecommitdiff
path: root/src/plugins/cppeditor
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cppeditor')
-rw-r--r--src/plugins/cppeditor/cppeditor.cpp47
-rw-r--r--src/plugins/cppeditor/cppeditor.h4
-rw-r--r--src/plugins/cppeditor/cppeditor.pro6
-rw-r--r--src/plugins/cppeditor/cppeditor.qbs6
-rw-r--r--src/plugins/cppeditor/cppeditorconstants.h3
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.cpp49
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.h7
-rw-r--r--src/plugins/cppeditor/cpppreprocessoradditionwidget.cpp171
-rw-r--r--src/plugins/cppeditor/cpppreprocessoradditionwidget.ui96
-rw-r--r--src/plugins/cppeditor/cpppreprocessordialog.cpp129
-rw-r--r--src/plugins/cppeditor/cpppreprocessordialog.h (renamed from src/plugins/cppeditor/cpppreprocessoradditionwidget.h)57
-rw-r--r--src/plugins/cppeditor/cpppreprocessordialog.ui109
-rw-r--r--src/plugins/cppeditor/cppquickfix_test.cpp180
-rw-r--r--src/plugins/cppeditor/cppquickfixes.cpp13
14 files changed, 510 insertions, 367 deletions
diff --git a/src/plugins/cppeditor/cppeditor.cpp b/src/plugins/cppeditor/cppeditor.cpp
index 7b36de8cf0..0604edde96 100644
--- a/src/plugins/cppeditor/cppeditor.cpp
+++ b/src/plugins/cppeditor/cppeditor.cpp
@@ -34,7 +34,7 @@
#include "cppeditorplugin.h"
#include "cppfollowsymbolundercursor.h"
#include "cpphighlighter.h"
-#include "cpppreprocessoradditionwidget.h"
+#include "cpppreprocessordialog.h"
#include "cppquickfixassistant.h"
#include <coreplugin/actionmanager/actioncontainer.h>
@@ -701,19 +701,15 @@ void CPPEditorWidget::selectAll()
void CPPEditorWidget::setMimeType(const QString &mt)
{
- const QString &fileName = editor()->document()->filePath();
- // Check if this editor belongs to a project
- QList<ProjectPart::Ptr> projectParts = m_modelManager->projectPart(fileName);
- if (projectParts.isEmpty())
- projectParts = m_modelManager->projectPartFromDependencies(fileName);
- if (!projectParts.isEmpty()) {
- if (ProjectExplorer::Project *project = projectParts.first()->project) {
- QByteArray additionalDefines = project->additionalCppDefines()
- .value(projectParts.first()->projectFile).toByteArray();
- m_modelManager->cppEditorSupport(editor())->snapshotUpdater()->setEditorDefines(
- additionalDefines);
- }
- }
+ const QString &filePath = editor()->document()->filePath();
+ const QString &projectFile = ProjectExplorer::SessionManager::value(
+ QLatin1String(Constants::CPP_PREPROCESSOR_PROJECT_PREFIX) + filePath).toString();
+ const QByteArray &additionalDirectives = ProjectExplorer::SessionManager::value(
+ projectFile + QLatin1Char(',') + filePath).toByteArray();
+
+ QSharedPointer<SnapshotUpdater> updater
+ = m_modelManager->cppEditorSupport(editor())->snapshotUpdater();
+ updater->setEditorDefines(additionalDirectives);
BaseTextEditorWidget::setMimeType(mt);
setObjCEnabled(mt == QLatin1String(CppTools::Constants::OBJECTIVE_C_SOURCE_MIMETYPE)
@@ -1968,28 +1964,21 @@ void CPPEditorWidget::onCommentsSettingsChanged(const CppTools::CommentsSettings
void CPPEditorWidget::showPreProcessorWidget()
{
const QString &fileName = editor()->document()->filePath();
- // Check if this editor belongs to a project
+ // Check if this editor belongs to a project
QList<ProjectPart::Ptr> projectParts = m_modelManager->projectPart(fileName);
if (projectParts.isEmpty())
projectParts = m_modelManager->projectPartFromDependencies(fileName);
if (projectParts.isEmpty())
projectParts << m_modelManager->fallbackProjectPart();
- PreProcessorAdditionPopUp::instance()->show(this, projectParts);
-
- connect(PreProcessorAdditionPopUp::instance(),
- SIGNAL(finished(QByteArray)),
- SLOT(preProcessorWidgetFinished(QByteArray)));
-}
-
-void CPPEditorWidget::preProcessorWidgetFinished(const QByteArray &additionalDefines)
-{
- PreProcessorAdditionPopUp::instance()->disconnect(this);
- QSharedPointer<SnapshotUpdater> updater
- = m_modelManager->cppEditorSupport(editor())->snapshotUpdater();
- updater->setEditorDefines(additionalDefines);
- updater->update(m_modelManager->workingCopy());
+ CppPreProcessorDialog preProcessorDialog(this, projectParts);
+ if (preProcessorDialog.exec() == QDialog::Accepted) {
+ QSharedPointer<SnapshotUpdater> updater
+ = m_modelManager->cppEditorSupport(editor())->snapshotUpdater();
+ updater->setEditorDefines(preProcessorDialog.additionalPreProcessorDirectives().toLatin1());
+ updater->update(m_modelManager->workingCopy());
+ }
}
#include <cppeditor.moc>
diff --git a/src/plugins/cppeditor/cppeditor.h b/src/plugins/cppeditor/cppeditor.h
index 1a5fe51d37..ae1f57e31b 100644
--- a/src/plugins/cppeditor/cppeditor.h
+++ b/src/plugins/cppeditor/cppeditor.h
@@ -144,6 +144,7 @@ public Q_SLOTS:
void renameSymbolUnderCursor();
void renameUsages();
void findUsages();
+ void showPreProcessorWidget();
void renameUsagesNow(const QString &replacement = QString());
void semanticRehighlight(bool force = false);
void highlighterStarted(QFuture<TextEditor::HighlightingResult> *highlighter,
@@ -187,9 +188,6 @@ private Q_SLOTS:
void onCommentsSettingsChanged(const CppTools::CommentsSettings &settings);
- void showPreProcessorWidget();
- void preProcessorWidgetFinished(const QByteArray &additionalDefines);
-
private:
void markSymbols(const QTextCursor &tc, const CppTools::SemanticInfo &info);
bool sortedOutline() const;
diff --git a/src/plugins/cppeditor/cppeditor.pro b/src/plugins/cppeditor/cppeditor.pro
index e0d9f7b0c4..64ffa94641 100644
--- a/src/plugins/cppeditor/cppeditor.pro
+++ b/src/plugins/cppeditor/cppeditor.pro
@@ -25,7 +25,7 @@ HEADERS += cppeditorplugin.h \
cppincludehierarchyitem.h \
cppincludehierarchytreeview.h \
cppvirtualfunctionassistprovider.h \
- cpppreprocessoradditionwidget.h
+ cpppreprocessordialog.h
SOURCES += cppeditorplugin.cpp \
cppautocompleter.cpp \
@@ -49,7 +49,7 @@ SOURCES += cppeditorplugin.cpp \
cppincludehierarchyitem.cpp \
cppincludehierarchytreeview.cpp \
cppvirtualfunctionassistprovider.cpp \
- cpppreprocessoradditionwidget.cpp
+ cpppreprocessordialog.cpp
RESOURCES += cppeditor.qrc
@@ -67,4 +67,4 @@ equals(TEST, 1) {
}
FORMS += \
- cpppreprocessoradditionwidget.ui
+ cpppreprocessordialog.ui
diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs
index 7ca766b74c..d8c465ad55 100644
--- a/src/plugins/cppeditor/cppeditor.qbs
+++ b/src/plugins/cppeditor/cppeditor.qbs
@@ -50,9 +50,9 @@ QtcPlugin {
"cppincludehierarchytreeview.h",
"cppoutline.cpp",
"cppoutline.h",
- "cpppreprocessoradditionwidget.cpp",
- "cpppreprocessoradditionwidget.h",
- "cpppreprocessoradditionwidget.ui",
+ "cpppreprocessordialog.cpp",
+ "cpppreprocessordialog.h",
+ "cpppreprocessordialog.ui",
"cppquickfixassistant.cpp",
"cppquickfixassistant.h",
"cppquickfix.cpp",
diff --git a/src/plugins/cppeditor/cppeditorconstants.h b/src/plugins/cppeditor/cppeditorconstants.h
index ae87b13ead..378789f911 100644
--- a/src/plugins/cppeditor/cppeditorconstants.h
+++ b/src/plugins/cppeditor/cppeditorconstants.h
@@ -41,6 +41,7 @@ const char SWITCH_DECLARATION_DEFINITION[] = "CppEditor.SwitchDeclarationDefinit
const char OPEN_DECLARATION_DEFINITION_IN_NEXT_SPLIT[] = "CppEditor.OpenDeclarationDefinitionInNextSplit";
const char RENAME_SYMBOL_UNDER_CURSOR[] = "CppEditor.RenameSymbolUnderCursor";
const char FIND_USAGES[] = "CppEditor.FindUsages";
+const char OPEN_PREPROCESSOR_DIALOG[] = "CppEditor.OpenPreprocessorDialog";
const char M_REFACTORING_MENU_INSERTION_POINT[] = "CppEditor.RefactorGroup";
const char UPDATE_CODEMODEL[] = "CppEditor.UpdateCodeModel";
@@ -62,6 +63,8 @@ const char WIZARD_TR_CATEGORY[] = QT_TRANSLATE_NOOP("CppEditor", "C++");
const char CPP_SNIPPETS_GROUP_ID[] = "C++";
+const char CPP_PREPROCESSOR_PROJECT_PREFIX[] = "CppPreprocessorProject-";
+
} // namespace Constants
} // namespace CppEditor
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp
index 4ffa0d93d6..b9c66de4a1 100644
--- a/src/plugins/cppeditor/cppeditorplugin.cpp
+++ b/src/plugins/cppeditor/cppeditorplugin.cpp
@@ -210,6 +210,13 @@ bool CppEditorPlugin::initialize(const QStringList & /*arguments*/, QString *err
contextMenu->addAction(cmd);
cppToolsMenu->addAction(cmd);
+ QAction *openPreprocessorDialog = new QAction(tr("Additional Preprocessor Directives"), this);
+ cmd = ActionManager::registerAction(openPreprocessorDialog,
+ Constants::OPEN_PREPROCESSOR_DIALOG, context);
+ cmd->setDefaultKeySequence(QKeySequence());
+ connect(openPreprocessorDialog, SIGNAL(triggered()), this, SLOT(showPreProcessorDialog()));
+ cppToolsMenu->addAction(cmd);
+
QAction *switchDeclarationDefinition = new QAction(tr("Switch Between Function Declaration/Definition"), this);
cmd = ActionManager::registerAction(switchDeclarationDefinition,
Constants::SWITCH_DECLARATION_DEFINITION, context, true);
@@ -326,32 +333,39 @@ ExtensionSystem::IPlugin::ShutdownFlag CppEditorPlugin::aboutToShutdown()
return SynchronousShutdown;
}
+static CPPEditorWidget *currentCppEditorWidget()
+{
+ return qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
+}
+
void CppEditorPlugin::switchDeclarationDefinition()
{
- CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
- if (editor)
- editor->switchDeclarationDefinition(/*inNextSplit*/ false);
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->switchDeclarationDefinition(/*inNextSplit*/ false);
}
void CppEditorPlugin::openDeclarationDefinitionInNextSplit()
{
- CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
- if (editor)
- editor->switchDeclarationDefinition(/*inNextSplit*/ true);
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->switchDeclarationDefinition(/*inNextSplit*/ true);
}
void CppEditorPlugin::renameSymbolUnderCursor()
{
- CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
- if (editor)
- editor->renameSymbolUnderCursor();
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->renameSymbolUnderCursor();
}
void CppEditorPlugin::findUsages()
{
- CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
- if (editor)
- editor->findUsages();
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->findUsages();
+}
+
+void CppEditorPlugin::showPreProcessorDialog()
+{
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->showPreProcessorWidget();
}
void CppEditorPlugin::onTaskStarted(Core::Id type)
@@ -381,14 +395,13 @@ void CppEditorPlugin::currentEditorChanged(IEditor *editor)
if (!editor)
return;
- if (CPPEditorWidget *textEditor = qobject_cast<CPPEditorWidget *>(editor->widget()))
- textEditor->semanticRehighlight(/*force = */ true);
+ if (CPPEditorWidget *editorWidget = currentCppEditorWidget())
+ editorWidget->semanticRehighlight(/*force = */ true);
}
void CppEditorPlugin::openTypeHierarchy()
{
- CPPEditorWidget *editor = qobject_cast<CPPEditorWidget*>(EditorManager::currentEditor()->widget());
- if (editor) {
+ if (currentCppEditorWidget()) {
NavigationWidget *navigation = NavigationWidget::instance();
navigation->activateSubWidget(Constants::TYPE_HIERARCHY_ID);
emit typeHierarchyRequested();
@@ -397,9 +410,7 @@ void CppEditorPlugin::openTypeHierarchy()
void CppEditorPlugin::openIncludeHierarchy()
{
- CPPEditorWidget *editor
- = qobject_cast<CPPEditorWidget*>(Core::EditorManager::currentEditor()->widget());
- if (editor) {
+ if (currentCppEditorWidget()) {
Core::NavigationWidget *navigation = Core::NavigationWidget::instance();
navigation->activateSubWidget(Core::Id(Constants::INCLUDE_HIERARCHY_ID));
emit includeHierarchyRequested();
diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h
index c1eb519de1..33e32593f4 100644
--- a/src/plugins/cppeditor/cppeditorplugin.h
+++ b/src/plugins/cppeditor/cppeditorplugin.h
@@ -81,6 +81,7 @@ public slots:
void openTypeHierarchy();
void openIncludeHierarchy();
void findUsages();
+ void showPreProcessorDialog();
void renameSymbolUnderCursor();
void switchDeclarationDefinition();
@@ -153,6 +154,12 @@ private slots:
void test_doxygen_comments_cpp_styleA_indented_continuation();
void test_doxygen_comments_cpp_styleA_corner_case();
+ void test_quickfix_CompleteSwitchCaseStatement_basic1();
+ void test_quickfix_CompleteSwitchCaseStatement_basic2();
+ void test_quickfix_CompleteSwitchCaseStatement_oneValueMissing();
+ void test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_1();
+ void test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_2();
+
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefix();
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespace();
void test_quickfix_GenerateGetterSetter_basicGetterWithPrefixAndNamespaceToCpp();
diff --git a/src/plugins/cppeditor/cpppreprocessoradditionwidget.cpp b/src/plugins/cppeditor/cpppreprocessoradditionwidget.cpp
deleted file mode 100644
index 7762af59cc..0000000000
--- a/src/plugins/cppeditor/cpppreprocessoradditionwidget.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of Qt Creator.
-**
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** 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.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-****************************************************************************/
-
-#include "cpppreprocessoradditionwidget.h"
-#include "ui_cpppreprocessoradditionwidget.h"
-
-#include "cppsnippetprovider.h"
-
-#include <utils/tooltip/tipcontents.h>
-#include <utils/tooltip/tooltip.h>
-#include <projectexplorer/project.h>
-
-#include <QDebug>
-
-using namespace CppEditor::Internal;
-
-PreProcessorAdditionWidget::PreProcessorAdditionWidget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::CppPreProcessorAdditionWidget)
-{
- ui->setupUi(this);
- CppEditor::Internal::CppSnippetProvider prov;
- prov.decorateEditor(ui->additionalEdit);
- setAttribute(Qt::WA_QuitOnClose, false);
- setFocusPolicy(Qt::StrongFocus);
- ui->additionalEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
-}
-
-PreProcessorAdditionWidget::~PreProcessorAdditionWidget()
-{
- emit finished();
- delete ui;
-}
-
-PreProcessorAdditionPopUp *PreProcessorAdditionPopUp::instance()
-{
- static PreProcessorAdditionPopUp inst;
- return &inst;
-}
-
-void PreProcessorAdditionPopUp::show(QWidget *parent,
- const QList<CppTools::ProjectPart::Ptr> &projectParts)
-{
- m_widget = new PreProcessorAdditionWidget();
- m_originalPartAdditions.clear();
- foreach (CppTools::ProjectPart::Ptr projectPart, projectParts) {
- ProjectPartAddition addition;
- addition.projectPart = projectPart;
- m_widget->ui->projectComboBox->addItem(projectPart->displayName);
- addition.additionalDefines = projectPart->project
- ->additionalCppDefines().value(projectPart->projectFile).toByteArray();
- m_originalPartAdditions << addition;
- }
- m_partAdditions = m_originalPartAdditions;
-
- m_widget->ui->additionalEdit->setPlainText(QLatin1String(
- m_partAdditions[m_widget->ui->projectComboBox->currentIndex()].additionalDefines));
-
- QPoint pos = parent->mapToGlobal(parent->rect().topRight());
- pos.setX(pos.x() - m_widget->width());
- showInternal(pos, Utils::WidgetContent(m_widget, true), parent, QRect());
-
- connect(m_widget->ui->additionalEdit, SIGNAL(textChanged()), SLOT(textChanged()));
- connect(m_widget->ui->projectComboBox, SIGNAL(currentIndexChanged(int)),
- SLOT(projectChanged(int)));
- connect(m_widget, SIGNAL(finished()), SLOT(finish()));
- connect(m_widget->ui->buttonBox, SIGNAL(accepted()), SLOT(apply()));
- connect(m_widget->ui->buttonBox, SIGNAL(rejected()), SLOT(cancel()));
-}
-
-bool PreProcessorAdditionPopUp::eventFilter(QObject *o, QEvent *event)
-{
- // Filter out some events that would hide the widget, when they would be handled by the ToolTip
- switch (event->type()) {
- case QEvent::Leave:
- // This event would hide the ToolTip because the view isn't a child of the WidgetContent
- if (m_widget->ui->projectComboBox->view() == qApp->focusWidget())
- return false;
- break;
- case QEvent::KeyPress:
- case QEvent::KeyRelease:
- case QEvent::ShortcutOverride:
- // Catch the escape key to close the widget
- if (static_cast<QKeyEvent *>(event)->key() == Qt::Key_Escape) {
- hideTipImmediately();
- return true;
- }
- break;
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseButtonDblClick:
- case QEvent::Wheel:
- // This event would hide the ToolTip because the viewport isn't a child of the WidgetContent
- if (o == m_widget->ui->projectComboBox->view()->viewport())
- return false;
- break;
- default:
- break;
- }
- return Utils::ToolTip::eventFilter(o, event);
-}
-
-void PreProcessorAdditionPopUp::textChanged()
-{
- m_partAdditions[m_widget->ui->projectComboBox->currentIndex()].additionalDefines
- = m_widget->ui->additionalEdit->toPlainText().toLatin1();
-}
-
-
-void PreProcessorAdditionPopUp::finish()
-{
- m_widget->disconnect(this);
- foreach (ProjectPartAddition partAddition, m_originalPartAdditions) {
- QVariantMap settings = partAddition.projectPart->project->additionalCppDefines();
- if (!settings[partAddition.projectPart->projectFile].toString().isEmpty()
- && !partAddition.additionalDefines.isEmpty()) {
- settings[partAddition.projectPart->projectFile] = partAddition.additionalDefines;
- partAddition.projectPart->project->setAdditionalCppDefines(settings);
- }
- }
- emit finished(m_originalPartAdditions.value(m_widget->ui->projectComboBox->currentIndex())
- .additionalDefines);
-}
-
-void PreProcessorAdditionPopUp::projectChanged(int index)
-{
- m_widget->ui->additionalEdit->setPlainText(
- QLatin1String(m_partAdditions[index].additionalDefines));
-}
-
-void PreProcessorAdditionPopUp::apply()
-{
- m_originalPartAdditions = m_partAdditions;
- hideTipImmediately();
-}
-
-void PreProcessorAdditionPopUp::cancel()
-{
- m_partAdditions = m_originalPartAdditions;
- hideTipImmediately();
-}
-
-PreProcessorAdditionPopUp::PreProcessorAdditionPopUp()
- : m_widget(0)
-{}
diff --git a/src/plugins/cppeditor/cpppreprocessoradditionwidget.ui b/src/plugins/cppeditor/cpppreprocessoradditionwidget.ui
deleted file mode 100644
index 101ba17d3f..0000000000
--- a/src/plugins/cppeditor/cpppreprocessoradditionwidget.ui
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>CppEditor::Internal::CppPreProcessorAdditionWidget</class>
- <widget class="QWidget" name="CppEditor::Internal::CppPreProcessorAdditionWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>415</width>
- <height>395</height>
- </rect>
- </property>
- <property name="focusPolicy">
- <enum>Qt::StrongFocus</enum>
- </property>
- <property name="windowTitle">
- <string>PP</string>
- </property>
- <property name="autoFillBackground">
- <bool>true</bool>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout">
- <item>
- <widget class="QLabel" name="projectLabel">
- <property name="text">
- <string>Project:</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="projectComboBox">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="Line" name="separator">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="additionalLabel">
- <property name="text">
- <string>Additional</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="TextEditor::SnippetEditorWidget" name="additionalEdit"/>
- </item>
- <item>
- <layout class="QHBoxLayout" name="horizontalLayout_2">
- <item>
- <spacer name="horizontalSpacer">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- <item>
- <widget class="QDialogButtonBox" name="buttonBox">
- <property name="standardButtons">
- <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- <customwidgets>
- <customwidget>
- <class>TextEditor::SnippetEditorWidget</class>
- <extends>QPlainTextEdit</extends>
- <header>texteditor/snippets/snippeteditor.h</header>
- </customwidget>
- </customwidgets>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/plugins/cppeditor/cpppreprocessordialog.cpp b/src/plugins/cppeditor/cpppreprocessordialog.cpp
new file mode 100644
index 0000000000..e964962555
--- /dev/null
+++ b/src/plugins/cppeditor/cpppreprocessordialog.cpp
@@ -0,0 +1,129 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+#include "cpppreprocessordialog.h"
+#include "ui_cpppreprocessordialog.h"
+
+#include "cppeditor.h"
+#include "cppeditorconstants.h"
+#include "cppsnippetprovider.h"
+
+#include <projectexplorer/session.h>
+
+using namespace CppEditor::Internal;
+
+static bool projectPartLessThan(const CppTools::ProjectPart::Ptr &projectPart1,
+ const CppTools::ProjectPart::Ptr &projectPart2)
+{
+ return projectPart1->displayName < projectPart2->displayName;
+}
+
+CppPreProcessorDialog::CppPreProcessorDialog(CPPEditorWidget *editorWidget,
+ const QList<CppTools::ProjectPart::Ptr> &projectParts)
+ : QDialog(editorWidget)
+ , m_ui(new Ui::CppPreProcessorDialog())
+ , m_filePath(editorWidget->editor()->document()->filePath())
+{
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
+ m_ui->setupUi(this);
+ m_ui->editorLabel->setText(m_ui->editorLabel->text().arg(QFileInfo(m_filePath).fileName()));
+ m_ui->editWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+
+ CppSnippetProvider().decorateEditor(m_ui->editWidget);
+
+ const QString &currentProjectFile = ProjectExplorer::SessionManager::value(
+ QLatin1String(Constants::CPP_PREPROCESSOR_PROJECT_PREFIX) + m_filePath).toString();
+ int currentIndex = 0;
+
+ QList<CppTools::ProjectPart::Ptr> sortedProjectParts(projectParts);
+ qStableSort(sortedProjectParts.begin(), sortedProjectParts.end(), projectPartLessThan);
+
+ foreach (CppTools::ProjectPart::Ptr projectPart, sortedProjectParts) {
+ m_ui->projectComboBox->addItem(projectPart->displayName);
+ ProjectPartAddition addition;
+ addition.projectPart = projectPart;
+ addition.additionalDirectives = ProjectExplorer::SessionManager::value(
+ projectPart->projectFile + QLatin1Char(',') + m_filePath).toString();
+ if (projectPart->projectFile == currentProjectFile)
+ currentIndex = m_ui->projectComboBox->count() - 1;
+ m_partAdditions << addition;
+ }
+ if (m_ui->projectComboBox->count() <= 1)
+ m_ui->projectComboBox->setEnabled(false);
+ m_ui->projectComboBox->setCurrentIndex(currentIndex);
+ m_ui->editWidget->setPlainText(m_partAdditions.value(currentIndex).additionalDirectives);
+
+ connect(m_ui->projectComboBox, SIGNAL(currentIndexChanged(int)), SLOT(projectChanged(int)));
+ connect(m_ui->editWidget, SIGNAL(textChanged()), SLOT(textChanged()));
+}
+
+CppPreProcessorDialog::~CppPreProcessorDialog()
+{
+ delete m_ui;
+}
+
+int CppPreProcessorDialog::exec()
+{
+ if (QDialog::exec() == Rejected)
+ return Rejected;
+
+ ProjectExplorer::SessionManager::setValue(
+ QLatin1String(Constants::CPP_PREPROCESSOR_PROJECT_PREFIX) + m_filePath,
+ m_partAdditions[m_ui->projectComboBox->currentIndex()].projectPart->projectFile);
+
+ foreach (ProjectPartAddition partAddition, m_partAdditions) {
+ const QString &previousDirectives = ProjectExplorer::SessionManager::value(
+ partAddition.projectPart->projectFile
+ + QLatin1Char(',')
+ + m_filePath).toString();
+ if (previousDirectives != partAddition.additionalDirectives) {
+ ProjectExplorer::SessionManager::setValue(
+ partAddition.projectPart->projectFile + QLatin1Char(',') + m_filePath,
+ partAddition.additionalDirectives);
+ }
+ }
+ return Accepted;
+}
+
+QString CppPreProcessorDialog::additionalPreProcessorDirectives() const
+{
+ return m_ui->editWidget->toPlainText();
+}
+
+void CppPreProcessorDialog::projectChanged(int index)
+{
+ m_ui->editWidget->setPlainText(m_partAdditions[index].additionalDirectives);
+}
+
+void CppPreProcessorDialog::textChanged()
+{
+ m_partAdditions[m_ui->projectComboBox->currentIndex()].additionalDirectives
+ = m_ui->editWidget->toPlainText();
+}
diff --git a/src/plugins/cppeditor/cpppreprocessoradditionwidget.h b/src/plugins/cppeditor/cpppreprocessordialog.h
index 828805ca1d..c56e397fe1 100644
--- a/src/plugins/cppeditor/cpppreprocessoradditionwidget.h
+++ b/src/plugins/cppeditor/cpppreprocessordialog.h
@@ -27,70 +27,47 @@
**
****************************************************************************/
-#ifndef CPPPREPROCESSORADDITIONWIDGET_H
-#define CPPPREPROCESSORADDITIONWIDGET_H
+#ifndef CPPPREPROCESSORDIALOG_H
+#define CPPPREPROCESSORDIALOG_H
#include <cpptools/cppmodelmanagerinterface.h>
-#include <utils/tooltip/tooltip.h>
-#include <QWidget>
-#include <QVariantMap>
-#include <QPointer>
+#include <QDialog>
namespace CppEditor {
namespace Internal {
-namespace Ui { class CppPreProcessorAdditionWidget; }
+namespace Ui { class CppPreProcessorDialog; }
-class PreProcessorAdditionWidget : public QWidget
-{
- Q_OBJECT
-
-public:
- explicit PreProcessorAdditionWidget(QWidget *parent = 0);
- ~PreProcessorAdditionWidget();
- Ui::CppPreProcessorAdditionWidget *ui;
+class CPPEditorWidget;
-signals:
- void finished();
-};
-
-class PreProcessorAdditionPopUp : public Utils::ToolTip
+class CppPreProcessorDialog : public QDialog
{
Q_OBJECT
public:
- ~PreProcessorAdditionPopUp(){}
- static PreProcessorAdditionPopUp *instance();
-
- void show(QWidget *parent, const QList<CppTools::ProjectPart::Ptr> &projectPartAdditions);
- bool eventFilter(QObject *o, QEvent *event);
+ explicit CppPreProcessorDialog(CPPEditorWidget *editorWidget,
+ const QList<CppTools::ProjectPart::Ptr> &projectParts);
+ ~CppPreProcessorDialog();
-signals:
- void finished(const QByteArray &additionalDefines);
+ int exec();
+ QString additionalPreProcessorDirectives() const;
private slots:
- void textChanged();
- void finish();
void projectChanged(int index);
- void apply();
- void cancel();
-
-protected:
- explicit PreProcessorAdditionPopUp();
+ void textChanged();
private:
struct ProjectPartAddition {
CppTools::ProjectPart::Ptr projectPart;
- QByteArray additionalDefines;
+ QString additionalDirectives;
};
- PreProcessorAdditionWidget* m_widget;
- QList<ProjectPartAddition> m_originalPartAdditions;
+ Ui::CppPreProcessorDialog *m_ui;
QList<ProjectPartAddition> m_partAdditions;
-
+ QString m_filePath;
};
-} // namespace CPPEditor
} // namespace Internal
+} // namespace CPPEditor
-#endif // CPPPREPROCESSORADDITIONWIDGET_H
+#endif // CPPPREPROCESSORDIALOG_H
diff --git a/src/plugins/cppeditor/cpppreprocessordialog.ui b/src/plugins/cppeditor/cpppreprocessordialog.ui
new file mode 100644
index 0000000000..28c7b5f47b
--- /dev/null
+++ b/src/plugins/cppeditor/cpppreprocessordialog.ui
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CppEditor::Internal::CppPreProcessorDialog</class>
+ <widget class="QDialog" name="CppEditor::Internal::CppPreProcessorDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>400</width>
+ <height>300</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Additional C++ Preprocess Directives</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="projectLabel">
+ <property name="text">
+ <string>Project:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="projectComboBox">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="Line" name="separator">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="editorLabel">
+ <property name="text">
+ <string>Additional C++ Preprocessor Directives for %1:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="TextEditor::SnippetEditorWidget" name="editWidget"/>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>TextEditor::SnippetEditorWidget</class>
+ <extends>QPlainTextEdit</extends>
+ <header location="global">texteditor/snippets/snippeteditor.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>CppEditor::Internal::CppPreProcessorDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>CppEditor::Internal::CppPreProcessorDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp
index 31c4b6513f..55fad435e7 100644
--- a/src/plugins/cppeditor/cppquickfix_test.cpp
+++ b/src/plugins/cppeditor/cppquickfix_test.cpp
@@ -349,6 +349,186 @@ private:
} // anonymous namespace
+/// Checks: All enum values are added as case statements for a blank switch.
+void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic1()
+{
+ const QByteArray original =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " @switch (t) {\n"
+ " }\n"
+ "}\n";
+ ;
+ const QByteArray expected =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " switch (t) {\n"
+ " case V1:\n"
+ " break;\n"
+ " case V2:\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ ;
+
+ CompleteSwitchCaseStatement factory;
+ TestCase data(original, expected);
+ data.run(&factory);
+}
+
+/// Checks: All enum values are added as case statements for a blank switch with a default case.
+void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_basic2()
+{
+ const QByteArray original =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " @switch (t) {\n"
+ " default:\n"
+ " break;\n"
+ " }\n"
+ "}\n";
+ ;
+ const QByteArray expected =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " switch (t) {\n"
+ " case V1:\n"
+ " break;\n"
+ " case V2:\n"
+ " break;\n"
+ " default:\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ ;
+
+ CompleteSwitchCaseStatement factory;
+ TestCase data(original, expected);
+ data.run(&factory);
+}
+
+/// Checks: The missing enum value is added.
+void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_oneValueMissing()
+{
+ const QByteArray original =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " @switch (t) {\n"
+ " case V2:\n"
+ " break;\n"
+ " default:\n"
+ " break;\n"
+ " }\n"
+ "}\n";
+ ;
+ const QByteArray expected =
+ "enum EnumType { V1, V2 };\n"
+ "\n"
+ "void f()\n"
+ "{\n"
+ " EnumType t;\n"
+ " switch (t) {\n"
+ " case V1:\n"
+ " break;\n"
+ " case V2:\n"
+ " break;\n"
+ " default:\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ ;
+
+ CompleteSwitchCaseStatement factory;
+ TestCase data(original, expected);
+ data.run(&factory);
+}
+
+/// Checks: Find the correct enum type despite there being a declaration with the same name.
+void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_1()
+{
+ const QByteArray original =
+ "enum test { TEST_1, TEST_2 };\n"
+ "\n"
+ "void f() {\n"
+ " enum test test;\n"
+ " @switch (test) {\n"
+ " }\n"
+ "}\n"
+ ;
+ const QByteArray expected =
+ "enum test { TEST_1, TEST_2 };\n"
+ "\n"
+ "void f() {\n"
+ " enum test test;\n"
+ " switch (test) {\n"
+ " case TEST_1:\n"
+ " break;\n"
+ " case TEST_2:\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ ;
+
+ CompleteSwitchCaseStatement factory;
+ TestCase data(original, expected);
+ data.run(&factory);
+}
+
+/// Checks: Find the correct enum type despite there being a declaration with the same name.
+void CppEditorPlugin::test_quickfix_CompleteSwitchCaseStatement_QTCREATORBUG10366_2()
+{
+ const QByteArray original =
+ "enum test1 { Wrong11, Wrong12 };\n"
+ "enum test { Right1, Right2 };\n"
+ "enum test2 { Wrong21, Wrong22 };\n"
+ "\n"
+ "int main() {\n"
+ " enum test test;\n"
+ " @switch (test) {\n"
+ " }\n"
+ "}\n"
+ ;
+ const QByteArray expected =
+ "enum test1 { Wrong11, Wrong12 };\n"
+ "enum test { Right1, Right2 };\n"
+ "enum test2 { Wrong21, Wrong22 };\n"
+ "\n"
+ "int main() {\n"
+ " enum test test;\n"
+ " switch (test) {\n"
+ " case Right1:\n"
+ " break;\n"
+ " case Right2:\n"
+ " break;\n"
+ " }\n"
+ "}\n"
+ "\n"
+ ;
+
+ CompleteSwitchCaseStatement factory;
+ TestCase data(original, expected);
+ data.run(&factory);
+}
+
/// Checks:
/// 1. If the name does not start with ("m_" or "_") and does not
/// end with "_", we are forced to prefix the getter with "get".
diff --git a/src/plugins/cppeditor/cppquickfixes.cpp b/src/plugins/cppeditor/cppquickfixes.cpp
index dcdd879686..6956cb9c78 100644
--- a/src/plugins/cppeditor/cppquickfixes.cpp
+++ b/src/plugins/cppeditor/cppquickfixes.cpp
@@ -2295,9 +2295,16 @@ Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctxt)
if (Enum *e = type->asEnumType())
return e;
if (const NamedType *namedType = type->asNamedType()) {
- const QList<LookupItem> candidates =
- ctxt.lookup(namedType->name(), result.scope());
- return findEnum(candidates, ctxt);
+ if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) {
+ const QList<Enum *> enums = con->unscopedEnums();
+ const Name *referenceName = namedType->name();
+ foreach (Enum *e, enums) {
+ if (const Name *candidateName = e->name()) {
+ if (candidateName->isEqualTo(referenceName))
+ return e;
+ }
+ }
+ }
}
}