sc-overwrite-char-font-attrs.diff: overwrite character level font attributes

n#374580, i#53545, i#96853

Overwrite character level font attributes when changing them at cell level
diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx
index 11b21ba..c8bd4c3 100644
--- a/sc/inc/attarray.hxx
+++ b/sc/inc/attarray.hxx
@@ -32,6 +32,7 @@
#include "attrib.hxx"

class ScDocument;
class ScEditDataArray;
class ScMarkArray;
class ScPatternAttr;
class ScStyleSheet;
@@ -102,6 +103,9 @@ friend void lcl_IterGetNumberFormat( ULONG& nFormat,
                            SCROW nStartRow, SCROW nEndRow,
                            BOOL bLeft, SCCOL nDistRight, BOOL bTop, SCROW nDistBottom );

    void RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow,
                              const ScPatternAttr* pPattern, ScEditDataArray* pDataArray );

public:
            ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, ScDocument* pDoc );
            ~ScAttrArray();
@@ -124,9 +128,11 @@ public:
                            SCROW nStartRow, SCROW nEndRow, BOOL bLeft, SCCOL nDistRight );

    void    SetPattern( SCROW nRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE );
    void    SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern, BOOL bPutToPool = FALSE);
    void    SetPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr* pPattern,
                            BOOL bPutToPool = FALSE, ScEditDataArray* pDataArray = NULL );
    void    ApplyStyleArea( SCROW nStartRow, SCROW nEndRow, ScStyleSheet* pStyle );
    void    ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache );
    void    ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache,
                            ScEditDataArray* pDataArray = NULL );
    void    ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
                                const SvxBorderLine* pLine, BOOL bColorOnly );

diff --git a/sc/inc/cell.hxx b/sc/inc/cell.hxx
index ad9ed02..fcedbbb0 100644
--- a/sc/inc/cell.hxx
+++ b/sc/inc/cell.hxx
@@ -31,6 +31,9 @@
#include <stddef.h>

#include <set>
#include <vector>
#include <boost/shared_ptr.hpp>

#include <tools/mempool.hxx>
#include <svl/listener.hxx>
#include "global.hxx"
@@ -56,6 +59,7 @@ class SvtBroadcaster;
class ScCodeArray;
class ScProgress;
class ScPostIt;
class ScPatternAttr;

// ============================================================================

@@ -276,6 +280,53 @@ public:
    void            GetString( String& rString ) const;

    const EditTextObject* GetData() const   { return pData; }

    /** Removes character attribute based on new pattern attributes. */
    void            RemoveCharAttribs( const ScPatternAttr& rAttr );
};

// ============================================================================

class ScEditDataArray
{
public:
    class Item
    {
    public:
        explicit Item(SCTAB nTab, SCCOL nCol, SCROW nRow,
                      EditTextObject* pOldData, EditTextObject* pNewData);
        ~Item();

        const EditTextObject* GetOldData() const;
        const EditTextObject* GetNewData() const;
        SCTAB GetTab() const;
        SCCOL GetCol() const;
        SCROW GetRow() const;

    private:
        Item(); // disabled

    private:
        ::boost::shared_ptr<EditTextObject> mpOldData;
        ::boost::shared_ptr<EditTextObject> mpNewData;
        SCTAB mnTab;
        SCCOL mnCol;
        SCROW mnRow;

    };

    ScEditDataArray();
    ~ScEditDataArray();

    void AddItem(SCTAB nTab, SCCOL nCol, SCROW nRow,
                 EditTextObject* pOldData, EditTextObject* pNewData);

    const Item* First();
    const Item* Next();

private:
    ::std::vector<Item>::const_iterator maIter;
    ::std::vector<Item> maArray;
};

// ============================================================================
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index af6292b..1a021dc 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -53,6 +53,7 @@ class ScAttrIterator;
class ScAttrArray;
class ScBaseCell;
class ScDocument;
class ScEditDataArray;
class ScFormulaCell;
class ScMarkData;
class ScPatternAttr;
@@ -311,7 +312,8 @@ public:

    void        ApplyAttr( SCROW nRow, const SfxPoolItem& rAttr );
    void        ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr );
    void        ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr );
    void        ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr,
                                  ScEditDataArray* pDataArray = NULL );
    void        SetPattern( SCROW nRow, const ScPatternAttr& rPatAttr, BOOL bPutToPool = FALSE );
    void        SetPatternArea( SCROW nStartRow, SCROW nEndRow,
                                const ScPatternAttr& rPatAttr, BOOL bPutToPool = FALSE );
@@ -343,7 +345,7 @@ public:

    void        RemoveProtected( SCROW nStartRow, SCROW nEndRow );

    SCsROW      ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark );
    SCsROW      ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray = NULL );
    void        DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark );

    void        ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark );
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 5c46852..f393b67 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1206,7 +1206,8 @@ public:
                                    const ScPatternAttr& rAttr );
    SC_DLLPUBLIC void           ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow,
                                        SCCOL nEndCol, SCROW nEndRow,
                                        const ScMarkData& rMark, const ScPatternAttr& rAttr );
                                        const ScMarkData& rMark, const ScPatternAttr& rAttr,
                                        ScEditDataArray* pDataArray = NULL );
    SC_DLLPUBLIC void           ApplyPatternAreaTab( SCCOL nStartCol, SCROW nStartRow,
                                            SCCOL nEndCol, SCROW nEndRow, SCTAB nTab,
                                            const ScPatternAttr& rAttr );
@@ -1268,7 +1269,8 @@ public:
                            SCCOL nVCol, SCROW nVRow, SCTAB nVTab,
                            const String& sValStr, double& nX);

    void            ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark );
    void            ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark,
                                           ScEditDataArray* pDataArray = NULL );
    void            DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark );
    void            DeleteSelectionTab( SCTAB nTab, USHORT nDelFlag, const ScMarkData& rMark );

diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 63cefe2..aacce96 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -64,6 +64,7 @@ class ScAutoFormatData;
class ScBaseCell;
class ScDocument;
class ScDrawLayer;
class ScEditDataArray;
class ScFormulaCell;
class ScOutlineTable;
class ScPostIt;
@@ -536,7 +537,8 @@ public:

    void        ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr );
    void        ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr );
    void        ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, const ScPatternAttr& rAttr );
    void        ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
                                  const ScPatternAttr& rAttr, ScEditDataArray* pDataArray = NULL );
    void        SetPattern( const ScAddress& rPos, const ScPatternAttr& rAttr, BOOL bPutToPool = FALSE )
                    {
                        if (ValidColRow(rPos.Col(),rPos.Row()))
@@ -567,7 +569,7 @@ public:
    BOOL        ApplyFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, INT16 nFlags );
    BOOL        RemoveFlags( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, INT16 nFlags );

    void        ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark );
    void        ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray = NULL );
    void        DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark );

    void        ClearSelectionItems( const USHORT* pWhich, const ScMarkData& rMark );
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index f344331..9d784b3 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -38,6 +38,7 @@
#include <editeng/bolnitem.hxx>
#include <editeng/frmdiritem.hxx>
#include <editeng/shaditem.hxx>
#include <editeng/editobj.hxx>
#include <svl/poolcach.hxx>
#include <editeng/fontitem.hxx>
#include <unotools/fontcvt.hxx>
@@ -53,6 +54,7 @@
#include "rechead.hxx"
#include "globstr.hrc"
#include "segmenttree.hxx"
#include "cell.hxx"

#undef DBG_INVALIDATE
#define DBGOUTPUT(s) \
@@ -299,8 +301,31 @@ void ScAttrArray::SetPattern( SCROW nRow, const ScPatternAttr* pPattern, BOOL bP
    SetPatternArea( nRow, nRow, pPattern, bPutToPool );
}

void ScAttrArray::RemoveCellCharAttribs( SCROW nStartRow, SCROW nEndRow,
                                       const ScPatternAttr* pPattern, ScEditDataArray* pDataArray )
{
    for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow)
    {
        ScBaseCell* pCell;
        pDocument->GetCell(nCol, nRow, nTab, pCell);
        if (pCell && pCell->GetCellType() == CELLTYPE_EDIT)
        {
            EditTextObject* pOldData = NULL;
            ScEditCell* pEditCell = static_cast<ScEditCell*>(pCell);
            if (pDataArray)
                pOldData = pEditCell->GetData()->Clone();
            pEditCell->RemoveCharAttribs(*pPattern);
            if (pDataArray)
            {
                EditTextObject* pNewData = pEditCell->GetData()->Clone();
                pDataArray->AddItem(nTab, nCol, nRow, pOldData, pNewData);
            }
        }
    }
}

void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr *pPattern, BOOL bPutToPool )
void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPatternAttr *pPattern,
                                 BOOL bPutToPool, ScEditDataArray* pDataArray )
{
    if (ValidRow(nStartRow) && ValidRow(nEndRow))
    {
@@ -470,6 +495,12 @@ void ScAttrArray::SetPatternArea(SCROW nStartRow, SCROW nEndRow, const ScPattern
                    pData[nInsert-1].nRow = nStartRow - 1;
                pData[nInsert].nRow = nEndRow;
                pData[nInsert].pPattern = pPattern;

                // Remove character attributes from these cells if the pattern
                // is applied during normal session.
                if (pDataArray)
                    RemoveCellCharAttribs(nStartRow, nEndRow, pPattern, pDataArray);

                nCount++;
            }

@@ -711,7 +742,7 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, SCROW nEndRow,
#undef SET_LINE


void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache )
void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCache* pCache, ScEditDataArray* pDataArray )
{
#ifdef DBG_UTIL
    TestData();
@@ -746,7 +777,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW nEndRow, SfxItemPoolCac
                {
                    if (nY1 < nStartRow) nY1=nStartRow;
                    if (nY2 > nEndRow) nY2=nEndRow;
                    SetPatternArea( nY1, nY2, pNewPattern );
                    SetPatternArea( nY1, nY2, pNewPattern, false, pDataArray );
                    Search( nStart, nPos );
                }
                else
diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx
index 1aab26a..b3e3d2c 100644
--- a/sc/source/core/data/cell2.cxx
+++ b/sc/source/core/data/cell2.cxx
@@ -51,6 +51,8 @@
#include "editutil.hxx"
#include "chgtrack.hxx"
#include "externalrefmgr.hxx"
#include "scitems.hxx"
#include "patattr.hxx"

using namespace formula;

@@ -139,6 +141,28 @@ void ScEditCell::GetString( String& rString ) const
        rString.Erase();
}

void ScEditCell::RemoveCharAttribs( const ScPatternAttr& rAttr )
{
    const struct {
        USHORT nAttrType;
        USHORT nCharType;
    } AttrTypeMap[] = {
        { ATTR_FONT,        EE_CHAR_FONTINFO },
        { ATTR_FONT_HEIGHT, EE_CHAR_FONTHEIGHT },
        { ATTR_FONT_WEIGHT, EE_CHAR_WEIGHT },
        { ATTR_FONT_COLOR,  EE_CHAR_COLOR }
    };
    USHORT nMapCount = sizeof(AttrTypeMap) / sizeof(AttrTypeMap[0]);

    const SfxItemSet& rSet = rAttr.GetItemSet();
    const SfxPoolItem* pItem;
    for (USHORT i = 0; i < nMapCount; ++i)
    {
        if ( rSet.GetItemState(AttrTypeMap[i].nAttrType, false, &pItem) == SFX_ITEM_SET )
            pData->RemoveCharAttribs(AttrTypeMap[i].nCharType);
    }
}

void ScEditCell::SetTextObject( const EditTextObject* pObject,
            const SfxItemPool* pFromPool )
{
@@ -174,6 +198,76 @@ void ScEditCell::SetTextObject( const EditTextObject* pObject,
        pData = NULL;
}

ScEditDataArray::ScEditDataArray()
{
}

ScEditDataArray::~ScEditDataArray()
{
}

void ScEditDataArray::AddItem(SCTAB nTab, SCCOL nCol, SCROW nRow,
                              EditTextObject* pOldData, EditTextObject* pNewData)
{
    maArray.push_back(Item(nTab, nCol, nRow, pOldData, pNewData));
}

const ScEditDataArray::Item* ScEditDataArray::First()
{
    maIter = maArray.begin();
    if (maIter == maArray.end())
        return NULL;
    return &(*maIter++);
}

const ScEditDataArray::Item* ScEditDataArray::Next()
{
    if (maIter == maArray.end())
        return NULL;
    return &(*maIter++);
}

// ============================================================================

ScEditDataArray::Item::Item(SCTAB nTab, SCCOL nCol, SCROW nRow,
                            EditTextObject* pOldData, EditTextObject* pNewData) :
    mnTab(nTab),
    mnCol(nCol),
    mnRow(nRow)
{
    mpOldData.reset(pOldData);
    mpNewData.reset(pNewData);
}

ScEditDataArray::Item::~Item()
{
}

const EditTextObject* ScEditDataArray::Item::GetOldData() const
{
    return mpOldData.get();
}

const EditTextObject* ScEditDataArray::Item::GetNewData() const
{
    return mpNewData.get();
}

SCTAB ScEditDataArray::Item::GetTab() const
{
    return mnTab;
}

SCCOL ScEditDataArray::Item::GetCol() const
{
    return mnCol;
}

SCROW ScEditDataArray::Item::GetRow() const
{
    return mnRow;
}

// ============================================================================

namespace
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index e9fd26c..d3c7651 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -361,7 +361,7 @@ ULONG ScColumn::GetNumberFormat( SCROW nRow ) const
}


SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark )
SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark, ScEditDataArray* pDataArray )
{
    SCROW nTop = 0;
    SCROW nBottom = 0;
@@ -372,7 +372,7 @@ SCsROW ScColumn::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData
        ScMarkArrayIter aMarkIter( rMark.GetArray() + nCol );
        while (aMarkIter.Next( nTop, nBottom ))
        {
            pAttrArray->ApplyCacheArea( nTop, nBottom, pCache );
            pAttrArray->ApplyCacheArea( nTop, nBottom, pCache, pDataArray );
            bFound = TRUE;
        }
    }
@@ -446,11 +446,12 @@ void ScColumn::ApplyPattern( SCROW nRow, const ScPatternAttr& rPatAttr )
}


void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr )
void ScColumn::ApplyPatternArea( SCROW nStartRow, SCROW nEndRow, const ScPatternAttr& rPatAttr,
                                 ScEditDataArray* pDataArray )
{
    const SfxItemSet* pSet = &rPatAttr.GetItemSet();
    SfxItemPoolCache aCache( pDocument->GetPool(), pSet );
    pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache );
    pAttrArray->ApplyCacheArea( nStartRow, nEndRow, &aCache, pDataArray );
}


diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 1efe324..17763c9 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3865,12 +3865,13 @@ void ScDocument::ApplyPattern( SCCOL nCol, SCROW nRow, SCTAB nTab, const ScPatte
void ScDocument::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow,
                        SCCOL nEndCol, SCROW nEndRow,
                        const ScMarkData& rMark,
                        const ScPatternAttr& rAttr )
                        const ScPatternAttr& rAttr,
                        ScEditDataArray* pDataArray )
{
    for (SCTAB i=0; i <= MAXTAB; i++)
        if (pTab[i])
            if (rMark.GetTableSelect(i))
                pTab[i]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr );
                pTab[i]->ApplyPatternArea( nStartCol, nStartRow, nEndCol, nEndRow, rAttr, pDataArray );
}


@@ -4805,7 +4806,7 @@ void ScDocument::ApplyFrameAreaTab( const ScRange& rRange,
}


void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark )
void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMarkData& rMark, ScEditDataArray* pDataArray )
{
    const SfxItemSet* pSet = &rAttr.GetItemSet();
    BOOL bSet = FALSE;
@@ -4822,7 +4823,7 @@ void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMark
            ScRange aRange;
            rMark.GetMarkArea( aRange );
            ApplyPatternArea( aRange.aStart.Col(), aRange.aStart.Row(),
                              aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rAttr );
                              aRange.aEnd.Col(), aRange.aEnd.Row(), rMark, rAttr, pDataArray );
        }
        else
        {
@@ -4830,7 +4831,7 @@ void ScDocument::ApplySelectionPattern( const ScPatternAttr& rAttr, const ScMark
            for (SCTAB nTab=0; nTab<=MAXTAB; nTab++)
                if (pTab[nTab])
                    if (rMark.GetTableSelect(nTab))
                        pTab[nTab]->ApplySelectionCache( &aCache, rMark );
                        pTab[nTab]->ApplySelectionCache( &aCache, rMark, pDataArray );
        }
    }
}
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index d54e16b8..66e385a1 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1871,14 +1871,14 @@ void ScTable::ApplyPattern( SCCOL nCol, SCROW nRow, const ScPatternAttr& rAttr )


void ScTable::ApplyPatternArea( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
                                     const ScPatternAttr& rAttr )
                                     const ScPatternAttr& rAttr, ScEditDataArray* pDataArray )
{
    if (ValidColRow(nStartCol, nStartRow) && ValidColRow(nEndCol, nEndRow))
    {
        PutInOrder(nStartCol, nEndCol);
        PutInOrder(nStartRow, nEndRow);
        for (SCCOL i = nStartCol; i <= nEndCol; i++)
            aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr);
            aCol[i].ApplyPatternArea(nStartRow, nEndRow, rAttr, pDataArray);
    }
}

@@ -2074,10 +2074,11 @@ void ScTable::ApplyAttr( SCCOL nCol, SCROW nRow, const SfxPoolItem& rAttr )
}


void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark )
void ScTable::ApplySelectionCache( SfxItemPoolCache* pCache, const ScMarkData& rMark,
                                   ScEditDataArray* pDataArray )
{
    for (SCCOL i=0; i<=MAXCOL; i++)
        aCol[i].ApplySelectionCache( pCache, rMark );
        aCol[i].ApplySelectionCache( pCache, rMark, pDataArray );
}


diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx
index d5d7f6e..99b7cb1 100644
--- a/sc/source/ui/docshell/docsh.cxx
+++ b/sc/source/ui/docshell/docsh.cxx
@@ -394,6 +394,27 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet)
    aDocument.DisableIdle( FALSE );
}

namespace {

class LoadMediumGuard
{
public:
    explicit LoadMediumGuard(ScDocument* pDoc) :
        mpDoc(pDoc)
    {
        mpDoc->SetLoadingMedium(true);
    }

    ~LoadMediumGuard()
    {
        mpDoc->SetLoadingMedium(false);
    }
private:
    ScDocument* mpDoc;
};

}

BOOL ScDocShell::LoadXML( SfxMedium* pLoadMedium, const ::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >& xStor )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "sb99857", "ScDocShell::LoadXML" );
@@ -450,7 +471,7 @@ BOOL ScDocShell::SaveXML( SfxMedium* pSaveMedium, const ::com::sun::star::uno::R
BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::Load" );

    LoadMediumGuard aLoadGuard(&aDocument);
    ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

    //  only the latin script language is loaded
@@ -933,7 +954,7 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint )
BOOL __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::LoadFrom" );

    LoadMediumGuard aLoadGuard(&aDocument);
    ScRefreshTimerProtector( aDocument.GetRefreshTimerControlAddress() );

    WaitObject aWait( GetActiveDialogParent() );
@@ -985,27 +1006,6 @@ static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLa
    rDateConvert = static_cast<bool>(aTokens[1].toInt32());
}

namespace {

class LoadMediumGuard
{
public:
    explicit LoadMediumGuard(ScDocument* pDoc) :
        mpDoc(pDoc)
    {
        mpDoc->SetLoadingMedium(true);
    }

    ~LoadMediumGuard()
    {
        mpDoc->SetLoadingMedium(false);
    }
private:
    ScDocument* mpDoc;
};

}

BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium )
{
    RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" );
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index 574926e..b910bac 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -32,6 +32,10 @@
#include "viewutil.hxx"
#include "spellparam.hxx"

#include "cell.hxx"

#include <boost/shared_ptr.hpp>

class ScDocShell;
class ScBaseCell;
class ScDocument;
@@ -351,9 +355,11 @@ public:

    virtual String  GetComment() const;

    ScEditDataArray*    GetDataArray();
private:
    ScMarkData      aMarkData;
    ScRange         aRange;
    ScEditDataArray aDataArray;
    ScDocument*     pUndoDoc;
    BOOL            bMulti;
    ScPatternAttr*  pApplyPattern;
@@ -361,6 +367,7 @@ private:
    SvxBoxInfoItem* pLineInner;

    void            DoChange( const BOOL bUndo );
    void            ChangeEditData( const bool bUndo );
};


diff --git a/sc/source/ui/inc/undocell.hxx b/sc/source/ui/inc/undocell.hxx
index 53f1291..8d7f17f 100644
--- a/sc/source/ui/inc/undocell.hxx
+++ b/sc/source/ui/inc/undocell.hxx
@@ -31,6 +31,8 @@
#include "undobase.hxx"
#include "postit.hxx"

#include <boost/shared_ptr.hpp>

class ScDocShell;
class ScBaseCell;
class ScPatternAttr;
@@ -59,6 +61,11 @@ public:

    virtual String  GetComment() const;

    /** once the objects are passed to this class, their life-cycle is
        managed by this class; the calling function must pass new'ed
        objects to this method. */
    void            SetEditData( EditTextObject* pOld, EditTextObject* pNew );

private:
    SCCOL           nCol;
    SCROW           nRow;
@@ -66,9 +73,11 @@ private:
    ScPatternAttr*  pOldPattern;
    ScPatternAttr*  pNewPattern;
    ScPatternAttr*  pApplyPattern;
    ::boost::shared_ptr<EditTextObject> pOldEditData;
    ::boost::shared_ptr<EditTextObject> pNewEditData;
    BOOL            bIsAutomatic;

    void            DoChange( const ScPatternAttr* pWhichPattern ) const;
    void            DoChange( const ScPatternAttr* pWhichPattern, const ::boost::shared_ptr<EditTextObject>& pEditData ) const;
};


diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 506afea..4140d85 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -479,6 +479,12 @@ String __EXPORT ScUndoSelectionAttr::GetComment() const
    return ScGlobal::GetRscString( pLineOuter ? STR_UNDO_SELATTRLINES : STR_UNDO_SELATTR );
}

//----------------------------------------------------------------------------

ScEditDataArray* ScUndoSelectionAttr::GetDataArray()
{
    return &aDataArray;
}

//----------------------------------------------------------------------------

@@ -497,6 +503,8 @@ void ScUndoSelectionAttr::DoChange( const BOOL bUndo )
    USHORT nExtFlags = 0;
    pDocShell->UpdatePaintExt( nExtFlags, aEffRange );

    ChangeEditData(bUndo);

    if (bUndo)  // nur bei Undo
    {
        ScRange aCopyRange = aRange;
@@ -521,6 +529,24 @@ void ScUndoSelectionAttr::DoChange( const BOOL bUndo )
    ShowTable( aRange );
}

void ScUndoSelectionAttr::ChangeEditData( const bool bUndo )
{
    ScDocument* pDoc = pDocShell->GetDocument();
    for (const ScEditDataArray::Item* pItem = aDataArray.First(); pItem; pItem = aDataArray.Next())
    {
        ScBaseCell* pCell;
        pDoc->GetCell(pItem->GetCol(), pItem->GetRow(), pItem->GetTab(), pCell);
        if (!pCell || pCell->GetCellType() != CELLTYPE_EDIT)
            continue;

        ScEditCell* pEditCell = static_cast<ScEditCell*>(pCell);
        if (bUndo)
            pEditCell->SetData(pItem->GetOldData(), NULL);
        else
            pEditCell->SetData(pItem->GetNewData(), NULL);
    }
}


//----------------------------------------------------------------------------

diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx
index cc13ce9..a9376e5 100644
--- a/sc/source/ui/undo/undocell.cxx
+++ b/sc/source/ui/undo/undocell.cxx
@@ -54,6 +54,8 @@
#include "sc.hrc"
#include "docuno.hxx"

using ::boost::shared_ptr;

// STATIC DATA -----------------------------------------------------------

TYPEINIT1(ScUndoCursorAttr, ScSimpleUndo);
@@ -82,6 +84,8 @@ ScUndoCursorAttr::ScUndoCursorAttr( ScDocShell* pNewDocShell,
    nCol( nNewCol ),
    nRow( nNewRow ),
    nTab( nNewTab ),
    pOldEditData( static_cast<EditTextObject*>(NULL) ),
    pNewEditData( static_cast<EditTextObject*>(NULL) ),
    bIsAutomatic( bAutomatic )
{
    ScDocumentPool* pPool = pDocShell->GetDocument()->GetPool();
@@ -106,9 +110,21 @@ String __EXPORT ScUndoCursorAttr::GetComment() const
    return ScGlobal::GetRscString( nId );
}

void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
void ScUndoCursorAttr::SetEditData( EditTextObject* pOld, EditTextObject* pNew )
{
    pDocShell->GetDocument()->SetPattern( nCol, nRow, nTab, *pWhichPattern, TRUE );
    pOldEditData.reset(pOld);
    pNewEditData.reset(pNew);
}

void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern, const shared_ptr<EditTextObject>& pEditData ) const
{
    ScDocument* pDoc = pDocShell->GetDocument();
    pDoc->SetPattern( nCol, nRow, nTab, *pWhichPattern, TRUE );

    ScBaseCell* pCell;
    pDoc->GetCell(nCol, nRow, nTab, pCell);
    if (pCell && pCell->GetCellType() == CELLTYPE_EDIT && pEditData.get())
        static_cast<ScEditCell*>(pCell)->SetData(pEditData.get(), NULL);

    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
    if (pViewShell)
@@ -134,7 +150,7 @@ void ScUndoCursorAttr::DoChange( const ScPatternAttr* pWhichPattern ) const
void __EXPORT ScUndoCursorAttr::Undo()
{
    BeginUndo();
    DoChange(pOldPattern);
    DoChange(pOldPattern, pOldEditData);

    if ( bIsAutomatic )
    {
@@ -152,7 +168,7 @@ void __EXPORT ScUndoCursorAttr::Undo()
void __EXPORT ScUndoCursorAttr::Redo()
{
    BeginRedo();
    DoChange(pNewPattern);
    DoChange(pNewPattern, pNewEditData);
    EndRedo();
}

diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 12fc573..ed81254 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1313,6 +1313,8 @@ void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,
        SCROW nEndRow = aMarkRange.aEnd.Row();
        SCTAB nEndTab = aMarkRange.aEnd.Tab();

        ScUndoSelectionAttr* pUndoAttr = NULL;
        ScEditDataArray* pEditDataArray = NULL;
        if (bRecord)
        {
            ScRange aCopyRange = aMarkRange;
@@ -1328,15 +1330,14 @@ void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,

            aFuncMark.MarkToMulti();

            pDocSh->GetUndoManager()->AddUndoAction(
                new ScUndoSelectionAttr(
                            pDocSh, aFuncMark,
                            nStartCol, nStartRow, nStartTab,
                            nEndCol, nEndRow, nEndTab,
                            pUndoDoc, bMulti, &rAttr ) );
            pUndoAttr = new ScUndoSelectionAttr(
                pDocSh, aFuncMark, nStartCol, nStartRow, nStartTab,
                nEndCol, nEndRow, nEndTab, pUndoDoc, bMulti, &rAttr );
            pDocSh->GetUndoManager()->AddUndoAction(pUndoAttr);
            pEditDataArray = pUndoAttr->GetDataArray();
        }

        pDoc->ApplySelectionPattern( rAttr, aFuncMark );
        pDoc->ApplySelectionPattern( rAttr, aFuncMark, pEditDataArray );

        pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
                           nEndCol,   nEndRow,   nEndTab,
@@ -1350,6 +1351,19 @@ void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,
        SCCOL nCol = pViewData->GetCurX();
        SCROW nRow = pViewData->GetCurY();
        SCTAB nTab = pViewData->GetTabNo();

        ScBaseCell* pCell;
        pDoc->GetCell(nCol, nRow, nTab, pCell);
        EditTextObject* pOldEditData = NULL;
        EditTextObject* pNewEditData = NULL;
        if (pCell && pCell->GetCellType() == CELLTYPE_EDIT)
        {
            ScEditCell* pEditCell = static_cast<ScEditCell*>(pCell);
            pOldEditData = pEditCell->GetData()->Clone();
            pEditCell->RemoveCharAttribs(rAttr);
            pNewEditData = pEditCell->GetData()->Clone();
        }

        aChangeRanges.Append( ScRange( nCol, nRow, nTab ) );
        ScPatternAttr* pOldPat = new ScPatternAttr(*pDoc->GetPattern( nCol, nRow, nTab ));

@@ -1359,11 +1373,10 @@ void ScViewFunc::ApplySelectionPattern( const ScPatternAttr& rAttr,

        if (bRecord)
        {
            pDocSh->GetUndoManager()->AddUndoAction(
                        new ScUndoCursorAttr( pDocSh,
                                              nCol, nRow, nTab,
                                              pOldPat, pNewPat, &rAttr,
                                              FALSE ) );    // FALSE = nicht automatisch
            ScUndoCursorAttr* pUndo = new ScUndoCursorAttr(
                pDocSh, nCol, nRow, nTab, pOldPat, pNewPat, &rAttr, false );
            pUndo->SetEditData(pOldEditData, pNewEditData);
            pDocSh->GetUndoManager()->AddUndoAction(pUndo);
        }
        delete pOldPat;     // wird im Undo kopiert (Pool)