Skip to content

Commit

Permalink
feat: [editor] Optimize the editor tooltip
Browse files Browse the repository at this point in the history
1.Implement Tooltip module
2.Added AI repair interface

Log: new feature
  • Loading branch information
Kakueeen authored and deepin-mozart committed Sep 14, 2024
1 parent d88337f commit a3c5401
Show file tree
Hide file tree
Showing 20 changed files with 2,492 additions and 813 deletions.
1,267 changes: 893 additions & 374 deletions assets/translations/en_US.ts

Large diffs are not rendered by default.

1,305 changes: 912 additions & 393 deletions assets/translations/zh_CN.ts

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ Build-Depends:
libdtkcore-dev,
libdtkcore5-bin,
libkf5syntaxhighlighting-dev,
libyaml-cpp-dev
libyaml-cpp-dev,
libcmark-dev
Standards-version: 3.9.8
Homepage: http://www.deepin.org

Expand Down
2 changes: 1 addition & 1 deletion src/common/lsp/client/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ bool ClientPrivate::diagnosticsCalled(const QJsonObject &jsonObj)
newlsp::Location {
newlsp::DocumentUri { reInfoLocationUrl },
newlsp::Range {
{ reInfoLocationRangeObj.value(lsp::K_LINE).toInt(), reInfoLocationRangeObj.value(lsp::K_CHARACTER).toInt() },
{ reInfoLocationStartObj.value(lsp::K_LINE).toInt(), reInfoLocationStartObj.value(lsp::K_CHARACTER).toInt() },
{ reInfoLocationEndObj.value(lsp::K_LINE).toInt(), reInfoLocationEndObj.value(lsp::K_CHARACTER).toInt() } } },
std::string {
reInfoMessage }
Expand Down
1 change: 1 addition & 0 deletions src/common/lsp/protocol/protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ QJsonObject initialize(const QString &workspaceFolder, const QString &language,
{ "declaration", QJsonObject { { "dynamicRegistration", true }, { "linkSupport", true } } },
{ "semanticHighlightingCapabilities", QJsonObject { { "semanticHighlighting", true } } },
{ "semanticTokens", capabilitiesSemanticTokens },
{ "hover", QJsonObject { { "contentFormat", QJsonArray { "markdown", "plaintext" } } } },
{ "completion", QJsonObject { { "editsNearCursor", true } } } } },
{ "workspace", workspace() },
{
Expand Down
149 changes: 149 additions & 0 deletions src/common/tooltip/tips.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#include "tips.h"

#include <QStyle>
#include <QScreen>
#include <QVBoxLayout>
#include <QFontMetrics>
#include <QStylePainter>
#include <QGuiApplication>
#include <QStyleOptionFrame>

TipLabel::TipLabel(QWidget *parent)
: QLabel(parent, Qt::ToolTip | Qt::BypassGraphicsProxyWidget)
{
}

TextTip::TextTip(QWidget *parent)
: TipLabel(parent)
{
setAutoFillBackground(true);
setForegroundRole(QPalette::BrightText);
setBackgroundRole(QPalette::Base);
ensurePolished();
setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, nullptr, this));
setFrameStyle(QFrame::NoFrame);
setAlignment(Qt::AlignLeft);
setIndent(1);
setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, nullptr, this) / 255.0);
}

void TextTip::setContent(const QVariant &content)
{
tipText = content.toString();
setOpenExternalLinks(likelyContainsLink());
}

bool TextTip::isInteractive() const
{
return likelyContainsLink();
}

void TextTip::configure(const QPoint &pos)
{
setText(tipText);

QFontMetrics fm(font());
int extraHeight = 0;
if (fm.descent() == 2 && fm.ascent() >= 11)
++extraHeight;

setWordWrap(false);
int tipWidth = sizeHint().width();

QScreen *screen = QGuiApplication::screenAt(pos);
if (!screen)
screen = QGuiApplication::primaryScreen();

const int screenWidth = screen->availableGeometry().width();
const int maxDesiredWidth = int(screenWidth * .5);
if (tipWidth > maxDesiredWidth) {
setWordWrap(true);
tipWidth = maxDesiredWidth;
}

resize(tipWidth, heightForWidth(tipWidth) + extraHeight);
}

