View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0015438 | Scribus | General | public | 2018-09-25 08:49 | 2019-12-08 21:24 |
| Reporter | ale | Assigned To | ale | ||
| Priority | normal | Severity | feature | Reproducibility | N/A |
| Status | closed | Resolution | fixed | ||
| Product Version | 1.5.5.svn | ||||
| Fixed in Version | 1.5.6.svn | ||||
| Summary | 0015438: Multiple duplicate on pages | ||||
| Description | - i've added a new tab to "item > duplicate > multiple duplicate" to duplicate an item on the following pages (all, even, odd, ranges; with text links). - this tab should replace the "insert > frames" dialog. - this tab should replace the "automatic text frames" in the "file > new" dialog. in the mailing list, there are a few more details: http://lists.scribus.net/pipermail/scribus/2018-September/055315.html | ||||
| Tags | No tags attached. | ||||
| Attached Files | |||||
| Patch | Yes | ||||
| related to | 0010557 | new | New "page dimension" buttons for multiple copy dialog |
|
|
https://github.com/scribusproject/scribus/compare/master...aoloe:insert-frames.diff insert-frames.diff (16,877 bytes)
diff --git a/scribus/pageitem.cpp b/scribus/pageitem.cpp
index 22c5fcb3d3..6050021f8f 100644
--- a/scribus/pageitem.cpp
+++ b/scribus/pageitem.cpp
@@ -9881,6 +9881,29 @@ PageItem* PageItem::lastInChain()
return last;
}
+bool PageItem::isAllNextInChainSamePage()
+{
+ PageItem* next = this;
+ while (next->nextInChain() != nullptr) {
+ next = next->nextInChain();
+ if (next->OwnPage != this->OwnPage) {
+ return false;
+ }
+ }
+ return true;
+}
+
+PageItem* PageItem::lastInChainSamePage()
+{
+ assert(isInChain());
+ auto last = lastInChain();
+ while (last->OwnPage != OwnPage && last->prevInChain() != nullptr) {
+ last = last->nextInChain();
+ }
+ return last;
+}
+
+
QRect PageItem::getRedrawBounding(const double viewScale)
{
int x = qRound(floor(BoundingX - Oldm_lineWidth / 2.0 - 5) * viewScale);
diff --git a/scribus/pageitem.h b/scribus/pageitem.h
index 31061f0aaa..162f476e31 100644
--- a/scribus/pageitem.h
+++ b/scribus/pageitem.h
@@ -465,6 +465,9 @@ class SCRIBUS_API PageItem : public QObject, public UndoObject, public SaxIO, pu
//you can change all code for search first or last item in chain
PageItem* firstInChain();
PageItem* lastInChain();
+ PageItem* lastInChainSamePage();
+ bool isAllNextInChainSamePage();
+
bool testLinkCandidate(PageItem* nextFrame);
void unlink(bool createUndo = true);
void link(PageItem* nextFrame, bool addPARSEP = true);
diff --git a/scribus/pageitem_textframe.cpp b/scribus/pageitem_textframe.cpp
index 9f5ec4b64a..dcd75df54c 100644
--- a/scribus/pageitem_textframe.cpp
+++ b/scribus/pageitem_textframe.cpp
@@ -1753,7 +1753,7 @@ void PageItem_TextFrame::layout()
realCharHeight = qMax(realCharHeight, gm.ascent + gm.descent);
gm = font.glyphBBox(gl.glyph, chsd / 10.0);
realAsce = qMax(realAsce, gm.ascent + gm.descent);
- wide += gm.width;
+ wide += gm.width; // a.l.e: this sets the width of the indent
}
wide = (wide* scaleH) + (1 - scaleH);
realAsce = realAsce * scaleV + offset;
diff --git a/scribus/scribus.cpp b/scribus/scribus.cpp
index 4330c79081..4eb0b3aab3 100644
--- a/scribus/scribus.cpp
+++ b/scribus/scribus.cpp
@@ -61,6 +61,8 @@ for which a new license (GPL+exception) is in place.
//#include <QQmlProperty>
//>>
#include <QRegExp>
+#include <memory>
+#include <QScopedPointer>
#include <QScopedPointer>
#include <QStyleFactory>
#include <QTableWidget>
@@ -259,6 +261,7 @@ for which a new license (GPL+exception) is in place.
#include "undostate.h"
#include "units.h"
#include "urllauncher.h"
+#include "usertaskstructs.h"
#include "util.h"
#include "util_file.h"
#include "util_formats.h"
@@ -6432,8 +6435,7 @@ void ScribusMainWindow::duplicateItem()
if (UndoManager::undoEnabled())
trans = m_undoManager->beginTransaction(Um::Selection, Um::IPolygon, Um::Duplicate, "", Um::IMultipleDuplicate);
- ItemMultipleDuplicateData mdData;
- memset(&mdData, 0, sizeof(mdData));
+ ItemMultipleDuplicateData mdData{};
mdData.type = 0;
mdData.copyCount = 1;
mdData.copyShiftOrGap = 0;
@@ -6469,7 +6471,7 @@ void ScribusMainWindow::duplicateItemMulti()
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;
diff --git a/scribus/scribusdoc.cpp b/scribus/scribusdoc.cpp
index e2e5da6fca..1e37b004cc 100644
--- a/scribus/scribusdoc.cpp
+++ b/scribus/scribusdoc.cpp
@@ -38,6 +38,7 @@ for which a new license (GPL+exception) is in place.
#include <QProgressBar>
#include <QtAlgorithms>
#include <QTime>
+#include <QStringList>
//#include <qtconcurrentmap.h>
#include "actionmanager.h"
@@ -13500,10 +13501,14 @@ QRectF ScribusDoc::ApplyGridF(const QRectF& in)
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) && (mdData.pageSelection != 4) && (currentPageNumber() == Pages->count() - 1))
+ // cannot copy on following pages, while being on the last page
+ return;
+
QString tooltip;
UndoTransaction activeTransaction;
@@ -13631,6 +13636,10 @@ void ScribusDoc::itemSelection_MultipleDuplicate(ItemMultipleDuplicateData& mdDa
QString vString = QString::number(mdData.gridGapV, 'f', unitPrecision) + " " + unitSuffix;
tooltip = tr("Number of copies: %1\nHorizontal gap: %2\nVertical gap: %3").arg(copyCount-1).arg(hString).arg(vString).arg(unitSuffix);
}
+ else if (mdData.type==2)
+ {
+ multipleDuplicateByPage(mdData, selection, tooltip);
+ }
if (activeTransaction)
{
activeTransaction.commit("", nullptr, "", tooltip, nullptr);
@@ -13643,6 +13652,76 @@ void ScribusDoc::itemSelection_MultipleDuplicate(ItemMultipleDuplicateData& mdDa
changed();
}
+void ScribusDoc::multipleDuplicateByPage(const ItemMultipleDuplicateData& dialogData, Selection& selection, QString& tooltip)
+{
+ std::vector<int> pages;
+ QString pageRange;
+ if (dialogData.pageSelection == 1) {
+ pageRange = QString("%1-%2").arg(currentPageNumber() + 2).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) {
+ if (item->isInChain() && item->isAllNextInChainSamePage()) {
+ 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) {
+ ScPage* targetPage = Pages->at(page - 1);
+ setCurrentPage(targetPage);
+ auto countBeforeInsert = Items->count();
+ xmlStream.ReadElem(buffer, m_appPrefsData.fontPrefs.AvailFonts, this, currentPage()->xOffset(), currentPage()->yOffset(), false, true, m_appPrefsData.fontPrefs.GFontSub);
+ if (lastInChain) {
+ for (auto i = countBeforeInsert; i < Items->count(); ++i) {
+ auto item = Items->at(i);
+ if (item->itemType() == PageItem::TextFrame) {
+ 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());
+}
+
void ScribusDoc::itemSelection_ApplyImageEffects(ScImageEffectList& newEffectList, Selection* customSelection)
{
diff --git a/scribus/scribusdoc.h b/scribus/scribusdoc.h
index 8ddb018bea..0bd0c1ff44 100644
--- a/scribus/scribusdoc.h
+++ b/scribus/scribusdoc.h
@@ -1512,7 +1512,7 @@ public slots:
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);
/**
@@ -1693,6 +1693,8 @@ public slots:
//flags used for indicating needs of updates
bool m_flag_notesChanged;
+ void multipleDuplicateByPage(const ItemMultipleDuplicateData& mdData, Selection& selection, QString& tooltip);
+
public:
const QList<Mark*> marksList() { return m_docMarksList; }
const QList<TextNote*> notesList() { return m_docNotesList; }
diff --git a/scribus/ui/multipleduplicate.cpp b/scribus/ui/multipleduplicate.cpp
index eb5a65aec7..1834486d6e 100644
--- a/scribus/ui/multipleduplicate.cpp
+++ b/scribus/ui/multipleduplicate.cpp
@@ -13,21 +13,24 @@ for which a new license (GPL+exception) is in place.
#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 @@ MultipleDuplicate::MultipleDuplicate( int unitIndex, QWidget* parent) : QDialog(
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,36 @@ void MultipleDuplicate::getMultiplyData(ItemMultipleDuplicateData& mdData)
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);
}
diff --git a/scribus/ui/multipleduplicate.h b/scribus/ui/multipleduplicate.h
index c8abb74b4e..36c1bd1580 100644
--- a/scribus/ui/multipleduplicate.h
+++ b/scribus/ui/multipleduplicate.h
@@ -9,20 +9,25 @@ for which a new license (GPL+exception) is in place.
#include "ui_multipleduplicate.h"
struct ItemMultipleDuplicateData;
+class ScribusDoc;
class MultipleDuplicate : public QDialog, Ui::MultipleDuplicate
{
Q_OBJECT
public:
- MultipleDuplicate(int unitIndex, QWidget* parent);
+ // InsertAFrame(QWidget* parent, ScribusDoc *doc);
+ 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
diff --git a/scribus/ui/multipleduplicate.ui b/scribus/ui/multipleduplicate.ui
index cb3524b2c3..dc12a729dd 100644
--- a/scribus/ui/multipleduplicate.ui
+++ b/scribus/ui/multipleduplicate.ui
@@ -350,6 +350,95 @@
</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 Following Pages</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">buttonGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButtonPageEven">
+ <property name="text">
+ <string>All Follwing &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>All 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>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
@@ -468,4 +557,7 @@
</hints>
</connection>
</connections>
+ <buttongroups>
+ <buttongroup name="buttonGroup"/>
+ </buttongroups>
</ui>
diff --git a/scribus/usertaskstructs.h b/scribus/usertaskstructs.h
index bffd02d241..1d5a0cd0f9 100644
--- a/scribus/usertaskstructs.h
+++ b/scribus/usertaskstructs.h
@@ -34,16 +34,19 @@ struct InsertAFrameData
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
|
|
|
ping |
|
|
Here is the patch updated to current code. 15438_multiple_duplicate_pages.diff (16,617 bytes)
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp (revision 23163)
+++ scribus/pageitem.cpp (working copy)
@@ -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::isAllNextInChainOnSamePage() 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);
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h (revision 23163)
+++ scribus/pageitem.h (working copy)
@@ -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 isAllNextInChainOnSamePage() const;
bool canBeLinkedTo(const PageItem* nextFrame) const;
void unlink(bool createUndo = true);
Index: scribus/pageitem_textframe.cpp
===================================================================
--- scribus/pageitem_textframe.cpp (revision 23163)
+++ scribus/pageitem_textframe.cpp (working copy)
@@ -1669,7 +1669,7 @@
realCharAscent = qMax(realCharAscent, gm.ascent);
gm = font.glyphBBox(gl.glyph, chsd / 10.0);
realAsce = qMax(realAsce, gm.ascent + gm.descent);
- wide += gm.width;
+ wide += gm.width; // a.l.e: this sets the width of the indent
}
wide = (wide* scaleH) + (1 - scaleH);
realAsce = realAsce * scaleV + offset;
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp (revision 23163)
+++ scribus/scribus.cpp (working copy)
@@ -61,7 +61,9 @@
//#include <QQmlProperty>
//>>
#include <QRegExp>
+#include <memory>
#include <QScopedPointer>
+#include <QScopedPointer>
#include <QStyleFactory>
#include <QTableWidget>
#include <QTextCodec>
@@ -261,6 +263,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 +6459,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 +6494,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;
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp (revision 23163)
+++ scribus/scribusdoc.cpp (working copy)
@@ -38,6 +38,7 @@
#include <QProgressBar>
#include <QtAlgorithms>
#include <QTime>
+#include <QStringList>
//#include <qtconcurrentmap.h>
#include "actionmanager.h"
@@ -13442,10 +13443,14 @@
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) && (mdData.pageSelection != 4) && (currentPageNumber() == Pages->count() - 1))
+ // cannot copy on following pages, while being on the last page
+ return;
+
QString tooltip;
UndoTransaction activeTransaction;
@@ -13572,6 +13577,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);
@@ -13584,7 +13593,90 @@
changed();
}
+void ScribusDoc::multipleDuplicateByPage(const ItemMultipleDuplicateData& dialogData, Selection& selection, QString& tooltip)
+{
+ std::vector<int> pages;
+ QString pageRange;
+ if (dialogData.pageSelection == 1)
+ pageRange = QString("%1-%2").arg(currentPageNumber() + 2).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->isAllNextInChainOnSamePage())
+ {
+ 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)
+ {
+ ScPage* targetPage = Pages->at(page - 1);
+ setCurrentPage(targetPage);
+ auto 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 (auto i = countBeforeInsert; i < Items->count(); ++i)
+ {
+ auto 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());
+}
+
+
void ScribusDoc::itemSelection_ApplyImageEffects(ScImageEffectList& newEffectList, Selection* customSelection)
{
Selection* itemSelection = (customSelection!=nullptr) ? customSelection : m_Selection;
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h (revision 23163)
+++ scribus/scribusdoc.h (working copy)
@@ -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);
/**
@@ -1708,6 +1708,8 @@
//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; }
const QList<TextNote*> notesList() { return m_docNotesList; }
Index: scribus/ui/multipleduplicate.cpp
===================================================================
--- scribus/ui/multipleduplicate.cpp (revision 23163)
+++ scribus/ui/multipleduplicate.cpp (working copy)
@@ -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,36 @@
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);
+}
Index: scribus/ui/multipleduplicate.h
===================================================================
--- scribus/ui/multipleduplicate.h (revision 23163)
+++ scribus/ui/multipleduplicate.h (working copy)
@@ -9,20 +9,25 @@
#include "ui_multipleduplicate.h"
struct ItemMultipleDuplicateData;
+class ScribusDoc;
class MultipleDuplicate : public QDialog, Ui::MultipleDuplicate
{
Q_OBJECT
public:
- MultipleDuplicate(int unitIndex, QWidget* parent);
+ // InsertAFrame(QWidget* parent, ScribusDoc *doc);
+ 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
Index: scribus/ui/multipleduplicate.ui
===================================================================
--- scribus/ui/multipleduplicate.ui (revision 23163)
+++ scribus/ui/multipleduplicate.ui (working copy)
@@ -350,6 +350,95 @@
</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 Following Pages</string>
+ </property>
+ <attribute name="buttonGroup">
+ <string notr="true">buttonGroup</string>
+ </attribute>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="radioButtonPageEven">
+ <property name="text">
+ <string>All 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>All 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>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
@@ -468,4 +557,7 @@
</hints>
</connection>
</connections>
+ <buttongroups>
+ <buttongroup name="buttonGroup"/>
+ </buttongroups>
</ui>
Index: scribus/usertaskstructs.h
===================================================================
--- scribus/usertaskstructs.h (revision 23163)
+++ scribus/usertaskstructs.h (working copy)
@@ -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
|
|
|
A basic test shows that frame linking is not correct if you try to duplicate a selection of two linked frames located on same page. |
|
|
The options should be also: - All Pages - Even Pages - Odd Pages - Range of Pages No need to limit us to following pages. You can just skip the current page when performing the copy. |
|
|
Not sure in the end if we should provide that "Link text" option... |
|
|
Here is a patch where I have renamed the "All Following *" options to Even / Odd pages and did the appropriate modifications + some minor cleanups. I will have to get a closer look at how this "Link Text" option works. 15438_multiple_duplicate_pages_v2.diff (15,636 bytes)
Index: scribus/pageitem.cpp
===================================================================
--- scribus/pageitem.cpp (revision 23163)
+++ scribus/pageitem.cpp (working copy)
@@ -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::isAllNextInChainOnSamePage() 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);
Index: scribus/pageitem.h
===================================================================
--- scribus/pageitem.h (revision 23163)
+++ scribus/pageitem.h (working copy)
@@ -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 isAllNextInChainOnSamePage() const;
bool canBeLinkedTo(const PageItem* nextFrame) const;
void unlink(bool createUndo = true);
Index: scribus/scribus.cpp
===================================================================
--- scribus/scribus.cpp (revision 23163)
+++ scribus/scribus.cpp (working copy)
@@ -93,7 +93,6 @@
#include <csignal>
#include <string>
-
#include "actionmanager.h"
#include "actionsearch.h"
#include "appmodehelper.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;
Index: scribus/scribusdoc.cpp
===================================================================
--- scribus/scribusdoc.cpp (revision 23163)
+++ scribus/scribusdoc.cpp (working copy)
@@ -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);
@@ -13584,7 +13591,88 @@
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 = (dialogData.pageSelection == 2) ? 0 : 1;
+
+ 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->isAllNextInChainOnSamePage())
+ {
+ 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);
+ auto 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 (auto i = countBeforeInsert; i < Items->count(); ++i)
+ {
+ auto 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());
+}
+
+
void ScribusDoc::itemSelection_ApplyImageEffects(ScImageEffectList& newEffectList, Selection* customSelection)
{
Selection* itemSelection = (customSelection!=nullptr) ? customSelection : m_Selection;
Index: scribus/scribusdoc.h
===================================================================
--- scribus/scribusdoc.h (revision 23163)
+++ scribus/scribusdoc.h (working copy)
@@ -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);
/**
@@ -1708,6 +1708,8 @@
//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; }
const QList<TextNote*> notesList() { return m_docNotesList; }
Index: scribus/ui/multipleduplicate.cpp
===================================================================
--- scribus/ui/multipleduplicate.cpp (revision 23163)
+++ scribus/ui/multipleduplicate.cpp (working copy)
@@ -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);
+}
Index: scribus/ui/multipleduplicate.h
===================================================================
--- scribus/ui/multipleduplicate.h (revision 23163)
+++ scribus/ui/multipleduplicate.h (working copy)
@@ -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
Index: scribus/ui/multipleduplicate.ui
===================================================================
--- scribus/ui/multipleduplicate.ui (revision 23163)
+++ scribus/ui/multipleduplicate.ui (working copy)
@@ -9,7 +9,7 @@
<rect>
<x>0</x>
<y>0</y>
- <width>300</width>
+ <width>329</width>
<height>302</height>
</rect>
</property>
@@ -350,6 +350,95 @@
</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>All &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>All &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>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
<item>
@@ -468,4 +557,7 @@
</hints>
</connection>
</connections>
+ <buttongroups>
+ <buttongroup name="buttonGroup"/>
+ </buttongroups>
</ui>
Index: scribus/usertaskstructs.h
===================================================================
--- scribus/usertaskstructs.h (revision 23163)
+++ scribus/usertaskstructs.h (working copy)
@@ -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
|
|
|
as discussed in irc: please, consider reverting the changes and let the duplicate apply only to the following pages. i really don't see a use case where somebody defines something on page 4 and wants it applied to the pages 1 to 8... and if there are such cases, it's trivial to cut and paste the item on page 1 and then duplicate it. i really think that the "normal" use case is to duplicate an item on the next n pages, and i would optimize the UI around that. obviously, we should make sure that other uses are possible and easy. |
|
|
Done! |
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 2018-09-25 08:49 | ale | New Issue | |
| 2018-09-25 08:49 | ale | Assigned To | => ale |
| 2018-09-25 08:49 | ale | Status | new => assigned |
| 2018-09-25 09:22 | jghali | Category | - => General |
| 2018-09-25 11:24 | ale | Relationship added | related to 0010557 |
| 2018-09-27 07:30 | ale | File Added: insert-frames.diff | |
| 2018-09-27 07:30 | ale | Note Added: 0045485 | |
| 2018-09-27 07:30 | ale | Summary | multiple duplicate on pages => [PATCH] multiple duplicate on pages |
| 2018-09-27 07:30 | ale | Patch | No => Yes |
| 2019-01-24 12:28 | ale | Note Added: 0045852 | |
| 2019-08-28 14:22 | jghali | File Added: 15438_multiple_duplicate_pages.diff | |
| 2019-08-28 14:22 | jghali | Note Added: 0046559 | |
| 2019-08-28 14:23 | jghali | Note Added: 0046560 | |
| 2019-08-28 14:23 | jghali | Note Edited: 0046560 | |
| 2019-08-28 14:29 | jghali | Note Added: 0046561 | |
| 2019-08-28 14:58 | jghali | Note Added: 0046563 | |
| 2019-08-28 15:21 | jghali | File Added: 15438_multiple_duplicate_pages_v2.diff | |
| 2019-08-28 15:21 | jghali | Note Added: 0046564 | |
| 2019-08-29 08:21 | ale | Note Added: 0046567 | |
| 2019-09-01 14:22 | jghali | Summary | [PATCH] multiple duplicate on pages => Multiple duplicate on pages |
| 2019-09-01 14:22 | jghali | Status | assigned => resolved |
| 2019-09-01 14:22 | jghali | Resolution | open => fixed |
| 2019-09-01 14:22 | jghali | Fixed in Version | => 1.5.6.svn |
| 2019-09-01 14:22 | jghali | Note Added: 0046596 | |
| 2019-12-08 21:24 | cbradney | Status | resolved => closed |