Commit f30bd48b authored by David Schulz's avatar David Schulz

CPPEditor: Rework preprocessor addition tooltip.

Change the preprocessor popup to a dialog.
Save the additional preprocessor directives to the session instead of the
.pro.user file.

Change-Id: I0d08c5684cfb21e822cde0a965c9cf14e5d6d47d
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 04cd0265
......@@ -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,18 +701,17 @@ void CPPEditorWidget::selectAll()
void CPPEditorWidget::setMimeType(const QString &mt)
{
const QString &fileName = editor()->document()->filePath();
const QString &filePath = editor()->document()->filePath();
// Check if this editor belongs to a project
QList<ProjectPart::Ptr> projectParts = m_modelManager->projectPart(fileName);
QList<ProjectPart::Ptr> projectParts = m_modelManager->projectPart(filePath);
if (projectParts.isEmpty())
projectParts = m_modelManager->projectPartFromDependencies(fileName);
projectParts = m_modelManager->projectPartFromDependencies(filePath);
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);
}
QSharedPointer<SnapshotUpdater> updater
= m_modelManager->cppEditorSupport(editor())->snapshotUpdater();
const QString &projectFile = projectParts.first()->projectFile;
updater->setEditorDefines(ProjectExplorer::SessionManager::value(
projectFile + QLatin1Char(',') + filePath).toByteArray());
}
BaseTextEditorWidget::setMimeType(mt);
......@@ -1968,28 +1967,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>
......@@ -188,7 +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);
......
......@@ -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
......@@ -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",
......
/****************************************************************************
**
** 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)
{}
/****************************************************************************
**
** 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 "cppsnippetprovider.h"
#include <projectexplorer/session.h>
using namespace CppEditor::Internal;
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()));
CppSnippetProvider().decorateEditor(m_ui->editWidget);
foreach (CppTools::ProjectPart::Ptr projectPart, projectParts) {
m_ui->projectComboBox->addItem(projectPart->displayName);
ProjectPartAddition addition;
addition.projectPart = projectPart;
addition.additionalDirectives = ProjectExplorer::SessionManager::value(
projectPart->projectFile + QLatin1Char(',') + m_filePath).toString();
m_partAdditions << addition;
}
if (m_ui->projectComboBox->count() <= 1)
m_ui->projectComboBox->setEnabled(false);
m_ui->editWidget->setPlainText(
m_partAdditions.value(m_ui->projectComboBox->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;
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();
}
......@@ -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
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>CppEditor::Internal::CppPreProcessorAdditionWidget</class>
<widget class="QWidget" name="CppEditor::Internal::CppPreProcessorAdditionWidget">
<class>CppEditor::Internal::CppPreProcessorDialog</class>
<widget class="QDialog" name="CppEditor::Internal::CppPreProcessorDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>415</width>
<height>395</height>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<property name="windowTitle">
<string>PP</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
<string>Additional C++ Preprocess Directives</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
......@@ -49,38 +43,24 @@
</widget>
</item>
<item>
<widget class="QLabel" name="additionalLabel">
<widget class="QLabel" name="editorLabel">
<property name="text">
<string>Additional</string>
<string>Additional C++ Preprocessor Directives for %1:</string>
</property>
</widget>
</item>
<item>
<widget class="TextEditor::SnippetEditorWidget" name="additionalEdit"/>
<widget class="TextEditor::SnippetEditorWidget" name="editWidget"/>
</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>
<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>
......@@ -88,9 +68,42 @@
<customwidget>
<class>TextEditor::SnippetEditorWidget</class>
<extends>QPlainTextEdit</extends>
<header>texteditor/snippets/snippeteditor.h</header>
<header location="global">texteditor/snippets/snippeteditor.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
<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>
......@@ -71,7 +71,6 @@ const char TARGET_KEY_PREFIX[] = "ProjectExplorer.Project.Target.";
const char TARGET_COUNT_KEY[] = "ProjectExplorer.Project.TargetCount";
const char EDITOR_SETTINGS_KEY[] = "ProjectExplorer.Project.EditorSettings";
const char PLUGIN_SETTINGS_KEY[] = "ProjectExplorer.Project.PluginSettings";
const char CPP_SETTINGS_KEY[] = "ProjectExplorer.Project.CppSettings";
} // namespace
namespace ProjectExplorer {
......@@ -91,7 +90,6 @@ public:
Core::Context m_projectContext;
Core::Context m_projectLanguages;
QVariantMap m_pluginSettings;
QVariantMap m_additionalCppDefines;
SettingsAccessor *m_accessor;
};
......@@ -331,7 +329,6 @@ QVariantMap Project::toMap() const
map.insert(QLatin1String(EDITOR_SETTINGS_KEY), d->m_editorConfiguration->toMap());
map.insert(QLatin1String(PLUGIN_SETTINGS_KEY), d->m_pluginSettings);
map.insert(QLatin1String(CPP_SETTINGS_KEY), d->m_additionalCppDefines);
return map;
}
......@@ -359,8 +356,6 @@ bool Project::fromMap(const QVariantMap &map)
if (map.contains(QLatin1String(PLUGIN_SETTINGS_KEY)))
d->m_pluginSettings = map.value(QLatin1String(PLUGIN_SETTINGS_KEY)).toMap();
if (map.contains(QLatin1String(CPP_SETTINGS_KEY)))
d->m_additionalCppDefines = map.value(QLatin1String(CPP_SETTINGS_KEY)).toMap();
bool ok;
int maxI(map.value(QLatin1String(TARGET_COUNT_KEY), 0).toInt(&ok));
......@@ -465,16 +460,6 @@ void Project::setNamedSettings(const QString &name, const QVariant &value)
d->m_pluginSettings.insert(name, value);
}
QVariantMap Project::additionalCppDefines() const
{
return d->m_additionalCppDefines;
}
void Project::setAdditionalCppDefines(const QVariantMap value) const
{
d->m_additionalCppDefines = value;
}
bool Project::needsConfiguration() const
{
return false;
......
......@@ -123,9 +123,6 @@ public:
QVariant namedSettings(const QString &name) const;
void setNamedSettings(const QString &name, const QVariant &value);
QVariantMap additionalCppDefines() const;
void setAdditionalCppDefines(const QVariantMap value) const;
virtual bool needsConfiguration() const;
virtual void configureAsExampleProject(const QStringList &platforms);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment