From 56c027686d67275846a994baa56acc6359d6e932 Mon Sep 17 00:00:00 2001
From: Roman Telezhynskyi <kroluku@gmail.com>
Date: Fri, 8 May 2015 13:10:56 +0300
Subject: [PATCH] New Layout setting "Save length of the sheet".

--HG--
branch : develop
---
 src/app/dialogs/app/dialoglayoutsettings.cpp | 37 +++++++++++
 src/app/dialogs/app/dialoglayoutsettings.h   |  3 +
 src/app/dialogs/app/dialoglayoutsettings.ui  | 11 ++--
 src/libs/vlayout/vbestsquare.cpp             | 65 +++++++++++++++-----
 src/libs/vlayout/vbestsquare.h               | 14 +++--
 src/libs/vlayout/vcontour.cpp                |  6 ++
 src/libs/vlayout/vcontour.h                  |  3 +
 src/libs/vlayout/vlayoutgenerator.cpp        | 15 ++++-
 src/libs/vlayout/vlayoutgenerator.h          |  4 ++
 src/libs/vlayout/vlayoutpaper.cpp            | 17 ++++-
 src/libs/vlayout/vlayoutpaper.h              |  3 +
 src/libs/vlayout/vlayoutpaper_p.h            |  7 ++-
 src/libs/vlayout/vposition.cpp               | 12 ++--
 src/libs/vlayout/vposition.h                 |  2 +-
 14 files changed, 162 insertions(+), 37 deletions(-)

diff --git a/src/app/dialogs/app/dialoglayoutsettings.cpp b/src/app/dialogs/app/dialoglayoutsettings.cpp
index f8012c286..befced84b 100644
--- a/src/app/dialogs/app/dialoglayoutsettings.cpp
+++ b/src/app/dialogs/app/dialoglayoutsettings.cpp
@@ -214,6 +214,18 @@ void DialogLayoutSettings::SetAutoCrop(bool autoCrop)
     ui->checkBoxAutoCrop->setChecked(autoCrop);
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+bool DialogLayoutSettings::IsSaveLength() const
+{
+    return ui->checkBoxSaveLength->isChecked();
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void DialogLayoutSettings::SetSaveLength(bool save)
+{
+    ui->checkBoxSaveLength->setChecked(save);
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 void DialogLayoutSettings::TemplateSelected()
 {
@@ -315,6 +327,7 @@ void DialogLayoutSettings::DialogAccepted()
     generator->SetRotate(GetRotate());
     generator->SetRotationIncrease(GetIncrease());
     generator->SetAutoCrop(GetAutoCrop());
+    generator->SetSaveLength(IsSaveLength());
 
     accepted();
 }
@@ -402,61 +415,85 @@ QSizeF DialogLayoutSettings::Template()
     {
         case PaperSizeTemplate::A0:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(841, Unit::Mm, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(1189, Unit::Mm, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::A1:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(594, Unit::Mm, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(841, Unit::Mm, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::A2:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(420, Unit::Mm, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(594, Unit::Mm, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::A3:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(297, Unit::Mm, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(420, Unit::Mm, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::A4:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(210, Unit::Mm, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(297, Unit::Mm, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Letter:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(8.5, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(11, Unit::Inch, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Legal:
             SetAutoCrop(false);
+            SetSaveLength(false);
+
             width = VAbstractMeasurements::UnitConvertor(11, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(17, Unit::Inch, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Roll24in:
             SetAutoCrop(true);
+            SetSaveLength(true);
+
             width = VAbstractMeasurements::UnitConvertor(24, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(QIMAGE_MAX, Unit::Px, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Roll30in:
             SetAutoCrop(true);
+            SetSaveLength(true);
+
             width = VAbstractMeasurements::UnitConvertor(30, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(QIMAGE_MAX, Unit::Px, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Roll36in:
             SetAutoCrop(true);
+            SetSaveLength(true);
+
             width = VAbstractMeasurements::UnitConvertor(36, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(QIMAGE_MAX, Unit::Px, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Roll42in:
             SetAutoCrop(true);
+            SetSaveLength(true);
+
             width = VAbstractMeasurements::UnitConvertor(42, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(QIMAGE_MAX, Unit::Px, paperUnit);
             return QSizeF(width, height);
         case PaperSizeTemplate::Roll44in:
             SetAutoCrop(true);
+            SetSaveLength(true);
+
             width = VAbstractMeasurements::UnitConvertor(44, Unit::Inch, paperUnit);
             height = VAbstractMeasurements::UnitConvertor(QIMAGE_MAX, Unit::Px, paperUnit);
             return QSizeF(width, height);
diff --git a/src/app/dialogs/app/dialoglayoutsettings.h b/src/app/dialogs/app/dialoglayoutsettings.h
index 4b46d9859..80891bd71 100644
--- a/src/app/dialogs/app/dialoglayoutsettings.h
+++ b/src/app/dialogs/app/dialoglayoutsettings.h
@@ -72,6 +72,9 @@ public:
     bool GetAutoCrop() const;
     void SetAutoCrop(bool crop);
 
+    bool IsSaveLength() const;
+    void SetSaveLength(bool save);
+
 public slots:
     void ConvertPaperSize();
     void ConvertLayoutSize();
diff --git a/src/app/dialogs/app/dialoglayoutsettings.ui b/src/app/dialogs/app/dialoglayoutsettings.ui
index 0e8806b7c..67ce64c61 100644
--- a/src/app/dialogs/app/dialoglayoutsettings.ui
+++ b/src/app/dialogs/app/dialoglayoutsettings.ui
@@ -17,10 +17,6 @@
    <iconset resource="../../share/resources/icon.qrc">
     <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
   </property>
-  <property name="windowIcon">
-   <iconset resource="../../share/resources/icon.qrc">
-    <normaloff>:/icon/64x64/icon64x64.png</normaloff>:/icon/64x64/icon64x64.png</iconset>
-  </property>
   <layout class="QVBoxLayout" name="verticalLayout_6">
    <item>
     <layout class="QHBoxLayout" name="horizontalLayout_4">
@@ -429,6 +425,13 @@
           </item>
          </layout>
         </item>
+        <item>
+         <widget class="QCheckBox" name="checkBoxSaveLength">
+          <property name="text">
+           <string>Save length of the sheet</string>
+          </property>
+         </widget>
+        </item>
         <item>
          <widget class="QGroupBox" name="groupBoxCase">
           <property name="title">
diff --git a/src/libs/vlayout/vbestsquare.cpp b/src/libs/vlayout/vbestsquare.cpp
index 74b23ba29..54401ea40 100644
--- a/src/libs/vlayout/vbestsquare.cpp
+++ b/src/libs/vlayout/vbestsquare.cpp
@@ -29,39 +29,60 @@
 #include "vbestsquare.h"
 
 //---------------------------------------------------------------------------------------------------------------------
-VBestSquare::VBestSquare()
-    :resI(0), resJ(0), resMatrix(QMatrix()), resSquare(LLONG_MAX), valideResult(false), resMirror(false),
-      type (BestFrom::Rotation)
+VBestSquare::VBestSquare(const QSizeF &sheetSize, bool saveLength)
+    :resI(0), resJ(0), resMatrix(QMatrix()), bestSize(QSizeF(sheetSize.width()+10, sheetSize.height()+10)),
+      sheetWidth(sheetSize.width()), valideResult(false), resMirror(false), type (BestFrom::Rotation),
+      saveLength(saveLength)
 {}
 
 //---------------------------------------------------------------------------------------------------------------------
-void VBestSquare::NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror, BestFrom type)
+void VBestSquare::NewResult(const QSizeF &candidate, int i, int j, const QTransform &matrix, bool mirror, BestFrom type)
 {
-    if (square <= resSquare && square > 0 && type >= this->type)
+    if (saveLength)
     {
-        resI = i;
-        resJ = j;
-        resMatrix = matrix;
-        resSquare = square;
-        valideResult = true;
-        resMirror = mirror;
-        this->type = type;
+        const QSizeF saveLengthSize(sheetWidth, candidate.height());
+        if (Square(saveLengthSize) <= Square(bestSize) && Square(saveLengthSize) > 0 && type >= this->type)
+        {
+            bestSize = saveLengthSize;
+        }
+        else
+        {
+            return;
+        }
     }
+    else
+    {
+        if (Square(candidate) <= Square(bestSize) && Square(candidate) > 0 && type >= this->type)
+        {
+            bestSize = candidate;
+        }
+        else
+        {
+            return;
+        }
+    }
+
+    resI = i;
+    resJ = j;
+    resMatrix = matrix;
+    valideResult = true;
+    resMirror = mirror;
+    this->type = type;
 }
 
 //---------------------------------------------------------------------------------------------------------------------
 void VBestSquare::NewResult(const VBestSquare &best)
 {
-    if (best.ValidResult())
+    if (best.ValidResult() && saveLength == best.IsSaveLength())
     {
-        NewResult(best.BestSquare(), best.GContourEdge(), best.DetailEdge(), best.Matrix(), best.Mirror(), best.Type());
+        NewResult(best.BestSize(), best.GContourEdge(), best.DetailEdge(), best.Matrix(), best.Mirror(), best.Type());
     }
 }
 
 //---------------------------------------------------------------------------------------------------------------------
-qint64 VBestSquare::BestSquare() const
+QSizeF VBestSquare::BestSize() const
 {
-    return resSquare;
+    return bestSize;
 }
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -99,3 +120,15 @@ BestFrom VBestSquare::Type() const
 {
     return type;
 }
+
+//---------------------------------------------------------------------------------------------------------------------
+bool VBestSquare::IsSaveLength() const
+{
+    return saveLength;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+qint64 VBestSquare::Square(const QSizeF &size)
+{
+    return static_cast<qint64>(size.width()*size.height());
+}
diff --git a/src/libs/vlayout/vbestsquare.h b/src/libs/vlayout/vbestsquare.h
index ba360f0b9..bc134c4c1 100644
--- a/src/libs/vlayout/vbestsquare.h
+++ b/src/libs/vlayout/vbestsquare.h
@@ -36,12 +36,12 @@
 class VBestSquare
 {
 public:
-    VBestSquare();
+    VBestSquare(const QSizeF &sheetSize, bool saveLength);
 
-    void NewResult(qint64 square, int i, int j, const QTransform &matrix, bool mirror, BestFrom type);
+    void NewResult(const QSizeF &candidate, int i, int j, const QTransform &matrix, bool mirror, BestFrom type);
     void NewResult(const VBestSquare &best);
 
-    qint64     BestSquare() const;
+    QSizeF     BestSize() const;
     int        GContourEdge() const;
     int        DetailEdge() const;
     QTransform Matrix() const;
@@ -49,15 +49,21 @@ public:
     bool       Mirror() const;
     BestFrom   Type() const;
 
+    bool IsSaveLength() const;
+
 private:
     // All nedded information about best result
     int resI; // Edge of global contour
     int resJ; // Edge of detail
     QTransform resMatrix; // Matrix for rotation and translation detail
-    qint64 resSquare; // Best square size (least). For begin set max value.
+    QSizeF bestSize;
+    qreal sheetWidth;
     bool valideResult;
     bool resMirror;
     BestFrom type;
+    bool saveLength;
+
+    static qint64 Square(const QSizeF &size);
 };
 
 #endif // VBESTSQUARE_H
diff --git a/src/libs/vlayout/vcontour.cpp b/src/libs/vlayout/vcontour.cpp
index a93f4ea75..a9499fc2e 100644
--- a/src/libs/vlayout/vcontour.cpp
+++ b/src/libs/vlayout/vcontour.cpp
@@ -116,6 +116,12 @@ void VContour::SetWidth(int width)
     d->paperWidth = width;
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+QSizeF VContour::GetSize() const
+{
+    return QSizeF(d->paperWidth, d->paperHeight);
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 QVector<QPointF> VContour::UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ, BestFrom type) const
 {
diff --git a/src/libs/vlayout/vcontour.h b/src/libs/vlayout/vcontour.h
index bef34f6d0..56c3bac9a 100644
--- a/src/libs/vlayout/vcontour.h
+++ b/src/libs/vlayout/vcontour.h
@@ -33,6 +33,7 @@
 
 #include <QVector>
 #include <QSharedDataPointer>
+#include <QSizeF>
 
 class VContourData;
 class QPointF;
@@ -60,6 +61,8 @@ public:
     int  GetWidth() const;
     void SetWidth(int width);
 
+    QSizeF GetSize() const;
+
     QVector<QPointF> UniteWithContour(const VLayoutDetail &detail, int globalI, int detJ, BestFrom type) const;
 
     int    EdgesCount() const;
diff --git a/src/libs/vlayout/vlayoutgenerator.cpp b/src/libs/vlayout/vlayoutgenerator.cpp
index 9e7b41457..1b9c350a5 100644
--- a/src/libs/vlayout/vlayoutgenerator.cpp
+++ b/src/libs/vlayout/vlayoutgenerator.cpp
@@ -40,7 +40,7 @@
 VLayoutGenerator::VLayoutGenerator(QObject *parent)
     :QObject(parent), papers(QVector<VLayoutPaper>()), bank(new VBank()), paperHeight(0), paperWidth(0),
       stopGeneration(false), state(LayoutErrors::NoError), shift(0), rotate(true), rotationIncrease(180),
-      autoCrop(false)
+      autoCrop(false), saveLength(false)
 {}
 
 //---------------------------------------------------------------------------------------------------------------------
@@ -106,6 +106,7 @@ void VLayoutGenerator::Generate()
             paper.SetPaperIndex(static_cast<quint32>(papers.count()));
             paper.SetRotate(rotate);
             paper.SetRotationIncrease(rotationIncrease);
+            paper.SetSaveLength(saveLength);
             do
             {
                 const int index = bank->GetTiket();
@@ -189,6 +190,18 @@ void VLayoutGenerator::Abort()
 #endif
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+bool VLayoutGenerator::IsSaveLength() const
+{
+    return saveLength;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void VLayoutGenerator::SetSaveLength(bool value)
+{
+    saveLength = value;
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 bool VLayoutGenerator::GetAutoCrop() const
 {
diff --git a/src/libs/vlayout/vlayoutgenerator.h b/src/libs/vlayout/vlayoutgenerator.h
index 71fb1974f..93a6d681e 100644
--- a/src/libs/vlayout/vlayoutgenerator.h
+++ b/src/libs/vlayout/vlayoutgenerator.h
@@ -76,6 +76,9 @@ public:
     bool GetAutoCrop() const;
     void SetAutoCrop(bool value);
 
+    bool IsSaveLength() const;
+    void SetSaveLength(bool value);
+
 signals:
     void Start();
     void Arranged(int count);
@@ -97,6 +100,7 @@ private:
     bool rotate;
     int rotationIncrease;
     bool autoCrop;
+    bool saveLength;
 
     void CheckDetailsSize();
 };
diff --git a/src/libs/vlayout/vlayoutpaper.cpp b/src/libs/vlayout/vlayoutpaper.cpp
index 1e967ea04..41c159e41 100644
--- a/src/libs/vlayout/vlayoutpaper.cpp
+++ b/src/libs/vlayout/vlayoutpaper.cpp
@@ -147,6 +147,18 @@ void VLayoutPaper::SetRotationIncrease(int value)
     }
 }
 
+//---------------------------------------------------------------------------------------------------------------------
+bool VLayoutPaper::IsSaveLength() const
+{
+    return d->saveLength;
+}
+
+//---------------------------------------------------------------------------------------------------------------------
+void VLayoutPaper::SetSaveLength(bool value)
+{
+    d->saveLength = value;
+}
+
 //---------------------------------------------------------------------------------------------------------------------
 void VLayoutPaper::SetPaperIndex(quint32 index)
 {
@@ -181,7 +193,7 @@ int VLayoutPaper::Count() const
 //---------------------------------------------------------------------------------------------------------------------
 bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, volatile bool &stop)
 {
-    VBestSquare bestResult;
+    VBestSquare bestResult(d->globalContour.GetSize(), d->saveLength);
     QThreadPool *thread_pool = QThreadPool::globalInstance();
     thread_pool->setExpiryTimeout(1000);
     QVector<VPosition *> threads;
@@ -190,7 +202,8 @@ bool VLayoutPaper::AddToSheet(const VLayoutDetail &detail, volatile bool &stop)
     {
         for (int i=1; i<= detail.EdgesCount(); i++)
         {
-            VPosition *thread = new VPosition(d->globalContour, j, detail, i, &stop, d->rotate, d->rotationIncrease);
+            VPosition *thread = new VPosition(d->globalContour, j, detail, i, &stop, d->rotate, d->rotationIncrease,
+                                              d->saveLength);
             //Info for debug
             #ifdef LAYOUT_DEBUG
                 thread->setPaperIndex(d->paperIndex);
diff --git a/src/libs/vlayout/vlayoutpaper.h b/src/libs/vlayout/vlayoutpaper.h
index 1fc409493..9fb22f6c1 100644
--- a/src/libs/vlayout/vlayoutpaper.h
+++ b/src/libs/vlayout/vlayoutpaper.h
@@ -65,6 +65,9 @@ public:
     int GetRotationIncrease() const;
     void SetRotationIncrease(int value);
 
+    bool IsSaveLength() const;
+    void SetSaveLength(bool value);
+
     void SetPaperIndex(quint32 index);
 
     bool ArrangeDetail(const VLayoutDetail &detail, volatile bool &stop);
diff --git a/src/libs/vlayout/vlayoutpaper_p.h b/src/libs/vlayout/vlayoutpaper_p.h
index fb31a0649..d047e0f47 100644
--- a/src/libs/vlayout/vlayoutpaper_p.h
+++ b/src/libs/vlayout/vlayoutpaper_p.h
@@ -46,18 +46,18 @@ class VLayoutPaperData : public QSharedData
 public:
     VLayoutPaperData()
         :details(QVector<VLayoutDetail>()), globalContour(VContour()), paperIndex(0), frame(0), layoutWidth(0),
-          rotate(true), rotationIncrease(180)
+          rotate(true), rotationIncrease(180), saveLength(false)
     {}
 
     VLayoutPaperData(int height, int width)
         :details(QVector<VLayoutDetail>()), globalContour(VContour(height, width)), paperIndex(0), frame(0),
-          layoutWidth(0), rotate(true), rotationIncrease(180)
+          layoutWidth(0), rotate(true), rotationIncrease(180), saveLength(false)
     {}
 
     VLayoutPaperData(const VLayoutPaperData &paper)
         :QSharedData(paper), details(paper.details), globalContour(paper.globalContour), paperIndex(paper.paperIndex),
           frame(paper.frame), layoutWidth(paper.layoutWidth), rotate(paper.rotate),
-          rotationIncrease(paper.rotationIncrease)
+          rotationIncrease(paper.rotationIncrease), saveLength(paper.saveLength)
     {}
 
     ~VLayoutPaperData() {}
@@ -73,6 +73,7 @@ public:
     qreal layoutWidth;
     bool rotate;
     int rotationIncrease;
+    bool saveLength;
 };
 
 #ifdef Q_CC_GNU
diff --git a/src/libs/vlayout/vposition.cpp b/src/libs/vlayout/vposition.cpp
index 7532799c6..ca38e199b 100644
--- a/src/libs/vlayout/vposition.cpp
+++ b/src/libs/vlayout/vposition.cpp
@@ -47,9 +47,10 @@
 
 //---------------------------------------------------------------------------------------------------------------------
 VPosition::VPosition(const VContour &gContour, int j, const VLayoutDetail &detail, int i, volatile bool *stop,
-                     bool rotate, int rotationIncrease)
-    :QRunnable(), bestResult(VBestSquare()), gContour(gContour), detail(detail), i(i), j(j), paperIndex(0), frame(0),
-      detailsCount(0), details(QVector<VLayoutDetail>()), stop(stop), rotate(rotate), rotationIncrease(rotationIncrease)
+                     bool rotate, int rotationIncrease, bool saveLength)
+    :QRunnable(), bestResult(VBestSquare(gContour.GetSize(), saveLength)), gContour(gContour), detail(detail), i(i),
+      j(j), paperIndex(0), frame(0), detailsCount(0), details(QVector<VLayoutDetail>()), stop(stop), rotate(rotate),
+      rotationIncrease(rotationIncrease)
 {
     if ((rotationIncrease >= 1 && rotationIncrease <= 180 && 360 % rotationIncrease == 0) == false)
     {
@@ -225,9 +226,8 @@ void VPosition::SaveCandidate(VBestSquare &bestResult, const VLayoutDetail &deta
 {
     QVector<QPointF> newGContour = gContour.UniteWithContour(detail, globalI, detJ, type);
     newGContour.append(newGContour.first());
-    const QRectF rec = QPolygonF(newGContour).boundingRect();
-    bestResult.NewResult(static_cast<qint64>(rec.width()*rec.height()), globalI, detJ, detail.GetMatrix(),
-                         detail.IsMirror(), type);
+    const QSizeF size = QPolygonF(newGContour).boundingRect().size();
+    bestResult.NewResult(size, globalI, detJ, detail.GetMatrix(), detail.IsMirror(), type);
 }
 
 //---------------------------------------------------------------------------------------------------------------------
diff --git a/src/libs/vlayout/vposition.h b/src/libs/vlayout/vposition.h
index ba2461a79..a4f62c718 100644
--- a/src/libs/vlayout/vposition.h
+++ b/src/libs/vlayout/vposition.h
@@ -47,7 +47,7 @@ class VPosition : public QRunnable
 {
 public:
     VPosition(const VContour &gContour, int j, const VLayoutDetail &detail, int i, volatile bool *stop, bool rotate,
-              int rotationIncrease);
+              int rotationIncrease, bool saveLength);
     virtual ~VPosition(){}
 
     quint32 getPaperIndex() const;