Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: [editor] New feature for AI #903

Merged
merged 2 commits into from
Sep 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading