[graphics/krita] /: Add a "mismatched layer color space" warning icon
Dmitry Kazakov
null at kde.org
Fri Nov 22 11:30:17 GMT 2024
Git commit 12eb4d835592b2f2fd60d33501d09ce5f6154732 by Dmitry Kazakov.
Committed on 22/11/2024 at 11:30.
Pushed by dkazakov into branch 'master'.
Add a "mismatched layer color space" warning icon
Sometimes the user may mix layers of different color spaces in the
image. That is a valid usecase for some users (to keep the original
quality of layer data), but it might cause significant performance
issues on huge (I mean, reeaaally huge) files. So we should warn users
about that with a not-very-critical icon (and a tooltip).
Even though the icon is technically a "warning", it should not cry
into the user's face, since it might be a well-thought usecase by
the user.
The icon can be removed from the layer only by converting the layer
into the color space of the image via:
* Ctrl+Enter: "Unify Layers Color Space"
* Layer->Convert->Convert Layer Color Space
CC:kimageshop at kde.org
M +25 -0 libs/image/kis_layer_properties_icons.cpp
M +2 -0 libs/image/kis_layer_properties_icons.h
M +6 -0 libs/image/kis_paint_layer.cc
M +7 -0 libs/ui/kis_file_layer.cpp
M +6 -2 plugins/dockers/layerdocker/NodeDelegate.cpp
M +15 -9 plugins/dockers/layerdocker/NodeToolTip.cpp
https://invent.kde.org/graphics/krita/-/commit/12eb4d835592b2f2fd60d33501d09ce5f6154732
diff --git a/libs/image/kis_layer_properties_icons.cpp b/libs/image/kis_layer_properties_icons.cpp
index 8d990a6db77..8c1f44e6209 100644
--- a/libs/image/kis_layer_properties_icons.cpp
+++ b/libs/image/kis_layer_properties_icons.cpp
@@ -11,6 +11,9 @@
#include <QGlobalStatic>
Q_GLOBAL_STATIC(KisLayerPropertiesIcons, s_instance)
+#include <KoColorSpace.h>
+#include <KoColorProfile.h>
+
#include <kis_icon_utils.h>
#include <kis_node.h>
#include <commands/kis_node_property_list_command.h>
@@ -31,6 +34,7 @@ const KoID KisLayerPropertiesIcons::colorizeEditKeyStrokes("colorize-show-key-st
const KoID KisLayerPropertiesIcons::colorizeShowColoring("colorize-show-coloring", ki18n("Show Coloring"));
const KoID KisLayerPropertiesIcons::openFileLayerFile("open-file-layer-file", ki18n("Open File"));
const KoID KisLayerPropertiesIcons::layerError("layer-error", ki18n("Error"));
+const KoID KisLayerPropertiesIcons::layerColorSpaceMismatch("layer-color-space-mismatch", ki18n("Layer Color Space Mismatch"));
const KoID KisLayerPropertiesIcons::antialiased("antialiased", ki18n("Anti-aliasing"));
struct IconsPair {
@@ -81,6 +85,7 @@ void KisLayerPropertiesIcons::updateIcons()
m_d->icons.insert(colorizeShowColoring.id(), IconsPair(KisIconUtils::loadIcon("showColoring"), KisIconUtils::loadIcon("showColoringOff")));
m_d->icons.insert(openFileLayerFile.id(), IconsPair(KisIconUtils::loadIcon("document-open"), KisIconUtils::loadIcon("document-open")));
m_d->icons.insert(layerError.id(), IconsPair(KisIconUtils::loadIcon("warning"), KisIconUtils::loadIcon("warning")));
+ m_d->icons.insert(layerColorSpaceMismatch.id(), IconsPair(KisIconUtils::loadIcon("color-adjustment-mode-channels"), KisIconUtils::loadIcon("color-adjustment-mode-channels")));
m_d->icons.insert(antialiased.id(), IconsPair(KisIconUtils::loadIcon("select-shape"), KisIconUtils::loadIcon("select-pixel")));
}
@@ -114,6 +119,26 @@ KisBaseNode::Property KisLayerPropertiesIcons::getErrorProperty(const QString &m
return prop;
}
+KisBaseNode::Property KisLayerPropertiesIcons::getColorSpaceMismatchProperty(const KoColorSpace *cs)
+{
+ const QString message =
+ i18nc("a tooltip shown in when hovering layer's property",
+ "Layer color space is different from the image color space:\n%1 [%2],\noperations may be slow",
+ cs->name(),
+ cs->profile() ? cs->profile()->name() : "");
+
+ const IconsPair &pair = instance()->m_d->icons[layerColorSpaceMismatch.id()];
+
+ KisBaseNode::Property prop;
+ prop.id = layerColorSpaceMismatch.id();
+ prop.name = layerColorSpaceMismatch.name();
+ prop.state = message;
+ prop.onIcon = pair.on;
+ prop.offIcon = pair.off;
+
+ return prop;
+}
+
void KisLayerPropertiesIcons::setNodePropertyAutoUndo(KisNodeSP node, const KoID &id, const QVariant &value, KisImageSP image)
{
KisBaseNode::PropertyList props = node->sectionModelProperties();
diff --git a/libs/image/kis_layer_properties_icons.h b/libs/image/kis_layer_properties_icons.h
index 1e1e3a63240..d7c4d871ea4 100644
--- a/libs/image/kis_layer_properties_icons.h
+++ b/libs/image/kis_layer_properties_icons.h
@@ -33,6 +33,7 @@ public:
static const KoID colorizeShowColoring;
static const KoID openFileLayerFile;
static const KoID layerError;
+ static const KoID layerColorSpaceMismatch;
static const KoID antialiased;
static KisLayerPropertiesIcons* instance();
@@ -42,6 +43,7 @@ public:
bool isInStasis, bool stateInStasis);
static KisBaseNode::Property getErrorProperty(const QString &message);
+ static KisBaseNode::Property getColorSpaceMismatchProperty(const KoColorSpace *cs);
/**
* Sets the specified property of the node and updates it
diff --git a/libs/image/kis_paint_layer.cc b/libs/image/kis_paint_layer.cc
index 58ae2102f0f..fe2d20b5e4e 100644
--- a/libs/image/kis_paint_layer.cc
+++ b/libs/image/kis_paint_layer.cc
@@ -200,6 +200,12 @@ KisBaseNode::PropertyList KisPaintLayer::sectionModelProperties() const
l << KisLayerPropertiesIcons::getProperty(KisLayerPropertiesIcons::onionSkins, onionSkinEnabled());
}
+ const KoColorSpace *cs = m_d->paintDevice->colorSpace();
+ KisImageSP image = this->image();
+ if (image && *image->colorSpace() != *cs) {
+ l << KisLayerPropertiesIcons::getColorSpaceMismatchProperty(cs);
+ }
+
return l;
}
diff --git a/libs/ui/kis_file_layer.cpp b/libs/ui/kis_file_layer.cpp
index 41d2ebf8461..8495f42f2b4 100644
--- a/libs/ui/kis_file_layer.cpp
+++ b/libs/ui/kis_file_layer.cpp
@@ -141,6 +141,13 @@ KisBaseNode::PropertyList KisFileLayer::sectionModelProperties() const
l << KisLayerPropertiesIcons::getErrorProperty(i18nc("a tooltip shown when a file layer cannot load its linked file",
"Failed to load linked file: %1", fileNameOrPlaceholder()));
}
+
+ const KoColorSpace *cs = m_paintDevice->colorSpace();
+ KisImageSP image = this->image();
+ if (image && *image->colorSpace() != *cs) {
+ l << KisLayerPropertiesIcons::getColorSpaceMismatchProperty(cs);
+ }
+
return l;
}
diff --git a/plugins/dockers/layerdocker/NodeDelegate.cpp b/plugins/dockers/layerdocker/NodeDelegate.cpp
index 851643505ab..932b5514afd 100644
--- a/plugins/dockers/layerdocker/NodeDelegate.cpp
+++ b/plugins/dockers/layerdocker/NodeDelegate.cpp
@@ -438,7 +438,9 @@ QList<OptionalProperty> NodeDelegate::Private::rightmostProperties(const KisBase
KisBaseNode::PropertyList::const_iterator it = props.constBegin();
KisBaseNode::PropertyList::const_iterator end = props.constEnd();
for (; it != end; ++it) {
- if (!it->isMutable && it->id != KisLayerPropertiesIcons::layerError.id()) continue;
+ if (!it->isMutable &&
+ it->id != KisLayerPropertiesIcons::layerError.id() &&
+ it->id != KisLayerPropertiesIcons::layerColorSpaceMismatch.id()) continue;
if (it->id == KisLayerPropertiesIcons::visible.id()) {
// noop...
@@ -1098,7 +1100,9 @@ bool NodeDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const Q
QHelpEvent *helpEvent = static_cast<QHelpEvent*>(event);
auto hoveredProperty = d->propForMousePos(index, helpEvent->pos(), option);
- if (hoveredProperty && hoveredProperty->id == KisLayerPropertiesIcons::layerError.id()) {
+ if (hoveredProperty &&
+ (hoveredProperty->id == KisLayerPropertiesIcons::layerError.id() ||
+ hoveredProperty->id == KisLayerPropertiesIcons::layerColorSpaceMismatch.id())) {
QToolTip::showText(helpEvent->globalPos(), hoveredProperty->state.toString(), d->view);
} else {
d->tip.showTip(d->view, helpEvent->pos(), option, index);
diff --git a/plugins/dockers/layerdocker/NodeToolTip.cpp b/plugins/dockers/layerdocker/NodeToolTip.cpp
index 62ea6887cf9..e439ef8feeb 100644
--- a/plugins/dockers/layerdocker/NodeToolTip.cpp
+++ b/plugins/dockers/layerdocker/NodeToolTip.cpp
@@ -40,7 +40,8 @@ QTextDocument *NodeToolTip::createDocument(const QModelIndex &index)
const QString row = QString("<tr><td align=\"right\"><p style=\"white-space:pre\">%1:</p></td><td align=\"left\">%2</td></tr>");
QString value;
for(int i = 0, n = properties.count(); i < n; ++i) {
- if (properties[i].id == KisLayerPropertiesIcons::layerError.id()) continue;
+ if (properties[i].id == KisLayerPropertiesIcons::layerError.id() ||
+ properties[i].id == KisLayerPropertiesIcons::layerColorSpaceMismatch.id()) continue;
if (properties[i].isMutable)
value = properties[i].state.toBool() ? i18n("Yes") : i18n("No");
@@ -58,14 +59,19 @@ QTextDocument *NodeToolTip::createDocument(const QModelIndex &index)
QString errorMessage;
{
- auto it = std::find_if(properties.begin(), properties.end(),
- kismpl::mem_equal_to(&KisBaseNode::Property::id,
- KisLayerPropertiesIcons::layerError.id()));
-
- if (it != properties.end()) {
- doc->addResource(QTextDocument::ImageResource, QUrl("data:warn_symbol"), it->onIcon.pixmap(QSize(32,32)).toImage());
- errorMessage = QString("<table align=\"center\" border=\"0\"><tr valign=\"middle\"><td align=\"right\"><img src=\"data:warn_symbol\"></td><td align=\"left\"><b>%1</b></td></tr></table>").arg(it->state.toString());
- }
+ auto addWarningProperty = [&] (const QString &propertyId) {
+ auto it = std::find_if(properties.begin(), properties.end(),
+ kismpl::mem_equal_to(&KisBaseNode::Property::id,
+ propertyId));
+
+ if (it != properties.end()) {
+ doc->addResource(QTextDocument::ImageResource, QUrl(QString("data:symbol_%1").arg(it->id)), it->onIcon.pixmap(QSize(32,32)).toImage());
+ errorMessage += QString("<table align=\"center\" border=\"0\"><tr valign=\"middle\"><td align=\"right\"><img src=\"data:symbol_%2\"></td><td align=\"left\"><b>%1</b></td></tr></table>").arg(it->state.toString(), it->id);
+ }
+ };
+
+ addWarningProperty(KisLayerPropertiesIcons::layerError.id());
+ addWarningProperty(KisLayerPropertiesIcons::layerColorSpaceMismatch.id());
}
rows = QString("<table>%1</table>").arg(rows);
More information about the kimageshop
mailing list