rpms/openoffice.org/devel openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch, NONE, 1.1 openoffice.org.spec, 1.1803, 1.1804

Caolan McNamara caolanm at fedoraproject.org
Mon Feb 16 09:19:57 UTC 2009


Author: caolanm

Update of /cvs/pkgs/rpms/openoffice.org/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv13857

Modified Files:
	openoffice.org.spec 
Added Files:
	openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch 
Log Message:
Resolves: rhbz#472853 openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch

openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch:

--- NEW FILE openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch ---
Index: sc/source/core/data/table2.cxx
===================================================================
--- sc/source/core/data/table2.cxx	(revision 266950)
+++ sc/source/core/data/table2.cxx	(working copy)
@@ -2630,7 +2630,7 @@
 					pCell = aCol[nCol].GetCell( nRow );
 					if (pCell)
 						if ( pCell->GetCellType() == CELLTYPE_FORMULA )
-							if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
+							if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
 								if ( aRef.aStart.Col() == nCol && aRef.aEnd.Col() == nCol &&
 									 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
 									 DiffSign( aRef.aStart.Row(), nRow ) ==
@@ -2661,7 +2661,7 @@
 			while ( aIter.Next( nRow, pCell ) && !bFound )
 			{
 				if ( pCell->GetCellType() == CELLTYPE_FORMULA )
-					if (((ScFormulaCell*)pCell)->HasOneReference( aRef ))
+					if (((ScFormulaCell*)pCell)->HasRefListExpressibleAsOneReference( aRef ))
 						if ( aRef.aStart.Row() == nRow && aRef.aEnd.Row() == nRow &&
 							 aRef.aStart.Tab() == nTab && aRef.aEnd.Tab() == nTab &&
 							 DiffSign( aRef.aStart.Col(), nCol ) ==
Index: sc/source/core/data/cell2.cxx
===================================================================
--- sc/source/core/data/cell2.cxx	(revision 266950)
+++ sc/source/core/data/cell2.cxx	(working copy)
@@ -34,6 +34,11 @@
 
 
 // INCLUDE ---------------------------------------------------------------
+#include <algorithm>
+#include <deque>
+
+#include <boost/bind.hpp>
+
 #include <vcl/mapmod.hxx>
 #include <svx/editobj.hxx>
 #include <svx/editstat.hxx>
@@ -180,6 +185,186 @@
 
 //---------------------------------------------------------------------
 
+namespace
+{
+
+using std::deque;
+
+typedef SCCOLROW(*DimensionSelector)(ScSingleRefData const&);
+
+
+static SCCOLROW lcl_GetCol(ScSingleRefData const& rData)
+{
+    return rData.nCol;
+}
+
+
+static SCCOLROW lcl_GetRow(ScSingleRefData const& rData)
+{
+    return rData.nRow;
+}
+
+
+static SCCOLROW lcl_GetTab(ScSingleRefData const& rData)
+{
+    return rData.nTab;
+}
+
+
+/** Check if both references span the same range in selected dimension.
+ */
+static bool
+lcl_checkRangeDimension(
+        SingleDoubleRefProvider const& rRef1,
+        SingleDoubleRefProvider const& rRef2,
+        DimensionSelector aWhich)
+{
+    return
+        aWhich(rRef1.Ref1) == aWhich(rRef2.Ref1)
+        && aWhich(rRef1.Ref2) == aWhich(rRef2.Ref2);
+}
+
+
+/** Check if the two given ranges (represented by tokens) can possibly
+    form a range. To do that, two of their dimensions must be the same.
+ */
+static bool
+lcl_checkRangeDimensions(
+        ScToken const* const pRef1, ScToken const* const pRef2,
+        bool& bCol, bool& bRow, bool& bTab)
+{
+    SingleDoubleRefProvider const rRef1(*pRef1);
+    SingleDoubleRefProvider const rRef2(*pRef2);
+    bool const bSameCols(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetCol));
+    bool const bSameRows(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetRow));
+    bool const bSameTabs(lcl_checkRangeDimension(rRef1, rRef2, lcl_GetTab));
+    // Just two of the bSameX variables can be true
+    if (!(bSameCols ^ bSameRows ^ bSameTabs)
+            && (bSameCols || bSameRows || bSameTabs))
+    {
+        bCol = !bSameCols;
+        bRow = !bSameRows;
+        bTab = !bSameTabs;
+        return true;
+    }
+    return false;
+}
+
+
+bool
+lcl_lessReferenceBy(
+        ScToken const* const pRef1, ScToken const* const pRef2,
+        DimensionSelector aWhich)
+{
+    SingleDoubleRefProvider const rRef1(*pRef1);
+    SingleDoubleRefProvider const rRef2(*pRef2);
+    return aWhich(rRef1.Ref1) < aWhich(rRef2.Ref1);
+}
+
+
+/** Returns true if range denoted by token pRef2 starts immediately after
+    range denoted by token pRef1. Dimension, in which the comparison takes
+    place, is given by aWhich.
+ */
+bool
+lcl_isImmediatelyFollowing(
+        ScToken const* const pRef1, ScToken const* const pRef2,
+        DimensionSelector aWhich)
+{
+    SingleDoubleRefProvider const rRef1(*pRef1);
+    SingleDoubleRefProvider const rRef2(*pRef2);
+    return aWhich(rRef2.Ref1) - aWhich(rRef1.Ref2) == 1;
+}
+
+
+static bool
+lcl_checkIfAdjacent(
+        deque<ScToken*> const& rReferences,
+        DimensionSelector aWhich)
+{
+    typedef deque<ScToken*>::const_iterator Iter;
+    Iter aBegin(rReferences.begin());
+    Iter aEnd(rReferences.end());
+    Iter aBegin1(aBegin);
+    ++aBegin1, --aEnd;
+    return std::equal(
+            aBegin, aEnd, aBegin1,
+            boost::bind(lcl_isImmediatelyFollowing, _1, _2, aWhich));
+}
+
+
+static void
+lcl_fillRangeFromRefList(
+        deque<ScToken*> const& rReferences, ScRange& rRange)
+{
+    ScSingleRefData const aStart(
+            SingleDoubleRefProvider(*rReferences.front()).Ref1);
+    rRange.aStart.Set(aStart.nCol, aStart.nRow, aStart.nTab);
+    ScSingleRefData const aEnd(
+            SingleDoubleRefProvider(*rReferences.back()).Ref2);
+    rRange.aEnd.Set(aEnd.nCol, aEnd.nRow, aEnd.nTab);
+}
+
+
+static bool
+lcl_refListFormsOneRange(
+        ScAddress const& aPos, deque<ScToken*>& rReferences,
+        ScRange& rRange)
+{
+    std::for_each(
+            rReferences.begin(), rReferences.end(),
+            bind(&ScToken::CalcAbsIfRel, _1, aPos))
+        ;
+    if (rReferences.size() == 1) {
+        lcl_fillRangeFromRefList(rReferences, rRange);
+        return true;
+    }
+
+    bool bCell;
+    bool bRow;
+    bool bTab;
+    if (lcl_checkRangeDimensions(rReferences.front(), rReferences.back(),
+            bCell, bRow, bTab))
+    {
+        DimensionSelector aWhich;
+        if (bCell)
+        {
+            aWhich = lcl_GetCol;
+        }
+        else if (bRow)
+        {
+            aWhich = lcl_GetRow;
+        }
+        else if (bTab)
+        {
+            aWhich = lcl_GetTab;
+        }
+        else
+        {
+            OSL_ENSURE(false, "lcl_checkRangeDimensions shouldn't allow that!");
+        }
+        // Sort the references by start of range
+        std::sort(rReferences.begin(), rReferences.end(),
+                boost::bind(lcl_lessReferenceBy, _1, _2, aWhich));
+        if (lcl_checkIfAdjacent(rReferences, aWhich))
+        {
+            lcl_fillRangeFromRefList(rReferences, rRange);
+            return true;
+        }
+    }
+    return false;
+}
+
+
+bool lcl_isReference(FormulaToken const& rToken)
+{
+    return
+        rToken.GetType() == svSingleRef ||
+        rToken.GetType() == svDoubleRef;
+}
+
+}
+
 BOOL ScFormulaCell::IsEmpty()
 {
     if (IsDirtyOrInTableOpDirty() && pDocument->GetAutoCalc())
@@ -308,7 +493,7 @@
                     pFCell = this;      // this MM_FORMULA
                 // this gibt's nur einmal, kein Vergleich auf pFCell==this
                 if ( pFCell && pFCell->GetCellType() == CELLTYPE_FORMULA
-                  && pFCell->cMatrixFlag == MM_FORMULA )
+                && pFCell->cMatrixFlag == MM_FORMULA )
                 {
                     pFCell->GetMatColsRows( nC, nR );
                     if ( nC == 0 || nR == 0 )
@@ -324,8 +509,8 @@
                         {
                             pCell = pDocument->GetCell( aAdr );
                             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
-                              && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
-                              && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
+                            && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
+                            && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
                             {
                                 nC++;
                                 aAdr.IncCol();
@@ -340,8 +525,8 @@
                         {
                             pCell = pDocument->GetCell( aAdr );
                             if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA
-                              && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
-                              && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
+                            && ((ScFormulaCell*)pCell)->cMatrixFlag == MM_REFERENCE
+                            && GetMatrixOrigin( aTmpOrg ) && aTmpOrg == aOrg )
                             {
                                 nR++;
                                 aAdr.IncRow();
@@ -454,6 +639,52 @@
         return FALSE;
 }
 
+bool
+ScFormulaCell::HasRefListExpressibleAsOneReference(ScRange& rRange) const
+{
+    /* If there appears just one reference in the formula, it's the same
+       as HasOneReference(). If there are more of them, they can denote
+       one range if they are (sole) arguments of one function.
+       Union of these references must form one range and their
+       intersection must be empty set.
+    */
+    pCode->Reset();
+    // Get first reference, if any
+    ScToken* const pFirstReference(
+            dynamic_cast<ScToken*>(pCode->GetNextReferenceRPN()));
+    if (pFirstReference)
+    {
+        // Collect all consecutive references, starting by the one
+        // already found
+        std::deque<ScToken*> aReferences;
+        aReferences.push_back(pFirstReference);
+        FormulaToken* pToken(pCode->NextRPN());
+        FormulaToken* pFunction(0);
+        while (pToken)
+        {
+            if (lcl_isReference(*pToken))
+            {
+                aReferences.push_back(dynamic_cast<ScToken*>(pToken));
+                pToken = pCode->NextRPN();
+            }
+            else
+            {
+                if (pToken->IsFunction())
+                {
+                    pFunction = pToken;
+                }
+                break;
+            }
+        }
+        if (pFunction && !pCode->GetNextReferenceRPN()
+                && (pFunction->GetParamCount() == aReferences.size()))
+        {
+            return lcl_refListFormsOneRange(aPos, aReferences, rRange);
+        }
+    }
+    return false;
+}
+
 BOOL ScFormulaCell::HasRelNameReference() const
 {
     pCode->Reset();
Index: sc/inc/cell.hxx
===================================================================
--- sc/inc/cell.hxx	(revision 266950)
+++ sc/inc/cell.hxx	(working copy)
@@ -309,6 +309,15 @@
     inline USHORT   GetSeenInIteration() const { return nSeenInIteration; }
 
 	BOOL			HasOneReference( ScRange& r ) const;
+    /* Checks if the formula contains reference list that can be
+       expressed by one reference (like A1;A2;A3:A5 -> A1:A5). The
+       reference list is not required to be sorted (i.e. A3;A1;A2 is
+       still recognized as A1:A3), but no overlapping is allowed.
+       If one reference is recognized, the rRange is filled.
+
+       It is similar to HasOneReference(), but more general.
+     */
+    bool HasRefListExpressibleAsOneReference(ScRange& rRange) const;
 	BOOL			HasRelNameReference() const;
 	BOOL			HasColRowName() const;
 
Index: sc/inc/pch/precompiled_sc.hxx
===================================================================
--- sc/inc/pch/precompiled_sc.hxx	(revision 266950)
+++ sc/inc/pch/precompiled_sc.hxx	(working copy)
@@ -36,6 +36,7 @@
 
 #include <algorithm>
 #include <assert.h>
+#include <deque>
 #include <stdarg.h>
 #include <stddef.h>
 #include <stdio.h>
@@ -49,6 +50,8 @@
 #include <new>
 #include <cfloat>
 
+#include <boost/bind.hpp>
+
 #include <basegfx/polygon/b2dpolygon.hxx>
 #include <basegfx/polygon/b3dpolygon.hxx>
 #include <basegfx/polygon/b3dpolypolygon.hxx>


Index: openoffice.org.spec
===================================================================
RCS file: /cvs/pkgs/rpms/openoffice.org/devel/openoffice.org.spec,v
retrieving revision 1.1803
retrieving revision 1.1804
diff -u -r1.1803 -r1.1804
--- openoffice.org.spec	16 Feb 2009 09:04:34 -0000	1.1803
+++ openoffice.org.spec	16 Feb 2009 09:19:26 -0000	1.1804
@@ -121,6 +121,7 @@
 Patch48: openoffice.org-3.0.1.ooo99050.sw.htmlload.patch
 Patch49: workspace.gfbcrash.patch
 Patch50: openoffice.org-3.1.0.oooXXXXX.gcc44.buildfixes.patch
+Patch51: openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch
 
 %define python_py_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib(0)")
 %define instdir %{_libdir}
@@ -1571,6 +1572,7 @@
 %patch48 -p1 -R -b .ooo99050.sw.htmlload.patch
 %patch49 -p0 -b .workspace.gfbcrash.patch
 %patch50 -p1 -b .oooXXXXX.gcc44.buildfixes.patch
+%patch51 -p0 -b .ooo99250.sc.autooutline-reflists.patch
 
 %build
 echo build start time is `date`, diskspace: `df -h . | tail -n 1`
@@ -4062,8 +4064,7 @@
     unopkg list --shared > /dev/null 2>&1 || :
 
 %changelog
-* Thu Feb 12 2009 Caolán McNamara <caolanm at redhat.com> - 1:3.1.0-1.1
-- Resolves: rhbz#483487 Updated Finnish translations
+* Mon Feb 16 2009 Caolán McNamara <caolanm at redhat.com> - 1:3.1.0-1.1
 - drop integrated workspace.selinux01.patch (finally)
 - drop integrated workspace.impressfontsize.patch
 - drop integrated workspace.cmcfixes48.patch
@@ -4086,6 +4087,8 @@
 - drop integrated workspace.fwk99.patch
 - drop integrated workspace.tkr16.patch
 - drop integrated workspace.i18n45.patch
+- Resolves: rhbz#483487 Updated Finnish translations
+- Resolves: rhbz#472853 openoffice.org-3.1.0.ooo99250.sc.autooutline-reflists.patch
 
 * Tue Feb 10 2009 Caolán McNamara <caolanm at redhat.com> - 1:3.0.1-15.8
 - culmus-fonts => culmus-nachlieli-clm-fonts




More information about the fedora-extras-commits mailing list