[ooo-build-commit] Branch 'ooo/OOO310' - sc/inc sc/source

Jan Holesovsky kendy at kemper.freedesktop.org
Tue Jun 9 17:09:42 PDT 2009


 sc/inc/brdcst.hxx                        |    1 
 sc/inc/compiler.hxx                      |    3 -
 sc/inc/externalrefmgr.hxx                |    4 +-
 sc/inc/global.hxx                        |   19 ++++++------
 sc/source/core/data/column3.cxx          |   47 +++++++++++++++++++++++++++----
 sc/source/core/data/documen8.cxx         |   13 ++++++++
 sc/source/core/data/document.cxx         |   12 ++++++-
 sc/source/core/data/dpobject.cxx         |    5 +--
 sc/source/core/tool/token.cxx            |    3 +
 sc/source/filter/xml/xmlexternaltabi.cxx |   45 +++++++++++++++++++++++++++++
 sc/source/filter/xml/xmlexternaltabi.hxx |   24 +++++++++++++++
 sc/source/filter/xml/xmltabi.cxx         |    6 +++
 sc/source/ui/docshell/docfunc.cxx        |    8 +++--
 sc/source/ui/docshell/docsh.cxx          |    2 +
 sc/source/ui/docshell/docsh4.cxx         |    8 +++++
 sc/source/ui/docshell/externalrefmgr.cxx |   31 ++++++++++++++++----
 sc/source/ui/unoobj/cellsuno.cxx         |    8 +++++
 sc/source/ui/unoobj/chart2uno.cxx        |   10 ++++++
 18 files changed, 218 insertions(+), 31 deletions(-)

New commits:
commit 2501b623374cbbc0b1ea151fb3bb7b18237857ae
Author: Oliver Bolte <obo at openoffice.org>
Date:   Tue Jun 9 06:07:51 2009 +0000

    CWS-TOOLING: integrate CWS calc311fixes
    2009-05-26 16:43:50 +0200 nn  r272311 : patch flags
    2009-05-26 15:20:08 +0200 nn  r272306 : CWS-TOOLING: rebase CWS calc311fixes to branches/OOO310 at 272261 (milestone: OOO310:m12)
    2009-05-26 13:39:20 +0200 nn  r272298 : #i101960# UpdateExternalRefLinks: set document modified
    2009-05-20 20:02:01 +0200 dr  r272148 : #i102056# drag and drop of note cells loses cell contents
    2009-05-19 17:37:04 +0200 nn  r272091 : #i101273# #i101304# #i101319# copied from CWS calclinkfixes
    2009-05-13 18:46:19 +0200 nn  r271869 : #i101690# copied from CWS calc50
    2009-05-13 17:45:18 +0200 nn  r271867 : #i101869# DeleteRange: before broadcasting, check if EndListening removed the note cells
    2009-05-11 18:44:54 +0200 nn  r271784 : #i101725# don't copy hash_set with pointers from the other collection
    2009-05-11 18:39:33 +0200 nn  r271782 : #i101512# copied from CWS calc50
    2009-05-11 18:39:22 +0200 nn  r271781 : #i101512# copied from CWS calc50

diff --git a/sc/inc/brdcst.hxx b/sc/inc/brdcst.hxx
index 06b9677..3d4f7f1 100644
--- a/sc/inc/brdcst.hxx
+++ b/sc/inc/brdcst.hxx
@@ -40,6 +40,7 @@ class ScBaseCell;
 #define SC_HINT_DYING		SFX_HINT_DYING
 #define SC_HINT_DATACHANGED	SFX_HINT_DATACHANGED
 #define SC_HINT_TABLEOPDIRTY	SFX_HINT_USER00
+#define SC_HINT_CALCALL         SFX_HINT_USER01
 
 class ScHint : public SfxSimpleHint
 {
diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index f960498..2140998 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -358,8 +358,7 @@ public:
     bool IsEnglishSymbol( const String& rName ); 
 
     //! _either_ CompileForFAP _or_ AutoCorrection, _not_ both
-    void            SetCompileForFAP( BOOL bVal )
-                        { bCompileForFAP = bVal; bIgnoreErrors = bVal; }
+    // #i101512# SetCompileForFAP is in formula::FormulaCompiler
     void            SetAutoCorrection( BOOL bVal )
                         { bAutoCorrect = bVal; bIgnoreErrors = bVal; }
     void            SetCloseBrackets( bool bVal ) { mbCloseBrackets = bVal; }
diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx
index dfb8145..1ca3bac 100644
--- a/sc/inc/externalrefmgr.hxx
+++ b/sc/inc/externalrefmgr.hxx
@@ -173,7 +173,7 @@ public:
      */
     ScExternalRefCache::TokenRef getCellData(
         sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow,
-        bool bEmptyCellOnNull, sal_uInt32* pnFmtIndex = NULL);
+        bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex);
 
     /**
      * Get a cached cell range data.
@@ -183,7 +183,7 @@ public:
      *         guaranteed if the TokenArrayRef is properly used..
      */
     ScExternalRefCache::TokenArrayRef getCellRangeData(
-        sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull);
+        sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty);
 
     ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName);
     void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray);
diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx
index 96fa9d4..a3ede77 100644
--- a/sc/inc/global.hxx
+++ b/sc/inc/global.hxx
@@ -238,6 +238,7 @@ const USHORT IDF_ATTRIB     = IDF_HARDATTR | IDF_STYLES;
 const USHORT IDF_CONTENTS   = IDF_VALUE | IDF_DATETIME | IDF_STRING | IDF_NOTE | IDF_FORMULA;
 const USHORT IDF_ALL        = IDF_CONTENTS | IDF_ATTRIB | IDF_OBJECTS;
 const USHORT IDF_NOCAPTIONS = 0x0200;   /// Internal use only (undo etc.): do not copy/delete caption objects of cell notes.
+const USHORT IDF_ADDNOTES   = 0x0400;   /// Internal use only (copy from clip): do not delete existing cell contents when pasting notes.
 
 /// Copy flags for auto/series fill functions: do not touch notes and drawing objects.
 const USHORT IDF_AUTOFILL   = IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS);
@@ -661,29 +662,29 @@ public:
     SC_DLLPUBLIC static bool             IsQuoted( const String& rString, sal_Unicode cQuote = '\'' );
 
     /** Inserts the character cQuote at beginning and end of rString.
-        @param bEscapeEmbedded      If <TRUE/>, embedded quote characters are 
+        @param bEscapeEmbedded      If <TRUE/>, embedded quote characters are
                                     escaped by doubling them.
      */
 SC_DLLPUBLIC    static void             AddQuotes( String& rString, sal_Unicode cQuote = '\'', bool bEscapeEmbedded = true );
 
     /** Erases the character cQuote from rString, if it exists at beginning AND end.
-        @param bUnescapeEmbedded    If <TRUE/>, embedded doubled quote characters 
-                                    are unescaped by replacing them with a 
+        @param bUnescapeEmbedded    If <TRUE/>, embedded doubled quote characters
+                                    are unescaped by replacing them with a
                                     single instance.
      */
 SC_DLLPUBLIC    static void             EraseQuotes( String& rString, sal_Unicode cQuote = '\'', bool bUnescapeEmbedded = true );
 
-    /** Finds an unquoted instance of cChar in rString, starting at 
-        offset nStart. Unquoted instances may occur when concatenating two 
-        quoted strings with a separator, for example, 's1':'s2'. Embedded 
-        quotes have to be escaped by being doubled. Caller must ensure that 
-        nStart points into an unquoted range or the opening quote. Specialty: 
+    /** Finds an unquoted instance of cChar in rString, starting at
+        offset nStart. Unquoted instances may occur when concatenating two
+        quoted strings with a separator, for example, 's1':'s2'. Embedded
+        quotes have to be escaped by being doubled. Caller must ensure that
+        nStart points into an unquoted range or the opening quote. Specialty:
         if cChar==cQuote the first cQuote character from nStart on is found.
         @returns offset if found, else STRING_NOTFOUND
      */
 SC_DLLPUBLIC    static xub_StrLen       FindUnquoted( const String& rString, sal_Unicode cChar, xub_StrLen nStart = 0, sal_Unicode cQuote = '\'' );
 
-    /** Finds an unquoted instance of cChar in null-terminated pString. Same 
+    /** Finds an unquoted instance of cChar in null-terminated pString. Same
         semantics as FindUnquoted( const String&, ...)
         @returns: pointer to cChar if found, else NULL
      */
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index da22ea3..c8a1384 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -521,6 +521,15 @@ void ScColumn::DeleteRange( SCSIZE nStartIndex, SCSIZE nEndIndex, USHORT nDelFla
     for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
         (*aIt)->EndListeningTo( pDocument );
 
+    // #i101869# if the note cell with the broadcaster was deleted in EndListening,
+    // forget the pointer to the broadcaster
+    for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
+    {
+        SCSIZE nIndex;
+        if ( !Search( (*aIt)->aPos.Row(), nIndex ) )
+            (*aIt)->ReleaseBroadcaster();
+    }
+
     // broadcast SC_HINT_DYING for all cells and delete them
     for ( FormulaCellVector::iterator aIt = aDelCells.begin(), aEnd = aDelCells.end(); aIt != aEnd; ++aIt )
     {
@@ -739,6 +748,9 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
             Resize( nNew );
     }
 
+    // IDF_ADDNOTES must be passed without other content flags than IDF_NOTE
+    bool bAddNotes = (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES);
+
     BOOL bAtEnd = FALSE;
     for (SCSIZE i = 0; i < nColCount && !bAtEnd; i++)
     {
@@ -751,12 +763,37 @@ void ScColumn::CopyFromClip(SCROW nRow1, SCROW nRow2, long nDy,
             //	nDestRow may be negative then
 
             ScAddress aDestPos( nCol, (SCROW)nDestRow, nTab );
-            ScBaseCell* pNew = bAsLink ?
-                rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) :
-                rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos );
 
-            if (pNew)
-                Insert((SCROW)nDestRow, pNew);
+            /*  #i102056# Paste from clipboard needs to paste the cell notes in
+                a second pass. This must not overwrite the existing cells
+                already copied to the destination position in the first pass.
+                To indicate this special case, the modifier IDF_ADDNOTES is
+                passed together with IDF_NOTE in nInsFlag. Of course, there is
+                still the need to create a new cell, if there is no cell at the
+                destination position at all. */
+            ScBaseCell* pAddNoteCell = bAddNotes ? GetCell( aDestPos.Row() ) : 0;
+            if (pAddNoteCell)
+            {
+                // do nothing if source cell does not contain a note
+                const ScBaseCell* pSourceCell = rColumn.pItems[i].pCell;
+                const ScPostIt* pSourceNote = pSourceCell ? pSourceCell->GetNote() : 0;
+                if (pSourceNote)
+                {
+                    DBG_ASSERT( !pAddNoteCell->HasNote(), "ScColumn::CopyFromClip - unexpected note at destination cell" );
+                    bool bCloneCaption = (nInsFlag & IDF_NOCAPTIONS) == 0;
+                    // #i52342# if caption is cloned, the note must be constructed with the destination document
+                    ScPostIt* pNewNote = ScNoteUtil::CloneNote( *pDocument, aDestPos, *pSourceNote, bCloneCaption );
+                    pAddNoteCell->TakeNote( pNewNote );
+                }
+            }
+            else
+            {
+                ScBaseCell* pNewCell = bAsLink ?
+                    rColumn.CreateRefCell( pDocument, aDestPos, i, nInsFlag ) :
+                    rColumn.CloneCell( i, nInsFlag, *pDocument, aDestPos );
+                if (pNewCell)
+                    Insert( aDestPos.Row(), pNewCell );
+            }
         }
     }
 }
diff --git a/sc/source/core/data/documen8.cxx b/sc/source/core/data/documen8.cxx
index 2e617d7..19d6d94 100644
--- a/sc/source/core/data/documen8.cxx
+++ b/sc/source/core/data/documen8.cxx
@@ -44,6 +44,7 @@
 #include <svx/linkmgr.hxx>
 #include <svx/scripttypeitem.hxx>
 #include <svx/unolingu.hxx>
+#include <sfx2/bindings.hxx>
 #include <sfx2/objsh.hxx>
 #include <sfx2/printer.hxx>
 #include <sfx2/viewfrm.hxx>
@@ -1046,6 +1047,18 @@ void ScDocument::UpdateExternalRefLinks()
         TrackFormulas();
         pShell->Broadcast( SfxSimpleHint(FID_DATACHANGED) );
         ResetChanged( ScRange(0, 0, 0, MAXCOL, MAXROW, MAXTAB) );
+
+        // #i101960# set document modified, as in TrackTimeHdl for DDE links
+        if (!pShell->IsModified())
+        {
+            pShell->SetModified( TRUE );
+            SfxBindings* pBindings = GetViewBindings();
+            if (pBindings)
+            {
+                pBindings->Invalidate( SID_SAVEDOC );
+                pBindings->Invalidate( SID_DOC_MODIFIED );
+            }
+        }
     }
 }
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 6baaf30..783e3d4 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1773,9 +1773,17 @@ void ScDocument::CopyFromClip( const ScRange& rDestRange, const ScMarkData& rMar
             nXw = sal::static_int_cast<SCCOL>( nXw + nDestAddX );
             nYw = sal::static_int_cast<SCROW>( nYw + nDestAddY );   // ClipArea, plus ExtendMerge value
 
-            //	Inhalte entweder komplett oder gar nicht loeschen:
+            /*  Decide which contents to delete before copying. Delete all
+                contents if nInsFlag contains any real content flag.
+                #i102056# Notes are pasted from clipboard in a second pass,
+                together with the special flag IDF_ADDNOTES that states to not
+                overwrite/delete existing cells but to insert the notes into
+                these cells. In this case, just delete old notes from the
+                destination area. */
             USHORT nDelFlag = IDF_NONE;
-            if ( nInsFlag & IDF_CONTENTS )
+            if ( (nInsFlag & (IDF_CONTENTS | IDF_ADDNOTES)) == (IDF_NOTE | IDF_ADDNOTES) )
+                nDelFlag |= IDF_NOTE;
+            else if ( nInsFlag & IDF_CONTENTS )
                 nDelFlag |= IDF_CONTENTS;
             //	With bSkipAttrForEmpty, don't remove attributes, copy
             //	on top of existing attributes instead.
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 915f6b6..358f5e2 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -2345,7 +2345,7 @@ ScDPCollection::ScDPCollection(const ScDPCollection& r) :
     ScCollection(r),
     pDoc(r.pDoc),
     maSharedString(r.maSharedString),
-    maCacheCellPool(r.maCacheCellPool)
+    maCacheCellPool()   // #i101725# don't copy hash_set with pointers from the other collection
 {
 }
 
@@ -2507,8 +2507,9 @@ void ScDPCollection::clearCacheCellPool()
     vector<ScDPCacheCell*> ps;
     ps.reserve(maCacheCellPool.size());
     copy(maCacheCellPool.begin(), maCacheCellPool.end(), back_inserter(ps));
-    for_each(ps.begin(), ps.end(), DeleteCacheCells());
     maCacheCellPool.clear();
+    // for correctness' sake, delete the elements after clearing the hash_set
+    for_each(ps.begin(), ps.end(), DeleteCacheCells());
 }
 
 //------------------------------------------------------------------------
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index e13d855..6571a07 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -1821,8 +1821,11 @@ void ScTokenArray::ReadjustRelative3DReferences( const ScAddress& rOldPos,
             case svSingleRef :
             {
                 ScSingleRefData& rRef1 = static_cast<ScToken*>(pCode[j])->GetSingleRef();
+                if ( rRef1.IsFlag3D() )
+                {
                     rRef1.CalcAbsIfRel( rOldPos );
                     rRef1.CalcRelFromAbs( rNewPos );
+                }
             }
             break;
             default:
diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx
index a79b379..ca94d26 100644
--- a/sc/source/filter/xml/xmlexternaltabi.cxx
+++ b/sc/source/filter/xml/xmlexternaltabi.cxx
@@ -114,6 +114,49 @@ void ScXMLExternalRefTabSourceContext::EndElement()
 
 // ============================================================================
 
+ScXMLExternalRefRowsContext::ScXMLExternalRefRowsContext(
+    ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
+    const Reference<XAttributeList>& /* xAttrList */, ScXMLExternalTabData& rRefInfo ) :
+    SvXMLImportContext( rImport, nPrefix, rLName ),
+    mrScImport(rImport),
+    mrExternalRefInfo(rRefInfo)
+{
+}
+
+ScXMLExternalRefRowsContext::~ScXMLExternalRefRowsContext()
+{
+}
+
+SvXMLImportContext* ScXMLExternalRefRowsContext::CreateChildContext(
+    USHORT nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
+{
+    // #i101319# row elements inside group, rows or header-rows
+    // are treated like row elements directly in the table element
+
+    const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowsElemTokenMap();
+    sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
+    switch (nToken)
+    {
+        case XML_TOK_TABLE_ROWS_ROW_GROUP:
+        case XML_TOK_TABLE_ROWS_HEADER_ROWS:
+        case XML_TOK_TABLE_ROWS_ROWS:
+            return new ScXMLExternalRefRowsContext(
+                mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+        case XML_TOK_TABLE_ROWS_ROW:
+            return new ScXMLExternalRefRowContext(
+                mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
+        default:
+            ;
+    }
+    return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
+}
+
+void ScXMLExternalRefRowsContext::EndElement()
+{
+}
+
+// ============================================================================
+
 ScXMLExternalRefRowContext::ScXMLExternalRefRowContext(
     ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName,
     const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
@@ -153,7 +196,7 @@ SvXMLImportContext* ScXMLExternalRefRowContext::CreateChildContext(
 {
     const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap();
     sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
-    if (nToken == XML_TOK_TABLE_ROW_CELL)
+    if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL)
         return new ScXMLExternalRefCellContext(mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
 
     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
diff --git a/sc/source/filter/xml/xmlexternaltabi.hxx b/sc/source/filter/xml/xmlexternaltabi.hxx
index 2174c30..6ece1ad 100644
--- a/sc/source/filter/xml/xmlexternaltabi.hxx
+++ b/sc/source/filter/xml/xmlexternaltabi.hxx
@@ -65,6 +65,30 @@ private:
 
 // ============================================================================
 
+class ScXMLExternalRefRowsContext : public SvXMLImportContext
+{
+public:
+    ScXMLExternalRefRowsContext( ScXMLImport& rImport, USHORT nPrefix,
+                        const ::rtl::OUString& rLName,
+                        const ::com::sun::star::uno::Reference<
+                                        ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
+                        ScXMLExternalTabData& rRefInfo );
+
+    virtual ~ScXMLExternalRefRowsContext();
+
+    virtual SvXMLImportContext *CreateChildContext( USHORT nPrefix,
+                                     const ::rtl::OUString& rLocalName,
+                                     const ::com::sun::star::uno::Reference<
+                                        ::com::sun::star::xml::sax::XAttributeList>& xAttrList );
+
+    virtual void EndElement();
+private:
+    ScXMLImport&            mrScImport;
+    ScXMLExternalTabData&   mrExternalRefInfo;
+};
+
+// ============================================================================
+
 class ScXMLExternalRefRowContext : public SvXMLImportContext
 {
 public:
diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx
index eec8423..b057f1b 100644
--- a/sc/source/filter/xml/xmltabi.cxx
+++ b/sc/source/filter/xml/xmltabi.cxx
@@ -235,6 +235,12 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix,
         // external cache data.
         switch (nToken)
         {
+            case XML_TOK_TABLE_ROW_GROUP:
+            case XML_TOK_TABLE_HEADER_ROWS:
+            case XML_TOK_TABLE_ROWS:
+                // #i101319# don't discard rows in groups or header (repeat range)
+                return new ScXMLExternalRefRowsContext(
+                    GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
             case XML_TOK_TABLE_ROW:
                 return new ScXMLExternalRefRowContext(
                     GetScImport(), nPrefix, rLName, xAttrList, *pExternalRefInfo);
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 5c15f29..2f7ce1b 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -2165,9 +2165,13 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
 
     /*  Paste cell notes and drawing objects after adjusting formula references
         and row heights. There are no cell notes or drawing objects, if the
-        clipdoc does not contain a drawing layer. */
+        clipdoc does not contain a drawing layer.
+        #i102056# Passing IDF_NOTE only would overwrite cell contents with
+        empty note cells, therefore the special modifier IDF_ADDNOTES is passed
+        here too which changes the behaviour of ScColumn::CopyFromClip() to not
+        touch existing cells. */
     if ( pClipDoc->GetDrawLayer() )
-        pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_OBJECTS,
+        pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS,
                             pRefUndoDoc, pClipDoc, TRUE, FALSE, bIncludeFiltered );
 
     if (bRecord)
diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index 2785abf..24fec26 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -283,6 +283,7 @@ void ScDocShell::BeforeXMLLoading()
     pModificator = new ScDocShellModificator( *this );
 
     aDocument.SetImportingXML( TRUE );
+    aDocument.EnableExecuteLink( false );   // #i101304# to be safe, prevent nested loading from external references
     aDocument.EnableUndo( FALSE );
     // prevent unnecessary broadcasts and "half way listeners"
     aDocument.SetInsertingFromOtherDoc( TRUE );
@@ -363,6 +364,7 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet)
         aDocument.SetInsertingFromOtherDoc( FALSE );
 
     aDocument.SetImportingXML( FALSE );
+    aDocument.EnableExecuteLink( true );
     aDocument.EnableUndo( TRUE );
     bIsEmpty = FALSE;
 
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 7ede02d..010246e 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -1266,6 +1266,8 @@ void ScDocShell::DoRecalc( BOOL bApi )
         if ( pSh )
             pSh->UpdateCharts(TRUE);
 
+        aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
         //	#47939# Wenn es Charts gibt, dann alles painten, damit nicht
         //	PostDataChanged und die Charts nacheinander kommen und Teile
         //	doppelt gepainted werden.
@@ -1291,6 +1293,12 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ )
     GetDocFunc().DetectiveRefresh();	// erzeugt eigenes Undo
     if ( pSh )
         pSh->UpdateCharts(TRUE);
+
+    // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally
+    // in addition to SFX_HINT_DATACHANGED.
+    aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) );
+    aDocument.BroadcastUno( SfxSimpleHint( SFX_HINT_DATACHANGED ) );
+
     PostPaintGridAll();
 }
 
diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx
index 8634ea4..7032b2d 100644
--- a/sc/source/ui/docshell/externalrefmgr.cxx
+++ b/sc/source/ui/docshell/externalrefmgr.cxx
@@ -328,7 +328,7 @@ const String* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const Str
 
 ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
     sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, 
-    bool bEmptyCellOnNull, sal_uInt32* pnFmtIndex)
+    bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex)
 {
     DocDataType::const_iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
@@ -355,12 +355,16 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData(
 
     TokenRef pToken = pTableData->getCell(nCol, nRow, pnFmtIndex);
     if (!pToken && bEmptyCellOnNull)
+    {
         pToken.reset(new ScEmptyCellToken(false, false));
+        if (bWriteEmpty)
+            pTableData->setCell(nCol, nRow, pToken);
+    }
     return pToken;
 }
 
 ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
-    sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull)
+    sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty)
 {
     DocDataType::iterator itrDoc = maDocs.find(nFileId);
     if (itrDoc == maDocs.end())
@@ -413,7 +417,11 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData(
                 if (!pToken)
                 {
                     if (bEmptyCellOnNull)
+                    {
                         pToken.reset(new ScEmptyCellToken(false, false));
+                        if (bWriteEmpty)
+                            pTab->setCell(nCol, nRow, pToken);
+                    }
                     else
                         return TokenArrayRef();
                 }
@@ -1504,10 +1512,18 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
     if (pFmt)
         pFmt->mbIsSet = false;
 
+    bool bLoading = mpDoc->IsImportingXML();
+
     // Check if the given table name and the cell position is cached.
+    // #i101304# When loading a file, the saved cache (hidden sheet)
+    // is assumed to contain all data for the loaded formulas.
+    // No cache entries are created from empty cells in the saved sheet,
+    // so they have to be created here (bWriteEmpty parameter).
+    // Otherwise, later interpretation of the loaded formulas would
+    // load the source document even if the user didn't want to update.
     sal_uInt32 nFmtIndex = 0;
     ScExternalRefCache::TokenRef pToken = maRefCache.getCellData(
-        nFileId, rTabName, rCell.Col(), rCell.Row(), false, &nFmtIndex);
+        nFileId, rTabName, rCell.Col(), rCell.Row(), bLoading, bLoading, &nFmtIndex);
     if (pToken)
     {
         if (pFmt)
@@ -1531,7 +1547,7 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken(
         // once again, but this time treat a non-cached cell as an empty cell
         // as long as the table itself is cached.
         pToken = maRefCache.getCellData(
-            nFileId, rTabName, rCell.Col(), rCell.Row(), true, &nFmtIndex);
+            nFileId, rTabName, rCell.Col(), rCell.Row(), true, false, &nFmtIndex);
         return pToken;
     }
 
@@ -1580,8 +1596,11 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_u
 
     maybeLinkExternalFile(nFileId);
 
+    bool bLoading = mpDoc->IsImportingXML();
+
     // Check if the given table name and the cell position is cached.
-    ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange, false);
+    // #i101304# When loading, put empty cells into cache, see getSingleRefToken.
+    ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange, bLoading, bLoading);
     if (p.get())
         return p;
 
@@ -1591,7 +1610,7 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_u
         // Source document is not reachable.  Try to get data from the cache 
         // once again, but this time treat non-cached cells as empty cells as
         // long as the table itself is cached.
-        return maRefCache.getCellRangeData(nFileId, rTabName, rRange, true);
+        return maRefCache.getCellRangeData(nFileId, rTabName, rRange, true, false);
     }
 
     SCTAB nTab1;
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index d1631ad..74b51c1 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -1619,6 +1619,14 @@ void ScCellRangesBase::Notify( SfxBroadcaster&, const SfxHint& rHint )
                 bGotDataChangedHint = FALSE;
             }
         }
+        else if ( nId == SC_HINT_CALCALL )
+        {
+            // broadcast from DoHardRecalc - set bGotDataChangedHint
+            // (SFX_HINT_DATACHANGED follows separately)
+
+            if ( aValueListeners.Count() )
+                bGotDataChangedHint = TRUE;
+        }
     }
     else if ( rHint.ISA( ScUnoRefUndoHint ) )
     {
diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx
index 2864537..cb75b82 100644
--- a/sc/source/ui/unoobj/chart2uno.cxx
+++ b/sc/source/ui/unoobj/chart2uno.cxx
@@ -2803,8 +2803,10 @@ void ScChart2DataSequence::BuildDataCache()
                                     break;
     
                                 if (pFCell->HasValueData())
+                                {
                                     rItem.mfValue = pFCell->GetValue();
                                     rItem.mbIsValue = true;
+                                }
                             }
                             break;
 #if DBG_UTIL
@@ -3035,6 +3037,14 @@ void ScChart2DataSequence::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint
                 m_bGotDataChangedHint = false;
             }
         }
+        else if ( nId == SC_HINT_CALCALL )
+        {
+            // broadcast from DoHardRecalc - set m_bGotDataChangedHint
+            // (SFX_HINT_DATACHANGED follows separately)
+
+            if ( m_aValueListeners.Count() )
+                m_bGotDataChangedHint = true;
+        }
     }
     else if ( rHint.ISA( ScUpdateRefHint ) )
     {


More information about the ooo-build-commit mailing list