LanguageClient: show icon with assigned server names in toolbar

Change-Id: I44ceeb184812a4c48f042a19197c7f0ffd4299f8
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2019-03-26 13:48:06 +01:00
parent 0c6f234d43
commit dac8262aeb
11 changed files with 156 additions and 11 deletions

View File

@@ -103,6 +103,16 @@ Client::Client(BaseClientInterface *clientInterface)
connect(clientInterface, &BaseClientInterface::finished, this, &Client::finished); connect(clientInterface, &BaseClientInterface::finished, this, &Client::finished);
} }
static void updateEditorToolBar(QList<Utils::FileName> files)
{
QList<Core::IEditor *> editors = Core::DocumentModel::editorsForDocuments(
Utils::transform(files, [](Utils::FileName &file) {
return Core::DocumentModel::documentForFilePath(file.toString());
}));
for (auto editor : editors)
updateEditorToolBar(editor);
}
Client::~Client() Client::~Client()
{ {
using namespace TextEditor; using namespace TextEditor;
@@ -120,6 +130,7 @@ Client::~Client()
} }
for (const DocumentUri &uri : m_diagnostics.keys()) for (const DocumentUri &uri : m_diagnostics.keys())
removeDiagnostics(uri); removeDiagnostics(uri);
updateEditorToolBar(m_openedDocument);
} }
static ClientCapabilities generateClientCapabilities() static ClientCapabilities generateClientCapabilities()
@@ -239,27 +250,27 @@ Client::State Client::state() const
return m_state; return m_state;
} }
void Client::openDocument(Core::IDocument *document) bool Client::openDocument(Core::IDocument *document)
{ {
using namespace TextEditor; using namespace TextEditor;
if (!isSupportedDocument(document)) if (!isSupportedDocument(document))
return; return false;
const FileName &filePath = document->filePath(); const FileName &filePath = document->filePath();
const QString method(DidOpenTextDocumentNotification::methodName); const QString method(DidOpenTextDocumentNotification::methodName);
if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) { if (Utils::optional<bool> registered = m_dynamicCapabilities.isRegistered(method)) {
if (!registered.value()) if (!registered.value())
return; return false;
const TextDocumentRegistrationOptions option( const TextDocumentRegistrationOptions option(
m_dynamicCapabilities.option(method).toObject()); m_dynamicCapabilities.option(method).toObject());
if (option.isValid(nullptr) if (option.isValid(nullptr)
&& !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) { && !option.filterApplies(filePath, Utils::mimeTypeForName(document->mimeType()))) {
return; return false;
} }
} else if (Utils::optional<ServerCapabilities::TextDocumentSync> _sync } else if (Utils::optional<ServerCapabilities::TextDocumentSync> _sync
= m_serverCapabilities.textDocumentSync()) { = m_serverCapabilities.textDocumentSync()) {
if (auto options = Utils::get_if<TextDocumentSyncOptions>(&_sync.value())) { if (auto options = Utils::get_if<TextDocumentSyncOptions>(&_sync.value())) {
if (!options->openClose().value_or(true)) if (!options->openClose().value_or(true))
return; return false;
} }
} }
auto uri = DocumentUri::fromFileName(filePath); auto uri = DocumentUri::fromFileName(filePath);
@@ -289,6 +300,8 @@ void Client::openDocument(Core::IDocument *document)
sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item))); sendContent(DidOpenTextDocumentNotification(DidOpenTextDocumentParams(item)));
if (textDocument) if (textDocument)
requestDocumentSymbols(textDocument); requestDocumentSymbols(textDocument);
return true;
} }
void Client::sendContent(const IContent &content) void Client::sendContent(const IContent &content)
@@ -320,6 +333,11 @@ void Client::closeDocument(const DidCloseTextDocumentParams &params)
sendContent(params.textDocument().uri(), DidCloseTextDocumentNotification(params)); sendContent(params.textDocument().uri(), DidCloseTextDocumentNotification(params));
} }
bool Client::documentOpen(const Core::IDocument *document) const
{
return m_openedDocument.contains(document->filePath());
}
void Client::documentContentsSaved(Core::IDocument *document) void Client::documentContentsSaved(Core::IDocument *document)
{ {
if (!m_openedDocument.contains(document->filePath())) if (!m_openedDocument.contains(document->filePath()))
@@ -783,6 +801,7 @@ bool Client::reset()
m_state = Uninitialized; m_state = Uninitialized;
m_responseHandlers.clear(); m_responseHandlers.clear();
m_clientInterface->resetBuffer(); m_clientInterface->resetBuffer();
updateEditorToolBar(m_openedDocument);
m_openedDocument.clear(); m_openedDocument.clear();
m_serverCapabilities = ServerCapabilities(); m_serverCapabilities = ServerCapabilities();
m_dynamicCapabilities.reset(); m_dynamicCapabilities.reset();
@@ -1028,8 +1047,12 @@ void Client::intializeCallback(const InitializeRequest::Response &initResponse)
m_state = Initialized; m_state = Initialized;
sendContent(InitializeNotification()); sendContent(InitializeNotification());
emit initialized(m_serverCapabilities); emit initialized(m_serverCapabilities);
for (auto openedDocument : Core::DocumentModel::openedDocuments()) for (auto openedDocument : Core::DocumentModel::openedDocuments()) {
openDocument(openedDocument); if (openDocument(openedDocument)) {
for (Core::IEditor *editor : Core::DocumentModel::editorsForDocument(openedDocument))
updateEditorToolBar(editor);
}
}
} }
void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse) void Client::shutDownCallback(const ShutdownRequest::Response &shutdownResponse)

