Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
407a6774
Kaydet (Commit)
407a6774
authored
Tem 26, 2013
tarafından
Kohei Yoshida
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Re-implement sheet reference adjustment on sheet move.
Change-Id: I24e93e0bbc51c7f9a1f1ea0c126a1399ace84a9e
üst
11e64bb4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
136 additions
and
23 deletions
+136
-23
tokenarray.hxx
sc/inc/tokenarray.hxx
+2
-0
ucalc_formula.cxx
sc/qa/unit/ucalc_formula.cxx
+50
-0
formulacell.cxx
sc/source/core/data/formulacell.cxx
+11
-23
token.cxx
sc/source/core/tool/token.cxx
+73
-0
No files found.
sc/inc/tokenarray.hxx
Dosyayı görüntüle @
407a6774
...
...
@@ -145,6 +145,8 @@ public:
bool
AdjustReferenceOnInsertedTab
(
SCTAB
nInsPos
,
SCTAB
nSheets
,
const
ScAddress
&
rOldPos
);
void
AdjustReferenceOnMovedTab
(
SCTAB
nOldPos
,
SCTAB
nNewPos
,
const
ScAddress
&
rOldPos
);
#if DEBUG_FORMULA_COMPILER
void
Dump
()
const
;
#endif
...
...
sc/qa/unit/ucalc_formula.cxx
Dosyayı görüntüle @
407a6774
...
...
@@ -813,6 +813,36 @@ void Test::testFormulaRefUpdateSheets()
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
2
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Move the last sheet (Sheet2) to the first position.
m_pDoc
->
MoveTab
(
2
,
0
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
1
,
0
),
"SUM(Sheet1.B2:C3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B2."
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
0
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Move back.
m_pDoc
->
MoveTab
(
0
,
2
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
1
,
2
),
"SUM(Sheet1.B2:C3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B2."
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
2
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Move the "Temp" sheet to the last position.
m_pDoc
->
MoveTab
(
1
,
2
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
1
,
1
),
"SUM(Sheet1.B2:C3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B2."
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
1
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Move back.
m_pDoc
->
MoveTab
(
2
,
1
);
// Delete the temporary sheet.
m_pDoc
->
DeleteTab
(
1
);
...
...
@@ -848,6 +878,26 @@ void Test::testFormulaRefUpdateSheets()
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
1
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Append a bunch of sheets.
m_pDoc
->
InsertTab
(
2
,
"Temp1"
);
m_pDoc
->
InsertTab
(
3
,
"Temp2"
);
m_pDoc
->
InsertTab
(
4
,
"Temp3"
);
// Move these tabs around. This shouldn't affects the first 2 sheets.
m_pDoc
->
MoveTab
(
2
,
4
);
m_pDoc
->
MoveTab
(
3
,
2
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
1
,
1
),
"SUM(Sheet1.B2:C3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B2."
);
if
(
!
checkFormula
(
*
m_pDoc
,
ScAddress
(
1
,
2
,
1
),
"SUM($Sheet1.$B$2:$C$3)"
))
CPPUNIT_FAIL
(
"Wrong formula in Sheet2.B3."
);
// Delete the temp sheets.
m_pDoc
->
DeleteTab
(
4
);
m_pDoc
->
DeleteTab
(
3
);
m_pDoc
->
DeleteTab
(
2
);
// Delete Sheet1.
m_pDoc
->
DeleteTab
(
0
);
m_pDoc
->
GetName
(
0
,
aName
);
...
...
sc/source/core/data/formulacell.cxx
Dosyayı görüntüle @
407a6774
...
...
@@ -2598,31 +2598,19 @@ bool ScFormulaCell::UpdateDeleteTab(SCTAB nTable, bool /*bIsMove*/, SCTAB nSheet
void
ScFormulaCell
::
UpdateMoveTab
(
SCTAB
nOldPos
,
SCTAB
nNewPos
,
SCTAB
nTabNo
)
{
pCode
->
Reset
();
if
(
pCode
->
GetNextReferenceRPN
()
&&
!
pDocument
->
IsClipOrUndo
()
)
if
(
!
pCode
->
GetNextReferenceRPN
()
||
pDocument
->
IsClipOrUndo
()
)
{
EndListeningTo
(
pDocument
);
// SetTab _after_ EndListeningTo und _before_ Compiler UpdateMoveTab !
aPos
.
SetTab
(
nTabNo
);
ScRangeData
*
pRangeData
;
ScCompiler
aComp
(
pDocument
,
aPos
,
*
pCode
);
aComp
.
SetGrammar
(
pDocument
->
GetGrammar
());
pRangeData
=
aComp
.
UpdateMoveTab
(
nOldPos
,
nNewPos
,
false
);
if
(
pRangeData
)
// Exchange Shared Formula with real Formula
{
pDocument
->
RemoveFromFormulaTree
(
this
);
// update formula count
delete
pCode
;
pCode
=
pRangeData
->
GetCode
()
->
Clone
();
ScCompiler
aComp2
(
pDocument
,
aPos
,
*
pCode
);
aComp2
.
SetGrammar
(
pDocument
->
GetGrammar
());
aComp2
.
CompileTokenArray
();
aComp2
.
MoveRelWrap
(
pRangeData
->
GetMaxCol
(),
pRangeData
->
GetMaxRow
());
aComp2
.
UpdateMoveTab
(
nOldPos
,
nNewPos
,
true
);
bCompile
=
true
;
}
// no StartListeningTo because pTab[nTab] not yet correct!
aPos
.
SetTab
(
nTabNo
);
return
;
}
else
aPos
.
SetTab
(
nTabNo
);
EndListeningTo
(
pDocument
);
ScAddress
aOldPos
=
aPos
;
// SetTab _after_ EndListeningTo und _before_ Compiler UpdateMoveTab !
aPos
.
SetTab
(
nTabNo
);
// no StartListeningTo because pTab[nTab] not yet correct!
pCode
->
AdjustReferenceOnMovedTab
(
nOldPos
,
nNewPos
,
aOldPos
);
}
void
ScFormulaCell
::
UpdateInsertTabAbs
(
SCTAB
nTable
)
...
...
sc/source/core/tool/token.cxx
Dosyayı görüntüle @
407a6774
...
...
@@ -2660,6 +2660,79 @@ bool ScTokenArray::AdjustReferenceOnInsertedTab( SCTAB nInsPos, SCTAB nSheets, c
return
bRefChanged
;
}
namespace
{
void
adjustTabOnMove
(
ScAddress
&
rPos
,
SCTAB
nOldPos
,
SCTAB
nNewPos
)
{
// Sheets below the lower bound or above the uppper bound will not change.
SCTAB
nLowerBound
=
std
::
min
(
nOldPos
,
nNewPos
);
SCTAB
nUpperBound
=
std
::
max
(
nOldPos
,
nNewPos
);
if
(
rPos
.
Tab
()
<
nLowerBound
||
nUpperBound
<
rPos
.
Tab
())
// Outside the boundary. Nothing to adjust.
return
;
if
(
rPos
.
Tab
()
==
nOldPos
)
{
rPos
.
SetTab
(
nNewPos
);
return
;
}
// It's somewhere in between.
if
(
nOldPos
<
nNewPos
)
{
// Moving a sheet to the right. The rest of the sheets shifts to the left.
rPos
.
IncTab
(
-
1
);
}
else
{
// Moving a sheet to the left. The rest of the sheets shifts to the right.
rPos
.
IncTab
();
}
}
}
void
ScTokenArray
::
AdjustReferenceOnMovedTab
(
SCTAB
nOldPos
,
SCTAB
nNewPos
,
const
ScAddress
&
rOldPos
)
{
if
(
nOldPos
==
nNewPos
)
return
;
ScAddress
aNewPos
=
rOldPos
;
adjustTabOnMove
(
aNewPos
,
nOldPos
,
nNewPos
);
FormulaToken
**
p
=
pCode
;
FormulaToken
**
pEnd
=
p
+
static_cast
<
size_t
>
(
nLen
);
for
(;
p
!=
pEnd
;
++
p
)
{
switch
((
*
p
)
->
GetType
())
{
case
svSingleRef
:
{
ScToken
*
pToken
=
static_cast
<
ScToken
*>
(
*
p
);
ScSingleRefData
&
rRef
=
pToken
->
GetSingleRef
();
ScAddress
aAbs
=
rRef
.
toAbs
(
rOldPos
);
adjustTabOnMove
(
aAbs
,
nOldPos
,
nNewPos
);
rRef
.
SetAddress
(
aAbs
,
aNewPos
);
}
break
;
case
svDoubleRef
:
{
ScToken
*
pToken
=
static_cast
<
ScToken
*>
(
*
p
);
ScComplexRefData
&
rRef
=
pToken
->
GetDoubleRef
();
ScRange
aAbs
=
rRef
.
toAbs
(
rOldPos
);
adjustTabOnMove
(
aAbs
.
aStart
,
nOldPos
,
nNewPos
);
adjustTabOnMove
(
aAbs
.
aEnd
,
nOldPos
,
nNewPos
);
rRef
.
SetRange
(
aAbs
,
aNewPos
);
}
break
;
default
:
;
}
}
}
#if DEBUG_FORMULA_COMPILER
void
ScTokenArray
::
Dump
()
const
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment