[ooo-build-commit] .: 4 commits - sc/inc sc/source sc/uiconfig

Fridrich Strba fridrich at kemper.freedesktop.org
Thu Sep 16 02:48:01 PDT 2010


 sc/inc/column.hxx                     |    4 
 sc/inc/document.hxx                   |    3 
 sc/inc/stringutil.hxx                 |   35 +++++
 sc/inc/table.hxx                      |    4 
 sc/source/core/data/column3.cxx       |   55 ++++----
 sc/source/core/data/document.cxx      |    4 
 sc/source/core/data/table2.cxx        |    4 
 sc/source/core/tool/stringutil.cxx    |    9 +
 sc/source/filter/rtf/eeimpars.cxx     |   13 +
 sc/source/ui/docshell/docfunc.cxx     |  224 ++++++++++++++++++++++------------
 sc/source/ui/docshell/impex.cxx       |   23 +++
 sc/source/ui/inc/cellmergeoption.hxx  |   60 +++++++++
 sc/source/ui/inc/docfunc.hxx          |  108 ++++++++--------
 sc/source/ui/inc/undoblk.hxx          |   14 +-
 sc/source/ui/inc/viewfunc.hxx         |    2 
 sc/source/ui/undo/undoblk.cxx         |  103 +++++++++------
 sc/source/ui/undo/undoblk3.cxx        |  107 ++++++++++------
 sc/source/ui/unoobj/cellsuno.cxx      |    9 +
 sc/source/ui/view/cellmergeoption.cxx |   74 +++++++++++
 sc/source/ui/view/cellsh3.cxx         |    4 
 sc/source/ui/view/dbfunc.cxx          |    2 
 sc/source/ui/view/gridwin.cxx         |   38 ++---
 sc/source/ui/view/makefile.mk         |    1 
 sc/source/ui/view/viewfun2.cxx        |   82 +++++++++++-
 sc/uiconfig/scalc/menubar/menubar.xml |    8 +
 25 files changed, 703 insertions(+), 287 deletions(-)

New commits:
commit be324baced0b7fada4e0792505155f10578f1d70
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:43:15 2010 +0200

    calc-enhanced-merge-cells-sc.diff
    
    n#213205, i#67243, i#101042
    Merging/unmerging of cells on multiple sheets & merge center icon.

diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 9f6d99a..bec1b90 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -65,6 +65,7 @@
 #include "dociter.hxx"
 #include "autoform.hxx"
 #include "cell.hxx"
+#include "cellmergeoption.hxx"
 #include "detdata.hxx"
 #include "detfunc.hxx"
 #include "docpool.hxx"
@@ -103,6 +104,7 @@
 #include <memory>
 #include <basic/basmgr.hxx>
 #include <boost/scoped_ptr.hpp>
+#include <set>
 
 using namespace com::sun::star;
 using ::com::sun::star::uno::Sequence;
@@ -1714,7 +1716,11 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
                     default:
                         break;
                 }
-                MergeCells(aRange, FALSE, TRUE, TRUE);
+                ScCellMergeOption aMergeOption(
+                    aRange.aStart.Col(), aRange.aStart.Row(),
+                    aRange.aEnd.Col(), aRange.aEnd.Row() );
+                aMergeOption.maTabs.insert(aRange.aStart.Tab());
+                MergeCells(aMergeOption, FALSE, TRUE, TRUE);
             }
             qIncreaseRange.pop_back();
         }
@@ -1763,7 +1769,10 @@ BOOL ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
             while( !qIncreaseRange.empty() )
             {
                 ScRange aRange = qIncreaseRange.back();
-                MergeCells(aRange, FALSE, TRUE, TRUE);
+                 ScCellMergeOption aMergeOption(
+                    aRange.aStart.Col(), aRange.aStart.Row(),
+                    aRange.aEnd.Col(), aRange.aEnd.Row() );
+                MergeCells(aMergeOption, FALSE, TRUE, TRUE);
                 qIncreaseRange.pop_back();
             }
 
@@ -2201,7 +2210,10 @@ BOOL ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
 
         if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
         {
-            MergeCells( aRange, FALSE, TRUE, TRUE );
+            ScCellMergeOption aMergeOption(
+                aRange.aStart.Col(), aRange.aStart.Row(),
+                aRange.aEnd.Col(), aRange.aEnd.Row() );
+            MergeCells( aMergeOption, FALSE, TRUE, TRUE );
         }
         qDecreaseRange.pop_back();
     }
@@ -4338,86 +4350,110 @@ BOOL ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
 
 //------------------------------------------------------------------------
 
-BOOL ScDocFunc::MergeCells( const ScRange& rRange, BOOL bContents, BOOL bRecord, BOOL bApi )
+BOOL ScDocFunc::MergeCells( const ScCellMergeOption& rOption, BOOL bContents, BOOL bRecord, BOOL bApi )
 {
+    using ::std::set;
+
     ScDocShellModificator aModificator( rDocShell );
 
+    SCCOL nStartCol = rOption.mnStartCol;
+    SCROW nStartRow = rOption.mnStartRow;
+    SCCOL nEndCol = rOption.mnEndCol;
+    SCROW nEndRow = rOption.mnEndRow;
+    if ((nStartCol == nEndCol && nStartRow == nEndRow) || rOption.maTabs.empty())
+    {
+        // Nothing to do.  Bail out quick.
+        return TRUE;
+    }
+
     ScDocument* pDoc = rDocShell.GetDocument();
-    SCCOL nStartCol = rRange.aStart.Col();
-    SCROW nStartRow = rRange.aStart.Row();
-    SCCOL nEndCol = rRange.aEnd.Col();
-    SCROW nEndRow = rRange.aEnd.Row();
-    SCTAB nTab = rRange.aStart.Tab();
+    set<SCTAB>::const_iterator itrBeg = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
+    SCTAB nTab1 = *itrBeg, nTab2 = *rOption.maTabs.rbegin();
 
     if (bRecord && !pDoc->IsUndoEnabled())
         bRecord = FALSE;
 
-    ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
-    if (!aTester.IsEditable())
+    for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
     {
-        if (!bApi)
-            rDocShell.ErrorMessage(aTester.GetMessageId());
-        return FALSE;
-    }
+        ScEditableTester aTester( pDoc, *itr, nStartCol, nStartRow, nEndCol, nEndRow );
+        if (!aTester.IsEditable())
+        {
+            if (!bApi)
+                rDocShell.ErrorMessage(aTester.GetMessageId());
+            return FALSE;
+        }
 
-    if ( nStartCol == nEndCol && nStartRow == nEndRow )
-    {
-        // nichts zu tun
-        return TRUE;
+        if ( pDoc->HasAttrib( nStartCol, nStartRow, *itr, nEndCol, nEndRow, *itr,
+                                HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+        {
+            // "Zusammenfassen nicht verschachteln !"
+            if (!bApi)
+                rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
+            return FALSE;
+        }
     }
 
-    if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
-                            HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+    ScDocument* pUndoDoc = NULL;
+    bool bNeedContentsUndo = false;
+    for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
     {
-        // "Zusammenfassen nicht verschachteln !"
-        if (!bApi)
-            rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
-        return FALSE;
-    }
+        SCTAB nTab = *itr;
+        bool bNeedContents = bContents &&
+                ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
+                  !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
 
-    BOOL bNeedContents = bContents &&
-            ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
-              !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
+        if (bRecord)
+        {
+            // test if the range contains other notes which also implies that we need an undo document
+            bool bHasNotes = false;
+            for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
+                for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
+                    bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNote( aPos ) != 0);
 
-    ScDocument* pUndoDoc = 0;
-    if (bRecord)
-    {
-        // test if the range contains other notes which also implies that we need an undo document
-        bool bHasNotes = false;
-        for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
-            for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
-                bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNote( aPos ) != 0);
+            if (bNeedContents || bHasNotes || rOption.mbCenter)
+            {
+                if (!pUndoDoc)
+                {
+                    pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+                    pUndoDoc->InitUndo(pDoc, nTab1, nTab2);
+                }
+                // note captions are collected by drawing undo
+                pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+                                      IDF_ALL|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+            }
+            if( bHasNotes )
+                pDoc->BeginDrawUndo();
+        }
+
+        if (bNeedContents)
+            pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+        pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
 
-        if (bNeedContents || bHasNotes)
+        if (rOption.mbCenter)
         {
-            pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
-            pUndoDoc->InitUndo( pDoc, nTab, nTab );
-            // note captions are collected by drawing undo
-            pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
-                                    IDF_ALL|IDF_NOCAPTIONS, FALSE, pUndoDoc );
+            pDoc->ApplyAttr( nStartCol, nStartRow, nTab, SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+            pDoc->ApplyAttr( nStartCol, nStartRow, nTab, SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
         }
-        if( bHasNotes )
-            pDoc->BeginDrawUndo();
-    }
 
-    if (bNeedContents)
-        pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
-    pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+        if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
+            rDocShell.PostPaint( nStartCol, nStartRow, nTab,
+                                 nEndCol, nEndRow, nTab, PAINT_GRID );
+        if (bNeedContents || rOption.mbCenter)
+        {
+            ScRange aRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab);
+            pDoc->SetDirty(aRange);
+        }
 
-    if( bRecord )
+        bNeedContentsUndo |= bNeedContents;
+    }
+
+    if (pUndoDoc)
     {
-        SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : 0;
+        SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : NULL;
         rDocShell.GetUndoManager()->AddUndoAction(
-            new ScUndoMerge( &rDocShell,
-                            nStartCol, nStartRow, nTab,
-                            nEndCol, nEndRow, nTab, bNeedContents, pUndoDoc, pDrawUndo ) );
+            new ScUndoMerge(&rDocShell, rOption, bNeedContentsUndo, pUndoDoc, pDrawUndo) );
     }
 
-    if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
-        rDocShell.PostPaint( nStartCol, nStartRow, nTab,
-                                            nEndCol, nEndRow, nTab, PAINT_GRID );
-    if (bNeedContents)
-        pDoc->SetDirty( rRange );
     aModificator.SetDocumentModified();
 
     SfxBindings* pBindings = rDocShell.GetViewBindings();
@@ -4433,49 +4469,81 @@ BOOL ScDocFunc::MergeCells( const ScRange& rRange, BOOL bContents, BOOL bRecord,
 
 BOOL ScDocFunc::UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi )
 {
-    ScDocShellModificator aModificator( rDocShell );
+    ScCellMergeOption aOption(rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row());
+    SCTAB nTab1 = rRange.aStart.Tab(), nTab2 = rRange.aEnd.Tab();
+    for (SCTAB i = nTab1; i <= nTab2; ++i)
+        aOption.maTabs.insert(i);
+
+    return UnmergeCells(aOption, bRecord, bApi);
+}
+
+bool ScDocFunc::UnmergeCells( const ScCellMergeOption& rOption, BOOL bRecord, BOOL bApi )
+{
+    using ::std::set;
+
+    if (rOption.maTabs.empty())
+        // Nothing to unmerge.
+        return true;
 
+    ScDocShellModificator aModificator( rDocShell );
     ScDocument* pDoc = rDocShell.GetDocument();
-    SCTAB nTab = rRange.aStart.Tab();
 
     if (bRecord && !pDoc->IsUndoEnabled())
         bRecord = FALSE;
 
-    if ( pDoc->HasAttrib( rRange, HASATTR_MERGED ) )
+    ScDocument* pUndoDoc = NULL;
+    bool bBeep = false;
+    for (set<SCTAB>::const_iterator itr = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
+          itr != itrEnd; ++itr)
     {
-        ScRange aExtended = rRange;
-        pDoc->ExtendMerge( aExtended );
+        SCTAB nTab = *itr;
+        ScRange aRange = rOption.getSingleRange(nTab);
+        if ( !pDoc->HasAttrib(aRange, HASATTR_MERGED) )
+        {
+            bBeep = true;
+            continue;
+        }
+
+        ScRange aExtended = aRange;
+        pDoc->ExtendMerge(aExtended);
         ScRange aRefresh = aExtended;
-        pDoc->ExtendOverlapped( aRefresh );
+        pDoc->ExtendOverlapped(aRefresh);
 
         if (bRecord)
         {
-            ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
-            pUndoDoc->InitUndo( pDoc, nTab, nTab );
-            pDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pUndoDoc );
-            rDocShell.GetUndoManager()->AddUndoAction(
-                new ScUndoRemoveMerge( &rDocShell, rRange, pUndoDoc ) );
+            if (!pUndoDoc)
+            {
+                pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+                pUndoDoc->InitUndo(pDoc, *rOption.maTabs.begin(), *rOption.maTabs.rbegin());
+            }
+            pDoc->CopyToDocument(aExtended, IDF_ATTRIB, FALSE, pUndoDoc);
         }
 
         const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
         ScPatternAttr aPattern( pDoc->GetPool() );
         aPattern.GetItemSet().Put( rDefAttr );
-        pDoc->ApplyPatternAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
-                                    rRange.aEnd.Col(), rRange.aEnd.Row(), nTab,
-                                    aPattern );
+        pDoc->ApplyPatternAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
+                                   aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
+                                   aPattern );
 
         pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
-                                aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
-                                SC_MF_HOR | SC_MF_VER );
+                              aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
+                              SC_MF_HOR | SC_MF_VER );
 
         pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
 
         if ( !AdjustRowHeight( aExtended ) )
             rDocShell.PostPaint( aExtended, PAINT_GRID );
-        aModificator.SetDocumentModified();
     }
-    else if (!bApi)
-        Sound::Beep();		//! FALSE zurueck???
+    if (bBeep && !bApi)
+        Sound::Beep();
+
+    if (bRecord)
+    {
+        rDocShell.GetUndoManager()->AddUndoAction(
+            new ScUndoRemoveMerge( &rDocShell, rOption, pUndoDoc ) );
+    }
+    aModificator.SetDocumentModified();
 
     return TRUE;
 }
diff --git a/sc/source/ui/inc/cellmergeoption.hxx b/sc/source/ui/inc/cellmergeoption.hxx
new file mode 100644
index 0000000..37b5b0b
--- /dev/null
+++ b/sc/source/ui/inc/cellmergeoption.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 by Novell, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docfunc.hxx,v $
+ * $Revision: 1.18.30.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_CELLMERGEOPTION_HXX
+#define SC_CELLMERGEOPTION_HXX
+
+#include "address.hxx"
+
+#include <set>
+
+class ScRange;
+
+struct ScCellMergeOption
+{
+    ::std::set<SCTAB> maTabs;
+    SCCOL mnStartCol;
+    SCROW mnStartRow;
+    SCCOL mnEndCol;
+    SCROW mnEndRow;
+    bool mbCenter;
+
+    explicit ScCellMergeOption();
+    explicit ScCellMergeOption(SCCOL nStartCol, SCROW nStartRow,
+                               SCCOL nEndCol, SCROW nEndRow,
+                               bool bCenter = false);
+    explicit ScCellMergeOption(const ScCellMergeOption& r);
+
+    ScRange getSingleRange(SCTAB nTab) const;
+    ScRange getFirstSingleRange() const;
+};
+
+
+#endif
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index d70c928..b2bb683 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -49,20 +49,21 @@ class ScBaseCell;
 class ScTokenArray;
 struct ScTabOpParam;
 class ScTableProtection;
+struct ScCellMergeOption;
 
 // ---------------------------------------------------------------------------
 
 class ScDocFunc
 {
 private:
-    ScDocShell&		rDocShell;
+    ScDocShell&        rDocShell;
 
-    BOOL			AdjustRowHeight( const ScRange& rRange, BOOL bPaint = TRUE );
-    void			CreateOneName( ScRangeName& rList,
+    BOOL            AdjustRowHeight( const ScRange& rRange, BOOL bPaint = TRUE );
+    void            CreateOneName( ScRangeName& rList,
                                     SCCOL nPosX, SCROW nPosY, SCTAB nTab,
                                     SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
                                     BOOL& rCancel, BOOL bApi );
-    void			NotifyInputHandler( const ScAddress& rPos );
+    void            NotifyInputHandler( const ScAddress& rPos );
 
 public:
                     ScDocFunc( ScDocShell& rDocSh ): rDocShell(rDocSh) {}
@@ -70,120 +71,121 @@ public:
 
     DECL_LINK( NotifyDrawUndo, SdrUndoAction* );
 
-    BOOL			DetectiveAddPred(const ScAddress& rPos);
-    BOOL			DetectiveDelPred(const ScAddress& rPos);
-    BOOL			DetectiveAddSucc(const ScAddress& rPos);
-    BOOL			DetectiveDelSucc(const ScAddress& rPos);
-    BOOL			DetectiveAddError(const ScAddress& rPos);
-    BOOL			DetectiveMarkInvalid(SCTAB nTab);
-    BOOL			DetectiveDelAll(SCTAB nTab);
-    BOOL			DetectiveRefresh(BOOL bAutomatic = FALSE);
+    BOOL            DetectiveAddPred(const ScAddress& rPos);
+    BOOL            DetectiveDelPred(const ScAddress& rPos);
+    BOOL            DetectiveAddSucc(const ScAddress& rPos);
+    BOOL            DetectiveDelSucc(const ScAddress& rPos);
+    BOOL            DetectiveAddError(const ScAddress& rPos);
+    BOOL            DetectiveMarkInvalid(SCTAB nTab);
+    BOOL            DetectiveDelAll(SCTAB nTab);
+    BOOL            DetectiveRefresh(BOOL bAutomatic = FALSE);
     void            DetectiveCollectAllPreds(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens);
     void            DetectiveCollectAllSuccs(const ScRangeList& rSrcRanges, ::std::vector<ScSharedTokenRef>& rRefTokens);
 
-    BOOL			DeleteContents( const ScMarkData& rMark, USHORT nFlags,
+    BOOL            DeleteContents( const ScMarkData& rMark, USHORT nFlags,
                                     BOOL bRecord, BOOL bApi );
 
-    BOOL			TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
+    BOOL            TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
                                     BOOL bRecord, BOOL bApi );
 
-    BOOL			SetNormalString( const ScAddress& rPos, const String& rText, BOOL bApi );
-    BOOL			PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi );
-    BOOL			PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
+    BOOL            SetNormalString( const ScAddress& rPos, const String& rText, BOOL bApi );
+    BOOL            PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, BOOL bApi );
+    BOOL            PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine,
                                 BOOL bInterpret, BOOL bApi );
-    BOOL			SetCellText( const ScAddress& rPos, const String& rText,
+    BOOL            SetCellText( const ScAddress& rPos, const String& rText,
                                     BOOL bInterpret, BOOL bEnglish, BOOL bApi,
                                     const String& rFormulaNmsp,
                                     const formula::FormulaGrammar::Grammar eGrammar );
 
                     // creates a new cell for use with PutCell
-    ScBaseCell*		InterpretEnglishString( const ScAddress& rPos, const String& rText,
+    ScBaseCell*     InterpretEnglishString( const ScAddress& rPos, const String& rText,
                         const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar );
 
-    bool			ShowNote( const ScAddress& rPos, bool bShow = true );
-    inline bool		HideNote( const ScAddress& rPos ) { return ShowNote( rPos, false ); }
+    bool            ShowNote( const ScAddress& rPos, bool bShow = true );
+    inline bool     HideNote( const ScAddress& rPos ) { return ShowNote( rPos, false ); }
 
     bool            SetNoteText( const ScAddress& rPos, const String& rNoteText, BOOL bApi );
     bool            ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate, BOOL bApi );
 
-    BOOL			ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
+    BOOL            ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
                                     BOOL bRecord, BOOL bApi );
-    BOOL			ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
+    BOOL            ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
                                     BOOL bRecord, BOOL bApi );
 
-    BOOL			InsertCells( const ScRange& rRange,const ScMarkData* pTabMark,
+    BOOL            InsertCells( const ScRange& rRange,const ScMarkData* pTabMark,
                                  InsCellCmd eCmd, BOOL bRecord, BOOL bApi,
                                     BOOL bPartOfPaste = FALSE );
-    BOOL			DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark,
                                  DelCellCmd eCmd, BOOL bRecord, BOOL bApi );
 
-    BOOL			MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
+    BOOL            MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
                                 BOOL bCut, BOOL bRecord, BOOL bPaint, BOOL bApi );
 
-    BOOL			InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
-    BOOL			RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
-    BOOL			DeleteTable( SCTAB nTab, BOOL bRecord, BOOL bApi );
+    BOOL            InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
+    BOOL            RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi );
+    BOOL            DeleteTable( SCTAB nTab, BOOL bRecord, BOOL bApi );
 
     bool            SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi );
     bool            SetTabBgColor( ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi );
 
-    BOOL			SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi );
+    BOOL            SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi );
 
-    BOOL			SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi );
+    BOOL            SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi );
 
-//UNUSED2009-05 BOOL	 	    SetGrammar( formula::FormulaGrammar::Grammar eGrammar );
+//UNUSED2009-05 BOOL             SetGrammar( formula::FormulaGrammar::Grammar eGrammar );
 
-    SC_DLLPUBLIC BOOL			SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
+    SC_DLLPUBLIC BOOL            SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges,
                                     SCTAB nTab, ScSizeMode eMode, USHORT nSizeTwips,
                                     BOOL bRecord, BOOL bApi );
 
-    BOOL			InsertPageBreak( BOOL bColumn, const ScAddress& rPos,
+    BOOL            InsertPageBreak( BOOL bColumn, const ScAddress& rPos,
                                     BOOL bRecord, BOOL bSetModified, BOOL bApi );
-    BOOL			RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
+    BOOL            RemovePageBreak( BOOL bColumn, const ScAddress& rPos,
                                     BOOL bRecord, BOOL bSetModified, BOOL bApi );
 
     void            ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect );
 
-    BOOL			Protect( SCTAB nTab, const String& rPassword, BOOL bApi );
-    BOOL			Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi );
+    BOOL            Protect( SCTAB nTab, const String& rPassword, BOOL bApi );
+    BOOL            Unprotect( SCTAB nTab, const String& rPassword, BOOL bApi );
 
-    BOOL			ClearItems( const ScMarkData& rMark, const USHORT* pWhich, BOOL bApi );
-    BOOL			ChangeIndent( const ScMarkData& rMark, BOOL bIncrement, BOOL bApi );
-    BOOL			AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            ClearItems( const ScMarkData& rMark, const USHORT* pWhich, BOOL bApi );
+    BOOL            ChangeIndent( const ScMarkData& rMark, BOOL bIncrement, BOOL bApi );
+    BOOL            AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
                                     USHORT nFormatNo, BOOL bRecord, BOOL bApi );
 
-    BOOL			EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
                                     const ScTokenArray* pTokenArray,
                                     const String& rString, BOOL bApi, BOOL bEnglish,
                                     const String& rFormulaNmsp,
                                     const formula::FormulaGrammar::Grammar );
 
-    BOOL			TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
                             const ScTabOpParam& rParam, BOOL bRecord, BOOL bApi );
 
-    BOOL			FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
                                 FillDir eDir, BOOL bRecord, BOOL bApi );
-    BOOL			FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
-                                FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
+    BOOL            FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
+                                FillDir    eDir, FillCmd eCmd, FillDateCmd    eDateCmd,
                                 double fStart, double fStep, double fMax,
                                 BOOL bRecord, BOOL bApi );
                     // FillAuto: rRange wird von Source-Range auf Dest-Range angepasst
-    BOOL			FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
+    BOOL            FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
                                 FillDir eDir, ULONG nCount, BOOL bRecord, BOOL bApi );
 
-    BOOL			ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
+    BOOL            ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
 
-    BOOL			MergeCells( const ScRange& rRange, BOOL bContents,
+    BOOL            MergeCells( const ScCellMergeOption& rOption, BOOL bContents,
                                 BOOL bRecord, BOOL bApi );
-    BOOL			UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+    BOOL            UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi );
+    bool            UnmergeCells( const ScCellMergeOption& rOption, BOOL bRecord, BOOL bApi );
 
     BOOL            SetNewRangeNames( ScRangeName* pNewRanges, BOOL bApi );     // takes ownership of pNewRanges
-    BOOL			ModifyRangeNames( const ScRangeName& rNewRanges, BOOL bApi );
+    BOOL            ModifyRangeNames( const ScRangeName& rNewRanges, BOOL bApi );
 
-    BOOL			CreateNames( const ScRange& rRange, USHORT nFlags, BOOL bApi );
-    BOOL			InsertNameList( const ScAddress& rStartPos, BOOL bApi );
+    BOOL            CreateNames( const ScRange& rRange, USHORT nFlags, BOOL bApi );
+    BOOL            InsertNameList( const ScAddress& rStartPos, BOOL bApi );
 
-    BOOL			InsertAreaLink( const String& rFile, const String& rFilter,
+    BOOL            InsertAreaLink( const String& rFile, const String& rFilter,
                                     const String& rOptions, const String& rSource,
                                     const ScRange& rDestRange, ULONG nRefresh,
                                     BOOL bFitBlock, BOOL bApi );
diff --git a/sc/source/ui/inc/undoblk.hxx b/sc/source/ui/inc/undoblk.hxx
index f1aab93..5a0af10 100644
--- a/sc/source/ui/inc/undoblk.hxx
+++ b/sc/source/ui/inc/undoblk.hxx
@@ -31,6 +31,7 @@
 #include "markdata.hxx"
 #include "viewutil.hxx"
 #include "spellparam.hxx"
+#include "cellmergeoption.hxx"
 
 #include "cell.hxx"
 
@@ -452,10 +453,8 @@ class ScUndoMerge: public ScSimpleUndo
 {
 public:
                     TYPEINFO();
-                    ScUndoMerge( ScDocShell* pNewDocShell,
-                                 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
-                                 SCCOL nEndX,   SCROW nEndY,   SCTAB nEndZ,
-                                 bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo );
+                    ScUndoMerge( ScDocShell* pNewDocShell, const ScCellMergeOption& rOption,
+                                 bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo);
     virtual 		~ScUndoMerge();
 
     virtual void	Undo();
@@ -466,7 +465,7 @@ public:
     virtual String	GetComment() const;
 
 private:
-    ScRange         maRange;
+    ScCellMergeOption maOption;
     bool            mbMergeContents;        // Merge contents in Redo().
     ScDocument*		mpUndoDoc;              // wenn Daten zusammengefasst
     SdrUndoAction*  mpDrawUndo;
@@ -947,7 +946,7 @@ class ScUndoRemoveMerge: public ScBlockUndo
 public:
                     TYPEINFO();
                     ScUndoRemoveMerge( ScDocShell* pNewDocShell,
-                                       const ScRange& rArea,
+                                       const ScCellMergeOption& rOption,
                                        ScDocument* pNewUndoDoc );
     virtual 		~ScUndoRemoveMerge();
 
@@ -959,6 +958,9 @@ public:
     virtual String	GetComment() const;
 
 private:
+    void            SetCurTab();
+
+    ScCellMergeOption maOption;
     ScDocument*		pUndoDoc;
 };
 
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index dd748e4..8a5aeee 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -239,7 +239,7 @@ public:
     BOOL			TestMergeCells();
     BOOL			TestRemoveMerge();
 
-    BOOL			MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord = TRUE );
+    BOOL			MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord = TRUE, BOOL bCenter = FALSE );
     BOOL			RemoveMerge( BOOL bRecord = TRUE );
 
     void			FillSimple( FillDir eDir, BOOL bRecord = TRUE );
diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx
index 6c096c9..5bb2da7 100644
--- a/sc/source/ui/undo/undoblk.cxx
+++ b/sc/source/ui/undo/undoblk.cxx
@@ -64,6 +64,7 @@
 #include "clipparam.hxx"
 #include "sc.hrc"
 
+#include <set>
 
 // STATIC DATA -----------------------------------------------------------
 
@@ -2051,8 +2052,9 @@ BOOL __EXPORT ScUndoRemoveBreaks::CanRepeat(SfxRepeatTarget& rTarget) const
 //
 
 ScUndoRemoveMerge::ScUndoRemoveMerge( ScDocShell* pNewDocShell,
-                                       const ScRange& rArea, ScDocument* pNewUndoDoc ) :
-    ScBlockUndo( pNewDocShell, rArea, SC_UNDO_SIMPLE ),
+                                      const ScCellMergeOption& rOption, ScDocument* pNewUndoDoc ) :
+    ScBlockUndo( pNewDocShell, rOption.getFirstSingleRange(), SC_UNDO_SIMPLE ),
+    maOption(rOption),
     pUndoDoc( pNewUndoDoc )
 {
 }
@@ -2069,66 +2071,78 @@ String __EXPORT ScUndoRemoveMerge::GetComment() const
 
 void __EXPORT ScUndoRemoveMerge::Undo()
 {
-    BeginUndo();
-
-    ScDocument* pDoc = pDocShell->GetDocument();
-
-    ScRange aExtended = aBlockRange;
-    pUndoDoc->ExtendMerge( aExtended );
+    using ::std::set;
 
-    pDoc->DeleteAreaTab( aExtended, IDF_ATTRIB );
-    pUndoDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pDoc );
+    SetCurTab();
+    BeginUndo();
 
-    BOOL bDidPaint = FALSE;
     ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
-    if ( pViewShell )
+
+    ScDocument* pDoc = pDocShell->GetDocument();
+    for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
+          itr != itrEnd; ++itr)
     {
-        pViewShell->SetTabNo( aExtended.aStart.Tab() );
-        bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+        // There is no need to extend merge area because it's already been extended.
+        ScRange aRange = maOption.getSingleRange(*itr);
+        pDoc->DeleteAreaTab(aRange, IDF_ATTRIB);
+        pUndoDoc->CopyToDocument(aRange, IDF_ATTRIB, FALSE, pDoc);
+
+        bool bDidPaint = false;
+        if ( pViewShell )
+        {
+            pViewShell->SetTabNo(*itr);
+            bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
+        }
+        if (!bDidPaint)
+            ScUndoUtil::PaintMore(pDocShell, aRange);
     }
-    if (!bDidPaint)
-        ScUndoUtil::PaintMore( pDocShell, aExtended );
 
     EndUndo();
 }
 
 void __EXPORT ScUndoRemoveMerge::Redo()
 {
+    using ::std::set;
+
+    SetCurTab();
     BeginRedo();
 
-    SCTAB nTab = aBlockRange.aStart.Tab();
     ScDocument* pDoc = pDocShell->GetDocument();
-    ScRange aExtended = aBlockRange;
-    pDoc->ExtendMerge( aExtended );
-    ScRange aRefresh = aExtended;
-    pDoc->ExtendOverlapped( aRefresh );
+    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+
+    for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
+          itr != itrEnd; ++itr)
+    {
+        SCTAB nTab = *itr;
+        // There is no need to extend merge area because it's already been extended.
+        ScRange aRange = maOption.getSingleRange(nTab);
 
-    //	ausfuehren
+        //	ausfuehren
 
-    const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
-    ScPatternAttr aPattern( pDoc->GetPool() );
-    aPattern.GetItemSet().Put( rDefAttr );
-    pDoc->ApplyPatternAreaTab( aBlockRange.aStart.Col(), aBlockRange.aStart.Row(),
-                                aBlockRange.aEnd.Col(), aBlockRange.aEnd.Row(), nTab,
-                                aPattern );
+        const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
+        ScPatternAttr aPattern( pDoc->GetPool() );
+        aPattern.GetItemSet().Put( rDefAttr );
+        pDoc->ApplyPatternAreaTab( maOption.mnStartCol, maOption.mnStartRow,
+                                   maOption.mnEndCol, maOption.mnEndRow, nTab,
+                                   aPattern );
 
-    pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
-                            aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
-                            SC_MF_HOR | SC_MF_VER );
+        pDoc->RemoveFlagsTab( maOption.mnStartCol, maOption.mnStartRow,
+                              maOption.mnEndCol, maOption.mnEndRow, nTab,
+                              SC_MF_HOR | SC_MF_VER );
 
-    pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
+        pDoc->ExtendMerge(aRange, TRUE, FALSE);
 
-    //	Paint
+        //	Paint
 
-    BOOL bDidPaint = FALSE;
-    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
-    if ( pViewShell )
-    {
-        pViewShell->SetTabNo( aExtended.aStart.Tab() );
-        bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+        BOOL bDidPaint = FALSE;
+        if ( pViewShell )
+        {
+            pViewShell->SetTabNo(nTab);
+            bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
+        }
+        if (!bDidPaint)
+            ScUndoUtil::PaintMore(pDocShell, aRange);
     }
-    if (!bDidPaint)
-        ScUndoUtil::PaintMore( pDocShell, aExtended );
 
     EndRedo();
 }
@@ -2144,6 +2158,13 @@ BOOL __EXPORT ScUndoRemoveMerge::CanRepeat(SfxRepeatTarget& rTarget) const
     return (rTarget.ISA(ScTabViewTarget));
 }
 
+void ScUndoRemoveMerge::SetCurTab()
+{
+    SCTAB nCurTab = pDocShell->GetCurTab();
+    aBlockRange.aStart.SetTab(nCurTab);
+    aBlockRange.aEnd.SetTab(nCurTab);
+}
+
 // -----------------------------------------------------------------------
 //
 //		nur Umrandung setzen, per ScRangeList (StarOne)
diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx
index 7fe686b..5152fff 100644
--- a/sc/source/ui/undo/undoblk3.cxx
+++ b/sc/source/ui/undo/undoblk3.cxx
@@ -31,6 +31,7 @@
 // INCLUDE -------------------------------------------------------------------
 
 #include "scitems.hxx"
+#include <svx/algitem.hxx>
 #include <editeng/boxitem.hxx>
 #include <svl/srchitem.hxx>
 #include <sfx2/linkmgr.hxx>
@@ -798,14 +799,12 @@ BOOL __EXPORT ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
 
 //----------------------------------------------------------------------------
 
-ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell,
-                            SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
-                            SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
-                            bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
+ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell, const ScCellMergeOption& rOption,
+                          bool bMergeContents, ScDocument* pUndoDoc, SdrUndoAction* pDrawUndo )
         //
     :	ScSimpleUndo( pNewDocShell ),
         //
-        maRange( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
+        maOption(rOption),
         mbMergeContents( bMergeContents ),
         mpUndoDoc( pUndoDoc ),
         mpDrawUndo( pDrawUndo )
@@ -834,51 +833,77 @@ String ScUndoMerge::GetComment() const
 
 void ScUndoMerge::DoChange( bool bUndo ) const
 {
-    ScDocument* pDoc = pDocShell->GetDocument();
+    using ::std::set;
 
-    ScUndoUtil::MarkSimpleBlock( pDocShell, maRange );
+    if (maOption.maTabs.empty())
+        // Nothing to do.
+        return;
 
-    if (bUndo)
-        // remove merge (contents are copied back below from undo document)
-        pDoc->RemoveMerge( maRange.aStart.Col(), maRange.aStart.Row(), maRange.aStart.Tab() );
-    else
-        // repeat merge, but do not remove note captions (will be done by drawing redo below)
-/*!*/	pDoc->DoMerge( maRange.aStart.Tab(),
-                       maRange.aStart.Col(), maRange.aStart.Row(),
-                       maRange.aEnd.Col(),   maRange.aEnd.Row(), false );
+    ScDocument* pDoc = pDocShell->GetDocument();
+    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
 
-    // undo -> copy back deleted contents
-    if (bUndo && mpUndoDoc)
-    {
-        pDoc->DeleteAreaTab( maRange, IDF_CONTENTS|IDF_NOCAPTIONS );
-        mpUndoDoc->CopyToDocument( maRange, IDF_ALL|IDF_NOCAPTIONS, FALSE, pDoc );
-    }
+    ScRange aCurRange = maOption.getSingleRange(pDocShell->GetCurTab());
+    ScUndoUtil::MarkSimpleBlock(pDocShell, aCurRange);
 
-    // redo -> merge contents again
-    else if (!bUndo && mbMergeContents)
+    for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
+          itr != itrEnd; ++itr)
     {
-/*!*/   pDoc->DoMergeContents( maRange.aStart.Tab(),
-                               maRange.aStart.Col(), maRange.aStart.Row(),
-                               maRange.aEnd.Col(),   maRange.aEnd.Row()   );
-    }
+        SCTAB nTab = *itr;
+        ScRange aRange = maOption.getSingleRange(nTab);
 
-    if (bUndo)
-        DoSdrUndoAction( mpDrawUndo, pDoc );
-    else
-        RedoSdrUndoAction( mpDrawUndo );
+        if (bUndo)
+            // remove merge (contents are copied back below from undo document)
+            pDoc->RemoveMerge( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() );
+        else
+        {
+            // repeat merge, but do not remove note captions (will be done by drawing redo below)
+            pDoc->DoMerge( aRange.aStart.Tab(),
+                           aRange.aStart.Col(), aRange.aStart.Row(),
+                           aRange.aEnd.Col(),   aRange.aEnd.Row(), false );
 
-    BOOL bDidPaint = FALSE;
-    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
-    if ( pViewShell )
-    {
-        pViewShell->SetTabNo( maRange.aStart.Tab() );
-        bDidPaint = pViewShell->AdjustRowHeight( maRange.aStart.Row(), maRange.aEnd.Row() );
-    }
+            if (maOption.mbCenter)
+            {
+                pDoc->ApplyAttr( aRange.aStart.Col(), aRange.aStart.Row(),
+                                 aRange.aStart.Tab(),
+                                 SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
+                pDoc->ApplyAttr( aRange.aStart.Col(), aRange.aStart.Row(),
+                                 aRange.aStart.Tab(),
+                                 SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
+            }
+        }
+
+        // undo -> copy back deleted contents
+        if (bUndo && mpUndoDoc)
+        {
+            pDoc->DeleteAreaTab( aRange, IDF_CONTENTS|IDF_NOCAPTIONS );
+            mpUndoDoc->CopyToDocument( aRange, IDF_ALL|IDF_NOCAPTIONS, FALSE, pDoc );
+        }
+
+        // redo -> merge contents again
+        else if (!bUndo && mbMergeContents)
+        {
+            pDoc->DoMergeContents( aRange.aStart.Tab(),
+                                   aRange.aStart.Col(), aRange.aStart.Row(),
+                                   aRange.aEnd.Col(), aRange.aEnd.Row() );
+        }
 
-    if (!bDidPaint)
-        ScUndoUtil::PaintMore( pDocShell, maRange );
+        if (bUndo)
+            DoSdrUndoAction( mpDrawUndo, pDoc );
+        else
+            RedoSdrUndoAction( mpDrawUndo );
+
+        bool bDidPaint = false;
+        if ( pViewShell )
+        {
+            pViewShell->SetTabNo(nTab);
+            bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
+        }
+
+        if (!bDidPaint)
+            ScUndoUtil::PaintMore(pDocShell, aRange);
+    }
 
-    ShowTable( maRange );
+    ShowTable(aCurRange);
 }
 
 
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index 54bfeb7..3a6d7ca 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -68,6 +68,7 @@
 #include <com/sun/star/text/WritingMode2.hpp>
 
 #include "autoform.hxx"
+#include "cellmergeoption.hxx"
 #include "cellsuno.hxx"
 #include "cursuno.hxx"
 #include "textuno.hxx"
@@ -5342,10 +5343,14 @@ void SAL_CALL ScCellRangeObj::merge( sal_Bool bMerge ) throw(uno::RuntimeExcepti
     if ( pDocSh )
     {
         ScDocFunc aFunc(*pDocSh);
+        ScCellMergeOption aMergeOption(
+            aRange.aStart.Col(), aRange.aStart.Row(),
+            aRange.aEnd.Col(), aRange.aEnd.Row(), false);
+        aMergeOption.maTabs.insert(aRange.aStart.Tab());
         if ( bMerge )
-            aFunc.MergeCells( aRange, FALSE, TRUE, TRUE );
+            aFunc.MergeCells( aMergeOption, FALSE, TRUE, TRUE );
         else
-            aFunc.UnmergeCells( aRange, TRUE, TRUE );
+            aFunc.UnmergeCells( aMergeOption, TRUE, TRUE );
 
         //!	Fehler abfangen?
     }
diff --git a/sc/source/ui/view/cellmergeoption.cxx b/sc/source/ui/view/cellmergeoption.cxx
new file mode 100644
index 0000000..da53196
--- /dev/null
+++ b/sc/source/ui/view/cellmergeoption.cxx
@@ -0,0 +1,74 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2010 by Novell, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: docfunc.hxx,v $
+ * $Revision: 1.18.30.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.
+ *
+ ************************************************************************/
+
+#include "cellmergeoption.hxx"
+#include "address.hxx"
+
+ScCellMergeOption::ScCellMergeOption() :
+    mnStartCol(0),
+    mnStartRow(0),
+    mnEndCol(0),
+    mnEndRow(0),
+    mbCenter(false)
+{
+}
+
+ScCellMergeOption::ScCellMergeOption(SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bCenter) :
+    mnStartCol(nStartCol),
+    mnStartRow(nStartRow),
+    mnEndCol(nEndCol),
+    mnEndRow(nEndRow),
+    mbCenter(bCenter)
+{
+}
+
+ScCellMergeOption::ScCellMergeOption(const ScCellMergeOption& r) :
+    maTabs(r.maTabs),
+    mnStartCol(r.mnStartCol),
+    mnStartRow(r.mnStartRow),
+    mnEndCol(r.mnEndCol),
+    mnEndRow(r.mnEndRow),
+    mbCenter(r.mbCenter)
+{
+}
+
+ScRange ScCellMergeOption::getSingleRange(SCTAB nTab) const
+{
+    return ScRange(mnStartCol, mnStartRow, nTab, mnEndCol, mnEndRow, nTab);
+}
+
+ScRange ScCellMergeOption::getFirstSingleRange() const
+{
+    SCTAB nTab = 0;
+    if (!maTabs.empty())
+        nTab = *maTabs.begin();
+
+    return getSingleRange(nTab);
+}
diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx
index e08ec21..a2a7520 100644
--- a/sc/source/ui/view/cellsh3.cxx
+++ b/sc/source/ui/view/cellsh3.cxx
@@ -769,6 +769,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
             {
                 // test whether to merge or to split
                 bool bMerge = false;
+                BOOL bCenter = FALSE;
                 switch( nSlot )
                 {
                     case FID_MERGE_ON:
@@ -779,6 +780,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
                     break;
                     case FID_MERGE_TOGGLE:
                     {
+                        bCenter = TRUE;
                         SfxPoolItem* pItem = 0;
                         if( rBindings.QueryState( nSlot, pItem ) >= SFX_ITEM_DEFAULT )
                             bMerge = !static_cast< SfxBoolItem* >( pItem )->GetValue();
@@ -799,7 +801,7 @@ void ScCellShell::Execute( SfxRequest& rReq )
                         bMoveContents = ((const SfxBoolItem*)pItem)->GetValue();
                     }
 
-                    if (pTabViewShell->MergeCells( bApi, bMoveContents ))
+                    if (pTabViewShell->MergeCells( bApi, bMoveContents, TRUE, bCenter ))
                     {
                         if (!bApi && bMoveContents)             // "ja" im Dialog geklickt
                             rReq.AppendItem( SfxBoolItem( nSlot, bMoveContents ) );
diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk
index 1b2fef9..521c5bd 100644
--- a/sc/source/ui/view/makefile.mk
+++ b/sc/source/ui/view/makefile.mk
@@ -96,6 +96,7 @@ SLOFILES =  \
         $(SLO)$/output3.obj \
         $(SLO)$/gridmerg.obj \
         $(SLO)$/invmerge.obj \
+        $(SLO)$/cellmergeoption.obj \
         $(SLO)$/select.obj \
         $(SLO)$/olinewin.obj \
         $(SLO)$/hintwin.obj \
diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx
index 89cabba..c341e8e 100644
--- a/sc/source/ui/view/viewfun2.cxx
+++ b/sc/source/ui/view/viewfun2.cxx
@@ -60,6 +60,7 @@
 #include "attrib.hxx"
 #include "autoform.hxx"
 #include "cell.hxx"					// EnterAutoSum
+#include "cellmergeoption.hxx"
 #include "compiler.hxx"
 #include "docfunc.hxx"
 #include "docpool.hxx"
@@ -1085,7 +1086,7 @@ BOOL ScViewFunc::TestMergeCells()			// Vorab-Test (fuer Menue)
 
 //----------------------------------------------------------------------------
 
-BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord )
+BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord, BOOL bCenter )
 {
     //	Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
     //	damit dann nicht die Inhalte-QueryBox kommt
@@ -1128,10 +1129,26 @@ BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord )
         return FALSE;
     }
 
+    // Check for the contents of all selected tables.
+    bool bAskDialog = false;
+    SCTAB nTabCount = pDoc->GetTableCount();
+    ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
+    for (SCTAB i = 0; i < nTabCount; ++i)
+    {
+        if (!rMark.GetTableSelect(i))
+            // this table is not selected.
+            continue;
+
+        aMergeOption.maTabs.insert(i);
+
+        if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
+            !pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
+            bAskDialog = true;
+    }
+
     BOOL bOk = TRUE;
 
-    if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
-         !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
+    if (bAskDialog)
     {
         if (!bApi)
         {
@@ -1151,7 +1168,7 @@ BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord )
     if (bOk)
     {
         HideCursor();
-        bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
+        bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
         ShowCursor();
 
         if (bOk)
@@ -1187,6 +1204,32 @@ BOOL ScViewFunc::TestRemoveMerge()
 
 //----------------------------------------------------------------------------
 
+static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
+{
+    bool bExtended = false;
+    if (rOption.mnStartCol > rRange.aStart.Col())
+    {
+        rOption.mnStartCol = rRange.aStart.Col();
+        bExtended = true;
+    }
+    if (rOption.mnStartRow > rRange.aStart.Row())
+    {
+        rOption.mnStartRow = rRange.aStart.Row();
+        bExtended = true;
+    }
+    if (rOption.mnEndCol < rRange.aEnd.Col())
+    {
+        rOption.mnEndCol = rRange.aEnd.Col();
+        bExtended = true;
+    }
+    if (rOption.mnEndRow < rRange.aEnd.Row())
+    {
+        rOption.mnEndRow = rRange.aEnd.Row();
+        bExtended = true;
+    }
+    return bExtended;
+}
+
 BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
 {
     ScRange aRange;
@@ -1198,12 +1241,39 @@ BOOL ScViewFunc::RemoveMerge( BOOL bRecord )
     }
     else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
     {
+        ScDocument* pDoc = GetViewData()->GetDocument();
         ScRange aExtended( aRange );
-        GetViewData()->GetDocument()->ExtendMerge( aExtended );
+        pDoc->ExtendMerge( aExtended );
         ScDocShell* pDocSh = GetViewData()->GetDocShell();
+        const ScMarkData& rMark = GetViewData()->GetMarkData();
+        SCTAB nTabCount = pDoc->GetTableCount();
+        ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
+        bool bExtended = false;
+        do
+        {
+            bExtended = false;
+            for (SCTAB i = 0; i < nTabCount; ++i)
+            {
+                if (!rMark.GetTableSelect(i))
+                    // This table is not selected.
+                    continue;
+
+                aOption.maTabs.insert(i);
+                aExtended.aStart.SetTab(i);
+                aExtended.aEnd.SetTab(i);
+                pDoc->ExtendMerge(aExtended);
+                pDoc->ExtendOverlapped(aExtended);
+
+                // Expand the current range to be inclusive of all merged
+                // areas on all sheets.
+                bExtended = lcl_extendMergeRange(aOption, aExtended);
+            }
+        }
+        while (bExtended);
 
         HideCursor();
-        BOOL bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, FALSE );
+        BOOL bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord, FALSE );
+        aExtended = aOption.getFirstSingleRange();
         MarkRange( aExtended );
         ShowCursor();
 
diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml
index 9132cc2..959e538 100644
--- a/sc/uiconfig/scalc/menubar/menubar.xml
+++ b/sc/uiconfig/scalc/menubar/menubar.xml
@@ -220,7 +220,13 @@
                     <menu:menuitem menu:id=".uno:SetTabBgColor"/>
                 </menu:menupopup>
             </menu:menu>
-            <menu:menuitem menu:id=".uno:ToggleMergeCells"/>
+            <menu:menu menu:id=".uno:MergeCellsMenu">
+                <menu:menupopup>
+                    <menu:menuitem menu:id=".uno:ToggleMergeCells"/>
+                    <menu:menuitem menu:id=".uno:MergeCells"/>
+                    <menu:menuitem menu:id=".uno:SplitCell"/>
+                </menu:menupopup>
+            </menu:menu>
             <menu:menuseparator/>
             <menu:menuitem menu:id=".uno:PageFormatDialog"/>
             <menu:menu menu:id=".uno:PrintRangesMenu">
commit 64c43addcd6bb9ce2dde27fa996baa513870c283
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:32:16 2010 +0200

    calc-html-csv-import-force-text-cell.diff: Migrated
    
    n#523414
    set cell format to Text when a string format is requested, and don't
    prepend ' in front of the value.

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 7b8ec82..2796015 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -66,6 +66,7 @@ struct ScFunctionData;
 struct ScLineFlags;
 struct ScMergePatternState;
 class ScFlatBoolRowSegments;
+struct ScSetStringParam;
 
 #define COLUMN_DELTA	4
 
@@ -236,8 +237,7 @@ public:
                 //	TRUE = Zahlformat gesetzt
     BOOL		SetString( SCROW nRow, SCTAB nTab, const String& rString,
                            formula::FormulaGrammar::AddressConvention conv = formula::FormulaGrammar::CONV_OOO,
-                           SvNumberFormatter* pFormatter = NULL,
-                           bool bDetectNumberFormat = true );
+                           ScSetStringParam* pParam = NULL );
     void		SetValue( SCROW nRow, const double& rVal);
     void		SetError( SCROW nRow, const USHORT nError);
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index bbe9640..9112c6d 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -146,6 +146,7 @@ class ScFormulaParserPool;
 struct ScClipParam;        
 struct ScClipRangeNameData;
 class ScRowBreakIterator;
+struct ScSetStringParam;
 
 namespace com { namespace sun { namespace star {
     namespace lang {
@@ -773,7 +774,7 @@ public:
                     //	return TRUE = Zahlformat gesetzt
     SC_DLLPUBLIC BOOL           SetString(
         SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, 
-        SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true );
+        ScSetStringParam* pParam = NULL );
     SC_DLLPUBLIC void           SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal );
     void 			SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const USHORT nError);
 
diff --git a/sc/inc/stringutil.hxx b/sc/inc/stringutil.hxx
index 4ca8629..3468640 100644
--- a/sc/inc/stringutil.hxx
+++ b/sc/inc/stringutil.hxx
@@ -32,6 +32,41 @@
 #define SC_STRINGUTIL_HXX
 
 #include "rtl/ustring.hxx"
+#include "scdllapi.h"
+
+class SvNumberFormatter;
+
+/**
+ * Store parameters used in the ScDocument::SetString() method.  Various
+ * options for string-setting operation are specified herein.
+ */
+struct SC_DLLPUBLIC ScSetStringParam
+{
+    /**
+     * Stores the pointer to the number formatter instance to be used during
+     * number format detection.  The caller must manage the life cycle of the
+     * instance.
+     */
+    SvNumberFormatter* mpNumFormatter;
+
+    /**
+     * When true, we try to detect special number format (dates etc) from the
+     * input string, when false, we only try to detect a basic decimal number
+     * format.
+     */
+    bool mbDetectNumberFormat;
+
+    /**
+     * When true, set the format of the cell to Text when a string cell is
+     * requested for a number input.  We may want to do this during text file
+     * import (csv, html etc).
+     */
+    bool mbSetTextCellFormat;
+
+    ScSetStringParam();
+};
+
+// ============================================================================
 
 class ScStringUtil
 {
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 746545d..c7ef0b2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -85,7 +85,7 @@ class CollatorWrapper;
 class ScFlatUInt16RowSegments;
 class ScFlatBoolRowSegments;
 class ScFlatBoolColSegments;
-
+struct ScSetStringParam;
 
 class ScTable
 {
@@ -301,7 +301,7 @@ public:
     void		PutCell(SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell);
                 //	TRUE = Zahlformat gesetzt
     BOOL		SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, 
-                           SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true );
+                           ScSetStringParam* pParam = NULL );
     void		SetValue( SCCOL nCol, SCROW nRow, const double& rVal );
     void 		SetError( SCCOL nCol, SCROW nRow, USHORT nError);
 
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index a44a7d1..b6ffc03 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -52,6 +52,7 @@
 #include "detfunc.hxx"			// fuer Notizen bei DeleteRange
 #include "postit.hxx"
 #include "stringutil.hxx"
+#include "docpool.hxx"
 
 #include <com/sun/star/i18n/LocaleDataItem.hpp>
 
@@ -1249,7 +1250,7 @@ void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 )
 //	TRUE = Zahlformat gesetzt
 BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                           formula::FormulaGrammar::AddressConvention eConv,
-                          SvNumberFormatter* pLangFormatter, bool bDetectNumberFormat )
+                          ScSetStringParam* pParam )
 {
     BOOL bNumFmtSet = FALSE;
     if (VALIDROW(nRow))
@@ -1258,14 +1259,15 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
         BOOL bIsLoading = FALSE;
         if (rString.Len() > 0)
         {
+            ScSetStringParam aParam;
+            if (pParam)
+                aParam = *pParam;
+
             double nVal;
             sal_uInt32 nIndex, nOldIndex = 0;
             sal_Unicode cFirstChar;
-            // #i110979# If a different NumberFormatter is passed in (pLangFormatter),
-            // its formats aren't valid in the document.
-            // Only use the language / LocaleDataWrapper from pLangFormatter,
-            // always the document's number formatter for IsNumberFormat.
-            SvNumberFormatter* pFormatter = pDocument->GetFormatTable();
+            if (!aParam.mpNumFormatter)
+                aParam.mpNumFormatter = pDocument->GetFormatTable();
             SfxObjectShell* pDocSh = pDocument->GetDocumentShell();
             if ( pDocSh )
                 bIsLoading = pDocSh->IsLoading();
@@ -1274,7 +1276,7 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
             {
                 nIndex = nOldIndex = GetNumberFormat( nRow );
                 if ( rString.Len() > 1
-                        && pFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
+                        && aParam.mpNumFormatter->GetType(nIndex) != NUMBERFORMAT_TEXT )
                     cFirstChar = rString.GetChar(0);
                 else
                     cFirstChar = 0;								// Text
@@ -1330,7 +1332,7 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                     }
                     // nIndex fuer IsNumberFormat vorbelegen
                     if ( !bIsText )
-                        nIndex = nOldIndex = pFormatter->GetStandardIndex();
+                        nIndex = nOldIndex = aParam.mpNumFormatter->GetStandardIndex();
                 }
 
                 do
@@ -1338,23 +1340,17 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                     if (bIsText)
                         break;
 
-                    if (bDetectNumberFormat)
+                    if (aParam.mbDetectNumberFormat)
                     {
-                        if ( pLangFormatter )
-                        {
-                            // for number detection: valid format index for selected language
-                            nIndex = pFormatter->GetStandardIndex( pLangFormatter->GetLanguage() );
-                        }
-
-                        if (!pFormatter->IsNumberFormat(rString, nIndex, nVal))
+                        if (!aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
                             break;
 
-                        if ( pLangFormatter )
+                        if ( aParam.mpNumFormatter )
                         {
                             // convert back to the original language if a built-in format was detected
-                            const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex );
+                            const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
                             if ( pOldFormat )
-                                nIndex = pFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() );
+                                nIndex = aParam.mpNumFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() );
                         }
 
                         pNewCell = new ScValueCell( nVal );
