[libreoffice/f20] Resolves: tdf#81659 handle expand reference edge correctly
Eike Rathke
erack at fedoraproject.org
Thu Feb 26 16:51:55 UTC 2015
commit 2709613374335d28c1f4325b978302e9449a0d7d
Author: Eike Rathke <erack at redhat.com>
Date: Thu Feb 26 17:42:47 2015 +0100
Resolves: tdf#81659 handle expand reference edge correctly
...f-81659-handle-expand-reference-edge-corr.patch | 281 +++++++++++++++++++++
libreoffice.spec | 4 +-
2 files changed, 284 insertions(+), 1 deletion(-)
---
diff --git a/0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch b/0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch
new file mode 100644
index 0000000..41318b4
--- /dev/null
+++ b/0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch
@@ -0,0 +1,281 @@
+From 3a9fc69e8f6de916c8f4ee9a7253346244c17cc7 Mon Sep 17 00:00:00 2001
+Message-Id: <3a9fc69e8f6de916c8f4ee9a7253346244c17cc7.1424968626.git.erack at redhat.com>
+From: Eike Rathke <erack at redhat.com>
+Date: Thu, 26 Feb 2015 12:54:13 +0100
+Subject: [PATCH] Resolves: tdf#81659 handle expand reference edge correctly
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary="------------erAck-patch-parts"
+
+This is a multi-part message in MIME format.
+--------------erAck-patch-parts
+Content-Type: text/plain; charset=UTF-8; format=fixed
+Content-Transfer-Encoding: 8bit
+
+
+split formula grouping for reference edge expansion, tdf#81659 related
+
+Edge expansion may change expressions individually, which must be split
+off the group.
+
+(cherry picked from commit 0cd15b4494f8e8abe67a258fb10189135bf5a8ac)
+
+tdf#81659 check that references are at least 2 cols/rows to expand edge
+
+Needs also 0cd15b4494f8e8abe67a258fb10189135bf5a8ac if edges are to be
+expanded and formula grouping is affected.
+
+(cherry picked from commit 23b0112ecea2f8796a4e237e9061de1a36997a30)
+
+Backported.
+
+b3cee8dd214d216907248316a2ac5a290399b169
+
+Change-Id: Id4328bd8c42f2ff9f83d2edc845537971f3a39d3
+---
+ sc/inc/tokenarray.hxx | 3 +
+ sc/source/core/data/column.cxx | 29 +++++++++
+ sc/source/core/tool/token.cxx | 132 +++++++++++++++++++++++++++++++++++++++--
+ 3 files changed, 158 insertions(+), 6 deletions(-)
+
+
+--------------erAck-patch-parts
+Content-Type: text/x-patch; name="0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch"
+Content-Transfer-Encoding: 8bit
+Content-Disposition: attachment; filename="0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch"
+
+diff --git a/sc/inc/tokenarray.hxx b/sc/inc/tokenarray.hxx
+index 75451e1..5153045 100644
+--- a/sc/inc/tokenarray.hxx
++++ b/sc/inc/tokenarray.hxx
+@@ -231,6 +231,9 @@ public:
+ void CheckRelativeReferenceBounds(
+ const ScAddress& rPos, SCROW nGroupLen, const ScRange& rRange, std::vector<SCROW>& rBounds ) const;
+
++ void CheckExpandReferenceBounds(
++ const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const;
++
+ /**
+ * Create a string representation of formula token array without modifying
+ * the internal state of the token array.
+diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
+index c014e00..14e2ed6 100644
+--- a/sc/source/core/data/column.cxx
++++ b/sc/source/core/data/column.cxx
+@@ -2308,6 +2308,27 @@ public:
+ }
+ };
+
++class UpdateRefExpandGroupBoundChecker : public SharedTopFormulaCellPicker
++{
++ const sc::RefUpdateContext& mrCxt;
++ std::vector<SCROW>& mrBounds;
++
++public:
++ UpdateRefExpandGroupBoundChecker(const sc::RefUpdateContext& rCxt, std::vector<SCROW>& rBounds) :
++ mrCxt(rCxt), mrBounds(rBounds) {}
++
++ virtual ~UpdateRefExpandGroupBoundChecker() {}
++
++ virtual void processSharedTop( ScFormulaCell** ppCells, size_t /*nRow*/, size_t /*nLength*/ ) SAL_OVERRIDE
++ {
++ // Check its tokens and record its reference boundaries.
++ ScFormulaCell& rCell = **ppCells;
++ const ScTokenArray& rCode = *rCell.GetCode();
++ rCode.CheckExpandReferenceBounds(
++ mrCxt, rCell.aPos, rCell.GetSharedLength(), mrBounds);
++ }
++};
++
+ class FormulaGroupPicker : public SharedTopFormulaCellPicker
+ {
+ std::vector<sc::FormulaGroupEntry>& mrGroups;
+@@ -2393,6 +2414,14 @@ bool ScColumn::UpdateReference( sc::RefUpdateContext& rCxt, ScDocument* pUndoDoc
+ UpdateRefGroupBoundChecker aBoundChecker(rCxt, aBounds);
+ std::for_each(maCells.begin(), maCells.end(), aBoundChecker);
+
++ // If expand reference edges is on, splitting groups may happen anywhere
++ // where a reference points to an adjacent row of the insertion.
++ if (rCxt.mnRowDelta > 0 && rCxt.mrDoc.IsExpandRefs())
++ {
++ UpdateRefExpandGroupBoundChecker aExpandChecker(rCxt, aBounds);
++ std::for_each(maCells.begin(), maCells.end(), aExpandChecker);
++ }
++
+ // Do the actual splitting.
+ sc::SharedFormulaUtil::splitFormulaCellGroups(maCells, aBounds);
+
+diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
+index db7f339..e17e7c9 100644
+--- a/sc/source/core/tool/token.cxx
++++ b/sc/source/core/tool/token.cxx
+@@ -2632,9 +2632,18 @@ bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
+ // Selected range is only partially overlapping in vertical direction. Bail out.
+ return false;
+
+- if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Col() <= rRefRange.aStart.Col())
+- // Selected range is at the left end and the edge expansion is turned off. No expansion.
+- return false;
++ if (rCxt.mrDoc.IsExpandRefs())
++ {
++ if (rRefRange.aEnd.Col() - rRefRange.aStart.Col() < 1)
++ // Reference must be at least two columns wide.
++ return false;
++ }
++ else
++ {
++ if (rSelectedRange.aStart.Col() <= rRefRange.aStart.Col())
++ // Selected range is at the left end and the edge expansion is turned off. No expansion.
++ return false;
++ }
+
+ // Move the last column position to the right.
+ SCCOL nDelta = rSelectedRange.aEnd.Col() - rSelectedRange.aStart.Col() + 1;
+@@ -2648,9 +2657,18 @@ bool expandRange( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, const Sc
+ // Selected range is only partially overlapping in horizontal direction. Bail out.
+ return false;
+
+- if (!rCxt.mrDoc.IsExpandRefs() && rSelectedRange.aStart.Row() <= rRefRange.aStart.Row())
+- // Selected range is at the top end and the edge expansion is turned off. No expansion.
+- return false;
++ if (rCxt.mrDoc.IsExpandRefs())
++ {
++ if (rRefRange.aEnd.Row() - rRefRange.aStart.Row() < 1)
++ // Reference must be at least two rows tall.
++ return false;
++ }
++ else
++ {
++ if (rSelectedRange.aStart.Row() <= rRefRange.aStart.Row())
++ // Selected range is at the top end and the edge expansion is turned off. No expansion.
++ return false;
++ }
+
+ // Move the last row position down.
+ SCROW nDelta = rSelectedRange.aEnd.Row() - rSelectedRange.aStart.Row() + 1;
+@@ -2677,6 +2695,11 @@ bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, co
+ if (rCxt.mnColDelta > 0)
+ {
+ // Insert and shift right.
++
++ if (rRefRange.aEnd.Col() - rRefRange.aStart.Col() < 1)
++ // Reference must be at least two columns wide.
++ return false;
++
+ if (rRefRange.aStart.Row() < rSelectedRange.aStart.Row() || rSelectedRange.aEnd.Row() < rRefRange.aEnd.Row())
+ // Selected range is only partially overlapping in vertical direction. Bail out.
+ return false;
+@@ -2692,6 +2715,10 @@ bool expandRangeByEdge( const sc::RefUpdateContext& rCxt, ScRange& rRefRange, co
+ }
+ else if (rCxt.mnRowDelta > 0)
+ {
++ if (rRefRange.aEnd.Row() - rRefRange.aStart.Row() < 1)
++ // Reference must be at least two rows tall.
++ return false;
++
+ if (rRefRange.aStart.Col() < rSelectedRange.aStart.Col() || rSelectedRange.aEnd.Col() < rRefRange.aEnd.Col())
+ // Selected range is only partially overlapping in horizontal direction. Bail out.
+ return false;
+@@ -3767,6 +3794,99 @@ void ScTokenArray::CheckRelativeReferenceBounds(
+ }
+ }
+
++void ScTokenArray::CheckExpandReferenceBounds(
++ const sc::RefUpdateContext& rCxt, const ScAddress& rPos, SCROW nGroupLen, std::vector<SCROW>& rBounds ) const
++{
++ const SCROW nInsRow = rCxt.maRange.aStart.Row();
++ const FormulaToken* const * p = pCode;
++ const FormulaToken* const * pEnd = p + static_cast<size_t>(nLen);
++ for (; p != pEnd; ++p)
++ {
++ switch ((*p)->GetType())
++ {
++ case svDoubleRef:
++ {
++ const ScToken* pToken = static_cast<const ScToken*>(*p);
++ const ScComplexRefData& rRef = pToken->GetDoubleRef();
++ bool bStartRowRelative = rRef.Ref1.IsRowRel();
++ bool bEndRowRelative = rRef.Ref2.IsRowRel();
++
++ // For absolute references nothing needs to be done, they stay
++ // the same for all and if to be expanded the group will be
++ // adjusted later.
++ if (!bStartRowRelative && !bEndRowRelative)
++ break; // switch
++
++ ScRange aAbsStart(rRef.toAbs(rPos));
++ ScAddress aPos(rPos);
++ aPos.IncRow(nGroupLen);
++ ScRange aAbsEnd(rRef.toAbs(aPos));
++ // References must be at least two rows to be expandable.
++ if ((aAbsStart.aEnd.Row() - aAbsStart.aStart.Row() < 1) &&
++ (aAbsEnd.aEnd.Row() - aAbsEnd.aStart.Row() < 1))
++ break; // switch
++
++ // Only need to process if an edge may be touching the
++ // insertion row anywhere within the run of the group.
++ if (!((aAbsStart.aStart.Row() <= nInsRow && nInsRow <= aAbsEnd.aStart.Row()) ||
++ (aAbsStart.aEnd.Row() <= nInsRow && nInsRow <= aAbsEnd.aEnd.Row())))
++ break; // switch
++
++ SCROW nStartRow = aAbsStart.aStart.Row();
++ SCROW nEndRow = aAbsStart.aEnd.Row();
++ // Position on first relevant range.
++ SCROW nOffset = 0;
++ if (nEndRow + 1 < nInsRow)
++ {
++ if (bEndRowRelative)
++ {
++ nOffset = nInsRow - nEndRow - 1;
++ nEndRow += nOffset;
++ if (bStartRowRelative)
++ nStartRow += nOffset;
++ }
++ else // bStartRowRelative==true
++ {
++ nOffset = nInsRow - nStartRow;
++ nStartRow += nOffset;
++ // Start is overtaking End, swap.
++ bStartRowRelative = false;
++ bEndRowRelative = true;
++ }
++ }
++ for (SCROW i = nOffset; i < nGroupLen; ++i)
++ {
++ bool bSplit = (nStartRow == nInsRow || nEndRow + 1 == nInsRow);
++ if (bSplit)
++ rBounds.push_back( rPos.Row() + i);
++
++ if (bEndRowRelative)
++ ++nEndRow;
++ if (bStartRowRelative)
++ {
++ ++nStartRow;
++ if (!bEndRowRelative && nStartRow == nEndRow)
++ {
++ // Start is overtaking End, swap.
++ bStartRowRelative = false;
++ bEndRowRelative = true;
++ }
++ }
++ if (nInsRow < nStartRow || (!bStartRowRelative && nInsRow <= nEndRow))
++ {
++ if (bSplit && (++i < nGroupLen))
++ rBounds.push_back( rPos.Row() + i);
++ break; // for, out of range now
++ }
++ }
++ }
++ break;
++ default:
++ ;
++ }
++ }
++}
++
+ namespace {
+
+ void appendDouble( sc::TokenStringContext& rCxt, OUStringBuffer& rBuf, double fVal )
+
+--------------erAck-patch-parts--
+
+
diff --git a/libreoffice.spec b/libreoffice.spec
index a6d379f..78b29a8 100644
--- a/libreoffice.spec
+++ b/libreoffice.spec
@@ -350,6 +350,7 @@ Patch94: 0001-Resolves-tdf-83461-do-not-override-MatColsRows-if-al.patch
Patch95: 0001-fdo-87199-sw-fix-root-cause-of-a11y-crash-when-mergi.patch
Patch96: 0001-Resolves-tdf-89500-catch-ISO-8601-datetime-in-all-lo.patch
Patch97: 0001-Resolves-tdf-89484-check-that-sheet-reference-is-wit.patch
+Patch98: 0001-Resolves-tdf-81659-handle-expand-reference-edge-corr.patch
%define instdir %{_libdir}
%define baseinstdir %{instdir}/libreoffice
@@ -2287,11 +2288,12 @@ update-desktop-database %{_datadir}/applications &> /dev/null || :
%endif
%changelog
-* Fri Feb 06 2015 Eike Rathke <erack at redhat.com> - 1:4.2.8.2-6-UNBUILT
+* Thu Feb 26 2015 Eike Rathke <erack at redhat.com> - 1:4.2.8.2-6
- Resolves: tdf#83461 do not override MatColsRows if already set
- Resolves: rhbz#1190657 tdf#87199 Writer crashes when merging table cells
- Resolves: tdf#89500 catch ISO 8601 datetime in all locales
- Resolves: tdf#89484 check that sheet reference is within selected sheets
+- Resolves: tdf#81659 handle expand reference edge correctly
* Thu Jan 29 2015 Caolán McNamara <caolanm at redhat.com> - 1:4.2.8.2-5
- Resolves: rhbz#1134841 bn/ml "close without saving" short-cuts
More information about the scm-commits
mailing list