ooo-build r15411 - in trunk: . patches/dev300
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r15411 - in trunk: . patches/dev300
- Date: Tue, 24 Feb 2009 22:45:34 +0000 (UTC)
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]