summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2009-09-07 15:38:19 +0000
committerOliver Bolte <obo@openoffice.org>2009-09-07 15:38:19 +0000
commitfbeb3ce4a4fc1cf2a4a171709cfeb677971cf577 (patch)
tree0954231fafce7d5addb67820f28cbec4280820ee
parent712e83090c793bd4a29ca77022e52d7fd82b70f7 (diff)
CWS-TOOLING: integrate CWS calcsheetdata
2009-08-13 16:18:48 +0200 nn r274950 : #i102616# shared/remote files, better handling of formula results 2009-08-12 11:17:30 +0200 nn r274884 : CWS-TOOLING: rebase CWS calcsheetdata to trunk@274622 (milestone: DEV300:m54) 2009-08-12 10:30:47 +0200 nn r274881 : #i102616# some clean-up 2009-08-11 19:01:18 +0200 nn r274876 : #i102616# store loaded namespaces, so prefixes remain valid 2009-08-11 19:00:49 +0200 nn r274875 : #i102616# store loaded namespaces, so prefixes remain valid 2009-08-10 19:12:04 +0200 nn r274835 : #i102616# detective, notes, encoding, error handling 2009-08-07 11:18:46 +0200 nn r274751 : #i102616# use new method SvXMLAutoStylePoolP::AddNamed 2009-08-07 11:18:15 +0200 nn r274750 : #i102616# new method SvXMLAutoStylePoolP::AddNamed 2009-08-06 18:02:42 +0200 nn r274740 : #i102616# modification: shapes, notes, pending row heights; skip sheets in export iterator 2009-08-05 18:41:59 +0200 nn r274694 : #i102616# handle text styles in notes 2009-08-03 18:55:59 +0200 nn r274594 : #i102616# handle text styles in cells 2009-07-31 19:00:06 +0200 nn r274548 : #i102616# handle styles for notes 2009-07-28 16:46:20 +0200 nn r274414 : missed a conflict 2009-07-28 14:01:56 +0200 nn r274404 : CWS-TOOLING: rebase CWS calcsheetdata to trunk@274203 (milestone: DEV300:m53) 2009-07-23 18:28:47 +0200 nn r274278 : #i102616# handle table styles 2009-07-22 15:40:24 +0200 nn r274244 : #i102616# handle row styles 2009-07-21 20:09:37 +0200 nn r274211 : #i102616# handle column styles 2009-07-16 13:00:18 +0200 nn r274043 : #i102616# invalidate all stream positions when inserting/deleting sheets 2009-07-15 17:41:15 +0200 nn r274021 : #i102616# don't collect cell styles twice for copied sheets 2009-07-14 18:36:11 +0200 nn r273985 : #i102616# allow to query stream position, clear buffer 2009-07-14 18:32:10 +0200 nn r273984 : #i102616# allow to specify a name for an autostyle 2009-07-09 22:01:23 +0200 nn r273870 : #i102616# copy stream for unchanged sheets 2009-07-08 18:11:42 +0200 nn r273844 : #i102616# store stream positions of sheets 2009-06-24 19:08:18 +0200 nn r273363 : #i102616# detect changed sheets since loading 2009-06-09 15:53:32 +0200 nn r272774 : #i102616# store automatic cell style information after loading
-rw-r--r--sc/inc/detfunc.hxx1
-rw-r--r--sc/inc/document.hxx5
-rw-r--r--sc/inc/docuno.hxx2
-rw-r--r--sc/inc/sheetdata.hxx183
-rw-r--r--sc/inc/table.hxx6
-rw-r--r--sc/inc/textuno.hxx11
-rw-r--r--sc/source/core/data/attarray.cxx12
-rw-r--r--sc/source/core/data/cell.cxx59
-rw-r--r--sc/source/core/data/documen2.cxx1
-rw-r--r--sc/source/core/data/documen7.cxx7
-rw-r--r--sc/source/core/data/documen8.cxx5
-rw-r--r--sc/source/core/data/documen9.cxx2
-rw-r--r--sc/source/core/data/document.cxx22
-rw-r--r--sc/source/core/data/table1.cxx19
-rw-r--r--sc/source/core/data/table2.cxx7
-rw-r--r--sc/source/core/data/table5.cxx3
-rw-r--r--sc/source/core/tool/detfunc.cxx16
-rw-r--r--sc/source/filter/xml/XMLExportIterator.cxx70
-rw-r--r--sc/source/filter/xml/XMLExportIterator.hxx8
-rw-r--r--sc/source/filter/xml/XMLStylesExportHelper.cxx4
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.cxx39
-rw-r--r--sc/source/filter/xml/XMLTableShapeImportHelper.hxx2
-rw-r--r--sc/source/filter/xml/makefile.mk51
-rw-r--r--sc/source/filter/xml/sheetdata.cxx275
-rw-r--r--sc/source/filter/xml/xmlannoi.cxx10
-rw-r--r--sc/source/filter/xml/xmlannoi.hxx23
-rw-r--r--sc/source/filter/xml/xmlbodyi.cxx38
-rw-r--r--sc/source/filter/xml/xmlbodyi.hxx1
-rw-r--r--sc/source/filter/xml/xmlcelli.cxx18
-rw-r--r--sc/source/filter/xml/xmlcoli.cxx12
-rw-r--r--sc/source/filter/xml/xmlexprt.cxx842
-rw-r--r--sc/source/filter/xml/xmlexprt.hxx25
-rw-r--r--sc/source/filter/xml/xmlimprt.cxx50
-rw-r--r--sc/source/filter/xml/xmlimprt.hxx2
-rw-r--r--sc/source/filter/xml/xmlrowi.cxx11
-rw-r--r--sc/source/filter/xml/xmlstyli.cxx72
-rw-r--r--sc/source/filter/xml/xmlstyli.hxx30
-rw-r--r--sc/source/filter/xml/xmlsubti.cxx10
-rw-r--r--sc/source/filter/xml/xmltabi.cxx17
-rw-r--r--sc/source/filter/xml/xmltabi.hxx1
-rw-r--r--sc/source/filter/xml/xmlwrap.cxx63
-rw-r--r--sc/source/ui/docshell/docfunc.cxx18
-rw-r--r--sc/source/ui/docshell/docsh.cxx41
-rw-r--r--sc/source/ui/docshell/docsh4.cxx7
-rw-r--r--sc/source/ui/docshell/docsh5.cxx2
-rw-r--r--sc/source/ui/drawfunc/futext3.cxx8
-rw-r--r--sc/source/ui/inc/docsh.hxx6
-rw-r--r--sc/source/ui/unoobj/docuno.cxx7
-rw-r--r--sc/source/ui/unoobj/textuno.cxx41
-rw-r--r--sc/source/ui/view/formatsh.cxx5
50 files changed, 1945 insertions, 225 deletions
diff --git a/sc/inc/detfunc.hxx b/sc/inc/detfunc.hxx
index edfff3c8dc7c..98922c1776b8 100644
--- a/sc/inc/detfunc.hxx
+++ b/sc/inc/detfunc.hxx
@@ -132,6 +132,7 @@ class SC_DLLPUBLIC ScDetectiveFunc
BOOL FindFrameForObject( SdrObject* pObject, ScRange& rRange );
+ void Modified();
public:
ScDetectiveFunc(ScDocument* pDocument, SCTAB nTable) : pDoc(pDocument),nTab(nTable) {}
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 69c3d6140431..566bd07b6223 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -411,6 +411,7 @@ private:
bool mbAdjustHeightEnabled;
bool mbExecuteLinkEnabled;
bool mbChangeReadOnlyEnabled; // allow changes in read-only document (for API import filters)
+ bool mbStreamValidLocked;
sal_Int16 mnNamedRangesLockCount;
@@ -571,6 +572,10 @@ public:
SC_DLLPUBLIC void TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos);
SC_DLLPUBLIC void SetVisible( SCTAB nTab, BOOL bVisible );
SC_DLLPUBLIC BOOL IsVisible( SCTAB nTab ) const;
+ BOOL IsStreamValid( SCTAB nTab ) const;
+ void SetStreamValid( SCTAB nTab, BOOL bSet, BOOL bIgnoreLock = FALSE );
+ void LockStreamValid( bool bLock );
+ bool IsStreamValidLocked() const { return mbStreamValidLocked; }
BOOL IsPendingRowHeights( SCTAB nTab ) const;
void SetPendingRowHeights( SCTAB nTab, BOOL bSet );
SC_DLLPUBLIC void SetLayoutRTL( SCTAB nTab, BOOL bRTL );
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index c4b6413c7d58..e46decce34ed 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -75,6 +75,7 @@ class ScTableSheetObj;
class SvxFmDrawPage;
class SvxDrawPage;
class ScRangeList;
+class ScSheetSaveData;
class SC_DLLPUBLIC ScModelObj : public SfxBaseModel,
public com::sun::star::sheet::XSpreadsheetDocument,
@@ -129,6 +130,7 @@ public:
void BeforeXMLLoading();
void AfterXMLLoading(sal_Bool bRet);
+ ScSheetSaveData* GetSheetSaveData();
bool HasChangesListeners() const;
diff --git a/sc/inc/sheetdata.hxx b/sc/inc/sheetdata.hxx
new file mode 100644
index 000000000000..63853f6bc675
--- /dev/null
+++ b/sc/inc/sheetdata.hxx
@@ -0,0 +1,183 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sheetdata.hxx,v $
+ * $Revision: 1.16.32.2 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef SC_SHEETDATA_HXX
+#define SC_SHEETDATA_HXX
+
+#include <xmloff/maptype.hxx>
+#include <svx/editdata.hxx>
+#include <vector>
+#include <hash_set>
+
+#include "address.hxx"
+
+class ScAddress;
+class SvXMLNamespaceMap;
+
+
+struct ScStreamEntry
+{
+ sal_Int32 mnStartOffset;
+ sal_Int32 mnEndOffset;
+
+ ScStreamEntry() :
+ mnStartOffset(-1),
+ mnEndOffset(-1)
+ {
+ }
+
+ ScStreamEntry( sal_Int32 nStart, sal_Int32 nEnd ) :
+ mnStartOffset(nStart),
+ mnEndOffset(nEnd)
+ {
+ }
+};
+
+struct ScCellStyleEntry
+{
+ rtl::OUString maName;
+ ScAddress maCellPos;
+
+ ScCellStyleEntry( const rtl::OUString& rName, const ScAddress& rPos ) :
+ maName(rName),
+ maCellPos(rPos)
+ {
+ }
+};
+
+struct ScNoteStyleEntry
+{
+ rtl::OUString maStyleName;
+ rtl::OUString maTextStyle;
+ ScAddress maCellPos;
+
+ ScNoteStyleEntry( const rtl::OUString& rStyle, const rtl::OUString& rText, const ScAddress& rPos ) :
+ maStyleName(rStyle),
+ maTextStyle(rText),
+ maCellPos(rPos)
+ {
+ }
+};
+
+struct ScTextStyleEntry
+{
+ rtl::OUString maName;
+ ScAddress maCellPos;
+ ESelection maSelection;
+
+ ScTextStyleEntry( const rtl::OUString& rName, const ScAddress& rPos, const ESelection& rSel ) :
+ maName(rName),
+ maCellPos(rPos),
+ maSelection(rSel)
+ {
+ }
+};
+
+struct ScLoadedNamespaceEntry
+{
+ rtl::OUString maPrefix;
+ rtl::OUString maName;
+ sal_uInt16 mnKey;
+
+ ScLoadedNamespaceEntry( const rtl::OUString& rPrefix, const rtl::OUString& rName, sal_uInt16 nKey ) :
+ maPrefix(rPrefix),
+ maName(rName),
+ mnKey(nKey)
+ {
+ }
+};
+
+class ScSheetSaveData
+{
+ std::hash_set<rtl::OUString, rtl::OUStringHash> maInitialPrefixes;
+ std::vector<ScLoadedNamespaceEntry> maLoadedNamespaces;
+
+ std::vector<ScCellStyleEntry> maCellStyles;
+ std::vector<ScCellStyleEntry> maColumnStyles;
+ std::vector<ScCellStyleEntry> maRowStyles;
+ std::vector<ScCellStyleEntry> maTableStyles;
+ std::vector<ScNoteStyleEntry> maNoteStyles;
+ std::vector<ScTextStyleEntry> maNoteParaStyles;
+ std::vector<ScTextStyleEntry> maNoteTextStyles;
+ std::vector<ScTextStyleEntry> maTextStyles;
+ std::vector<bool> maBlocked;
+ std::vector<ScStreamEntry> maStreamEntries;
+ std::vector<ScStreamEntry> maSaveEntries;
+ sal_Int32 mnStartTab;
+ sal_Int32 mnStartOffset;
+
+ ScNoteStyleEntry maPreviousNote;
+
+public:
+ ScSheetSaveData();
+ ~ScSheetSaveData();
+
+ void AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos );
+ void AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos );
+ void AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos );
+ void AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos );
+
+ void HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos );
+ void AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection );
+
+ void AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection );
+
+ void BlockSheet( sal_Int32 nTab );
+ bool IsSheetBlocked( sal_Int32 nTab ) const;
+
+ void AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset );
+ void GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const;
+ bool HasStreamPos( sal_Int32 nTab ) const;
+
+ void StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset );
+ void EndStreamPos( sal_Int32 nEndOffset );
+
+ bool HasStartPos() const { return mnStartTab >= 0; }
+
+ void ResetSaveEntries();
+ void AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset );
+ void UseSaveEntries();
+
+ void StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces );
+ void StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces );
+ bool AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const;
+
+ const std::vector<ScCellStyleEntry>& GetCellStyles() const { return maCellStyles; }
+ const std::vector<ScCellStyleEntry>& GetColumnStyles() const { return maColumnStyles; }
+ const std::vector<ScCellStyleEntry>& GetRowStyles() const { return maRowStyles; }
+ const std::vector<ScCellStyleEntry>& GetTableStyles() const { return maTableStyles; }
+ const std::vector<ScNoteStyleEntry>& GetNoteStyles() const { return maNoteStyles; }
+ const std::vector<ScTextStyleEntry>& GetNoteParaStyles() const { return maNoteParaStyles; }
+ const std::vector<ScTextStyleEntry>& GetNoteTextStyles() const { return maNoteTextStyles; }
+ const std::vector<ScTextStyleEntry>& GetTextStyles() const { return maTextStyles; }
+};
+
+#endif
+
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index bacd4d207cca..1deaa8f334a6 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -127,6 +127,7 @@ private:
// interne Verwaltung ------------------
BOOL bVisible;
+ BOOL bStreamValid;
BOOL bPendingRowHeights;
SCTAB nTab;
@@ -193,6 +194,9 @@ public:
BOOL IsVisible() const { return bVisible; }
void SetVisible( BOOL bVis );
+ BOOL IsStreamValid() const { return bStreamValid; }
+ void SetStreamValid( BOOL bSet, BOOL bIgnoreLock = FALSE );
+
BOOL IsPendingRowHeights() const { return bPendingRowHeights; }
void SetPendingRowHeights( BOOL bSet );
@@ -726,7 +730,7 @@ private:
BOOL GetNextSpellingCell(SCCOL& rCol, SCROW& rRow, BOOL bInSel,
const ScMarkData& rMark) const;
BOOL GetNextMarkedCell( SCCOL& rCol, SCROW& rRow, const ScMarkData& rMark );
- void SetDrawPageSize();
+ void SetDrawPageSize(bool bResetStreamValid = true);
BOOL TestTabRefAbs(SCTAB nTable);
void CompileDBFormula();
void CompileDBFormula( BOOL bCreateFormulaString );
diff --git a/sc/inc/textuno.hxx b/sc/inc/textuno.hxx
index fdad032b8300..8ec7707874be 100644
--- a/sc/inc/textuno.hxx
+++ b/sc/inc/textuno.hxx
@@ -259,6 +259,8 @@ public:
ScCellTextCursor(ScCellObj& rText);
virtual ~ScCellTextCursor() throw();
+ ScCellObj& GetCellObj() const { return rTextObj; }
+
// SvxUnoTextCursor methods reimplemented here:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > SAL_CALL
getText() throw(::com::sun::star::uno::RuntimeException);
@@ -324,6 +326,15 @@ public:
getStart() throw(::com::sun::star::uno::RuntimeException);
virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL
getEnd() throw(::com::sun::star::uno::RuntimeException);
+
+ // XUnoTunnel
+ virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence<
+ sal_Int8 >& aIdentifier )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ static const com::sun::star::uno::Sequence<sal_Int8>& getUnoTunnelId();
+ static ScDrawTextCursor* getImplementation( const com::sun::star::uno::Reference<
+ com::sun::star::uno::XInterface> xObj );
};
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index c00cc111a7cd..1a466d231459 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -170,6 +170,9 @@ void ScAttrArray::Reset( const ScPatternAttr* pPattern, BOOL bAlloc )
}
delete[] pData;
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
+
if (bAlloc)
{
nCount = nLimit = 1;
@@ -472,6 +475,9 @@ void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPattern
pData[nInsert].pPattern = pPattern;
nCount++;
}
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
}
}
// InfoBox(0, String(nCount) + String(" Eintraege") ).Execute();
@@ -550,6 +556,9 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet*
delete pNewPattern;
}
while ((nStart <= nEndRow) && (nPos < nCount));
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
}
#ifdef DBG_UTIL
@@ -789,6 +798,9 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCac
}
}
while (nStart <= nEndRow);
+
+ if (pDocument->IsStreamValid(nTab))
+ pDocument->SetStreamValid(nTab, FALSE);
}
#ifdef DBG_UTIL
diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx
index 364d8b1b3c52..aea2bf4ff276 100644
--- a/sc/source/core/data/cell.cxx
+++ b/sc/source/core/data/cell.cxx
@@ -1559,6 +1559,10 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
}
bRunning = bOldRunning;
+ // #i102616# For single-sheet saving consider only content changes, not format type,
+ // because format type isn't set on loading (might be changed later)
+ BOOL bContentChanged = FALSE;
+
// Do not create a HyperLink() cell if the formula results in an error.
if( p->GetError() && pCode->IsHyperLink())
pCode->SetHyperLink(FALSE);
@@ -1597,7 +1601,12 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// New error code?
if( p->GetError() != nOldErrCode )
+ {
bChanged = TRUE;
+ // bContentChanged only has to be set if the file content would be changed
+ if ( aResult.GetCellResultType() != svUnknown )
+ bContentChanged = TRUE;
+ }
// Different number format?
if( nFormatType != p->GetRetFormatType() )
{
@@ -1613,7 +1622,33 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// In case of changes just obtain the result, no temporary and
// comparison needed anymore.
if (bChanged)
+ {
+ // #i102616# Compare anyway if the sheet is still marked unchanged for single-sheet saving
+ // Also handle special cases of initial results after loading.
+
+ if ( !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
+ {
+ ScFormulaResult aNewResult( p->GetResultToken());
+ StackVar eOld = aResult.GetCellResultType();
+ StackVar eNew = aNewResult.GetCellResultType();
+ if ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) )
+ {
+ // ScXMLTableRowCellContext::EndElement doesn't call SetFormulaResultDouble for 0
+ // -> no change
+ }
+ else
+ {
+ if ( eOld == svHybridCell ) // string result from SetFormulaResultString?
+ eOld = svString; // ScHybridCellToken has a valid GetString method
+
+ bContentChanged = (eOld != eNew ||
+ (eNew == svDouble && aResult.GetDouble() != aNewResult.GetDouble()) ||
+ (eNew == svString && aResult.GetString() != aNewResult.GetString()));
+ }
+ }
+
aResult.SetToken( p->GetResultToken() );
+ }
else
{
ScFormulaResult aNewResult( p->GetResultToken());
@@ -1622,6 +1657,19 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
bChanged = (eOld != eNew ||
(eNew == svDouble && aResult.GetDouble() != aNewResult.GetDouble()) ||
(eNew == svString && aResult.GetString() != aNewResult.GetString()));
+
+ // #i102616# handle special cases of initial results after loading (only if the sheet is still marked unchanged)
+ if ( bChanged && !bContentChanged && pDocument->IsStreamValid(aPos.Tab()) )
+ {
+ if ( ( eOld == svUnknown && ( eNew == svError || ( eNew == svDouble && aNewResult.GetDouble() == 0.0 ) ) ) ||
+ ( eOld == svHybridCell && eNew == svString && aResult.GetString() == aNewResult.GetString() ) )
+ {
+ // no change, see above
+ }
+ else
+ bContentChanged = TRUE;
+ }
+
aResult.Assign( aNewResult);
}
@@ -1658,13 +1706,19 @@ void ScFormulaCell::InterpretTail( ScInterpretTailParameter eTailParam )
// Coded double error may occur via filter import.
USHORT nErr = GetDoubleErrorValue( aResult.GetDouble());
aResult.SetResultError( nErr);
- bChanged = true;
+ bChanged = bContentChanged = true;
}
if( bChanged )
{
SetTextWidth( TEXTWIDTH_DIRTY );
SetScriptType( SC_SCRIPTTYPE_UNKNOWN );
}
+ if (bContentChanged && pDocument->IsStreamValid(aPos.Tab()))
+ {
+ // pass bIgnoreLock=TRUE, because even if called from pending row height update,
+ // a changed result must still reset the stream flag
+ pDocument->SetStreamValid(aPos.Tab(), FALSE, TRUE);
+ }
if ( !pCode->IsRecalcModeAlways() )
pDocument->RemoveFromFormulaTree( this );
@@ -1789,6 +1843,9 @@ void ScFormulaCell::SetDirty()
pDocument->TrackFormulas();
}
}
+
+ if (pDocument->IsStreamValid(aPos.Tab()))
+ pDocument->SetStreamValid(aPos.Tab(), FALSE);
}
}
diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx
index 482aedbc7940..ae1f087a23a8 100644
--- a/sc/source/core/data/documen2.cxx
+++ b/sc/source/core/data/documen2.cxx
@@ -217,6 +217,7 @@ ScDocument::ScDocument( ScDocumentMode eMode,
mbAdjustHeightEnabled( true ),
mbExecuteLinkEnabled( true ),
mbChangeReadOnlyEnabled( false ),
+ mbStreamValidLocked( false ),
mnNamedRangesLockCount( 0 )
{
SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT);
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index c0ae477ed96b..9527089ebde3 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -125,6 +125,13 @@ void ScDocument::Broadcast( const ScHint& rHint )
// Repaint fuer bedingte Formate mit relativen Referenzen:
if ( pCondFormList && rHint.GetAddress() != BCA_BRDCST_ALWAYS )
pCondFormList->SourceChanged( rHint.GetAddress() );
+
+ if ( rHint.GetAddress() != BCA_BRDCST_ALWAYS )
+ {
+ SCTAB nTab = rHint.GetAddress().Tab();
+ if (pTab[nTab] && pTab[nTab]->IsStreamValid())
+ pTab[nTab]->SetStreamValid(FALSE);
+ }
}
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index c34e93f10d66..b337cc902aef 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -271,6 +271,11 @@ void ScDocument::ModifyStyleSheet( SfxStyleSheetBase& rStyleSheet,
if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
rSet, rChanges ) )
InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
+
+ for (SCTAB nTab=0; nTab<=MAXTAB; ++nTab)
+ if (pTab[nTab] && pTab[nTab]->IsStreamValid())
+ pTab[nTab]->SetStreamValid( FALSE );
+
ULONG nOldFormat =
((const SfxUInt32Item*)&rSet.Get(
ATTR_VALUE_FORMAT ))->GetValue();
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 06a683b0bf72..793be9a8c2e9 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -245,7 +245,7 @@ void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell )
pTab[nTab]->GetName(aTabName);
pDrawLayer->ScRenamePage( nTab, aTabName );
- pTab[nTab]->SetDrawPageSize(); // #54782# sofort die richtige Groesse
+ pTab[nTab]->SetDrawPageSize(false); // #54782# set the right size immediately
#if 0
ULONG nx = (ULONG) ((double) (MAXCOL+1) * STD_COL_WIDTH * HMM_PER_TWIPS );
ULONG ny = (ULONG) ((double) (MAXROW+1) * ScGlobal::nStdRowHeight * HMM_PER_TWIPS );
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index b1d19d4b3dae..e5af00781cff 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -497,6 +497,28 @@ BOOL ScDocument::IsVisible( SCTAB nTab ) const
}
+BOOL ScDocument::IsStreamValid( SCTAB nTab ) const
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ return pTab[nTab]->IsStreamValid();
+
+ return FALSE;
+}
+
+
+void ScDocument::SetStreamValid( SCTAB nTab, BOOL bSet, BOOL bIgnoreLock )
+{
+ if ( ValidTab(nTab) && pTab[nTab] )
+ pTab[nTab]->SetStreamValid( bSet, bIgnoreLock );
+}
+
+
+void ScDocument::LockStreamValid( bool bLock )
+{
+ mbStreamValidLocked = bLock;
+}
+
+
BOOL ScDocument::IsPendingRowHeights( SCTAB nTab ) const
{
if ( ValidTab(nTab) && pTab[nTab] )
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index ff6caa2da1bd..1f1d82023f45 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -141,6 +141,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName,
pOutlineTable( NULL ),
bTableAreaValid( FALSE ),
bVisible( TRUE ),
+ bStreamValid( FALSE ),
bPendingRowHeights( FALSE ),
nTab( nNewTab ),
nRecalcLvl( 0 ),
@@ -248,9 +249,18 @@ const String& ScTable::GetUpperName() const
void ScTable::SetVisible( BOOL bVis )
{
+ if (bVisible != bVis && IsStreamValid())
+ SetStreamValid(FALSE);
+
bVisible = bVis;
}
+void ScTable::SetStreamValid( BOOL bSet, BOOL bIgnoreLock )
+{
+ if ( bIgnoreLock || !pDocument->IsStreamValidLocked() )
+ bStreamValid = bSet;
+}
+
void ScTable::SetPendingRowHeights( BOOL bSet )
{
bPendingRowHeights = bSet;
@@ -1247,6 +1257,9 @@ void ScTable::UpdateInsertTab(SCTAB nTable)
{
if (nTab >= nTable) nTab++;
for (SCCOL i=0; i <= MAXCOL; i++) aCol[i].UpdateInsertTab(nTable);
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
}
//UNUSED2008-05 void ScTable::UpdateInsertTabOnlyCells(SCTAB nTable)
@@ -1263,6 +1276,9 @@ void ScTable::UpdateDeleteTab( SCTAB nTable, BOOL bIsMove, ScTable* pRefUndo )
for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, &pRefUndo->aCol[i]);
else
for (i=0; i <= MAXCOL; i++) aCol[i].UpdateDeleteTab(nTable, bIsMove, NULL);
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
}
void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
@@ -1274,6 +1290,9 @@ void ScTable::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos, SCTAB nTabNo,
aCol[i].UpdateMoveTab( nOldPos, nNewPos, nTabNo );
rProgress.SetState( rProgress.GetState() + aCol[i].GetCodeCount() );
}
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
}
void ScTable::UpdateCompile( BOOL bForceIfNameInUse )
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index daaf2d56b193..104fb46b4495 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2837,7 +2837,7 @@ void ScTable::GetUpperCellString(SCCOL nCol, SCROW nRow, String& rStr)
// Berechnen der Groesse der Tabelle und setzen der Groesse an der DrawPage
-void ScTable::SetDrawPageSize()
+void ScTable::SetDrawPageSize(bool bResetStreamValid)
{
ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer();
if( pDrawLayer )
@@ -2852,6 +2852,11 @@ void ScTable::SetDrawPageSize()
pDrawLayer->SetPageSize( static_cast<sal_uInt16>(nTab), Size( x, y ) );
}
+
+ // #i102616# actions that modify the draw page size count as sheet modification
+ // (exception: InitDrawLayer)
+ if (bResetStreamValid && IsStreamValid())
+ SetStreamValid(FALSE);
}
diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx
index 021385678160..eb959dfb2ffa 100644
--- a/sc/source/core/data/table5.cxx
+++ b/sc/source/core/data/table5.cxx
@@ -353,6 +353,9 @@ void ScTable::SetPageStyle( const String& rName )
if ( pNewStyle ) // auch ohne den alten (fuer UpdateStdNames)
aPageStyle = aStrNew;
+
+ if (IsStreamValid())
+ SetStreamValid(FALSE);
}
}
}
diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx
index 2d337eab2eb3..a08b81a1917c 100644
--- a/sc/source/core/tool/detfunc.cxx
+++ b/sc/source/core/tool/detfunc.cxx
@@ -290,6 +290,12 @@ void ScCommentData::UpdateCaptionSet( const SfxItemSet& rItemSet )
//------------------------------------------------------------------------
+void ScDetectiveFunc::Modified()
+{
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+}
+
inline BOOL Intersect( SCCOL nStartCol1, SCROW nStartRow1, SCCOL nEndCol1, SCROW nEndRow1,
SCCOL nStartCol2, SCROW nStartRow2, SCCOL nEndCol2, SCROW nEndRow2 )
{
@@ -547,6 +553,7 @@ BOOL ScDetectiveFunc::InsertArrow( SCCOL nCol, SCROW nRow,
pData->maEnd.Set( nCol, nRow, nTab);
+ Modified();
return TRUE;
}
@@ -609,6 +616,7 @@ BOOL ScDetectiveFunc::InsertToOtherTab( SCCOL nStartCol, SCROW nStartRow,
pData->maStart.Set( nStartCol, nStartRow, nTab);
pData->maEnd.SetInvalid();
+ Modified();
return TRUE;
}
@@ -676,6 +684,8 @@ void ScDetectiveFunc::DrawCircle( SCCOL nCol, SCROW nRow, ScDetectiveData& rData
ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle, TRUE );
pData->maStart.Set( nCol, nRow, nTab);
pData->maEnd.SetInvalid();
+
+ Modified();
}
void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, BOOL bDestPnt )
@@ -716,6 +726,8 @@ void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, BOOL bDestPnt )
pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
delete[] ppObj;
+
+ Modified();
}
}
@@ -791,6 +803,8 @@ void ScDetectiveFunc::DeleteBox( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nR
pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
delete[] ppObj;
+
+ Modified();
}
}
@@ -1333,6 +1347,8 @@ BOOL ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat )
pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
delete[] ppObj;
+
+ Modified();
}
return ( nDelCount != 0 );
diff --git a/sc/source/filter/xml/XMLExportIterator.cxx b/sc/source/filter/xml/XMLExportIterator.cxx
index 72194c8be11c..c0b50a06b45a 100644
--- a/sc/source/filter/xml/XMLExportIterator.cxx
+++ b/sc/source/filter/xml/XMLExportIterator.cxx
@@ -130,6 +130,13 @@ void ScMyShapesContainer::SetCellData( ScMyCell& rMyCell )
rMyCell.bHasShape = !rMyCell.aShapeList.empty();
}
+void ScMyShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyShapeList::iterator aItr = aShapeList.begin();
+ while( (aItr != aShapeList.end()) && (aItr->aAddress.Tab() == nSkip) )
+ aItr = aShapeList.erase(aItr);
+}
+
void ScMyShapesContainer::Sort()
{
aShapeList.sort();
@@ -184,6 +191,13 @@ void ScMyNoteShapesContainer::SetCellData( ScMyCell& rMyCell )
}
}
+void ScMyNoteShapesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyNoteShapeList::iterator aItr = aNoteShapeList.begin();
+ while( (aItr != aNoteShapeList.end()) && (aItr->aPos.Tab() == nSkip) )
+ aItr = aNoteShapeList.erase(aItr);
+}
+
void ScMyNoteShapesContainer::Sort()
{
aNoteShapeList.sort();
@@ -269,6 +283,13 @@ void ScMyMergedRangesContainer::SetCellData( ScMyCell& rMyCell )
}
}
+void ScMyMergedRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyMergedRangeList::iterator aItr = aRangeList.begin();
+ while( (aItr != aRangeList.end()) && (aItr->aCellRange.Sheet == nSkip) )
+ aItr = aRangeList.erase(aItr);
+}
+
void ScMyMergedRangesContainer::Sort()
{
aRangeList.sort();
@@ -344,6 +365,13 @@ void ScMyAreaLinksContainer::SetCellData( ScMyCell& rMyCell )
}
}
+void ScMyAreaLinksContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyAreaLinkList::iterator aItr = aAreaLinkList.begin();
+ while( (aItr != aAreaLinkList.end()) && (aItr->aDestRange.Sheet == nSkip) )
+ aItr = aAreaLinkList.erase(aItr);
+}
+
void ScMyAreaLinksContainer::Sort()
{
aAreaLinkList.sort();
@@ -417,6 +445,13 @@ void ScMyEmptyDatabaseRangesContainer::SetCellData( ScMyCell& rMyCell )
}
}
+void ScMyEmptyDatabaseRangesContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyEmptyDatabaseRangeList::iterator aItr = aDatabaseList.begin();
+ while( (aItr != aDatabaseList.end()) && (aItr->Sheet == nSkip) )
+ aItr = aDatabaseList.erase(aItr);
+}
+
void ScMyEmptyDatabaseRangesContainer::Sort()
{
aDatabaseList.sort();
@@ -498,6 +533,13 @@ void ScMyDetectiveObjContainer::SetCellData( ScMyCell& rMyCell )
rMyCell.bHasDetectiveObj = (rMyCell.aDetectiveObjVec.size() != 0);
}
+void ScMyDetectiveObjContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveObjList::iterator aItr = aDetectiveObjList.begin();
+ while( (aItr != aDetectiveObjList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveObjList.erase(aItr);
+}
+
void ScMyDetectiveObjContainer::Sort()
{
aDetectiveObjList.sort();
@@ -557,6 +599,13 @@ void ScMyDetectiveOpContainer::SetCellData( ScMyCell& rMyCell )
rMyCell.bHasDetectiveOp = (rMyCell.aDetectiveOpVec.size() != 0);
}
+void ScMyDetectiveOpContainer::SkipTable(SCTAB nSkip)
+{
+ ScMyDetectiveOpList::iterator aItr = aDetectiveOpList.begin();
+ while( (aItr != aDetectiveOpList.end()) && (aItr->aPosition.Sheet == nSkip) )
+ aItr = aDetectiveOpList.erase(aItr);
+}
+
void ScMyDetectiveOpContainer::Sort()
{
aDetectiveOpList.sort();
@@ -766,6 +815,27 @@ void ScMyNotEmptyCellsIterator::SetCurrentTable(const SCTAB nTable,
}
}
+void ScMyNotEmptyCellsIterator::SkipTable(SCTAB nSkip)
+{
+ // Skip entries for a sheet that is copied instead of saving normally.
+ // Cells (including aAnnotations) are handled separately in SetCurrentTable.
+
+ if( pShapes )
+ pShapes->SkipTable(nSkip);
+ if( pNoteShapes )
+ pNoteShapes->SkipTable(nSkip);
+ if( pEmptyDatabaseRanges )
+ pEmptyDatabaseRanges->SkipTable(nSkip);
+ if( pMergedRanges )
+ pMergedRanges->SkipTable(nSkip);
+ if( pAreaLinks )
+ pAreaLinks->SkipTable(nSkip);
+ if( pDetectiveObj )
+ pDetectiveObj->SkipTable(nSkip);
+ if( pDetectiveOp )
+ pDetectiveOp->SkipTable(nSkip);
+}
+
sal_Bool ScMyNotEmptyCellsIterator::GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles)
{
table::CellAddress aAddress( nCurrentTable, MAXCOL + 1, MAXROW + 1 );
diff --git a/sc/source/filter/xml/XMLExportIterator.hxx b/sc/source/filter/xml/XMLExportIterator.hxx
index d15ef94f99e6..92c61ca060e9 100644
--- a/sc/source/filter/xml/XMLExportIterator.hxx
+++ b/sc/source/filter/xml/XMLExportIterator.hxx
@@ -96,6 +96,7 @@ public:
const ScMyShapeList* GetShapes() { return &aShapeList; }
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
struct ScMyNoteShape
@@ -124,6 +125,7 @@ public:
const ScMyNoteShapeList* GetNotes() { return &aNoteShapeList; }
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -152,6 +154,7 @@ public:
using ScMyIteratorBase::UpdateAddress;
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort(); // + remove doublets
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -192,6 +195,7 @@ public:
using ScMyIteratorBase::UpdateAddress;
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -218,6 +222,7 @@ public:
using ScMyIteratorBase::UpdateAddress;
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -254,6 +259,7 @@ public:
using ScMyIteratorBase::UpdateAddress;
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -284,6 +290,7 @@ public:
using ScMyIteratorBase::UpdateAddress;
virtual void SetCellData( ScMyCell& rMyCell );
virtual void Sort();
+ void SkipTable(SCTAB nSkip);
};
//==============================================================================
@@ -400,6 +407,7 @@ public:
void SetCurrentTable(const SCTAB nTable,
com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& rxTable);
+ void SkipTable(SCTAB nSkip);
sal_Bool GetNext(ScMyCell& aCell, ScFormatRangeStyles* pCellStyles);
};
diff --git a/sc/source/filter/xml/XMLStylesExportHelper.cxx b/sc/source/filter/xml/XMLStylesExportHelper.cxx
index 6482fe571b62..98100f4b3646 100644
--- a/sc/source/filter/xml/XMLStylesExportHelper.cxx
+++ b/sc/source/filter/xml/XMLStylesExportHelper.cxx
@@ -878,7 +878,7 @@ sal_Int32 ScFormatRangeStyles::GetIndexOfStyleName(const rtl::OUString& rString,
sal_Int32 nPrefixLength(rPrefix.getLength());
rtl::OUString sTemp(rString.copy(nPrefixLength));
sal_Int32 nIndex(sTemp.toInt32());
- if (aAutoStyleNames.at(nIndex - 1)->equals(rString))
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aAutoStyleNames.size() && aAutoStyleNames.at(nIndex - 1)->equals(rString))
{
bIsAutoStyle = sal_True;
return nIndex - 1;
@@ -1111,7 +1111,7 @@ sal_Int32 ScColumnRowStylesBase::GetIndexOfStyleName(const rtl::OUString& rStrin
sal_Int32 nPrefixLength(rPrefix.getLength());
rtl::OUString sTemp(rString.copy(nPrefixLength));
sal_Int32 nIndex(sTemp.toInt32());
- if (aStyleNames.at(nIndex - 1)->equals(rString))
+ if (nIndex > 0 && static_cast<size_t>(nIndex-1) < aStyleNames.size() && aStyleNames.at(nIndex - 1)->equals(rString))
return nIndex - 1;
else
{
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
index 48def752b038..f498faf93e5b 100644
--- a/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.cxx
@@ -36,6 +36,8 @@
#include "drwlayer.hxx"
#include "xmlannoi.hxx"
#include "rangeutl.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmluconv.hxx>
@@ -80,9 +82,11 @@ void XMLTableShapeImportHelper::finishShape(
const uno::Reference< xml::sax::XAttributeList >& xAttrList,
uno::Reference< drawing::XShapes >& rShapes )
{
+ bool bNote = false;
XMLShapeImportHelper::finishShape( rShape, xAttrList, rShapes );
static_cast<ScXMLImport&>(mrImporter).LockSolarMutex();
- if (rShapes == static_cast<ScXMLImport&>(mrImporter).GetTables().GetCurrentXShapes())
+ ScMyTables& rTables = static_cast<ScXMLImport&>(mrImporter).GetTables();
+ if (rShapes == rTables.GetCurrentXShapes())
{
if (!pAnnotationContext)
{
@@ -126,7 +130,7 @@ void XMLTableShapeImportHelper::finishShape(
if (!bOnTable)
{
- static_cast<ScXMLImport&>(mrImporter).GetTables().AddShape(rShape,
+ rTables.AddShape(rShape,
pRangeList, aStartCell, aEndCell, nEndX, nEndY);
SvxShape* pShapeImp = SvxShape::getImplementation(rShape);
if (pShapeImp)
@@ -145,7 +149,7 @@ void XMLTableShapeImportHelper::finishShape(
// -> call AddShape with invalid cell position (checked in ScMyShapeResizer::ResizeShapes)
table::CellAddress aInvalidPos( -1, -1, -1 );
- static_cast<ScXMLImport&>(mrImporter).GetTables().AddShape(rShape,
+ rTables.AddShape(rShape,
pRangeList, aInvalidPos, aInvalidPos, 0, 0);
}
@@ -160,7 +164,26 @@ void XMLTableShapeImportHelper::finishShape(
}
else // shape is annotation
{
- pAnnotationContext->SetShape(rShape, rShapes);
+ // get the style names for stream copying
+ rtl::OUString aStyleName;
+ rtl::OUString aTextStyle;
+ sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
+ for( sal_Int16 i=0; i < nAttrCount; ++i )
+ {
+ const rtl::OUString& rAttrName(xAttrList->getNameByIndex( i ));
+ rtl::OUString aLocalName;
+ sal_uInt16 nPrefix(static_cast<ScXMLImport&>(mrImporter).GetNamespaceMap().GetKeyByAttrName( rAttrName, &aLocalName ));
+ if(nPrefix == XML_NAMESPACE_DRAW)
+ {
+ if (IsXMLToken(aLocalName, XML_STYLE_NAME))
+ aStyleName = xAttrList->getValueByIndex( i );
+ else if (IsXMLToken(aLocalName, XML_TEXT_STYLE_NAME))
+ aTextStyle = xAttrList->getValueByIndex( i );
+ }
+ }
+
+ pAnnotationContext->SetShape(rShape, rShapes, aStyleName, aTextStyle);
+ bNote = true;
}
}
else //#99532# this are grouped shapes which should also get the layerid
@@ -183,5 +206,13 @@ void XMLTableShapeImportHelper::finishShape(
}
SetLayer(rShape, nLayerID, rShape->getShapeType());
}
+
+ if (!bNote)
+ {
+ // any shape other than a note prevents copying the sheet
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(mrImporter.GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( rTables.GetCurrentSheet() );
+ }
+
static_cast<ScXMLImport&>(mrImporter).UnlockSolarMutex();
}
diff --git a/sc/source/filter/xml/XMLTableShapeImportHelper.hxx b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
index 4299649427e4..06d49dc4beed 100644
--- a/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
+++ b/sc/source/filter/xml/XMLTableShapeImportHelper.hxx
@@ -57,6 +57,8 @@ public:
void SetCell (const ::com::sun::star::table::CellAddress& rAddress) { aStartCell = rAddress; }
void SetOnTable (const sal_Bool bTempOnTable) { bOnTable = bTempOnTable; }
void SetAnnotation(ScXMLAnnotationContext* pAnnotation) { pAnnotationContext = pAnnotation; }
+
+ ScXMLAnnotationContext* GetAnnotationContext() const { return pAnnotationContext; }
};
diff --git a/sc/source/filter/xml/makefile.mk b/sc/source/filter/xml/makefile.mk
index 19d8a99f789c..c1e7e215e199 100644
--- a/sc/source/filter/xml/makefile.mk
+++ b/sc/source/filter/xml/makefile.mk
@@ -51,57 +51,8 @@ PROJECTPCHSOURCE=..\pch\filt_pch
# --- Files --------------------------------------------------------
-CXXFILES = \
- xmlwrap.cxx \
- xmlimprt.cxx \
- xmlexprt.cxx \
- xmlbodyi.cxx \
- xmltabi.cxx \
- xmlexternaltabi.cxx \
- xmlrowi.cxx \
- xmlcelli.cxx \
- xmlconti.cxx \
- xmlcoli.cxx \
- xmlsubti.cxx \
- xmlnexpi.cxx \
- xmldrani.cxx \
- xmlfilti.cxx \
- xmlsorti.cxx \
- xmlstyle.cxx \
- xmlstyli.cxx \
- xmldpimp.cxx \
- xmlannoi.cxx \
- xmlsceni.cxx \
- xmlcvali.cxx \
- XMLTableMasterPageExport.cxx \
- xmllabri.cxx \
- XMLTableHeaderFooterContext.cxx \
- XMLDetectiveContext.cxx \
- XMLCellRangeSourceContext.cxx \
- XMLConsolidationContext.cxx \
- XMLConverter.cxx \
- XMLExportIterator.cxx \
- XMLColumnRowGroupExport.cxx \
- XMLStylesExportHelper.cxx \
- XMLStylesImportHelper.cxx \
- XMLExportDataPilot.cxx \
- XMLExportDatabaseRanges.cxx \
- XMLTableShapeImportHelper.cxx \
- XMLTableShapesContext.cxx \
- XMLExportDDELinks.cxx \
- XMLDDELinksContext.cxx \
- XMLCalculationSettingsContext.cxx \
- XMLTableSourceContext.cxx \
- XMLTextPContext.cxx \
- XMLTableShapeResizer.cxx \
- XMLChangeTrackingExportHelper.cxx \
- xmlfonte.cxx \
- XMLChangeTrackingImportHelper.cxx \
- XMLTrackedChangesContext.cxx \
- XMLExportSharedData.cxx \
- XMLEmptyContext.cxx
-
SLOFILES = \
+ $(SLO)$/sheetdata.obj \
$(SLO)$/xmlwrap.obj \
$(SLO)$/xmlimprt.obj \
$(SLO)$/xmlexprt.obj \
diff --git a/sc/source/filter/xml/sheetdata.cxx b/sc/source/filter/xml/sheetdata.cxx
new file mode 100644
index 000000000000..a8b96eb6d768
--- /dev/null
+++ b/sc/source/filter/xml/sheetdata.cxx
@@ -0,0 +1,275 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: sheetdata.cxx,v $
+ * $Revision: 1.69.32.3 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+// INCLUDE ---------------------------------------------------------------
+
+#include <xmloff/families.hxx>
+#include <xmloff/xmlaustp.hxx>
+#include <xmloff/nmspmap.hxx>
+#include <tools/string.hxx>
+#include <tools/debug.hxx>
+
+#include "sheetdata.hxx"
+
+// -----------------------------------------------------------------------
+
+ScSheetSaveData::ScSheetSaveData() :
+ mnStartTab( -1 ),
+ mnStartOffset( -1 ),
+ maPreviousNote( rtl::OUString(), rtl::OUString(), ScAddress(ScAddress::INITIALIZE_INVALID) )
+{
+}
+
+ScSheetSaveData::~ScSheetSaveData()
+{
+}
+
+void ScSheetSaveData::AddCellStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maCellStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddColumnStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maColumnStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddRowStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maRowStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::AddTableStyle( const rtl::OUString& rName, const ScAddress& rCellPos )
+{
+ maTableStyles.push_back( ScCellStyleEntry( rName, rCellPos ) );
+}
+
+void ScSheetSaveData::HandleNoteStyles( const rtl::OUString& rStyleName, const rtl::OUString& rTextName, const ScAddress& rCellPos )
+{
+ // only consecutive duplicates (most common case) are filtered out here,
+ // the others are found when the styles are created
+
+ if ( rStyleName == maPreviousNote.maStyleName &&
+ rTextName == maPreviousNote.maTextStyle &&
+ rCellPos.Tab() == maPreviousNote.maCellPos.Tab() )
+ {
+ // already stored for the same sheet - ignore
+ return;
+ }
+
+ ScNoteStyleEntry aNewEntry( rStyleName, rTextName, rCellPos );
+ maPreviousNote = aNewEntry;
+ maNoteStyles.push_back( aNewEntry );
+}
+
+void ScSheetSaveData::AddNoteContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ if ( nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
+ maNoteParaStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+ else
+ maNoteTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::AddTextStyle( const rtl::OUString& rName, const ScAddress& rCellPos, const ESelection& rSelection )
+{
+ maTextStyles.push_back( ScTextStyleEntry( rName, rCellPos, rSelection ) );
+}
+
+void ScSheetSaveData::BlockSheet( sal_Int32 nTab )
+{
+ if ( nTab >= (sal_Int32)maBlocked.size() )
+ maBlocked.resize( nTab + 1, false ); // fill vector with "false" entries
+
+ maBlocked[nTab] = true;
+}
+
+bool ScSheetSaveData::IsSheetBlocked( sal_Int32 nTab ) const
+{
+ if ( nTab < (sal_Int32)maBlocked.size() )
+ return maBlocked[nTab];
+ else
+ return false;
+}
+
+void ScSheetSaveData::AddStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maStreamEntries.size() )
+ maStreamEntries.resize( nTab + 1 );
+
+ maStreamEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::StartStreamPos( sal_Int32 nTab, sal_Int32 nStartOffset )
+{
+ DBG_ASSERT( mnStartTab < 0, "StartStreamPos without EndStreamPos" );
+
+ mnStartTab = nTab;
+ mnStartOffset = nStartOffset;
+}
+
+void ScSheetSaveData::EndStreamPos( sal_Int32 nEndOffset )
+{
+ if ( mnStartTab >= 0 )
+ {
+ AddStreamPos( mnStartTab, mnStartOffset, nEndOffset );
+ mnStartTab = -1;
+ mnStartOffset = -1;
+ }
+}
+
+void ScSheetSaveData::GetStreamPos( sal_Int32 nTab, sal_Int32& rStartOffset, sal_Int32& rEndOffset ) const
+{
+ if ( nTab < (sal_Int32)maStreamEntries.size() )
+ {
+ const ScStreamEntry& rEntry = maStreamEntries[nTab];
+ rStartOffset = rEntry.mnStartOffset;
+ rEndOffset = rEntry.mnEndOffset;
+ }
+ else
+ rStartOffset = rEndOffset = -1;
+}
+
+bool ScSheetSaveData::HasStreamPos( sal_Int32 nTab ) const
+{
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ GetStreamPos( nTab, nStartOffset, nEndOffset );
+ return ( nStartOffset >= 0 && nEndOffset >= 0 );
+}
+
+void ScSheetSaveData::ResetSaveEntries()
+{
+ maSaveEntries.clear();
+}
+
+void ScSheetSaveData::AddSavePos( sal_Int32 nTab, sal_Int32 nStartOffset, sal_Int32 nEndOffset )
+{
+ if ( nTab >= (sal_Int32)maSaveEntries.size() )
+ maSaveEntries.resize( nTab + 1 );
+
+ maSaveEntries[nTab] = ScStreamEntry( nStartOffset, nEndOffset );
+}
+
+void ScSheetSaveData::UseSaveEntries()
+{
+ maStreamEntries = maSaveEntries;
+}
+
+void ScSheetSaveData::StoreInitialNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // the initial namespaces are just removed from the list of loaded namespaces,
+ // so only a hash_set of the prefixes is needed.
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ maInitialPrefixes.insert( aIter->first );
+ ++aIter;
+ }
+}
+
+void ScSheetSaveData::StoreLoadedNamespaces( const SvXMLNamespaceMap& rNamespaces )
+{
+ // store the loaded namespaces, so the prefixes in copied stream fragments remain valid
+
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ // ignore the initial namespaces
+ if ( maInitialPrefixes.find( aIter->first ) == maInitialPrefixes.end() )
+ {
+ const NameSpaceEntry& rEntry = aIter->second.getBody();
+ maLoadedNamespaces.push_back( ScLoadedNamespaceEntry( rEntry.sPrefix, rEntry.sName, rEntry.nKey ) );
+ }
+ ++aIter;
+ }
+}
+
+bool lcl_NameInHash( const NameSpaceHash& rNameHash, const rtl::OUString& rName )
+{
+ NameSpaceHash::const_iterator aIter = rNameHash.begin(), aEnd = rNameHash.end();
+ while (aIter != aEnd)
+ {
+ if ( aIter->second->sName == rName )
+ return true;
+
+ ++aIter;
+ }
+ return false; // not found
+}
+
+bool ScSheetSaveData::AddLoadedNamespaces( SvXMLNamespaceMap& rNamespaces ) const
+{
+ // Add the loaded namespaces to the name space map.
+
+ // first loop: only look for conflicts
+ // (if the loaded namespaces were added first, this might not be necessary)
+ const NameSpaceHash& rNameHash = rNamespaces.GetAllEntries();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aIter = maLoadedNamespaces.begin();
+ std::vector<ScLoadedNamespaceEntry>::const_iterator aEnd = maLoadedNamespaces.end();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ {
+ if ( lcl_NameInHash( rNameHash, aIter->maName ) )
+ {
+ // a second prefix for the same name would confuse SvXMLNamespaceMap lookup,
+ // so this is also considered a conflict
+ return false;
+ }
+ }
+ else if ( aHashIter->second->sName != aIter->maName )
+ {
+ // same prefix, but different name: loaded namespaces can't be used
+ return false;
+ }
+ ++aIter;
+ }
+
+ // only if there were no conflicts, add the entries that aren't in the map already
+ // (the key is needed if the same namespace is added later within an element)
+ aIter = maLoadedNamespaces.begin();
+ while (aIter != aEnd)
+ {
+ NameSpaceHash::const_iterator aHashIter = rNameHash.find( aIter->maPrefix );
+ if ( aHashIter == rNameHash.end() )
+ rNamespaces.Add( aIter->maPrefix, aIter->maName, aIter->mnKey );
+ ++aIter;
+ }
+
+ return true; // success
+}
+
diff --git a/sc/source/filter/xml/xmlannoi.cxx b/sc/source/filter/xml/xmlannoi.cxx
index f8081b7b8f48..294a335033c1 100644
--- a/sc/source/filter/xml/xmlannoi.cxx
+++ b/sc/source/filter/xml/xmlannoi.cxx
@@ -207,9 +207,17 @@ void ScXMLAnnotationContext::EndElement()
pTableShapeImport->SetAnnotation(NULL);
}
-void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes )
+void ScXMLAnnotationContext::SetShape( const uno::Reference< drawing::XShape >& rxShape, const uno::Reference< drawing::XShapes >& rxShapes,
+ const rtl::OUString& rStyleName, const rtl::OUString& rTextStyle )
{
mrAnnotationData.mxShape = rxShape;
mrAnnotationData.mxShapes = rxShapes;
+ mrAnnotationData.maStyleName = rStyleName;
+ mrAnnotationData.maTextStyle = rTextStyle;
+}
+
+void ScXMLAnnotationContext::AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection )
+{
+ mrAnnotationData.maContentStyles.push_back( ScXMLAnnotationStyleEntry( nFamily, rName, rSelection ) );
}
diff --git a/sc/source/filter/xml/xmlannoi.hxx b/sc/source/filter/xml/xmlannoi.hxx
index c509b72124ed..41b206bd4380 100644
--- a/sc/source/filter/xml/xmlannoi.hxx
+++ b/sc/source/filter/xml/xmlannoi.hxx
@@ -34,12 +34,27 @@
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <rtl/ustrbuf.hxx>
+#include <svx/editdata.hxx>
#include <com/sun/star/drawing/XShape.hpp>
#include <com/sun/star/drawing/XShapes.hpp>
class ScXMLImport;
class ScXMLTableRowCellContext;
+struct ScXMLAnnotationStyleEntry
+{
+ sal_uInt16 mnFamily;
+ rtl::OUString maName;
+ ESelection maSelection;
+
+ ScXMLAnnotationStyleEntry( sal_uInt16 nFam, const rtl::OUString& rNam, const ESelection& rSel ) :
+ mnFamily( nFam ),
+ maName( rNam ),
+ maSelection( rSel )
+ {
+ }
+};
+
struct ScXMLAnnotationData
{
::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >
@@ -49,8 +64,11 @@ struct ScXMLAnnotationData
::rtl::OUString maAuthor;
::rtl::OUString maCreateDate;
::rtl::OUString maSimpleText;
+ ::rtl::OUString maStyleName;
+ ::rtl::OUString maTextStyle;
bool mbUseShapePos;
bool mbShown;
+ std::vector<ScXMLAnnotationStyleEntry> maContentStyles;
explicit ScXMLAnnotationData();
~ScXMLAnnotationData();
@@ -82,7 +100,10 @@ public:
void SetShape(
const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& rxShape,
- const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes );
+ const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& rxShapes,
+ const ::rtl::OUString& rStyleName, const ::rtl::OUString& rTextStyle );
+
+ void AddContentStyle( sal_uInt16 nFamily, const rtl::OUString& rName, const ESelection& rSelection );
private:
ScXMLAnnotationData& mrAnnotationData;
diff --git a/sc/source/filter/xml/xmlbodyi.cxx b/sc/source/filter/xml/xmlbodyi.cxx
index 048f1ec0c549..a301ddbf27e6 100644
--- a/sc/source/filter/xml/xmlbodyi.cxx
+++ b/sc/source/filter/xml/xmlbodyi.cxx
@@ -36,6 +36,8 @@
#include <cstdio>
#include "document.hxx"
+#include "docuno.hxx"
+#include "sheetdata.hxx"
#include "xmlbodyi.hxx"
#include "xmltabi.hxx"
@@ -136,6 +138,14 @@ SvXMLImportContext *ScXMLBodyContext::CreateChildContext( USHORT nPrefix,
const ::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList>& xAttrList )
{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the next child element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
SvXMLImportContext *pContext = 0;
const SvXMLTokenMap& rTokenMap = GetScImport().GetBodyElemTokenMap();
@@ -218,8 +228,36 @@ SvXMLImportContext *ScXMLBodyContext::CreateChildContext( USHORT nPrefix,
return pContext;
}
+void ScXMLBodyContext::Characters( const OUString& )
+{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before any content (whitespace) within the spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+ // otherwise ignore
+}
+
void ScXMLBodyContext::EndElement()
{
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ if ( pSheetData && pSheetData->HasStartPos() )
+ {
+ // stream part to copy ends before the closing tag of spreadsheet element
+ sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+ pSheetData->EndStreamPos( nEndOffset );
+ }
+
+ if ( pSheetData )
+ {
+ // store the loaded namespaces (for the office:spreadsheet element),
+ // so the prefixes in copied stream fragments remain valid
+ const SvXMLNamespaceMap& rNamespaces = GetImport().GetNamespaceMap();
+ pSheetData->StoreLoadedNamespaces( rNamespaces );
+ }
+
if (!bHadCalculationSettings)
{
// #111055#; set calculation settings defaults if there is no calculation settings element
diff --git a/sc/source/filter/xml/xmlbodyi.hxx b/sc/source/filter/xml/xmlbodyi.hxx
index d57af40eaf25..2c489418bfff 100644
--- a/sc/source/filter/xml/xmlbodyi.hxx
+++ b/sc/source/filter/xml/xmlbodyi.hxx
@@ -57,6 +57,7 @@ public:
const ::com::sun::star::uno::Reference<
::com::sun::star::xml::sax::XAttributeList>& xAttrList );
virtual void EndElement();
+ virtual void Characters( const ::rtl::OUString& rChars );
};
#endif
diff --git a/sc/source/filter/xml/xmlcelli.cxx b/sc/source/filter/xml/xmlcelli.cxx
index f0a4569cc86e..6a42d505cdc8 100644
--- a/sc/source/filter/xml/xmlcelli.cxx
+++ b/sc/source/filter/xml/xmlcelli.cxx
@@ -44,6 +44,7 @@
#include "docuno.hxx"
#include "unonames.hxx"
#include "postit.hxx"
+#include "sheetdata.hxx"
#include "XMLTableShapeImportHelper.hxx"
#include "XMLTextPContext.hxx"
@@ -550,6 +551,11 @@ void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Referen
}
}
xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet));
+
+ // For now, any sheet with validity is blocked from stream-copying.
+ // Later, the validation names could be stored along with the style names.
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
}
}
}
@@ -676,6 +682,18 @@ void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddr
uno::Reference< drawing::XShape > xShape;
rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
}
+
+ // store the style names for stream copying
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, aPos );
+
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
+ std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
+ while (aIter != aEnd)
+ {
+ pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, aPos, aIter->maSelection );
+ ++aIter;
+ }
}
// core implementation
diff --git a/sc/source/filter/xml/xmlcoli.cxx b/sc/source/filter/xml/xmlcoli.cxx
index 31662f4e68dd..73c06f23a7bf 100644
--- a/sc/source/filter/xml/xmlcoli.cxx
+++ b/sc/source/filter/xml/xmlcoli.cxx
@@ -42,6 +42,7 @@
#include "document.hxx"
#include "docuno.hxx"
#include "olinetab.hxx"
+#include "sheetdata.hxx"
#include "unonames.hxx"
#include <xmloff/xmltkmap.hxx>
@@ -145,7 +146,7 @@ SvXMLImportContext *ScXMLTableColContext::CreateChildContext( USHORT nPrefix,
void ScXMLTableColContext::EndElement()
{
ScXMLImport& rXMLImport = GetScImport();
- //sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
sal_Int32 nCurrentColumn = rXMLImport.GetTables().GetCurrentColumn();
uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
if(xSheet.is())
@@ -169,7 +170,16 @@ void ScXMLTableColContext::EndElement()
XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
XML_STYLE_FAMILY_TABLE_COLUMN, sStyleName, sal_True);
if (pStyle)
+ {
pStyle->FillPropertySet(xColumnProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddColumnStyle( sStyleName, ScAddress( (SCCOL)nCurrentColumn, 0, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
}
}
rtl::OUString sVisible(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLVIS));
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 98965cba07bc..a35a426e4831 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -53,10 +53,12 @@
#include "XMLColumnRowGroupExport.hxx"
#include "XMLStylesExportHelper.hxx"
#include "XMLChangeTrackingExportHelper.hxx"
+#include "sheetdata.hxx"
#include "docoptio.hxx"
#include "XMLExportSharedData.hxx"
#include "chgviset.hxx"
#include "docuno.hxx"
+#include "textuno.hxx"
#include "chartlis.hxx"
#include "unoguard.hxx"
#include "scitems.hxx"
@@ -80,6 +82,7 @@
#include <xmloff/xmluconv.hxx>
#include <xmloff/txtparae.hxx>
#include <xmloff/xmlcnitm.hxx>
+#include <xmloff/xmlerror.hxx>
#include <rtl/ustring.hxx>
@@ -122,6 +125,8 @@
#include <com/sun/star/container/XNamed.hpp>
#include <com/sun/star/sheet/XSheetLinkable.hpp>
#include <com/sun/star/form/XFormsSupplier2.hpp>
+#include <com/sun/star/io/XActiveDataSource.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
#include <com/sun/star/chart2/data/XRangeXMLConversion.hpp>
@@ -452,6 +457,7 @@ ScXMLExport::ScXMLExport(
const sal_uInt16 nExportFlag)
: SvXMLExport( xServiceFactory, SvXMLUnitConverter::GetMapUnit(GetFieldUnit()), XML_SPREADSHEET, nExportFlag ),
pDoc(NULL),
+ nSourceStreamPos(0),
pNumberFormatAttributesExportHelper(NULL),
pSharedData(NULL),
pColumnStyles(NULL),
@@ -567,6 +573,45 @@ ScXMLExport::~ScXMLExport()
delete pNumberFormatAttributesExportHelper;
}
+void ScXMLExport::SetSourceStream( const uno::Reference<io::XInputStream>& xNewStream )
+{
+ xSourceStream = xNewStream;
+
+ if ( xSourceStream.is() )
+ {
+ // make sure it's a plain UTF-8 stream as written by OOo itself
+
+ const sal_Char pXmlHeader[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ sal_Int32 nLen = strlen(pXmlHeader);
+
+ uno::Sequence<sal_Int8> aFileStart(nLen);
+ sal_Int32 nRead = xSourceStream->readBytes( aFileStart, nLen );
+
+ if ( nRead != nLen || rtl_compareMemory( aFileStart.getConstArray(), pXmlHeader, nLen ) != 0 )
+ {
+ // invalid - ignore stream, save normally
+ xSourceStream.clear();
+ }
+ else
+ {
+ // keep track of the bytes already read
+ nSourceStreamPos = nRead;
+
+ const ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ if (pSheetData)
+ {
+ // add the loaded namespaces to the name space map
+
+ if ( !pSheetData->AddLoadedNamespaces( _GetNamespaceMap() ) )
+ {
+ // conflicts in the namespaces - ignore the stream, save normally
+ xSourceStream.clear();
+ }
+ }
+ }
+ }
+}
+
sal_Int32 ScXMLExport::GetNumberFormatStyleIndex(sal_Int32 nNumFmt) const
{
NumberFormatIndexMap::const_iterator itr = aNumFmtIndexMap.find(nNumFmt);
@@ -803,7 +848,7 @@ void ScXMLExport::_ExportFontDecls()
SvXMLExport::_ExportFontDecls();
}
-table::CellRangeAddress ScXMLExport::GetEndAddress(uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
+table::CellRangeAddress ScXMLExport::GetEndAddress(const uno::Reference<sheet::XSpreadsheet>& xTable, const sal_Int32 /* nTable */)
{
table::CellRangeAddress aCellAddress;
uno::Reference<sheet::XSheetCellCursor> xCursor(xTable->createCursor());
@@ -1481,6 +1526,95 @@ void ScXMLExport::SetBodyAttributes()
}
}
+static bool lcl_CopyStreamElement( const uno::Reference< io::XInputStream >& xInput,
+ const uno::Reference< io::XOutputStream >& xOutput,
+ sal_Int32 nCount )
+{
+ const sal_Int32 nBufSize = 16*1024;
+ uno::Sequence<sal_Int8> aSequence(nBufSize);
+
+ sal_Int32 nRemaining = nCount;
+ bool bFirst = true;
+
+ while ( nRemaining > 0 )
+ {
+ sal_Int32 nRead = xInput->readBytes( aSequence, std::min( nRemaining, nBufSize ) );
+ if (bFirst)
+ {
+ // safety check: Make sure the copied part actually points to the start of an element
+ if ( nRead < 1 || aSequence[0] != static_cast<sal_Int8>('<') )
+ {
+ return false; // abort and set an error
+ }
+ bFirst = false;
+ }
+ if (nRead == nRemaining)
+ {
+ // safety check: Make sure the copied part also ends at the end of an element
+ if ( aSequence[nRead-1] != static_cast<sal_Int8>('>') )
+ {
+ return false; // abort and set an error
+ }
+ }
+
+ if ( nRead == nBufSize )
+ {
+ xOutput->writeBytes( aSequence );
+ nRemaining -= nRead;
+ }
+ else
+ {
+ if ( nRead > 0 )
+ {
+ uno::Sequence<sal_Int8> aTempBuf( aSequence.getConstArray(), nRead );
+ xOutput->writeBytes( aTempBuf );
+ }
+ nRemaining = 0;
+ }
+ }
+ return true; // successful
+}
+
+void ScXMLExport::CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd )
+{
+ uno::Reference<xml::sax::XDocumentHandler> xHandler = GetDocHandler();
+ uno::Reference<io::XActiveDataSource> xDestSource( xHandler, uno::UNO_QUERY );
+ if ( xDestSource.is() )
+ {
+ uno::Reference<io::XOutputStream> xDestStream = xDestSource->getOutputStream();
+ uno::Reference<io::XSeekable> xDestSeek( xDestStream, uno::UNO_QUERY );
+ if ( xDestSeek.is() )
+ {
+ // temporary: set same stream again to clear buffer
+ xDestSource->setOutputStream( xDestStream );
+
+ if ( getExportFlags() & EXPORT_PRETTY )
+ {
+ ByteString aOutStr("\n ");
+ uno::Sequence<sal_Int8> aOutSeq( (sal_Int8*)aOutStr.GetBuffer(), aOutStr.Len() );
+ xDestStream->writeBytes( aOutSeq );
+ }
+
+ rNewStart = (sal_Int32)xDestSeek->getPosition();
+
+ if ( nStartOffset > nSourceStreamPos )
+ xSourceStream->skipBytes( nStartOffset - nSourceStreamPos );
+
+ if ( !lcl_CopyStreamElement( xSourceStream, xDestStream, nEndOffset - nStartOffset ) )
+ {
+ // If copying went wrong, set an error.
+ // ScXMLImportWrapper then resets all stream flags, so the next save attempt will use normal saving.
+
+ uno::Sequence<OUString> aEmptySeq;
+ SetError(XMLERROR_CANCEL|XMLERROR_FLAG_SEVERE, aEmptySeq);
+ }
+ nSourceStreamPos = nEndOffset;
+
+ rNewEnd = (sal_Int32)xDestSeek->getPosition();
+ }
+ }
+}
+
void ScXMLExport::_ExportContent()
{
nCurrentTable = 0;
@@ -1500,6 +1634,10 @@ void ScXMLExport::_ExportContent()
if ( !xSpreadDoc.is() )
return;
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData)
+ pSheetData->ResetSaveEntries();
+
uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY );
if ( xIndex.is() )
{
@@ -1531,6 +1669,27 @@ void ScXMLExport::_ExportContent()
WriteTheLabelRanges( xSpreadDoc );
for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
{
+ sal_Int32 nStartOffset = -1;
+ sal_Int32 nEndOffset = -1;
+ if (pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable))
+ pSheetData->GetStreamPos( nTable, nStartOffset, nEndOffset );
+
+ if ( nStartOffset >= 0 && nEndOffset >= 0 && xSourceStream.is() )
+ {
+ sal_Int32 nNewStart = -1;
+ sal_Int32 nNewEnd = -1;
+ CopySourceStream( nStartOffset, nEndOffset, nNewStart, nNewEnd );
+
+ // store position of copied sheet in output
+ pSheetData->AddSavePos( nTable, nNewStart, nNewEnd );
+
+ // skip iterator entries for this sheet
+ pCellsItr->SkipTable(static_cast<SCTAB>(nTable));
+ }
+ else
+ {
+ //! indent after rebasing to m52
+
uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xTable.is())
{
@@ -1653,6 +1812,8 @@ void ScXMLExport::_ExportContent()
nEqualCells = 0;
}
}
+
+ }
IncrementProgressBar(sal_False);
}
}
@@ -1729,6 +1890,245 @@ void ScXMLExport::_ExportStyles( sal_Bool bUsed )
SvXMLExport::_ExportStyles(bUsed);
}
+void ScXMLExport::AddStyleFromCells(const uno::Reference<beans::XPropertySet>& xProperties,
+ const uno::Reference<sheet::XSpreadsheet>& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName)
+{
+ //! pass xCellRanges instead
+ uno::Reference<sheet::XSheetCellRanges> xCellRanges( xProperties, uno::UNO_QUERY );
+
+ rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
+ rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
+
+ rtl::OUString sStyleName;
+ sal_Int32 nNumberFormat(-1);
+ sal_Int32 nValidationIndex(-1);
+ std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ sal_Int32 nCount(0);
+ while (aItr != aEndItr)
+ {
+ if (aItr->mnIndex != -1)
+ {
+ switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
+ {
+ case CTF_SC_VALIDATION :
+ {
+ pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
+ // this is not very slow, because it is most the last property or
+ // if it is not the last property it is the property before the last property,
+ // so in the worst case only one property has to be copied, but in the best case no
+ // property has to be copied
+ aItr = xPropStates.erase(aItr);
+ aEndItr = xPropStates.end(); // #120346# old aEndItr is invalidated!
+ }
+ break;
+ case CTF_SC_CELLSTYLE :
+ {
+ aItr->maValue >>= sStyleName;
+ aItr->mnIndex = -1;
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ case CTF_SC_NUMBERFORMAT :
+ {
+ if (aItr->maValue >>= nNumberFormat)
+ addDataStyle(nNumberFormat);
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ default:
+ {
+ ++aItr;
+ ++nCount;
+ }
+ break;
+ }
+ }
+ else
+ {
+ ++aItr;
+ ++nCount;
+ }
+ }
+ if (nCount == 1) // this is the CellStyle and should be removed if alone
+ xPropStates.clear();
+ if (nNumberFormat == -1)
+ xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
+ if (sStyleName.getLength())
+ {
+ if (xPropStates.size())
+ {
+ sal_Int32 nIndex;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_CELL, *pOldName);
+ // add to pCellStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ sal_Bool bIsAutoStyle(sal_True);
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ if (!pCellStyles->AddStyleName(pTemp, nIndex))
+ delete pTemp;
+ }
+ else
+ nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
+
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ }
+ }
+ }
+ else
+ {
+ rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
+ sal_Int32 nIndex(0);
+ if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False))
+ {
+ delete pTemp;
+ pTemp = NULL;
+ }
+ if ( !pOldName )
+ {
+ uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
+ table::CellRangeAddress* pAddresses(aAddresses.getArray());
+ sal_Bool bGetMerge(sal_True);
+ for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
+ {
+ if (bGetMerge)
+ bGetMerge = GetMerged(pAddresses, xTable);
+ pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat);
+ if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
+ {
+ pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
+ pSharedData->SetLastRow(nTable, pAddresses->EndRow);
+ }
+ }
+ }
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromColumn(const uno::Reference<beans::XPropertySet>& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible)
+{
+ rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
+ if(xPropStates.size())
+ {
+ std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
+ std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
+ while (aItr != aEndItr)
+ {
+ if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
+ {
+ aItr->maValue >>= rIsVisible;
+ break;
+ }
+ ++aItr;
+ }
+
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_COLUMN, *pOldName);
+ // add to pColumnStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pColumnStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
+ }
+ }
+}
+
+void ScXMLExport::AddStyleFromRow(const uno::Reference<beans::XPropertySet>& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex)
+{
+ rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
+
+ std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
+ if(xPropStates.size())
+ {
+ rtl::OUString sParent;
+ if (pOldName)
+ {
+ if (GetAutoStylePool()->AddNamed(*pOldName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_ROW, *pOldName);
+ // add to pRowStyles, so the name is found for normal sheets
+ rtl::OUString* pTemp(new rtl::OUString(*pOldName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ }
+ else
+ {
+ rtl::OUString sName;
+ if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
+ {
+ rtl::OUString* pTemp(new rtl::OUString(sName));
+ rIndex = pRowStyles->AddStyleName(pTemp);
+ }
+ else
+ rIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
+ }
+ }
+}
+
+uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumAccess, sal_Int32 nIndex )
+{
+ uno::Any aRet;
+ uno::Reference<container::XEnumeration> xEnum( xEnumAccess->createEnumeration() );
+ try
+ {
+ sal_Int32 nSkip = nIndex;
+ while ( nSkip > 0 )
+ {
+ (void) xEnum->nextElement();
+ --nSkip;
+ }
+ aRet = xEnum->nextElement();
+ }
+ catch (container::NoSuchElementException&)
+ {
+ // leave aRet empty
+ }
+ return aRet;
+}
+
void ScXMLExport::_ExportAutoStyles()
{
if (GetModel().is())
@@ -1741,6 +2141,272 @@ void ScXMLExport::_ExportAutoStyles()
{
if (getExportFlags() & EXPORT_CONTENT)
{
+ // re-create automatic styles with old names from stored data
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData();
+ if (pSheetData && pDoc)
+ {
+ // formulas have to be calculated now, to detect changed results
+ // (during normal save, they will be calculated anyway)
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (pDoc->IsStreamValid(nTab))
+ {
+ ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab );
+ ScBaseCell* pCell = aIter.GetFirst();
+ while (pCell)
+ {
+ if (pCell->GetCellType() == CELLTYPE_FORMULA)
+ static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty
+ pCell = aIter.GetNext();
+ }
+ }
+
+ // stored cell styles
+ const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end();
+ while (aCellIter != aCellEnd)
+ {
+ ScAddress aPos = aCellIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference <beans::XPropertySet> xProperties(
+ xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY );
+
+ AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName);
+ }
+ ++aCellIter;
+ }
+
+ // stored column styles
+ const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end();
+ while (aColumnIter != aColumnEnd)
+ {
+ ScAddress aPos = aColumnIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns());
+ uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ sal_Bool bIsVisible(sal_True);
+ AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible );
+ }
+ ++aColumnIter;
+ }
+
+ // stored row styles
+ const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end();
+ while (aRowIter != aRowEnd)
+ {
+ ScAddress aPos = aRowIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows());
+ uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY);
+
+ sal_Int32 nIndex(-1);
+ AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex );
+ }
+ ++aRowIter;
+ }
+
+ // stored table styles
+ const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles();
+ std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin();
+ std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end();
+ while (aTableIter != aTableEnd)
+ {
+ ScAddress aPos = aTableIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromTable needed?
+ uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ if (xTableProperties.is())
+ {
+ std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTableIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName);
+ }
+ }
+ ++aTableIter;
+ }
+
+ // stored styles for notes
+
+ UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this );
+ GetShapeExport(); // make sure the graphics styles family is added
+
+ const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin();
+ std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end();
+ while (aNoteIter != aNoteEnd)
+ {
+ ScAddress aPos = aNoteIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromNote needed?
+
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ // all uno shapes are created anyway in CollectSharedData
+ uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY );
+ if (xShapeProperties.is())
+ {
+ if ( aNoteIter->maStyleName.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maStyleName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName);
+ }
+ if ( aNoteIter->maTextStyle.getLength() )
+ {
+ std::vector<XMLPropertyState> xPropStates(
+ GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteIter->maTextStyle );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ }
+ ++aNoteIter;
+ }
+
+ // note paragraph styles
+
+ //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this );
+ UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper();
+
+ const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end();
+ while (aNoteParaIter != aNoteParaEnd)
+ {
+ ScAddress aPos = aNoteParaIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xParaProp(
+ lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY );
+ if ( xParaProp.is() )
+ {
+ std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteParaIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName);
+ }
+ }
+ }
+ ++aNoteParaIter;
+ }
+
+ // note text styles
+
+ UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
+
+ const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end();
+ while (aNoteTextIter != aNoteTextEnd)
+ {
+ ScAddress aPos = aNoteTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ ScPostIt* pNote = pDoc->GetNote( aPos );
+ DBG_ASSERT( pNote, "note not found" );
+ if (pNote)
+ {
+ SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos );
+ uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aNoteTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aNoteTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ }
+ ++aNoteTextIter;
+ }
+
+ // stored text styles
+
+ //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this );
+
+ const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles();
+ std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin();
+ std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end();
+ while (aTextIter != aTextEnd)
+ {
+ ScAddress aPos = aTextIter->maCellPos;
+ sal_Int32 nTable = aPos.Tab();
+ bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) );
+ if (bCopySheet)
+ {
+ //! separate method AddStyleFromText needed?
+ //! cache sheet object
+
+ uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY);
+ uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY);
+ ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp );
+ if (pCursor)
+ {
+ pCursor->SetSelection( aTextIter->maSelection );
+
+ std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp));
+ rtl::OUString sParent;
+ rtl::OUString sName( aTextIter->maName );
+ GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates);
+ GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName);
+ }
+ }
+ ++aTextIter;
+ }
+ }
+
ExportExternalRefCacheStyles();
if (!pSharedData)
@@ -1751,18 +2417,18 @@ void ScXMLExport::_ExportAutoStyles()
CollectSharedData(nTableCount, nShapesCount, nCellCount);
//DBG_ERROR("no shared data setted");
}
- rtl::OUString SC_SCOLUMNPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_COLUMN_STYLES_PREFIX));
- rtl::OUString SC_SROWPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_ROW_STYLES_PREFIX));
- rtl::OUString SC_SCELLPREFIX(RTL_CONSTASCII_USTRINGPARAM(XML_STYLE_FAMILY_TABLE_CELL_STYLES_PREFIX));
- rtl::OUString SC_NUMBERFORMAT(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_NUMFMT));
sal_Int32 nTableCount(xIndex->getCount());
pCellStyles->AddNewTable(nTableCount - 1);
CollectShapesAutoStyles(nTableCount);
for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable)
{
+ bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) &&
+ pSheetData->HasStreamPos(nTable) && xSourceStream.is();
+
uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY);
if (xTable.is())
{
+ // table styles array must be complete, including copied tables - Add should find the stored style
uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY);
if (xTableProperties.is())
{
@@ -1775,7 +2441,11 @@ void ScXMLExport::_ExportAutoStyles()
aTableStyles.push_back(sName);
}
}
- uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTableProperties, uno::UNO_QUERY );
+ }
+ // collect other auto-styles only for non-copied sheets
+ if (xTable.is() && !bUseStream)
+ {
+ uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY );
if ( xCellFormatRanges.is() )
{
uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges());
@@ -1791,123 +2461,14 @@ void ScXMLExport::_ExportAutoStyles()
uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY);
if (xProperties.is())
{
- rtl::OUString sStyleName;
- sal_Int32 nNumberFormat(-1);
- sal_Int32 nValidationIndex(-1);
- std::vector< XMLPropertyState > xPropStates(xCellStylesExportPropertySetMapper->Filter( xProperties ));
- std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
- std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
- sal_Int32 nCount(0);
- while (aItr != aEndItr)
- {
- if (aItr->mnIndex != -1)
- {
- switch (xCellStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex))
- {
- case CTF_SC_VALIDATION :
- {
- pValidationsContainer->AddValidation(aItr->maValue, nValidationIndex);
- // this is not very slow, because it is most the last property or
- // if it is not the last property it is the property before the last property,
- // so in the worst case only one property has to be copied, but in the best case no
- // property has to be copied
- aItr = xPropStates.erase(aItr);
- aEndItr = xPropStates.end(); // #120346# old aEndItr is invalidated!
- }
- break;
- case CTF_SC_CELLSTYLE :
- {
- aItr->maValue >>= sStyleName;
- aItr->mnIndex = -1;
- ++aItr;
- ++nCount;
- }
- break;
- case CTF_SC_NUMBERFORMAT :
- {
- if (aItr->maValue >>= nNumberFormat)
- addDataStyle(nNumberFormat);
- ++aItr;
- ++nCount;
- }
- break;
- default:
- {
- ++aItr;
- ++nCount;
- }
- break;
- }
- }
- else
- {
- ++aItr;
- ++nCount;
- }
- }
- if (nCount == 1) // this is the CellStyle and should be removed if alone
- xPropStates.clear();
- if (nNumberFormat == -1)
- xProperties->getPropertyValue(SC_NUMBERFORMAT) >>= nNumberFormat;
- if (sStyleName.getLength())
- {
- if (xPropStates.size())
- {
- sal_Int32 nIndex;
- rtl::OUString sName;
- sal_Bool bIsAutoStyle(sal_True);
- if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_CELL, sStyleName, xPropStates))
- {
- rtl::OUString* pTemp(new rtl::OUString(sName));
- if (!pCellStyles->AddStyleName(pTemp, nIndex))
- delete pTemp;
- }
- else
- nIndex = pCellStyles->GetIndexOfStyleName(sName, SC_SCELLPREFIX, bIsAutoStyle);
- uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
- table::CellRangeAddress* pAddresses(aAddresses.getArray());
- sal_Bool bGetMerge(sal_True);
- for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
- {
- pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
- pSharedData->SetLastRow(nTable, pAddresses->EndRow);
- pCellStyles->AddRangeStyleName(*pAddresses, nIndex, bIsAutoStyle, nValidationIndex, nNumberFormat);
- if (bGetMerge)
- bGetMerge = GetMerged(pAddresses, xTable);
- }
- }
- else
- {
- rtl::OUString* pTemp(new rtl::OUString(EncodeStyleName(sStyleName)));
- sal_Int32 nIndex(0);
- if (!pCellStyles->AddStyleName(pTemp, nIndex, sal_False))
- {
- delete pTemp;
- pTemp = NULL;
- }
- uno::Sequence<table::CellRangeAddress> aAddresses(xCellRanges->getRangeAddresses());
- table::CellRangeAddress* pAddresses(aAddresses.getArray());
- sal_Bool bGetMerge(sal_True);
- for (sal_Int32 i = 0; i < aAddresses.getLength(); ++i, ++pAddresses)
- {
- if (bGetMerge)
- bGetMerge = GetMerged(pAddresses, xTable);
- pCellStyles->AddRangeStyleName(*pAddresses, nIndex, sal_False, nValidationIndex, nNumberFormat);
- if (!sStyleName.equalsAsciiL("Default", 7) || nValidationIndex != -1)
- {
- pSharedData->SetLastColumn(nTable, pAddresses->EndColumn);
- pSharedData->SetLastRow(nTable, pAddresses->EndRow);
- }
- }
- }
- }
+ AddStyleFromCells(xProperties, xTable, nTable, NULL);
IncrementProgressBar(sal_False);
}
}
}
}
}
- uno::Reference<table::XColumnRowRange> xColumnRowRange (xTableProperties, uno::UNO_QUERY);
+ uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY);
if (xColumnRowRange.is())
{
if (pDoc)
@@ -1935,31 +2496,9 @@ void ScXMLExport::_ExportAutoStyles()
uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY);
if (xColumnProperties.is())
{
- std::vector<XMLPropertyState> xPropStates(xColumnStylesExportPropertySetMapper->Filter(xColumnProperties));
- if(xPropStates.size())
- {
- std::vector< XMLPropertyState >::iterator aItr(xPropStates.begin());
- std::vector< XMLPropertyState >::iterator aEndItr(xPropStates.end());
- while (aItr != aEndItr)
- {
- if (xColumnStylesPropertySetMapper->GetEntryContextId(aItr->mnIndex) == CTF_SC_ISVISIBLE)
- {
- aItr->maValue >>= bIsVisible;
- break;
- }
- ++aItr;
- }
- rtl::OUString sParent;
- rtl::OUString sName;
- if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_COLUMN, sParent, xPropStates))
- {
- rtl::OUString* pTemp(new rtl::OUString(sName));
- nIndex = pColumnStyles->AddStyleName(pTemp);
- }
- else
- nIndex = pColumnStyles->GetIndexOfStyleName(sName, SC_SCOLUMNPREFIX);
- pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
- }
+ AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible );
+ //if(xPropStates.size())
+ pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible);
}
sal_Int32 nOld(nColumn);
nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<USHORT>(nColumn));
@@ -1996,20 +2535,9 @@ void ScXMLExport::_ExportAutoStyles()
uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY);
if(xRowProperties.is())
{
- std::vector<XMLPropertyState> xPropStates(xRowStylesExportPropertySetMapper->Filter(xRowProperties));
- if(xPropStates.size())
- {
- rtl::OUString sParent;
- rtl::OUString sName;
- if (GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_ROW, sParent, xPropStates))
- {
- rtl::OUString* pTemp(new rtl::OUString(sName));
- nIndex = pRowStyles->AddStyleName(pTemp);
- }
- else
- nIndex = pRowStyles->GetIndexOfStyleName(sName, SC_SROWPREFIX);
- pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
- }
+ AddStyleFromRow( xRowProperties, NULL, nIndex );
+ //if(xPropStates.size())
+ pRowStyles->AddFieldStyleName(nTable, nRow, nIndex);
}
sal_Int32 nOld(nRow);
nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<USHORT>(nRow), false);
@@ -2025,7 +2553,7 @@ void ScXMLExport::_ExportAutoStyles()
}
}
}
- uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTableProperties, uno::UNO_QUERY);
+ uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY);
if (xCellRangesQuery.is())
{
uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED));
diff --git a/sc/source/filter/xml/xmlexprt.hxx b/sc/source/filter/xml/xmlexprt.hxx
index d38bd7b23970..b71886c1871e 100644
--- a/sc/source/filter/xml/xmlexprt.hxx
+++ b/sc/source/filter/xml/xmlexprt.hxx
@@ -38,6 +38,10 @@
#include <com/sun/star/drawing/XShapes.hpp>
#include <com/sun/star/table/XCellRange.hpp>
+namespace com { namespace sun { namespace star {
+ namespace beans { class XPropertySet; }
+} } }
+
#include <hash_map>
class ScOutlineArray;
@@ -72,6 +76,9 @@ class ScXMLExport : public SvXMLExport
com::sun::star::uno::Reference <com::sun::star::sheet::XSpreadsheet> xCurrentTable;
com::sun::star::uno::Reference <com::sun::star::table::XCellRange> xCurrentTableCellRange;
+ com::sun::star::uno::Reference<com::sun::star::io::XInputStream> xSourceStream;
+ sal_Int32 nSourceStreamPos;
+
UniReference < XMLPropertyHandlerFactory > xScPropHdlFactory;
UniReference < XMLPropertySetMapper > xCellStylesPropertySetMapper;
UniReference < XMLPropertySetMapper > xColumnStylesPropertySetMapper;
@@ -139,7 +146,7 @@ class ScXMLExport : public SvXMLExport
void CollectInternalShape( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape );
- com::sun::star::table::CellRangeAddress GetEndAddress(com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable,
+ com::sun::star::table::CellRangeAddress GetEndAddress(const com::sun::star::uno::Reference<com::sun::star::sheet::XSpreadsheet>& xTable,
const sal_Int32 nTable);
// ScMyEmptyDatabaseRangesContainer GetEmptyDatabaseRanges();
void GetAreaLinks( com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheetDocument>& xSpreadDoc, ScMyAreaLinksContainer& rAreaLinks );
@@ -207,7 +214,21 @@ class ScXMLExport : public SvXMLExport
void CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib);
+ void AddStyleFromCells(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xProperties,
+ const com::sun::star::uno::Reference< com::sun::star::sheet::XSpreadsheet >& xTable,
+ sal_Int32 nTable, const rtl::OUString* pOldName );
+ void AddStyleFromColumn(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xColumnProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex, sal_Bool& rIsVisible );
+ void AddStyleFromRow(
+ const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xRowProperties,
+ const rtl::OUString* pOldName, sal_Int32& rIndex );
+
void IncrementProgressBar(sal_Bool bEditCell, sal_Int32 nInc = 1);
+
+ void CopySourceStream( sal_Int32 nStartOffset, sal_Int32 nEndOffset, sal_Int32& rNewStart, sal_Int32& rNewEnd );
+
protected:
virtual SvXMLAutoStylePoolP* CreateAutoStylePool();
virtual XMLPageExport* CreatePageExport();
@@ -234,6 +255,8 @@ public:
UniReference < XMLPropertySetMapper > GetCellStylesPropertySetMapper() { return xCellStylesPropertySetMapper; }
UniReference < XMLPropertySetMapper > GetTableStylesPropertySetMapper() { return xTableStylesPropertySetMapper; }
+ void SetSourceStream( const com::sun::star::uno::Reference<com::sun::star::io::XInputStream>& xNewStream );
+
void GetChangeTrackViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
virtual void GetViewSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
virtual void GetConfigurationSettings(com::sun::star::uno::Sequence<com::sun::star::beans::PropertyValue>& rProps);
diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx
index 200e33743020..8e3f4b421a6c 100644
--- a/sc/source/filter/xml/xmlimprt.cxx
+++ b/sc/source/filter/xml/xmlimprt.cxx
@@ -71,6 +71,7 @@
#include "XMLChangeTrackingImportHelper.hxx"
#include "chgviset.hxx"
#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
#include "unonames.hxx"
#include "rangeutl.hxx"
#include "postit.hxx"
@@ -93,6 +94,7 @@
#include <com/sun/star/sheet/NamedRangeFlag.hpp>
#include <com/sun/star/sheet/XNamedRange.hpp>
#include <com/sun/star/sheet/XLabelRanges.hpp>
+#include <com/sun/star/io/XSeekable.hpp>
#define SC_LOCALE "Locale"
#define SC_STANDARDFORMAT "StandardFormat"
@@ -2416,6 +2418,20 @@ void ScXMLImport::SetStyleToRanges()
pStyle->FillPropertySet(xProperties);
sal_Int32 nNumberFormat(pStyle->GetNumberFormat());
SetType(xProperties, nNumberFormat, nPrevCellType, sPrevCurrency);
+
+ // store first cell of first range for each style, once per sheet
+ uno::Sequence<table::CellRangeAddress> aAddresses(xSheetCellRanges->getRangeAddresses());
+ if ( aAddresses.getLength() > 0 )
+ {
+ const table::CellRangeAddress& rRange = aAddresses[0];
+ if ( rRange.Sheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ pSheetData->AddCellStyle( sPrevStyleName,
+ ScAddress( (SCCOL)rRange.StartColumn, (SCROW)rRange.StartRow, (SCTAB)rRange.Sheet ) );
+ pStyle->SetLastSheet(rRange.Sheet);
+ }
+ }
}
else
{
@@ -2569,6 +2585,17 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
if ( ( nFlags & IMPORT_CONTENT ) && !( nFlags & IMPORT_STYLES ) )
ExamineDefaultStyle();
+ if (getImportFlags() & IMPORT_CONTENT)
+ {
+ if (GetModel().is())
+ {
+ // store initial namespaces, to find the ones that were added from the file later
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+ const SvXMLNamespaceMap& rNamespaces = GetNamespaceMap();
+ pSheetData->StoreInitialNamespaces(rNamespaces);
+ }
+ }
+
UnlockSolarMutex();
}
@@ -2772,6 +2799,19 @@ throw( ::com::sun::star::xml::sax::SAXException, ::com::sun::star::uno::RuntimeE
GetProgressBarHelper()->End(); // make room for subsequent SfxProgressBars
if (pDoc)
pDoc->CompileXML();
+
+ if (pDoc && GetModel().is())
+ {
+ // set "valid stream" flags after loading (before UpdateRowHeights, so changed formula results
+ // in UpdateRowHeights can already clear the flags again)
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetModel())->GetSheetSaveData();
+
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (!pSheetData->IsSheetBlocked( nTab ))
+ pDoc->SetStreamValid( nTab, TRUE );
+ }
+
aTables.UpdateRowHeights();
aTables.ResizeShapes();
}
@@ -2831,6 +2871,16 @@ void ScXMLImport::UnlockSolarMutex()
}
}
+sal_Int32 ScXMLImport::GetByteOffset()
+{
+ sal_Int32 nOffset = -1;
+ uno::Reference<xml::sax::XLocator> xLocator = GetLocator();
+ uno::Reference<io::XSeekable> xSeek( xLocator, uno::UNO_QUERY ); //! should use different interface
+ if ( xSeek.is() )
+ nOffset = (sal_Int32)xSeek->getPosition();
+ return nOffset;
+}
+
void ScXMLImport::SetRangeOverflowType(sal_uInt32 nType)
{
// #i31130# Overflow is stored in the document, because the ScXMLImport object
diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx
index f96d34c40ca5..c108642d0b68 100644
--- a/sc/source/filter/xml/xmlimprt.hxx
+++ b/sc/source/filter/xml/xmlimprt.hxx
@@ -980,6 +980,8 @@ public:
void LockSolarMutex();
void UnlockSolarMutex();
+ sal_Int32 GetByteOffset();
+
void SetRangeOverflowType(sal_uInt32 nType);
sal_Int32 GetRangeType(const rtl::OUString sRangeType) const;
diff --git a/sc/source/filter/xml/xmlrowi.cxx b/sc/source/filter/xml/xmlrowi.cxx
index 079691944481..f62208cdd2ff 100644
--- a/sc/source/filter/xml/xmlrowi.cxx
+++ b/sc/source/filter/xml/xmlrowi.cxx
@@ -43,6 +43,7 @@
#include "document.hxx"
#include "docuno.hxx"
#include "olinetab.hxx"
+#include "sheetdata.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
@@ -170,6 +171,7 @@ void ScXMLTableRowContext::EndElement()
GetScImport().GetTables().AddRow();
DBG_ERRORFILE("it seems here is a nonvalid file; possible missing of table:table-cell element");
}
+ sal_Int32 nSheet = rXMLImport.GetTables().GetCurrentSheet();
sal_Int32 nCurrentRow(rXMLImport.GetTables().GetCurrentRow());
uno::Reference<sheet::XSpreadsheet> xSheet(rXMLImport.GetTables().GetCurrentXSheet());
if(xSheet.is())
@@ -196,7 +198,16 @@ void ScXMLTableRowContext::EndElement()
XMLTableStyleContext* pStyle((XMLTableStyleContext *)pStyles->FindStyleChildContext(
XML_STYLE_FAMILY_TABLE_ROW, sStyleName, sal_True));
if (pStyle)
+ {
pStyle->FillPropertySet(xRowProperties);
+
+ if ( nSheet != pStyle->GetLastSheet() )
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddRowStyle( sStyleName, ScAddress( 0, (SCROW)nFirstRow, (SCTAB)nSheet ) );
+ pStyle->SetLastSheet(nSheet);
+ }
+ }
}
}
sal_Bool bVisible (sal_True);
diff --git a/sc/source/filter/xml/xmlstyli.cxx b/sc/source/filter/xml/xmlstyli.cxx
index 79ba79f0e689..20158d1f13db 100644
--- a/sc/source/filter/xml/xmlstyli.cxx
+++ b/sc/source/filter/xml/xmlstyli.cxx
@@ -50,6 +50,11 @@
#include <tools/debug.hxx>
#include "XMLTableHeaderFooterContext.hxx"
#include "XMLConverter.hxx"
+#include "XMLTableShapeImportHelper.hxx"
+#include "sheetdata.hxx"
+#include "xmlannoi.hxx"
+#include "textuno.hxx"
+#include "cellsuno.hxx"
#include "docuno.hxx"
#include "unonames.hxx"
@@ -461,6 +466,7 @@ XMLTableStyleContext::XMLTableStyleContext( ScXMLImport& rImport,
sNumberFormat(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("NumberFormat"))),
pStyles(&rStyles),
nNumberFormat(-1),
+ nLastSheet(-1),
bConditionalFormatCreated(sal_False),
bParentSet(sal_False)
{
@@ -609,15 +615,22 @@ sal_Int32 XMLTableStyleContext::GetNumberFormat()
}
return nNumberFormat;
}
+
// ----------------------------------------------------------------------------
SvXMLStyleContext *XMLTableStylesContext::CreateStyleStyleChildContext(
sal_uInt16 nFamily, sal_uInt16 nPrefix, const OUString& rLocalName,
const uno::Reference< xml::sax::XAttributeList > & xAttrList )
{
- SvXMLStyleContext *pStyle(SvXMLStylesContext::CreateStyleStyleChildContext( nFamily, nPrefix,
- rLocalName,
- xAttrList ));
+ SvXMLStyleContext *pStyle;
+ // use own wrapper for text and paragraph, to record style usage
+ if (nFamily == XML_STYLE_FAMILY_TEXT_PARAGRAPH || nFamily == XML_STYLE_FAMILY_TEXT_TEXT)
+ pStyle = new ScCellTextStyleContext( GetImport(), nPrefix, rLocalName,
+ xAttrList, *this, nFamily );
+ else
+ pStyle = SvXMLStylesContext::CreateStyleStyleChildContext(
+ nFamily, nPrefix, rLocalName, xAttrList );
+
if (!pStyle)
{
switch( nFamily )
@@ -1013,3 +1026,56 @@ void ScMasterPageContext::Finish( sal_Bool bOverwrite )
ClearContent(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_PAGE_RIGHTHDRCON)));
}
+// ---------------------------------------------------------------------------
+
+ScCellTextStyleContext::ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const rtl::OUString& rLName, const uno::Reference<xml::sax::XAttributeList> & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily, sal_Bool bDefaultStyle ) :
+ XMLTextStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle ),
+ nLastSheet(-1)
+{
+}
+
+ScCellTextStyleContext::~ScCellTextStyleContext()
+{
+}
+
+void ScCellTextStyleContext::FillPropertySet( const uno::Reference<beans::XPropertySet>& xPropSet )
+{
+ XMLTextStyleContext::FillPropertySet( xPropSet );
+
+ ScXMLImport& rXMLImport = GetScImport();
+
+ ScCellTextCursor* pCellImp = ScCellTextCursor::getImplementation( xPropSet );
+ if (pCellImp)
+ {
+ ScAddress aPos = pCellImp->GetCellObj().GetPosition();
+ if ( static_cast<sal_Int32>(aPos.Tab()) != nLastSheet )
+ {
+ ESelection aSel = pCellImp->GetSelection();
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
+ pSheetData->AddTextStyle( GetName(), aPos, aSel );
+
+ nLastSheet = static_cast<sal_Int32>(aPos.Tab());
+ }
+ }
+ else if ( rXMLImport.GetTables().GetCurrentSheet() != nLastSheet )
+ {
+ ScDrawTextCursor* pDrawImp = ScDrawTextCursor::getImplementation( xPropSet );
+ if (pDrawImp)
+ {
+ XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)GetScImport().GetShapeImport().get();
+ ScXMLAnnotationContext* pAnnotationContext = pTableShapeImport->GetAnnotationContext();
+ if (pAnnotationContext)
+ {
+ pAnnotationContext->AddContentStyle( GetFamily(), GetName(), pDrawImp->GetSelection() );
+ nLastSheet = rXMLImport.GetTables().GetCurrentSheet();
+ }
+ }
+
+ // if it's a different shape, BlockSheet is called from XMLTableShapeImportHelper::finishShape
+ // formatted text in page headers/footers can be ignored
+ }
+}
+
diff --git a/sc/source/filter/xml/xmlstyli.hxx b/sc/source/filter/xml/xmlstyli.hxx
index 272ec0151134..c80ea8b5c92d 100644
--- a/sc/source/filter/xml/xmlstyli.hxx
+++ b/sc/source/filter/xml/xmlstyli.hxx
@@ -40,9 +40,12 @@
#include <xmloff/xmlimppr.hxx>
#include <xmloff/XMLTextMasterPageContext.hxx>
#include <xmloff/XMLTextMasterStylesContext.hxx>
+#include <xmloff/txtstyli.hxx>
#include <com/sun/star/sheet/ConditionOperator.hpp>
#include "xmlimprt.hxx"
+class ScSheetSaveData;
+
class ScXMLCellImportPropertyMapper : public SvXMLImportPropertyMapper
{
protected:
@@ -101,6 +104,7 @@ class XMLTableStyleContext : public XMLPropStyleContext
std::vector<ScXMLMapContent> aMaps;
com::sun::star::uno::Any aConditionalFormat;
sal_Int32 nNumberFormat;
+ sal_Int32 nLastSheet;
sal_Bool bConditionalFormatCreated;
sal_Bool bParentSet;
@@ -158,6 +162,9 @@ public:
sal_Int32 GetNumberFormat();// { return nNumberFormat; }
+ sal_Int32 GetLastSheet() const { return nLastSheet; }
+ void SetLastSheet(sal_Int32 nNew) { nLastSheet = nNew; }
+
private:
using XMLPropStyleContext::SetStyle;
};
@@ -298,5 +305,28 @@ public:
virtual void Finish( sal_Bool bOverwrite );
};
+class ScCellTextStyleContext : public XMLTextStyleContext
+{
+ sal_Int32 nLastSheet;
+
+ const ScXMLImport& GetScImport() const { return (const ScXMLImport&)GetImport(); }
+ ScXMLImport& GetScImport() { return (ScXMLImport&)GetImport(); }
+
+public:
+ ScCellTextStyleContext( SvXMLImport& rImport, sal_uInt16 nPrfx,
+ const ::rtl::OUString& rLName,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::xml::sax::XAttributeList > & xAttrList,
+ SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
+ sal_Bool bDefaultStyle = sal_False );
+ virtual ~ScCellTextStyleContext();
+
+ // overload FillPropertySet to store style information
+ virtual void FillPropertySet(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::beans::XPropertySet > & rPropSet );
+};
+
+
#endif
diff --git a/sc/source/filter/xml/xmlsubti.cxx b/sc/source/filter/xml/xmlsubti.cxx
index 231839b9f946..0f980c4a9608 100644
--- a/sc/source/filter/xml/xmlsubti.cxx
+++ b/sc/source/filter/xml/xmlsubti.cxx
@@ -43,6 +43,7 @@
#include "docuno.hxx"
#include "cellsuno.hxx"
#include "XMLStylesImportHelper.hxx"
+#include "sheetdata.hxx"
#include "tabprotection.hxx"
#include <svx/svdpage.hxx>
@@ -269,7 +270,12 @@ void ScMyTables::NewSheet(const rtl::OUString& sTableName, const rtl::OUString&
XMLTableStyleContext* pStyle = (XMLTableStyleContext *)pStyles->FindStyleChildContext(
XML_STYLE_FAMILY_TABLE_TABLE, sStyleName, sal_True);
if (pStyle)
+ {
pStyle->FillPropertySet(xProperties);
+
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rImport.GetModel())->GetSheetSaveData();
+ pSheetData->AddTableStyle( sStyleName, ScAddress( 0, 0, (SCTAB)nCurrentSheet ) );
+ }
}
}
}
@@ -609,7 +615,11 @@ void ScMyTables::UpdateRowHeights()
}
if (aUpdateSheets.GetSelectCount())
+ {
+ pDoc->LockStreamValid( true ); // ignore draw page size (but not formula results)
ScModelObj::getImplementation(rImport.GetModel())->UpdateAllRowHeights(&aUpdateSheets);
+ pDoc->LockStreamValid( false );
+ }
}
rImport.UnlockSolarMutex();
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index cc95e01be821..8ea9701ecd32 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -50,6 +50,7 @@
#include "XMLStylesImportHelper.hxx"
#include "rangeutl.hxx"
#include "externalrefmgr.hxx"
+#include "sheetdata.hxx"
#include <xmloff/xmltkmap.hxx>
#include <xmloff/nmspmap.hxx>
@@ -147,9 +148,13 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport,
const sal_Int32 nSpannedCols) :
SvXMLImportContext( rImport, nPrfx, rLName ),
pExternalRefInfo(NULL),
+ nStartOffset(-1),
bStartFormPage(sal_False),
bPrintEntireSheet(sal_True)
{
+ // get start offset in file (if available)
+ nStartOffset = GetScImport().GetByteOffset();
+
if (!bTempIsSubTable)
{
sal_Bool bProtection(sal_False);
@@ -326,6 +331,9 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
void ScXMLTableContext::EndElement()
{
+ // get end offset in file (if available)
+// sal_Int32 nEndOffset = GetScImport().GetByteOffset();
+
GetScImport().LockSolarMutex();
GetScImport().GetStylesImportHelper()->EndTable();
ScDocument* pDoc(GetScImport().GetDocument());
@@ -386,6 +394,15 @@ void ScXMLTableContext::EndElement()
GetScImport().GetTables().DeleteTable();
GetScImport().ProgressBarIncrement(sal_False);
+
+ // store stream positions
+ if (!pExternalRefInfo.get() && nStartOffset >= 0 /* && nEndOffset >= 0 */)
+ {
+ ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetScImport().GetModel())->GetSheetSaveData();
+ sal_Int32 nTab = GetScImport().GetTables().GetCurrentSheet();
+ // pSheetData->AddStreamPos( nTab, nStartOffset, nEndOffset );
+ pSheetData->StartStreamPos( nTab, nStartOffset );
+ }
}
GetScImport().UnlockSolarMutex();
}
diff --git a/sc/source/filter/xml/xmltabi.hxx b/sc/source/filter/xml/xmltabi.hxx
index 7b8c9878f2d5..1a4438b28955 100644
--- a/sc/source/filter/xml/xmltabi.hxx
+++ b/sc/source/filter/xml/xmltabi.hxx
@@ -52,6 +52,7 @@ class ScXMLTableContext : public SvXMLImportContext
{
rtl::OUString sPrintRanges;
::std::auto_ptr<ScXMLExternalTabData> pExternalRefInfo;
+ sal_Int32 nStartOffset;
sal_Bool bStartFormPage;
sal_Bool bPrintEntireSheet;
diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx
index 960d78ada163..dbf672993310 100644
--- a/sc/source/filter/xml/xmlwrap.cxx
+++ b/sc/source/filter/xml/xmlwrap.cxx
@@ -624,6 +624,25 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError)
return sal_False;
}
+bool lcl_HasValidStream(ScDocument& rDoc)
+{
+ SfxObjectShell* pObjSh = rDoc.GetDocumentShell();
+ if ( pObjSh->IsDocShared() )
+ return false; // never copy stream from shared file
+
+ // don't read remote file again
+ // (could instead re-use medium directly in that case)
+ SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium();
+ if ( !pSrcMed || pSrcMed->IsRemote() )
+ return false;
+
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; ++nTab)
+ if (rDoc.IsStreamValid(nTab))
+ return true;
+ return false;
+}
+
sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServiceFactory>& xServiceFactory,
uno::Reference<frame::XModel>& xModel, uno::Reference<uno::XInterface>& xWriter,
uno::Sequence<beans::PropertyValue>& aDescriptor, const rtl::OUString& sName,
@@ -691,7 +710,49 @@ sal_Bool ScXMLImportWrapper::ExportToComponent(uno::Reference<lang::XMultiServic
{
ScXMLExport* pExport = static_cast<ScXMLExport*>(SvXMLExport::getImplementation(xFilter));
pExport->SetSharedData(pSharedData);
- bRet = xFilter->filter( aDescriptor );
+
+ // if there are sheets to copy, get the source stream
+ if ( sName.equalsAscii("content.xml") && lcl_HasValidStream(rDoc) &&
+ ( pExport->getExportFlags() & EXPORT_OASIS ) )
+ {
+ // old stream is still in this file's storage - open read-only
+
+ SfxMedium* pSrcMed = rDoc.GetDocumentShell()->GetMedium();
+ String aSrcURL = pSrcMed->GetOrigURL();
+
+ // SfxMedium must not be read-only, or it will create a temp file in GetStorage
+ SfxMedium aTmpMedium( aSrcURL, STREAM_READWRITE, FALSE, NULL, NULL );
+ uno::Reference<embed::XStorage> xTmpStorage = aTmpMedium.GetStorage();
+ uno::Reference<io::XStream> xSrcStream;
+ uno::Reference<io::XInputStream> xSrcInput;
+ try
+ {
+ if (xTmpStorage.is())
+ xSrcStream = xTmpStorage->openStreamElement( sName, embed::ElementModes::READ );
+ if (xSrcStream.is())
+ xSrcInput = xSrcStream->getInputStream();
+ }
+ catch (uno::Exception&)
+ {
+ // stream not available (for example, password protected) - save normally (xSrcInput is null)
+ }
+
+ pExport->SetSourceStream( xSrcInput );
+ bRet = xFilter->filter( aDescriptor );
+ pExport->SetSourceStream( uno::Reference<io::XInputStream>() );
+
+ // If there was an error, reset all stream flags, so the next save attempt will use normal saving.
+ if (!bRet)
+ {
+ SCTAB nTabCount = rDoc.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (rDoc.IsStreamValid(nTab))
+ rDoc.SetStreamValid(nTab, FALSE);
+ }
+ }
+ else
+ bRet = xFilter->filter( aDescriptor );
+
pSharedData = pExport->GetSharedData();
//stream is closed by SAX parser
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 61bd4f7bf0e9..424e4731a324 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -113,6 +113,14 @@ IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
else
rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
rDocShell.SetDrawModified();
+
+ // the affected sheet isn't known, so all stream positions are invalidated
+ ScDocument* pDoc = rDocShell.GetDocument();
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
return 0;
}
@@ -1061,6 +1069,9 @@ bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
if( rDoc.IsUndoEnabled() )
rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
+ if (rDoc.IsStreamValid(rPos.Tab()))
+ rDoc.SetStreamValid(rPos.Tab(), FALSE);
+
rDocShell.SetDocumentModified();
return true;
@@ -1089,6 +1100,9 @@ bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, BOOL bA
//! Undo !!!
+ if (pDoc->IsStreamValid(rPos.Tab()))
+ pDoc->SetStreamValid(rPos.Tab(), FALSE);
+
rDocShell.PostPaintCell( rPos );
aModificator.SetDocumentModified();
@@ -1142,6 +1156,10 @@ bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, con
// repaint cell (to make note marker visible)
rDocShell.PostPaintCell( rPos );
+
+ if (rDoc.IsStreamValid(rPos.Tab()))
+ rDoc.SetStreamValid(rPos.Tab(), FALSE);
+
aModificator.SetDocumentModified();
bDone = true;
}
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index c62c2dc41fdf..c8a41e81497d 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -120,6 +120,7 @@
#include "cfgids.hxx"
#include "warnpassword.hxx"
#include "optsolver.hxx"
+#include "sheetdata.hxx"
#include "tabprotection.hxx"
#include "docsh.hxx"
@@ -755,8 +756,13 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
if ( IsDocShared() && !SC_MOD()->IsInSharedDocSaving() )
{
}
+ UseSheetSaveEntries(); // use positions from saved file for next saving
}
break;
+ case SFX_EVENT_SAVEASDOCDONE:
+ // new positions are used after "save" and "save as", but not "save to"
+ UseSheetSaveEntries(); // use positions from saved file for next saving
+ break;
default:
{
}
@@ -2212,6 +2218,7 @@ BOOL ScDocShell::HasAutomaticTableName( const String& rFilter ) // static
pPaintLockData ( NULL ), \
pOldJobSetup ( NULL ), \
pSolverSaveData ( NULL ), \
+ pSheetSaveData ( NULL ), \
pModificator ( NULL )
//------------------------------------------------------------------
@@ -2305,6 +2312,7 @@ __EXPORT ScDocShell::~ScDocShell()
delete pOldJobSetup; // gesetzt nur bei Fehler in StartJob()
delete pSolverSaveData;
+ delete pSheetSaveData;
delete pOldAutoDBRange;
if (pModificator)
@@ -2475,6 +2483,39 @@ void ScDocShell::SetSolverSaveData( const ScOptSolverSave& rData )
pSolverSaveData = new ScOptSolverSave( rData );
}
+ScSheetSaveData* ScDocShell::GetSheetSaveData()
+{
+ if (!pSheetSaveData)
+ pSheetSaveData = new ScSheetSaveData;
+
+ return pSheetSaveData;
+}
+
+void ScDocShell::UseSheetSaveEntries()
+{
+ if (pSheetSaveData)
+ {
+ pSheetSaveData->UseSaveEntries(); // use positions from saved file for next saving
+
+ bool bHasEntries = false;
+ SCTAB nTabCount = aDocument.GetTableCount();
+ SCTAB nTab;
+ for (nTab = 0; nTab < nTabCount; ++nTab)
+ if (pSheetSaveData->HasStreamPos(nTab))
+ bHasEntries = true;
+
+ if (!bHasEntries)
+ {
+ // if no positions were set (for example, export to other format),
+ // reset all "valid" flags
+
+ for (nTab = 0; nTab < nTabCount; ++nTab)
+ if (aDocument.IsStreamValid(nTab))
+ aDocument.SetStreamValid(nTab, FALSE);
+ }
+ }
+}
+
// --- ScDocShellModificator ------------------------------------------
ScDocShellModificator::ScDocShellModificator( ScDocShell& rDS )
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index d4df2863eec5..80b0c76a64be 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1300,6 +1300,13 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ )
aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) );
aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+ // use hard recalc also to disable stream-copying of all sheets
+ // (somewhat consistent with charts)
+ SCTAB nTabCount = aDocument.GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (aDocument.IsStreamValid(nTab))
+ aDocument.SetStreamValid(nTab, FALSE);
+
PostPaintGridAll();
}
diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx
index b8d89a644fb4..b7c726deeb71 100644
--- a/sc/source/ui/docshell/docsh5.cxx
+++ b/sc/source/ui/docshell/docsh5.cxx
@@ -406,6 +406,7 @@ void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore )
{
BOOL bIsUndoEnabled = aDocument.IsUndoEnabled();
aDocument.EnableUndo( FALSE );
+ aDocument.LockStreamValid( true ); // ignore draw page size (but not formula results)
if ( bBefore ) // check all sheets up to nUpdateTab
{
SCTAB nTabCount = aDocument.GetTableCount();
@@ -437,6 +438,7 @@ void ScDocShell::UpdatePendingRowHeights( SCTAB nUpdateTab, bool bBefore )
aDocument.SetPendingRowHeights( nUpdateTab, FALSE );
}
}
+ aDocument.LockStreamValid( false );
aDocument.EnableUndo( bIsUndoEnabled );
}
diff --git a/sc/source/ui/drawfunc/futext3.cxx b/sc/source/ui/drawfunc/futext3.cxx
index 701a53aecfcc..2152abfd4f8b 100644
--- a/sc/source/ui/drawfunc/futext3.cxx
+++ b/sc/source/ui/drawfunc/futext3.cxx
@@ -110,6 +110,9 @@ void FuText::StopEditMode(BOOL /*bTextDirection*/)
}
}
+ if( pNote )
+ rDoc.LockStreamValid(true); // only the affected sheet is invalidated below
+
/* SdrObjEditView::SdrEndTextEdit() may try to delete the entire drawing
object, if it does not contain text and has invisible border and fill.
This must not happen for note caption objects. They will be removed
@@ -183,6 +186,11 @@ void FuText::StopEditMode(BOOL /*bTextDirection*/)
pAction->SetComment( ScGlobal::GetRscString( bNewNote ? STR_UNDO_INSERTNOTE : STR_UNDO_DELETENOTE ) );
}
}
+
+ // invalidate stream positions only for the affected sheet
+ rDoc.LockStreamValid(false);
+ if (rDoc.IsStreamValid(aNotePos.Tab()))
+ rDoc.SetStreamValid(aNotePos.Tab(), FALSE);
}
}
diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx
index 4e6cf05ddd0d..9556b4ad8138 100644
--- a/sc/source/ui/inc/docsh.hxx
+++ b/sc/source/ui/inc/docsh.hxx
@@ -72,6 +72,7 @@ class VirtualDevice;
class ScImportOptions;
class ScDocShellModificator;
class ScOptSolverSave;
+class ScSheetSaveData;
namespace sfx2 { class FileDialogHelper; }
struct DocShell_Impl;
@@ -123,6 +124,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
ScPaintLockData* pPaintLockData;
ScJobSetup* pOldJobSetup;
ScOptSolverSave* pSolverSaveData;
+ ScSheetSaveData* pSheetSaveData;
ScDocShellModificator* pModificator; // #109979#; is used to load XML (created in BeforeXMLLoading and destroyed in AfterXMLLoading)
@@ -167,6 +169,8 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener
SC_DLLPRIVATE void EnableSharedSettings( bool bEnable );
SC_DLLPRIVATE ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > LoadSharedDocument();
+ SC_DLLPRIVATE void UseSheetSaveEntries();
+
protected:
virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
@@ -414,6 +418,8 @@ public:
const ScOptSolverSave* GetSolverSaveData() const { return pSolverSaveData; } // may be null
void SetSolverSaveData( const ScOptSolverSave& rData );
+
+ ScSheetSaveData* GetSheetSaveData();
};
SO2_DECL_REF(ScDocShell)
diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx
index a4370f6665fb..ec706252a737 100644
--- a/sc/source/ui/unoobj/docuno.cxx
+++ b/sc/source/ui/unoobj/docuno.cxx
@@ -289,6 +289,13 @@ void ScModelObj::AfterXMLLoading(sal_Bool bRet)
pDocShell->AfterXMLLoading(bRet);
}
+ScSheetSaveData* ScModelObj::GetSheetSaveData()
+{
+ if (pDocShell)
+ return pDocShell->GetSheetSaveData();
+ return NULL;
+}
+
uno::Any SAL_CALL ScModelObj::queryInterface( const uno::Type& rType )
throw(uno::RuntimeException)
{
diff --git a/sc/source/ui/unoobj/textuno.cxx b/sc/source/ui/unoobj/textuno.cxx
index bd481dfc49f0..a9e6a799e010 100644
--- a/sc/source/ui/unoobj/textuno.cxx
+++ b/sc/source/ui/unoobj/textuno.cxx
@@ -897,6 +897,47 @@ uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::
return xRange;
}
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+// static
+const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+// static
+ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScDrawTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
//------------------------------------------------------------------------
ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
diff --git a/sc/source/ui/view/formatsh.cxx b/sc/source/ui/view/formatsh.cxx
index b2f3e12d1ee6..36f6c682832f 100644
--- a/sc/source/ui/view/formatsh.cxx
+++ b/sc/source/ui/view/formatsh.cxx
@@ -824,6 +824,11 @@ void __EXPORT ScFormatShell::ExecuteStyle( SfxRequest& rReq )
bNumFormatChanged, aOldSet, rNewSet ) )
pDoc->InvalidateTextWidth( NULL, NULL, bNumFormatChanged );
+ SCTAB nTabCount = pDoc->GetTableCount();
+ for (SCTAB nTab=0; nTab<nTabCount; nTab++)
+ if (pDoc->IsStreamValid(nTab))
+ pDoc->SetStreamValid(nTab, FALSE);
+
ULONG nOldFormat = ((const SfxUInt32Item&)aOldSet.
Get( ATTR_VALUE_FORMAT )).GetValue();
ULONG nNewFormat = ((const SfxUInt32Item&)rNewSet.