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. | ||||
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 |