summaryrefslogtreecommitdiff
path: root/sc/source/core/tool
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-06-17 17:12:49 +0200
committerAndras Timar <andras.timar@collabora.com>2015-06-30 18:51:08 +0200
commitf344397f13d4596fcd6253523268ffdcf4bb7e8e (patch)
tree7632065745bce2be1ea514c9bc877ddf0a2d1bac /sc/source/core/tool
parent3a6421cd98f18ae286dd2f302ca0f44db0c5f82e (diff)
Resolves: tdf#83365 push proper references in INDIRECT
... that take relative/absolute addressing and sheet 3D flag into account to be fed to reference extension via range operator. (cherry picked from commit fb6dd2a73074b9695bd8ddf7ba40f1819b03024e) properly inherit relative and 3D flags when extending, tdf#83365 related Commit 194e9f9bae28bdf22a9ed4779c1656ee693f3302 oversimplified things. (cherry picked from commit e503addfbbe45efe1a3c06392c66fb79c3c72d07) Change-Id: Iabe13ae384577e2d71ca87af6482ddccbf7ad0ac ea6a84c4a7be49af036690afbb1512ae2c1045a2 Reviewed-on: https://gerrit.libreoffice.org/16352 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'sc/source/core/tool')
-rw-r--r--sc/source/core/tool/interpr1.cxx5
-rw-r--r--sc/source/core/tool/interpr4.cxx20
-rw-r--r--sc/source/core/tool/refdata.cxx73
3 files changed, 94 insertions, 4 deletions
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index f2f1d43f9c50..fe314bfef995 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -7064,8 +7064,7 @@ void ScInterpreter::ScIndirect()
aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab());
}
else
- PushDoubleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab(),
- aRefAd2.Col(), aRefAd2.Row(), aRefAd2.Tab() );
+ PushDoubleRef( aRefAd, aRefAd2);
}
else if (ConvertSingleRef(pDok, sRefStr, nTab, aRefAd, aDetails, &aExtInfo))
{
@@ -7075,7 +7074,7 @@ void ScInterpreter::ScIndirect()
aExtInfo.mnFileId, aExtInfo.maTabName, aRefAd.Col(), aRefAd.Row(), aRefAd.Tab());
}
else
- PushSingleRef( aRefAd.Col(), aRefAd.Row(), aRefAd.Tab() );
+ PushSingleRef( aRefAd);
}
else
{
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 8b5fb734e390..504e87873fcf 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1965,6 +1965,26 @@ void ScInterpreter::PushExternalDoubleRef(
}
}
+void ScInterpreter::PushSingleRef( const ScRefAddress& rRef )
+{
+ if (!IfErrorPushError())
+ {
+ ScSingleRefData aRef;
+ aRef.InitFromRefAddress( rRef, aPos);
+ PushTempTokenWithoutError( new ScSingleRefToken( aRef ) );
+ }
+}
+
+void ScInterpreter::PushDoubleRef( const ScRefAddress& rRef1, const ScRefAddress& rRef2 )
+{
+ if (!IfErrorPushError())
+ {
+ ScComplexRefData aRef;
+ aRef.InitFromRefAddresses( rRef1, rRef2, aPos);
+ PushTempTokenWithoutError( new ScDoubleRefToken( aRef ) );
+ }
+}
+
void ScInterpreter::PushMatrix( const sc::RangeMatrix& rMat )
{
if (!rMat.isRangeValid())
diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx
index d508247ad641..97d419c03105 100644
--- a/sc/source/core/tool/refdata.cxx
+++ b/sc/source/core/tool/refdata.cxx
@@ -41,6 +41,16 @@ void ScSingleRefData::InitAddressRel( const ScAddress& rAdr, const ScAddress& rP
SetAddress(rAdr, rPos);
}
+void ScSingleRefData::InitFromRefAddress( const ScRefAddress& rRef, const ScAddress& rPos )
+{
+ InitFlags();
+ SetColRel( rRef.IsRelCol());
+ SetRowRel( rRef.IsRelRow());
+ SetTabRel( rRef.IsRelTab());
+ SetFlag3D( rRef.Tab() != rPos.Tab());
+ SetAddress( rRef.GetAddress(), rPos);
+}
+
void ScSingleRefData::SetAbsCol( SCCOL nVal )
{
Flags.bColRel = false;
@@ -257,10 +267,38 @@ void ScSingleRefData::Dump( int nIndent ) const
}
#endif
+void ScComplexRefData::InitFromRefAddresses( const ScRefAddress& rRef1, const ScRefAddress& rRef2, const ScAddress& rPos )
+{
+ InitFlags();
+ Ref1.SetColRel( rRef1.IsRelCol());
+ Ref1.SetRowRel( rRef1.IsRelRow());
+ Ref1.SetTabRel( rRef1.IsRelTab());
+ Ref1.SetFlag3D( rRef1.Tab() != rPos.Tab() || rRef1.Tab() != rRef2.Tab());
+ Ref2.SetColRel( rRef2.IsRelCol());
+ Ref2.SetRowRel( rRef2.IsRelRow());
+ Ref2.SetTabRel( rRef2.IsRelTab());
+ Ref2.SetFlag3D( rRef1.Tab() != rRef2.Tab());
+ SetRange( ScRange( rRef1.GetAddress(), rRef2.GetAddress()), rPos);
+}
+
ScComplexRefData& ScComplexRefData::Extend( const ScSingleRefData & rRef, const ScAddress & rPos )
{
+ bool bInherit3D = (Ref1.IsFlag3D() && !Ref2.IsFlag3D() && !rRef.IsFlag3D());
ScRange aAbsRange = toAbs(rPos);
- ScAddress aAbs = rRef.toAbs(rPos);
+
+ ScSingleRefData aRef = rRef;
+ // If no sheet was given in the extending part, let it point to the same
+ // sheet as this reference's end point, inheriting the absolute/relative
+ // mode.
+ // [$]Sheet1.A5:A6:A7 on Sheet2 do still reference only Sheet1.
+ if (!rRef.IsFlag3D())
+ {
+ if (Ref2.IsTabRel())
+ aRef.SetRelTab( Ref2.Tab());
+ else
+ aRef.SetAbsTab( Ref2.Tab());
+ }
+ ScAddress aAbs = aRef.toAbs(rPos);
if (aAbs.Col() < aAbsRange.aStart.Col())
aAbsRange.aStart.SetCol(aAbs.Col());
@@ -280,6 +318,39 @@ ScComplexRefData& ScComplexRefData::Extend( const ScSingleRefData & rRef, const
if (aAbsRange.aEnd.Tab() < aAbs.Tab())
aAbsRange.aEnd.SetTab(aAbs.Tab());
+ // In Ref2 inherit absolute/relative addressing from the extending part.
+ // A$5:A5 => A$5:A$5:A5 => A$5:A5, and not A$5:A$5
+ // A$6:$A5 => A$6:A$6:$A5 => A5:$A$6
+ if (aAbsRange.aEnd.Col() == aAbs.Col())
+ Ref2.SetColRel( rRef.IsColRel());
+ if (aAbsRange.aEnd.Row() == aAbs.Row())
+ Ref2.SetRowRel( rRef.IsRowRel());
+
+ // In Ref1 inherit relative sheet from extending part if given.
+ if (aAbsRange.aStart.Tab() == aAbs.Tab() && rRef.IsFlag3D())
+ Ref1.SetTabRel( rRef.IsTabRel());
+
+ // In Ref2 inherit relative sheet from either Ref1 or extending part.
+ // Use the original 3D flags to determine which.
+ // $Sheet1.$A$5:$A$6 => $Sheet1.$A$5:$A$5:$A$6 => $Sheet1.$A$5:$A$6, and
+ // not $Sheet1.$A$5:Sheet1.$A$6 (with invisible second 3D, but relative).
+ if (aAbsRange.aEnd.Tab() == aAbs.Tab())
+ Ref2.SetTabRel( bInherit3D ? Ref1.IsTabRel() : rRef.IsTabRel());
+
+ // Force 3D flag in Ref1 if different sheet or more than one sheet
+ // referenced.
+ if (aAbsRange.aStart.Tab() != rPos.Tab() || aAbsRange.aStart.Tab() != aAbsRange.aEnd.Tab())
+ Ref1.SetFlag3D(true);
+
+ // Force 3D flag in Ref2 if more than one sheet referenced.
+ if (aAbsRange.aStart.Tab() != aAbsRange.aEnd.Tab())
+ Ref2.SetFlag3D(true);
+
+ // Inherit 3D flag in Ref1 from extending part in case range wasn't
+ // extended as in A5:A5:Sheet1.A5 if on Sheet1.
+ if (rRef.IsFlag3D())
+ Ref1.SetFlag3D( true);
+
SetRange(aAbsRange, rPos);
return *this;