r23169 by jghali - #15438: Multiple duplicate on pages

scribus-commit scribus-commit at lists.scribus.net
Sun Sep 1 14:21:37 UTC 2019


Author: jghali
Date: Sun Sep  1 14:21:37 2019
New Revision: 23169

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23169
Log:
#15438: Multiple duplicate on pages

Modified:
    trunk/Scribus/scribus/pageitem.cpp
    trunk/Scribus/scribus/pageitem.h
    trunk/Scribus/scribus/scribus.cpp
    trunk/Scribus/scribus/scribusdoc.cpp
    trunk/Scribus/scribus/scribusdoc.h
    trunk/Scribus/scribus/ui/multipleduplicate.cpp
    trunk/Scribus/scribus/ui/multipleduplicate.h
    trunk/Scribus/scribus/ui/multipleduplicate.ui
    trunk/Scribus/scribus/usertaskstructs.h

Modified: trunk/Scribus/scribus/pageitem.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/pageitem.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem.cpp	(original)
+++ trunk/Scribus/scribus/pageitem.cpp	Sun Sep  1 14:21:37 2019
@@ -10025,6 +10025,27 @@
 	return last;
 }
 
+PageItem* PageItem::lastInChainSamePage()
+{
+	//huh? Q_ASSERT(this != nullptr);
+	PageItem* last = this;
+	while (last->OwnPage != OwnPage && last->nextInChain() != nullptr)
+		last = last->nextInChain();
+	return last;
+}
+
+bool PageItem::areNextInChainOnSamePage() const
+{
+	const PageItem* next = this;
+	while (next->nextInChain() != nullptr)
+	{
+		next = next->nextInChain();
+		if (next->OwnPage != this->OwnPage)
+			return false;
+	}
+	return true;
+}
+
 QRect PageItem::getRedrawBounding(double viewScale) const
 {
 	int x = qRound(floor(BoundingX - m_oldLineWidth / 2.0 - 5) * viewScale);

Modified: trunk/Scribus/scribus/pageitem.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/pageitem.h
==============================================================================
--- trunk/Scribus/scribus/pageitem.h	(original)
+++ trunk/Scribus/scribus/pageitem.h	Sun Sep  1 14:21:37 2019
@@ -467,11 +467,13 @@
 	//you can change all code for search first or last item in chain
 	PageItem* firstInChain();
 	PageItem* lastInChain();
+	PageItem* lastInChainSamePage();
 	PageItem* prevInChain() { return BackBox; }
 	PageItem* nextInChain() { return NextBox; }
 	const PageItem* prevInChain() const { return BackBox; }
 	const PageItem* nextInChain() const { return NextBox; }
 	bool isInChain() const { return ((BackBox != nullptr) || (NextBox != nullptr)); }
+	bool areNextInChainOnSamePage() const;
 
 	bool canBeLinkedTo(const PageItem* nextFrame) const;
 	void unlink(bool createUndo = true);

Modified: trunk/Scribus/scribus/scribus.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/scribus.cpp
==============================================================================
--- trunk/Scribus/scribus/scribus.cpp	(original)
+++ trunk/Scribus/scribus/scribus.cpp	Sun Sep  1 14:21:37 2019
@@ -92,7 +92,6 @@
 #include <sstream>
 #include <csignal>
 #include <string>
-
 
 #include "actionmanager.h"
 #include "actionsearch.h"
@@ -261,6 +260,7 @@
 #include "undostate.h"
 #include "units.h"
 #include "urllauncher.h"
+#include "usertaskstructs.h"
 #include "util.h"
 #include "util_file.h"
 #include "util_formats.h"
@@ -6456,7 +6456,6 @@
 		trans = m_undoManager->beginTransaction(Um::Selection, Um::IPolygon, Um::Duplicate, "", Um::IMultipleDuplicate);
 
 	ItemMultipleDuplicateData mdData;
-	memset(&mdData, 0, sizeof(mdData));
 	mdData.type = 0;
 	mdData.copyCount = 1;
 	mdData.copyShiftOrGap = 0;
@@ -6492,7 +6491,7 @@
 	if (doc->appMode == modeEditClip)
 		view->requestMode(submodeEndNodeEdit);
 	internalCopy = true;
-	QScopedPointer<MultipleDuplicate> dia(new MultipleDuplicate(doc->unitIndex(), this));
+	QScopedPointer<MultipleDuplicate> dia(new MultipleDuplicate(this, doc));
 	if (dia->exec())
 	{
 		ItemMultipleDuplicateData mdData;

Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp	(original)
+++ trunk/Scribus/scribus/scribusdoc.cpp	Sun Sep  1 14:21:37 2019
@@ -13442,10 +13442,13 @@
 	return nr;
 }
 
-void ScribusDoc::itemSelection_MultipleDuplicate(ItemMultipleDuplicateData& mdData)
+void ScribusDoc::itemSelection_MultipleDuplicate(const ItemMultipleDuplicateData& mdData)
 {
 	if ((mdData.type==0 && mdData.copyCount<1) || (mdData.type==1 && (mdData.gridRows==1 && mdData.gridCols==1)))
 		return;
+	if ((mdData.type == 2) && (Pages->count() == 1))
+		return;
+
 	QString tooltip;
 	UndoTransaction activeTransaction;
 
@@ -13572,6 +13575,10 @@
 		QString vString = QString::number(mdData.gridGapV, 'f', unitPrecision) + " " + unitSuffix;
 		tooltip = tr("Number of rows: %1\nNumber of columns: %2\nHorizontal gap: %3\nVertical gap: %4").arg(mdData.gridRows).arg(mdData.gridCols).arg(hString).arg(vString).arg(unitSuffix);
 	}
+	else if (mdData.type == 2)
+	{
+		multipleDuplicateByPage(mdData, selection, tooltip);
+	}
 	if (activeTransaction)
 	{
 		activeTransaction.commit("", nullptr, "", tooltip, nullptr);
@@ -13582,6 +13589,92 @@
 	m_View->Deselect(true);
 	view()->DrawNew();
 	changed();
+}
+
+void ScribusDoc::multipleDuplicateByPage(const ItemMultipleDuplicateData& dialogData, Selection& selection, QString& tooltip)
+{
+	int currPageNumber = currentPageNumber();
+	std::vector<int> pages;
+	QString pageRange;
+
+	if (dialogData.pageSelection == 1)
+		pageRange = QString("%1-%2").arg(1).arg(Pages->count());
+	else if ((dialogData.pageSelection == 2) || dialogData.pageSelection == 3)
+	{
+		int start = currentPageNumber() + 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)
+			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)
+	{
+		for (auto item: selection.items())
+		{
+			// get the first text frame in the selection, the first frame in the chain
+			if (item->itemType() != PageItem::TextFrame)
+				continue;
+			if (item->isInChain() && item->areNextInChainOnSamePage())
+			{
+				lastInChain = item->lastInChain();
+				assert( !lastInChain->nextInChain() );
+			}
+			else
+			{
+				lastInChain = item;
+			}
+			break;
+		}
+	}
+
+	ScPage* oldCurrentPage = currentPage();
+	ScriXmlDoc xmlStream;
+	QString buffer = xmlStream.writeElem(this, &selection);
+	for (const auto page: pages)
+	{
+		if (currPageNumber == page - 1)
+			continue;
+		ScPage* targetPage = Pages->at(page - 1);
+		setCurrentPage(targetPage);
+		int countBeforeInsert = Items->count();
+		xmlStream.readElem(buffer, m_appPrefsData.fontPrefs.AvailFonts, this, currentPage()->xOffset(), currentPage()->yOffset(), false, true, m_appPrefsData.fontPrefs.GFontSub);
+		if (!lastInChain)
+			continue;
+		for (int i = countBeforeInsert; i < Items->count(); ++i)
+		{
+			PageItem* item = Items->at(i);
+			if (item->itemType() != PageItem::TextFrame)
+				continue;
+			if (item->isInChain())
+			{
+				lastInChain->link(item->firstInChain());
+				lastInChain = item->lastInChain();
+			}
+			else
+			{
+				lastInChain->link(item);
+				lastInChain = item;
+			}
+			break;
+		}
+	}
+
+	setCurrentPage(oldCurrentPage);
+
+	tooltip = tr("Copied %1 items on %2 pages").arg(selection.count()).arg(pages.size());
 }
 
 

