From 59fe13fe40cec2f7a9d00ceb549ef9326ab29d7a Mon Sep 17 00:00:00 2001
From: ale rimoldi <ale@graphicslab.org>
Date: Tue, 25 Nov 2025 19:58:26 +0100
Subject: Add the reviewed RTL-binding changes by Fahad


diff --git a/resources/iconsets/1_7_0/16/page-binding-left.svg b/resources/iconsets/1_7_0/16/page-binding-left.svg
new file mode 100644
index 000000000..d678525fd
--- /dev/null
+++ b/resources/iconsets/1_7_0/16/page-binding-left.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><style>@import '../colors.css';</style>
+<path d="M13 15H3V13H2V11H3V9H2V7H3V5H2V3H3V1H13V15ZM4 3H5V5H4V7H5V9H4V11H5V13H4V14H12V2H4V3Z"/>
+</svg>
diff --git a/resources/iconsets/1_7_0/16/page-binding-right.svg b/resources/iconsets/1_7_0/16/page-binding-right.svg
new file mode 100644
index 000000000..372f25208
--- /dev/null
+++ b/resources/iconsets/1_7_0/16/page-binding-right.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><style>@import '../colors.css';</style>
+<path d="M13 3H14V5H13V7H14V9H13V11H14V13H13V15H3V1H13V3ZM4 14H12V13H11V11H12V9H11V7H12V5H11V3H12V2H4V14Z"/>
+</svg>
diff --git a/resources/iconsets/1_7_0/1_7_0.xml b/resources/iconsets/1_7_0/1_7_0.xml
index c7604a120..4dfd16d66 100644
--- a/resources/iconsets/1_7_0/1_7_0.xml
+++ b/resources/iconsets/1_7_0/1_7_0.xml
@@ -385,6 +385,8 @@ On Dark:  #e580ff; rgb(229, 128, 255); hsl(288, 100, 75)
 		<icon id="list-remove" file="16/action-remove.svg" />		
 		<icon id="lock" file="16/action-lock.svg" />
 		<icon id="lock-unlocked" file="16/action-unlock.svg" />
+		<icon id="page-binding-left" file="16/page-binding-left.svg" />
+		<icon id="page-binding-right" file="16/page-binding-right.svg" />
 		<icon id="page-3fold" file="16/page-type-threefold.svg" />
 		<icon id="page-4fold" file="16/page-type-fourfold.svg" />
 		<icon id="page-doublesided" file="16/page-type-facing.svg" />
diff --git a/scribus/plugins/fileloader/scribus171format/scribus171format.cpp b/scribus/plugins/fileloader/scribus171format/scribus171format.cpp
index 06336482a..e7380a2d2 100644
--- a/scribus/plugins/fileloader/scribus171format/scribus171format.cpp
+++ b/scribus/plugins/fileloader/scribus171format/scribus171format.cpp
@@ -2533,6 +2533,7 @@ void Scribus171Format::readDocAttributes(ScribusDoc* doc, const ScXmlStreamAttri
 		m_Doc->setPageOrientation(attrs.valueAsInt("ORIENTATION", 0));
 		m_Doc->FirstPnum = attrs.valueAsInt("FIRSTNUM", 1);
 		m_Doc->setPagePositioning(attrs.valueAsInt("BOOK", 0));
+		m_Doc->setBindingDirection(attrs.valueAsInt("BINDINGDIRECTION", 0));
 
 		m_Doc->setUsesAutomaticTextFrames( attrs.valueAsInt("AUTOTEXT") );
 		m_Doc->PageSp = attrs.valueAsInt("AUTOSPALTEN");
@@ -2599,6 +2600,7 @@ void Scribus171Format::readDocAttributes(ScribusDoc* doc, const ScXmlStreamAttri
 		m_Doc->setPageOrientation(attrs.valueAsInt("PageOrientation", 0));
 		m_Doc->FirstPnum = attrs.valueAsInt("FirstPageNumber", 1);
 		m_Doc->setPagePositioning(attrs.valueAsInt("PagePositioning", 0));
+		m_Doc->setBindingDirection(attrs.valueAsInt("BindingDirection", 0));
 
 		m_Doc->setUsesAutomaticTextFrames( attrs.valueAsInt("AutomaticTextFrames") );
 		m_Doc->PageSp = attrs.valueAsInt("AutomaticTextFrameColumnCount");
diff --git a/scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp b/scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
index ea195db72..bcc9f7a5f 100644
--- a/scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
+++ b/scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp
@@ -336,6 +336,7 @@ bool Scribus171Format::saveFile(const QString & fileName, const FileFormat & /*
 	docu.writeAttribute("PageSize", m_Doc->pageSize());
 	docu.writeAttribute("FirstPageNumber", m_Doc->FirstPnum);
 	docu.writeAttribute("PagePositioning", m_Doc->pagePositioning());
+	docu.writeAttribute("BindingDirection", m_Doc->bindingDirection());
 	if (m_Doc->usesAutomaticTextFrames())
 		docu.writeAttribute("AutomaticTextFrames", 1);
 	docu.writeAttribute("AutomaticTextFrameColumnCount", m_Doc->PageSp);
diff --git a/scribus/plugins/scriptplugin/cmddoc.cpp b/scribus/plugins/scriptplugin/cmddoc.cpp
index 00b63cd7e..f016824bc 100644
--- a/scribus/plugins/scriptplugin/cmddoc.cpp
+++ b/scribus/plugins/scriptplugin/cmddoc.cpp
@@ -15,22 +15,20 @@ for which a new license (GPL+exception) is in place.
 
 #include <QApplication>
 
-/*
-newDocument(size, margins, orientation, firstPageNumber,
-            unit, pagesType, firstPageOrder)*/
 PyObject *scribus_newdocument(PyObject* /* self */, PyObject* args)
 {
 	double topMargin, bottomMargin, leftMargin, rightMargin;
 	double pageWidth, pageHeight;
 	int orientation, firstPageNr, unit, pagesType, firstPageOrder, numPages;
+	int bindingDirection = 0;
 
 	PyObject *p, *m;
 
-	if ((!PyArg_ParseTuple(args, "OOiiiiii", &p, &m, &orientation,
+	if ((!PyArg_ParseTuple(args, "OOiiiiii|i", &p, &m, &orientation,
 											&firstPageNr, &unit,
 											&pagesType,
 											&firstPageOrder,
-											&numPages)) ||
+											&numPages, &bindingDirection)) ||
 						(!PyArg_ParseTuple(p, "dd", &pageWidth, &pageHeight)) ||
 						(!PyArg_ParseTuple(m, "dddd", &leftMargin, &rightMargin,
 												&topMargin, &bottomMargin)))
@@ -39,12 +37,8 @@ PyObject *scribus_newdocument(PyObject* /* self */, PyObject* args)
 		numPages = 1;
 	if (pagesType == 0)
 	{
-	//	facingPages = 0;
 		firstPageOrder = 0;
 	}
-//	else
-//		facingPages = 1;
-	// checking the bounds
 	if (pagesType < firstPageOrder)
 	{
 		PyErr_SetString(ScribusException, QObject::tr("firstPageOrder is bigger than allowed.","python error").toUtf8().constData());
@@ -71,7 +65,8 @@ PyObject *scribus_newdocument(PyObject* /* self */, PyObject* args)
 								// columnDistance, numberCols, autoframes,
 								0, 1, false,
 								pagesType, unit, firstPageOrder,
-								orientation, firstPageNr, "Custom", true, numPages);
+								orientation, firstPageNr, "Custom", true,
+								numPages, true, 0, bindingDirection);
 	ScCore->primaryMainWindow()->doc->setPageSetFirstPage(pagesType, firstPageOrder);
 
 	return PyLong_FromLong(static_cast<long>(ret));
diff --git a/scribus/plugins/scriptplugin/cmddoc.h b/scribus/plugins/scriptplugin/cmddoc.h
index 8a01a35e5..8917e4900 100644
--- a/scribus/plugins/scriptplugin/cmddoc.h
+++ b/scribus/plugins/scriptplugin/cmddoc.h
@@ -14,7 +14,7 @@ for which a new license (GPL+exception) is in place.
 
 PyDoc_STRVAR(scribus_newdocument__doc__,
 QT_TR_NOOP("newDocument(size, margins, orientation, firstPageNumber,\n\
-                        unit, pagesType, firstPageOrder, numPages) -> bool\n\
+                        unit, pagesType, firstPageOrder, numPages, bindingDirection) -> bool\n\
 \n\
 Creates a new document and returns true if successful. The parameters have the\n\
 following meaning:\n\
@@ -42,7 +42,9 @@ PAGE_4 is 4-fold.\n\
 firstPageOrder = What is position of first page in the document.\n\
 Indexed from 0 (0 = first).\n\
 \n\
-numPage = Number of pages to be created.\n\
+numPages = Number of pages to be created.\n\
+\n\
+bindingDirection = 0 = LTR, 1 = RTL (optional, defaults to 0).\n\
 \n\
 The values for width, height and the margins are expressed in the given unit\n\
 for the document. PAPER_* constants are expressed in points. If your document\n\
diff --git a/scribus/prefsmanager.cpp b/scribus/prefsmanager.cpp
index eccd2aaf9..d87023beb 100644
--- a/scribus/prefsmanager.cpp
+++ b/scribus/prefsmanager.cpp
@@ -455,6 +455,7 @@ void PrefsManager::initDefaults()
 	pageS.pageNames.append(CommonStrings::pageLocRight);
 	appPrefs.pageSets.append(pageS);
 	appPrefs.docSetupPrefs.pagePositioning = singlePage;
+	appPrefs.docSetupPrefs.bindingDirection = 0;
 	appPrefs.fontPrefs.askBeforeSubstitute = true;
 	appPrefs.miscPrefs.haveStylePreview = true;
 	appPrefs.miscPrefs.saveEmergencyFile = true;
@@ -1385,6 +1386,7 @@ bool PrefsManager::writePref(const QString& filePath)
 	deDocumentSetup.setAttribute("MarginRight", ScCLocale::toQStringC(appPrefs.docSetupPrefs.margins.right()));
 	deDocumentSetup.setAttribute("MarginPreset", appPrefs.docSetupPrefs.marginPreset);
 	deDocumentSetup.setAttribute("PagePositioning", appPrefs.docSetupPrefs.pagePositioning);
+	deDocumentSetup.setAttribute("BindingDirection", appPrefs.docSetupPrefs.bindingDirection);
 	deDocumentSetup.setAttribute("AutoSave", static_cast<int>(appPrefs.docSetupPrefs.AutoSave));
 	deDocumentSetup.setAttribute("AutoSaveTime", appPrefs.docSetupPrefs.AutoSaveTime);
 	deDocumentSetup.setAttribute("AutoSaveCount", appPrefs.docSetupPrefs.AutoSaveCount);
@@ -2080,6 +2082,7 @@ bool PrefsManager::readPref(const QString& filePath)
 			appPrefs.docSetupPrefs.margins.setRight(ScCLocale::toDoubleC(dc.attribute("MarginRight"), 9.0));
 			appPrefs.docSetupPrefs.marginPreset   = dc.attribute("MarginPreset", "0").toInt();
 			appPrefs.docSetupPrefs.pagePositioning	= dc.attribute("PagePositioning", "0").toInt();
+			appPrefs.docSetupPrefs.bindingDirection	= dc.attribute("BindingDirection", "0").toInt();
 			appPrefs.docSetupPrefs.AutoSave	  = static_cast<bool>(dc.attribute("AutoSave", "0").toInt());
 			appPrefs.docSetupPrefs.AutoSaveTime  = dc.attribute("AutoSaveTime", "600000").toInt();
 			appPrefs.docSetupPrefs.AutoSaveCount  = dc.attribute("AutoSaveCount", "1").toInt();
diff --git a/scribus/prefsstructs.h b/scribus/prefsstructs.h
index bbf957683..ccdd9ccb6 100644
--- a/scribus/prefsstructs.h
+++ b/scribus/prefsstructs.h
@@ -168,6 +168,7 @@ struct DocumentSetupPrefs
 	bool AutoSaveLocation;
 	QString AutoSaveDir;
 	bool saveCompressed;
+	int bindingDirection; //! 0 = LTR, 1 = RTL
 };
 
 //Guides
diff --git a/scribus/scribus.cpp b/scribus/scribus.cpp
index 7d41c39dd..6e4b8e4e2 100644
--- a/scribus/scribus.cpp
+++ b/scribus/scribus.cpp
@@ -337,7 +337,7 @@ int ScribusMainWindow::initScMW(bool primaryMainWindow)
 	internalCopy = false;
 	internalCopyBuffer.clear();
 	m_doc = new ScribusDoc();
-	m_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
+	m_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom", 0);
 	m_doc->setPage(100, 100, 0, 0, 0, 0, 0, 0, false, false);
 	m_doc->addPage(0);
 	m_doc->setGUI(false, this, nullptr);
@@ -2026,6 +2026,7 @@ void ScribusMainWindow::startUpDialog()
 		{
 			int facingPages = dia->choosenLayout();
 			int firstPage = dia->layoutFirstPage();
+			int bindingDirection = dia->bindingDirection();
 			docSet = dia->startDocSetup->isChecked();
 			double topMargin = dia->marginGroup->margins().top();
 			double bottomMargin = dia->marginGroup->margins().bottom();
@@ -2039,7 +2040,11 @@ void ScribusMainWindow::startUpDialog()
 			int orientation = dia->orientation();
 			int pageCount = dia->pageCountSpinBox->value();
 			QString pagesize = dia->pageSizeName();
-			doFileNew(pageWidth, pageHeight, topMargin, leftMargin, rightMargin, bottomMargin, columnDistance, numberCols, autoframes, facingPages, dia->unitOfMeasureComboBox->currentIndex(), firstPage, orientation, 1, pagesize, true, pageCount, true, dia->marginGroup->marginPreset());
+			doFileNew(pageWidth, pageHeight, topMargin, leftMargin, rightMargin, bottomMargin,
+				columnDistance, numberCols, autoframes, facingPages, dia->unitOfMeasureComboBox->currentIndex(),
+				firstPage, orientation, 1, pagesize, true, pageCount, true, dia->marginGroup->marginPreset(),
+				bindingDirection
+			);
 			doc->setPageSetFirstPage(facingPages, firstPage);
 			doc->bleeds()->set(dia->bleedTop(), dia->bleedLeft(), dia->bleedBottom(), dia->bleedRight());
 			HaveNewDoc();
@@ -2102,6 +2107,7 @@ bool ScribusMainWindow::slotFileNew()
 
 	int facingPages = dia->choosenLayout();
 	int firstPage = dia->layoutFirstPage();
+	int bindingDirection = dia->bindingDirection();
 	bool docSet = dia->startDocSetup->isChecked();
 	double topMargin = dia->marginGroup->margins().top();
 	double bottomMargin = dia->marginGroup->margins().bottom();
@@ -2116,7 +2122,9 @@ bool ScribusMainWindow::slotFileNew()
 	int pageCount = dia->pageCountSpinBox->value();
 	QString pagesize = dia->pageSizeName();
 
-	if (doFileNew(pageWidth, pageHeight, topMargin, leftMargin, rightMargin, bottomMargin, columnDistance, numberCols, autoframes, facingPages, dia->unitOfMeasureComboBox->currentIndex(), firstPage, orientation, 1, pagesize, true, pageCount, true, dia->marginGroup->marginPreset()))
+	if (doFileNew(pageWidth, pageHeight, topMargin, leftMargin, rightMargin, bottomMargin, columnDistance, numberCols,
+			autoframes, facingPages, dia->unitOfMeasureComboBox->currentIndex(), firstPage, orientation, 1,
+			pagesize, true, pageCount, true, dia->marginGroup->marginPreset(), bindingDirection))
 	{
 		doc->setPageSetFirstPage(facingPages, firstPage);
 		doc->bleeds()->set(dia->bleedTop(), dia->bleedLeft(), dia->bleedBottom(), dia->bleedRight());
@@ -2135,13 +2143,9 @@ bool ScribusMainWindow::slotFileNew()
 	return retVal;
 }
 
-//TODO move to core, assign doc to doc list, optionally create gui for it
-ScribusDoc *ScribusMainWindow::newDoc(double width, double height, double topMargin, double leftMargin, double rightMargin, double bottomMargin, double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement, int unitIndex, int firstPageLocation, int orientation, int firstPageNumber, const QString& defaultPageSize, bool requiresGUI, int pageCount, bool showView, int marginPreset)
-{
-	return doFileNew(width, height, topMargin, leftMargin, rightMargin, bottomMargin, columnDistance, columnCount, autoTextFrames, pageArrangement, unitIndex, firstPageLocation, orientation, firstPageNumber, defaultPageSize, requiresGUI, pageCount, showView, marginPreset);
-}
-
-ScribusDoc *ScribusMainWindow::doFileNew(double width, double height, double topMargin, double leftMargin, double rightMargin, double bottomMargin, double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement, int unitIndex, int firstPageLocation, int orientation, int firstPageNumber, const QString& defaultPageSize, bool requiresGUI, int pageCount, bool showView, int marginPreset)
+ScribusDoc *ScribusMainWindow::doFileNew(double width, double height, double topMargin, double leftMargin, double rightMargin, double bottomMargin,
+	double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement, int unitIndex, int firstPageLocation, int orientation,
+	int firstPageNumber, const QString& defaultPageSize, bool requiresGUI, int pageCount, bool showView, int marginPreset, int bindingDirection)
 {
 	if (HaveDoc)
 		outlinePalette->buildReopenVals();
@@ -2189,7 +2193,7 @@ ScribusDoc *ScribusMainWindow::doFileNew(double width, double height, double top
 			doc->PageColors = m_prefsManager.appPrefs.colorPrefs.DColors;
 	}
 	tempDoc->PageColors.ensureDefaultColors();
-	tempDoc->setup(unitIndex, pageArrangement, firstPageLocation, orientation, firstPageNumber, defaultPageSize, newDocName);
+	tempDoc->setup(unitIndex, pageArrangement, firstPageLocation, orientation, firstPageNumber, defaultPageSize, newDocName, bindingDirection);
 	if (requiresGUI)
 	{
 		HaveDoc++;
@@ -9221,7 +9225,7 @@ void ScribusMainWindow::manageColorsAndFills()
 			if (fmt)
 			{
 				ScribusDoc *s_doc = new ScribusDoc();
-				s_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
+				s_doc->setup(0, 1, 1, 1, 1, "Custom", "Custom", 0);
 				s_doc->setPage(100, 100, 0, 0, 0, 0, 0, 0, false, false);
 				s_doc->addPage(0);
 				s_doc->setGUI(false, this, nullptr);
diff --git a/scribus/scribus.h b/scribus/scribus.h
index 7b2a7185b..61dd6e314 100644
--- a/scribus/scribus.h
+++ b/scribus/scribus.h
@@ -154,8 +154,10 @@ public:
 	inline bool scriptIsRunning(void) const { return (m_ScriptRunning > 0); }
 	inline void setScriptRunning(bool value) { m_ScriptRunning += (value ? 1 : -1); }
 
-	ScribusDoc* doFileNew(double width, double height, double topMargin, double leftMargin, double rightMargin, double bottomMargin, double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement, int unitIndex, int firstPageLocation, int orientation, int firstPageNumber, const QString& defaultPageSize, bool requiresGUI, int pageCount = 1, bool showView = true, int marginPreset = 0);
-	ScribusDoc* newDoc(double width, double height, double topMargin, double leftMargin, double rightMargin, double bottomMargin, double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement, int unitIndex, int firstPageLocation, int orientation, int firstPageNumber, const QString& defaultPageSize, bool requiresGUI, int pageCount = 1, bool showView = true, int marginPreset = 0);
+	ScribusDoc* doFileNew(double width, double height, double topMargin, double leftMargin, double rightMargin,
+		double bottomMargin, double columnDistance, double columnCount, bool autoTextFrames, int pageArrangement,
+		int unitIndex, int firstPageLocation, int orientation, int firstPageNumber, const QString& defaultPageSize,
+		bool requiresGUI, int pageCount = 1, bool showView = true, int marginPreset = 0, int bindingDirection = 0);
 	bool DoFileSave(const QString& fileName, QString* savedFileName = nullptr, uint formatID = FORMATID_CURRENTEXPORT);
 
 	void changeEvent(QEvent *e) override;
diff --git a/scribus/scribusdoc.cpp b/scribus/scribusdoc.cpp
index d5dc3c2aa..747d8b385 100644
--- a/scribus/scribusdoc.cpp
+++ b/scribus/scribusdoc.cpp
@@ -680,7 +680,7 @@ QList<PageItem*> *ScribusDoc::parentGroup(PageItem* item, QList<PageItem*> *list
 	return retList;
 }
 
-void ScribusDoc::setup(int unitIndex, int fp, int firstLeft, int orientation, int firstPageNumber, const QString& defaultPageSize, const QString& documentName)
+void ScribusDoc::setup(int unitIndex, int fp, int firstLeft, int orientation, int firstPageNumber, const QString& defaultPageSize, const QString& documentName, int bindingDirection)
 {
 	m_docPrefsData.docSetupPrefs.docUnitIndex = unitIndex;
 	setPageSetFirstPage(fp, firstLeft);
@@ -688,6 +688,7 @@ void ScribusDoc::setup(int unitIndex, int fp, int firstLeft, int orientation, in
 	m_docPrefsData.docSetupPrefs.pageSize = defaultPageSize;
 	FirstPnum = firstPageNumber;
 	m_docPrefsData.docSetupPrefs.pagePositioning = fp;
+	m_docPrefsData.docSetupPrefs.bindingDirection = bindingDirection;
 	setDocumentFileName(documentName);
 	HasCMS = false;
 	if (!pdfOptions().UseLPI)
@@ -6067,11 +6068,21 @@ void ScribusDoc::reformPages(bool moveObjects)
 	int rowcounter = 0;
 	double maxXPos = 0.0;
 	double maxYPos = 0.0;
+	double lastYPos = Pages->at(0)->initialHeight();
+
+	bool rtlBinding = m_docPrefsData.docSetupPrefs.bindingDirection == 1;
+
 	double currentXPos = m_docPrefsData.displayPrefs.scratch.left();
+	if (rtlBinding)
+	{
+		counter = counter == 1 ? 0 : 1;
+		currentXPos +=  m_docPrefsData.docSetupPrefs.pageWidth
+			- (m_docPrefsData.docSetupPrefs.pageWidth + m_docPrefsData.displayPrefs.pageGapHorizontal) * counter;
+	}
+	else
+		currentXPos += (Pages->at(0)->initialWidth() + m_docPrefsData.displayPrefs.pageGapHorizontal) * counter;
+
 	double currentYPos = m_docPrefsData.displayPrefs.scratch.top();
-	double lastYPos = Pages->at(0)->initialHeight();
-	currentXPos += (Pages->at(0)->initialWidth() + m_docPrefsData.displayPrefs.pageGapHorizontal) * counter;
-	// currentXPos += (m_docPrefsData.docSetupPrefs.pageWidth + m_docPrefsData.displayPrefs.pageGapHorizontal) * counter;
 
 	ScPage* page;
 	int docPageCount = Pages->count();
@@ -6111,29 +6122,59 @@ void ScribusDoc::reformPages(bool moveObjects)
 			page->setYOffset(currentYPos);
 			if (counter < pageSets()[m_docPrefsData.docSetupPrefs.pagePositioning].Columns-1)
 			{
-				currentXPos += page->width() + m_docPrefsData.displayPrefs.pageGapHorizontal;
+				if (rtlBinding)
+					currentXPos -= page->width() + m_docPrefsData.displayPrefs.pageGapHorizontal;
+				else
+					currentXPos += page->width() + m_docPrefsData.displayPrefs.pageGapHorizontal;
 				lastYPos = qMax(lastYPos, page->height());
 				if (counter == 0)
 				{
-					page->Margins.setLeft(page->initialMargins.right());
-					page->Margins.setRight(page->initialMargins.left());
+					if (rtlBinding)
+					{
+						page->Margins.setLeft(page->initialMargins.left());
+						page->Margins.setRight(page->initialMargins.right());
+					}
+					else
+					{
+						page->Margins.setLeft(page->initialMargins.right());
+						page->Margins.setRight(page->initialMargins.left());
+					}
 				}
 				else
 				{
-					page->Margins.setLeft(page->initialMargins.left());
-					page->Margins.setRight(page->initialMargins.left());
+					if (rtlBinding)
+					{
+						page->Margins.setLeft(page->initialMargins.right());
+						page->Margins.setRight(page->initialMargins.right());
+					}
+					else
+					{
+						page->Margins.setLeft(page->initialMargins.left());
+						page->Margins.setRight(page->initialMargins.left());
+					}
 				}
 			}
 			else
 			{
-				currentXPos = m_docPrefsData.displayPrefs.scratch.left();
+				if (rtlBinding)
+					currentXPos = m_docPrefsData.displayPrefs.scratch.left() + m_docPrefsData.docSetupPrefs.pageWidth;
+				else
+					currentXPos = m_docPrefsData.displayPrefs.scratch.left();
 				if (pageSets()[m_docPrefsData.docSetupPrefs.pagePositioning].Columns > 1)
 					currentYPos += qMax(lastYPos, page->height())+m_docPrefsData.displayPrefs.pageGapVertical;
 				else
 					currentYPos += page->height()+m_docPrefsData.displayPrefs.pageGapVertical;
 				lastYPos = 0;
-				page->Margins.setRight(page->initialMargins.right());
-				page->Margins.setLeft(page->initialMargins.left());
+				if (rtlBinding)
+				{
+					page->Margins.setRight(page->initialMargins.left());
+					page->Margins.setLeft(page->initialMargins.right());
+				}
+				else
+				{
+					page->Margins.setRight(page->initialMargins.right());
+					page->Margins.setLeft(page->initialMargins.left());
+				}
 			}
 			counter++;
 			if (counter > pageSets()[m_docPrefsData.docSetupPrefs.pagePositioning].Columns-1)
diff --git a/scribus/scribusdoc.h b/scribus/scribusdoc.h
index 389113876..6078a6a30 100644
--- a/scribus/scribusdoc.h
+++ b/scribus/scribusdoc.h
@@ -107,7 +107,10 @@ public:
 	bool inASpecialEditMode() const;
 	QList<PageItem*> getAllItems(const QList<PageItem*> &items) const;
 	QList<PageItem*> *parentGroup(PageItem* item, QList<PageItem*> *list);
-	void setup(int, int, int, int, int, const QString&, const QString&);
+	/**
+	 * @param bindingDirection Defaults to 0 for all the one page temporary documents Scribus creates
+	 */
+	void setup(int unitIndex, int fp, int firstLeft, int orientation, int firstPageNumber, const QString& defaultPageSize, const QString& documentName, int bindingDirection = 0);
 	void setLoading(bool);
 	bool isLoading() const;
 	void setModified(bool);
@@ -217,6 +220,8 @@ public:
 
 	int pageOrientation() const { return m_docPrefsData.docSetupPrefs.pageOrientation; }
 	void setPageOrientation(int o) { m_docPrefsData.docSetupPrefs.pageOrientation = o; }
+	int bindingDirection() const { return m_docPrefsData.docSetupPrefs.bindingDirection; }
+	void setBindingDirection(int d) { m_docPrefsData.docSetupPrefs.bindingDirection = d; }
 	int pagePositioning() const { return m_docPrefsData.docSetupPrefs.pagePositioning; }
 	void setPagePositioning(int p) { m_docPrefsData.docSetupPrefs.pagePositioning = p; }
 
diff --git a/scribus/ui/newdocdialog.cpp b/scribus/ui/newdocdialog.cpp
index 4a5c52eb9..6d7a95ab0 100644
--- a/scribus/ui/newdocdialog.cpp
+++ b/scribus/ui/newdocdialog.cpp
@@ -63,12 +63,17 @@ NewDocDialog::NewDocDialog(QWidget* parent, const QStringList& recentDocs, bool
 	m_unitRatio = unitGetRatioFromIndex(m_unitIndex);
 	m_unitSuffix = unitGetSuffixFromIndex(m_unitIndex);
 	m_orientation = prefsManager.appPrefs.docSetupPrefs.pageOrientation;
+	m_bindingDirection = prefsManager.appPrefs.docSetupPrefs.bindingDirection;
 
 	buttonVertical->setIcon(iconManager.loadIcon("page-orientation-vertical"));
 	buttonHorizontal->setIcon(iconManager.loadIcon("page-orientation-horizontal"));
 	buttonSinglePage->setIcon(iconManager.loadIcon("page-simple"));
 	buttonDoublePageLeft->setIcon(iconManager.loadIcon("page-first-left"));
 	buttonDoublePageRight->setIcon(iconManager.loadIcon("page-first-right"));
+	QIcon pageBindingIcon;
+	pageBindingIcon.addPixmap(iconManager.loadPixmap("page-binding-left"), QIcon::Normal, QIcon::Off);
+	pageBindingIcon.addPixmap(iconManager.loadPixmap("page-binding-right"), QIcon::Normal, QIcon::On);
+	buttonBindingDirection->setIcon(pageBindingIcon);
 	labelColumns->setPixmap(iconManager.loadPixmap("paragraph-columns"));
 
 	createNewDocPage();
@@ -98,6 +103,7 @@ NewDocDialog::NewDocDialog(QWidget* parent, const QStringList& recentDocs, bool
 	buttonSinglePage->setToolTip(tr("Single page document"));
 	buttonDoublePageLeft->setToolTip(tr("A document with facing pages, with the first page on the left side"));
 	buttonDoublePageRight->setToolTip(tr("A document with facing pages, with the first page on the right side"));
+	buttonBindingDirection->setToolTip(tr("Bind the pages on the right (LTR) or left (RTL) side"));
 	widthSpinBox->setToolTip( tr( "Width of the document's pages, editable if you have chosen a custom page size" ) );
 	heightSpinBox->setToolTip( tr( "Height of the document's pages, editable if you have chosen a custom page size" ) );
 	pageCountSpinBox->setToolTip( tr( "Initial number of pages of the document" ) );
@@ -112,6 +118,7 @@ NewDocDialog::NewDocDialog(QWidget* parent, const QStringList& recentDocs, bool
 
 	connect(pageOrientationButtons, &QButtonGroup::idClicked, this, &NewDocDialog::setOrientation);
 	connect(pageLayoutButtons, &QButtonGroup::idClicked, this, &NewDocDialog::setLayout);
+	connect(buttonBindingDirection, &QToolButton::toggled, this, &NewDocDialog::setBindingDirection);
 	connect(unitOfMeasureComboBox, SIGNAL(activated(int)), this, SLOT(setUnit(int)));
 	connect(Distance, SIGNAL(valueChanged(double)), this, SLOT(setDistance(double)));
 	connect(autoTextFrame, SIGNAL(clicked()), this, SLOT(handleAutoFrame()));
@@ -155,16 +162,21 @@ void NewDocDialog::createNewDocPage()
 	if (pagePositioning == singlePage)
 	{
 		pageLayoutButtons->button(0)->setChecked(true);
+		buttonBindingDirection->setDisabled(true);
 	}
 	else if (prefsManager.appPrefs.pageSets[pagePositioning].FirstPage == 0)
 	{
 		pageLayoutButtons->button(1)->setChecked(true);
+		buttonBindingDirection->setDisabled(false);
 	}
 	else
 	{
 		pageLayoutButtons->button(2)->setChecked(true);
+		buttonBindingDirection->setDisabled(false);
 	}
 
+	buttonBindingDirection->setChecked(m_bindingDirection);
+
 	listPageFormats->setValues(pageSize, orientation, PageSizeInfo::Preferred, PageSizeList::NameAsc);
 
 	pageSizeSelector->setHasFormatSelector(false);
@@ -525,20 +537,28 @@ void NewDocDialog::setLayout(int layoutId)
 	{
 		case 0:
 			setDocLayout(0);
+			buttonBindingDirection->setDisabled(true);
 		break;
 		case 1:
 			setDocLayout(1);
 			pagePreview->setFirstPage(0);
 			setDocFirstPage(0);
+			buttonBindingDirection->setDisabled(false);
 		break;
 		case 2:
 			setDocLayout(1);
 			pagePreview->setFirstPage(1);
 			setDocFirstPage(1);
+			buttonBindingDirection->setDisabled(false);
 		break;
 	}
 }
 
+void NewDocDialog::setBindingDirection(bool checked)
+{
+	m_bindingDirection = int(checked);
+}
+
 void NewDocDialog::setPageSize(const QString &size)
 {
 	setSize(size);
diff --git a/scribus/ui/newdocdialog.h b/scribus/ui/newdocdialog.h
index a65550f3d..14a5ad202 100644
--- a/scribus/ui/newdocdialog.h
+++ b/scribus/ui/newdocdialog.h
@@ -76,6 +76,7 @@ public:
 
 	int orientation() const { return m_orientation;}
 	int choosenLayout() const { return m_choosenLayout;}
+	int bindingDirection() const { return m_bindingDirection; }
 	int layoutFirstPage() const { return m_layoutFirstPage; }
 	double pageWidth() const { return m_pageWidth;}
 	double pageHeight() const { return m_pageHeight;}
@@ -94,6 +95,7 @@ public slots:
 	void ExitOK();
 	void setOrientation(int ori);
 	void setLayout(int layoutId);
+	void setBindingDirection(bool checked);
 	void setPageSize(const QString &);
 	void setDocLayout(int layout);
 	void setDocFirstPage(int firstPage);
@@ -126,6 +128,7 @@ protected:
 	double m_unitRatio { 1.0 };
 	int m_orientation { 0 };
 	int m_choosenLayout { 0 };
+	int m_bindingDirection { 0 }; // 0 = LTR, 1 = RTL
 	int m_layoutFirstPage { 0 };
 	double m_pageWidth { 1.0 };
 	double m_pageHeight { 1.0 };
diff --git a/scribus/ui/newdocdialog.ui b/scribus/ui/newdocdialog.ui
index 53c60dcff..d9312efd6 100644
--- a/scribus/ui/newdocdialog.ui
+++ b/scribus/ui/newdocdialog.ui
@@ -474,6 +474,16 @@
                         </property>
                        </widget>
                       </item>
+                      <item>
+                       <widget class="QToolButton" name="buttonBindingDirection">
+                        <property name="text">
+                         <string/>
+                        </property>
+                        <property name="checkable">
+                         <bool>true</bool>
+                        </property>
+                       </widget>
+                      </item>
                      </layout>
                     </item>
                    </layout>
diff --git a/scribus/ui/pagepalette_pages.cpp b/scribus/ui/pagepalette_pages.cpp
index 4fad09a0d..15e8a132c 100644
--- a/scribus/ui/pagepalette_pages.cpp
+++ b/scribus/ui/pagepalette_pages.cpp
@@ -379,12 +379,10 @@ void PagePalette_Pages::rebuildPages()
 	pageLayout->setScheme(currView->m_doc->pagePositioning());
 	pageLayout->setFirstPage(currentPageSet.FirstPage);
 
-	int counter = currentPageSet.FirstPage;
-	int cols = currentPageSet.Columns;
-
+	pageViewWidget->pageGrid()->setBindingDirection(currView->m_doc->bindingDirection());
 	pageViewWidget->pageGrid()->setDocumentPageSize(QSize(currView->m_doc->pageWidth(), currView->m_doc->pageHeight()));
-	pageViewWidget->pageGrid()->setPageInGroup(cols);
-	pageViewWidget->pageGrid()->setPageOffset(counter);
+	pageViewWidget->pageGrid()->setPageInGroup(currentPageSet.Columns);
+	pageViewWidget->pageGrid()->setPageOffset(currentPageSet.FirstPage);
 
 	m_pagePreviewUpdatePending = false;
 
@@ -456,6 +454,7 @@ void PagePalette_Pages::setView(ScribusView *view)
 		return;
 
 	pageViewWidget->pageGrid()->setSelectionColor(PrefsManager::instance().appPrefs.displayPrefs.pageBorderColor);
+	pageViewWidget->pageGrid()->setBindingDirection(view->m_doc->bindingDirection());
 
 //	if (currView)
 //		connect(currView->m_doc, SIGNAL(pagePreviewChanged()), this, SLOT(updatePagePreview()));
diff --git a/scribus/ui/pagepalette_widgets.cpp b/scribus/ui/pagepalette_widgets.cpp
index 3c9519901..1139ac80d 100644
--- a/scribus/ui/pagepalette_widgets.cpp
+++ b/scribus/ui/pagepalette_widgets.cpp
@@ -316,9 +316,12 @@ void PageGrid::setPageLayout(PageLayout layout)
 	update();
 }
 
-void PageGrid::setPageOffset(int pageCount)
+void PageGrid::setPageOffset(int offset)
 {
-	m_pageOffset = pageCount;
+	if (m_rtlBinding)
+		m_pageOffset = offset == 1 ? 0 : 1;
+	else
+		m_pageOffset = offset;
 	calculateSize();
 	update();
 }
@@ -444,7 +447,11 @@ int PageGrid::columnAt(QPoint pos)
 
 	int m_columns = columns();
 
-	return (m_col < m_columns) ? m_col : m_columns -1;
+	int correctedCol = (m_col < m_columns) ? m_col : m_columns - 1;
+	// for RTL documents, we only support single and double page documents, not the legacy multipane documents
+	if (m_rtlBinding)
+		return  correctedCol == 0 ? 1 : 0;
+	return correctedCol;
 }
 
 int PageGrid::rowAt(QPoint pos)
@@ -789,6 +796,12 @@ void PageGrid::showContextMenu(QPoint pos)
 	m_contextMenu->exec( mapToGlobal(pos) );
 }
 
+
+void PageGrid::setBindingDirection(int rtl_binding)
+{
+	m_rtlBinding = rtl_binding == 1;
+}
+
 /* ********************************************************************************* *
  *
  * Events
@@ -802,6 +815,9 @@ void PageGrid::paintEvent(QPaintEvent *event)
 	int x = m_groupSpace;
 	int y = m_rowSpace;
 	int offset = 0;
+	bool firstPage = false;
+	bool lastPage = false;
+	int groupStart = 0;
 	QRect selectedPageRect;
 	QColor foregroundColor( PrefsManager::instance().appPrefs.displayPrefs.scratchColor.lightness() <= 128 ? Qt::white : Qt::black);
 
@@ -818,7 +834,8 @@ void PageGrid::paintEvent(QPaintEvent *event)
 	// Draw pages
 	for (int r = 0; r < rows(); r++)
 	{
-		int groupStart = m_groupSpace;
+		if (!lastPage)
+			groupStart = m_groupSpace;
 		int groupWidth = 0;
 		bool drawGroupRect = false;
 
@@ -829,11 +846,26 @@ void PageGrid::paintEvent(QPaintEvent *event)
 			if (count >= pageCount() + m_pageOffset)
 				break;
 
+			if (count == pageCount() + m_pageOffset - 1)
+				lastPage = true;
+
 			// cell is a page cell
 			if (count >= m_pageOffset && count < pageCount() + m_pageOffset)
 			{
 				int id = count - m_pageOffset;
 				PageCell * cell = getPageItem(id);
+				if (m_rtlBinding)
+				{
+					x = (rowWidth(r) - dummyPageSize().width() - 1 - m_cellGap - x);;
+					if (firstPage)
+					{
+						x = m_groupSpace;
+						firstPage = false;
+						lastPage = false;
+					}
+					if (lastPage)
+						groupStart = x;
+				}
 				if (id == m_selectedPage)
 					selectedPageRect = QRect(x, y, cell->pageWidthByHeight(pageHeight()), pageHeight() );
 				QPoint pos(x,y);
@@ -846,8 +878,8 @@ void PageGrid::paintEvent(QPaintEvent *event)
 				else
 					offset = m_cellGap;
 
-
-				x += cell->pageWidthByHeight(pageHeight()) + offset;
+				if (!m_rtlBinding)
+					x += cell->pageWidthByHeight(pageHeight()) + offset;
 				groupWidth += cell->pageWidthByHeight(pageHeight()) + offset;
 				drawGroupRect = true;
 
@@ -857,7 +889,9 @@ void PageGrid::paintEvent(QPaintEvent *event)
 			else
 			{
 				offset = ((c + 1) % m_cellsInGroup) == 0 ? 0 : m_cellGap;
-				x += dummyPageSize().width() + offset;
+				if (!m_rtlBinding)
+					x += dummyPageSize().width() + offset;
+				firstPage = true;
 
 				// adjust start on first row if first page has an offset
 				if(r == 0)
diff --git a/scribus/ui/pagepalette_widgets.h b/scribus/ui/pagepalette_widgets.h
index 9c7186ec8..817a6962c 100644
--- a/scribus/ui/pagepalette_widgets.h
+++ b/scribus/ui/pagepalette_widgets.h
@@ -75,8 +75,8 @@ protected:
 	QPoint m_mousePos;
 	bool m_mousePressed {false};
 	bool m_thumb {false};
-	QString m_prefsContext = "PagePalette";
-	QString m_prefsName = "showMasterThumbnails";
+	QString m_prefsContext = "PagePalette";
+	QString m_prefsName = "showMasterThumbnails";
 
 };
 
@@ -134,7 +134,10 @@ public:
 	void setPageLayout(PageLayout layout);
 	PageLayout pageLayout() { return m_pageLayout; };
 
-	void setPageOffset(int pageCount);
+	/**
+	 * @param offset currrently it's 0 for single page document documents, 0 or 1 for double page document.
+	 */
+	void setPageOffset(int offset);
 	int pageOffset() { return m_pageOffset; };
 
 	QList<PageCell*> pageList {QList<PageCell*>()};
@@ -148,6 +151,7 @@ public:
 	int pageHeight();
 
 	void setSelectedPage(int pageID);
+	void setBindingDirection(int rtl_binding);
 	int selectedPage() { return m_selectedPage; };
 
 	void deleteSelectedPage();
@@ -190,6 +194,7 @@ private:
 	int m_cellsInGroup {1}; // 1 for single page
 	int m_pageOffset {0};
 	QMenu *m_contextMenu {nullptr};
+	bool m_rtlBinding = false;
 
 	int columns();
 	int rows();
diff --git a/scribus/ui/prefs_documentsetup.cpp b/scribus/ui/prefs_documentsetup.cpp
index f5fc66b9a..29c13c4b0 100644
--- a/scribus/ui/prefs_documentsetup.cpp
+++ b/scribus/ui/prefs_documentsetup.cpp
@@ -63,6 +63,9 @@ Prefs_DocumentSetup::Prefs_DocumentSetup(QWidget* parent, ScribusDoc* doc)
 	layoutFirstPageIsComboBox->addItem(" ");
 	layoutFirstPageIsComboBox->setCurrentIndex(0);
 	layoutFirstPageIsComboBox->setEnabled(false);
+	bindingDirectionButtonGroup->setId(leftToRightRadioButton, 0);
+	bindingDirectionButtonGroup->setId(rightToLeftRadioButton, 1);
+	leftToRightRadioButton->setChecked(true);
 
 	pageWidthSpinBox->setMaximum(16777215);
 	pageHeightSpinBox->setMaximum(16777215);
@@ -176,6 +179,16 @@ void Prefs_DocumentSetup::restoreDefaults(struct ApplicationPrefs *prefsData)
 
 	layoutFirstPageIsComboBox->setCurrentIndex(prefsData->pageSets[prefsData->docSetupPrefs.pagePositioning].FirstPage);
 
+	switch (prefsData->docSetupPrefs.bindingDirection)
+	{
+		case 0:
+			leftToRightRadioButton->setChecked(true);
+			break;
+		case 1:
+			rightToLeftRadioButton->setChecked(true);
+			break;
+	}
+
 	pageWidthSpinBox->blockSignals(false);
 	pageHeightSpinBox->blockSignals(false);
 	pageOrientationComboBox->blockSignals(false);
@@ -221,6 +234,7 @@ void Prefs_DocumentSetup::saveGuiToPrefs(struct ApplicationPrefs *prefsData) con
 	prefsData->docSetupPrefs.pageWidth = pageW;
 	prefsData->docSetupPrefs.pageHeight = pageH;
 	prefsData->docSetupPrefs.pagePositioning = pageLayoutButtonGroup->checkedId();
+	prefsData->docSetupPrefs.bindingDirection = bindingDirectionButtonGroup->checkedId();
 	prefsData->pageSets[prefsData->docSetupPrefs.pagePositioning].FirstPage = layoutFirstPageIsComboBox->currentIndex();
 
 	prefsData->docSetupPrefs.margins = marginsWidget->margins();
diff --git a/scribus/ui/prefs_documentsetupbase.ui b/scribus/ui/prefs_documentsetupbase.ui
index 008af5be5..cec1365ef 100644
--- a/scribus/ui/prefs_documentsetupbase.ui
+++ b/scribus/ui/prefs_documentsetupbase.ui
@@ -307,6 +307,33 @@
            </attribute>
           </widget>
          </item>
+         <item row="5" column="0">
+          <widget class="QLabel" name="layoutBindingDirectionLabel">
+           <property name="text">
+            <string>Binding Direction:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="5" column="1">
+          <widget class="QRadioButton" name="leftToRightRadioButton">
+           <property name="text">
+            <string>Left to Right</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">bindingDirectionButtonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item row="6" column="1">
+          <widget class="QRadioButton" name="rightToLeftRadioButton">
+           <property name="text">
+            <string>Right to Left</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">bindingDirectionButtonGroup</string>
+           </attribute>
+          </widget>
+         </item>
         </layout>
        </item>
        <item>
@@ -885,5 +912,6 @@
  </connections>
  <buttongroups>
   <buttongroup name="pageLayoutButtonGroup"/>
+  <buttongroup name="bindingDirectionButtonGroup"/>
  </buttongroups>
 </ui>
