summaryrefslogtreecommitdiffstats
path: root/sc/source
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2011-12-17 00:37:45 +0100
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2011-12-17 01:10:07 +0100
commitbfbcd95c3f701251270fac06f9ef58f484580407 (patch)
treeb6520286e8b4ee303070908d6bb9474d07299991 /sc/source
parentFix assertion in PageSelector::CheckConsistency() (diff)
downloadcore-bfbcd95c3f701251270fac06f9ef58f484580407.tar.gz
core-bfbcd95c3f701251270fac06f9ef58f484580407.zip
Copy Absolute Formulas between documents: Part I
Copying absolute sheet references between different documents now transforms absolute sheet references into external references if the refered range is not copied. Working: References to already saved documents work already with: -only transform reference into an external reference if range is not in the copied range -don't transform relative references Missing: handling for copying from not yet saved files idea: - add handling of external references to open documents that are not yet saved through the temporary document name - transform the url to the correct file url as soon as the source document is saved - if target document is saved first show warning message to the user and save with temporary name as file url
Diffstat (limited to 'sc/source')
-rw-r--r--sc/source/core/data/cell.cxx5
-rw-r--r--sc/source/core/data/document.cxx52
-rw-r--r--sc/source/core/tool/reftokenhelper.cxx59
-rw-r--r--sc/source/core/tool/token.cxx89
4 files changed, 203 insertions, 2 deletions
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 6cc8209f909e..f86d8987e3f0 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -881,6 +881,11 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons
adjustDBRange(pToken, rDoc, rCell.pDocument);
}
}
+
+ if (pDocument->GetPool() != rCell.pDocument->GetPool())
+ {
+ pCode->ReadjusteAbsolute3DReferences( rCell.pDocument, &rDoc, rCell.aPos);
+ }
}
if( !bCompile )
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index efb003ba8f1b..d12601fe992e 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -42,12 +42,14 @@
#include <svx/svdocapt.hxx>
#include <sfx2/app.hxx>
#include <sfx2/objsh.hxx>
+#include <sfx2/docfile.hxx>
#include <svl/poolcach.hxx>
#include <unotools/saveopt.hxx>
#include <svl/zforlist.hxx>
#include <unotools/charclass.hxx>
#include <unotools/transliterationwrapper.hxx>
#include <tools/tenccvt.hxx>
+#include <tools/urlobj.hxx>
#include <com/sun/star/text/WritingMode2.hpp>
#include <com/sun/star/script/vba/XVBACompatibility.hpp>
@@ -97,6 +99,9 @@
#include <map>
#include <limits>
+#include <rtl/oustringostreaminserter.hxx>
+#include <iostream>
+
using ::editeng::SvxBorderLine;
using namespace ::com::sun::star;
@@ -180,6 +185,14 @@ bool ScDocument::GetName( SCTAB nTab, rtl::OUString& rName ) const
return false;
}
+rtl::OUString ScDocument::GetCopyTabName( SCTAB nTab ) const
+{
+ if (nTab < static_cast<SCTAB>(maTabNames.size()))
+ return maTabNames[nTab];
+ else
+ return rtl::OUString();
+}
+
bool ScDocument::SetCodeName( SCTAB nTab, const rtl::OUString& rName )
{
if (VALIDTAB(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
@@ -1675,6 +1688,7 @@ void ScDocument::InitUndoSelected( ScDocument* pSrcDoc, const ScMarkData& rTabSe
xPoolHelper = pSrcDoc->xPoolHelper;
+
rtl::OUString aString;
for (SCTAB nTab = 0; nTab <= rTabSelection.GetLastSelected(); nTab++)
if ( rTabSelection.GetTableSelect( nTab ) )
@@ -1694,9 +1708,9 @@ void ScDocument::InitUndoSelected( ScDocument* pSrcDoc, const ScMarkData& rTabSe
}
}
else
- {
+ {
OSL_FAIL("InitUndo");
- }
+ }
}
@@ -1708,6 +1722,12 @@ void ScDocument::InitUndo( ScDocument* pSrcDoc, SCTAB nTab1, SCTAB nTab2,
Clear();
xPoolHelper = pSrcDoc->xPoolHelper;
+ if (pSrcDoc->pShell->GetMedium())
+ {
+ maFileURL = pSrcDoc->pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
+ std::cout << "SfxMedium: " << maFileURL << std::endl;
+ std::cout << "GetName: " << rtl::OUString(pSrcDoc->pShell->GetName()) << std::endl;
+ }
rtl::OUString aString;
if ( nTab2 >= static_cast<SCTAB>(maTabs.size()))
@@ -1893,6 +1913,34 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam,
pClipDoc = SC_MOD()->GetClipDoc();
}
+ if (pShell->GetMedium())
+ {
+ pClipDoc->maFileURL = pShell->GetMedium()->GetURLObject().GetMainURL(INetURLObject::DECODE_TO_IURI);
+ // for unsaved files use the title name and adjust during save of file
+ if (pClipDoc->maFileURL.isEmpty())
+ pClipDoc->maFileURL = pShell->GetName();
+
+ std::cout << pClipDoc->maFileURL << std::endl;
+ std::cout << "GetName: " << rtl::OUString(pShell->GetName()) << std::endl;
+ }
+ else
+ {
+ pClipDoc->maFileURL = pShell->GetName();
+ }
+
+ //init maTabNames
+ for (TableContainer::iterator itr = maTabs.begin(); itr != maTabs.end(); ++itr)
+ {
+ if( *itr )
+ {
+ rtl::OUString aTabName;
+ (*itr)->GetName(aTabName);
+ pClipDoc->maTabNames.push_back(aTabName);
+ }
+ else
+ pClipDoc->maTabNames.push_back(rtl::OUString());
+ }
+
pClipDoc->aDocName = aDocName;
pClipDoc->SetClipParam(rClipParam);
ScRange aClipRange = rClipParam.getWholeRange();
diff --git a/sc/source/core/tool/reftokenhelper.cxx b/sc/source/core/tool/reftokenhelper.cxx
index 0a7ed4e64d99..1d966f1dea0d 100644
--- a/sc/source/core/tool/reftokenhelper.cxx
+++ b/sc/source/core/tool/reftokenhelper.cxx
@@ -136,6 +136,9 @@ void ScRefTokenHelper::compileRangeRepresentation(
rRefTokens.clear();
}
+namespace {
+
+//may return a relative address
void singleRefToAddr(const ScSingleRefData& rRef, ScAddress& rAddr)
{
if (rRef.IsColRel())
@@ -154,6 +157,27 @@ void singleRefToAddr(const ScSingleRefData& rRef, ScAddress& rAddr)
rAddr.SetTab(rRef.nTab);
}
+//returns an absolute address in reference to rPos
+void singleRefToAbsAddr(const ScSingleRefData& rRef, ScAddress& rAddr, const ScAddress& rPos)
+{
+ if (rRef.IsColRel())
+ rAddr.SetCol(rRef.nRelCol + rPos.Col());
+ else
+ rAddr.SetCol(rRef.nCol);
+
+ if (rRef.IsRowRel())
+ rAddr.SetRow(rRef.nRelRow + rPos.Row());
+ else
+ rAddr.SetRow(rRef.nRow);
+
+ if (rRef.IsTabRel())
+ rAddr.SetTab(rRef.nRelTab + rPos.Tab());
+ else
+ rAddr.SetTab(rRef.nTab);
+}
+
+}
+
bool ScRefTokenHelper::getRangeFromToken(ScRange& rRange, const ScTokenRef& pToken, bool bExternal)
{
StackVar eType = pToken->GetType();
@@ -189,6 +213,41 @@ bool ScRefTokenHelper::getRangeFromToken(ScRange& rRange, const ScTokenRef& pTok
return false;
}
+bool ScRefTokenHelper::getAbsRangeFromToken(ScRange& rRange, const ScTokenRef& pToken, const ScAddress& rPos, bool bExternal)
+{
+ StackVar eType = pToken->GetType();
+ switch (pToken->GetType())
+ {
+ case svSingleRef:
+ case svExternalSingleRef:
+ {
+ if ((eType == svExternalSingleRef && !bExternal) ||
+ (eType == svSingleRef && bExternal))
+ return false;
+
+ const ScSingleRefData& rRefData = pToken->GetSingleRef();
+ singleRefToAbsAddr(rRefData, rRange.aStart, rPos);
+ rRange.aEnd = rRange.aStart;
+ return true;
+ }
+ case svDoubleRef:
+ case svExternalDoubleRef:
+ {
+ if ((eType == svExternalDoubleRef && !bExternal) ||
+ (eType == svDoubleRef && bExternal))
+ return false;
+
+ const ScComplexRefData& rRefData = pToken->GetDoubleRef();
+ singleRefToAbsAddr(rRefData.Ref1, rRange.aStart, rPos);
+ singleRefToAbsAddr(rRefData.Ref2, rRange.aEnd, rPos);
+ return true;
+ }
+ default:
+ ; // do nothing
+ }
+ return false;
+}
+
void ScRefTokenHelper::getRangeListFromTokens(ScRangeList& rRangeList, const vector<ScTokenRef>& rTokens)
{
vector<ScTokenRef>::const_iterator itr = rTokens.begin(), itrEnd = rTokens.end();
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 11780223c9bf..0e5433881458 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -37,9 +37,12 @@
#include <string.h>
#include <tools/mempool.hxx>
#include <osl/diagnose.h>
+#include <sfx2/docfile.hxx>
#include "token.hxx"
#include "tokenarray.hxx"
+#include "reftokenhelper.hxx"
+#include "clipparam.hxx"
#include "compiler.hxx"
#include <formula/compiler.hrc>
#include "rechead.hxx"
@@ -49,6 +52,9 @@
#include "externalrefmgr.hxx"
#include "document.hxx"
+#include <iostream>
+#include <rtl/oustringostreaminserter.hxx>
+
using ::std::vector;
#include <com/sun/star/sheet/ComplexReference.hpp>
@@ -1815,5 +1821,88 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
}
}
+namespace {
+
+void GetExternalTableData(const ScDocument* pOldDoc, const ScDocument* pNewDoc, const SCTAB nTab, rtl::OUString& rTabName, sal_uInt16& rFileId)
+{
+ rtl::OUString aFileName = pOldDoc->GetFileURL();;
+ std::cout << aFileName << std::endl;
+ rFileId = pNewDoc->GetExternalRefManager()->getExternalFileId(aFileName);
+ rTabName = pOldDoc->GetCopyTabName(nTab);
+ std::cout << "TabName: " << rTabName << std::endl;
+}
+
+bool IsInCopyRange( const ScRange& rRange, const ScDocument* pClipDoc )
+{
+ ScClipParam& rClipParam = const_cast<ScDocument*>(pClipDoc)->GetClipParam();
+ std::cout << "Col: " << rRange.aStart.Col() << "Row: " << rRange.aStart.Row() << "Tab: " << rRange.aStart.Tab() << std::endl;
+ return rClipParam.maRanges.In(rRange);
+}
+
+}
+
+void ScTokenArray::ReadjusteAbsolute3DReferences( const ScDocument* pOldDoc, const ScDocument* pNewDoc, const ScAddress& rPos )
+{
+ for ( sal_uInt16 j=0; j<nLen; ++j )
+ {
+ switch ( pCode[j]->GetType() )
+ {
+ case svDoubleRef :
+ {
+ ScComplexRefData& rRef = static_cast<ScToken*>(pCode[j])->GetDoubleRef();
+ ScSingleRefData& rRef2 = rRef.Ref2;
+ ScSingleRefData& rRef1 = rRef.Ref1;
+
+ ScRange aRange;
+ if (!ScRefTokenHelper::getAbsRangeFromToken(aRange, static_cast<ScToken*>(pCode[j]), rPos))
+ continue; // might be an external ref token
+
+ if (IsInCopyRange(aRange, pOldDoc))
+ continue; // don't adjust references to copied values
+
+ if ( (rRef2.IsFlag3D() && !rRef2.IsTabRel()) || (rRef1.IsFlag3D() && !rRef1.IsTabRel()) )
+ {
+ rtl::OUString aTabName;
+ sal_uInt16 nFileId;
+ GetExternalTableData(pOldDoc, pNewDoc, rRef1.nTab, aTabName, nFileId);
+ pCode[j]->DecRef();
+ ScExternalDoubleRefToken* pToken = new ScExternalDoubleRefToken(nFileId, aTabName, rRef);
+ pToken->IncRef();
+ pCode[j] = pToken;
+ }
+ }
+ break;
+ case svSingleRef :
+ {
+ ScSingleRefData& rRef = static_cast<ScToken*>(pCode[j])->GetSingleRef();
+
+ ScRange aRange;
+ if (!ScRefTokenHelper::getAbsRangeFromToken(aRange, static_cast<ScToken*>(pCode[j]), rPos))
+ continue; // might be an external ref token
+
+ if (IsInCopyRange(aRange, pOldDoc))
+ continue; // don't adjust references to copied values
+
+ if ( rRef.IsFlag3D() && !rRef.IsTabRel() )
+ {
+ rtl::OUString aTabName;
+ sal_uInt16 nFileId;
+ GetExternalTableData(pOldDoc, pNewDoc, rRef.nTab, aTabName, nFileId);
+ //replace with ScExternalSingleRefToken and adjust references
+ pCode[j]->DecRef();
+ ScExternalSingleRefToken* pToken = new ScExternalSingleRefToken(nFileId, aTabName, rRef);
+ pToken->IncRef();
+ pCode[j] = pToken;
+ }
+ }
+ break;
+ default:
+ {
+ // added to avoid warnings
+ }
+ }
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */