forked from qt-creator/qt-creator
LanguageClient: add artificial <Select Symbol> item to outline
Use this item when the text cursor is currently outside of any symbol that is shown in the outline. Fixes: QTCREATORBUG-32088 Change-Id: Ie4d1478f764af03f5a02631c05f303ecf3335254 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
@@ -137,6 +137,7 @@ class ClangdOutlineItem : public LanguageClientOutlineItem
|
|||||||
private:
|
private:
|
||||||
QVariant data(int column, int role) const override
|
QVariant data(int column, int role) const override
|
||||||
{
|
{
|
||||||
|
if (valid()) {
|
||||||
switch (role) {
|
switch (role) {
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return ClangdClient::displayNameFromDocumentSymbol(
|
return ClangdClient::displayNameFromDocumentSymbol(
|
||||||
@@ -148,6 +149,7 @@ private:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return LanguageClientOutlineItem::data(column, role);
|
return LanguageClientOutlineItem::data(column, role);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -54,15 +54,19 @@ public:
|
|||||||
LanguageClientOutlineModel(Client *client) : m_client(client) {}
|
LanguageClientOutlineModel(Client *client) : m_client(client) {}
|
||||||
void setFilePath(const Utils::FilePath &filePath) { m_filePath = filePath; }
|
void setFilePath(const Utils::FilePath &filePath) { m_filePath = filePath; }
|
||||||
|
|
||||||
void setInfo(const QList<SymbolInformation> &info)
|
void setInfo(const QList<SymbolInformation> &info, bool createOutOfScopeItem)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
if (createOutOfScopeItem)
|
||||||
|
rootItem()->appendChild(new LanguageClientOutlineItem());
|
||||||
for (const SymbolInformation &symbol : sortedSymbols(info))
|
for (const SymbolInformation &symbol : sortedSymbols(info))
|
||||||
rootItem()->appendChild(new LanguageClientOutlineItem(symbol));
|
rootItem()->appendChild(new LanguageClientOutlineItem(symbol));
|
||||||
}
|
}
|
||||||
void setInfo(const QList<DocumentSymbol> &info)
|
void setInfo(const QList<DocumentSymbol> &info, bool createOutOfScopeItem)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
|
if (createOutOfScopeItem)
|
||||||
|
rootItem()->appendChild(new LanguageClientOutlineItem());
|
||||||
for (const DocumentSymbol &symbol : sortedSymbols(info))
|
for (const DocumentSymbol &symbol : sortedSymbols(info))
|
||||||
rootItem()->appendChild(m_client->createOutlineItem(symbol));
|
rootItem()->appendChild(m_client->createOutlineItem(symbol));
|
||||||
}
|
}
|
||||||
@@ -81,7 +85,7 @@ public:
|
|||||||
{
|
{
|
||||||
auto mimeData = new Utils::DropMimeData;
|
auto mimeData = new Utils::DropMimeData;
|
||||||
for (const QModelIndex &index : indexes) {
|
for (const QModelIndex &index : indexes) {
|
||||||
if (LanguageClientOutlineItem *item = itemForIndex(index)) {
|
if (LanguageClientOutlineItem *item = itemForIndex(index); item->valid()) {
|
||||||
const LanguageServerProtocol::Position pos = item->pos();
|
const LanguageServerProtocol::Position pos = item->pos();
|
||||||
mimeData->addFile(m_filePath, pos.line() + 1, pos.character());
|
mimeData->addFile(m_filePath, pos.line() + 1, pos.character());
|
||||||
}
|
}
|
||||||
@@ -229,9 +233,9 @@ void LanguageClientOutlineWidget::handleResponse(const DocumentUri &uri,
|
|||||||
if (uri != m_uri)
|
if (uri != m_uri)
|
||||||
return;
|
return;
|
||||||
if (const auto i = std::get_if<QList<SymbolInformation>>(&result))
|
if (const auto i = std::get_if<QList<SymbolInformation>>(&result))
|
||||||
m_model.setInfo(*i);
|
m_model.setInfo(*i, false);
|
||||||
else if (const auto s = std::get_if<QList<DocumentSymbol>>(&result))
|
else if (const auto s = std::get_if<QList<DocumentSymbol>>(&result))
|
||||||
m_model.setInfo(*s);
|
m_model.setInfo(*s, false);
|
||||||
else
|
else
|
||||||
m_model.clear();
|
m_model.clear();
|
||||||
|
|
||||||
@@ -242,6 +246,8 @@ void LanguageClientOutlineWidget::handleResponse(const DocumentUri &uri,
|
|||||||
void LanguageClientOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)
|
void LanguageClientOutlineWidget::updateTextCursor(const QModelIndex &proxyIndex)
|
||||||
{
|
{
|
||||||
LanguageClientOutlineItem *item = m_model.itemForIndex(m_proxyModel.mapToSource(proxyIndex));
|
LanguageClientOutlineItem *item = m_model.itemForIndex(m_proxyModel.mapToSource(proxyIndex));
|
||||||
|
if (!item->valid())
|
||||||
|
return;
|
||||||
const Position &pos = item->pos();
|
const Position &pos = item->pos();
|
||||||
// line has to be 1 based, column 0 based!
|
// line has to be 1 based, column 0 based!
|
||||||
m_editor->editorWidget()->gotoLine(pos.line() + 1, pos.character(), true, true);
|
m_editor->editorWidget()->gotoLine(pos.line() + 1, pos.character(), true, true);
|
||||||
@@ -253,7 +259,7 @@ static LanguageClientOutlineItem *itemForCursor(const LanguageClientOutlineModel
|
|||||||
const Position pos(cursor);
|
const Position pos(cursor);
|
||||||
LanguageClientOutlineItem *result = nullptr;
|
LanguageClientOutlineItem *result = nullptr;
|
||||||
m_model.forAllItems([&](LanguageClientOutlineItem *candidate){
|
m_model.forAllItems([&](LanguageClientOutlineItem *candidate){
|
||||||
if (!candidate->contains(pos))
|
if (!candidate->valid() || !candidate->contains(pos))
|
||||||
return;
|
return;
|
||||||
if (result && candidate->range().contains(result->range()))
|
if (result && candidate->range().contains(result->range()))
|
||||||
return; // skip item if the range is equal or bigger than the previous found range
|
return; // skip item if the range is equal or bigger than the previous found range
|
||||||
@@ -349,9 +355,9 @@ void OutlineComboBox::updateModel(const DocumentUri &resultUri, const DocumentSy
|
|||||||
if (m_uri != resultUri)
|
if (m_uri != resultUri)
|
||||||
return;
|
return;
|
||||||
if (const auto i = std::get_if<QList<SymbolInformation>>(&result))
|
if (const auto i = std::get_if<QList<SymbolInformation>>(&result))
|
||||||
m_model.setInfo(*i);
|
m_model.setInfo(*i, true);
|
||||||
else if (const auto s = std::get_if<QList<DocumentSymbol>>(&result))
|
else if (const auto s = std::get_if<QList<DocumentSymbol>>(&result))
|
||||||
m_model.setInfo(*s);
|
m_model.setInfo(*s, true);
|
||||||
else
|
else
|
||||||
m_model.clear();
|
m_model.clear();
|
||||||
|
|
||||||
@@ -364,20 +370,26 @@ void OutlineComboBox::updateEntry()
|
|||||||
{
|
{
|
||||||
if (LanguageClientOutlineItem *item = itemForCursor(m_model, m_editorWidget->textCursor()))
|
if (LanguageClientOutlineItem *item = itemForCursor(m_model, m_editorWidget->textCursor()))
|
||||||
setCurrentIndex(m_proxyModel.mapFromSource(m_model.indexForItem(item)));
|
setCurrentIndex(m_proxyModel.mapFromSource(m_model.indexForItem(item)));
|
||||||
|
else
|
||||||
|
setCurrentIndex(m_proxyModel.mapFromSource(m_model.index(0,0)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutlineComboBox::activateEntry()
|
void OutlineComboBox::activateEntry()
|
||||||
{
|
{
|
||||||
const QModelIndex modelIndex = m_proxyModel.mapToSource(view()->currentIndex());
|
const QModelIndex modelIndex = m_proxyModel.mapToSource(view()->currentIndex());
|
||||||
if (modelIndex.isValid()) {
|
if (!modelIndex.isValid())
|
||||||
const Position &pos = m_model.itemForIndex(modelIndex)->pos();
|
return;
|
||||||
|
LanguageClientOutlineItem *item = m_model.itemForIndex(modelIndex);
|
||||||
|
if (!item->valid())
|
||||||
|
return;
|
||||||
|
const Position &pos = item->pos();
|
||||||
Core::EditorManager::cutForwardNavigationHistory();
|
Core::EditorManager::cutForwardNavigationHistory();
|
||||||
Core::EditorManager::addCurrentPositionToNavigationHistory();
|
Core::EditorManager::addCurrentPositionToNavigationHistory();
|
||||||
// line has to be 1 based, column 0 based!
|
// line has to be 1 based, column 0 based!
|
||||||
m_editorWidget->gotoLine(pos.line() + 1, pos.character(), true, true);
|
m_editorWidget->gotoLine(pos.line() + 1, pos.character(), true, true);
|
||||||
emit m_editorWidget->activateEditor();
|
emit m_editorWidget->activateEditor();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void OutlineComboBox::documentUpdated(TextEditor::TextDocument *document)
|
void OutlineComboBox::documentUpdated(TextEditor::TextDocument *document)
|
||||||
{
|
{
|
||||||
@@ -417,7 +429,7 @@ QVariant LanguageClientOutlineItem::data(int column, int role) const
|
|||||||
case Qt::DecorationRole:
|
case Qt::DecorationRole:
|
||||||
return symbolIcon(m_type);
|
return symbolIcon(m_type);
|
||||||
case Qt::DisplayRole:
|
case Qt::DisplayRole:
|
||||||
return m_name;
|
return valid() ? m_name : Tr::tr("<Select Symbol>");
|
||||||
default:
|
default:
|
||||||
return Utils::TreeItem::data(column, role);
|
return Utils::TreeItem::data(column, role);
|
||||||
}
|
}
|
||||||
|
@@ -29,6 +29,8 @@ public:
|
|||||||
return m_range.contains(pos);
|
return m_range.contains(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool valid() const { return m_client; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// TreeItem interface
|
// TreeItem interface
|
||||||
QVariant data(int column, int role) const override;
|
QVariant data(int column, int role) const override;
|
||||||
|
Reference in New Issue
Block a user