From f6da85cc4b8cc6e86e6b67b57a9aaaac1609fef4 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Wed, 12 Sep 2018 10:24:02 +0200 Subject: [PATCH] LSP: support 'window/showMessageRequest' and 'window/showMessage' All showMessage notification are send to the GeneralMessages Pane and the showMessageRequest will show a message box Change-Id: Ida3f2a43669ec4c08694ed74e086a281d3d66f9d Reviewed-by: Eike Ziller --- src/libs/languageserverprotocol/messages.h | 1 + src/plugins/languageclient/baseclient.cpp | 54 ++++++++++++++++++- src/plugins/languageclient/baseclient.h | 7 ++- .../languageclient/languageclientmanager.cpp | 2 + 4 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/libs/languageserverprotocol/messages.h b/src/libs/languageserverprotocol/messages.h index ff807a93726..3a3aaa52a5d 100644 --- a/src/libs/languageserverprotocol/messages.h +++ b/src/libs/languageserverprotocol/messages.h @@ -65,6 +65,7 @@ class LANGUAGESERVERPROTOCOL_EXPORT MessageActionItem : public JsonObject { public: using JsonObject::JsonObject; + using JsonObject::operator=; QString title() const { return typedValue(titleKey); } void setTitle(QString title) { insert(titleKey, title); } diff --git a/src/plugins/languageclient/baseclient.cpp b/src/plugins/languageclient/baseclient.cpp index dac8e88be6b..e124a4c3af8 100644 --- a/src/plugins/languageclient/baseclient.cpp +++ b/src/plugins/languageclient/baseclient.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -516,12 +517,40 @@ void BaseClient::log(const QString &message, Core::MessageManager::PrintToOutput Core::MessageManager::write(QString("LanguageClient %1: %2").arg(name(), message), flag); } -void BaseClient::log(const LogMessageParams &message, +void BaseClient::log(const ShowMessageParams &message, Core::MessageManager::PrintToOutputPaneFlag flag) { log(message.toString(), flag); } +void BaseClient::showMessageBox(const ShowMessageRequestParams &message, const MessageId &id) +{ + auto box = new QMessageBox(); + box->setText(message.toString()); + box->setAttribute(Qt::WA_DeleteOnClose); + switch (message.type()) { + case Error: box->setIcon(QMessageBox::Critical); break; + case Warning: box->setIcon(QMessageBox::Warning); break; + case Info: box->setIcon(QMessageBox::Information); break; + case Log: box->setIcon(QMessageBox::NoIcon); break; + } + QHash itemForButton; + if (const Utils::optional> actions = message.actions()) { + for (const MessageActionItem &action : actions.value()) + itemForButton.insert(box->addButton(action.title(), QMessageBox::InvalidRole), action); + } + box->setModal(true); + connect(box, &QMessageBox::finished, this, [=]{ + Response, LanguageClientNull> response; + response.setId(id); + const MessageActionItem &item = itemForButton.value(box->clickedButton()); + response.setResult(item.isValid(nullptr) ? LanguageClientValue(item) + : LanguageClientValue()); + sendContent(response); + }); + box->show(); +} + void BaseClient::handleResponse(const MessageId &id, const QByteArray &content, QTextCodec *codec) { if (auto handler = m_responseHandlers[id]) @@ -540,8 +569,31 @@ void BaseClient::handleMethod(const QString &method, MessageId id, const IConten } else if (method == LogMessageNotification::methodName) { auto params = dynamic_cast(content)->params().value_or(LogMessageParams()); paramsValid = params.isValid(&error); + if (paramsValid) + log(params, Core::MessageManager::Flash); + } else if (method == ShowMessageNotification::methodName) { + auto params = dynamic_cast(content)->params().value_or(ShowMessageParams()); + paramsValid = params.isValid(&error); if (paramsValid) log(params); + } else if (method == ShowMessageRequest::methodName) { + const ShowMessageRequest *request = dynamic_cast(content); + auto params = request->params().value_or(ShowMessageRequestParams()); + paramsValid = params.isValid(&error); + if (paramsValid) { + showMessageBox(params, request->id()); + } else { + Response, LanguageClientNull> response; + response.setId(request->id()); + ResponseError error; + const QString errorMessage = + QString("Could not parse ShowMessageRequest parameter of '%1': \"%2\"") + .arg(request->id().toString(), + QString::fromUtf8(QJsonDocument(params).toJson())); + error.setMessage(errorMessage); + response.setError(error); + sendContent(response); + } } else if (method == RegisterCapabilityRequest::methodName) { auto params = dynamic_cast(content)->params().value_or(RegistrationParams()); paramsValid = params.isValid(&error); diff --git a/src/plugins/languageclient/baseclient.h b/src/plugins/languageclient/baseclient.h index 5c4ba6ed25c..543d67cbc36 100644 --- a/src/plugins/languageclient/baseclient.h +++ b/src/plugins/languageclient/baseclient.h @@ -118,8 +118,6 @@ public: void log(const QString &message, Core::MessageManager::PrintToOutputPaneFlag flag = Core::MessageManager::NoModeSwitch); - void log(const LanguageServerProtocol::LogMessageParams &message, - Core::MessageManager::PrintToOutputPaneFlag flag = Core::MessageManager::NoModeSwitch); signals: void initialized(LanguageServerProtocol::ServerCapabilities capabilities); @@ -139,6 +137,11 @@ private: void intializeCallback(const LanguageServerProtocol::InitializeResponse &initResponse); void shutDownCallback(const LanguageServerProtocol::ShutdownResponse &shutdownResponse); bool sendWorkspceFolderChanges() const; + void log(const LanguageServerProtocol::ShowMessageParams &message, + Core::MessageManager::PrintToOutputPaneFlag flag = Core::MessageManager::NoModeSwitch); + + void showMessageBox(const LanguageServerProtocol::ShowMessageRequestParams &message, + const LanguageServerProtocol::MessageId &id); using ContentHandler = std::function(); JsonRpcMessageHandler::registerMessageProvider(); + JsonRpcMessageHandler::registerMessageProvider(); + JsonRpcMessageHandler::registerMessageProvider(); managerInstance = this; }