View Issue Details

IDProjectCategoryView StatusLast Update
0001096ScribusGraphics / Image Framespublic2025-03-29 10:04
Reporterpacketbell Assigned Tonitramr  
PrioritynormalSeverityfeatureReproducibilityN/A
Status assignedResolutionopen 
PlatformallOSallOS Versionall
Product Version1.3 
Target Version1.7 milestone 
Summary0001096: Picture frame padding
DescriptionThe ability to add precise amounts of white space between the frame border and the picture itself, similar to the shape properties for a text box (distance from top, bottom, left, right).
TagsNo tags attached.
PatchYes

Relationships

related to 0015893 assignedale Margin for images 
related to 0017423 resolvednitramr New text flow icons 

Activities

cbradney

2004-09-19 21:16

administrator   ~0002425

Well, we have the Contour line, but specifying shape distances for anything but rectangular is a difficult task, although possible. See what you think of Contour lines.

packetbell

2004-09-19 22:55

reporter   ~0002430

Actually, the padding would be the distance from the frame border to the frame contents, to create a bit of white space between (for instance) a photograph and the border that surrounds it.
Should be possible even the frame is irregular, because the shape is identical.

mkoren

2006-05-08 21:53

reporter   ~0011115

Seems to me the same fields used for text should be enabled here. This would at least make sense for images scaled to the frame size.

For free scaling images wouldn't it also make sense to be able to set a basepoint for the coordinates (in Properties:Image)? E.g. refer to upper right corner instead of upper left.

aliB

2009-07-15 11:12

reporter   ~0022188

The UI would be more consequent if you'd just allow to use the same fields as you use for textframes already.
This makes even sense, when the image is not scaled to framesize!

You just have to change the caption to "space between content"

pygmee

2009-07-20 22:45

developer   ~0022217

duplicate with 8275 ?

hammeredklavier

2009-07-23 16:18

reporter   ~0022236

I found the way Scribus handles the "standard box model" odd - it might be worth making it more straightforward to add margins and padding to text and graphics frames, basically in the same way as in CSS. I can't help thinking it ought to be a bit easier to put a standard amount of white space between my pictures and the text body.

Kunda

2015-10-09 19:59

updater   ~0036588

the target version was obsolete so I bumped it.
Perhaps this will get addressed by avox via ScribusCTL

nitramr

2025-03-09 21:09

developer   ~0052194

I'm working on an implementation.

The idea is to have a numeric input in the shape section to define a distance between the shape and the text.
- 4 inputs if bounding box mode is used
- 1 input for all other modes

The distance calculation is using the QPathStroker to generate the new "margin" path. It differs from the scale function of the nodes edit palette.
At the moment, it is not possible to have a negative stroking. And because of the QPathStroker the path is not quite smooth anymore.

Here is a first result. The light blue box visualize the distance.
textflow.png (202,995 bytes)   
textflow.png (202,995 bytes)   

pygmee

2025-03-12 22:08

developer   ~0052204

That sounds good to me. I guess we’d have to define use cases to be more precise, but most of the layout will work with your proposal. What i see :
- most of the frames are usually rectangular. So using a single field to have a quick margin around in shape mode is good enough. Those who want custom margin on each side may use bounding box.
- other frame shapes might not need 4 inputs, because they should have one / side.

Another possible behavior would be to activate a tool mode that would allow to create the margin on-canvas by moving the side.
We can see there might be some troubles with acute shapes. People may still be able to use contour mode if necessary.
Do you plan to keep contour mode untouched with point window ?

nitramr

2025-03-17 17:26

developer   ~0052245

Finally there is a patch available.


>> Another possible behavior would be to activate a tool mode that would allow to create the margin on-canvas by moving the side.
Could be a feature in the editing frame.

>> Do you plan to keep contour mode untouched with point window ?
The contour mode still exists. The new Object Margin is more of an extension and can be applied to all existing modes. If you draw a contour and select the "contour" text flow option in the Shape section, the object margin is calculated based on the contour path plus the margin, without changing the original contour.
textflow_2025-03-17_01.patch (51,207 bytes)   
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26788)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,30 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
+		if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
 		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
+			p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
 			p->setupSharpPolygon(&ContourLine);
 			p->strokePath();
 		}
+
+		bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.left() > 0);
+		bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.left() > 0;
+
+		// Draw Text Flow Margin Path
+		if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+		{
+			QTransform tf;
+			tf.rotate(-m_rotation);
+			tf.translate(-m_xPos, -m_yPos);
+			QPainterPath qpp = tf.map(textFlowPath());
+			FPointArray tfMargin;
+			tfMargin.fromQPainterPath(qpp);
+			p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+			p->setupSharpPolygon(&tfMargin);
+			p->strokePath();
+		}
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -4443,30 +4462,33 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	m_textFlowMargins = distances;
+
+	if (m_textFlowMode != mode)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
 	}
-	m_textFlowMode = mode;
-	
+
 	checkTextFlowInteractions();
 }
 
@@ -9664,19 +9686,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
+	QPainterPath pathOut;
+
 	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+		return pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
-
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9702,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9749,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9768,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.left() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9781,50 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.left() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.left() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{	
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26788)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1848,6 +1854,8 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/plugins/fileloader/scribus170format/scribus170format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Revision 26788)
+++ scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Arbeitskopie)
@@ -5842,8 +5842,15 @@
 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.setLeft(attrs.valueAsDouble("TextFlowLeft", 0.0));
+	textFlowMargins.setTop(attrs.valueAsDouble("TextFlowTop", 0.0));
+	textFlowMargins.setRight(attrs.valueAsDouble("TextFlowRight", 0.0));
+	textFlowMargins.setBottom(attrs.valueAsDouble("TextFlowBottom", 0.0));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
@@ -5851,7 +5858,7 @@
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
 	}
 	else
 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
Index: scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Revision 26788)
+++ scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Arbeitskopie)
@@ -2868,7 +2868,13 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowLeft", item->textFlowMargins().left());
+		docu.writeAttribute("TextFlowTop", item->textFlowMargins().top());
+		docu.writeAttribute("TextFlowRight", item->textFlowMargins().right());
+		docu.writeAttribute("TextFlowBottom", item->textFlowMargins().bottom());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26788)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26788)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -74,57 +74,67 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed around the physical page" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -133,35 +143,35 @@
 
 void NewMarginWidget::setPageWidth(double newWidth)
 {
-	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-	// {
-		leftMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - rightMarginSpinBox->value()));
-		rightMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - leftMarginSpinBox->value()));
-//	}
+	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+	// {
+		leftMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - rightMarginSpinBox->value()));
+		rightMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - leftMarginSpinBox->value()));
+//	}
 	m_pageWidth = newWidth;
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setPageHeight(double newHeight)
 {
-	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-	// {
-		topMarginSpinBox->setMaximum(qMax(0.0, newHeight * m_unitRatio - bottomMarginSpinBox->value()));
-		bottomMarginSpinBox->setMaximum(qMax(0.0,newHeight * m_unitRatio - topMarginSpinBox->value()));
-//	}
+	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+	// {
+		topMarginSpinBox->setMaximum(qMax(0.0, newHeight * m_unitRatio - bottomMarginSpinBox->value()));
+		bottomMarginSpinBox->setMaximum(qMax(0.0,newHeight * m_unitRatio - topMarginSpinBox->value()));
+//	}
 	m_pageHeight = newHeight;
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setTop()
 {
 	double newVal = topMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		bottomMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - topMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		bottomMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - topMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
 		m_marginData.set(newVal, newVal, newVal, newVal);
@@ -170,15 +180,15 @@
 	else
 		m_marginData.setTop(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setBottom()
 {
 	double newVal = bottomMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		topMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - bottomMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		topMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - bottomMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
 		m_marginData.set(newVal, newVal, newVal, newVal);
@@ -187,15 +197,15 @@
 	else
 		m_marginData.setBottom(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setLeft()
 {
 	double newVal = leftMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		rightMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - leftMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		rightMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - leftMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
 		m_marginData.set(newVal, newVal, newVal, newVal);
@@ -204,15 +214,15 @@
 	else
 		m_marginData.setLeft(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setRight()
 {
 	double newVal = rightMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		leftMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - rightMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		leftMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - rightMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
 		m_marginData.set(newVal, newVal, newVal, newVal);
@@ -221,8 +231,8 @@
 	else
 		m_marginData.setRight(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setNewUnit(int newUnitIndex)
@@ -296,8 +306,8 @@
 	topMarginSpinBox->blockSignals(false);
 	bottomMarginSpinBox->blockSignals(false);
 	m_savedPresetItem = item;
-
-	emit marginChanged(m_marginData);
+
+	emit marginChanged(m_marginData);
 }
 
 void NewMarginWidget::setPageSize(const QString& pageSize)
@@ -308,10 +318,10 @@
 
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
@@ -318,34 +328,26 @@
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
 	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +388,37 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	// we have to avoid that the single mode changes all other values if link button is checked
+	if (isSingle)
+		marginLinkButton->setChecked(false);
+
+	languageChange(); // update tooltips
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26788)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -44,6 +44,9 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
 
 	public slots:
 		void languageChange();
@@ -66,6 +69,7 @@
 		MarginStruct m_savedMarginData;
 		QString m_pageSize;
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26788)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
+    <width>168</width>
     <height>182</height>
    </rect>
   </property>
@@ -35,40 +35,6 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
    <item row="1" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
@@ -120,8 +86,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="1" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +95,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +102,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +116,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Bottom</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,32 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QPushButton" name="printerMarginsPushButton">
-       <property name="text">
-        <string>Printer Margins...</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item row="2" column="3">
-    <widget class="FormWidget" name="bottomMarginLabel">
+   <item row="1" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -237,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Bottom</string>
+      <string>Left</string>
      </property>
      <property name="font">
       <font>
@@ -244,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_8">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -258,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -270,8 +212,66 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QPushButton" name="printerMarginsPushButton">
+       <property name="text">
+        <string>Printer Margins...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,7 +279,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -286,7 +286,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,7 +300,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -312,6 +312,19 @@
      </layout>
     </widget>
    </item>
+   <item row="1" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26788)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26788)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26788)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26788)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,18 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +332,13 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +363,6 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +370,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -453,24 +480,51 @@
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +555,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +567,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26788)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26788)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-17_01.patch (51,207 bytes)   
textflow_ui.png (85,925 bytes)   
textflow_ui.png (85,925 bytes)   

nitramr

2025-03-17 17:39

developer   ~0052246

@cbradney @jghali, can you please take a look at the code?

For the path calculation, I used the QPainterPathStroker to create a more precise path offset. I know this calculation is quite complex, but the created path is cached for drawing, and the result is significantly better than the simple scaling method in the node editing dialog. One drawback: For rounded shapes, the path appears blocky.

In the future, we should replace this part with a more optimized path generator. I think a newer version of the lib2geom library has some options for this, but this change is currently outside the scope.

ale

2025-03-18 18:24

manager   ~0052262

some feebback from my side:

- when creating a new document and directly creating a text frame i get the distances even if i did not choice in the text flow (and it does not flow)
- when switching between items, the distances get shown when not defined and not shown when they should. it feels a bit random.
- by default, i would activate the "keep same distance"
- for the third and fourth option, i get the left distance displayed (only!), but it does nothing.
- if the last item had text flow around bounding box with margins, then the newly created ones also get them "automatically"
 (ah, once you have actively selected one of the modes, it applies to the newly created ones.)
- when creating a margin for a frame that is not on top of a text frame with text (there is nothing to flow around it), then the thin blue border is not displayed

nitramr

2025-03-19 17:08

developer   ~0052267

The new patch should fix all the previously mentioned issues. In addition, I fixed more issues I found regarding the object shape. Now, the margin path updates correctly, even in node edit mode.

I changed the format of how the margin values are stored in the sla file in this patch, new format (l, t, r, b):
TextFlowMargins="2.83465 5.66929 8.50394 11.3386"
textflow_2025-03-19_01.patch (55,115 bytes)   
Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml	(Revision 26796)
+++ resources/iconsets/1_7_0/1_7_0.xml	(Arbeitskopie)
@@ -367,6 +367,7 @@
 		<icon id="folder" file="16/file-open.svg" />
 				
 		<!-- Page & Layer -->
+		<icon id="border-all" file="16/border-all.svg" />
 		<icon id="border-bottom" file="16/border-bottom.svg" />
 		<icon id="border-inside" file="16/border-inside.svg" />
 		<icon id="border-left" file="16/border-left.svg" />
Index: scribus/margins.h
===================================================================
--- scribus/margins.h	(Revision 26796)
+++ scribus/margins.h	(Arbeitskopie)
@@ -42,12 +42,36 @@
 		inline void setRight(double aright) { m_right = aright; }
 		inline void setBottom(double abottom) { m_bottom = abottom; }
 
+		bool operator==(const MarginStruct &other) const
+		{
+			return ((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
 
+		void fromString(const QString &string)
+		{
+			resetToZero();
+			QStringList s = string.split(" ");
+			if (s.size() == 4) // l t r b
+				set(convert(s.at(1)), convert(s.at(0)), convert(s.at(3)), convert(s.at(2)));
+		}
+
+		QString toString() const
+		{
+			return QString("%0 %1 %2 %3").arg(QString::number(m_left)).arg(QString::number(m_top)).arg(QString::number(m_right)).arg(QString::number(m_bottom));
+		}
+
 	protected:
 		double m_top {0.0};
 		double m_left {0.0};
 		double m_bottom {0.0};
 		double m_right {0.0};
+
+		double convert(const QString& s)
+		{
+			bool ok(false);
+			double number = s.toDouble(&ok);
+			return ok ? number : 0.0;
+		}
 };
 
 class ScMargins : public QMarginsF
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26796)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,10 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
+
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -2388,6 +2387,29 @@
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setShape(const FPointArray &val)
+{
+	PoLine = val;
+
+	if (textFlowUsesFrameShape())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+
+}
+
+void PageItem::setContour(const FPointArray &val)
+{
+	ContourLine = val;
+
+	if (textFlowUsesContourLine())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
@@ -4443,31 +4465,39 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	if (m_textFlowMargins != distances)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		m_textFlowMargins = distances;
+		m_textFlowMarginsNeedUpdate = true;
 	}
-	m_textFlowMode = mode;
-	
-	checkTextFlowInteractions();
+
+	if (m_textFlowMode != mode)
+	{
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
+		m_textFlowMarginsNeedUpdate = true;
+	}
+
+	checkChanges();
 }
 
 void PageItem::checkTextFlowInteractions(bool allItems)
@@ -4597,7 +4627,7 @@
 	{
 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
 			(oldWidth != m_width || oldHeight != m_height) ||
-			(oldRot != m_rotation))
+			(oldRot != m_rotation || m_textFlowMarginsNeedUpdate))
 		{
 			textFlowCheckRect = getOldBoundingRect();
 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
@@ -4605,6 +4635,8 @@
 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
+			spreadChanges = true;
+			m_textFlowMarginsNeedUpdate = false;
 		}
 	}
 
@@ -4615,7 +4647,7 @@
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
 	}
 	// has the item been rotated
-	if (force || ((oldRot != m_rotation) && (shouldCheck())))
+	if (force || ((oldRot != m_rotation) && shouldCheck()))
 	{
 		rotateUndoAction();
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
@@ -9089,6 +9121,9 @@
 		PoLine.addPoint(x1, y1);
 		PoLine.addPoint(x2, y2);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = true;
 }
@@ -9149,6 +9184,9 @@
 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = false;
 	FrameType = 2;
@@ -9664,19 +9702,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
-	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+	QPainterPath pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
+	if (textFlowMode() == TextFlowDisabled)
+		return pathOut;
 
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9718,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9765,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9784,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.left() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9797,51 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.left() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	// TODO: nitramr: Replace QPainterPathStroker with a more performant path offset method.
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.left() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
@@ -10132,6 +10216,37 @@
 	p->drawLine(FPoint(bx1 + scp1 / 2, ofy + scp1), FPoint(bx1 + scp1 * 3.5, ofy + scp1));
 }
 
+void PageItem::drawTextFlowPath(ScPainter *p) const
+{
+	bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.left() > 0);
+	bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.left() > 0;
+
+	// Draw Text Flow Margin Path
+	if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+	{
+		QTransform tf;
+		tf.rotate(-m_rotation);
+		tf.translate(-m_xPos, -m_yPos);
+		QPainterPath qpp = tf.map(textFlowPath());
+		FPointArray tfMargin;
+		tfMargin.fromQPainterPath(qpp);
+		// Color: Scribus Blue 200, https://wiki.scribus.net/canvas/IndigoUI_Style_Guide#Colors
+		p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&tfMargin);
+		p->strokePath();
+	}
+}
+
+void PageItem::drawContourLine(ScPainter *p) const
+{
+	if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
+	{
+		p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&ContourLine);
+		p->strokePath();
+	}
+}
+
 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
 {
 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex - 1).points.copy();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26796)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -453,9 +453,9 @@
 	void SetQColor(QColor *tmp, const QString& farbe, double shad);
 	void DrawPolyL(QPainter *p, const QPolygon& pts);
 	FPointArray shape() const { return PoLine; }
-	void setShape(const FPointArray& val) { PoLine = val; }
+	void setShape(const FPointArray& val);
 	FPointArray contour() const { return ContourLine; }
-	void setContour(const FPointArray& val) { ContourLine = val; }
+	void setContour(const FPointArray& val);
 	bool flipPathText() const { return textPathFlipped; }
 	void setFlipPathText(bool val) { textPathFlipped = val; }
 	int pathTextType() const { return textPathType; }
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1533,6 +1539,8 @@
 	void DrawObj_PolyLine(ScPainter *p);
 	void DrawObj_PathText(ScPainter *p, double sc);
 	void drawLockedMarker(ScPainter *p) const;
+	void drawTextFlowPath(ScPainter *p) const;
+	void drawContourLine(ScPainter *p) const;
 	void drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex);
 
 	/** @brief Manages undostack and is where all undo actions/states are sent. */
@@ -1848,6 +1856,9 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
+	bool m_textFlowMarginsNeedUpdate {false};
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(Revision 26796)
+++ scribus/pageitem_textframe.cpp	(Arbeitskopie)
@@ -3587,6 +3587,7 @@
 	//#12405 if (isAnnotation() && ((annotation().Type() > 1) && (annotation().Type() < 7)) && (annotation().borderWidth() > 0))
 	//	return;
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -3608,13 +3609,10 @@
 			p->setupSharpPolygon(&PoLine);
 			p->strokePath();
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
 
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
Index: scribus/plugins/fileloader/scribus170format/scribus170format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Arbeitskopie)
@@ -5842,8 +5842,12 @@
 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.fromString(attrs.valueAsString("TextFlowMargins", "0 0 0 0"));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
@@ -5851,7 +5855,7 @@
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
 	}
 	else
 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
Index: scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Arbeitskopie)
@@ -2868,7 +2868,10 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowMargins", item->textFlowMargins().toString());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26796)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26796)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -74,57 +74,71 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed around the physical page" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	if (isSingleMode())
+		leftMarginLabel->setPixmap(im.loadPixmap("border-all"));
+	else
+		leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -308,10 +322,10 @@
 
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
@@ -318,34 +332,26 @@
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
 	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +392,32 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	// we have to avoid that the single mode changes all other values if link button is checked
+	if (isSingle)
+		marginLinkButton->setChecked(false);
+
+	iconSetChange();
+	languageChange(); // update tooltips
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	languageChange();
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26796)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -44,6 +44,9 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
 
 	public slots:
 		void languageChange();
@@ -66,6 +69,7 @@
 		MarginStruct m_savedMarginData;
 		QString m_pageSize;
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26796)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
+    <width>168</width>
     <height>182</height>
    </rect>
   </property>
@@ -35,40 +35,6 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
    <item row="1" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
@@ -120,8 +86,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="1" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +95,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +102,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +116,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Bottom</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,32 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QPushButton" name="printerMarginsPushButton">
-       <property name="text">
-        <string>Printer Margins...</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item row="2" column="3">
-    <widget class="FormWidget" name="bottomMarginLabel">
+   <item row="1" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -237,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Bottom</string>
+      <string>Left</string>
      </property>
      <property name="font">
       <font>
@@ -244,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_8">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -258,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -270,8 +212,66 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QPushButton" name="printerMarginsPushButton">
+       <property name="text">
+        <string>Printer Margins...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,7 +279,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -286,7 +286,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,7 +300,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -312,6 +312,19 @@
      </layout>
     </widget>
    </item>
+   <item row="1" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp	(Revision 26796)
+++ scribus/ui/nodeeditpalette.cpp	(Arbeitskopie)
@@ -370,7 +370,7 @@
 		UndoManager::instance()->action(currItem, is);
 	}
 	//FIXME make an internal item copy poline to contourline member
-	currItem->ContourLine = currItem->PoLine.copy();
+	currItem->setContour(currItem->PoLine.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -382,7 +382,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->ContourLine = currItem->imageClip.copy();
+	currItem->setContour(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -394,7 +394,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->PoLine = currItem->imageClip.copy();
+	currItem->setShape(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	currItem->FrameType = 3;
 	m_doc->adjustItemSize(currItem);
@@ -796,9 +796,9 @@
 		// relative to the current position (in the item's coordinate space).
 		// adjustItemSize will then take care of moving the position and changing
 		// image offsets, etc.
-		currItem->PoLine = m_itemPath.copy();
+		currItem->setShape(m_itemPath.copy());
 		currItem->PoLine.translate(delta.x(), delta.y());
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		m_doc->adjustItemSize(currItem);
 		if (currItem->itemType() == PageItem::PathText)
 			currItem->updatePolyClip();
@@ -828,15 +828,15 @@
 	QPointF delta = m.map(QPointF(m_xPos, m_yPos)) - m.map(QPointF(currItem->xPos(), currItem->yPos()));
 	if (EditCont->isChecked())
 	{
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		currItem->ContourLine.translate(delta.x(), delta.y());
 	}
 	else
 	{
 		// See comment in NodePalette::CancelEdit
-		currItem->PoLine = m_itemPath;
+		currItem->setShape(m_itemPath);
  		currItem->PoLine.translate(delta.x(), delta.y());
- 		currItem->ContourLine = m_itemContourPath;
+		currItem->setContour(m_itemContourPath);
 		m_doc->adjustItemSize(currItem);
 	}
 	if (currItem->itemType() == PageItem::PathText)
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26796)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,18 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +332,12 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +362,8 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
+
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +371,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -447,30 +475,57 @@
 	roundRect->blockSignals(b);
 	if (f == 0)
 		m_doc->setFrameRounded();
-	if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
-		return;
+	// if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
+	// 	return;
 	m_doc->invalidateAll();
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +556,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +568,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26796)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-19_01.patch (55,115 bytes)   
border-all.svg (397 bytes)   
border-all.svg (397 bytes)   

nitramr

2025-03-21 22:16

developer   ~0052288

new patch adds missing operator in margins.h
textflow_2025-03-21_01.patch (55,305 bytes)   
Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml	(Revision 26796)
+++ resources/iconsets/1_7_0/1_7_0.xml	(Arbeitskopie)
@@ -367,6 +367,7 @@
 		<icon id="folder" file="16/file-open.svg" />
 				
 		<!-- Page & Layer -->
+		<icon id="border-all" file="16/border-all.svg" />
 		<icon id="border-bottom" file="16/border-bottom.svg" />
 		<icon id="border-inside" file="16/border-inside.svg" />
 		<icon id="border-left" file="16/border-left.svg" />
Index: scribus/margins.h
===================================================================
--- scribus/margins.h	(Revision 26800)
+++ scribus/margins.h	(Arbeitskopie)
@@ -42,12 +42,40 @@
 		inline void setRight(double aright) { m_right = aright; }
 		inline void setBottom(double abottom) { m_bottom = abottom; }
 
+		bool operator==(const MarginStruct &other) const
+		{
+			return ((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
+		bool operator!=(const MarginStruct& other) const
+		{
+			return !((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
 
+		void fromString(const QString &string)
+		{
+			resetToZero();
+			QStringList s = string.split(" ");
+			if (s.size() == 4) // l t r b
+				set(convert(s.at(1)), convert(s.at(0)), convert(s.at(3)), convert(s.at(2)));
+		}
+
+		QString toString() const
+		{
+			return QString("%0 %1 %2 %3").arg(QString::number(m_left)).arg(QString::number(m_top)).arg(QString::number(m_right)).arg(QString::number(m_bottom));
+		}
+
 	protected:
 		double m_top {0.0};
 		double m_left {0.0};
 		double m_bottom {0.0};
 		double m_right {0.0};
+
+		double convert(const QString& s)
+		{
+			bool ok(false);
+			double number = s.toDouble(&ok);
+			return ok ? number : 0.0;
+		}
 };
 
 class ScMargins : public QMarginsF
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26796)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,10 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
+
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -2388,6 +2387,29 @@
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setShape(const FPointArray &val)
+{
+	PoLine = val;
+
+	if (textFlowUsesFrameShape())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+
+}
+
+void PageItem::setContour(const FPointArray &val)
+{
+	ContourLine = val;
+
+	if (textFlowUsesContourLine())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
@@ -4443,31 +4465,39 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	if (m_textFlowMargins != distances)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		m_textFlowMargins = distances;
+		m_textFlowMarginsNeedUpdate = true;
 	}
-	m_textFlowMode = mode;
-	
-	checkTextFlowInteractions();
+
+	if (m_textFlowMode != mode)
+	{
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
+		m_textFlowMarginsNeedUpdate = true;
+	}
+
+	checkChanges();
 }
 
 void PageItem::checkTextFlowInteractions(bool allItems)
@@ -4597,7 +4627,7 @@
 	{
 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
 			(oldWidth != m_width || oldHeight != m_height) ||
-			(oldRot != m_rotation))
+			(oldRot != m_rotation || m_textFlowMarginsNeedUpdate))
 		{
 			textFlowCheckRect = getOldBoundingRect();
 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
@@ -4605,6 +4635,8 @@
 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
+			spreadChanges = true;
+			m_textFlowMarginsNeedUpdate = false;
 		}
 	}
 
@@ -4615,7 +4647,7 @@
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
 	}
 	// has the item been rotated
-	if (force || ((oldRot != m_rotation) && (shouldCheck())))
+	if (force || ((oldRot != m_rotation) && shouldCheck()))
 	{
 		rotateUndoAction();
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
@@ -9089,6 +9121,9 @@
 		PoLine.addPoint(x1, y1);
 		PoLine.addPoint(x2, y2);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = true;
 }
@@ -9149,6 +9184,9 @@
 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = false;
 	FrameType = 2;
@@ -9664,19 +9702,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
-	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+	QPainterPath pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
+	if (textFlowMode() == TextFlowDisabled)
+		return pathOut;
 
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9718,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9765,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9784,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.left() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9797,51 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.left() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	// TODO: nitramr: Replace QPainterPathStroker with a more performant path offset method.
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.left() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
@@ -10132,6 +10216,37 @@
 	p->drawLine(FPoint(bx1 + scp1 / 2, ofy + scp1), FPoint(bx1 + scp1 * 3.5, ofy + scp1));
 }
 
+void PageItem::drawTextFlowPath(ScPainter *p) const
+{
+	bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.left() > 0);
+	bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.left() > 0;
+
+	// Draw Text Flow Margin Path
+	if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+	{
+		QTransform tf;
+		tf.rotate(-m_rotation);
+		tf.translate(-m_xPos, -m_yPos);
+		QPainterPath qpp = tf.map(textFlowPath());
+		FPointArray tfMargin;
+		tfMargin.fromQPainterPath(qpp);
+		// Color: Scribus Blue 200, https://wiki.scribus.net/canvas/IndigoUI_Style_Guide#Colors
+		p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&tfMargin);
+		p->strokePath();
+	}
+}
+
+void PageItem::drawContourLine(ScPainter *p) const
+{
+	if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
+	{
+		p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&ContourLine);
+		p->strokePath();
+	}
+}
+
 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
 {
 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex - 1).points.copy();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26796)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -453,9 +453,9 @@
 	void SetQColor(QColor *tmp, const QString& farbe, double shad);
 	void DrawPolyL(QPainter *p, const QPolygon& pts);
 	FPointArray shape() const { return PoLine; }
-	void setShape(const FPointArray& val) { PoLine = val; }
+	void setShape(const FPointArray& val);
 	FPointArray contour() const { return ContourLine; }
-	void setContour(const FPointArray& val) { ContourLine = val; }
+	void setContour(const FPointArray& val);
 	bool flipPathText() const { return textPathFlipped; }
 	void setFlipPathText(bool val) { textPathFlipped = val; }
 	int pathTextType() const { return textPathType; }
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1533,6 +1539,8 @@
 	void DrawObj_PolyLine(ScPainter *p);
 	void DrawObj_PathText(ScPainter *p, double sc);
 	void drawLockedMarker(ScPainter *p) const;
+	void drawTextFlowPath(ScPainter *p) const;
+	void drawContourLine(ScPainter *p) const;
 	void drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex);
 
 	/** @brief Manages undostack and is where all undo actions/states are sent. */
@@ -1848,6 +1856,9 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
+	bool m_textFlowMarginsNeedUpdate {false};
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(Revision 26796)
+++ scribus/pageitem_textframe.cpp	(Arbeitskopie)
@@ -3587,6 +3587,7 @@
 	//#12405 if (isAnnotation() && ((annotation().Type() > 1) && (annotation().Type() < 7)) && (annotation().borderWidth() > 0))
 	//	return;
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -3608,13 +3609,10 @@
 			p->setupSharpPolygon(&PoLine);
 			p->strokePath();
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
 
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
Index: scribus/plugins/fileloader/scribus170format/scribus170format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Arbeitskopie)
@@ -5842,8 +5842,12 @@
 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.fromString(attrs.valueAsString("TextFlowMargins", "0 0 0 0"));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
@@ -5851,7 +5855,7 @@
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
 	}
 	else
 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
Index: scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Arbeitskopie)
@@ -2868,7 +2868,10 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowMargins", item->textFlowMargins().toString());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26796)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26796)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -74,57 +74,71 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed around the physical page" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	if (isSingleMode())
+		leftMarginLabel->setPixmap(im.loadPixmap("border-all"));
+	else
+		leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -308,10 +322,10 @@
 
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
@@ -318,34 +332,26 @@
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
 	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +392,32 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	// we have to avoid that the single mode changes all other values if link button is checked
+	if (isSingle)
+		marginLinkButton->setChecked(false);
+
+	iconSetChange();
+	languageChange(); // update tooltips
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	languageChange();
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26796)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -44,6 +44,9 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
 
 	public slots:
 		void languageChange();
@@ -66,6 +69,7 @@
 		MarginStruct m_savedMarginData;
 		QString m_pageSize;
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26796)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
+    <width>168</width>
     <height>182</height>
    </rect>
   </property>
@@ -35,40 +35,6 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
    <item row="1" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
@@ -120,8 +86,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="1" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +95,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +102,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +116,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Bottom</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,32 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QPushButton" name="printerMarginsPushButton">
-       <property name="text">
-        <string>Printer Margins...</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item row="2" column="3">
-    <widget class="FormWidget" name="bottomMarginLabel">
+   <item row="1" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -237,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Bottom</string>
+      <string>Left</string>
      </property>
      <property name="font">
       <font>
@@ -244,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_8">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -258,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -270,8 +212,66 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QPushButton" name="printerMarginsPushButton">
+       <property name="text">
+        <string>Printer Margins...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,7 +279,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -286,7 +286,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,7 +300,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -312,6 +312,19 @@
      </layout>
     </widget>
    </item>
+   <item row="1" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp	(Revision 26796)
+++ scribus/ui/nodeeditpalette.cpp	(Arbeitskopie)
@@ -370,7 +370,7 @@
 		UndoManager::instance()->action(currItem, is);
 	}
 	//FIXME make an internal item copy poline to contourline member
-	currItem->ContourLine = currItem->PoLine.copy();
+	currItem->setContour(currItem->PoLine.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -382,7 +382,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->ContourLine = currItem->imageClip.copy();
+	currItem->setContour(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -394,7 +394,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->PoLine = currItem->imageClip.copy();
+	currItem->setShape(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	currItem->FrameType = 3;
 	m_doc->adjustItemSize(currItem);
@@ -796,9 +796,9 @@
 		// relative to the current position (in the item's coordinate space).
 		// adjustItemSize will then take care of moving the position and changing
 		// image offsets, etc.
-		currItem->PoLine = m_itemPath.copy();
+		currItem->setShape(m_itemPath.copy());
 		currItem->PoLine.translate(delta.x(), delta.y());
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		m_doc->adjustItemSize(currItem);
 		if (currItem->itemType() == PageItem::PathText)
 			currItem->updatePolyClip();
@@ -828,15 +828,15 @@
 	QPointF delta = m.map(QPointF(m_xPos, m_yPos)) - m.map(QPointF(currItem->xPos(), currItem->yPos()));
 	if (EditCont->isChecked())
 	{
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		currItem->ContourLine.translate(delta.x(), delta.y());
 	}
 	else
 	{
 		// See comment in NodePalette::CancelEdit
-		currItem->PoLine = m_itemPath;
+		currItem->setShape(m_itemPath);
  		currItem->PoLine.translate(delta.x(), delta.y());
- 		currItem->ContourLine = m_itemContourPath;
+		currItem->setContour(m_itemContourPath);
 		m_doc->adjustItemSize(currItem);
 	}
 	if (currItem->itemType() == PageItem::PathText)
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26796)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,18 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +332,12 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +362,8 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
+
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +371,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -447,30 +475,57 @@
 	roundRect->blockSignals(b);
 	if (f == 0)
 		m_doc->setFrameRounded();
-	if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
-		return;
+	// if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
+	// 	return;
 	m_doc->invalidateAll();
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +556,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +568,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26796)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-21_01.patch (55,305 bytes)   

pygmee

2025-03-22 19:06

developer   ~0052292

After applying your last patch, the behaviour sounds good to me, and values seems ok when selecting random frames.
blue border appears even if there is no frame around.
What in can see is that if only the last value is set, then the blue line doesn’t appear, be it over a text frame or not.
no-margin-displayed-bottom.jpg (205,515 bytes)   
no-margin-displayed-bottom.jpg (205,515 bytes)   

nitramr

2025-03-22 20:15

developer   ~0052293

Oh, nice catch.

There was a typo in the PageItem class. The values ​​of the left input were checked twice, but the values ​​of the bottom input were not.
textflow_2025-03-22_01.patch (55,239 bytes)   
Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml	(Revision 26796)
+++ resources/iconsets/1_7_0/1_7_0.xml	(Arbeitskopie)
@@ -367,6 +367,7 @@
 		<icon id="folder" file="16/file-open.svg" />
 				
 		<!-- Page & Layer -->
+		<icon id="border-all" file="16/border-all.svg" />
 		<icon id="border-bottom" file="16/border-bottom.svg" />
 		<icon id="border-inside" file="16/border-inside.svg" />
 		<icon id="border-left" file="16/border-left.svg" />
Index: scribus/margins.h
--- scribus/margins.h	(Revision 26800)
+++ scribus/margins.h	(Arbeitskopie)
@@ -42,12 +42,40 @@
 		inline void setRight(double aright) { m_right = aright; }
 		inline void setBottom(double abottom) { m_bottom = abottom; }
 
+		bool operator==(const MarginStruct &other) const
+		{
+			return ((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
+		bool operator!=(const MarginStruct& other) const
+		{
+			return !((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
 
+		void fromString(const QString &string)
+		{
+			resetToZero();
+			QStringList s = string.split(" ");
+			if (s.size() == 4) // l t r b
+				set(convert(s.at(1)), convert(s.at(0)), convert(s.at(3)), convert(s.at(2)));
+		}
+
+		QString toString() const
+		{
+			return QString("%0 %1 %2 %3").arg(QString::number(m_left)).arg(QString::number(m_top)).arg(QString::number(m_right)).arg(QString::number(m_bottom));
+		}
+
 	protected:
 		double m_top {0.0};
 		double m_left {0.0};
 		double m_bottom {0.0};
 		double m_right {0.0};
+
+		double convert(const QString& s)
+		{
+			bool ok(false);
+			double number = s.toDouble(&ok);
+			return ok ? number : 0.0;
+		}
 };
 
 class ScMargins : public QMarginsF
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26796)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,10 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
+
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -2388,6 +2387,29 @@
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setShape(const FPointArray &val)
+{
+	PoLine = val;
+
+	if (textFlowUsesFrameShape())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+
+}
+
+void PageItem::setContour(const FPointArray &val)
+{
+	ContourLine = val;
+
+	if (textFlowUsesContourLine())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
@@ -4443,31 +4465,39 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	if (m_textFlowMargins != distances)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		m_textFlowMargins = distances;
+		m_textFlowMarginsNeedUpdate = true;
 	}
-	m_textFlowMode = mode;
-	
-	checkTextFlowInteractions();
+
+	if (m_textFlowMode != mode)
+	{
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
+		m_textFlowMarginsNeedUpdate = true;
+	}
+
+	checkChanges();
 }
 
 void PageItem::checkTextFlowInteractions(bool allItems)
@@ -4597,7 +4627,7 @@
 	{
 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
 			(oldWidth != m_width || oldHeight != m_height) ||
-			(oldRot != m_rotation))
+			(oldRot != m_rotation || m_textFlowMarginsNeedUpdate))
 		{
 			textFlowCheckRect = getOldBoundingRect();
 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
@@ -4605,6 +4635,8 @@
 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
+			spreadChanges = true;
+			m_textFlowMarginsNeedUpdate = false;
 		}
 	}
 
@@ -4615,7 +4647,7 @@
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
 	}
 	// has the item been rotated
-	if (force || ((oldRot != m_rotation) && (shouldCheck())))
+	if (force || ((oldRot != m_rotation) && shouldCheck()))
 	{
 		rotateUndoAction();
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
@@ -9089,6 +9121,9 @@
 		PoLine.addPoint(x1, y1);
 		PoLine.addPoint(x2, y2);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = true;
 }
@@ -9149,6 +9184,9 @@
 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = false;
 	FrameType = 2;
@@ -9664,19 +9702,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
-	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+	QPainterPath pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
+	if (textFlowMode() == TextFlowDisabled)
+		return pathOut;
 
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9718,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9765,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9784,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.left() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9797,51 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.left() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	// TODO: nitramr: Replace QPainterPathStroker with a more performant path offset method.
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.left() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
@@ -10132,6 +10216,37 @@
 	p->drawLine(FPoint(bx1 + scp1 / 2, ofy + scp1), FPoint(bx1 + scp1 * 3.5, ofy + scp1));
 }
 
+void PageItem::drawTextFlowPath(ScPainter *p) const
+{
+	bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.bottom() > 0);
+	bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.left() > 0;
+
+	// Draw Text Flow Margin Path
+	if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+	{
+		QTransform tf;
+		tf.rotate(-m_rotation);
+		tf.translate(-m_xPos, -m_yPos);
+		QPainterPath qpp = tf.map(textFlowPath());
+		FPointArray tfMargin;
+		tfMargin.fromQPainterPath(qpp);
+		// Color: Scribus Blue 200, https://wiki.scribus.net/canvas/IndigoUI_Style_Guide#Colors
+		p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&tfMargin);
+		p->strokePath();
+	}
+}
+
+void PageItem::drawContourLine(ScPainter *p) const
+{
+	if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
+	{
+		p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&ContourLine);
+		p->strokePath();
+	}
+}
+
 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
 {
 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex - 1).points.copy();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26796)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -453,9 +453,9 @@
 	void SetQColor(QColor *tmp, const QString& farbe, double shad);
 	void DrawPolyL(QPainter *p, const QPolygon& pts);
 	FPointArray shape() const { return PoLine; }
-	void setShape(const FPointArray& val) { PoLine = val; }
+	void setShape(const FPointArray& val);
 	FPointArray contour() const { return ContourLine; }
-	void setContour(const FPointArray& val) { ContourLine = val; }
+	void setContour(const FPointArray& val);
 	bool flipPathText() const { return textPathFlipped; }
 	void setFlipPathText(bool val) { textPathFlipped = val; }
 	int pathTextType() const { return textPathType; }
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1533,6 +1539,8 @@
 	void DrawObj_PolyLine(ScPainter *p);
 	void DrawObj_PathText(ScPainter *p, double sc);
 	void drawLockedMarker(ScPainter *p) const;
+	void drawTextFlowPath(ScPainter *p) const;
+	void drawContourLine(ScPainter *p) const;
 	void drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex);
 
 	/** @brief Manages undostack and is where all undo actions/states are sent. */
@@ -1848,6 +1856,9 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
+	bool m_textFlowMarginsNeedUpdate {false};
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(Revision 26796)
+++ scribus/pageitem_textframe.cpp	(Arbeitskopie)
@@ -3587,6 +3587,7 @@
 	//#12405 if (isAnnotation() && ((annotation().Type() > 1) && (annotation().Type() < 7)) && (annotation().borderWidth() > 0))
 	//	return;
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -3608,13 +3609,10 @@
 			p->setupSharpPolygon(&PoLine);
 			p->strokePath();
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
 
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
Index: scribus/plugins/fileloader/scribus170format/scribus170format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format.cpp	(Arbeitskopie)
@@ -5842,8 +5842,12 @@
 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.fromString(attrs.valueAsString("TextFlowMargins", "0 0 0 0"));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
@@ -5851,7 +5855,7 @@
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
 	}
 	else
 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
Index: scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Revision 26796)
+++ scribus/plugins/fileloader/scribus170format/scribus170format_save.cpp	(Arbeitskopie)
@@ -2868,7 +2868,10 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowMargins", item->textFlowMargins().toString());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26796)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26796)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -74,57 +74,71 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed around the physical page" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	if (isSingleMode())
+		leftMarginLabel->setPixmap(im.loadPixmap("border-all"));
+	else
+		leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -308,10 +322,10 @@
 
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
@@ -318,34 +332,26 @@
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
 	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +392,32 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	// we have to avoid that the single mode changes all other values if link button is checked
+	if (isSingle)
+		marginLinkButton->setChecked(false);
+
+	iconSetChange();
+	languageChange(); // update tooltips
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	languageChange();
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26796)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -44,6 +44,9 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
 
 	public slots:
 		void languageChange();
@@ -66,6 +69,7 @@
 		MarginStruct m_savedMarginData;
 		QString m_pageSize;
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26796)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
+    <width>168</width>
     <height>182</height>
    </rect>
   </property>
@@ -35,40 +35,6 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
    <item row="1" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
@@ -120,8 +86,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="1" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +95,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +102,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +116,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Bottom</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,32 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QPushButton" name="printerMarginsPushButton">
-       <property name="text">
-        <string>Printer Margins...</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item row="2" column="3">
-    <widget class="FormWidget" name="bottomMarginLabel">
+   <item row="1" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -237,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Bottom</string>
+      <string>Left</string>
      </property>
      <property name="font">
       <font>
@@ -244,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_8">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -258,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -270,8 +212,66 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QPushButton" name="printerMarginsPushButton">
+       <property name="text">
+        <string>Printer Margins...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,7 +279,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -286,7 +286,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,7 +300,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -312,6 +312,19 @@
      </layout>
     </widget>
    </item>
+   <item row="1" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp	(Revision 26796)
+++ scribus/ui/nodeeditpalette.cpp	(Arbeitskopie)
@@ -370,7 +370,7 @@
 		UndoManager::instance()->action(currItem, is);
 	}
 	//FIXME make an internal item copy poline to contourline member
-	currItem->ContourLine = currItem->PoLine.copy();
+	currItem->setContour(currItem->PoLine.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -382,7 +382,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->ContourLine = currItem->imageClip.copy();
+	currItem->setContour(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -394,7 +394,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->PoLine = currItem->imageClip.copy();
+	currItem->setShape(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	currItem->FrameType = 3;
 	m_doc->adjustItemSize(currItem);
@@ -796,9 +796,9 @@
 		// relative to the current position (in the item's coordinate space).
 		// adjustItemSize will then take care of moving the position and changing
 		// image offsets, etc.
-		currItem->PoLine = m_itemPath.copy();
+		currItem->setShape(m_itemPath.copy());
 		currItem->PoLine.translate(delta.x(), delta.y());
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		m_doc->adjustItemSize(currItem);
 		if (currItem->itemType() == PageItem::PathText)
 			currItem->updatePolyClip();
@@ -828,15 +828,15 @@
 	QPointF delta = m.map(QPointF(m_xPos, m_yPos)) - m.map(QPointF(currItem->xPos(), currItem->yPos()));
 	if (EditCont->isChecked())
 	{
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		currItem->ContourLine.translate(delta.x(), delta.y());
 	}
 	else
 	{
 		// See comment in NodePalette::CancelEdit
-		currItem->PoLine = m_itemPath;
+		currItem->setShape(m_itemPath);
  		currItem->PoLine.translate(delta.x(), delta.y());
- 		currItem->ContourLine = m_itemContourPath;
+		currItem->setContour(m_itemContourPath);
 		m_doc->adjustItemSize(currItem);
 	}
 	if (currItem->itemType() == PageItem::PathText)
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26796)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,18 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +332,12 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +362,8 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
+
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +371,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -447,30 +475,57 @@
 	roundRect->blockSignals(b);
 	if (f == 0)
 		m_doc->setFrameRounded();
-	if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
-		return;
+	// if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
+	// 	return;
 	m_doc->invalidateAll();
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +556,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +568,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26796)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-22_01.patch (55,239 bytes)   

nitramr

2025-03-24 22:42

developer   ~0052334

New patch, read and write new text flow margin properties only to new file format 1.7.1.
Margin values are stored as separate attributes in sla file again.

Patch requires "border-all.svg" file from above.
textflow_2025-03-24_01.patch (56,130 bytes)   
Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml	(Revision 26796)
+++ resources/iconsets/1_7_0/1_7_0.xml	(Arbeitskopie)
@@ -367,6 +367,7 @@
 		<icon id="folder" file="16/file-open.svg" />
 				
 		<!-- Page & Layer -->
+		<icon id="border-all" file="16/border-all.svg" />
 		<icon id="border-bottom" file="16/border-bottom.svg" />
 		<icon id="border-inside" file="16/border-inside.svg" />
 		<icon id="border-left" file="16/border-left.svg" />
Index: scribus/margins.h
--- scribus/margins.h	(Revision 26800)
+++ scribus/margins.h	(Arbeitskopie)
@@ -42,12 +42,40 @@
 		inline void setRight(double aright) { m_right = aright; }
 		inline void setBottom(double abottom) { m_bottom = abottom; }
 
+		bool operator==(const MarginStruct &other) const
+		{
+			return ((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
+		bool operator!=(const MarginStruct& other) const
+		{
+			return !((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom));
+		}
 
+		void fromString(const QString &string)
+		{
+			resetToZero();
+			QStringList s = string.split(" ");
+			if (s.size() == 4) // l t r b
+				set(convert(s.at(1)), convert(s.at(0)), convert(s.at(3)), convert(s.at(2)));
+		}
+
+		QString toString() const
+		{
+			return QString("%0 %1 %2 %3").arg(QString::number(m_left)).arg(QString::number(m_top)).arg(QString::number(m_right)).arg(QString::number(m_bottom));
+		}
+
 	protected:
 		double m_top {0.0};
 		double m_left {0.0};
 		double m_bottom {0.0};
 		double m_right {0.0};
+
+		double convert(const QString& s)
+		{
+			bool ok(false);
+			double number = s.toDouble(&ok);
+			return ok ? number : 0.0;
+		}
 };
 
 class ScMargins : public QMarginsF
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26796)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,10 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
+
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -2388,6 +2387,29 @@
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setShape(const FPointArray &val)
+{
+	PoLine = val;
+
+	if (textFlowUsesFrameShape())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+
+}
+
+void PageItem::setContour(const FPointArray &val)
+{
+	ContourLine = val;
+
+	if (textFlowUsesContourLine())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
@@ -4443,31 +4465,39 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	if (m_textFlowMargins != distances)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		m_textFlowMargins = distances;
+		m_textFlowMarginsNeedUpdate = true;
 	}
-	m_textFlowMode = mode;
-	
-	checkTextFlowInteractions();
+
+	if (m_textFlowMode != mode)
+	{
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
+		m_textFlowMarginsNeedUpdate = true;
+	}
+
+	checkChanges();
 }
 
 void PageItem::checkTextFlowInteractions(bool allItems)
@@ -4597,7 +4627,7 @@
 	{
 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
 			(oldWidth != m_width || oldHeight != m_height) ||
-			(oldRot != m_rotation))
+			(oldRot != m_rotation || m_textFlowMarginsNeedUpdate))
 		{
 			textFlowCheckRect = getOldBoundingRect();
 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
@@ -4605,6 +4635,8 @@
 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
+			spreadChanges = true;
+			m_textFlowMarginsNeedUpdate = false;
 		}
 	}
 
@@ -4615,7 +4647,7 @@
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
 	}
 	// has the item been rotated
-	if (force || ((oldRot != m_rotation) && (shouldCheck())))
+	if (force || ((oldRot != m_rotation) && shouldCheck()))
 	{
 		rotateUndoAction();
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
@@ -9089,6 +9121,9 @@
 		PoLine.addPoint(x1, y1);
 		PoLine.addPoint(x2, y2);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = true;
 }
@@ -9149,6 +9184,9 @@
 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = false;
 	FrameType = 2;
@@ -9664,19 +9702,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
-	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+	QPainterPath pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
+	if (textFlowMode() == TextFlowDisabled)
+		return pathOut;
 
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9718,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9765,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9784,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.left() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9797,51 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.left() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	// TODO: nitramr: Replace QPainterPathStroker with a more performant path offset method.
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.left() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
@@ -10132,6 +10216,37 @@
 	p->drawLine(FPoint(bx1 + scp1 / 2, ofy + scp1), FPoint(bx1 + scp1 * 3.5, ofy + scp1));
 }
 
+void PageItem::drawTextFlowPath(ScPainter *p) const
+{
+	bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.bottom() > 0);
+	bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.left() > 0;
+
+	// Draw Text Flow Margin Path
+	if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+	{
+		QTransform tf;
+		tf.rotate(-m_rotation);
+		tf.translate(-m_xPos, -m_yPos);
+		QPainterPath qpp = tf.map(textFlowPath());
+		FPointArray tfMargin;
+		tfMargin.fromQPainterPath(qpp);
+		// Color: Scribus Blue 200, https://wiki.scribus.net/canvas/IndigoUI_Style_Guide#Colors
+		p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&tfMargin);
+		p->strokePath();
+	}
+}
+
+void PageItem::drawContourLine(ScPainter *p) const
+{
+	if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
+	{
+		p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&ContourLine);
+		p->strokePath();
+	}
+}
+
 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
 {
 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex - 1).points.copy();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26796)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -453,9 +453,9 @@
 	void SetQColor(QColor *tmp, const QString& farbe, double shad);
 	void DrawPolyL(QPainter *p, const QPolygon& pts);
 	FPointArray shape() const { return PoLine; }
-	void setShape(const FPointArray& val) { PoLine = val; }
+	void setShape(const FPointArray& val);
 	FPointArray contour() const { return ContourLine; }
-	void setContour(const FPointArray& val) { ContourLine = val; }
+	void setContour(const FPointArray& val);
 	bool flipPathText() const { return textPathFlipped; }
 	void setFlipPathText(bool val) { textPathFlipped = val; }
 	int pathTextType() const { return textPathType; }
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1533,6 +1539,8 @@
 	void DrawObj_PolyLine(ScPainter *p);
 	void DrawObj_PathText(ScPainter *p, double sc);
 	void drawLockedMarker(ScPainter *p) const;
+	void drawTextFlowPath(ScPainter *p) const;
+	void drawContourLine(ScPainter *p) const;
 	void drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex);
 
 	/** @brief Manages undostack and is where all undo actions/states are sent. */
@@ -1848,6 +1856,9 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
+	bool m_textFlowMarginsNeedUpdate {false};
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(Revision 26796)
+++ scribus/pageitem_textframe.cpp	(Arbeitskopie)
@@ -3587,6 +3587,7 @@
 	//#12405 if (isAnnotation() && ((annotation().Type() > 1) && (annotation().Type() < 7)) && (annotation().borderWidth() > 0))
 	//	return;
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -3608,13 +3609,10 @@
 			p->setupSharpPolygon(&PoLine);
 			p->strokePath();
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
 
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
Index: scribus/plugins/fileloader/scribus171format/scribus171format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format.cpp	(Revision 26812)
+++ scribus/plugins/fileloader/scribus171format/scribus171format.cpp	(Arbeitskopie)
@@ -6047,19 +6047,26 @@
 	currItem->BaseOffs = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.setLeft(attrs.valueAsDouble("TextFlowLeft", 0.0));
+	textFlowMargins.setTop(attrs.valueAsDouble("TextFlowTop", 0.0));
+	textFlowMargins.setRight(attrs.valueAsDouble("TextFlowRight", 0.0));
+	textFlowMargins.setBottom(attrs.valueAsDouble("TextFlowBottom", 0.0));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
-			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox);
+			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox, textFlowMargins);
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
-			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
+			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine, textFlowMargins);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape, textFlowMargins);
 	}
 	else
-		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
+		currItem->setTextFlowMode(PageItem::TextFlowDisabled, textFlowMargins);
 	currItem->setLocked (attrs.valueAsBool("LOCK", false));
 	currItem->setSizeLocked(attrs.valueAsBool("LOCKR", false));
 	currItem->fillRule = attrs.valueAsBool("fillRule", true);
Index: scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(Revision 26812)
+++ scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(Arbeitskopie)
@@ -2860,7 +2860,13 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowLeft", item->textFlowMargins().left());
+		docu.writeAttribute("TextFlowTop", item->textFlowMargins().top());
+		docu.writeAttribute("TextFlowRight", item->textFlowMargins().right());
+		docu.writeAttribute("TextFlowBottom", item->textFlowMargins().bottom());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26796)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26796)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -74,57 +74,71 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed around the physical page" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the left of the physical page" ) + "</qt>" );
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		if (isSingleMode())
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		else
+			leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	if (isSingleMode())
+		leftMarginLabel->setText( tr("Around"));
+	else
+		leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	if (isSingleMode())
+		leftMarginLabel->setPixmap(im.loadPixmap("border-all"));
+	else
+		leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -308,10 +322,10 @@
 
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
@@ -318,34 +332,26 @@
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
 	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +392,32 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	// we have to avoid that the single mode changes all other values if link button is checked
+	if (isSingle)
+		marginLinkButton->setChecked(false);
+
+	iconSetChange();
+	languageChange(); // update tooltips
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	languageChange();
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26796)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -44,6 +44,9 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
 
 	public slots:
 		void languageChange();
@@ -66,6 +69,7 @@
 		MarginStruct m_savedMarginData;
 		QString m_pageSize;
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26796)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,7 +6,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
+    <width>168</width>
     <height>182</height>
    </rect>
   </property>
@@ -35,40 +35,6 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
    <item row="1" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
@@ -120,8 +86,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="1" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +95,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +102,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +116,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Bottom</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_8">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,32 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout_4">
-     <item>
-      <widget class="QPushButton" name="printerMarginsPushButton">
-       <property name="text">
-        <string>Printer Margins...</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
-   </item>
-   <item row="2" column="3">
-    <widget class="FormWidget" name="bottomMarginLabel">
+   <item row="1" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -237,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Bottom</string>
+      <string>Left</string>
      </property>
      <property name="font">
       <font>
@@ -244,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_8">
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -258,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="bottomMarginSpinBox">
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -270,8 +212,66 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="4" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout_4">
+     <item>
+      <widget class="QPushButton" name="printerMarginsPushButton">
+       <property name="text">
+        <string>Printer Margins...</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,7 +279,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -286,7 +286,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,7 +300,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -312,6 +312,19 @@
      </layout>
     </widget>
    </item>
+   <item row="1" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
   </layout>
  </widget>
  <customwidgets>
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp	(Revision 26796)
+++ scribus/ui/nodeeditpalette.cpp	(Arbeitskopie)
@@ -370,7 +370,7 @@
 		UndoManager::instance()->action(currItem, is);
 	}
 	//FIXME make an internal item copy poline to contourline member
-	currItem->ContourLine = currItem->PoLine.copy();
+	currItem->setContour(currItem->PoLine.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -382,7 +382,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->ContourLine = currItem->imageClip.copy();
+	currItem->setContour(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -394,7 +394,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->PoLine = currItem->imageClip.copy();
+	currItem->setShape(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	currItem->FrameType = 3;
 	m_doc->adjustItemSize(currItem);
@@ -796,9 +796,9 @@
 		// relative to the current position (in the item's coordinate space).
 		// adjustItemSize will then take care of moving the position and changing
 		// image offsets, etc.
-		currItem->PoLine = m_itemPath.copy();
+		currItem->setShape(m_itemPath.copy());
 		currItem->PoLine.translate(delta.x(), delta.y());
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		m_doc->adjustItemSize(currItem);
 		if (currItem->itemType() == PageItem::PathText)
 			currItem->updatePolyClip();
@@ -828,15 +828,15 @@
 	QPointF delta = m.map(QPointF(m_xPos, m_yPos)) - m.map(QPointF(currItem->xPos(), currItem->yPos()));
 	if (EditCont->isChecked())
 	{
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		currItem->ContourLine.translate(delta.x(), delta.y());
 	}
 	else
 	{
 		// See comment in NodePalette::CancelEdit
-		currItem->PoLine = m_itemPath;
+		currItem->setShape(m_itemPath);
  		currItem->PoLine.translate(delta.x(), delta.y());
- 		currItem->ContourLine = m_itemContourPath;
+		currItem->setContour(m_itemContourPath);
 		m_doc->adjustItemSize(currItem);
 	}
 	if (currItem->itemType() == PageItem::PathText)
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26796)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,18 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +332,12 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +362,8 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
+
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +371,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -447,30 +475,57 @@
 	roundRect->blockSignals(b);
 	if (f == 0)
 		m_doc->setFrameRounded();
-	if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
-		return;
+	// if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
+	// 	return;
 	m_doc->invalidateAll();
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +556,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +568,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26796)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-24_01.patch (56,130 bytes)   

nitramr

2025-03-28 12:09

developer   ~0052356

New patch add new all value to margins object. The sla file v1.7.1 will save and read this value too.

Behavior changes:
- link button is enabled by default
- if link button is enabled, all 5 fields will synchronize on a value change.
- the "all" input will only change the other four if the link button is enabled too
textflow_2025-03-28_01.patch (67,564 bytes)   
Index: resources/iconsets/1_7_0/1_7_0.xml
===================================================================
--- resources/iconsets/1_7_0/1_7_0.xml	(Revision 26796)
+++ resources/iconsets/1_7_0/1_7_0.xml	(Arbeitskopie)
@@ -367,6 +367,7 @@
 		<icon id="folder" file="16/file-open.svg" />
 				
 		<!-- Page & Layer -->
+		<icon id="border-all" file="16/border-all.svg" />
 		<icon id="border-bottom" file="16/border-bottom.svg" />
 		<icon id="border-inside" file="16/border-inside.svg" />
 		<icon id="border-left" file="16/border-left.svg" />
Index: scribus/margins.h
===================================================================
--- scribus/margins.h	(Revision 26816)
+++ scribus/margins.h	(Arbeitskopie)
@@ -25,29 +25,60 @@
 {
 	public:
 		MarginStruct() {}
-		MarginStruct(double top, double left, double bottom, double right) :
-			m_top(top), m_left(left), m_bottom(bottom), m_right(right) {}
+		MarginStruct(double top, double left, double bottom, double right, double all = 0.0) :
+			m_top(top), m_left(left), m_bottom(bottom), m_right(right), m_all(all) {}
 
-		void set(double top, double left, double bottom, double right) { m_top = top; m_bottom = bottom; m_left = left; m_right = right; }
-		void resetToZero() { m_top = 0.0; m_bottom = 0.0; m_left = 0.0; m_right = 0.0; }
-		bool isNull() const {return qFuzzyIsNull(m_left) && qFuzzyIsNull(m_top) && qFuzzyIsNull(m_right) && qFuzzyIsNull(m_bottom);}
-		void print() const { qDebug() << m_top << m_left << m_bottom << m_right; }
+		void set(double top, double left, double bottom, double right, double all = 0.0) { m_top = top; m_bottom = bottom; m_left = left; m_right = right; m_all = all;}
+		void resetToZero() { m_top = 0.0; m_bottom = 0.0; m_left = 0.0; m_right = 0.0; m_all = 0.0; }
+		bool isNull() const {return qFuzzyIsNull(m_left) && qFuzzyIsNull(m_top) && qFuzzyIsNull(m_right) && qFuzzyIsNull(m_bottom) && qFuzzyIsNull(m_all);}
+		void print() const { qDebug() << m_top << m_left << m_bottom << m_right << m_all; }
 		inline double left() const { return m_left; }
 		inline double top() const { return m_top; }
 		inline double bottom() const { return m_bottom; }
 		inline double right() const { return m_right; }
+		inline double all() const { return m_all; }
 
 		inline void setLeft(double aleft) { m_left = aleft; }
 		inline void setTop(double atop) { m_top = atop; }
 		inline void setRight(double aright) { m_right = aright; }
 		inline void setBottom(double abottom) { m_bottom = abottom; }
+		inline void setAll(double aall) { m_all = aall; }
 
+		bool operator==(const MarginStruct &other) const
+		{
+			return ((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom) && (m_all == other.m_all));
+		}
+		bool operator!=(const MarginStruct& other) const
+		{
+			return !((m_left == other.m_left) && (m_top == other.m_top) && (m_right == other.m_right) && (m_bottom == other.m_bottom) && (m_all == other.m_all));
+		}
 
+		void fromString(const QString &string)
+		{
+			resetToZero();
+			QStringList s = string.split(" ");
+			if (s.size() == 5) // l t r b a
+				set(convert(s.at(1)), convert(s.at(0)), convert(s.at(3)), convert(s.at(2)), convert(s.at(4)));
+		}
+
+		QString toString() const
+		{
+			return QString("%0 %1 %2 %3 %4").arg(QString::number(m_left)).arg(QString::number(m_top)).arg(QString::number(m_right)).arg(QString::number(m_bottom)).arg(QString::number(m_all));
+		}
+
 	protected:
 		double m_top {0.0};
 		double m_left {0.0};
 		double m_bottom {0.0};
 		double m_right {0.0};
+		double m_all {0.0};
+
+		double convert(const QString& s)
+		{
+			bool ok(false);
+			double number = s.toDouble(&ok);
+			return ok ? number : 0.0;
+		}
 };
 
 class ScMargins : public QMarginsF
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp	(Revision 26796)
+++ scribus/pageitem.cpp	(Arbeitskopie)
@@ -1954,6 +1954,7 @@
 void PageItem::DrawObj_Decoration(ScPainter *p)
 {
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -1997,12 +1998,10 @@
 				p->strokePath();
 			}
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
+
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		if (itemType() == ImageFrame)
 		{
 			double minres = m_Doc->checkerProfiles()[m_Doc->curCheckProfile()].minResolution;
@@ -2388,6 +2387,29 @@
 	p->drawPolygon(pts.constData() + firstVal, pts.size() - firstVal);
 }
 
+void PageItem::setShape(const FPointArray &val)
+{
+	PoLine = val;
+
+	if (textFlowUsesFrameShape())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+
+}
+
+void PageItem::setContour(const FPointArray &val)
+{
+	ContourLine = val;
+
+	if (textFlowUsesContourLine())
+	{
+		m_textFlowMarginsNeedUpdate = true;
+		checkChanges();
+	}
+}
+
 void PageItem::setItemName(const QString& newName)
 {
 	if (m_itemName == newName || newName.isEmpty())
@@ -4443,31 +4465,39 @@
 	m_PrintEnabled=!m_PrintEnabled;
 }
 
-void PageItem::setTextFlowMode(TextFlowMode mode)
+void PageItem::setTextFlowMode(TextFlowMode mode, MarginStruct distances)
 {
-	if (m_textFlowMode == mode)
-		return;
-	if (UndoManager::undoEnabled())
+	if (m_textFlowMargins != distances)
 	{
-		QString stateMessage;
-		if (mode == TextFlowUsesFrameShape)
-			stateMessage = Um::ObjectFrame;
-		else if (mode == TextFlowUsesBoundingBox)
-			stateMessage = Um::BoundingBox;
-		else if (mode == TextFlowUsesContourLine)
-			stateMessage = Um::ContourLine;
-		else if (mode == TextFlowUsesImageClipping)
-			stateMessage = Um::ImageClip;
-		else
-			stateMessage = Um::NoTextFlow;
-		auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
-		ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
-		ss->set("TEXTFLOW_NEWMODE", (int) mode);
-		undoManager->action(this, ss);
+		m_textFlowMargins = distances;
+		m_textFlowMarginsNeedUpdate = true;
 	}
-	m_textFlowMode = mode;
-	
-	checkTextFlowInteractions();
+
+	if (m_textFlowMode != mode)
+	{
+		if (UndoManager::undoEnabled())
+		{
+			QString stateMessage;
+			if (mode == TextFlowUsesFrameShape)
+				stateMessage = Um::ObjectFrame;
+			else if (mode == TextFlowUsesBoundingBox)
+				stateMessage = Um::BoundingBox;
+			else if (mode == TextFlowUsesContourLine)
+				stateMessage = Um::ContourLine;
+			else if (mode == TextFlowUsesImageClipping)
+				stateMessage = Um::ImageClip;
+			else
+				stateMessage = Um::NoTextFlow;
+			auto *ss = new SimpleState(stateMessage, QString(), Um::IFont);
+			ss->set("TEXTFLOW_OLDMODE", (int) m_textFlowMode);
+			ss->set("TEXTFLOW_NEWMODE", (int) mode);
+			undoManager->action(this, ss);
+		}
+		m_textFlowMode = mode;
+		m_textFlowMarginsNeedUpdate = true;
+	}
+
+	checkChanges();
 }
 
 void PageItem::checkTextFlowInteractions(bool allItems)
@@ -4597,7 +4627,7 @@
 	{
 		if ((oldXpos  != m_xPos  || oldYpos != m_yPos) ||
 			(oldWidth != m_width || oldHeight != m_height) ||
-			(oldRot != m_rotation))
+			(oldRot != m_rotation || m_textFlowMarginsNeedUpdate))
 		{
 			textFlowCheckRect = getOldBoundingRect();
 			QRectF rect1 = textInteractionRegion(0.0, 0.0).boundingRect().adjusted(-1, -1, 1, 1);
@@ -4605,6 +4635,8 @@
 			rect2.setWidth(qMax(1.0, rect1.width() + oldWidth - m_width));
 			rect2.setHeight(qMax(1.0, rect1.height() + oldHeight - m_height));
 			textFlowCheckRect = textFlowCheckRect.united(rect1.united(rect2));
+			spreadChanges = true;
+			m_textFlowMarginsNeedUpdate = false;
 		}
 	}
 
@@ -4615,7 +4647,7 @@
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
 	}
 	// has the item been rotated
-	if (force || ((oldRot != m_rotation) && (shouldCheck())))
+	if (force || ((oldRot != m_rotation) && shouldCheck()))
 	{
 		rotateUndoAction();
 		spreadChanges = (textFlowMode() != TextFlowDisabled);
@@ -9089,6 +9121,9 @@
 		PoLine.addPoint(x1, y1);
 		PoLine.addPoint(x2, y2);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = true;
 }
@@ -9149,6 +9184,9 @@
 		PoLine.addQuadPoint(0, Height_rr, 0, Height_rr, 0, rr, 0, rr);
 		PoLine.addQuadPoint(0, rr, rrxBezierFactor, rr, rr, 0, rr, rr*bezierFactor);
 	}
+
+	setShape(PoLine);
+
 	Clip = flattenPath(PoLine, Segments);
 	ClipEdited = false;
 	FrameType = 2;
@@ -9664,19 +9702,14 @@
 	return arrowRect;
 }
 
-QRegion PageItem::textInteractionRegion(double xOffset, double yOffset) const
+QPainterPath PageItem::createTextFlowPath(double xOffset, double yOffset)
 {
-	QRegion res;
-	if (m_textFlowMode == TextFlowDisabled)
-		return res;
+	QPainterPath pathOut;
 
-	QTransform pp;
-	if (this->isGroupChild())
-		pp.translate(gXpos, gYpos);
-	else
-		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
-	pp.rotate(m_rotation);
+	if (textFlowMode() == TextFlowDisabled)
+		return pathOut;
 
+	// Bounding Box
 	if (textFlowUsesBoundingBox())
 	{
 		QRectF bb = getVisualBoundingRect();
@@ -9685,19 +9718,37 @@
 			bb.translate(-m_xPos, -m_yPos);
 			bb.translate(gXpos, gYpos);
 		}
-		res = QRegion(bb.toRect());
+
+		pathOut.addRect(bb.adjusted(-m_textFlowMargins.left(), -m_textFlowMargins.top(), m_textFlowMargins.right(), m_textFlowMargins.bottom()));
+		setTextFlowPath(pathOut);
+		return pathOut;
 	}
-	else if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
+
+	QPainterPath shape;
+	QPolygonF poly;
+	QTransform pp;
+	bool strokePath = false;
+
+	if (this->isGroupChild())
+		pp.translate(gXpos, gYpos);
+	else
+		pp.translate(m_xPos - xOffset, m_yPos - yOffset);
+
+	pp.rotate(m_rotation);
+
+	// Image Clipping Path
+	if ((textFlowUsesImageClipping()) && (!imageClip.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(imageClip, Segs);
-		res = QRegion(pp.map(Clip2)).intersected(QRegion(pp.map(Clip)));
+		shape = pp.map(imageClip.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
+	//Contour Line
 	else if ((textFlowUsesContourLine()) && (!ContourLine.empty()))
 	{
-		QList<uint> Segs;
-		QPolygon Clip2 = flattenPath(ContourLine, Segs);
-		res = QRegion(pp.map(Clip2));
+		shape = pp.map(ContourLine.toQPainterPath(true));
+		poly = shape.toFillPolygon();
+		strokePath = true;
 	}
 	else
 	{
@@ -9714,14 +9765,19 @@
 				pp.scale(1, -1);
 			}
 		}
+
+		poly = pp.map(Clip);
+
+		// Shape with Stroke
 		if ((((m_lineColor != CommonStrings::None) || (!patternStrokeVal.isEmpty()) || (GrTypeStroke > 0)) && (m_lineWidth > 1)) || (!NamedLStyle.isEmpty()))
 		{
 			QPainterPath ppa;
-			QPainterPath result;
+			// QPainterPath result;
 			if (itemType() == PageItem::PolyLine)
 				ppa = PoLine.toQPainterPath(false);
 			else
 				ppa = PoLine.toQPainterPath(true);
+
 			if (NamedLStyle.isEmpty())
 			{
 				QPainterPathStroker stroke;
@@ -9728,8 +9784,8 @@
 				stroke.setCapStyle(PLineEnd);
 				stroke.setJoinStyle(PLineJoin);
 				stroke.setDashPattern(Qt::SolidLine);
-				stroke.setWidth(m_lineWidth);
-				result = stroke.createStroke(ppa);
+				stroke.setWidth(m_lineWidth + m_textFlowMargins.all() * 2.0);
+				shape = pp.map(stroke.createStroke(ppa));
 			}
 			else
 			{
@@ -9741,23 +9797,51 @@
 					stroke.setCapStyle(static_cast<Qt::PenCapStyle>(ml[ind].LineEnd));
 					stroke.setJoinStyle(static_cast<Qt::PenJoinStyle>(ml[ind].LineJoin));
 					stroke.setDashPattern(Qt::SolidLine);
-					stroke.setWidth(ml[ind].Width);
-					result = stroke.createStroke(ppa);
+					stroke.setWidth(ml[ind].Width + m_textFlowMargins.all() * 2.0);
+					shape = pp.map(stroke.createStroke(ppa));
 				}
-			}
-			res = QRegion(pp.map(Clip));
-			QList<QPolygonF> pl = result.toSubpathPolygons();
-			for (int b = 0; b < pl.count(); b++)
-			{
-				res = res.united(QRegion(pp.map(pl[b].toPolygon())));
-			}
+			}			
 		}
+		// Shape without Stroke
 		else
-			res = QRegion(pp.map(Clip));
+		{
+			shape.addPolygon(poly);
+			shape.closeSubpath();
+
+			strokePath = true;
+		}
 	}
-	return  res;
+
+	// TODO: nitramr: Replace QPainterPathStroker with a more performant path offset method.
+	if (strokePath)
+	{
+		QPainterPathStroker stroke;
+		stroke.setWidth(m_textFlowMargins.all() * 2.0);
+		stroke.setJoinStyle(Qt::MiterJoin);
+		shape = stroke.createStroke(shape);
+	}
+
+	shape = shape.simplified();
+
+	QList<QPolygonF> pl = shape.toSubpathPolygons();
+	for (int b = 0; b < pl.count(); b++)
+	{
+		poly = poly.united(pl[b].toPolygon());
+	}
+
+	pathOut.addPolygon(poly);
+	pathOut = pathOut.simplified();
+
+	setTextFlowPath(pathOut);
+
+	return  pathOut;
 }
 
+QRegion PageItem::textInteractionRegion(double xOffset, double yOffset)
+{
+	return QRegion(createTextFlowPath(xOffset, yOffset).toFillPolygon().toPolygon());
+}
+
 bool PageItem::pointWithinItem(int x, const int y) const
 {
 	const_cast<PageItem*>(this)->setRedrawBounding();
@@ -10132,6 +10216,37 @@
 	p->drawLine(FPoint(bx1 + scp1 / 2, ofy + scp1), FPoint(bx1 + scp1 * 3.5, ofy + scp1));
 }
 
+void PageItem::drawTextFlowPath(ScPainter *p) const
+{
+	bool usesTextFlowBoundingBox = textFlowUsesBoundingBox() && (m_textFlowMargins.left() > 0 || m_textFlowMargins.top() > 0 || m_textFlowMargins.right() > 0 || m_textFlowMargins.bottom() > 0);
+	bool usesTextFlowAround = textFlowAroundObject() && m_textFlowMargins.all() > 0;
+
+	// Draw Text Flow Margin Path
+	if (m_Doc->guidesPrefs().framesShown && (usesTextFlowBoundingBox || usesTextFlowAround))
+	{
+		QTransform tf;
+		tf.rotate(-m_rotation);
+		tf.translate(-m_xPos, -m_yPos);
+		QPainterPath qpp = tf.map(textFlowPath());
+		FPointArray tfMargin;
+		tfMargin.fromQPainterPath(qpp);
+		// Color: Scribus Blue 200, https://wiki.scribus.net/canvas/IndigoUI_Style_Guide#Colors
+		p->setPen(QColor(168, 220, 248), 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&tfMargin);
+		p->strokePath();
+	}
+}
+
+void PageItem::drawContourLine(ScPainter *p) const
+{
+	if (m_Doc->guidesPrefs().framesShown && textFlowUsesContourLine() && (!ContourLine.empty()))
+	{
+		p->setPen(Qt::darkGray, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
+		p->setupSharpPolygon(&ContourLine);
+		p->strokePath();
+	}
+}
+
 void PageItem::drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex)
 {
 	FPointArray arrow = m_Doc->arrowStyles().at(arrowIndex - 1).points.copy();
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h	(Revision 26796)
+++ scribus/pageitem.h	(Arbeitskopie)
@@ -338,7 +338,7 @@
 	virtual QRectF getEndArrowBoundingRect() const;
 	virtual QRectF getEndArrowOldBoundingRect() const;
 
-	virtual QRegion textInteractionRegion(double xOffset, double yOffset) const;
+	virtual QRegion textInteractionRegion(double xOffset, double yOffset);
 
 	//>> ********* Functions related to drawing the item *********
 
@@ -453,9 +453,9 @@
 	void SetQColor(QColor *tmp, const QString& farbe, double shad);
 	void DrawPolyL(QPainter *p, const QPolygon& pts);
 	FPointArray shape() const { return PoLine; }
-	void setShape(const FPointArray& val) { PoLine = val; }
+	void setShape(const FPointArray& val);
 	FPointArray contour() const { return ContourLine; }
-	void setContour(const FPointArray& val) { ContourLine = val; }
+	void setContour(const FPointArray& val);
 	bool flipPathText() const { return textPathFlipped; }
 	void setFlipPathText(bool val) { textPathFlipped = val; }
 	int pathTextType() const { return textPathType; }
@@ -1117,8 +1117,14 @@
 	 * @param mode true if text is wanted to flow around this object or false if not
 	 * @sa textFlowMode()
 	 */
-	void setTextFlowMode(TextFlowMode mode);
+	void setTextFlowMode(TextFlowMode mode, MarginStruct distances = MarginStruct());
 
+	MarginStruct textFlowMargins() { return m_textFlowMargins; }
+	QPainterPath createTextFlowPath(double xOffset, double yOffset);
+
+	void setTextFlowPath(const QPainterPath path) { m_textFlowPath = path; }
+	QPainterPath textFlowPath() const { return m_textFlowPath; }
+
 	/**
 	 * @brief If text should flow around object frame
 	 * @sa PageItem::setTextFlowMode()
@@ -1533,6 +1539,8 @@
 	void DrawObj_PolyLine(ScPainter *p);
 	void DrawObj_PathText(ScPainter *p, double sc);
 	void drawLockedMarker(ScPainter *p) const;
+	void drawTextFlowPath(ScPainter *p) const;
+	void drawContourLine(ScPainter *p) const;
 	void drawArrow(ScPainter *p, QTransform &arrowTrans, int arrowIndex);
 
 	/** @brief Manages undostack and is where all undo actions/states are sent. */
@@ -1848,6 +1856,9 @@
 	 * @sa PageItem::textFlowMode(), PateItem::setTextFlowMode()
 	 */
 	TextFlowMode m_textFlowMode {TextFlowDisabled};
+	MarginStruct m_textFlowMargins;
+	QPainterPath m_textFlowPath;
+	bool m_textFlowMarginsNeedUpdate {false};
 
 	/**
 	 * @brief Stores the attributes of the pageitem (NOT properties, the user defined ATTRIBUTES)
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp	(Revision 26796)
+++ scribus/pageitem_textframe.cpp	(Arbeitskopie)
@@ -3587,6 +3587,7 @@
 	//#12405 if (isAnnotation() && ((annotation().Type() > 1) && (annotation().Type() < 7)) && (annotation().borderWidth() > 0))
 	//	return;
 	p->save();
+	p->setPenOpacity(1.0);
 //	p->setAntialiasing(false);
 	if (!isEmbedded)
 		p->translate(m_xPos, m_yPos);
@@ -3608,13 +3609,10 @@
 			p->setupSharpPolygon(&PoLine);
 			p->strokePath();
 		}
-		if ((m_Doc->guidesPrefs().framesShown) && textFlowUsesContourLine() && (!ContourLine.empty()))
-		{
-			p->setPen(Qt::darkGray, 0, Qt::DotLine, Qt::FlatCap, Qt::MiterJoin);
-			p->setupSharpPolygon(&ContourLine);
-			p->strokePath();
-		}
 
+		drawContourLine(p);
+		drawTextFlowPath(p);
+
 		//Draw the overflow icon
 		if (frameOverflows())
 		{
Index: scribus/plugins/fileloader/scribus171format/scribus171format.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format.cpp	(Revision 26812)
+++ scribus/plugins/fileloader/scribus171format/scribus171format.cpp	(Arbeitskopie)
@@ -6047,19 +6047,27 @@
 	currItem->BaseOffs = attrs.valueAsDouble("BASEOF", 0.0);
 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
+
+	MarginStruct textFlowMargins;
+	textFlowMargins.setLeft(attrs.valueAsDouble("TextFlowLeft", 0.0));
+	textFlowMargins.setTop(attrs.valueAsDouble("TextFlowTop", 0.0));
+	textFlowMargins.setRight(attrs.valueAsDouble("TextFlowRight", 0.0));
+	textFlowMargins.setBottom(attrs.valueAsDouble("TextFlowBottom", 0.0));
+	textFlowMargins.setAll(attrs.valueAsDouble("TextFlowAll", 0.0));
+
 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
-		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
+		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0), textFlowMargins);
 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
 	{
 		if (attrs.valueAsInt("TEXTFLOW2", 0))
-			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox);
+			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox, textFlowMargins);
 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
-			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
+			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine, textFlowMargins);
 		else
-			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);	
+			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape, textFlowMargins);
 	}
 	else
-		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
+		currItem->setTextFlowMode(PageItem::TextFlowDisabled, textFlowMargins);
 	currItem->setLocked (attrs.valueAsBool("LOCK", false));
 	currItem->setSizeLocked(attrs.valueAsBool("LOCKR", false));
 	currItem->fillRule = attrs.valueAsBool("fillRule", true);
Index: scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
===================================================================
--- scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(Revision 26812)
+++ scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp	(Arbeitskopie)
@@ -2860,7 +2860,14 @@
 		docu.writeAttribute("ANNAME", item->itemName());
 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
 	if (item->textFlowMode() != 0)
+	{
 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
+		docu.writeAttribute("TextFlowLeft", item->textFlowMargins().left());
+		docu.writeAttribute("TextFlowTop", item->textFlowMargins().top());
+		docu.writeAttribute("TextFlowRight", item->textFlowMargins().right());
+		docu.writeAttribute("TextFlowBottom", item->textFlowMargins().bottom());
+		docu.writeAttribute("TextFlowAll", item->textFlowMargins().all());
+	}
 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
 	// with versions prior to 1.3.4
 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp	(Revision 26796)
+++ scribus/scribus.cpp	(Arbeitskopie)
@@ -2723,7 +2723,7 @@
 		actionManager->setPDFActions(view);
 		updateItemLayerList();
 		rebuildScrapbookMenu();
-		propertiesPalette->setTextFlowMode(currItem->textFlowMode());
+		propertiesPalette->setTextFlowMode(currItem->textFlowMode(), currItem->textFlowMargins());
 	}
 
 	if (selectedType != -1)
Index: scribus/ui/newmarginwidget.cpp
===================================================================
--- scribus/ui/newmarginwidget.cpp	(Revision 26816)
+++ scribus/ui/newmarginwidget.cpp	(Arbeitskopie)
@@ -6,12 +6,13 @@
 */
 
 #include "newmarginwidget.h"
-#include "iconmanager.h"
+#include "iconmanager.h"
+#include "pagesize.h"
+#include "scribusapp.h"
 #include "scrspinbox.h"
-#include "units.h"
 #include "ui/marginpresetlayout.h"
 #include "ui/useprintermarginsdialog.h"
-#include "scribusapp.h"
+#include "units.h"
 
 NewMarginWidget::NewMarginWidget(QWidget* parent)
 	: QWidget(parent)
@@ -25,10 +26,13 @@
 	m_unitIndex = unitIndex;
 	m_unitRatio = unitGetRatioFromIndex(unitIndex);
 	m_flags = flags;
+	allMarginLabel->setVisible(false);
+	allMarginSpinBox->setMaximum(1000);
 	leftMarginSpinBox->setMaximum(1000);
 	rightMarginSpinBox->setMaximum(1000);
 	topMarginSpinBox->setMaximum(1000);
 	bottomMarginSpinBox->setMaximum(1000);
+	allMarginSpinBox->init(unitIndex);
 	leftMarginSpinBox->init(unitIndex);
 	rightMarginSpinBox->init(unitIndex);
 	topMarginSpinBox->init(unitIndex);
@@ -41,8 +45,8 @@
 		presetLayoutLabel->resize(0,0);
 		presetLayoutComboBox->hide();
 		presetLayoutLabel->hide();
-		horizontalLayout->removeWidget(presetLayoutComboBox);
-		horizontalLayout->removeWidget(presetLayoutLabel);
+		horizontalLayout->removeWidget(presetLayoutComboBox);
+		horizontalLayout->removeWidget(presetLayoutLabel);
 	}
 	if ((m_flags & ShowPrinterMargins) == 0)
 	{
@@ -49,16 +53,17 @@
 		printerMarginsPushButton->blockSignals(true);
 		printerMarginsPushButton->resize(0,0);
 		printerMarginsPushButton->hide();
-		horizontalLayout->removeWidget(printerMarginsPushButton);
+		horizontalLayout->removeWidget(printerMarginsPushButton);
 	}
 	setFacingPages(!(layoutType == singlePage));
 
 	languageChange();
-	iconSetChange();
-	toggleLabelVisibility(true);
+	iconSetChange();
+	toggleLabelVisibility(true);
 
-	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
-//	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
+	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
+//	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
+	connect(allMarginSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setAll()));
 	connect(topMarginSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setTop()));
 	connect(bottomMarginSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setBottom()));
 	connect(leftMarginSpinBox, SIGNAL(valueChanged(double)), this, SLOT(setLeft()));
@@ -74,11 +79,11 @@
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the top margin guide and the edge of the page" ) + "</qt>");
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the bottom margin guide and the edge of the page" ) + "</qt>");
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the left margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance between the right margin guide and the edge of the page. If a double-sided layout is selected, this margin space can be used to achieve the correct margins for binding.") + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all margins have the same value" ) + "</qt>");
 	}
-	else if (m_flags & BleedWidgetFlags)
+	else if (m_flags & BleedWidgetFlags)
 	{
 		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the top of the physical page" ) + "</qt>" );
 		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the bottom of the physical page" ) + "</qt>" );
@@ -86,45 +91,50 @@
 		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance for bleed from the right of the physical page" )  + "</qt>");
 		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all bleeds have the same value" ) + "</qt>");
 	}
-	else
-	{
-		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
-		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
-		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
-		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
-		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
-	}
+	else
+	{
+		topMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the top" ) + "</qt>" );
+		bottomMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the bottom" ) + "</qt>" );
+		allMarginSpinBox->setToolTip( "<qt>" + tr( "Distance around the object" ) + "</qt>" );
+		leftMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the left" ) + "</qt>" );
+		rightMarginSpinBox->setToolTip( "<qt>" + tr( "Distance from the right" )  + "</qt>");
+		marginLinkButton->setToolTip( "<qt>" + tr( "Ensure all distances have the same value" ) + "</qt>");
+	}
 	printerMarginsPushButton->setToolTip( "<qt>" + tr( "Import the margins for the selected page size from the available printers" ) + "</qt>");
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
+
+	allMarginLabel->setText( tr("Around"));
+	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
+	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
 }
 
-void NewMarginWidget::iconSetChange()
-{
-	IconManager &im = IconManager::instance();
-
-	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
-	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
-	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
-	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
-}
-
-void NewMarginWidget::toggleLabelVisibility(bool v)
-{
-	formWidget->setLabelVisibility(v);
-	leftMarginLabel->setLabelVisibility(v);
-	rightMarginLabel->setLabelVisibility(v);
-	topMarginLabel->setLabelVisibility(v);
-	bottomMarginLabel->setLabelVisibility(v);
-
-	leftMarginLabel->setIconVisibility(!v);
-	rightMarginLabel->setIconVisibility(!v);
-	topMarginLabel->setIconVisibility(!v);
-	bottomMarginLabel->setIconVisibility(!v);
-
-}
-
+void NewMarginWidget::iconSetChange()
+{
+	IconManager &im = IconManager::instance();
+
+	allMarginLabel->setPixmap(im.loadPixmap("border-all"));
+	leftMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-inside" : "border-left"));
+	rightMarginLabel->setPixmap(im.loadPixmap(m_facingPages ? "border-outside" : "border-right"));
+	topMarginLabel->setPixmap(im.loadPixmap("border-top"));
+	bottomMarginLabel->setPixmap(im.loadPixmap("border-bottom"));
+}
+
+void NewMarginWidget::toggleLabelVisibility(bool v)
+{
+	formWidget->setLabelVisibility(v);
+	leftMarginLabel->setLabelVisibility(v);
+	rightMarginLabel->setLabelVisibility(v);
+	topMarginLabel->setLabelVisibility(v);
+	bottomMarginLabel->setLabelVisibility(v);
+	allMarginLabel->setLabelVisibility(v);
+
+	leftMarginLabel->setIconVisibility(!v);
+	rightMarginLabel->setIconVisibility(!v);
+	topMarginLabel->setIconVisibility(!v);
+	bottomMarginLabel->setIconVisibility(!v);
+	allMarginLabel->setIconVisibility(!v);
+
+}
+
 void NewMarginWidget::setNewValues(const MarginStruct& margs)
 {
 	m_marginData = m_savedMarginData = margs;
@@ -133,105 +143,122 @@
 
 void NewMarginWidget::setPageWidth(double newWidth)
 {
-	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-	// {
-		leftMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - rightMarginSpinBox->value()));
-		rightMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - leftMarginSpinBox->value()));
-//	}
+	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+	// {
+		leftMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - rightMarginSpinBox->value()));
+		rightMarginSpinBox->setMaximum(qMax(0.0, newWidth * m_unitRatio - leftMarginSpinBox->value()));
+//	}
 	m_pageWidth = newWidth;
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setPageHeight(double newHeight)
 {
-	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-	// {
-		topMarginSpinBox->setMaximum(qMax(0.0, newHeight * m_unitRatio - bottomMarginSpinBox->value()));
-		bottomMarginSpinBox->setMaximum(qMax(0.0,newHeight * m_unitRatio - topMarginSpinBox->value()));
-//	}
+	// if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+	// {
+		topMarginSpinBox->setMaximum(qMax(0.0, newHeight * m_unitRatio - bottomMarginSpinBox->value()));
+		bottomMarginSpinBox->setMaximum(qMax(0.0,newHeight * m_unitRatio - topMarginSpinBox->value()));
+//	}
 	m_pageHeight = newHeight;
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
+void NewMarginWidget::setAll()
+{
+	double newVal = allMarginSpinBox->value() / m_unitRatio;
+
+	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
+	{
+		m_marginData.set(newVal, newVal, newVal, newVal, newVal);
+		updateMarginSpinValues();
+	}
+	else
+		m_marginData.setAll(newVal);
+
+	emit valuesChanged(m_marginData);
+}
+
 void NewMarginWidget::setTop()
 {
 	double newVal = topMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		bottomMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - topMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		bottomMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - topMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
-		m_marginData.set(newVal, newVal, newVal, newVal);
+		m_marginData.set(newVal, newVal, newVal, newVal, newVal);
 		updateMarginSpinValues();
 	}
 	else
 		m_marginData.setTop(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setBottom()
 {
 	double newVal = bottomMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		topMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - bottomMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		topMarginSpinBox->setMaximum(qMax(0.0, m_pageHeight * m_unitRatio - bottomMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
-		m_marginData.set(newVal, newVal, newVal, newVal);
+		m_marginData.set(newVal, newVal, newVal, newVal, newVal);
 		updateMarginSpinValues();
 	}
 	else
 		m_marginData.setBottom(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setLeft()
 {
 	double newVal = leftMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		rightMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - leftMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		rightMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - leftMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
-		m_marginData.set(newVal, newVal, newVal, newVal);
+		m_marginData.set(newVal, newVal, newVal, newVal, newVal);
 		updateMarginSpinValues();
 	}
 	else
 		m_marginData.setLeft(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setRight()
 {
 	double newVal = rightMarginSpinBox->value() / m_unitRatio;
-//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
-		leftMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - rightMarginSpinBox->value()));
+//	if ((m_flags & MarginWidgetFlags) == 0 || (m_flags & BleedWidgetFlags) == 0)
+		leftMarginSpinBox->setMaximum(qMax(0.0, m_pageWidth * m_unitRatio - rightMarginSpinBox->value()));
 	if (marginLinkButton->isChecked() && m_savedPresetItem == PresetLayout::none)
 	{
-		m_marginData.set(newVal, newVal, newVal, newVal);
+		m_marginData.set(newVal, newVal, newVal, newVal, newVal);
 		updateMarginSpinValues();
 	}
 	else
 		m_marginData.setRight(newVal);
 	setPreset();
-	emit valuesChanged(m_marginData);
-
+	emit valuesChanged(m_marginData);
+
 }
 
 void NewMarginWidget::setNewUnit(int newUnitIndex)
 {
-	bool leftSigBlocked   = leftMarginSpinBox->blockSignals(true);
-	bool rightSigBlocked  = rightMarginSpinBox->blockSignals(true);
-	bool topSigBlocked    = topMarginSpinBox->blockSignals(true);
-	bool bottomSigBlocked = bottomMarginSpinBox->blockSignals(true);
 
+	QSignalBlocker sigAll(allMarginSpinBox);
+	QSignalBlocker sigLeft(leftMarginSpinBox);
+	QSignalBlocker sigTop(topMarginSpinBox);
+	QSignalBlocker sigRight(rightMarginSpinBox);
+	QSignalBlocker sigBottom(bottomMarginSpinBox);
+
 	m_unitIndex = newUnitIndex;
 	m_unitRatio = unitGetRatioFromIndex(newUnitIndex);
 	topMarginSpinBox->setNewUnit(newUnitIndex);
@@ -238,11 +265,8 @@
 	bottomMarginSpinBox->setNewUnit(newUnitIndex);
 	leftMarginSpinBox->setNewUnit(newUnitIndex);
 	rightMarginSpinBox->setNewUnit(newUnitIndex);
+	allMarginSpinBox->setNewUnit(newUnitIndex);
 
-	leftMarginSpinBox->blockSignals(leftSigBlocked);
-	rightMarginSpinBox->blockSignals(rightSigBlocked);
-	topMarginSpinBox->blockSignals(topSigBlocked);
-	bottomMarginSpinBox->blockSignals(bottomSigBlocked);
 }
 
 void NewMarginWidget::setPreset()
@@ -296,56 +320,44 @@
 	topMarginSpinBox->blockSignals(false);
 	bottomMarginSpinBox->blockSignals(false);
 	m_savedPresetItem = item;
-
-	emit marginChanged(m_marginData);
-}
 
-void NewMarginWidget::setPageSize(const QString& pageSize)
-{
-	m_pageSize = pageSize;
+	emit marginChanged(m_marginData);
 }
 
-
 void NewMarginWidget::updateMarginSpinValues()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
+	QSignalBlocker allBlocked(allMarginSpinBox);
 
 	topMarginSpinBox->setValue(m_marginData.top() * m_unitRatio);
 	rightMarginSpinBox->setValue(m_marginData.right() * m_unitRatio);
 	bottomMarginSpinBox->setValue(m_marginData.bottom() * m_unitRatio);
-	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);
+	leftMarginSpinBox->setValue(m_marginData.left() * m_unitRatio);	
+	allMarginSpinBox->setValue(m_marginData.all() * m_unitRatio);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
 }
 
 void NewMarginWidget::slotLinkMargins()
 {
-	bool leftBlocked = leftMarginSpinBox->blockSignals(true);
-	bool rightBlocked = rightMarginSpinBox->blockSignals(true);
-	bool topBlocked = topMarginSpinBox->blockSignals(true);
-	bool bottomBlocked = bottomMarginSpinBox->blockSignals(true);
+	if (!marginLinkButton->isChecked())
+		return;
 
-	if (marginLinkButton->isChecked())
-	{
-		bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
-		topMarginSpinBox->setValue(leftMarginSpinBox->value());
-		rightMarginSpinBox->setValue(leftMarginSpinBox->value());
-		double newVal = leftMarginSpinBox->value() / m_unitRatio;
-		m_marginData.set(newVal, newVal, newVal, newVal);
-
-		emit marginChanged(m_marginData);
-	}
+	QSignalBlocker leftBlocked(leftMarginSpinBox);
+	QSignalBlocker rightBlocked(rightMarginSpinBox);
+	QSignalBlocker topBlocked(topMarginSpinBox);
+	QSignalBlocker bottomBlocked(bottomMarginSpinBox);
 
-	leftMarginSpinBox->blockSignals(leftBlocked);
-	rightMarginSpinBox->blockSignals(rightBlocked);
-	topMarginSpinBox->blockSignals(topBlocked);
-	bottomMarginSpinBox->blockSignals(bottomBlocked);
+	bottomMarginSpinBox->setValue(leftMarginSpinBox->value());
+	topMarginSpinBox->setValue(leftMarginSpinBox->value());
+	rightMarginSpinBox->setValue(leftMarginSpinBox->value());
+	double newVal = leftMarginSpinBox->value() / m_unitRatio;
+	m_marginData.set(newVal, newVal, newVal, newVal, newVal);
+
+	emit marginChanged(m_marginData);
+	emit valuesChanged(m_marginData);
 }
 
 void NewMarginWidget::setMarginPreset(int p)
@@ -386,15 +398,40 @@
 	presetLayoutComboBox->blockSignals(false);
 }
 
+void NewMarginWidget::setSingleMode(bool isSingle)
+{
+	// Single mode only for modes other than margin and bleed
+	if ((m_flags & MarginWidgetFlags) || (m_flags & BleedWidgetFlags))
+		return;
+
+	m_isSingle = isSingle;
+
+	QSignalBlocker blocker(this);
+
+	allMarginLabel->setVisible(isSingle);
+
+	leftMarginLabel->setVisible(!isSingle);
+	topMarginLabel->setVisible(!isSingle);
+	rightMarginLabel->setVisible(!isSingle);
+	bottomMarginLabel->setVisible(!isSingle);
+	formWidget->setVisible(!isSingle);
+
+	iconSetChange();
+	languageChange(); // update tooltips
+}
+
+void NewMarginWidget::setLinkValues(bool link)
+{
+	marginLinkButton->setChecked(link);
+}
+
 void NewMarginWidget::setFacingPages(bool facing, int pageType)
 {
 	m_facingPages = facing;
 	m_pageType = pageType;
-
-	leftMarginLabel->setText( m_facingPages ? tr("Inside") : tr("Left"));
-	rightMarginLabel->setText( m_facingPages ? tr("Outside") : tr("Right"));
-
-	iconSetChange();
+
+	languageChange();
+	iconSetChange();
 	setPreset();
 }
 
Index: scribus/ui/newmarginwidget.h
===================================================================
--- scribus/ui/newmarginwidget.h	(Revision 26816)
+++ scribus/ui/newmarginwidget.h	(Arbeitskopie)
@@ -36,8 +36,6 @@
 		void setPageWidth(double);
 		/*! \brief Setup the spinboxes properties (min/max value etc.) by height */
 		void setPageHeight(double);
-		/*! \brief Set the page size for margin getting from cups */
-		void setPageSize(const QString&);
 		void setNewUnit(int unitIndex);
 		void setNewValues(const MarginStruct& margs);
 		/*! \brief Setup the presetCombo without changing the margin values, only used by tabdocument */
@@ -44,11 +42,21 @@
 		void setMarginPreset(int p);
 		int marginPreset() { return m_savedPresetItem; };
 		const MarginStruct & margins() const { return m_marginData; };
+		/*! \brief Switch 4 inputs to 1*/
+		void setSingleMode(bool isSingle);
+		bool isSingleMode() { return m_isSingle; };
+		/*! \brief Link input fields*/
+		void setLinkValues(bool link);
+		bool linkValues() { return marginLinkButton->isChecked(); }
 
 	public slots:
 		void languageChange();
 		void iconSetChange();
 		void toggleLabelVisibility(bool v);
+
+	protected slots:
+		void setMarginsToPrinterMargins();
+		void setAll();
 		void setTop();
 		void setBottom();
 		void setLeft();
@@ -56,16 +64,14 @@
 		void slotLinkMargins();
 		void setPreset();
 
-	protected slots:
-		void setMarginsToPrinterMargins();
-
 	protected:
 		void updateMarginSpinValues();
 
 		MarginStruct m_marginData;
 		MarginStruct m_savedMarginData;
-		QString m_pageSize;
+
 		bool   m_facingPages {false};
+		bool   m_isSingle {false};
 		double m_pageHeight {0.0};
 		double m_pageWidth {0.0};
 		double m_unitRatio {1.0};
Index: scribus/ui/newmarginwidgetbase.ui
===================================================================
--- scribus/ui/newmarginwidgetbase.ui	(Revision 26816)
+++ scribus/ui/newmarginwidgetbase.ui	(Arbeitskopie)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>164</width>
-    <height>182</height>
+    <width>168</width>
+    <height>238</height>
    </rect>
   </property>
   <property name="sizePolicy">
@@ -35,41 +35,49 @@
    <property name="verticalSpacing">
     <number>8</number>
    </property>
-   <item row="0" column="1" colspan="3">
-    <layout class="QHBoxLayout" name="horizontalLayout">
-     <item>
-      <widget class="QLabel" name="presetLayoutLabel">
-       <property name="text">
-        <string>Preset:</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="PresetLayout" name="presetLayoutComboBox">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <spacer name="horizontalSpacer_5">
-       <property name="orientation">
-        <enum>Qt::Orientation::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>0</width>
-         <height>0</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
+   <item row="2" column="1">
+    <widget class="FormWidget" name="leftMarginLabel">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="label" stdset="0">
+      <string>Left</string>
+     </property>
+     <property name="font">
+      <font>
+       <pointsize>8</pointsize>
+      </font>
+     </property>
+     <layout class="QHBoxLayout" name="horizontalLayout_5">
+      <property name="leftMargin">
+       <number>0</number>
+      </property>
+      <property name="topMargin">
+       <number>0</number>
+      </property>
+      <property name="rightMargin">
+       <number>0</number>
+      </property>
+      <property name="bottomMargin">
+       <number>0</number>
+      </property>
+      <item>
+       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+        <property name="sizePolicy">
+         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+          <horstretch>0</horstretch>
+          <verstretch>0</verstretch>
+         </sizepolicy>
+        </property>
+       </widget>
+      </item>
+     </layout>
+    </widget>
    </item>
-   <item row="1" column="2" rowspan="2">
+   <item row="2" column="2" rowspan="2">
     <widget class="FormWidget" name="formWidget">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
@@ -120,8 +128,8 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="FormWidget" name="leftMarginLabel">
+   <item row="3" column="1">
+    <widget class="FormWidget" name="topMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -129,7 +137,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Left</string>
+      <string>Top</string>
      </property>
      <property name="font">
       <font>
@@ -136,7 +144,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_5">
+     <layout class="QHBoxLayout" name="horizontalLayout_3">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -150,7 +158,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="leftMarginSpinBox">
+       <widget class="ScrSpinBox" name="topMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -162,8 +170,8 @@
      </layout>
     </widget>
    </item>
-   <item row="2" column="1">
-    <widget class="FormWidget" name="topMarginLabel">
+   <item row="2" column="3">
+    <widget class="FormWidget" name="rightMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -171,7 +179,7 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Top</string>
+      <string>Right</string>
      </property>
      <property name="font">
       <font>
@@ -178,7 +186,7 @@
        <pointsize>8</pointsize>
       </font>
      </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_3">
+     <layout class="QHBoxLayout" name="horizontalLayout_6">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -192,7 +200,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="topMarginSpinBox">
+       <widget class="ScrSpinBox" name="rightMarginSpinBox">
         <property name="sizePolicy">
          <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
           <horstretch>0</horstretch>
@@ -204,7 +212,7 @@
      </layout>
     </widget>
    </item>
-   <item row="4" column="1" colspan="3">
+   <item row="5" column="1" colspan="3">
     <layout class="QHBoxLayout" name="horizontalLayout_4">
      <item>
       <widget class="QPushButton" name="printerMarginsPushButton">
@@ -228,7 +236,7 @@
      </item>
     </layout>
    </item>
-   <item row="2" column="3">
+   <item row="3" column="3">
     <widget class="FormWidget" name="bottomMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
@@ -270,8 +278,55 @@
      </layout>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="FormWidget" name="rightMarginLabel">
+   <item row="2" column="4">
+    <spacer name="horizontalSpacer_2">
+     <property name="orientation">
+      <enum>Qt::Orientation::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>0</width>
+       <height>0</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="0" column="1" colspan="3">
+    <layout class="QHBoxLayout" name="horizontalLayout">
+     <item>
+      <widget class="QLabel" name="presetLayoutLabel">
+       <property name="text">
+        <string>Preset:</string>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="PresetLayout" name="presetLayoutComboBox">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_5">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item row="1" column="1">
+    <widget class="FormWidget" name="allMarginLabel">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
        <horstretch>0</horstretch>
@@ -279,14 +334,9 @@
       </sizepolicy>
      </property>
      <property name="label" stdset="0">
-      <string>Right</string>
+      <string>Around</string>
      </property>
-     <property name="font">
-      <font>
-       <pointsize>8</pointsize>
-      </font>
-     </property>
-     <layout class="QHBoxLayout" name="horizontalLayout_6">
+     <layout class="QHBoxLayout" name="horizontalLayout_7">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -300,14 +350,7 @@
        <number>0</number>
       </property>
       <item>
-       <widget class="ScrSpinBox" name="rightMarginSpinBox">
-        <property name="sizePolicy">
-         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-          <horstretch>0</horstretch>
-          <verstretch>0</verstretch>
-         </sizepolicy>
-        </property>
-       </widget>
+       <widget class="ScrSpinBox" name="allMarginSpinBox"/>
       </item>
      </layout>
     </widget>
Index: scribus/ui/nodeeditpalette.cpp
===================================================================
--- scribus/ui/nodeeditpalette.cpp	(Revision 26796)
+++ scribus/ui/nodeeditpalette.cpp	(Arbeitskopie)
@@ -370,7 +370,7 @@
 		UndoManager::instance()->action(currItem, is);
 	}
 	//FIXME make an internal item copy poline to contourline member
-	currItem->ContourLine = currItem->PoLine.copy();
+	currItem->setContour(currItem->PoLine.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -382,7 +382,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->ContourLine = currItem->imageClip.copy();
+	currItem->setContour(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	m_doc->regionsChanged()->update(QRectF());
 	emit DocChanged();
@@ -394,7 +394,7 @@
 		return;
 
 	PageItem *currItem = m_doc->m_Selection->itemAt(0);
-	currItem->PoLine = currItem->imageClip.copy();
+	currItem->setShape(currItem->imageClip.copy());
 	currItem->ClipEdited = true;
 	currItem->FrameType = 3;
 	m_doc->adjustItemSize(currItem);
@@ -796,9 +796,9 @@
 		// relative to the current position (in the item's coordinate space).
 		// adjustItemSize will then take care of moving the position and changing
 		// image offsets, etc.
-		currItem->PoLine = m_itemPath.copy();
+		currItem->setShape(m_itemPath.copy());
 		currItem->PoLine.translate(delta.x(), delta.y());
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		m_doc->adjustItemSize(currItem);
 		if (currItem->itemType() == PageItem::PathText)
 			currItem->updatePolyClip();
@@ -828,15 +828,15 @@
 	QPointF delta = m.map(QPointF(m_xPos, m_yPos)) - m.map(QPointF(currItem->xPos(), currItem->yPos()));
 	if (EditCont->isChecked())
 	{
-		currItem->ContourLine = m_itemContourPath.copy();
+		currItem->setContour(m_itemContourPath.copy());
 		currItem->ContourLine.translate(delta.x(), delta.y());
 	}
 	else
 	{
 		// See comment in NodePalette::CancelEdit
-		currItem->PoLine = m_itemPath;
+		currItem->setShape(m_itemPath);
  		currItem->PoLine.translate(delta.x(), delta.y());
- 		currItem->ContourLine = m_itemContourPath;
+		currItem->setContour(m_itemContourPath);
 		m_doc->adjustItemSize(currItem);
 	}
 	if (currItem->itemType() == PageItem::PathText)
Index: scribus/ui/propertiespalette.cpp
===================================================================
--- scribus/ui/propertiespalette.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette.cpp	(Arbeitskopie)
@@ -243,11 +243,11 @@
 	handleSelectionChanged();
 }
 
-void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette::setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
-	shapePal->showTextFlowMode(mode);
+	shapePal->showTextFlowMode(mode, distances);
 }
 
 PageItem* PropertiesPalette::currentItemFromSelection()
@@ -307,7 +307,7 @@
 	m_haveItem = false;
 	m_item = item;
 
-	setTextFlowMode(m_item->textFlowMode());
+	setTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 
 //CB replaces old emits from PageItem::emitAllToGUI()
 	setLocked(item->locked());
Index: scribus/ui/propertiespalette.h
===================================================================
--- scribus/ui/propertiespalette.h	(Revision 26796)
+++ scribus/ui/propertiespalette.h	(Arbeitskopie)
@@ -62,7 +62,7 @@
 //	void updateColorSpecialGradient();
 	void updateColorList();
 	void setGradientEditMode(bool);
