Index: resources/iconsets/1_7_0/1_7_0.xml =================================================================== --- resources/iconsets/1_7_0/1_7_0.xml (revision 27528) +++ resources/iconsets/1_7_0/1_7_0.xml (working copy) @@ -387,6 +387,8 @@ + + Index: scribus/plugins/fileloader/scribus171format/scribus171format.cpp =================================================================== --- scribus/plugins/fileloader/scribus171format/scribus171format.cpp (revision 27528) +++ scribus/plugins/fileloader/scribus171format/scribus171format.cpp (working copy) @@ -2533,7 +2533,7 @@ 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"); m_Doc->PageSpa = attrs.valueAsDouble("ABSTSPALTEN"); @@ -2599,7 +2599,7 @@ 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"); m_Doc->PageSpa = attrs.valueAsDouble("AutomaticTextFrameColumnGap"); Index: scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp =================================================================== --- scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp (revision 27528) +++ scribus/plugins/fileloader/scribus171format/scribus171format_save.cpp (working copy) @@ -336,6 +336,7 @@ 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); Index: scribus/plugins/scriptplugin/cmddoc.cpp =================================================================== --- scribus/plugins/scriptplugin/cmddoc.cpp (revision 27528) +++ scribus/plugins/scriptplugin/cmddoc.cpp (working copy) @@ -15,22 +15,20 @@ #include -/* -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 @@ 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 @@ // 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(ret)); Index: scribus/plugins/scriptplugin/cmddoc.h =================================================================== --- scribus/plugins/scriptplugin/cmddoc.h (revision 27528) +++ scribus/plugins/scriptplugin/cmddoc.h (working copy) @@ -14,7 +14,7 @@ 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,8 +42,10 @@ 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\ is not in points, make sure to account for this.\n\ Index: scribus/prefsmanager.cpp =================================================================== --- scribus/prefsmanager.cpp (revision 27528) +++ scribus/prefsmanager.cpp (working copy) @@ -459,6 +459,7 @@ 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; @@ -1390,6 +1391,7 @@ 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(appPrefs.docSetupPrefs.AutoSave)); deDocumentSetup.setAttribute("AutoSaveTime", appPrefs.docSetupPrefs.AutoSaveTime); deDocumentSetup.setAttribute("AutoSaveCount", appPrefs.docSetupPrefs.AutoSaveCount); @@ -2092,6 +2094,7 @@ 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(dc.attribute("AutoSave", "0").toInt()); appPrefs.docSetupPrefs.AutoSaveTime = dc.attribute("AutoSaveTime", "600000").toInt(); appPrefs.docSetupPrefs.AutoSaveCount = dc.attribute("AutoSaveCount", "1").toInt(); Index: scribus/prefsstructs.h =================================================================== --- scribus/prefsstructs.h (revision 27528) +++ scribus/prefsstructs.h (working copy) @@ -168,6 +168,7 @@ bool AutoSaveLocation; QString AutoSaveDir; bool saveCompressed; + int bindingDirection; //! 0 = LTR, 1 = RTL }; //Guides Index: scribus/scribus.cpp =================================================================== --- scribus/scribus.cpp (revision 27528) +++ scribus/scribus.cpp (working copy) @@ -340,7 +340,7 @@ 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); @@ -2035,6 +2035,7 @@ { 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(); @@ -2048,7 +2049,10 @@ 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(); @@ -2111,6 +2115,7 @@ 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(); @@ -2125,7 +2130,7 @@ 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()); @@ -2150,7 +2155,7 @@ 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(); @@ -2198,7 +2203,7 @@ 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++; @@ -9218,7 +9223,7 @@ 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); Index: scribus/scribus.h =================================================================== --- scribus/scribus.h (revision 27528) +++ scribus/scribus.h (working copy) @@ -154,7 +154,7 @@ 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* 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); 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); bool DoFileSave(const QString& fileName, QString* savedFileName = nullptr, uint formatID = FORMATID_CURRENTEXPORT); Index: scribus/scribusdoc.cpp =================================================================== --- scribus/scribusdoc.cpp (revision 27528) +++ scribus/scribusdoc.cpp (working copy) @@ -681,7 +681,7 @@ 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); @@ -689,6 +689,7 @@ m_docPrefsData.docSetupPrefs.pageSize = defaultPageSize; FirstPnum = firstPageNumber; m_docPrefsData.docSetupPrefs.pagePositioning = fp; + m_docPrefsData.docSetupPrefs.bindingDirection = bindingDirection; setDocumentFileName(documentName); HasCMS = false; if (!pdfOptions().UseLPI) @@ -6203,11 +6204,22 @@ 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(); @@ -6247,29 +6259,63 @@ page->setYOffset(currentYPos); if (counter < pageSets()[m_docPrefsData.docSetupPrefs.pagePositioning].Columns-1) { - currentXPos += page->width() + m_docPrefsData.displayPrefs.pageGapHorizontal; + if (rtlBinding) + { + // check width of next page for correct offset + int w = i < Pages->size() - 1 ? Pages->at(i+1)->width() : page->width(); + currentXPos -= w + 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) @@ -14166,51 +14212,45 @@ int lastPage = 0; for (auto item : selection.items()) { - if (item->OwnPage >= 0) - { - if (item->OwnPage < firstPage) - firstPage = item->OwnPage; - if (item->OwnPage > lastPage) - lastPage = item->OwnPage; - } + if ((item->OwnPage >= 0) && (item->OwnPage < firstPage)) + firstPage = item->OwnPage; + if ((item->OwnPage) >= 0 && (item->OwnPage > lastPage)) + lastPage = item->OwnPage; } setCurrentPage(Pages->at(firstPage)); int pageSpread = lastPage - firstPage + 1; QStringList pageList; - // with multi-page selection, only "following pages" is available - for (int i = lastPage + 2; i < Pages->count(); i += pageSpread) - pageList << QString::number(i); - pageRange = pageList.join(','); - } - else - { if (dialogData.pageSelection == 1) - pageRange = QString("%1-%2").arg(currPageNumber + 2).arg(Pages->count()); - else if ((dialogData.pageSelection == 2) || dialogData.pageSelection == 3) - { - int start = currPageNumber + 2; - // round to the next odd / even number - if (dialogData.pageSelection == 2) - start += start % 2; - else - start += 1 - (start % 2); - - QStringList pageList; - for (int i = start; i <= Pages->count(); i += 2) + for (int i = lastPage + 2; i < Pages->count(); i += pageSpread) pageList << QString::number(i); - pageRange = pageList.join(','); - } else if (dialogData.pageSelection == 4) { + // TODO: what to do with manual selections? pageRange = dialogData.pageRange; } + pageRange = pageList.join(','); } - parsePagesString(pageRange, &pages, Pages->count()); + else if (dialogData.pageSelection == 1) + pageRange = QString("%1-%2").arg(currPageNumber + 2).arg(Pages->count()); + else if ((dialogData.pageSelection == 2) || dialogData.pageSelection == 3) + { + int start = currPageNumber + 2; + // round to the next odd / even number + if (dialogData.pageSelection == 2) + start += start % 2; + else + start += 1 - (start % 2); - if (dialogData.copyCount > 0 && dialogData.copyCount < pages.size()) { - pages.resize(dialogData.copyCount); - pages.shrink_to_fit(); + QStringList pageList; + for (int i = start; i <= Pages->count(); i += 2) + pageList << QString::number(i); + pageRange = pageList.join(','); } + else if (dialogData.pageSelection == 4) + { + pageRange = dialogData.pageRange; + } + parsePagesString(pageRange, &pages, Pages->count()); PageItem* lastInChain = nullptr; if (dialogData.pageLinkText) Index: scribus/scribusdoc.h =================================================================== --- scribus/scribusdoc.h (revision 27528) +++ scribus/scribusdoc.h (working copy) @@ -107,7 +107,10 @@ bool inASpecialEditMode() const; QList getAllItems(const QList &items) const; QList *parentGroup(PageItem* item, QList *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 @@ 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; } Index: scribus/ui/newdocdialog.cpp =================================================================== --- scribus/ui/newdocdialog.cpp (revision 27528) +++ scribus/ui/newdocdialog.cpp (working copy) @@ -63,6 +63,7 @@ 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")); @@ -69,6 +70,10 @@ 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(); @@ -112,6 +117,7 @@ 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,14 +161,17 @@ if (pagePositioning == singlePage) { pageLayoutButtons->button(0)->setChecked(true); + buttonBindingDirection->setDisabled(true); } else if (prefsManager.appPrefs.pageSets.at(pagePositioning).FirstPage == 0) { pageLayoutButtons->button(1)->setChecked(true); + buttonBindingDirection->setDisabled(false); } else { pageLayoutButtons->button(2)->setChecked(true); + buttonBindingDirection->setDisabled(false); } listPageFormats->setValues(pageSize, orientation, PageSizeInfo::Preferred, PageSizeList::NameAsc); @@ -525,20 +534,28 @@ { 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); Index: scribus/ui/newdocdialog.h =================================================================== --- scribus/ui/newdocdialog.h (revision 27528) +++ scribus/ui/newdocdialog.h (working copy) @@ -76,6 +76,7 @@ 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 @@ 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 @@ 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 }; Index: scribus/ui/newdocdialog.ui =================================================================== --- scribus/ui/newdocdialog.ui (revision 27528) +++ scribus/ui/newdocdialog.ui (working copy) @@ -474,6 +474,16 @@ + + + + + + + true + + + Index: scribus/ui/pagepalette_pages.cpp =================================================================== --- scribus/ui/pagepalette_pages.cpp (revision 27528) +++ scribus/ui/pagepalette_pages.cpp (working copy) @@ -379,12 +379,10 @@ 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,10 +454,7 @@ return; pageViewWidget->pageGrid()->setSelectionColor(PrefsManager::instance().appPrefs.displayPrefs.pageBorderColor); - -// if (currView) -// connect(currView->m_doc, SIGNAL(pagePreviewChanged()), this, SLOT(updatePagePreview())); - + pageViewWidget->pageGrid()->setBindingDirection(view->m_doc->bindingDirection()); } void PagePalette_Pages::selMasterPage() Index: scribus/ui/pagepalette_widgets.cpp =================================================================== --- scribus/ui/pagepalette_widgets.cpp (revision 27528) +++ scribus/ui/pagepalette_widgets.cpp (working copy) @@ -318,7 +318,7 @@ void PageGrid::setPageOffset(int pageCount) { - m_pageOffset = pageCount; + m_pageOffset = columnNormalized(pageCount); calculateSize(); update(); } @@ -328,6 +328,8 @@ if ( r == -1 || c == -1) return -1; + c = columnNormalized(c); + int id = (r == 0) ? c : r * columns() + c; id -= m_pageOffset; @@ -363,9 +365,9 @@ return m_rowHeight - m_fontSize - m_labelGap; } -void PageGrid::setSelectedPage(int pageID) +void PageGrid::setSelectedPage(int pageId) { - m_selectedPage = clampPageId(pageID); + m_selectedPage = clampPageId(pageId); update(); } @@ -398,6 +400,11 @@ return qCeil( (double)(pageCount() + m_pageOffset + 1) / (double)columns() ); } +int PageGrid::columnNormalized(int column) +{ + return m_rtlBinding ? columns() - column - 1: column; +} + int PageGrid::columnAt(QPoint pos) { if(pageCount() == 0) return -1; @@ -407,29 +414,21 @@ int m_col = -1; - int cellId = row * m_cellsInGroup; - int pageId = cellId - m_pageOffset; QRect cellRect(m_groupSpace, m_rowSpace + row * (rowHeight() + m_rowSpace), dummyPageSize().width(), rowHeight()); int width = 0; - for (int i = 0; i < m_cellsInGroup; ++i) + for (int i = 0; i <= m_cellsInGroup; ++i) { + int id = pageId(row, i, false); - int id = cellId + i; - // skip empty cells - if (id < m_pageOffset || id >= pageCount() + m_pageOffset) + if (pageInRange(id)) { - //qDebug() << "Cell" << id << "is Empty"; - width = dummyPageSize().width(); + PageCell *pc = pageList.at(id); + width = pc->pageWidthByHeight(pageHeight()); } else - { - //qDebug() << "Cell" << id << "is Page" << "PageId" << pageId + i; - PageCell *pc = pageList.at(pageId + i); - width = pc->pageWidthByHeight(pageHeight()); - } - + width = dummyPageSize().width(); cellRect.setWidth( width ); if(cellRect.contains(pos)) @@ -462,24 +461,19 @@ { if(pageCount() == 0 || rowId < 0) return -1; - int cellId = rowId * m_cellsInGroup; - int pageId = cellId - m_pageOffset; int width = 0; for (int i = 0; i < m_cellsInGroup; ++i) { - int id = cellId + i; + int id = pageId(rowId, i, false); - if (id < m_pageOffset || id >= pageCount() + m_pageOffset) + if (pageInRange(id)) { - width += dummyPageSize().width(); + PageCell *pc = pageList.at(id); + width += pc->pageWidthByHeight(pageHeight()); } else - { - PageCell *pc = pageList.at(pageId + i); - width += pc->pageWidthByHeight(pageHeight()); - } - + width += dummyPageSize().width(); width += m_cellGap; }; @@ -494,33 +488,27 @@ { if ( row == -1 || col == -1) return QRect(); - int cellId = row * m_cellsInGroup; - int pageId = cellId - m_pageOffset; QRect cellRect(m_groupSpace, m_rowSpace + row * (rowHeight() + m_rowSpace), dummyPageSize().width(), rowHeight()); int width = 0; - for (int i = 0; i < m_cellsInGroup; ++i) + for (int i = 0; i <= m_cellsInGroup; ++i) { - int id = cellId + i; + int id = pageId(row, i, false); // skip empty cells - if (id < m_pageOffset || id >= pageCount() + m_pageOffset) + if (pageInRange(id)) { - width = dummyPageSize().width(); + PageCell *pc = pageList.at(id); + width = pc->pageWidthByHeight(pageHeight()); } else - { - PageCell *pc = pageList.at(pageId + i); - width = pc->pageWidthByHeight(pageHeight()); - } + width = dummyPageSize().width(); cellRect.setWidth( width ); - if(i == col) - { + if(id == pageId(row, col, false)) return cellRect; - } cellRect.setX(cellRect.x() + width + m_cellGap); }; @@ -539,7 +527,7 @@ return dummySize; } -QPoint PageGrid::mapPosToCell(QPoint pos, Mode &mode) +QRect PageGrid::mapPosToCell(QPoint pos, Mode &mode) { int col = columnAt(pos); int row = rowAt(pos); @@ -548,7 +536,7 @@ if (col == -1 || row == -1) { mode = Mode::Invalid; - return QPoint(); + return QRect(); } int id = pageId(row, col, false); @@ -557,7 +545,8 @@ int y = cellRect.y(); // cell doesn't have a page - if (id < 0 || id >= pageCount()){ + if (!pageInRange(id)) + { mode = Mode::Add; } else @@ -564,6 +553,10 @@ { // check if mouse is on "insert area" QRect insertArea(x, y, 8, rowHeight()); + + if (m_rtlBinding) + insertArea = QRect(cellRect.right() - 8, y, 8, rowHeight()); + if (insertArea.contains(pos)) mode = Mode::Insert; else @@ -570,26 +563,25 @@ mode = Mode::Hover; } - return QPoint(x,y); + return cellRect; } QPoint PageGrid::pagePosition(int pageId) { - if (pageId < 0 || pageId >= pageCount()) return QPoint(); + if (!pageInRange(pageId)) + return QPoint(); int row = qCeil( (pageId + m_pageOffset) / m_cellsInGroup ); - int col = 0; - - return rectAt(row, col).topLeft(); + return rectAt(row, 0).topLeft(); } -int PageGrid::clampPageId(int pageID, bool allowPlusOne) +int PageGrid::clampPageId(int pageId, bool allowPlusOne) { // Always returns 0 if there is no page in the page list if (pageCount() == 0) return 0; int max = (allowPlusOne) ? pageCount() : pageCount() -1; - return qBound( 0, pageID, max); + return qBound( 0, pageId, max); } @@ -606,7 +598,7 @@ int id = pageId(row, col); // check if page id is in range of an existing cell - if (id > -1 && id < pageCount() ) + if (pageInRange(id)) { int newSelectedPage = clampPageId( id ); @@ -623,7 +615,7 @@ void PageGrid::updateModeMarker(QPoint pos) { Mode mode; - QPoint mapPos = mapPosToCell(pos, mode); + QRect mapPos = mapPosToCell(pos, mode); // check if mouse is on "insert area" switch (mode) @@ -636,7 +628,11 @@ case Mode::Insert: { int selectorWidth = 4; - int offsetX = mapPos.x() - selectorWidth / 2 - qRound((double)m_cellGap / 2); + int offsetX; + if (m_rtlBinding) + offsetX = mapPos.right() - selectorWidth / 2 + qRound((double)m_cellGap / 2); + else + offsetX = mapPos.left() - selectorWidth / 2 - qRound((double)m_cellGap / 2); m_rectInsert = QRect(offsetX, mapPos.y() - 4, selectorWidth, pageHeight() + 8 ); m_rectAdd = QRect(); m_hoveredPage = -1; @@ -789,6 +785,11 @@ m_contextMenu->exec( mapToGlobal(pos) ); } +void PageGrid::setBindingDirection(int rtl_binding) +{ + m_rtlBinding = rtl_binding == 1; +} + /* ********************************************************************************* * * * Events @@ -797,8 +798,6 @@ void PageGrid::paintEvent(QPaintEvent *event) { - - int count = 0; int x = m_groupSpace; int y = m_rowSpace; int offset = 0; @@ -824,15 +823,15 @@ for (int c = 0; c < columns(); c++) { - + int id = pageId(r, c, false); + int maxCells = m_rtlBinding ? columns() : 0; // cell is after last page cell - if (count >= pageCount() + m_pageOffset) + if (id >= pageCount() + maxCells) break; // cell is a page cell - if (count >= m_pageOffset && count < pageCount() + m_pageOffset) + if (pageInRange(id)) { - int id = count - m_pageOffset; PageCell * cell = getPageItem(id); if (id == m_selectedPage) selectedPageRect = QRect(x, y, cell->pageWidthByHeight(pageHeight()), pageHeight() ); @@ -840,18 +839,22 @@ bool isRightPage = (m_cellsInGroup == c + 1 && m_cellsInGroup > 1); drawTile(painter, pos, cell, (id == m_selectedPage) ? true : false, (id == m_hoveredPage) ? true : false, foregroundColor, isRightPage); + bool ltrLast = !m_rtlBinding && id == pageCount() -1; + bool rtlFirst = m_rtlBinding && id == 0; + // add space only between pages - if ((c + 1) % m_cellsInGroup == 0 || count == pageCount() + m_pageOffset -1) + if ((c + 1) % m_cellsInGroup == 0 || ltrLast || rtlFirst) offset = 0; else offset = m_cellGap; + if(isLastRow(r + 1)) + groupStart = m_rtlBinding ? x : m_groupSpace; + int w = cell->pageWidthByHeight(pageHeight()) + offset; + x += w; + groupWidth += w; - x += cell->pageWidthByHeight(pageHeight()) + offset; - groupWidth += cell->pageWidthByHeight(pageHeight()) + offset; drawGroupRect = true; - - } // cell is before first page cell else @@ -860,11 +863,9 @@ x += dummyPageSize().width() + offset; // adjust start on first row if first page has an offset - if(r == 0) - groupStart = x; + if(isFirstRow(r)) + groupStart = m_rtlBinding ? m_groupSpace : x; } - - count++; } // Draw group border @@ -952,7 +953,7 @@ if ( r == -1 || c == -1 ) return; - int p = pageId(r, c); + int id = pageId(r, c); Mode mode; mapPosToCell(dropEventPos, mode); @@ -960,10 +961,10 @@ { case Mode::Add: case Mode::Insert: - emit newPage(p, tmp); + emit newPage(id, tmp); break; case Mode::Hover: - emit useTemplate(tmp, clampPageId(p)); + emit useTemplate(tmp, clampPageId(id)); break; case Mode::Invalid: break; @@ -1050,9 +1051,9 @@ int row = rowAt(mouseEventPos); int col = columnAt(mouseEventPos); - int pageID = pageId(row, col); + int id = pageId(row, col); - if (pageID > -1 && pageID < pageCount() ) + if (pageInRange(id)) emit click(m_selectedPage, event->button()); } break; Index: scribus/ui/pagepalette_widgets.h =================================================================== --- scribus/ui/pagepalette_widgets.h (revision 27528) +++ scribus/ui/pagepalette_widgets.h (working copy) @@ -75,8 +75,8 @@ 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,6 +134,9 @@ void setPageLayout(PageLayout layout); PageLayout pageLayout() { return m_pageLayout; }; + /** + * @param offset currrently it's 0 for single page document documents, 0 or 1 for double page document. + */ void setPageOffset(int pageCount); int pageOffset() { return m_pageOffset; }; @@ -147,8 +150,9 @@ int pageCount(); int pageHeight(); - void setSelectedPage(int pageID); + void setSelectedPage(int pageId); int selectedPage() { return m_selectedPage; }; + void setBindingDirection(int rtl_binding); void deleteSelectedPage(); void clear(); @@ -190,10 +194,15 @@ int m_cellsInGroup {1}; // 1 for single page int m_pageOffset {0}; QMenu *m_contextMenu {nullptr}; + bool m_rtlBinding = false; int columns(); int rows(); + int columnNormalized(int column); + bool isFirstRow(int row) { return row == 0 ? true : false; }; + bool isLastRow(int row) { return row == rows() ? true : false; }; + int columnAt(QPoint pos); int rowAt(QPoint pos); int rowWidth(int rowId); @@ -201,10 +210,11 @@ QSize dummyPageSize(); - QPoint mapPosToCell(QPoint pos, Mode &mode); + QRect mapPosToCell(QPoint pos, Mode &mode); QPoint pagePosition(int pageId); - int clampPageId(int pageID, bool allowPlusOne = false); + int clampPageId(int pageId, bool allowPlusOne = false); + bool pageInRange(int pageId) { return pageId >= 0 && pageId < pageCount(); }; void updateSelectedPage(QPoint pos); void updateModeMarker(QPoint pos); Index: scribus/ui/preferences/prefs_documentsetup.cpp =================================================================== --- scribus/ui/preferences/prefs_documentsetup.cpp (revision 27528) +++ scribus/ui/preferences/prefs_documentsetup.cpp (working copy) @@ -63,6 +63,9 @@ 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 @@ 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 @@ 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(); Index: scribus/ui/preferences/prefs_documentsetupbase.ui =================================================================== --- scribus/ui/preferences/prefs_documentsetupbase.ui (revision 27528) +++ scribus/ui/preferences/prefs_documentsetupbase.ui (working copy) @@ -39,7 +39,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -68,7 +68,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -83,10 +83,10 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical - QSizePolicy::Policy::Fixed + QSizePolicy::Policy::Fixed @@ -111,7 +111,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -127,12 +127,12 @@ - + - Qt::ArrowType::NoArrow + Qt::ArrowType::NoArrow @@ -209,7 +209,7 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical @@ -241,7 +241,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -260,7 +260,7 @@ - QComboBox::SizeAdjustPolicy::AdjustToContents + QComboBox::SizeAdjustPolicy::AdjustToContents @@ -310,9 +310,36 @@ + + + Binding Direction: + + + + + + + Left to Right + + + bindingDirectionButtonGroup + + + + + + + Right to Left + + + bindingDirectionButtonGroup + + + + - Qt::Orientation::Vertical + Qt::Orientation::Vertical @@ -344,10 +371,10 @@ - QFrame::Shape::NoFrame + QFrame::Shape::NoFrame - QFrame::Shadow::Plain + QFrame::Shadow::Plain 0 @@ -360,8 +387,8 @@ 0 0 - 494 - 575 + 244 + 244 @@ -380,7 +407,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -404,7 +431,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -433,10 +460,10 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical - QSizePolicy::Policy::Fixed + QSizePolicy::Policy::Fixed @@ -461,7 +488,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -485,7 +512,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -500,7 +527,7 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical @@ -538,10 +565,10 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical - QSizePolicy::Policy::Fixed + QSizePolicy::Policy::Fixed @@ -566,7 +593,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -617,7 +644,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -680,10 +707,10 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical - QSizePolicy::Policy::Maximum + QSizePolicy::Policy::Maximum @@ -708,7 +735,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -734,7 +761,7 @@ - Qt::Orientation::Horizontal + Qt::Orientation::Horizontal @@ -749,7 +776,7 @@ - Qt::Orientation::Vertical + Qt::Orientation::Vertical @@ -769,20 +796,20 @@ ScrSpinBox QDoubleSpinBox -
ui/scrspinbox.h
+
ui/scrspinbox.h
NewMarginWidget QWidget -
ui/newmarginwidget.h
+
ui/newmarginwidget.h
1
- - PageSizeSelector - QWidget -
ui/widgets/pagesizeselector.h
- 1 -
+ + PageSizeSelector + QWidget +
ui/widgets/pagesizeselector.h
+ 1 +
tabWidget @@ -885,5 +912,6 @@ +