ooo-build r15411 - in trunk: . patches/dev300



Author: kyoshida
Date: Tue Feb 24 22:45:34 2009
New Revision: 15411
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15411&view=rev

Log:
2009-02-24  Kohei Yoshida  <kyoshida novell com>

	* patches/dev300/calc-multisheet-merge-cells.diff:
	* patches/dev300/apply: support merging and unmerging of cells on 
	multiple sheets. (n#213205)


Added:
   trunk/patches/dev300/calc-multisheet-merge-cells.diff
Modified:
   trunk/ChangeLog
   trunk/patches/dev300/apply

Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply	(original)
+++ trunk/patches/dev300/apply	Tue Feb 24 22:45:34 2009
@@ -1978,6 +1978,9 @@
 calc-find-replace-empty-cells-sc.diff  i#49380, n#415352, kohei
 calc-find-replace-empty-cells-svx.diff i#49380, n#415352, kohei
 
+# Support merging and unmerging of cells on multiple sheets.
+calc-multisheet-merge-cells.diff, n#213205, kohei
+
 [ CalcRowLimit ]
 # The work to increase Calc's row size limit, and any work associated with it.
 SectionOwner => kohei

Added: trunk/patches/dev300/calc-multisheet-merge-cells.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/calc-multisheet-merge-cells.diff	Tue Feb 24 22:45:34 2009
@@ -0,0 +1,981 @@
+diff --git sc/source/ui/docshell/docfunc.cxx sc/source/ui/docshell/docfunc.cxx
+index 4936634..243b637 100644
+--- sc/source/ui/docshell/docfunc.cxx
++++ sc/source/ui/docshell/docfunc.cxx
+@@ -67,6 +67,7 @@
+ #include "attrib.hxx"
+ #include "autoform.hxx"
+ #include "cell.hxx"
++#include "cellmergeoption.hxx"
+ #include "detdata.hxx"
+ #include "detfunc.hxx"
+ #include "docpool.hxx"
+@@ -101,6 +102,7 @@
+ #include "tabprotection.hxx"
+ 
+ #include <memory>
++#include <set>
+ 
+ using namespace com::sun::star;
+ using ::com::sun::star::uno::Sequence;
+@@ -3906,78 +3908,97 @@ BOOL ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark, FillDir e
+ 
+ //------------------------------------------------------------------------
+ 
+-BOOL ScDocFunc::MergeCells( const ScRange& rRange, BOOL bContents, BOOL bRecord, BOOL bApi, BOOL bCenter )
++BOOL ScDocFunc::MergeCells( const ScCellMergeOption& rOption, BOOL bContents, BOOL bRecord, BOOL bApi )
+ {
++    using ::std::set;
++
+ 	ScDocShellModificator aModificator( rDocShell );
+ 
+-	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();
++    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();
++    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())
+-	{
+-		if (!bApi)
+-			rDocShell.ErrorMessage(aTester.GetMessageId());
+-		return FALSE;
+-	}
+-
+-	if ( nStartCol == nEndCol && nStartRow == nEndRow )
+-	{
+-		// nichts zu tun
+-		return TRUE;
+-	}
++    for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
++    {
++        ScEditableTester aTester( pDoc, *itr, nStartCol, nStartRow, nEndCol, nEndRow );
++        if (!aTester.IsEditable())
++        {
++            if (!bApi)
++                rDocShell.ErrorMessage(aTester.GetMessageId());
++            return FALSE;
++        }
+ 
+-	if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+-							HASATTR_MERGED | HASATTR_OVERLAPPED ) )
+-	{
+-		// "Zusammenfassen nicht verschachteln !"
+-		if (!bApi)
+-			rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
+-		return FALSE;
+-	}
++        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;
++        }
++    }
+ 
+-	BOOL bNeedContents = bContents &&
+-			( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow ) ||
+-			  !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow ) );
++    ScDocument* pUndoDoc = NULL;
++    for (set<SCTAB>::const_iterator itr = itrBeg; itr != itrEnd; ++itr)
++    {
++        SCTAB nTab = *itr;
++        BOOL bNeedContents = bContents &&
++                ( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow ) ||
++                  !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow ) );
++    
++        if (bRecord)
++        {
++            if ( (bNeedContents && bContents) || rOption.mbCenter )
++            {
++                if (!pUndoDoc)
++                {    
++                    pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
++                    pUndoDoc->InitUndo(pDoc, nTab1, nTab2);
++                }
++                pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
++                                        IDF_ALL, FALSE, pUndoDoc );
++            }
++        }
+ 
+-	if (bRecord)
+-	{
+-		ScDocument* pUndoDoc = NULL;
+-		if ( (bNeedContents && bContents) || bCenter )
+-		{
+-			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
+-			pUndoDoc->InitUndo( pDoc, nTab, nTab );
+-			pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
+-									IDF_ALL, FALSE, pUndoDoc );
+-		}
+-		rDocShell.GetUndoManager()->AddUndoAction(
+-			new ScUndoMerge( &rDocShell,
+-							nStartCol, nStartRow, nTab,
+-							nEndCol, nEndRow, nTab, TRUE, pUndoDoc, bCenter) );
+-	}
++        if (bNeedContents && bContents)
++            pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
++        pDoc->DoMerge( nTab, nStartCol, nStartRow, nEndCol, nEndRow );
++        
++        if (rOption.mbCenter)
++        {
++            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 ( !AdjustRowHeight( ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab ) ) )
++            rDocShell.PostPaint( nStartCol, nStartRow, nTab,
++                                 nEndCol, nEndRow, nTab, PAINT_GRID );
++        if ( (bNeedContents && bContents) || rOption.mbCenter )
++        {
++            ScRange aRange(nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab);
++            pDoc->SetDirty(aRange);
++        }
++    }
+ 
+-	if (bNeedContents && bContents)
+-		pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+-	pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
+-	
+-	if (bCenter)
+-	{
+-		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 (pUndoDoc)
++    {
++        rDocShell.GetUndoManager()->AddUndoAction(
++            new ScUndoMerge(&rDocShell, rOption, TRUE, pUndoDoc) );
++    }
+ 
+-	if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
+-		rDocShell.PostPaint( nStartCol, nStartRow, nTab,
+-											nEndCol, nEndRow, nTab, PAINT_GRID );
+-	if ( (bNeedContents && bContents) || bCenter )
+-		pDoc->SetDirty( rRange );
+ 	aModificator.SetDocumentModified();
+ 
+ 	SfxBindings* pBindings = rDocShell.GetViewBindings();
+@@ -3993,49 +4014,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 ) )
+-	{
+-		ScRange aExtended = rRange;
+-		pDoc->ExtendMerge( aExtended );
+-		ScRange aRefresh = aExtended;
+-		pDoc->ExtendOverlapped( aRefresh );
++    ScDocument* pUndoDoc = NULL;
++    bool bBeep = false;
++    for (set<SCTAB>::const_iterator itr = rOption.maTabs.begin(), itrEnd = rOption.maTabs.end();
++          itr != itrEnd; ++itr)
++    {
++        SCTAB nTab = *itr;
++        ScRange aRange = rOption.getSingleRange(nTab);
++        if ( !pDoc->HasAttrib(aRange, HASATTR_MERGED) )
++        {
++            bBeep = true;
++            continue;
++        }
+ 
+-		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 ) );
+-		}
++        ScRange aExtended = aRange;
++        pDoc->ExtendMerge(aExtended);
++        ScRange aRefresh = aExtended;
++        pDoc->ExtendOverlapped(aRefresh);
+ 
+-		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 );
++        if (bRecord)
++        {
++            if (!pUndoDoc)
++            {
++                pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
++                pUndoDoc->InitUndo(pDoc, *rOption.maTabs.begin(), *rOption.maTabs.rbegin());
++            }
++            pDoc->CopyToDocument(aExtended, IDF_ATTRIB, FALSE, pUndoDoc);
++        }
+ 
+-		pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
+-								aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
+-								SC_MF_HOR | SC_MF_VER );
++        const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
++        ScPatternAttr aPattern( pDoc->GetPool() );
++        aPattern.GetItemSet().Put( rDefAttr );
++        pDoc->ApplyPatternAreaTab( aRange.aStart.Col(), aRange.aStart.Row(),
++                                   aRange.aEnd.Col(), aRange.aEnd.Row(), nTab,
++                                   aPattern );
+ 
+-		pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
++        pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
++                              aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
++                              SC_MF_HOR | SC_MF_VER );
+ 
+-		if ( !AdjustRowHeight( aExtended ) )
+-			rDocShell.PostPaint( aExtended, PAINT_GRID );
+-		aModificator.SetDocumentModified();
+-	}
+-	else if (!bApi)
+-		Sound::Beep();		//! FALSE zurueck???
++        pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
++
++        if ( !AdjustRowHeight( aExtended ) )
++            rDocShell.PostPaint( aExtended, PAINT_GRID );
++    }
++    if (bBeep && !bApi)
++        Sound::Beep();
++
++    if (bRecord)
++    {
++        rDocShell.GetUndoManager()->AddUndoAction(
++            new ScUndoRemoveMerge( &rDocShell, rOption, pUndoDoc ) );
++    }
++    aModificator.SetDocumentModified();
+ 
+ 	return TRUE;
+ }
+diff --git sc/source/ui/inc/cellmergeoption.hxx sc/source/ui/inc/cellmergeoption.hxx
+new file mode 100644
+index 0000000..2e2dff2
+--- /dev/null
++++ sc/source/ui/inc/cellmergeoption.hxx
+@@ -0,0 +1,60 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: 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 sc/source/ui/inc/docfunc.hxx sc/source/ui/inc/docfunc.hxx
+index cf19ea2..bafd306 100644
+--- sc/source/ui/inc/docfunc.hxx
++++ sc/source/ui/inc/docfunc.hxx
+@@ -49,6 +49,7 @@ class ScBaseCell;
+ class ScTokenArray;
+ struct ScTabOpParam;
+ class ScTableProtection;
++struct ScCellMergeOption;
+ 
+ // ---------------------------------------------------------------------------
+ 
+@@ -168,9 +169,10 @@ public:
+ 
+ 	BOOL			ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, BOOL bApi );
+ 
+-	BOOL			MergeCells( const ScRange& rRange, BOOL bContents,
+-								BOOL bRecord, BOOL bApi, BOOL bCenter );
++	BOOL			MergeCells( const ScCellMergeOption& rOption, BOOL bContents,
++								BOOL bRecord, BOOL bApi );
+ 	BOOL			UnmergeCells( const ScRange& rRange, BOOL bRecord, BOOL bApi );
++	bool			UnmergeCells( const ScCellMergeOption& rOption, BOOL bRecord, BOOL bApi );
+ 
+ 	BOOL			SetNote( const ScAddress& rPos, const ScPostIt& rNote, BOOL bApi );
+ 
+diff --git sc/source/ui/inc/undoblk.hxx sc/source/ui/inc/undoblk.hxx
+index 25634dd..2f8ef78 100644
+--- sc/source/ui/inc/undoblk.hxx
++++ sc/source/ui/inc/undoblk.hxx
+@@ -34,6 +34,7 @@
+ #include "markdata.hxx"
+ #include "viewutil.hxx"
+ #include "spellparam.hxx"
++#include "cellmergeoption.hxx"
+ 
+ #include "cell.hxx"
+ 
+@@ -454,11 +455,8 @@ class ScUndoMerge: public ScSimpleUndo
+ {
+ public:
+ 					TYPEINFO();
+-					ScUndoMerge( ScDocShell* pNewDocShell,
+-								 SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+-								 SCCOL nEndX,   SCROW nEndY,   SCTAB nEndZ,
+-								 BOOL bNewDoMerge, ScDocument* pNewUndoDoc = NULL,
+-								 BOOL bNewCenter = FALSE );
++					ScUndoMerge(ScDocShell* pNewDocShell, const ScCellMergeOption& rOption,
++								BOOL bNewDoMerge, ScDocument* pNewUndoDoc = NULL);
+ 	virtual 		~ScUndoMerge();
+ 
+ 	virtual void	Undo();
+@@ -469,10 +467,9 @@ public:
+ 	virtual String	GetComment() const;
+ 
+ private:
+-	ScRange			aRange;
++    ScCellMergeOption maOption;
+ 	BOOL			bDoMerge;				// Merge oder aufheben
+ 	ScDocument*		pUndoDoc;				// wenn Daten zusammengefasst
+-	BOOL			bCenter;
+ 
+ 	void			DoChange( const BOOL bUndo ) const;
+ };
+@@ -921,7 +918,7 @@ class ScUndoRemoveMerge: public ScBlockUndo
+ public:
+ 					TYPEINFO();
+ 					ScUndoRemoveMerge( ScDocShell* pNewDocShell,
+-									   const ScRange& rArea,
++									   const ScCellMergeOption& rOption,
+ 									   ScDocument* pNewUndoDoc );
+ 	virtual 		~ScUndoRemoveMerge();
+ 
+@@ -933,6 +930,9 @@ public:
+ 	virtual String	GetComment() const;
+ 
+ private:
++    void            SetCurTab();
++
++    ScCellMergeOption maOption;
+ 	ScDocument*		pUndoDoc;
+ };
+ 
+diff --git sc/source/ui/undo/undoblk.cxx sc/source/ui/undo/undoblk.cxx
+index 4d2cd3a..ff4d654 100644
+--- sc/source/ui/undo/undoblk.cxx
++++ sc/source/ui/undo/undoblk.cxx
+@@ -66,6 +66,7 @@
+ #include "undoolk.hxx"
+ #include "sc.hrc"
+ 
++#include <set>
+ 
+ // STATIC DATA -----------------------------------------------------------
+ 
+@@ -2038,8 +2039,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 )
+ {
+ }
+@@ -2056,66 +2058,78 @@ String __EXPORT ScUndoRemoveMerge::GetComment() const
+ 
+ void __EXPORT ScUndoRemoveMerge::Undo()
+ {
+-	BeginUndo();
+-
+-	ScDocument* pDoc = pDocShell->GetDocument();
++    using ::std::set;
+ 
+-	ScRange aExtended = aBlockRange;
+-	pUndoDoc->ExtendMerge( aExtended );
++    SetCurTab();
++    BeginUndo();
+ 
+-	pDoc->DeleteAreaTab( aExtended, IDF_ATTRIB );
+-	pUndoDoc->CopyToDocument( aExtended, IDF_ATTRIB, FALSE, pDoc );
++    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ 
+-	BOOL bDidPaint = FALSE;
+-	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+-	if ( pViewShell )
+-	{
+-		pViewShell->SetTabNo( aExtended.aStart.Tab() );
+-		bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+-	}
+-	if (!bDidPaint)
+-		ScUndoUtil::PaintMore( pDocShell, aExtended );
++	ScDocument* pDoc = pDocShell->GetDocument();
++    for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
++          itr != itrEnd; ++itr)
++    {
++        // 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);
++    }
+ 
+ 	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 );
+-
+-	//	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 );
+-
+-	pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
+-							aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
+-							SC_MF_HOR | SC_MF_VER );
+-
+-	pDoc->ExtendMerge( aRefresh, TRUE, FALSE );
+-
+-	//	Paint
++    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ 
+-	BOOL bDidPaint = FALSE;
+-	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+-	if ( pViewShell )
+-	{
+-		pViewShell->SetTabNo( aExtended.aStart.Tab() );
+-		bDidPaint = pViewShell->AdjustRowHeight( aExtended.aStart.Row(), aExtended.aEnd.Row() );
+-	}
+-	if (!bDidPaint)
+-		ScUndoUtil::PaintMore( pDocShell, aExtended );
++    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
++    
++        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( maOption.mnStartCol, maOption.mnStartRow,
++                              maOption.mnEndCol, maOption.mnEndRow, nTab,
++                              SC_MF_HOR | SC_MF_VER );
++    
++        pDoc->ExtendMerge(aRange, TRUE, FALSE);
++
++        //	Paint
++
++        BOOL bDidPaint = FALSE;
++        if ( pViewShell )
++        {
++            pViewShell->SetTabNo(nTab);
++            bDidPaint = pViewShell->AdjustRowHeight(maOption.mnStartRow, maOption.mnEndRow);
++        }
++        if (!bDidPaint)
++            ScUndoUtil::PaintMore(pDocShell, aRange);
++    }
+ 
+ 	EndRedo();
+ }
+@@ -2131,6 +2145,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 sc/source/ui/undo/undoblk3.cxx sc/source/ui/undo/undoblk3.cxx
+index a04b997..9d92944 100644
+--- sc/source/ui/undo/undoblk3.cxx
++++ sc/source/ui/undo/undoblk3.cxx
+@@ -793,18 +793,14 @@ BOOL __EXPORT ScUndoAutoFill::CanRepeat(SfxRepeatTarget& rTarget) const
+ 
+ //----------------------------------------------------------------------------
+ 
+-ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell,
+-							SCCOL nStartX, SCROW nStartY, SCTAB nStartZ,
+-							SCCOL nEndX, SCROW nEndY, SCTAB nEndZ,
+-							BOOL bNewDoMerge, ScDocument* pNewUndoDoc,
+-							BOOL bNewCenter )
++ScUndoMerge::ScUndoMerge( ScDocShell* pNewDocShell, const ScCellMergeOption& rOption,
++                          BOOL bNewDoMerge, ScDocument* pNewUndoDoc)
+ 		//
+ 	:	ScSimpleUndo( pNewDocShell ),
+ 		//
+-		aRange	( nStartX, nStartY, nStartZ, nEndX, nEndY, nEndZ ),
++        maOption(rOption),
+ 		bDoMerge( bNewDoMerge ),
+-		pUndoDoc( pNewUndoDoc ),
+-		bCenter ( bNewCenter )
++		pUndoDoc( pNewUndoDoc )
+ {
+ }
+ 
+@@ -832,54 +828,64 @@ String __EXPORT ScUndoMerge::GetComment() const
+ 
+ void ScUndoMerge::DoChange( const BOOL bUndo ) const
+ {
+-	ScDocument* pDoc = pDocShell->GetDocument();
++    using ::std::set;
+ 
+-	ScUndoUtil::MarkSimpleBlock( pDocShell, aRange );
++    if (maOption.maTabs.empty())
++        // Nothing to do.
++        return;
+ 
+-	if (bDoMerge == bUndo)
+-		pDoc->RemoveMerge( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aStart.Tab() );
+-//!		pDoc->RemoveMerge( aRange.aStart );
+-	else
+-/*!*/	pDoc->DoMerge( aRange.aStart.Tab(),
+-					   aRange.aStart.Col(), aRange.aStart.Row(),
+-					   aRange.aEnd.Col(),   aRange.aEnd.Row()   );
++	ScDocument* pDoc = pDocShell->GetDocument();
++    ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+ 
+-	if (pUndoDoc)
+-	{
+-		if (bUndo)
+-		{
+-			pDoc->DeleteAreaTab( aRange, IDF_CONTENTS );
+-			pUndoDoc->CopyToDocument( aRange, IDF_ALL, FALSE, pDoc );
+-		}
+-		else
++    ScRange aCurRange = maOption.getSingleRange(pDocShell->GetCurTab());
++    ScUndoUtil::MarkSimpleBlock(pDocShell, aCurRange);
++
++    for (set<SCTAB>::const_iterator itr = maOption.maTabs.begin(), itrEnd = maOption.maTabs.end();
++          itr != itrEnd; ++itr)
++    {
++        SCTAB nTab = *itr;
++        ScRange aRange = maOption.getSingleRange(nTab);
++    
++        if (bDoMerge == bUndo)
++            pDoc->RemoveMerge( maOption.mnStartCol, maOption.mnStartRow, nTab );
++        else
++            pDoc->DoMerge( nTab, maOption.mnStartCol, maOption.mnStartRow,
++                           maOption.mnEndCol, maOption.mnEndRow );
++    
++        if (pUndoDoc)
+         {
+-/*!*/		pDoc->DoMergeContents( aRange.aStart.Tab(),
+-								   aRange.aStart.Col(), aRange.aStart.Row(),
+-								   aRange.aEnd.Col(),   aRange.aEnd.Row()   );
+-            if (bCenter)
++            if (bUndo)
++            {
++                pDoc->DeleteAreaTab(aRange, IDF_CONTENTS);
++                pUndoDoc->CopyToDocument(aRange, IDF_ALL, FALSE, pDoc);
++            }
++            else
+             {
+-                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 ) );
++                pDoc->DoMergeContents( nTab,
++                                       maOption.mnStartCol, maOption.mnStartRow,
++                                       maOption.mnEndCol, maOption.mnEndRow );
++                if (maOption.mbCenter)
++                {
++                    pDoc->ApplyAttr( maOption.mnStartCol, maOption.mnStartRow, nTab,
++                                     SvxHorJustifyItem( SVX_HOR_JUSTIFY_CENTER, ATTR_HOR_JUSTIFY ) );
++                    pDoc->ApplyAttr( maOption.mnStartCol, maOption.mnStartRow, nTab,
++                                     SvxVerJustifyItem( SVX_VER_JUSTIFY_CENTER, ATTR_VER_JUSTIFY ) );
++                }
+             }
+         }
+-	}
+ 
+-	BOOL bDidPaint = FALSE;
+-	ScTabViewShell* pViewShell = ScTabViewShell::GetActiveViewShell();
+-	if ( pViewShell )
+-	{
+-		pViewShell->SetTabNo( aRange.aStart.Tab() );
+-		bDidPaint = pViewShell->AdjustRowHeight( aRange.aStart.Row(), aRange.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, aRange);
++    }
+ 
+-	ShowTable( aRange );
++    ShowTable(aCurRange);
+ }
+ 
+ 
+diff --git sc/source/ui/unoobj/cellsuno.cxx sc/source/ui/unoobj/cellsuno.cxx
+index 79d5e40..4e7f35d 100644
+--- sc/source/ui/unoobj/cellsuno.cxx
++++ sc/source/ui/unoobj/cellsuno.cxx
+@@ -71,6 +71,7 @@
+ #include <com/sun/star/text/WritingMode2.hpp>
+ 
+ #include "autoform.hxx"
++#include "cellmergeoption.hxx"
+ #include "cellsuno.hxx"
+ #include "cursuno.hxx"
+ #include "textuno.hxx"
+@@ -5404,10 +5405,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, FALSE );
++			aFunc.MergeCells( aMergeOption, FALSE, TRUE, TRUE );
+ 		else
+-			aFunc.UnmergeCells( aRange, TRUE, TRUE );
++			aFunc.UnmergeCells( aMergeOption, TRUE, TRUE );
+ 
+ 		//!	Fehler abfangen?
+ 	}
+diff --git sc/source/ui/view/cellmergeoption.cxx sc/source/ui/view/cellmergeoption.cxx
+new file mode 100644
+index 0000000..ed6b8cb
+--- /dev/null
++++ sc/source/ui/view/cellmergeoption.cxx
+@@ -0,0 +1,74 @@
++/*************************************************************************
++ *
++ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
++ * 
++ * Copyright 2008 by Sun Microsystems, Inc.
++ *
++ * OpenOffice.org - a multi-platform office productivity suite
++ *
++ * $RCSfile: 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 sc/source/ui/view/makefile.mk sc/source/ui/view/makefile.mk
+index 48395f3..46b8122 100644
+--- sc/source/ui/view/makefile.mk
++++ sc/source/ui/view/makefile.mk
+@@ -100,6 +100,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 sc/source/ui/view/viewfun2.cxx sc/source/ui/view/viewfun2.cxx
+index 050e3fb..19d87b2 100644
+--- sc/source/ui/view/viewfun2.cxx
++++ sc/source/ui/view/viewfun2.cxx
+@@ -70,6 +70,7 @@ using namespace com::sun::star;
+ #include "attrib.hxx"
+ #include "autoform.hxx"
+ #include "cell.hxx"					// EnterAutoSum
++#include "cellmergeoption.hxx"
+ #include "compiler.hxx"
+ #include "docfunc.hxx"
+ #include "docpool.hxx"
+@@ -1129,11 +1130,27 @@ BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord, BOOL bC
+ 		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;
+ 	BOOL bNeedContents = FALSE;
+ 
+-	if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow ) ||
+-		 !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow ) )
++    if (bAskDialog)
+ 	{
+ 		bNeedContents = TRUE;
+ 		if (!bApi)
+@@ -1154,7 +1171,7 @@ BOOL ScViewFunc::MergeCells( BOOL bApi, BOOL& rDoContents, BOOL bRecord, BOOL bC
+ 	if (bOk)
+ 	{
+ 		HideCursor();
+-		bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi, bCenter );
++		bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
+ 		ShowCursor();
+ 
+ 		if (bOk)
+@@ -1190,6 +1207,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;
+@@ -1201,12 +1244,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();
+ 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]