forked from qt-creator/qt-creator
CppEditor: Rework showing/switching parse configurations
* Move the combox box for switching the parse configurations out of the
"Additional Preprocessor Directives" dialog ('#'-button) to make it
better visible/accessible. Also, decouple the extra preprocessor
directives from the concrete parse context since this is not anymore
in same dialog.
* The combo box appears only if multiple parse configurations are
available for a file.
* The first time multiple parse configurations are detected, an info bar
is shown that points the user to the combox box. A "Do Not Show Again"
button is provided.
* Upon selecting an entry, the preferred parse configuration is saved as
part of the session. The setting can be cleared with the context menu
entry on the combo box.
Follow-up changes need to ensure that the display name and/or tooltip is
unambiguous, e.g. for qbs and cmake projects.
Change-Id: I9e9773704187291524ad7b605bfdddd83ef5b19d
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
172
src/plugins/cppeditor/cppparsecontext.cpp
Normal file
172
src/plugins/cppeditor/cppparsecontext.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2017 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** 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 The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cppparsecontext.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QDir>
|
||||
#include <QDebug>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
namespace CppEditor {
|
||||
namespace Internal {
|
||||
|
||||
void ParseContextModel::update(const CppTools::ProjectPartInfo &projectPartInfo)
|
||||
{
|
||||
beginResetModel();
|
||||
reset(projectPartInfo);
|
||||
endResetModel();
|
||||
|
||||
emit updated(areMultipleAvailable());
|
||||
}
|
||||
|
||||
QString ParseContextModel::currentToolTip() const
|
||||
{
|
||||
const QModelIndex index = createIndex(m_currentIndex, 0);
|
||||
if (!index.isValid())
|
||||
return QString();
|
||||
|
||||
return tr("<p><b>Active Parse Context</b>:<br/>%1</p>"
|
||||
"<p>Multiple parse contexts (set of defines, include paths, and so on) "
|
||||
"are available for this file.</p>"
|
||||
"<p>Choose a parse context to set it as the preferred one. "
|
||||
"Clear the preference from the context menu.</p>")
|
||||
.arg(data(index, Qt::ToolTipRole).toString());
|
||||
}
|
||||
|
||||
void ParseContextModel::setPreferred(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
emit preferredParseContextChanged(m_projectParts[index]->id());
|
||||
}
|
||||
|
||||
void ParseContextModel::clearPreferred()
|
||||
{
|
||||
emit preferredParseContextChanged(QString());
|
||||
}
|
||||
|
||||
bool ParseContextModel::areMultipleAvailable() const
|
||||
{
|
||||
return m_projectParts.size() >= 2;
|
||||
}
|
||||
|
||||
void ParseContextModel::reset(const CppTools::ProjectPartInfo &projectPartInfo)
|
||||
{
|
||||
// Sort
|
||||
m_hints = projectPartInfo.hints;
|
||||
m_projectParts = projectPartInfo.projectParts;
|
||||
Utils::sort(m_projectParts, &CppTools::ProjectPart::displayName);
|
||||
|
||||
// Determine index for current
|
||||
const QString id = projectPartInfo.projectPart->id();
|
||||
m_currentIndex = Utils::indexOf(m_projectParts, [id](const CppTools::ProjectPart::Ptr &pp) {
|
||||
return pp->id() == id;
|
||||
});
|
||||
QTC_CHECK(m_currentIndex >= 0);
|
||||
}
|
||||
|
||||
int ParseContextModel::currentIndex() const
|
||||
{
|
||||
return m_currentIndex;
|
||||
}
|
||||
|
||||
bool ParseContextModel::isCurrentPreferred() const
|
||||
{
|
||||
return m_hints & CppTools::ProjectPartInfo::IsPreferredMatch;
|
||||
}
|
||||
|
||||
QString ParseContextModel::currentId() const
|
||||
{
|
||||
if (m_currentIndex < 0)
|
||||
return QString();
|
||||
|
||||
return m_projectParts[m_currentIndex]->id();
|
||||
}
|
||||
|
||||
int ParseContextModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return m_projectParts.size();
|
||||
}
|
||||
|
||||
QVariant ParseContextModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (m_projectParts.isEmpty())
|
||||
return QVariant();
|
||||
|
||||
const int row = index.row();
|
||||
if (role == Qt::DisplayRole)
|
||||
return m_projectParts[row]->displayName;
|
||||
else if (role == Qt::ToolTipRole)
|
||||
return QDir::toNativeSeparators(m_projectParts[row]->projectFile);
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
ParseContextWidget::ParseContextWidget(ParseContextModel &parseContextModel, QWidget *parent)
|
||||
: QComboBox(parent)
|
||||
, m_parseContextModel(parseContextModel)
|
||||
{
|
||||
// Set up context menu with a clear action
|
||||
setContextMenuPolicy(Qt::ActionsContextMenu);
|
||||
m_clearPreferredAction = new QAction(tr("Clear Preferred Parse Context"), this);
|
||||
connect(m_clearPreferredAction, &QAction::triggered,[&]() {
|
||||
m_parseContextModel.clearPreferred();
|
||||
});
|
||||
addAction(m_clearPreferredAction);
|
||||
|
||||
// Set up sync of this widget and model in both directions
|
||||
connect(this,
|
||||
static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),
|
||||
&m_parseContextModel,
|
||||
&ParseContextModel::setPreferred);
|
||||
connect(&m_parseContextModel, &ParseContextModel::updated,
|
||||
this, &ParseContextWidget::syncToModel);
|
||||
|
||||
// Set up model
|
||||
setModel(&m_parseContextModel);
|
||||
}
|
||||
|
||||
void ParseContextWidget::syncToModel()
|
||||
{
|
||||
const int index = m_parseContextModel.currentIndex();
|
||||
if (index < 0)
|
||||
return; // E.g. editor was duplicated but no project context was determined yet.
|
||||
|
||||
if (currentIndex() != index)
|
||||
setCurrentIndex(index);
|
||||
|
||||
setToolTip(m_parseContextModel.currentToolTip());
|
||||
|
||||
const bool isPreferred = m_parseContextModel.isCurrentPreferred();
|
||||
m_clearPreferredAction->setEnabled(isPreferred);
|
||||
QComboBox::setProperty("highlightWidget", isPreferred);
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace CppEditor
|
||||
Reference in New Issue
Block a user