Modified: trunk/Scribus/scribus/scribusdoc.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/scribusdoc.h
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.h	(original)
+++ trunk/Scribus/scribus/scribusdoc.h	Sun Sep  1 14:21:37 2019
@@ -1527,7 +1527,7 @@
 	void itemSelection_DistributeTop();
 	void itemSelection_SwapLeft();
 	void itemSelection_SwapRight();
-	void itemSelection_MultipleDuplicate(ItemMultipleDuplicateData&);
+	void itemSelection_MultipleDuplicate(const ItemMultipleDuplicateData&);
 	void itemSelection_UniteItems(Selection* customSelection = nullptr);
 	void itemSelection_SplitItems(Selection* customSelection = nullptr);
 	/**
@@ -1707,6 +1707,8 @@
 	QList<TextNote*> m_docNotesList;
 	//flags used for indicating needs of updates
 	bool m_flag_notesChanged {false};
+
+	void multipleDuplicateByPage(const ItemMultipleDuplicateData& mdData, Selection& selection, QString& tooltip);
 
 public:
 	const QList<Mark*> marksList() { return m_docMarksList; }

Modified: trunk/Scribus/scribus/ui/multipleduplicate.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/ui/multipleduplicate.cpp
==============================================================================
--- trunk/Scribus/scribus/ui/multipleduplicate.cpp	(original)
+++ trunk/Scribus/scribus/ui/multipleduplicate.cpp	Sun Sep  1 14:21:37 2019
@@ -13,21 +13,24 @@
 #include <QSpinBox>
 #include <QTabWidget>
 
+#include "iconmanager.h"
+#include "scribusdoc.h"
 #include "scrspinbox.h"
 #include "units.h"
+#include "ui/createrange.h"
 #include "usertaskstructs.h"
 
-MultipleDuplicate::MultipleDuplicate( int unitIndex, QWidget* parent) : QDialog(parent), m_unitIndex(unitIndex)
+MultipleDuplicate::MultipleDuplicate(QWidget* parent, ScribusDoc *doc) : QDialog(parent), m_Doc(doc)
 {
 	setupUi(this);
 
-	m_unitRatio = unitGetRatioFromIndex(m_unitIndex);
+	m_unitRatio = unitGetRatioFromIndex(m_Doc->unitIndex());
 
 	//set up mspinboxes
-	horizShiftSpinBox->setNewUnit(unitIndex);
-	vertShiftSpinBox->setNewUnit(unitIndex);
-	horizRCGapSpinBox->setNewUnit(unitIndex);
-	vertRCGapSpinBox->setNewUnit(unitIndex);
+	horizShiftSpinBox->setNewUnit(m_Doc->unitIndex());
+	vertShiftSpinBox->setNewUnit(m_Doc->unitIndex());
+	horizRCGapSpinBox->setNewUnit(m_Doc->unitIndex());
+	vertRCGapSpinBox->setNewUnit(m_Doc->unitIndex());
 	horizShiftSpinBox->setMinimum(-1000);
 	vertShiftSpinBox->setMinimum(-1000);
 	horizRCGapSpinBox->setMinimum(-1000);
@@ -43,9 +46,16 @@
 	
 	createGapRadioButton->setChecked(true);
 	setCopiesGap();
+
+	toolButtonPageRange->setIcon(IconManager::instance().loadIcon("ellipsis.png"));
+	radioButtonPageAll->setChecked(true);
+
 	// signals and slots connections
 	connect(createGapRadioButton, SIGNAL(clicked()), this, SLOT(setCopiesGap()));
 	connect(shiftCreatedItemsRadioButton, SIGNAL(clicked()), this, SLOT(setCopiesShift()));
+
+	connect(lineEditPageRange, &QLineEdit::textChanged, this, &MultipleDuplicate::selectRangeOfPages);
+	connect(toolButtonPageRange, &QToolButton::clicked, this, &MultipleDuplicate::createPageNumberRange);
 }
 
 MultipleDuplicate::~MultipleDuplicate()
@@ -76,4 +86,35 @@
 	mdData.gridCols = gridColsSpinBox->value();
 	mdData.gridGapH = horizRCGapSpinBox->value();
 	mdData.gridGapV = vertRCGapSpinBox->value();
+	if (radioButtonPageAll->isChecked())
+		mdData.pageSelection = 1;
+	else if (radioButtonPageEven->isChecked())
+		mdData.pageSelection = 2;
+	else if (radioButtonPageOdd->isChecked())
+		mdData.pageSelection = 3;
+	else if (radioButtonPageRange->isChecked())
+		mdData.pageSelection = 4;
+	mdData.pageRange = lineEditPageRange->text();
+	mdData.pageLinkText = checkBoxPageLinkText->isChecked();
 }
+
+void MultipleDuplicate::selectRangeOfPages()
+{
+	radioButtonPageRange->setChecked(true);
+}
+
+void MultipleDuplicate::createPageNumberRange()
+{
+	if (m_Doc!=0)
+	{
+		CreateRange cr(lineEditPageRange->text(), m_Doc->Pages->count(), this);
+		if (cr.exec())
+		{
+			CreateRangeData crData;
+			cr.getCreateRangeData(crData);
+			lineEditPageRange->setText(crData.pageRange);
+			return;
+		}
+	}
+	lineEditPageRange->setText(QString::null);
+}

Modified: trunk/Scribus/scribus/ui/multipleduplicate.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/ui/multipleduplicate.h
==============================================================================
--- trunk/Scribus/scribus/ui/multipleduplicate.h	(original)
+++ trunk/Scribus/scribus/ui/multipleduplicate.h	Sun Sep  1 14:21:37 2019
@@ -9,20 +9,24 @@
 
 #include "ui_multipleduplicate.h"
 struct ItemMultipleDuplicateData;
+class ScribusDoc;
 
 class MultipleDuplicate : public QDialog, Ui::MultipleDuplicate
 {
 	Q_OBJECT
 	public:
-		MultipleDuplicate(int unitIndex, QWidget* parent);
+		MultipleDuplicate(QWidget* parent, ScribusDoc *doc);
 		~MultipleDuplicate();
 		void getMultiplyData(ItemMultipleDuplicateData&);
 	protected:
-		int m_unitIndex;
+		// int m_unitIndex;
+		ScribusDoc *m_Doc;
 		double m_unitRatio;
 	protected slots:
 		void setCopiesShift();
 		void setCopiesGap();
+		void selectRangeOfPages();
+		void createPageNumberRange();
 };
 
 #endif

Modified: trunk/Scribus/scribus/ui/multipleduplicate.ui
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/ui/multipleduplicate.ui
==============================================================================
--- trunk/Scribus/scribus/ui/multipleduplicate.ui	(original)
+++ trunk/Scribus/scribus/ui/multipleduplicate.ui	Sun Sep  1 14:21:37 2019
@@ -9,7 +9,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>300</width>
+    <width>329</width>
     <height>302</height>
    </rect>
   </property>
@@ -337,6 +337,95 @@
        </item>
        <item>
         <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab3">
+      <attribute name="title">
+       <string>By &Page</string>
+      </attribute>
+      <layout class="QVBoxLayout" name="verticalLayout_8">
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_7">
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageAll">
+           <property name="text">
+            <string>&All Pages</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageEven">
+           <property name="text">
+            <string>Following &Even Pages</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageOdd">
+           <property name="text">
+            <string>Following &Odd Pages</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageRange">
+           <property name="text">
+            <string>Ran&ge of Pages:</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <layout class="QHBoxLayout" name="horizontalLayout">
+           <item>
+            <widget class="QLineEdit" name="lineEditPageRange"/>
+           </item>
+           <item>
+            <widget class="QToolButton" name="toolButtonPageRange">
+             <property name="text">
+              <string>...</string>
+             </property>
+            </widget>
+           </item>
+          </layout>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <layout class="QVBoxLayout" name="verticalLayout_9">
+         <item>
+          <widget class="QCheckBox" name="checkBoxPageLinkText">
+           <property name="text">
+            <string>&Link Text Frames</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_5">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
@@ -468,4 +557,7 @@
    </hints>
   </connection>
  </connections>
+ <buttongroups>
+  <buttongroup name="buttonGroup"/>
+ </buttongroups>
 </ui>

Modified: trunk/Scribus/scribus/usertaskstructs.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/usertaskstructs.h
==============================================================================
--- trunk/Scribus/scribus/usertaskstructs.h	(original)
+++ trunk/Scribus/scribus/usertaskstructs.h	Sun Sep  1 14:21:37 2019
@@ -34,16 +34,19 @@
 
 struct ItemMultipleDuplicateData
 {
-	int type;
-	int copyCount;
-	int copyShiftOrGap;
-	double copyShiftGapH;
-	double copyShiftGapV;
-	double copyRotation;
-	int gridRows;
-	int gridCols;
-	double gridGapH;
-	double gridGapV;
+	int type = 0;
+	int copyCount = 0;
+	int copyShiftOrGap = 0;
+	double copyShiftGapH = 0.0;
+	double copyShiftGapV = 0.0;
+	double copyRotation = 0.0;
+	int gridRows = 0;
+	int gridCols = 0;
+	double gridGapH = 0.0;
+	double gridGapV = 0.0;
+	int pageSelection = 0; // 1 = All, 2 = Even, 3 = Odd, 4 = Range
+	QString pageRange;
+	bool pageLinkText = false;
 };
 
 struct CreateRangeData




More information about the scribus-commit mailing list