2012-10-02 09:12:39 +02:00
|
|
|
/****************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2014-01-07 13:27:11 +01:00
|
|
|
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
2012-10-02 09:12:39 +02:00
|
|
|
** Contact: http://www.qt-project.org/legal
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** This file is part of Qt Creator.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
** 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.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2012-10-02 09:12:39 +02:00
|
|
|
** 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
|
2010-12-17 16:01:08 +01:00
|
|
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
|
**
|
2012-10-02 09:12:39 +02:00
|
|
|
****************************************************************************/
|
2008-12-02 15:08:31 +01:00
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "cppeditor.h"
|
2013-03-27 18:54:03 +01:00
|
|
|
|
2013-09-20 10:32:41 +02:00
|
|
|
#include "cppautocompleter.h"
|
2014-06-09 22:02:57 -04:00
|
|
|
#include "cppcanonicalsymbol.h"
|
|
|
|
|
#include "cppdocumentationcommenthelper.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "cppeditorconstants.h"
|
2014-08-19 15:59:29 +02:00
|
|
|
#include "cppeditordocument.h"
|
2014-05-23 13:55:03 -04:00
|
|
|
#include "cppeditoroutline.h"
|
2013-03-19 13:44:02 +01:00
|
|
|
#include "cppeditorplugin.h"
|
2013-09-20 10:32:41 +02:00
|
|
|
#include "cppfollowsymbolundercursor.h"
|
2008-12-02 12:01:29 +01:00
|
|
|
#include "cpphighlighter.h"
|
2014-05-20 12:24:32 -04:00
|
|
|
#include "cpplocalrenaming.h"
|
2013-10-17 11:19:26 +02:00
|
|
|
#include "cpppreprocessordialog.h"
|
2011-04-15 16:19:23 +02:00
|
|
|
#include "cppquickfixassistant.h"
|
2014-08-19 15:59:29 +02:00
|
|
|
#include "cppuseselectionsupdater.h"
|
2009-08-07 13:02:36 +02:00
|
|
|
|
2013-03-27 18:54:03 +01:00
|
|
|
#include <coreplugin/actionmanager/actioncontainer.h>
|
|
|
|
|
#include <coreplugin/actionmanager/actionmanager.h>
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
#include <cpptools/cppchecksymbols.h>
|
2012-02-07 15:09:08 +01:00
|
|
|
#include <cpptools/cppchecksymbols.h>
|
2010-07-05 13:48:53 +02:00
|
|
|
#include <cpptools/cppcodeformatter.h>
|
2013-08-30 12:55:06 +02:00
|
|
|
#include <cpptools/cppcompletionassistprovider.h>
|
2014-09-15 00:12:27 +02:00
|
|
|
#include <cpptools/cppmodelmanager.h>
|
2014-05-20 09:24:48 -04:00
|
|
|
#include <cpptools/cppsemanticinfo.h>
|
2014-08-19 12:12:45 +02:00
|
|
|
#include <cpptools/cpptoolsconstants.h>
|
2014-05-20 09:24:48 -04:00
|
|
|
#include <cpptools/cpptoolsplugin.h>
|
2011-11-14 13:14:39 +01:00
|
|
|
#include <cpptools/cpptoolsreuse.h>
|
2014-07-30 16:29:02 +02:00
|
|
|
#include <cpptools/cppworkingcopy.h>
|
2012-01-20 14:43:21 +01:00
|
|
|
#include <cpptools/symbolfinder.h>
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-09-26 09:14:03 +02:00
|
|
|
#include <texteditor/textdocument.h>
|
|
|
|
|
#include <texteditor/textdocumentlayout.h>
|
2014-09-04 00:04:18 +02:00
|
|
|
#include <texteditor/codeassist/assistproposalitem.h>
|
|
|
|
|
#include <texteditor/codeassist/genericproposalmodel.h>
|
2013-03-27 18:54:03 +01:00
|
|
|
#include <texteditor/codeassist/genericproposal.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
#include <texteditor/fontsettings.h>
|
2011-08-10 09:50:04 +02:00
|
|
|
#include <texteditor/refactoroverlay.h>
|
2013-03-27 18:54:03 +01:00
|
|
|
|
|
|
|
|
#include <cplusplus/ASTPath.h>
|
2014-08-19 15:59:29 +02:00
|
|
|
#include <utils/qtcassert.h>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QAction>
|
2014-08-19 15:59:29 +02:00
|
|
|
#include <QElapsedTimer>
|
2014-05-20 09:24:48 -04:00
|
|
|
#include <QFutureWatcher>
|
2012-02-15 10:42:41 +01:00
|
|
|
#include <QMenu>
|
2014-05-20 09:24:48 -04:00
|
|
|
#include <QPointer>
|
|
|
|
|
#include <QSignalMapper>
|
|
|
|
|
#include <QTextEdit>
|
|
|
|
|
#include <QTimer>
|
2013-08-20 07:46:19 +02:00
|
|
|
#include <QToolButton>
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
enum { UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL = 200 };
|
2009-06-24 16:40:30 +02:00
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
using namespace Core;
|
2009-07-09 12:14:00 +02:00
|
|
|
using namespace CPlusPlus;
|
2012-02-07 15:09:08 +01:00
|
|
|
using namespace CppTools;
|
2014-09-03 10:57:51 +02:00
|
|
|
using namespace TextEditor;
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
namespace CppEditor {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
CppEditor::CppEditor()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-09-03 12:43:01 +02:00
|
|
|
addContext(ProjectExplorer::Constants::LANG_CXX);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2012-01-24 11:07:26 +01:00
|
|
|
Q_GLOBAL_STATIC(CppTools::SymbolFinder, symbolFinder)
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
class CppEditorWidgetPrivate
|
2014-05-20 09:24:48 -04:00
|
|
|
{
|
|
|
|
|
public:
|
2014-07-30 16:30:31 +02:00
|
|
|
CppEditorWidgetPrivate(CppEditorWidget *q);
|
2014-05-20 09:24:48 -04:00
|
|
|
|
|
|
|
|
public:
|
2014-09-15 00:12:27 +02:00
|
|
|
QPointer<CppTools::CppModelManager> m_modelManager;
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
CppEditorDocument *m_cppEditorDocument;
|
2014-05-23 13:55:03 -04:00
|
|
|
CppEditorOutline *m_cppEditorOutline;
|
|
|
|
|
|
2014-05-26 12:24:23 -04:00
|
|
|
CppDocumentationCommentHelper m_cppDocumentationCommentHelper;
|
|
|
|
|
|
2014-08-21 17:47:22 +02:00
|
|
|
QTimer m_updateFunctionDeclDefLinkTimer;
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-05-20 12:24:32 -04:00
|
|
|
CppLocalRenaming m_localRenaming;
|
2014-05-20 09:24:48 -04:00
|
|
|
|
|
|
|
|
CppTools::SemanticInfo m_lastSemanticInfo;
|
2014-09-03 21:53:40 +02:00
|
|
|
QList<QuickFixOperation::Ptr> m_quickFixes;
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
CppUseSelectionsUpdater m_useSelectionsUpdater;
|
2014-05-20 09:24:48 -04:00
|
|
|
|
|
|
|
|
FunctionDeclDefLinkFinder *m_declDefLinkFinder;
|
|
|
|
|
QSharedPointer<FunctionDeclDefLink> m_declDefLink;
|
|
|
|
|
|
|
|
|
|
QScopedPointer<FollowSymbolUnderCursor> m_followSymbolUnderCursor;
|
|
|
|
|
QToolButton *m_preprocessorButton;
|
|
|
|
|
};
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
CppEditorWidgetPrivate::CppEditorWidgetPrivate(CppEditorWidget *q)
|
2014-09-15 00:12:27 +02:00
|
|
|
: m_modelManager(CppModelManager::instance())
|
2014-08-27 10:01:27 +02:00
|
|
|
, m_cppEditorDocument(qobject_cast<CppEditorDocument *>(q->textDocument()))
|
2014-05-23 13:55:03 -04:00
|
|
|
, m_cppEditorOutline(new CppEditorOutline(q))
|
2014-05-26 12:24:23 -04:00
|
|
|
, m_cppDocumentationCommentHelper(q)
|
2014-05-20 12:24:32 -04:00
|
|
|
, m_localRenaming(q)
|
2014-08-19 15:59:29 +02:00
|
|
|
, m_useSelectionsUpdater(q)
|
2014-05-20 09:24:48 -04:00
|
|
|
, m_declDefLinkFinder(new FunctionDeclDefLinkFinder(q))
|
|
|
|
|
, m_followSymbolUnderCursor(new FollowSymbolUnderCursor(q))
|
|
|
|
|
, m_preprocessorButton(0)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-27 14:18:35 +02:00
|
|
|
CppEditorWidget::CppEditorWidget()
|
|
|
|
|
: d(new CppEditorWidgetPrivate(this))
|
2014-01-09 18:04:45 +01:00
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
qRegisterMetaType<SemanticInfo>("CppTools::SemanticInfo");
|
2014-08-27 14:18:35 +02:00
|
|
|
}
|
2014-08-19 15:59:29 +02:00
|
|
|
|
2014-08-27 14:18:35 +02:00
|
|
|
void CppEditorWidget::finalizeInitialization()
|
|
|
|
|
{
|
|
|
|
|
d->m_cppEditorDocument = qobject_cast<CppEditorDocument *>(textDocument());
|
2014-08-21 18:08:58 +02:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
setLanguageSettingsId(CppTools::Constants::CPP_SETTINGS_ID);
|
2009-03-16 17:23:50 +01:00
|
|
|
setCodeFoldingSupported(true);
|
2014-08-19 15:59:29 +02:00
|
|
|
setMarksVisible(true);
|
|
|
|
|
setParenthesesMatchingEnabled(true);
|
2014-08-01 18:29:38 +02:00
|
|
|
setRevisionsVisible(true);
|
2010-11-10 17:00:07 +01:00
|
|
|
|
2014-08-27 14:18:35 +02:00
|
|
|
// function combo box sorting
|
|
|
|
|
connect(CppEditorPlugin::instance(), &CppEditorPlugin::outlineSortingChanged,
|
|
|
|
|
outline(), &CppEditorOutline::setSorted);
|
|
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
connect(d->m_cppEditorDocument, &CppEditorDocument::codeWarningsUpdated,
|
2014-08-19 15:59:29 +02:00
|
|
|
this, &CppEditorWidget::onCodeWarningsUpdated);
|
2014-08-27 10:01:27 +02:00
|
|
|
connect(d->m_cppEditorDocument, &CppEditorDocument::ifdefedOutBlocksUpdated,
|
2014-08-19 15:59:29 +02:00
|
|
|
this, &CppEditorWidget::onIfdefedOutBlocksUpdated);
|
|
|
|
|
connect(d->m_cppEditorDocument, SIGNAL(cppDocumentUpdated(CPlusPlus::Document::Ptr)),
|
|
|
|
|
this, SLOT(onCppDocumentUpdated()));
|
|
|
|
|
connect(d->m_cppEditorDocument, SIGNAL(semanticInfoUpdated(CppTools::SemanticInfo)),
|
|
|
|
|
this, SLOT(updateSemanticInfo(CppTools::SemanticInfo)));
|
2010-07-05 18:52:52 +02:00
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
connect(d->m_declDefLinkFinder, SIGNAL(foundLink(QSharedPointer<FunctionDeclDefLink>)),
|
2011-08-10 09:50:04 +02:00
|
|
|
this, SLOT(onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink>)));
|
2011-12-07 15:05:02 +01:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
connect(&d->m_useSelectionsUpdater,
|
|
|
|
|
SIGNAL(selectionsForVariableUnderCursorUpdated(QList<QTextEdit::ExtraSelection>)),
|
|
|
|
|
&d->m_localRenaming,
|
|
|
|
|
SLOT(updateSelectionsForVariableUnderCursor(QList<QTextEdit::ExtraSelection>)));
|
2014-08-21 17:47:22 +02:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
connect(&d->m_useSelectionsUpdater, &CppUseSelectionsUpdater::finished,
|
|
|
|
|
[this] (CppTools::SemanticInfo::LocalUseMap localUses) {
|
|
|
|
|
QTC_CHECK(isSemanticInfoValidExceptLocalUses());
|
|
|
|
|
d->m_lastSemanticInfo.localUsesUpdated = true;
|
|
|
|
|
d->m_lastSemanticInfo.localUses = localUses;
|
|
|
|
|
});
|
2014-05-20 09:24:48 -04:00
|
|
|
|
2014-09-09 11:09:07 +02:00
|
|
|
connect(document(), SIGNAL(contentsChange(int,int,int)),
|
|
|
|
|
&d->m_localRenaming, SLOT(onContentsChangeOfEditorWidgetDocument(int,int,int)));
|
2014-08-19 15:59:29 +02:00
|
|
|
connect(&d->m_localRenaming, &CppLocalRenaming::finished, [this] {
|
|
|
|
|
cppEditorDocument()->semanticRehighlight();
|
|
|
|
|
});
|
|
|
|
|
connect(&d->m_localRenaming, &CppLocalRenaming::processKeyPressNormally,
|
|
|
|
|
this, &CppEditorWidget::processKeyNormally);
|
2014-05-23 13:55:03 -04:00
|
|
|
connect(this, SIGNAL(cursorPositionChanged()),
|
|
|
|
|
d->m_cppEditorOutline, SLOT(updateIndex()));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-09-09 16:02:31 +02:00
|
|
|
connect(cppEditorDocument(), &CppEditorDocument::preprocessorSettingsChanged,
|
|
|
|
|
[this](bool customSettings) {
|
|
|
|
|
d->m_preprocessorButton->setProperty("highlightWidget", customSettings);
|
|
|
|
|
d->m_preprocessorButton->update();
|
|
|
|
|
});
|
|
|
|
|
|
2011-08-10 09:50:04 +02:00
|
|
|
// set up function declaration - definition link
|
2014-08-19 15:59:29 +02:00
|
|
|
d->m_updateFunctionDeclDefLinkTimer.setSingleShot(true);
|
|
|
|
|
d->m_updateFunctionDeclDefLinkTimer.setInterval(UPDATE_FUNCTION_DECL_DEF_LINK_INTERVAL);
|
|
|
|
|
connect(&d->m_updateFunctionDeclDefLinkTimer, SIGNAL(timeout()),
|
|
|
|
|
this, SLOT(updateFunctionDeclDefLinkNow()));
|
2011-08-10 09:50:04 +02:00
|
|
|
connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(updateFunctionDeclDefLink()));
|
|
|
|
|
connect(this, SIGNAL(textChanged()), this, SLOT(updateFunctionDeclDefLink()));
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
// set up the use highlighitng
|
|
|
|
|
connect(this, &CppEditorWidget::cursorPositionChanged, [this]() {
|
|
|
|
|
if (!d->m_localRenaming.isActive())
|
|
|
|
|
d->m_useSelectionsUpdater.scheduleUpdate();
|
|
|
|
|
});
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
// Tool bar creation
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_preprocessorButton = new QToolButton(this);
|
|
|
|
|
d->m_preprocessorButton->setText(QLatin1String("#"));
|
2014-09-03 21:53:40 +02:00
|
|
|
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
2013-10-23 14:13:06 +02:00
|
|
|
connect(cmd, SIGNAL(keySequenceChanged()), this, SLOT(updatePreprocessorButtonTooltip()));
|
|
|
|
|
updatePreprocessorButtonTooltip();
|
2014-05-20 09:24:48 -04:00
|
|
|
connect(d->m_preprocessorButton, SIGNAL(clicked()), this, SLOT(showPreProcessorWidget()));
|
2014-09-03 21:53:40 +02:00
|
|
|
insertExtraToolBarWidget(BaseTextEditorWidget::Left, d->m_preprocessorButton);
|
|
|
|
|
insertExtraToolBarWidget(BaseTextEditorWidget::Left, d->m_cppEditorOutline->widget());
|
2014-08-28 18:37:50 +02:00
|
|
|
}
|
2014-08-27 14:18:35 +02:00
|
|
|
|
2014-08-28 18:37:50 +02:00
|
|
|
void CppEditorWidget::finalizeInitializationAfterDuplication(BaseTextEditorWidget *other)
|
|
|
|
|
{
|
|
|
|
|
QTC_ASSERT(other, return);
|
|
|
|
|
CppEditorWidget *cppEditorWidget = qobject_cast<CppEditorWidget *>(other);
|
|
|
|
|
QTC_ASSERT(cppEditorWidget, return);
|
|
|
|
|
|
|
|
|
|
if (cppEditorWidget->isSemanticInfoValidExceptLocalUses())
|
|
|
|
|
updateSemanticInfo(cppEditorWidget->semanticInfo());
|
|
|
|
|
d->m_cppEditorOutline->update();
|
|
|
|
|
const ExtraSelectionKind selectionKind = CodeWarningsSelection;
|
|
|
|
|
setExtraSelections(selectionKind, cppEditorWidget->extraSelections(selectionKind));
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-01 18:01:29 +02:00
|
|
|
CppEditorWidget::~CppEditorWidget()
|
|
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
// non-inline destructor, see section "Forward Declared Pointers" of QScopedPointer.
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-27 10:01:27 +02:00
|
|
|
CppEditorDocument *CppEditorWidget::cppEditorDocument() const
|
2014-08-01 18:01:29 +02:00
|
|
|
{
|
|
|
|
|
return d->m_cppEditorDocument;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CppEditorOutline *CppEditorWidget::outline() const
|
|
|
|
|
{
|
|
|
|
|
return d->m_cppEditorOutline;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::paste()
|
2009-12-03 18:35:36 +01:00
|
|
|
{
|
2014-05-20 12:24:32 -04:00
|
|
|
if (d->m_localRenaming.handlePaste())
|
2009-12-03 18:35:36 +01:00
|
|
|
return;
|
|
|
|
|
|
2011-02-21 16:02:26 +01:00
|
|
|
BaseTextEditorWidget::paste();
|
2009-12-03 18:35:36 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::cut()
|
2009-12-03 18:35:36 +01:00
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
if (d->m_localRenaming.handleCut())
|
2009-12-03 18:35:36 +01:00
|
|
|
return;
|
|
|
|
|
|
2011-02-21 16:02:26 +01:00
|
|
|
BaseTextEditorWidget::cut();
|
2009-12-03 18:35:36 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::selectAll()
|
2012-01-18 12:09:41 +01:00
|
|
|
{
|
2014-05-20 12:24:32 -04:00
|
|
|
if (d->m_localRenaming.handleSelectAll())
|
2009-12-03 18:35:36 +01:00
|
|
|
return;
|
2011-11-14 13:22:44 +01:00
|
|
|
|
2014-05-20 12:24:32 -04:00
|
|
|
BaseTextEditorWidget::selectAll();
|
2009-07-01 18:41:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
void CppEditorWidget::onCppDocumentUpdated()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-23 13:55:03 -04:00
|
|
|
d->m_cppEditorOutline->update();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
void CppEditorWidget::onCodeWarningsUpdated(unsigned revision,
|
|
|
|
|
const QList<QTextEdit::ExtraSelection> selections)
|
|
|
|
|
{
|
|
|
|
|
if (revision != documentRevision())
|
|
|
|
|
return;
|
|
|
|
|
setExtraSelections(BaseTextEditorWidget::CodeWarningsSelection, selections);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CppEditorWidget::onIfdefedOutBlocksUpdated(unsigned revision,
|
2014-09-03 21:53:40 +02:00
|
|
|
const QList<BlockRange> ifdefedOutBlocks)
|
2014-08-19 15:59:29 +02:00
|
|
|
{
|
|
|
|
|
if (revision != documentRevision())
|
|
|
|
|
return;
|
|
|
|
|
setIfdefedOutBlocks(ifdefedOutBlocks);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::findUsages()
|
2010-01-29 21:33:57 +01:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_modelManager)
|
2013-10-02 09:26:50 +02:00
|
|
|
return;
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
SemanticInfo info = d->m_lastSemanticInfo;
|
2014-09-15 00:12:27 +02:00
|
|
|
info.snapshot = CppModelManager::instance()->snapshot();
|
2010-08-05 13:59:09 +02:00
|
|
|
info.snapshot.insert(info.doc);
|
2010-05-31 12:09:28 +02:00
|
|
|
|
2014-06-10 16:05:14 -04:00
|
|
|
if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_modelManager->findMacroUsages(*macro);
|
2012-03-08 15:53:28 +01:00
|
|
|
} else {
|
2014-06-13 14:16:14 -04:00
|
|
|
CanonicalSymbol cs(info.doc, info.snapshot);
|
2012-03-08 15:53:28 +01:00
|
|
|
Symbol *canonicalSymbol = cs(textCursor());
|
|
|
|
|
if (canonicalSymbol)
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_modelManager->findUsages(canonicalSymbol, cs.context());
|
2009-10-09 11:33:31 +02:00
|
|
|
}
|
2009-10-05 15:17:25 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::renameUsages(const QString &replacement)
|
2010-08-05 13:59:09 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_modelManager)
|
2013-10-02 09:26:50 +02:00
|
|
|
return;
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
SemanticInfo info = d->m_lastSemanticInfo;
|
2014-09-15 00:12:27 +02:00
|
|
|
info.snapshot = CppModelManager::instance()->snapshot();
|
2010-08-05 13:59:09 +02:00
|
|
|
info.snapshot.insert(info.doc);
|
|
|
|
|
|
2014-06-10 16:05:14 -04:00
|
|
|
if (const Macro *macro = CppTools::findCanonicalMacro(textCursor(), info.doc)) {
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_modelManager->renameMacroUsages(*macro, replacement);
|
2012-03-17 13:26:27 +01:00
|
|
|
} else {
|
2014-06-13 14:16:14 -04:00
|
|
|
CanonicalSymbol cs(info.doc, info.snapshot);
|
2012-03-17 13:26:27 +01:00
|
|
|
if (Symbol *canonicalSymbol = cs(textCursor()))
|
|
|
|
|
if (canonicalSymbol->identifier() != 0)
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_modelManager->renameUsages(canonicalSymbol, cs.context(), replacement);
|
2012-03-17 13:26:27 +01:00
|
|
|
}
|
2010-08-05 13:59:09 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::renameSymbolUnderCursor()
|
2009-07-01 17:57:00 +02:00
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
d->m_useSelectionsUpdater.abortSchedule();
|
2014-08-26 11:20:39 +02:00
|
|
|
updateSemanticInfo(d->m_cppEditorDocument->recalculateSemanticInfo(),
|
|
|
|
|
/*updateUseSelectionSynchronously=*/ true);
|
2009-09-29 16:40:32 +02:00
|
|
|
|
2014-08-26 11:20:39 +02:00
|
|
|
if (!d->m_localRenaming.start()) // Rename local symbol
|
|
|
|
|
renameUsages(); // Rename non-local symbol or macro
|
2009-07-01 18:41:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::updatePreprocessorButtonTooltip()
|
2013-10-23 14:13:06 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
QTC_ASSERT(d->m_preprocessorButton, return);
|
2014-09-03 21:53:40 +02:00
|
|
|
Command *cmd = ActionManager::command(Constants::OPEN_PREPROCESSOR_DIALOG);
|
2013-10-23 14:13:06 +02:00
|
|
|
QTC_ASSERT(cmd, return);
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_preprocessorButton->setToolTip(cmd->action()->toolTip());
|
2013-10-23 14:13:06 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_modelManager)
|
2008-12-02 12:01:29 +01:00
|
|
|
return;
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_lastSemanticInfo.doc)
|
2013-04-26 17:35:55 +02:00
|
|
|
return;
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-04-26 17:35:55 +02:00
|
|
|
// Find function declaration or definition under cursor
|
|
|
|
|
Function *functionDefinitionSymbol = 0;
|
|
|
|
|
Symbol *functionDeclarationSymbol = 0;
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
ASTPath astPathFinder(d->m_lastSemanticInfo.doc);
|
2013-04-26 17:35:55 +02:00
|
|
|
const QList<AST *> astPath = astPathFinder(textCursor());
|
|
|
|
|
|
|
|
|
|
for (int i = 0, size = astPath.size(); i < size; ++i) {
|
|
|
|
|
AST *ast = astPath.at(i);
|
|
|
|
|
if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) {
|
|
|
|
|
if ((functionDefinitionSymbol = functionDefinitionAST->symbol))
|
|
|
|
|
break; // Function definition found!
|
|
|
|
|
} else if (SimpleDeclarationAST *simpleDeclaration = ast->asSimpleDeclaration()) {
|
|
|
|
|
if (List<Symbol *> *symbols = simpleDeclaration->symbols) {
|
|
|
|
|
if (Symbol *symbol = symbols->value) {
|
|
|
|
|
if (symbol->isDeclaration() && symbol->type()->isFunctionType()) {
|
|
|
|
|
functionDeclarationSymbol = symbol;
|
|
|
|
|
break; // Function declaration found!
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2013-04-26 17:35:55 +02:00
|
|
|
// Link to function definition/declaration
|
2014-07-30 16:30:31 +02:00
|
|
|
CppEditorWidget::Link symbolLink;
|
2013-04-26 17:35:55 +02:00
|
|
|
if (functionDeclarationSymbol) {
|
|
|
|
|
symbolLink = linkToSymbol(symbolFinder()
|
2014-05-20 09:24:48 -04:00
|
|
|
->findMatchingDefinition(functionDeclarationSymbol, d->m_modelManager->snapshot()));
|
2013-04-26 17:35:55 +02:00
|
|
|
} else if (functionDefinitionSymbol) {
|
2014-05-20 09:24:48 -04:00
|
|
|
const Snapshot snapshot = d->m_modelManager->snapshot();
|
|
|
|
|
LookupContext context(d->m_lastSemanticInfo.doc, snapshot);
|
2013-04-26 17:35:55 +02:00
|
|
|
ClassOrNamespace *binding = context.lookupType(functionDefinitionSymbol);
|
|
|
|
|
const QList<LookupItem> declarations = context.lookup(functionDefinitionSymbol->name(),
|
|
|
|
|
functionDefinitionSymbol->enclosingScope());
|
|
|
|
|
|
|
|
|
|
QList<Symbol *> best;
|
|
|
|
|
foreach (const LookupItem &r, declarations) {
|
|
|
|
|
if (Symbol *decl = r.declaration()) {
|
|
|
|
|
if (Function *funTy = decl->type()->asFunctionType()) {
|
2014-05-15 12:00:13 -04:00
|
|
|
if (funTy->match(functionDefinitionSymbol)) {
|
2013-04-26 17:35:55 +02:00
|
|
|
if (decl != functionDefinitionSymbol && binding == r.binding())
|
|
|
|
|
best.prepend(decl);
|
|
|
|
|
else
|
|
|
|
|
best.append(decl);
|
2010-12-10 10:47:57 +01:00
|
|
|
}
|
|
|
|
|
}
|
2010-05-12 16:36:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
2013-02-05 14:14:33 +01:00
|
|
|
|
2013-04-26 17:35:55 +02:00
|
|
|
if (best.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
symbolLink = linkToSymbol(best.first());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2013-04-26 17:35:55 +02:00
|
|
|
|
|
|
|
|
// Open Editor at link position
|
|
|
|
|
if (symbolLink.hasValidTarget())
|
|
|
|
|
openCppEditorAt(symbolLink, inNextSplit != alwaysOpenLinksInNextSplit());
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
CppEditorWidget::Link CppEditorWidget::findLinkAt(const QTextCursor &cursor, bool resolveTarget,
|
2013-07-04 20:11:10 +02:00
|
|
|
bool inNextSplit)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_modelManager)
|
2013-09-20 10:32:41 +02:00
|
|
|
return Link();
|
2009-01-28 23:46:43 +01:00
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
return d->m_followSymbolUnderCursor->findLink(cursor, resolveTarget,
|
|
|
|
|
d->m_modelManager->snapshot(),
|
|
|
|
|
d->m_lastSemanticInfo.doc,
|
|
|
|
|
symbolFinder(),
|
|
|
|
|
inNextSplit);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
unsigned CppEditorWidget::documentRevision() const
|
2009-12-15 15:52:55 +01:00
|
|
|
{
|
|
|
|
|
return document()->revision();
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
bool CppEditorWidget::isSemanticInfoValidExceptLocalUses() const
|
2009-11-18 15:06:26 +01:00
|
|
|
{
|
2014-08-26 14:26:28 +02:00
|
|
|
return d->m_lastSemanticInfo.doc
|
|
|
|
|
&& d->m_lastSemanticInfo.revision == documentRevision()
|
|
|
|
|
&& !d->m_lastSemanticInfo.snapshot.isEmpty();
|
2014-08-19 15:59:29 +02:00
|
|
|
}
|
2009-11-18 15:06:26 +01:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
bool CppEditorWidget::isSemanticInfoValid() const
|
|
|
|
|
{
|
|
|
|
|
return isSemanticInfoValidExceptLocalUses() && d->m_lastSemanticInfo.localUsesUpdated;
|
2009-11-18 15:06:26 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
SemanticInfo CppEditorWidget::semanticInfo() const
|
2009-07-10 12:09:26 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
return d->m_lastSemanticInfo;
|
2009-07-10 12:09:26 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
bool CppEditorWidget::event(QEvent *e)
|
2009-07-01 17:57:00 +02:00
|
|
|
{
|
|
|
|
|
switch (e->type()) {
|
|
|
|
|
case QEvent::ShortcutOverride:
|
2011-09-05 10:33:17 +02:00
|
|
|
// handle escape manually if a rename is active
|
2014-05-20 12:24:32 -04:00
|
|
|
if (static_cast<QKeyEvent*>(e)->key() == Qt::Key_Escape && d->m_localRenaming.isActive()) {
|
2009-07-01 17:57:00 +02:00
|
|
|
e->accept();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2011-02-21 16:02:26 +01:00
|
|
|
return BaseTextEditorWidget::event(e);
|
2009-07-01 17:57:00 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::performQuickFix(int index)
|
2009-11-23 16:55:04 +01:00
|
|
|
{
|
2014-09-03 21:53:40 +02:00
|
|
|
QuickFixOperation::Ptr op = d->m_quickFixes.at(index);
|
2010-06-03 14:45:55 +02:00
|
|
|
op->perform();
|
2009-11-23 16:55:04 +01:00
|
|
|
}
|
|
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
void CppEditorWidget::processKeyNormally(QKeyEvent *e)
|
|
|
|
|
{
|
|
|
|
|
BaseTextEditorWidget::keyPressEvent(e);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::contextMenuEvent(QContextMenuEvent *e)
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2009-07-09 12:14:00 +02:00
|
|
|
// ### enable
|
|
|
|
|
// updateSemanticInfo(m_semanticHighlighter->semanticInfo(currentSource()));
|
|
|
|
|
|
2013-02-18 15:12:09 +01:00
|
|
|
QPointer<QMenu> menu(new QMenu(this));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
ActionContainer *mcontext = ActionManager::actionContainer(Constants::M_CONTEXT);
|
2008-12-02 12:01:29 +01:00
|
|
|
QMenu *contextMenu = mcontext->menu();
|
|
|
|
|
|
2010-12-10 15:51:25 +01:00
|
|
|
QMenu *quickFixMenu = new QMenu(tr("&Refactor"), menu);
|
2014-09-03 21:53:40 +02:00
|
|
|
quickFixMenu->addAction(ActionManager::command(Constants::RENAME_SYMBOL_UNDER_CURSOR)->action());
|
2009-11-23 16:55:04 +01:00
|
|
|
|
|
|
|
|
QSignalMapper mapper;
|
|
|
|
|
connect(&mapper, SIGNAL(mapped(int)), this, SLOT(performQuickFix(int)));
|
2014-08-19 15:59:29 +02:00
|
|
|
if (isSemanticInfoValid()) {
|
2014-09-04 00:04:18 +02:00
|
|
|
AssistInterface *interface = createAssistInterface(QuickFix, ExplicitlyInvoked);
|
2011-04-15 16:19:23 +02:00
|
|
|
if (interface) {
|
2014-09-03 21:53:40 +02:00
|
|
|
QScopedPointer<IAssistProcessor> processor(
|
2013-03-19 13:44:02 +01:00
|
|
|
CppEditorPlugin::instance()->quickFixProvider()->createProcessor());
|
2014-09-03 21:53:40 +02:00
|
|
|
QScopedPointer<IAssistProposal> proposal(processor->perform(interface));
|
2011-04-15 16:19:23 +02:00
|
|
|
if (!proposal.isNull()) {
|
2014-09-04 00:04:18 +02:00
|
|
|
auto model = static_cast<GenericProposalModel *>(proposal->model());
|
2011-04-15 16:19:23 +02:00
|
|
|
for (int index = 0; index < model->size(); ++index) {
|
2014-09-04 00:04:18 +02:00
|
|
|
auto item = static_cast<AssistProposalItem *>(model->proposalItem(index));
|
2014-09-03 21:53:40 +02:00
|
|
|
QuickFixOperation::Ptr op = item->data().value<QuickFixOperation::Ptr>();
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_quickFixes.append(op);
|
2011-04-15 16:19:23 +02:00
|
|
|
QAction *action = quickFixMenu->addAction(op->description());
|
|
|
|
|
mapper.setMapping(action, index);
|
|
|
|
|
connect(action, SIGNAL(triggered()), &mapper, SLOT(map()));
|
|
|
|
|
}
|
|
|
|
|
delete model;
|
2009-11-23 16:55:04 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-09-15 14:33:44 +02:00
|
|
|
foreach (QAction *action, contextMenu->actions()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
menu->addAction(action);
|
2012-01-11 14:26:09 +01:00
|
|
|
if (action->objectName() == QLatin1String(Constants::M_REFACTORING_MENU_INSERTION_POINT))
|
2010-09-15 14:33:44 +02:00
|
|
|
menu->addMenu(quickFixMenu);
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
|
2009-11-02 14:02:18 +01:00
|
|
|
appendStandardContextMenuActions(menu);
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
menu->exec(e->globalPos());
|
2013-02-18 15:12:09 +01:00
|
|
|
if (!menu)
|
|
|
|
|
return;
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_quickFixes.clear();
|
2008-12-02 12:01:29 +01:00
|
|
|
delete menu;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::keyPressEvent(QKeyEvent *e)
|
2009-07-01 17:57:00 +02:00
|
|
|
{
|
2014-05-20 12:24:32 -04:00
|
|
|
if (d->m_localRenaming.handleKeyPressEvent(e))
|
2009-07-01 18:41:04 +02:00
|
|
|
return;
|
|
|
|
|
|
2014-05-26 12:24:23 -04:00
|
|
|
if (d->m_cppDocumentationCommentHelper.handleKeyPressEvent(e))
|
|
|
|
|
return;
|
|
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
BaseTextEditorWidget::keyPressEvent(e);
|
2009-07-01 17:57:00 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::applyFontSettings()
|
2008-12-02 12:01:29 +01:00
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
// This also makes the document apply font settings
|
2014-09-03 21:53:40 +02:00
|
|
|
BaseTextEditorWidget::applyFontSettings();
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::slotCodeStyleSettingsChanged(const QVariant &)
|
2011-02-03 15:48:14 +01:00
|
|
|
{
|
|
|
|
|
CppTools::QtStyleCodeFormatter formatter;
|
|
|
|
|
formatter.invalidateCache(document());
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
CppEditorWidget::Link CppEditorWidget::linkToSymbol(CPlusPlus::Symbol *symbol)
|
2008-12-11 10:28:39 +01:00
|
|
|
{
|
2010-08-13 16:38:45 +02:00
|
|
|
if (!symbol)
|
|
|
|
|
return Link();
|
|
|
|
|
|
2013-02-06 14:23:18 +01:00
|
|
|
const QString filename = QString::fromUtf8(symbol->fileName(),
|
2009-03-23 17:20:19 +01:00
|
|
|
symbol->fileNameLength());
|
2013-02-06 14:23:18 +01:00
|
|
|
|
2009-03-23 17:20:19 +01:00
|
|
|
unsigned line = symbol->line();
|
|
|
|
|
unsigned column = symbol->column();
|
2009-03-04 15:47:26 +01:00
|
|
|
|
2009-03-03 13:46:37 +01:00
|
|
|
if (column)
|
|
|
|
|
--column;
|
2009-03-04 15:47:26 +01:00
|
|
|
|
2009-03-23 17:20:19 +01:00
|
|
|
if (symbol->isGenerated())
|
2009-03-05 16:29:18 +01:00
|
|
|
column = 0;
|
2009-03-03 13:46:37 +01:00
|
|
|
|
2013-02-06 14:23:18 +01:00
|
|
|
return Link(filename, line, column);
|
2009-03-23 17:20:19 +01:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
bool CppEditorWidget::openCppEditorAt(const Link &link, bool inNextSplit)
|
2009-03-23 17:20:19 +01:00
|
|
|
{
|
2013-02-05 14:14:33 +01:00
|
|
|
if (!link.hasValidTarget())
|
2009-03-23 17:20:19 +01:00
|
|
|
return false;
|
|
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
EditorManager::OpenEditorFlags flags;
|
2013-05-31 15:16:06 +02:00
|
|
|
if (inNextSplit)
|
2014-09-03 21:53:40 +02:00
|
|
|
flags |= EditorManager::OpenInOtherSplit;
|
|
|
|
|
return EditorManager::openEditorAt(link.targetFileName,
|
|
|
|
|
link.targetLine,
|
|
|
|
|
link.targetColumn,
|
|
|
|
|
Constants::CPPEDITOR_ID,
|
|
|
|
|
flags);
|
2008-12-02 12:01:29 +01:00
|
|
|
}
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-08-26 11:20:39 +02:00
|
|
|
void CppEditorWidget::updateSemanticInfo(const SemanticInfo &semanticInfo,
|
|
|
|
|
bool updateUseSelectionSynchronously)
|
2009-07-09 12:14:00 +02:00
|
|
|
{
|
2014-08-19 15:59:29 +02:00
|
|
|
if (semanticInfo.revision != documentRevision())
|
2009-07-10 12:09:26 +02:00
|
|
|
return;
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-08-19 15:59:29 +02:00
|
|
|
d->m_lastSemanticInfo = semanticInfo;
|
2009-07-09 12:14:00 +02:00
|
|
|
|
2014-08-26 11:20:39 +02:00
|
|
|
if (!d->m_localRenaming.isActive()) {
|
|
|
|
|
const CppUseSelectionsUpdater::CallType type = updateUseSelectionSynchronously
|
|
|
|
|
? CppUseSelectionsUpdater::Synchronous
|
|
|
|
|
: CppUseSelectionsUpdater::Asynchronous;
|
|
|
|
|
d->m_useSelectionsUpdater.update(type);
|
|
|
|
|
}
|
2011-08-10 09:50:04 +02:00
|
|
|
|
|
|
|
|
// schedule a check for a decl/def link
|
|
|
|
|
updateFunctionDeclDefLink();
|
2009-07-09 12:14:00 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-04 00:04:18 +02:00
|
|
|
AssistInterface *CppEditorWidget::createAssistInterface(AssistKind kind, AssistReason reason) const
|
2011-04-15 16:19:23 +02:00
|
|
|
{
|
2014-09-03 21:53:40 +02:00
|
|
|
if (kind == Completion) {
|
2014-08-19 15:59:29 +02:00
|
|
|
if (CppCompletionAssistProvider *cap = cppEditorDocument()->completionAssistProvider()) {
|
2013-08-30 13:13:44 +02:00
|
|
|
return cap->createAssistInterface(
|
2014-08-19 15:59:29 +02:00
|
|
|
textDocument()->filePath(),
|
|
|
|
|
document(),
|
|
|
|
|
cppEditorDocument()->isObjCEnabled(),
|
|
|
|
|
position(),
|
2014-05-14 11:34:45 -04:00
|
|
|
reason);
|
2013-08-19 16:05:29 +02:00
|
|
|
}
|
2014-09-03 21:53:40 +02:00
|
|
|
} else if (kind == QuickFix) {
|
|
|
|
|
if (isSemanticInfoValid())
|
|
|
|
|
return new CppQuickFixAssistInterface(const_cast<CppEditorWidget *>(this), reason);
|
2013-07-04 20:11:10 +02:00
|
|
|
} else {
|
|
|
|
|
return BaseTextEditorWidget::createAssistInterface(kind, reason);
|
2011-04-15 16:19:23 +02:00
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
QSharedPointer<FunctionDeclDefLink> CppEditorWidget::declDefLink() const
|
2011-09-05 10:33:17 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
return d->m_declDefLink;
|
2011-09-05 10:33:17 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
void CppEditorWidget::onRefactorMarkerClicked(const RefactorMarker &marker)
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
|
|
|
|
if (marker.data.canConvert<FunctionDeclDefLink::Marker>())
|
|
|
|
|
applyDeclDefLinkChanges(true);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::updateFunctionDeclDefLink()
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
|
|
|
|
const int pos = textCursor().selectionStart();
|
|
|
|
|
|
2011-08-25 13:22:21 +02:00
|
|
|
// if there's already a link, abort it if the cursor is outside or the name changed
|
2012-11-23 13:25:45 +01:00
|
|
|
// (adding a prefix is an exception since the user might type a return type)
|
2014-05-20 09:24:48 -04:00
|
|
|
if (d->m_declDefLink
|
|
|
|
|
&& (pos < d->m_declDefLink->linkSelection.selectionStart()
|
|
|
|
|
|| pos > d->m_declDefLink->linkSelection.selectionEnd()
|
|
|
|
|
|| !d->m_declDefLink->nameSelection.selectedText().trimmed()
|
|
|
|
|
.endsWith(d->m_declDefLink->nameInitial))) {
|
2011-08-10 09:50:04 +02:00
|
|
|
abortDeclDefLink();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// don't start a new scan if there's one active and the cursor is already in the scanned area
|
2014-05-20 09:24:48 -04:00
|
|
|
const QTextCursor scannedSelection = d->m_declDefLinkFinder->scannedSelection();
|
2011-08-10 09:50:04 +02:00
|
|
|
if (!scannedSelection.isNull()
|
|
|
|
|
&& scannedSelection.selectionStart() <= pos
|
|
|
|
|
&& scannedSelection.selectionEnd() >= pos) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-21 17:47:22 +02:00
|
|
|
d->m_updateFunctionDeclDefLinkTimer.start();
|
2011-08-10 09:50:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::updateFunctionDeclDefLinkNow()
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
2014-08-27 12:00:15 +02:00
|
|
|
static bool noTracking = qgetenv("QTC_NO_FUNCTION_DECL_DEF_LINK_TRACKING").trimmed() == "1";
|
|
|
|
|
if (noTracking)
|
|
|
|
|
return;
|
|
|
|
|
|
2014-09-08 13:40:44 +02:00
|
|
|
IEditor *editor = EditorManager::currentEditor();
|
|
|
|
|
if (!editor || editor->widget() != this)
|
2011-08-10 09:50:04 +02:00
|
|
|
return;
|
2014-08-19 15:59:29 +02:00
|
|
|
|
2014-08-18 12:25:11 +02:00
|
|
|
const Snapshot semanticSnapshot = d->m_lastSemanticInfo.snapshot;
|
|
|
|
|
const Document::Ptr semanticDoc = d->m_lastSemanticInfo.doc;
|
2014-08-19 15:59:29 +02:00
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
if (d->m_declDefLink) {
|
2011-08-10 09:50:04 +02:00
|
|
|
// update the change marker
|
2014-08-18 12:25:11 +02:00
|
|
|
const Utils::ChangeSet changes = d->m_declDefLink->changes(semanticSnapshot);
|
2011-08-10 09:50:04 +02:00
|
|
|
if (changes.isEmpty())
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_declDefLink->hideMarker(this);
|
2011-08-10 09:50:04 +02:00
|
|
|
else
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_declDefLink->showMarker(this);
|
2011-08-10 09:50:04 +02:00
|
|
|
return;
|
|
|
|
|
}
|
2014-08-19 15:59:29 +02:00
|
|
|
|
|
|
|
|
if (!isSemanticInfoValidExceptLocalUses())
|
2011-08-10 09:50:04 +02:00
|
|
|
return;
|
|
|
|
|
|
2014-09-15 00:12:27 +02:00
|
|
|
Snapshot snapshot = CppModelManager::instance()->snapshot();
|
2014-08-18 12:25:11 +02:00
|
|
|
snapshot.insert(semanticDoc);
|
2011-08-10 09:50:04 +02:00
|
|
|
|
2014-08-18 12:25:11 +02:00
|
|
|
d->m_declDefLinkFinder->startFindLinkAt(textCursor(), semanticDoc, snapshot);
|
2011-08-10 09:50:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::onFunctionDeclDefLinkFound(QSharedPointer<FunctionDeclDefLink> link)
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
|
|
|
|
abortDeclDefLink();
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_declDefLink = link;
|
2014-09-03 21:53:40 +02:00
|
|
|
IDocument *targetDocument = DocumentModel::documentForFilePath( d->m_declDefLink->targetFile->fileName());
|
2014-08-01 23:31:56 +02:00
|
|
|
if (textDocument() != targetDocument) {
|
2014-09-26 09:14:03 +02:00
|
|
|
if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
|
2014-07-25 14:54:10 +02:00
|
|
|
connect(textDocument, SIGNAL(contentsChanged()),
|
2013-07-18 09:40:50 +02:00
|
|
|
this, SLOT(abortDeclDefLink()));
|
2011-08-17 12:21:04 +02:00
|
|
|
}
|
2013-07-18 09:40:50 +02:00
|
|
|
|
2011-08-10 09:50:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::applyDeclDefLinkChanges(bool jumpToMatch)
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_declDefLink)
|
2011-08-10 09:50:04 +02:00
|
|
|
return;
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_declDefLink->apply(this, jumpToMatch);
|
2011-08-30 10:05:09 +02:00
|
|
|
abortDeclDefLink();
|
2011-08-10 09:50:04 +02:00
|
|
|
updateFunctionDeclDefLink();
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
FollowSymbolUnderCursor *CppEditorWidget::followSymbolUnderCursorDelegate()
|
2013-07-04 20:11:10 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
return d->m_followSymbolUnderCursor.data();
|
2013-07-04 20:11:10 +02:00
|
|
|
}
|
|
|
|
|
|
2014-09-03 10:57:51 +02:00
|
|
|
CompletionAssistProvider *CppEditorWidget::completionAssistProvider() const
|
|
|
|
|
{
|
|
|
|
|
auto document = qobject_cast<CppEditorDocument *>(textDocument());
|
|
|
|
|
QTC_ASSERT(document, return 0);
|
|
|
|
|
return document->completionAssistProvider();
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::abortDeclDefLink()
|
2011-08-10 09:50:04 +02:00
|
|
|
{
|
2014-05-20 09:24:48 -04:00
|
|
|
if (!d->m_declDefLink)
|
2011-08-10 09:50:04 +02:00
|
|
|
return;
|
2011-08-17 12:21:04 +02:00
|
|
|
|
2014-09-03 21:53:40 +02:00
|
|
|
IDocument *targetDocument = DocumentModel::documentForFilePath(d->m_declDefLink->targetFile->fileName());
|
2014-08-01 23:31:56 +02:00
|
|
|
if (textDocument() != targetDocument) {
|
2014-09-26 09:14:03 +02:00
|
|
|
if (auto textDocument = qobject_cast<BaseTextDocument *>(targetDocument))
|
2014-07-25 14:54:10 +02:00
|
|
|
disconnect(textDocument, SIGNAL(contentsChanged()),
|
2013-07-18 09:40:50 +02:00
|
|
|
this, SLOT(abortDeclDefLink()));
|
2011-08-17 12:21:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
d->m_declDefLink->hideMarker(this);
|
|
|
|
|
d->m_declDefLink.clear();
|
2011-08-10 09:50:04 +02:00
|
|
|
}
|
|
|
|
|
|
2014-07-30 16:30:31 +02:00
|
|
|
void CppEditorWidget::showPreProcessorWidget()
|
2013-08-20 07:46:19 +02:00
|
|
|
{
|
2014-09-01 18:07:31 +02:00
|
|
|
const QString &fileName = textDocument()->filePath();
|
2013-08-20 07:46:19 +02:00
|
|
|
|
2013-10-17 11:19:26 +02:00
|
|
|
// Check if this editor belongs to a project
|
2014-05-20 09:24:48 -04:00
|
|
|
QList<ProjectPart::Ptr> projectParts = d->m_modelManager->projectPart(fileName);
|
2013-08-20 07:46:19 +02:00
|
|
|
if (projectParts.isEmpty())
|
2014-05-20 09:24:48 -04:00
|
|
|
projectParts = d->m_modelManager->projectPartFromDependencies(fileName);
|
2013-08-20 07:46:19 +02:00
|
|
|
if (projectParts.isEmpty())
|
2014-05-20 09:24:48 -04:00
|
|
|
projectParts << d->m_modelManager->fallbackProjectPart();
|
2013-08-20 07:46:19 +02:00
|
|
|
|
2014-08-01 23:31:56 +02:00
|
|
|
CppPreProcessorDialog preProcessorDialog(this, textDocument()->filePath(), projectParts);
|
2013-10-17 11:19:26 +02:00
|
|
|
if (preProcessorDialog.exec() == QDialog::Accepted) {
|
2014-09-09 16:02:31 +02:00
|
|
|
cppEditorDocument()->setPreprocessorSettings(
|
|
|
|
|
preProcessorDialog.projectPart(),
|
|
|
|
|
preProcessorDialog.additionalPreProcessorDirectives().toUtf8());
|
|
|
|
|
cppEditorDocument()->scheduleProcessDocument();
|
2013-10-17 11:19:26 +02:00
|
|
|
}
|
2013-08-20 07:46:19 +02:00
|
|
|
}
|
|
|
|
|
|
2014-05-20 09:24:48 -04:00
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace CppEditor
|