[graphics/drawy/gsoc2026] src: feat: add mime handler for html
Abdelhadi Wael <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit 372a6459547f6c842272b19187845527ca74a497 by Abdelhadi Wael.
Committed on 24/07/2026 at 09:34.
Pushed by mlaurent into branch 'gsoc2026'.
feat: add mime handler for html
M +30 -6 src/gui/item/text.cpp
M +1 -0 src/gui/item/text.hpp
M +1 -1 src/gui/serializer/textdeserializer.cpp
M +12 -10 src/widgets/mime/textmimehandler.cpp
https://invent.kde.org/graphics/drawy/-/commit/372a6459547f6c842272b19187845527ca74a497
diff --git a/src/gui/item/text.cpp b/src/gui/item/text.cpp
index 6f26f9a7..bd2ddc58 100644
--- a/src/gui/item/text.cpp
+++ b/src/gui/item/text.cpp
@@ -170,12 +170,15 @@ void TextItem::scaleTextFragments(const qreal scaleY)
for (auto it = block.begin(); !it.atEnd(); ++it) {
const QTextFragment fragment = it.fragment();
QTextCharFormat fmt = fragment.charFormat();
- const qreal size = fmt.fontPointSize();
+ const qreal size = getFontSize(fmt);
fmt.setFontPointSize(std::max(1.0, size * scaleY));
+ fmt.setProperty(QTextFormat::FontPixelSize, QVariant());
+ fmt.setProperty(QTextFormat::FontSizeAdjustment, QVariant());
+
m_cursor.setPosition(fragment.position());
m_cursor.setPosition(fragment.position() + fragment.length(), QTextCursor::KeepAnchor);
- m_cursor.setCharFormat(fmt);
+ m_cursor.mergeCharFormat(fmt);
}
block = block.next();
}
@@ -273,6 +276,18 @@ void TextItem::updateBoundingBox()
setDirty(true);
}
+qreal TextItem::getFontSize(const QTextCharFormat &fmt)
+{
+ qreal size = fmt.fontPointSize();
+ if (size <= 0) {
+ size = fmt.font().pointSizeF();
+ }
+ if (size <= 0) {
+ size = fmt.font().pixelSize() * 72.0 / 96.0;
+ }
+ return std::max(size, 1.0);
+}
+
QFont TextItem::getFont() const
{
QFont font;
@@ -394,12 +409,15 @@ Property TextItem::property(const Property::Type propertyType) const
switch (propertyType) {
case Property::Type::StrokeColor: {
+ if (!cursor.charFormat().hasProperty(QTextFormat::ForegroundBrush)) {
+ return Item::property(Property::Type::StrokeColor);
+ }
const QColor color = cursor.charFormat().foreground().color();
return Property{color, Property::Type::StrokeColor};
}
case Property::Type::FontSize: {
- const qreal size = cursor.charFormat().font().pointSize();
- return Property{static_cast<int>(size), Property::Type::FontSize};
+ const qreal size = getFontSize(cursor.charFormat());
+ return Property{qRound(size), Property::Type::FontSize};
}
case Property::Type::FontFamily: {
const QString font = cursor.charFormat().font().family();
@@ -445,6 +463,7 @@ bool TextItem::needsPropertyUpdate(const Property &property) const
cursor.setPosition(start + 1);
const QTextCharFormat firstFormat = cursor.charFormat();
+ const qreal firstSize = getFontSize(firstFormat);
QTextBlock block = m_document.findBlock(start);
while (block.isValid() && block.position() < end) {
@@ -465,11 +484,12 @@ bool TextItem::needsPropertyUpdate(const Property &property) const
return true;
}
break;
- case Property::Type::FontSize:
- if (fmt.font().pointSize() != firstFormat.font().pointSize()) {
+ case Property::Type::FontSize: {
+ if (qRound(getFontSize(fmt)) != qRound(firstSize)) {
return true;
}
break;
+ }
case Property::Type::FontFamily:
if (fmt.font().family() != firstFormat.font().family()) {
return true;
@@ -493,6 +513,10 @@ void TextItem::setProperty(const Property::Type propertyType, const Property new
break;
case Property::Type::FontSize:
fmt.setFontPointSize(newObj.value<int>());
+
+ // these properties take priority over point size preventing size change
+ fmt.setProperty(QTextFormat::FontPixelSize, QVariant());
+ fmt.setProperty(QTextFormat::FontSizeAdjustment, QVariant());
break;
case Property::Type::FontFamily:
fmt.setFontFamilies(QStringList{newObj.value<QString>()});
diff --git a/src/gui/item/text.hpp b/src/gui/item/text.hpp
index 4240e6ef..93922d94 100644
--- a/src/gui/item/text.hpp
+++ b/src/gui/item/text.hpp
@@ -74,6 +74,7 @@ protected:
void drawItem(QPainter &painter, const QPointF &offset) const override;
private:
+ [[nodiscard]] LIBDRAWYGUI_NO_EXPORT static qreal getFontSize(const QTextCharFormat &fmt);
[[nodiscard]] LIBDRAWYGUI_NO_EXPORT QFont getFont() const;
[[nodiscard]] LIBDRAWYGUI_NO_EXPORT QTextOption getTextOptions() const;
diff --git a/src/gui/serializer/textdeserializer.cpp b/src/gui/serializer/textdeserializer.cpp
index ed5c8966..78c717de 100644
--- a/src/gui/serializer/textdeserializer.cpp
+++ b/src/gui/serializer/textdeserializer.cpp
@@ -26,7 +26,7 @@ void TextDeserializer::deserialize(const QJsonObject &obj)
}
if (obj.contains(u"html"_s)) {
- textItem->cursor().insertHtml(value(obj, u"html"_s).toString());
+ textItem->setHtml(value(obj, u"html"_s).toString());
} else {
textItem->cursor().insertText(text);
}
diff --git a/src/widgets/mime/textmimehandler.cpp b/src/widgets/mime/textmimehandler.cpp
index b664f5c4..3b826b7e 100644
--- a/src/widgets/mime/textmimehandler.cpp
+++ b/src/widgets/mime/textmimehandler.cpp
@@ -10,20 +10,21 @@
QList<std::shared_ptr<Item>> TextMimeHandler::tryReadData(const QMimeData &mimeData)
{
- if (!mimeData.hasText()) {
- return {};
+ if (mimeData.hasHtml() && !mimeData.html().trimmed().isEmpty()) {
+ const auto text = std::make_shared<TextItem>();
+ text->createTextBox({0, 0});
+ text->cursor().insertHtml(mimeData.html());
+ return {text};
}
- if (mimeData.text().trimmed().isEmpty()) {
- return {};
+ if (mimeData.hasText() && !mimeData.text().trimmed().isEmpty()) {
+ const auto text = std::make_shared<TextItem>();
+ text->createTextBox({0, 0});
+ text->cursor().insertText(mimeData.text());
+ return {text};
}
- const std::shared_ptr<TextItem> text = std::make_shared<TextItem>();
-
- text->createTextBox({0, 0});
- text->cursor().insertText(mimeData.text());
-
- return {text};
+ return {};
}
void TextMimeHandler::contributeData(QMimeData &mimeData, const QList<std::shared_ptr<Item>> &selectedItems)
@@ -35,4 +36,5 @@ void TextMimeHandler::contributeData(QMimeData &mimeData, const QList<std::share
const TextItem *item = static_cast<TextItem *>(&*selectedItems[0]);
mimeData.setText(item->text());
+ mimeData.setHtml(item->html());
}