bool TextTip::canHandleContentReplacement(ContentType type) const
{
return type == TextContent;
}

int TextTip::showTime() const
{
return 100000 + 40 * qMax(0, tipText.size() - 100);
}

bool TextTip::equals(ContentType type, const QVariant &other) const
{
return type == TextContent && other.canConvert<QStringList>() && other.toString() == tipText;
}

void TextTip::paintEvent(QPaintEvent *event)
{
QStylePainter p(this);
QStyleOptionFrame opt;
opt.initFrom(this);
p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
p.end();

QLabel::paintEvent(event);
}

void TextTip::resizeEvent(QResizeEvent *event)
{
QStyleHintReturnMask frameMask;
QStyleOption option;
option.initFrom(this);
if (style()->styleHint(QStyle::SH_ToolTip_Mask, &option, this, &frameMask))
setMask(frameMask.region);

QLabel::resizeEvent(event);
}

bool TextTip::likelyContainsLink() const
{
if (tipText.contains("href"), Qt::CaseInsensitive)
return true;

return false;
}

WidgetTip::WidgetTip(QWidget *parent)
: TipLabel(parent)
{
layout = new QVBoxLayout;
layout->setContentsMargins(0, 0, 0, 0);
setLayout(layout);
}

void WidgetTip::setContent(const QVariant &content)
{
widget = content.value<QWidget *>();
}

void WidgetTip::configure(const QPoint &pos)
{
if (!widget || layout->count() != 0)
return;

move(pos);
layout->addWidget(widget);
layout->setSizeConstraint(QLayout::SetFixedSize);
adjustSize();
}

bool WidgetTip::canHandleContentReplacement(ContentType type) const
{
Q_UNUSED(type)
return false;
}

bool WidgetTip::equals(ContentType type, const QVariant &other) const
{
return type == WidgetContent && other.value<QWidget *>() == widget;
}
71 changes: 71 additions & 0 deletions src/common/tooltip/tips.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-FileCopyrightText: 2024 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef TIPS_H
#define TIPS_H

#include <QLabel>
#include <QVariant>

QT_BEGIN_NAMESPACE
class QVBoxLayout;
QT_END_NAMESPACE

class TipLabel : public QLabel
{
public:
enum ContentType {
TextContent = 0,
WidgetContent
};

explicit TipLabel(QWidget *parent = nullptr);

virtual void setContent(const QVariant &content) = 0;
virtual bool isInteractive() const { return false; }
virtual int showTime() const = 0;
virtual void configure(const QPoint &pos) = 0;
virtual bool canHandleContentReplacement(ContentType type) const = 0;
virtual bool equals(ContentType type, const QVariant &other) const = 0;
};

class TextTip : public TipLabel
{
public:
explicit TextTip(QWidget *parent = nullptr);

void setContent(const QVariant &content) override;
bool isInteractive() const override;
void configure(const QPoint &pos) override;
bool canHandleContentReplacement(ContentType type) const override;
int showTime() const override;
bool equals(ContentType type, const QVariant &other) const override;
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;

private:
bool likelyContainsLink() const;

QString tipText;
};

class WidgetTip : public TipLabel
{
Q_OBJECT
public:
explicit WidgetTip(QWidget *parent = nullptr);

void setContent(const QVariant &content) override;
void configure(const QPoint &pos) override;
bool canHandleContentReplacement(ContentType type) const override;
int showTime() const override { return 30000; }
bool equals(ContentType type, const QVariant &other) const override;
bool isInteractive() const override { return true; }

private:
QWidget *widget { nullptr };
QVBoxLayout *layout { nullptr };
};

#endif // TIPS_H
Loading

0 comments on commit a3c5401

Please sign in to comment.