@@ -1365,21 +1361,21 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                             // Exception: If the new format is boolean, always apply it.
 
                             BOOL bOverwrite = FALSE;
-                            const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex );
+                            const SvNumberformat* pOldFormat = aParam.mpNumFormatter->GetEntry( nOldIndex );
                             if ( pOldFormat )
                             {
                                 short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED;
                                 if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE ||
                                      nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL )
                                 {
-                                    if ( nOldIndex == pFormatter->GetStandardFormat(
+                                    if ( nOldIndex == aParam.mpNumFormatter->GetStandardFormat(
                                                         nOldType, pOldFormat->GetLanguage() ) )
                                     {
                                         bOverwrite = TRUE;      // default of these types can be overwritten
                                     }
                                 }
                             }
-                            if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL )
+                            if ( !bOverwrite && aParam.mpNumFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL )
                             {
                                 bOverwrite = TRUE;              // overwrite anything if boolean was detected
                             }
@@ -1395,8 +1391,7 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                     else
                     {
                         // Only check if the string is a regular number.
-                        SvNumberFormatter* pLocaleSource = pLangFormatter ? pLangFormatter : pFormatter;
-                        const LocaleDataWrapper* pLocale = pLocaleSource->GetLocaleData();
+                        const LocaleDataWrapper* pLocale = aParam.mpNumFormatter->GetLocaleData();
                         if (!pLocale)
                             break;
                         
@@ -1418,7 +1413,19 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString,
                 while (false);
 
                 if (!pNewCell)
+                {
+                    if (aParam.mbSetTextCellFormat && aParam.mpNumFormatter->IsNumberFormat(rString, nIndex, nVal))
+                    {
+                        // Set the cell format type to Text.
+                        sal_uInt32 nFormat = aParam.mpNumFormatter->GetStandardFormat(NUMBERFORMAT_TEXT);
+                        ScPatternAttr aNewAttrs(pDocument->GetPool());
+                        SfxItemSet& rSet = aNewAttrs.GetItemSet();
+                        rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat) );
+                        ApplyPattern(nRow, aNewAttrs);
+                    }
+
                     pNewCell = new ScStringCell(rString);
+                }
             }
         }
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 0aa44d7..26719e5 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -2658,10 +2658,10 @@ void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell, BOOL bForceT
 
 
 BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, 
-                            SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
+                            ScSetStringParam* pParam )
 {
     if ( ValidTab(nTab) && pTab[nTab] )
-        return pTab[nTab]->SetString( nCol, nRow, nTab, rString, pFormatter, bDetectNumberFormat );
+        return pTab[nTab]->SetString( nCol, nRow, nTab, rString, pParam );
     else
         return FALSE;
 }
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 093a8a1..a5eb818 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1015,11 +1015,11 @@ void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell )
 
 
 BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString, 
-                         SvNumberFormatter* pFormatter, bool bDetectNumberFormat )
+                         ScSetStringParam* pParam )
 {
     if (ValidColRow(nCol,nRow))
         return aCol[nCol].SetString( 
-            nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat );
+            nRow, nTabP, rString, pDocument->GetAddressConvention(), pParam );
     else
         return FALSE;
 }
diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx
index ae6247f..d5e09a6 100644
--- a/sc/source/core/tool/stringutil.cxx
+++ b/sc/source/core/tool/stringutil.cxx
@@ -40,6 +40,15 @@
 using ::rtl::OUString;
 using ::rtl::OUStringBuffer;
 
+ScSetStringParam::ScSetStringParam() :
+    mpNumFormatter(NULL),
+    mbDetectNumberFormat(true),
+    mbSetTextCellFormat(false)
+{
+}
+
+// ============================================================================-
+
 bool ScStringUtil::parseSimpleNumber(
     const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal)
 {
diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx
index 0bc43ca..fadb53e 100644
--- a/sc/source/filter/rtf/eeimpars.cxx
+++ b/sc/source/filter/rtf/eeimpars.cxx
@@ -66,6 +66,7 @@
 #include "drwlayer.hxx"
 #include "rangenam.hxx"
 #include "progress.hxx"
+#include "stringutil.hxx"
 
 #include "globstr.hrc"
 
@@ -329,12 +330,17 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNu
             // Daten eintragen
             if (bSimple)
             {
+                ScSetStringParam aParam;
+                aParam.mpNumFormatter = pFormatter;
+                aParam.mbDetectNumberFormat = true;
+                aParam.mbSetTextCellFormat = true;
+
                 if ( aValStr.Len() )
                     mpDoc->SetValue( nCol, nRow, nTab, fVal );
                 else if ( !pE->aSel.HasRange() )
                 {
                     // maybe ALT text of IMG or similar
-                    mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, pFormatter );
+                    mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, &aParam );
                     // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen!
                 }
                 else
@@ -379,7 +385,10 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNu
                     if (bNumbersEnglishUS && !bEnUsRecognized)
                         mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr));
                     else
-                        mpDoc->SetString( nCol, nRow, nTab, aStr, pFormatter, bConvertDate );
+                    {
+                        aParam.mbDetectNumberFormat = bConvertDate;
+                        mpDoc->SetString( nCol, nRow, nTab, aStr, &aParam );
+                    }
                 }
             }
             else
diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx
index 1edfc2d..3b8182e 100644
--- a/sc/source/ui/docshell/impex.cxx
+++ b/sc/source/ui/docshell/impex.cxx
@@ -82,6 +82,9 @@ class StarBASIC;
 
 // ause
 #include "editutil.hxx"
+#include "patattr.hxx"
+#include "docpool.hxx"
+#include "stringutil.hxx"
 
 #include "globstr.hrc"
 #include <vcl/msgbox.hxx>
@@ -914,6 +917,18 @@ static bool lcl_PutString(
 
     if ( nColFormat == SC_COL_TEXT )
     {
+        double fDummy;
+        sal_uInt32 nIndex;
+        if (pFormatter->IsNumberFormat(rStr, nIndex, fDummy))
+        {
+            // Set the format of this cell to Text.
+            sal_uInt32 nFormat = pFormatter->GetStandardFormat(NUMBERFORMAT_TEXT);
+            ScPatternAttr aNewAttrs(pDoc->GetPool());
+            SfxItemSet& rSet = aNewAttrs.GetItemSet();
+            rSet.Put( SfxUInt32Item(ATTR_VALUE_FORMAT, nFormat) );
+            pDoc->ApplyPattern(nCol, nRow, nTab, aNewAttrs);
+
+        }
         pDoc->PutCell( nCol, nRow, nTab, ScBaseCell::CreateTextCell( rStr, pDoc ) );
         return bMultiLine;
     }
@@ -1126,7 +1141,13 @@ static bool lcl_PutString(
 
     // Standard or date not determined -> SetString / EditCell
     if( rStr.Search( _LF ) == STRING_NOTFOUND )
-        pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat );
+    {
+        ScSetStringParam aParam;
+        aParam.mpNumFormatter = pFormatter;
+        aParam.mbDetectNumberFormat = bDetectNumFormat;
+        aParam.mbSetTextCellFormat = true;
+        pDoc->SetString( nCol, nRow, nTab, rStr, &aParam );
+    }
     else 
     {
         bMultiLine = true;
commit 7b2297f149ffbcece78a3c0107b006be38618087
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:27:59 2010 +0200

    calc-autofilter-shrink-selection.diff: Migrated
    
    n#514164,  shrink selection to data area before setting autofilter.

diff --git a/sc/source/ui/view/dbfunc.cxx b/sc/source/ui/view/dbfunc.cxx
index 2eefb06..891cf0e 100644
--- a/sc/source/ui/view/dbfunc.cxx
+++ b/sc/source/ui/view/dbfunc.cxx
@@ -344,7 +344,7 @@ void ScDBFunc::ToggleAutoFilter()
 
     ScQueryParam	aParam;
     ScDocument*		pDoc	= GetViewData()->GetDocument();
-    ScDBData*		pDBData = GetDBData( FALSE, SC_DB_MAKE, SC_DBSEL_ROW_DOWN );
+    ScDBData*		pDBData = GetDBData(false, SC_DB_MAKE, SC_DBSEL_ROW_DOWN, false, true);
 
     pDBData->SetByRow( TRUE );				//! Undo, vorher abfragen ??
     pDBData->GetQueryParam( aParam );
commit 49af023527783e80bec13bb4cdce7b43cac1f262
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Thu Sep 16 11:21:13 2010 +0200

    calc-cursor-split-view.diff: show cursor in non-active panes
    
    n#433834

diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index da7bfb4..fb8511c 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -5264,24 +5264,16 @@ void ScGridWindow::UpdateCursorOverlay()
             if ( bLayoutRTL )
                 aScrPos.X() -= nSizeXPix - 2;       // move instead of mirroring
 
-            BOOL bFix = ( pViewData->GetHSplitMode() == SC_SPLIT_FIX ||
-                            pViewData->GetVSplitMode() == SC_SPLIT_FIX );
-            if ( pViewData->GetActivePart()==eWhich || bFix )
-            {
-                aScrPos.X() -= 2;
-                aScrPos.Y() -= 2;
-                Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
-
-                aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
-                aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
-                aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
-                aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
-            }
-            else
-            {
-                Rectangle aRect( aScrPos, Size( nSizeXPix - 1, nSizeYPix - 1 ) );
-                aPixelRects.push_back( aRect );
-            }
+            // Now, draw the cursor.
+
+            aScrPos.X() -= 2;
+            aScrPos.Y() -= 2;
+            Rectangle aRect( aScrPos, Size( nSizeXPix + 3, nSizeYPix + 3 ) );
+
+            aPixelRects.push_back(Rectangle( aRect.Left(), aRect.Top(), aRect.Left()+2, aRect.Bottom() ));
+            aPixelRects.push_back(Rectangle( aRect.Right()-2, aRect.Top(), aRect.Right(), aRect.Bottom() ));
+            aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Top(), aRect.Right()-3, aRect.Top()+2 ));
+            aPixelRects.push_back(Rectangle( aRect.Left()+3, aRect.Bottom()-2, aRect.Right()-3, aRect.Bottom() ));
         }
     }
 
@@ -5292,7 +5284,10 @@ void ScGridWindow::UpdateCursorOverlay()
 
         if(pOverlayManager)
         {
-            const Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+            Color aCursorColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+            if (pViewData->GetActivePart() != eWhich)
+                // non-active pane uses a different color.
+                aCursorColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
             std::vector< basegfx::B2DRange > aRanges;
             const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
             
@@ -5441,7 +5436,10 @@ void ScGridWindow::UpdateAutoFillOverlay()
 
         if(pOverlayManager)
         {
-            const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+            Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor );
+            if (pViewData->GetActivePart() != eWhich)
+                // non-active pane uses a different color.
+                aHandleColor = SC_MOD()->GetColorConfig().GetColorValue(svtools::CALCPAGEBREAKAUTOMATIC).nColor;
             std::vector< basegfx::B2DRange > aRanges;
             const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation());
             basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1);


More information about the ooo-build-commit mailing list