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 <eike.ziller@qt.io>
This commit is contained in:
David Schulz
2018-09-12 10:24:02 +02:00
parent d3c31ff945
commit f6da85cc4b
4 changed files with 61 additions and 3 deletions

View File

@@ -65,6 +65,7 @@ class LANGUAGESERVERPROTOCOL_EXPORT MessageActionItem : public JsonObject
{
public:
using JsonObject::JsonObject;
using JsonObject::operator=;
QString title() const { return typedValue<QString>(titleKey); }
void setTitle(QString title) { insert(titleKey, title); }

View File

@@ -47,6 +47,7 @@
#include <QLoggingCategory>
#include <QMessageBox>
#include <QPointer>
#include <QPushButton>
#include <QTextBlock>
#include <QTextCursor>
#include <QTextDocument>
@@ -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<QAbstractButton *, MessageActionItem> itemForButton;
if (const Utils::optional<QList<MessageActionItem>> 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<LanguageClientValue<MessageActionItem>, LanguageClientNull> response;
response.setId(id);
const MessageActionItem &item = itemForButton.value(box->clickedButton());
response.setResult(item.isValid(nullptr) ? LanguageClientValue<MessageActionItem>(item)
: LanguageClientValue<MessageActionItem>());
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<const LogMessageNotification *>(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<const ShowMessageNotification *>(content)->params().value_or(ShowMessageParams());
paramsValid = params.isValid(&error);
if (paramsValid)
log(params);
} else if (method == ShowMessageRequest::methodName) {
const ShowMessageRequest *request = dynamic_cast<const ShowMessageRequest *>(content);
auto params = request->params().value_or(ShowMessageRequestParams());
paramsValid = params.isValid(&error);
if (paramsValid) {
showMessageBox(params, request->id());
} else {
Response<LanguageClientValue<MessageActionItem>, LanguageClientNull> response;
response.setId(request->id());
ResponseError<LanguageClientNull> 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<const RegisterCapabilityRequest *>(content)->params().value_or(RegistrationParams());
paramsValid = params.isValid(&error);

View File

@@ -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<void(const QByteArray &, QTextCodec *, QString &,
LanguageServerProtocol::ResponseHandlers,

View File

@@ -75,6 +75,8 @@ LanguageClientManager::LanguageClientManager()
{
JsonRpcMessageHandler::registerMessageProvider<PublishDiagnosticsNotification>();
JsonRpcMessageHandler::registerMessageProvider<LogMessageNotification>();
JsonRpcMessageHandler::registerMessageProvider<ShowMessageRequest>();
JsonRpcMessageHandler::registerMessageProvider<ShowMessageNotification>();
managerInstance = this;
}