View File

@@ -90,9 +90,9 @@ public:
bool reachable() const { return m_state == Initialized; } bool reachable() const { return m_state == Initialized; }
// document synchronization // document synchronization
void openDocument(Core::IDocument *document); bool openDocument(Core::IDocument *document);
void closeDocument(const LanguageServerProtocol::DidCloseTextDocumentParams &params); void closeDocument(const LanguageServerProtocol::DidCloseTextDocumentParams &params);
bool documentOpen(const LanguageServerProtocol::DocumentUri &uri) const; bool documentOpen(const Core::IDocument *document) const;
void documentContentsSaved(Core::IDocument *document); void documentContentsSaved(Core::IDocument *document);
void documentWillSave(Core::IDocument *document); void documentWillSave(Core::IDocument *document);
void documentContentsChanged(Core::IDocument *document); void documentContentsChanged(Core::IDocument *document);

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 360 B

View File

@@ -1,5 +1,7 @@
<RCC> <RCC>
<qresource prefix="/languageclient"> <qresource prefix="/languageclient">
<file>images/languageclient.png</file>
<file>images/languageclient@2x.png</file>
<file>images/settingscategory_languageclient.png</file> <file>images/settingscategory_languageclient.png</file>
<file>images/settingscategory_languageclient@2x.png</file> <file>images/settingscategory_languageclient@2x.png</file>
</qresource> </qresource>

View File

@@ -31,6 +31,7 @@ namespace LanguageClient {
namespace Constants { namespace Constants {
const char LANGUAGECLIENT_SETTINGS_CATEGORY[] = "ZY.LanguageClient"; const char LANGUAGECLIENT_SETTINGS_CATEGORY[] = "ZY.LanguageClient";
const char LANGUAGECLIENT_SETTINGS_PAGE[] = "LanguageClient.General";
const char LANGUAGECLIENT_SETTINGS_TR[] = QT_TRANSLATE_NOOP("LanguageClient", "Language Client"); const char LANGUAGECLIENT_SETTINGS_TR[] = QT_TRANSLATE_NOOP("LanguageClient", "Language Client");
} // namespace Constants } // namespace Constants

View File

@@ -228,6 +228,7 @@ void LanguageClientManager::editorOpened(Core::IEditor *editor)
} }
}); });
}); });
updateEditorToolBar(editor);
} }
} }
} }

View File

