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

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

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

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

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

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

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

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

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

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

Modified: trunk/Scribus/scribus/ui/multipleduplicate.ui
URL: 
http://scribus.net/websvn/diff.php?repname=Scribus&rev=23169&path=/trunk/Scribus/scribus/ui/multipleduplicate.ui
==============================================================================
--- trunk/Scribus/scribus/ui/multipleduplicate.ui       (original)
+++ trunk/Scribus/scribus/ui/multipleduplicate.ui       Sun Sep  1 14:21:37 2019
@@ -9,7 +9,7 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>300</width>
+    <width>329</width>
     <height>302</height>
    </rect>
   </property>
@@ -337,6 +337,95 @@
        </item>
        <item>
         <spacer name="verticalSpacer">
+         <property name="orientation">
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0">
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tab3">
+      <attribute name="title">
+       <string>By &amp;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>&amp;All Pages</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageEven">
+           <property name="text">
+            <string>Following &amp;Even Pages</string>
+           </property>
+           <attribute name="buttonGroup">
+            <string notr="true">buttonGroup</string>
+           </attribute>
+          </widget>
+         </item>
+         <item>
+          <widget class="QRadioButton" name="radioButtonPageOdd">
+           <property name="text">
+            <string>Following &amp;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&amp;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>&amp;Link Text Frames</string>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </item>
+       <item>
+        <spacer name="verticalSpacer_5">
          <property name="orientation">
           <enum>Qt::Vertical</enum>
          </property>
@@ -468,4 +557,7 @@
    </hints>
   </connection>
  </connections>
+ <buttongroups>
+  <buttongroup name="buttonGroup"/>
+ </buttongroups>
 </ui>

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


_______________________________________________
scribus-commit mailing list
[email protected]
http://lists.scribus.net/mailman/listinfo/scribus-commit

Reply via email to