-	void setTextFlowMode(PageItem::TextFlowMode mode);
+	void setTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 	/** @brief Returns true if there is a user action going on at the moment of call. */
 	bool userActionOn(); // not yet implemented!!! This is needed badly.
Index: scribus/ui/propertiespalette_line.cpp
===================================================================
--- scribus/ui/propertiespalette_line.cpp	(Revision 26796)
+++ scribus/ui/propertiespalette_line.cpp	(Arbeitskopie)
@@ -674,8 +674,11 @@
 		return;
 	bool setter = (c == 0);
 	m_doc->itemSelection_SetNamedLineStyle(setter ? QString("") : comboLineStyle->currentText());
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
 	buttonLineStyleEdit->setEnabled(comboLineStyle->currentIndex() != 0);
+
 }
 
 void PropertiesPalette_Line::handleLineStyleNew()
@@ -757,7 +760,6 @@
 
 		m_item->setStrokeGradientExtend(buttonLineColor->gradientData().repeatMethod);
 		m_item->update();
-		m_doc->regionsChanged()->update(QRect());
 
 		break;
 	case Mode::Hatch:
@@ -782,9 +784,9 @@
 	}
 
 	m_doc->itemSelection_SetOverprint(buttonLineColor->generalData().overprint);
+	m_doc->invalidateAll();
+	m_doc->regionsChanged()->update(QRect());
 
-	//	m_item->update();
-	//	m_doc->regionsChanged()->update(QRect());
 	blockUpdates(false);
 
 }
Index: scribus/ui/propertiespalette_shape.cpp
===================================================================
--- scribus/ui/propertiespalette_shape.cpp	(Revision 26816)
+++ scribus/ui/propertiespalette_shape.cpp	(Arbeitskopie)
@@ -38,11 +38,19 @@
 	iconSetChange();
 	languageChange();
 
+	MarginStruct distances;
+	distances.resetToZero();
+
+	textFlowMargins->setup(distances, 0, m_unitIndex, NewMarginWidget::DistanceWidgetFlags);
+	textFlowMargins->toggleLabelVisibility(false);
+	textFlowMargins->setLinkValues(true);
+
 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
 	connect(ScQApp, SIGNAL(localeChanged()), this, SLOT(localeChange()));
 	connect(ScQApp, SIGNAL(labelVisibilityChanged(bool)), this, SLOT(toggleLabelVisibility(bool)));
 
 	connect(textFlowBtnGroup, SIGNAL(idClicked(int)), this, SLOT(handleTextFlow()));
+	connect(textFlowMargins, SIGNAL(valuesChanged(MarginStruct)), this, SLOT(handleTextFlow()));
 	connect(editShape, SIGNAL(clicked()) , this, SLOT(handleShapeEdit()));
 	connect(roundRect, SIGNAL(valueChanged(double)) , this, SLOT(handleCornerRadius()));
 	connect(customShape, SIGNAL(FormSel(int,int,qreal*)), this, SLOT(handleNewShape(int,int,qreal*)));
@@ -325,13 +333,12 @@
 		customShape->setIcon(customShape->getIconPixmap(m_item->FrameType-2));
 
 	roundRect->setValue(m_item->cornerRadius()*m_unitRatio);
-	showTextFlowMode(m_item->textFlowMode());
 	setLocked(m_item->locked());
 	setSizeLocked(m_item->sizeLocked());
 
 	// Frame type 3 is obsolete: CR 2005-02-06
 	//if (((i->itemType() == PageItem::TextFrame) || (i->itemType() == PageItem::ImageFrame) || (i->itemType() == 3)) &&  (!i->ClipEdited))
-	if (((m_item->isTextFrame()) || (m_item->isImageFrame())) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
+	if ((m_item->isTextFrame() || m_item->isImageFrame()) &&  (!m_item->ClipEdited) && ((m_item->FrameType == 0) || (m_item->FrameType == 2)))
 		roundRect->setEnabled(true);
 	else
 	{
@@ -356,7 +363,8 @@
 		customShape->setEnabled(false);
 	}
 	m_haveItem = true;
-	showTextFlowMode(m_item->textFlowMode());
+
+	showTextFlowMode(m_item->textFlowMode(), m_item->textFlowMargins());
 }
 
 void PropertiesPalette_Shape::handleTextFlow()
@@ -364,17 +372,38 @@
 	PageItem::TextFlowMode mode = PageItem::TextFlowDisabled;
 	if (!m_haveDoc || !m_haveItem || !m_ScMW || m_ScMW->scriptIsRunning())
 		return;
+
 	if (textFlowDisabled->isChecked())
+	{
 		mode = PageItem::TextFlowDisabled;
-	if (textFlowUsesFrameShape->isChecked())
+		textFlowMargins->setVisible(false);
+	}
+	else if (textFlowUsesFrameShape->isChecked())
+	{
 		mode = PageItem::TextFlowUsesFrameShape;
-	if (textFlowUsesBoundingBox->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesBoundingBox->isChecked())
+	{
 		mode = PageItem::TextFlowUsesBoundingBox;
-	if (textFlowUsesContourLine->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
+	else if (textFlowUsesContourLine->isChecked())
+	{
 		mode = PageItem::TextFlowUsesContourLine;
-	if (textFlowUsesImageClipping->isChecked())
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+	else if (textFlowUsesImageClipping->isChecked())
+	{
 		mode = PageItem::TextFlowUsesImageClipping;
-	m_item->setTextFlowMode(mode);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
+	m_item->setTextFlowMode(mode, textFlowMargins->margins());
 	m_doc->changed();
 	m_doc->changedPagePreview();
 	m_doc->invalidateAll();
@@ -447,30 +476,57 @@
 	roundRect->blockSignals(b);
 	if (f == 0)
 		m_doc->setFrameRounded();
-	if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
-		return;
+	// if ((m_item->itemType() == PageItem::ImageFrame) || (m_item->itemType() == PageItem::TextFrame))
+	// 	return;
 	m_doc->invalidateAll();
 	m_doc->regionsChanged()->update(QRect());
 }
 
-void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode)
+void PropertiesPalette_Shape::showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances)
 {
 	if (!m_ScMW || m_ScMW->scriptIsRunning() || !m_haveItem)
 		return;
+
+	QSignalBlocker textFlowMarginsBlocker(textFlowMargins);
+	textFlowMargins->setPageHeight(2000);
+	textFlowMargins->setPageWidth(2000);
+	textFlowMargins->setNewValues(distances);
+
 	if (mode == PageItem::TextFlowDisabled)
+	{
 		textFlowDisabled->setChecked(true);
+		textFlowMargins->setVisible(false);
+	}
 	else if (mode == PageItem::TextFlowUsesFrameShape)
+	{
 		textFlowUsesFrameShape->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesBoundingBox)
+	{
 		textFlowUsesBoundingBox->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(false);
+	}
 	else if (mode == PageItem::TextFlowUsesContourLine)
+	{
 		textFlowUsesContourLine->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
 	else if (mode == PageItem::TextFlowUsesImageClipping)
+	{
 		textFlowUsesImageClipping->setChecked(true);
+		textFlowMargins->setVisible(true);
+		textFlowMargins->setSingleMode(true);
+	}
+
 	if ((m_item->isImageFrame()) && (!m_item->imageClip.empty()))
 		textFlowUsesImageClipping->setEnabled(true);
 	else
 		textFlowUsesImageClipping->setEnabled(false);
+
 }
 
 void PropertiesPalette_Shape::iconSetChange()
@@ -501,9 +557,12 @@
 	m_unitRatio = m_doc->unitRatio();
 	m_unitIndex = m_doc->unitIndex();
 
-	roundRect->blockSignals(true);
+	QSignalBlocker roundRectBlocker(roundRect);
+	QSignalBlocker textFlowMarginBlocker(textFlowMargins);
+
 	roundRect->setNewUnit( m_unitIndex );
-	roundRect->blockSignals(false);
+	textFlowMargins->setNewUnit(m_unitIndex);
+
 }
 
 void PropertiesPalette_Shape::localeChange()
@@ -510,6 +569,7 @@
 {
 	const QLocale& l(LocaleManager::instance().userPreferredLocale());
 	roundRect->setLocale(l);
+	textFlowMargins->setLocale(l);
 }
 
 void PropertiesPalette_Shape::toggleLabelVisibility(bool v)
Index: scribus/ui/propertiespalette_shape.h
===================================================================
--- scribus/ui/propertiespalette_shape.h	(Revision 26796)
+++ scribus/ui/propertiespalette_shape.h	(Arbeitskopie)
@@ -35,7 +35,7 @@
 	void setLocked(bool isLocked);
 	void setSizeLocked(bool isLocked);
 	void setRoundRectEnabled(bool enabled);
-	void showTextFlowMode(PageItem::TextFlowMode mode);
+	void showTextFlowMode(PageItem::TextFlowMode mode, MarginStruct distances);
 
 protected:
 	bool m_haveDoc {false};
Index: scribus/ui/propertiespalette_shapebase.ui
===================================================================
--- scribus/ui/propertiespalette_shapebase.ui	(Revision 26796)
+++ scribus/ui/propertiespalette_shapebase.ui	(Arbeitskopie)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>238</width>
-    <height>107</height>
+    <height>117</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -54,10 +54,10 @@
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeType">
-        <enum>QSizePolicy::Fixed</enum>
+        <enum>QSizePolicy::Policy::Fixed</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -93,7 +93,7 @@
      <item>
       <spacer name="horizontalSpacer_2">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -148,7 +148,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -156,9 +156,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesFrameShape">
+         <widget class="QToolButton" name="textFlowUsesBoundingBox">
           <property name="toolTip">
-           <string>Text flow around frame shape</string>
+           <string>Text flow around bounding box</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -167,7 +167,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -175,9 +175,9 @@
          </widget>
         </item>
         <item>
-         <widget class="QToolButton" name="textFlowUsesBoundingBox">
+         <widget class="QToolButton" name="textFlowUsesFrameShape">
           <property name="toolTip">
-           <string>Text flow around bounding box</string>
+           <string>Text flow around frame shape</string>
           </property>
           <property name="checkable">
            <bool>true</bool>
@@ -186,7 +186,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -205,7 +205,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -224,7 +224,7 @@
            <bool>true</bool>
           </property>
           <property name="toolButtonStyle">
-           <enum>Qt::ToolButtonIconOnly</enum>
+           <enum>Qt::ToolButtonStyle::ToolButtonIconOnly</enum>
           </property>
           <attribute name="buttonGroup">
            <string notr="true">textFlowBtnGroup</string>
@@ -237,7 +237,7 @@
      <item>
       <spacer name="horizontalSpacer_4">
        <property name="orientation">
-        <enum>Qt::Horizontal</enum>
+        <enum>Qt::Orientation::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
@@ -250,9 +250,29 @@
     </layout>
    </item>
    <item>
+    <layout class="QHBoxLayout" name="horizontalLayout_2">
+     <item>
+      <widget class="NewMarginWidget" name="textFlowMargins" native="true"/>
+     </item>
+     <item>
+      <spacer name="horizontalSpacer_3">
+       <property name="orientation">
+        <enum>Qt::Orientation::Horizontal</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>0</width>
+         <height>0</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
     <spacer name="verticalSpacer">
      <property name="orientation">
-      <enum>Qt::Vertical</enum>
+      <enum>Qt::Orientation::Vertical</enum>
      </property>
      <property name="sizeHint" stdset="0">
       <size>
@@ -274,7 +294,7 @@
   <customwidget>
    <class>ScrSpinBox</class>
    <extends>QDoubleSpinBox</extends>
-   <header>ui/scrspinbox.h</header>
+   <header location="global">ui/scrspinbox.h</header>
   </customwidget>
   <customwidget>
    <class>Autoforms</class>
@@ -281,6 +301,12 @@
    <extends>QToolButton</extends>
    <header>ui/autoform.h</header>
   </customwidget>
+  <customwidget>
+   <class>NewMarginWidget</class>
+   <extends>QWidget</extends>
+   <header>ui/newmarginwidget.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
textflow_2025-03-28_01.patch (67,564 bytes)   

ale

2025-03-29 10:04

manager   ~0052363

yes, this way it is coherent.

(overwriting the different values in the bounding box when getting back to it would also have been an option, but i have the feeling that this solution allows the least "data loss" when clicking around)

from my side, it looks ready to be merged.

Issue History

Date Modified Username Field Change
2004-09-17 18:27 packetbell New Issue
2004-09-19 21:16 cbradney Note Added: 0002425
2004-09-19 22:55 packetbell Note Added: 0002430
2005-05-08 17:54 plinnell Severity tweak => feature
2005-05-08 17:54 plinnell Product Version 1.2 => 1.3
2006-04-12 22:09 mhanski OS => all
2006-04-12 22:09 mhanski OS Version => all
2006-04-12 22:09 mhanski Platform => all
2006-05-06 22:45 mhanski Status new => feedback
2006-05-08 21:53 mkoren Note Added: 0011115
2009-07-15 11:12 aliB Note Added: 0022188
2009-07-17 21:47 plinnell Status feedback => acknowledged
2009-07-17 21:47 plinnell Target Version => 1.5.0svn
2009-07-20 22:45 pygmee Note Added: 0022217
2009-07-23 16:18 hammeredklavier Note Added: 0022236
2015-09-17 20:10 Kunda Category Graphics / Image Frames => Graphics/Img Frames
2015-09-17 20:11 Kunda Category Graphics/Img Frames => Graphics / Image Frames
2015-10-09 19:59 Kunda Patch => No
2015-10-09 19:59 Kunda Note Added: 0036588
2015-10-09 19:59 Kunda Target Version 1.5.0svn => 1.6 milestone
2025-03-09 20:58 nitramr Assigned To => nitramr
2025-03-09 20:58 nitramr Status acknowledged => assigned
2025-03-09 20:58 nitramr Target Version 1.6 milestone => 1.7 milestone
2025-03-09 21:09 nitramr Note Added: 0052194
2025-03-09 21:09 nitramr File Added: textflow.png
2025-03-12 22:08 pygmee Note Added: 0052204
2025-03-13 15:17 ale Relationship added related to 0015893
2025-03-17 17:26 nitramr Note Added: 0052245
2025-03-17 17:26 nitramr File Added: textflow_2025-03-17_01.patch
2025-03-17 17:26 nitramr File Added: textflow_ui.png
2025-03-17 17:27 nitramr Patch No => Yes
2025-03-17 17:39 nitramr Note Added: 0052246
2025-03-17 21:12 nitramr Relationship added related to 0017423
2025-03-18 18:24 ale Note Added: 0052262
2025-03-19 17:08 nitramr Note Added: 0052267
2025-03-19 17:08 nitramr File Added: textflow_2025-03-19_01.patch
2025-03-19 17:08 nitramr File Added: border-all.svg
2025-03-21 22:16 nitramr Note Added: 0052288
2025-03-21 22:16 nitramr File Added: textflow_2025-03-21_01.patch
2025-03-22 19:06 pygmee Note Added: 0052292
2025-03-22 19:06 pygmee File Added: no-margin-displayed-bottom.jpg
2025-03-22 20:15 nitramr Note Added: 0052293
2025-03-22 20:15 nitramr File Added: textflow_2025-03-22_01.patch
2025-03-24 22:42 nitramr Note Added: 0052334
2025-03-24 22:42 nitramr File Added: textflow_2025-03-24_01.patch
2025-03-28 12:09 nitramr Note Added: 0052356
2025-03-28 12:09 nitramr File Added: textflow_2025-03-28_01.patch
2025-03-29 10:04 ale Note Added: 0052363