@@ -224,7 +224,7 @@ void LanguageClientSettingsPageWidget::deleteItem()
LanguageClientSettingsPage::LanguageClientSettingsPage() LanguageClientSettingsPage::LanguageClientSettingsPage()
{ {
setId("LanguageClient.General"); setId(Constants::LANGUAGECLIENT_SETTINGS_PAGE);
setDisplayName(tr("General")); setDisplayName(tr("General"));
setCategory(Constants::LANGUAGECLIENT_SETTINGS_CATEGORY); setCategory(Constants::LANGUAGECLIENT_SETTINGS_CATEGORY);
setDisplayCategory(QCoreApplication::translate("LanguageClient", setDisplayCategory(QCoreApplication::translate("LanguageClient",

View File

@@ -26,8 +26,11 @@
#include "languageclientutils.h" #include "languageclientutils.h"
#include "client.h" #include "client.h"
#include "languageclient_global.h"
#include "languageclientmanager.h"
#include <coreplugin/editormanager/documentmodel.h> #include <coreplugin/editormanager/documentmodel.h>
#include <coreplugin/icore.h>
#include <texteditor/codeassist/textdocumentmanipulatorinterface.h> #include <texteditor/codeassist/textdocumentmanipulatorinterface.h>
#include <texteditor/refactoringchanges.h> #include <texteditor/refactoringchanges.h>
@@ -37,6 +40,8 @@
#include <QFile> #include <QFile>
#include <QTextDocument> #include <QTextDocument>
#include <QToolBar>
#include <QToolButton>
using namespace LanguageServerProtocol; using namespace LanguageServerProtocol;
using namespace Utils; using namespace Utils;
@@ -185,4 +190,44 @@ void updateCodeActionRefactoringMarker(Client *client,
} }
} }
void updateEditorToolBar(Core::IEditor *editor)
{
auto *textEditor = qobject_cast<BaseTextEditor *>(editor);
if (!textEditor)
return;
TextEditorWidget *widget = textEditor->editorWidget();
if (!widget)
return;
const Core::IDocument *document = editor->document();
QStringList clientsWithDoc;
for (auto client : LanguageClientManager::clients()) {
if (client->documentOpen(document))
clientsWithDoc << client->name();
}
static QMap<QWidget *, QAction *> actions;
if (actions.contains(widget)) {
auto action = actions[widget];
if (clientsWithDoc.isEmpty()) {
widget->toolBar()->removeAction(action);
actions.remove(widget);
} else {
action->setText(clientsWithDoc.join(';'));
}
} else if (!clientsWithDoc.isEmpty()) {
const QIcon icon
= Utils::Icon({{":/languageclient/images/languageclient.png",
Utils::Theme::IconsBaseColor}})
.icon();
actions[widget] = widget->toolBar()->addAction(icon, clientsWithDoc.join(';'), []() {
Core::ICore::showOptionsDialog(Constants::LANGUAGECLIENT_SETTINGS_PAGE);
});
QObject::connect(widget, &QWidget::destroyed, [widget]() {
actions.remove(widget);
});
}
}
} // namespace LanguageClient } // namespace LanguageClient

View File

@@ -30,6 +30,8 @@
#include <texteditor/refactoroverlay.h> #include <texteditor/refactoroverlay.h>
namespace Core { class IEditor; }
namespace TextEditor { namespace TextEditor {
class TextDocument; class TextDocument;
class TextDocumentManipulatorInterface; class TextDocumentManipulatorInterface;
@@ -48,5 +50,6 @@ void applyTextEdit(TextEditor::TextDocumentManipulatorInterface &manipulator,
void updateCodeActionRefactoringMarker(Client *client, void updateCodeActionRefactoringMarker(Client *client,
const LanguageServerProtocol::CodeAction &action, const LanguageServerProtocol::CodeAction &action,
const LanguageServerProtocol::DocumentUri &uri); const LanguageServerProtocol::DocumentUri &uri);
void updateEditorToolBar(Core::IEditor *editor);
} // namespace LanguageClient } // namespace LanguageClient

View File

@@ -3537,6 +3537,76 @@
height="100%" height="100%"
inkscape:transform-center-x="-3.5355339" /> inkscape:transform-center-x="-3.5355339" />
</g> </g>
<g
style="display:inline"
transform="translate(144)"
id="src/plugins/languageclient/images/languageclient">
<use
transform="translate(1740,132)"
height="100%"
width="100%"
id="use4105-8"
xlink:href="#backgroundRect"
y="0"
x="0" />
<ellipse
style="fill:none;stroke:#000000"
id="path4643-3"
cx="1729"
cy="580.5"
rx="3.5"
ry="2" />
<use
x="0"
y="0"
xlink:href="#path4643-3"
id="use4684-9"
width="100%"
height="100%"
transform="translate(0,-5)" />
<rect
style="fill:#ffffff"
id="rect4670-9"
width="8"
height="2.5"
x="1725"
y="578" />
<path
style="fill:none;stroke:#000000"
d="m 1725.5,575.5 v 5"
id="path4672-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<use
x="0"
y="0"
xlink:href="#path4672-0"
id="use4686-9"
transform="translate(7)"
width="100%"
height="100%" />
<path
style="display:inline;fill:#000000"
d="m 1733,569 h 4 c 1,0 2,1 2,2 v 3 c 0,2.5 -1.5,2.5 -5.5,4 l 2,-2 h -2.5 c -1,0 -2,-1 -2,-2 v -3 c 0,-1 1,-2 2,-2 z"
id="path4639-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccc" />
<path
style="display:inline;fill:none;stroke:#ffffff"
d="m 1734.25,570.75 -1.75,1.75 1.75,1.75"
id="path4676-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<use
style="display:inline"
x="0"
y="0"
xlink:href="#path4676-1"
id="use4682-2"
transform="matrix(-1,0,0,1,3470,0)"
width="100%"
height="100%" />
</g>
</g> </g>
<g <g
inkscape:groupmode="layer" inkscape:groupmode="layer"

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 373 KiB