10#include <klocalizedstring.h>
19#include <ksharedconfig.h>
73 setObjectName(
"tool_enclose_and_fill");
91 if (resourceProvider) {
106 if (resourceProvider) {
107 disconnect(resourceProvider,
179 i18n(
"You cannot use this tool with the selected layer type"),
295 newReferenceNodeList,
297 newReferencePaintDevice,
319 QTransform transform;
322 transform.scale(normalizedScale, normalizedScale);
390 optionButtonStripEnclosingMethod->
addButton(
393 optionButtonStripEnclosingMethod->
addButton(
406 static_cast<int>(RegionSelectionMethod::SelectAllRegions)
410 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithSpecificColor)
414 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithTransparent)
418 static_cast<int>(RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent)
422 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor)
426 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent)
430 RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent
432 static_cast<int>(RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent)
436 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor)
440 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedByTransparent)
444 static_cast<int>(RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent)
454 i18nc(
"The 'invert' checkbox in enclose and fill tool",
459 i18nc(
"The 'include contour regions' checkbox in enclose and fill tool",
460 "Include contour regions")
476 i18nc(
"The pattern 'scale' spinbox in enclose and fill tool options; {n} is the "
477 "number value, % is the percent sign",
487 i18nc(
"{n} is the number value, % is the percent sign",
"Opacity: {n}%"));
491 m_sliderFillThreshold->setPrefix(i18nc(
"The 'threshold' spinbox prefix in enclose and fill tool options",
"Threshold: "));
496 i18nc(
"The 'spread' spinbox in enclose and fill tool options; {n} is the number value, % is the percent sign",
500 m_sliderCloseGap->setPrefix(i18nc(
"The 'close gap' spinbox prefix in enclose and fill tool options",
"Close Gap: "));
505 i18nc(
"The 'use selection as boundary' checkbox in enclose and fill tool to use selection borders as boundary when filling",
506 "Use selection as boundary")
510 m_checkBoxAntiAlias =
new QCheckBox(i18nc(
"The anti-alias checkbox in enclose and fill tool options",
"Anti-aliasing"));
513 m_sliderExpand->setPrefix(i18nc(
"The 'grow/shrink' spinbox prefix in enclose and fill tool options",
"Grow: "));
525 m_sliderFeather->setPrefix(i18nc(
"The 'feather' spinbox prefix in enclose and fill tool options",
"Feather: "));
545 QPushButton *buttonReset =
new QPushButton(i18nc(
"The 'reset' button in enclose and fill tool options",
"Reset"));
565 m_sliderFillThreshold->setToolTip(i18n(
"Set the color similarity tolerance of the fill. Increasing threshold increases the range of similar colors to be filled."));
566 m_sliderFillOpacitySpread->setToolTip(i18n(
"Set the extent of the opaque portion of the fill. Decreasing spread decreases opacity of fill areas depending on color similarity."));
567 m_sliderCloseGap->setToolTip(i18n(
"Close gaps in lines up to the set amount"));
568 m_checkBoxSelectionAsBoundary->setToolTip(i18n(
"Set if the contour of the active selection should be treated as a boundary when filling the region"));
571 m_sliderExpand->setToolTip(i18n(
"Grow or shrink the fill by the set amount"));
577 m_buttonReferenceLabeled->setToolTip(i18n(
"Fill regions found from the merging of layers with specific color labels"));
578 m_checkBoxUseActiveLayer->setToolTip(i18n(
"Includes the active layer in regions found from merging of layers with specific color labels"));
580 buttonReset->setToolTip(i18n(
"Reset the options to their default values"));
589 i18nc(
"The 'enclosing method' section label in enclose and fill tool options",
"Enclosing method")
601 i18nc(
"The 'reference' section label in enclose and fill tool options",
"Reference")
604 sectionReference->
appendWidget(
"widgetLabels", widgetLabelsGroup);
611 i18nc(
"The 'target regions' section label in enclose and fill tool options",
"Target regions")
621 i18nc(
"The 'fill source' section label in enclose and fill tool options",
"Fill source")
635 i18nc(
"The 'fill extent' section label in enclose and fill tool options",
"Fill extent")
645 i18nc(
"The 'adjustments' section label in enclose and fill tool options",
"Adjustments")
648 sectionAdjustments->
appendWidget(
"containerGrow", containerGrow);
669 "buttonRegionSelectionColor",
673 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent ||
680 "checkBoxRegionSelectionIncludeContourRegions",
726 connect(optionButtonStripEnclosingMethod,
732 SIGNAL(currentIndexChanged(
int)),
735 SIGNAL(changed(
const KoColor&)),
738 SIGNAL(toggled(
bool)),
741 SIGNAL(toggled(
bool)),
743 connect(optionButtonStripFillWith,
747 SIGNAL(valueChanged(
double)),
750 SIGNAL(angleChanged(
double)),
753 SIGNAL(toggled(
bool)),
756 SIGNAL(valueChanged(
int)),
759 SIGNAL(currentIndexChanged(
int)),
762 SIGNAL(valueChanged(
int)),
765 SIGNAL(valueChanged(
int)),
768 SIGNAL(valueChanged(
int)),
771 SIGNAL(toggled(
bool)),
774 SIGNAL(toggled(
bool)),
777 SIGNAL(valueChanged(
int)),
780 SIGNAL(toggled(
bool)),
783 SIGNAL(valueChanged(
int)),
785 connect(optionButtonStripReference,
792 SIGNAL(toggled(
bool)),
809 const QString fillTypeStr =
m_configGroup.readEntry<QString>(
"fillWith",
"");
810 if (fillTypeStr ==
"foregroundColor") {
812 }
else if (fillTypeStr ==
"backgroundColor") {
814 }
else if (fillTypeStr ==
"pattern") {
841 const QString sampleLayersModeStr =
m_configGroup.readEntry<QString>(
"reference",
"currentLayer");
842 if (sampleLayersModeStr ==
"allLayers") {
844 }
else if (sampleLayersModeStr ==
"colorLabeledLayers") {
851 const QStringList colorLabelsStr =
m_configGroup.readEntry<QString>(
"colorLabels",
"").split(
',', Qt::SkipEmptyParts);
854 for (
const QString &colorLabelStr : colorLabelsStr) {
856 const int colorLabel = colorLabelStr.toInt(&ok);
879 switch (enclosingMethod) {
881 case Ellipse:
return "ellipse";
882 case Path:
return "path";
883 case Brush:
return "brush";
884 default:
return "lasso";
890 if (configString ==
"rectangle") {
892 }
else if (configString ==
"ellipse") {
894 }
else if (configString ==
"path") {
896 }
else if (configString ==
"brush") {
904 if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegions) {
905 return i18nc(
"Region selection method in enclose and fill tool",
907 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor) {
908 return i18nc(
"Region selection method in enclose and fill tool",
910 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent) {
911 return i18nc(
"Region selection method in enclose and fill tool",
913 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent) {
914 return i18nc(
"Region selection method in enclose and fill tool",
915 "Specific color or transparency");
916 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor) {
917 return i18nc(
"Region selection method in enclose and fill tool",
918 "All, excluding a specific color");
919 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent) {
920 return i18nc(
"Region selection method in enclose and fill tool",
921 "All, excluding transparency");
922 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent) {
923 return i18nc(
"Region selection method in enclose and fill tool",
924 "All, excluding a specific color or transparency");
925 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor) {
926 return i18nc(
"Region selection method in enclose and fill tool",
927 "Any surrounded by a specific color");
928 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedByTransparent) {
929 return i18nc(
"Region selection method in enclose and fill tool",
930 "Any surrounded by transparency");
931 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent) {
932 return i18nc(
"Region selection method in enclose and fill tool",
933 "Any surrounded by a specific color or transparency");
950 if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegions) {
952 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColor) {
953 return "regionsFilledWithSpecificColor";
954 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithTransparent) {
955 return "regionsFilledWithTransparent";
956 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent) {
957 return "regionsFilledWithSpecificColorOrTransparent";
958 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor) {
959 return "allRegionsExceptFilledWithSpecificColor";
960 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent) {
961 return "allRegionsExceptFilledWithTransparent";
962 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent) {
963 return "allRegionsExceptFilledWithSpecificColorOrTransparent";
964 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor) {
965 return "regionsSurroundedBySpecificColor";
966 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedByTransparent) {
967 return "regionsSurroundedByTransparent";
968 }
else if (regionSelectionMethod == RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent) {
969 return "regionsSurroundedBySpecificColorOrTransparent";
976 if (configString ==
"regionsFilledWithSpecificColor") {
977 return RegionSelectionMethod::SelectRegionsFilledWithSpecificColor;
978 }
else if (configString ==
"regionsFilledWithTransparent") {
979 return RegionSelectionMethod::SelectRegionsFilledWithTransparent;
980 }
else if (configString ==
"regionsFilledWithSpecificColorOrTransparent") {
981 return RegionSelectionMethod::SelectRegionsFilledWithSpecificColorOrTransparent;
982 }
else if (configString ==
"allRegionsExceptFilledWithSpecificColor") {
983 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColor;
984 }
else if (configString ==
"allRegionsExceptFilledWithTransparent") {
985 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithTransparent;
986 }
else if (configString ==
"allRegionsExceptFilledWithSpecificColorOrTransparent") {
987 return RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent;
988 }
else if (configString ==
"regionsSurroundedBySpecificColor") {
989 return RegionSelectionMethod::SelectRegionsSurroundedBySpecificColor;
990 }
else if (configString ==
"regionsSurroundedByTransparent") {
991 return RegionSelectionMethod::SelectRegionsSurroundedByTransparent;
992 }
else if (configString ==
"regionsSurroundedBySpecificColorOrTransparent") {
993 return RegionSelectionMethod::SelectRegionsSurroundedBySpecificColorOrTransparent;
995 return RegionSelectionMethod::SelectAllRegions;
1000 const QString xmlColor =
m_configGroup.readEntry(
"regionSelectionColor", QString());
1002 if (doc.setContent(xmlColor)) {
1003 QDomElement e = doc.documentElement().firstChild().toElement();
1006 if (e.hasAttribute(
"space") || e.tagName().toLower() ==
"srgb") {
1008 }
else if (doc.documentElement().hasAttribute(
"space") || doc.documentElement().tagName().toLower() ==
"srgb"){
1020 bool sampleMerged =
m_configGroup.readEntry(
"sampleMerged",
false);
1036 return "colorLabeledLayers";
1038 return "currentLayer";
1043 if (configString ==
"allLayers") {
1045 }
else if (configString ==
"colorLabeledLayers") {
1085 m_regionSelectionMethod == RegionSelectionMethod::SelectAllRegionsExceptFilledWithSpecificColorOrTransparent ||
1090 "checkBoxRegionSelectionIncludeContourRegions",
1129 m_configGroup.writeEntry(
"regionSelectionIncludeContourRegions", checked);
1143 sectionFillWith->
setWidgetVisible(
"angleSelectorPatternRotation", visible);
1179 m_configGroup.writeEntry(
"useCustomBlendingOptions", checked);
1199 m_configGroup.writeEntry(
"customCompositeOp", compositeOpId);
1235 m_configGroup.writeEntry(
"useSelectionAsBoundary", checked);
1262 m_configGroup.writeEntry(
"stopGrowingAtDarkestPixel", enabled);
1301 if (labels.isEmpty()) {
1304 QString colorLabels = QString::number(labels.first());
1305 for (
int i = 1; i < labels.size(); ++i) {
1306 colorLabels +=
"," + QString::number(labels[i]);
float value(const T *src, size_t ch)
const KoID Integer16BitsColorDepthID("U16", ki18n("16-bit integer/channel"))
const QString COMPOSITE_OVER
connect(this, SIGNAL(optionsChanged()), this, SLOT(saveOptions()))
@ IncreasingDirection_Clockwise
A widget with several options to select an angle.
@ FlipOptionsMode_ContextMenu
The flip options are shown only as a context menu when right-clicking the gauge widget.
void setFlipOptionsMode(FlipOptionsMode newMode)
Sets the mode in which the flip options should be shown.
void setIncreasingDirection(KisAngleGauge::IncreasingDirection newIncreasingDirection)
Sets the increasing direction in the angle gauge.
void setAngle(qreal newAngle)
Sets the current angle.
KisViewManager * viewManager() const
void validate(const KoColorSpace *cs)
KoID selectedCompositeOp() const
void selectCompositeOp(const KoID &op)
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
void setValue(qreal newValue)
void setRange(qreal newMinimum, qreal newMaximum, int newNumberOfDecimals=0, bool computeNewFastSliderStep=true)
Set the minimum and the maximum values of the range.
void setSoftMaximum(qreal newSoftMaximum)
KisImageAnimationInterface * animationInterface() const
KisPaintDeviceSP projection() const
void addJob(KisStrokeId id, KisStrokeJobData *data) override
KisStrokeId startStroke(KisStrokeStrategy *strokeStrategy) override
void endStroke(KisStrokeId id) override
static KisPaintDeviceSP createRefPaintDevice(KisImageSP originalImage, QString name="Merge Labeled Layers Reference Paint Device")
@ GroupSelectionPolicy_SelectIfColorLabeled
Groups will be taken into account only if they have set an explicit color label. This ignores groups ...
virtual const KoColorSpace * compositionSourceColorSpace() const
const KoColorSpace * colorSpace() const
The KisResourcesSnapshot class takes a snapshot of the various resources like colors and settings use...
KisSelectionSP activeSelection() const
void setFillTransform(QTransform transform)
This class is a spinbox in which you can click and drag to set the value. A slider like bar is displa...
void setSoftRange(int newSoftMinimum, int newSoftMaximum)
Set the minimum and the maximum values of the soft range.
void setValue(int newValue)
void setRange(int newMinimum, int newMaximum, bool computeNewFastSliderStep=true)
Set the minimum and the maximum values of the range, computing a new "fast slider step" based on the ...
void setSupportsWrapAroundMode(bool value)
KisCanvasResourceProvider * canvasResourceProvider()
static KoColor fromXML(const QDomElement &elt, const QString &channelDepthId)
void toXML(QDomDocument &doc, QDomElement &colorElt) const
static const KoCompositeOpRegistry & instance()
KoID getKoID(const QString &compositeOpID) const
#define KIS_SAFE_ASSERT_RECOVER_RETURN(cond)
QString button(const QWheelEvent &ev)
QSharedPointer< KUndo2Command > KUndo2CommandSP
KUndo2MagicString kundo2_i18n(const char *text)
QIcon loadIcon(const QString &name)
void setText(QSpinBox *spinBox, const QStringView textTemplate)
virtual KisPaintDeviceSP paintDevice() const =0