xref: /aoo42x/main/sc/source/ui/docshell/docfunc.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #include "scitems.hxx"
36*cdf0e10cSrcweir #include <editeng/eeitem.hxx>
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir #include <sfx2/app.hxx>
39*cdf0e10cSrcweir #include <editeng/editobj.hxx>
40*cdf0e10cSrcweir #include <sfx2/linkmgr.hxx>
41*cdf0e10cSrcweir #include <svx/svdundo.hxx>
42*cdf0e10cSrcweir #include <sfx2/bindings.hxx>
43*cdf0e10cSrcweir #include <sfx2/printer.hxx>
44*cdf0e10cSrcweir #include <vcl/msgbox.hxx>
45*cdf0e10cSrcweir #include <vcl/sound.hxx>
46*cdf0e10cSrcweir #include <vcl/virdev.hxx>
47*cdf0e10cSrcweir #include <vcl/waitobj.hxx>
48*cdf0e10cSrcweir #include <svl/zforlist.hxx>
49*cdf0e10cSrcweir #include <svl/PasswordHelper.hxx>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir #include <basic/sbstar.hxx>
52*cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
53*cdf0e10cSrcweir #include <com/sun/star/script/ModuleType.hpp>
54*cdf0e10cSrcweir #include <com/sun/star/script/XLibraryContainer.hpp>
55*cdf0e10cSrcweir #include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include <list>
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir #include "docfunc.hxx"
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir #include "sc.hrc"
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir #include "arealink.hxx"
64*cdf0e10cSrcweir #include "attrib.hxx"
65*cdf0e10cSrcweir #include "dociter.hxx"
66*cdf0e10cSrcweir #include "autoform.hxx"
67*cdf0e10cSrcweir #include "cell.hxx"
68*cdf0e10cSrcweir #include "detdata.hxx"
69*cdf0e10cSrcweir #include "detfunc.hxx"
70*cdf0e10cSrcweir #include "docpool.hxx"
71*cdf0e10cSrcweir #include "docsh.hxx"
72*cdf0e10cSrcweir #include "drwlayer.hxx"
73*cdf0e10cSrcweir #include "editutil.hxx"
74*cdf0e10cSrcweir #include "globstr.hrc"
75*cdf0e10cSrcweir //CHINA001 #include "namecrea.hxx"		// NAME_TOP etc.
76*cdf0e10cSrcweir #include "olinetab.hxx"
77*cdf0e10cSrcweir #include "patattr.hxx"
78*cdf0e10cSrcweir #include "rangenam.hxx"
79*cdf0e10cSrcweir #include "rangeutl.hxx"
80*cdf0e10cSrcweir #include "refundo.hxx"
81*cdf0e10cSrcweir #include "scresid.hxx"
82*cdf0e10cSrcweir #include "stlpool.hxx"
83*cdf0e10cSrcweir #include "stlsheet.hxx"
84*cdf0e10cSrcweir #include "tablink.hxx"
85*cdf0e10cSrcweir #include "tabvwsh.hxx"
86*cdf0e10cSrcweir #include "uiitems.hxx"
87*cdf0e10cSrcweir #include "undoblk.hxx"
88*cdf0e10cSrcweir #include "undocell.hxx"
89*cdf0e10cSrcweir #include "undodraw.hxx"
90*cdf0e10cSrcweir #include "undotab.hxx"
91*cdf0e10cSrcweir #include "waitoff.hxx"
92*cdf0e10cSrcweir #include "sizedev.hxx"
93*cdf0e10cSrcweir #include "scmod.hxx"
94*cdf0e10cSrcweir #include "inputhdl.hxx"
95*cdf0e10cSrcweir #include "inputwin.hxx"
96*cdf0e10cSrcweir #include "editable.hxx"
97*cdf0e10cSrcweir #include "compiler.hxx"
98*cdf0e10cSrcweir #include "scui_def.hxx" //CHINA001
99*cdf0e10cSrcweir #include "tabprotection.hxx"
100*cdf0e10cSrcweir #include "clipparam.hxx"
101*cdf0e10cSrcweir #include "externalrefmgr.hxx"
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir #include <memory>
104*cdf0e10cSrcweir #include <basic/basmgr.hxx>
105*cdf0e10cSrcweir #include <boost/scoped_ptr.hpp>
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir using namespace com::sun::star;
108*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir // STATIC DATA -----------------------------------------------------------
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir //========================================================================
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir IMPL_LINK( ScDocFunc, NotifyDrawUndo, SdrUndoAction*, pUndoAction )
115*cdf0e10cSrcweir {
116*cdf0e10cSrcweir     // #i101118# if drawing layer collects the undo actions, add it there
117*cdf0e10cSrcweir     ScDrawLayer* pDrawLayer = rDocShell.GetDocument()->GetDrawLayer();
118*cdf0e10cSrcweir     if( pDrawLayer && pDrawLayer->IsRecording() )
119*cdf0e10cSrcweir         pDrawLayer->AddCalcUndo( pUndoAction );
120*cdf0e10cSrcweir     else
121*cdf0e10cSrcweir         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDraw( pUndoAction, &rDocShell ) );
122*cdf0e10cSrcweir 	rDocShell.SetDrawModified();
123*cdf0e10cSrcweir 
124*cdf0e10cSrcweir     // the affected sheet isn't known, so all stream positions are invalidated
125*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
126*cdf0e10cSrcweir     SCTAB nTabCount = pDoc->GetTableCount();
127*cdf0e10cSrcweir     for (SCTAB nTab=0; nTab<nTabCount; nTab++)
128*cdf0e10cSrcweir         if (pDoc->IsStreamValid(nTab))
129*cdf0e10cSrcweir             pDoc->SetStreamValid(nTab, sal_False);
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir 	return 0;
132*cdf0e10cSrcweir }
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir //------------------------------------------------------------------------
135*cdf0e10cSrcweir 
136*cdf0e10cSrcweir //	Zeile ueber dem Range painten (fuer Linien nach AdjustRowHeight)
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir void lcl_PaintAbove( ScDocShell& rDocShell, const ScRange& rRange )
139*cdf0e10cSrcweir {
140*cdf0e10cSrcweir 	SCROW nRow = rRange.aStart.Row();
141*cdf0e10cSrcweir 	if ( nRow > 0 )
142*cdf0e10cSrcweir 	{
143*cdf0e10cSrcweir 		SCTAB nTab = rRange.aStart.Tab();	//! alle?
144*cdf0e10cSrcweir 		--nRow;
145*cdf0e10cSrcweir 		rDocShell.PostPaint( ScRange(0,nRow,nTab, MAXCOL,nRow,nTab), PAINT_GRID );
146*cdf0e10cSrcweir 	}
147*cdf0e10cSrcweir }
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir //------------------------------------------------------------------------
150*cdf0e10cSrcweir 
151*cdf0e10cSrcweir sal_Bool ScDocFunc::AdjustRowHeight( const ScRange& rRange, sal_Bool bPaint )
152*cdf0e10cSrcweir {
153*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
154*cdf0e10cSrcweir 	if ( pDoc->IsImportingXML() )
155*cdf0e10cSrcweir 	{
156*cdf0e10cSrcweir 		//	for XML import, all row heights are updated together after importing
157*cdf0e10cSrcweir 		return sal_False;
158*cdf0e10cSrcweir 	}
159*cdf0e10cSrcweir     if ( !pDoc->IsAdjustHeightEnabled() )
160*cdf0e10cSrcweir     {
161*cdf0e10cSrcweir         return sal_False;
162*cdf0e10cSrcweir     }
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 	SCTAB nTab      = rRange.aStart.Tab();
165*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
166*cdf0e10cSrcweir 	SCROW nEndRow   = rRange.aEnd.Row();
167*cdf0e10cSrcweir 
168*cdf0e10cSrcweir 	ScSizeDeviceProvider aProv( &rDocShell );
169*cdf0e10cSrcweir 	Fraction aOne(1,1);
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir 	sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
172*cdf0e10cSrcweir 											aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, sal_False );
173*cdf0e10cSrcweir 
174*cdf0e10cSrcweir 	if ( bPaint && bChanged )
175*cdf0e10cSrcweir 		rDocShell.PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
176*cdf0e10cSrcweir 											PAINT_GRID | PAINT_LEFT );
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir 	return bChanged;
179*cdf0e10cSrcweir }
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir 
182*cdf0e10cSrcweir //------------------------------------------------------------------------
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveAddPred(const ScAddress& rPos)
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
187*cdf0e10cSrcweir 
188*cdf0e10cSrcweir 	rDocShell.MakeDrawLayer();
189*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
190*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
191*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
192*cdf0e10cSrcweir 	SCCOL nCol = rPos.Col();
193*cdf0e10cSrcweir 	SCROW nRow = rPos.Row();
194*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
195*cdf0e10cSrcweir 
196*cdf0e10cSrcweir 	if (bUndo)
197*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
198*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowPred( nCol, nRow );
199*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
200*cdf0e10cSrcweir 	if (bUndo)
201*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
202*cdf0e10cSrcweir 	if (bDone)
203*cdf0e10cSrcweir 	{
204*cdf0e10cSrcweir 		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDPRED );
205*cdf0e10cSrcweir 		pDoc->AddDetectiveOperation( aOperation );
206*cdf0e10cSrcweir 		if (bUndo)
207*cdf0e10cSrcweir 		{
208*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
209*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
210*cdf0e10cSrcweir 		}
211*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
212*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
213*cdf0e10cSrcweir 		if (pBindings)
214*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
215*cdf0e10cSrcweir 	}
216*cdf0e10cSrcweir 	else
217*cdf0e10cSrcweir 		delete pUndo;
218*cdf0e10cSrcweir 
219*cdf0e10cSrcweir 	return bDone;
220*cdf0e10cSrcweir }
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveDelPred(const ScAddress& rPos)
223*cdf0e10cSrcweir {
224*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
227*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
228*cdf0e10cSrcweir 	if (!pModel)
229*cdf0e10cSrcweir 		return sal_False;
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir 	SCCOL nCol = rPos.Col();
234*cdf0e10cSrcweir 	SCROW nRow = rPos.Row();
235*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
236*cdf0e10cSrcweir 
237*cdf0e10cSrcweir 	if (bUndo)
238*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
239*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeletePred( nCol, nRow );
240*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
241*cdf0e10cSrcweir 	if (bUndo)
242*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
243*cdf0e10cSrcweir 	if (bDone)
244*cdf0e10cSrcweir 	{
245*cdf0e10cSrcweir 		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELPRED );
246*cdf0e10cSrcweir 		pDoc->AddDetectiveOperation( aOperation );
247*cdf0e10cSrcweir 		if (bUndo)
248*cdf0e10cSrcweir 		{
249*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
250*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
251*cdf0e10cSrcweir 		}
252*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
253*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
254*cdf0e10cSrcweir 		if (pBindings)
255*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
256*cdf0e10cSrcweir 	}
257*cdf0e10cSrcweir 	else
258*cdf0e10cSrcweir 		delete pUndo;
259*cdf0e10cSrcweir 
260*cdf0e10cSrcweir 	return bDone;
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveAddSucc(const ScAddress& rPos)
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 	rDocShell.MakeDrawLayer();
268*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
269*cdf0e10cSrcweir 
270*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
271*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
272*cdf0e10cSrcweir 	SCCOL nCol = rPos.Col();
273*cdf0e10cSrcweir 	SCROW nRow = rPos.Row();
274*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir 	if (bUndo)
277*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
278*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowSucc( nCol, nRow );
279*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
280*cdf0e10cSrcweir 	if (bUndo)
281*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
282*cdf0e10cSrcweir 	if (bDone)
283*cdf0e10cSrcweir 	{
284*cdf0e10cSrcweir 		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDSUCC );
285*cdf0e10cSrcweir 		pDoc->AddDetectiveOperation( aOperation );
286*cdf0e10cSrcweir 		if (bUndo)
287*cdf0e10cSrcweir 		{
288*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
289*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
290*cdf0e10cSrcweir 		}
291*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
292*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
293*cdf0e10cSrcweir 		if (pBindings)
294*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
295*cdf0e10cSrcweir 	}
296*cdf0e10cSrcweir 	else
297*cdf0e10cSrcweir 		delete pUndo;
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir 	return bDone;
300*cdf0e10cSrcweir }
301*cdf0e10cSrcweir 
302*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveDelSucc(const ScAddress& rPos)
303*cdf0e10cSrcweir {
304*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
307*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
308*cdf0e10cSrcweir 	if (!pModel)
309*cdf0e10cSrcweir 		return sal_False;
310*cdf0e10cSrcweir 
311*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 	SCCOL nCol = rPos.Col();
314*cdf0e10cSrcweir 	SCROW nRow = rPos.Row();
315*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
316*cdf0e10cSrcweir 
317*cdf0e10cSrcweir 	if (bUndo)
318*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
319*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteSucc( nCol, nRow );
320*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
321*cdf0e10cSrcweir 	if (bUndo)
322*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
323*cdf0e10cSrcweir 	if (bDone)
324*cdf0e10cSrcweir 	{
325*cdf0e10cSrcweir 		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_DELSUCC );
326*cdf0e10cSrcweir 		pDoc->AddDetectiveOperation( aOperation );
327*cdf0e10cSrcweir 		if (bUndo)
328*cdf0e10cSrcweir 		{
329*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
330*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
331*cdf0e10cSrcweir 		}
332*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
333*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
334*cdf0e10cSrcweir 		if (pBindings)
335*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
336*cdf0e10cSrcweir 	}
337*cdf0e10cSrcweir 	else
338*cdf0e10cSrcweir 		delete pUndo;
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 	return bDone;
341*cdf0e10cSrcweir }
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveAddError(const ScAddress& rPos)
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir 	rDocShell.MakeDrawLayer();
348*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
351*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
352*cdf0e10cSrcweir 	SCCOL nCol = rPos.Col();
353*cdf0e10cSrcweir 	SCROW nRow = rPos.Row();
354*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
355*cdf0e10cSrcweir 
356*cdf0e10cSrcweir 	if (bUndo)
357*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
358*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).ShowError( nCol, nRow );
359*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
360*cdf0e10cSrcweir 	if (bUndo)
361*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
362*cdf0e10cSrcweir 	if (bDone)
363*cdf0e10cSrcweir 	{
364*cdf0e10cSrcweir 		ScDetOpData aOperation( ScAddress(nCol,nRow,nTab), SCDETOP_ADDERROR );
365*cdf0e10cSrcweir 		pDoc->AddDetectiveOperation( aOperation );
366*cdf0e10cSrcweir 		if (bUndo)
367*cdf0e10cSrcweir 		{
368*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
369*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, &aOperation ) );
370*cdf0e10cSrcweir 		}
371*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
372*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
373*cdf0e10cSrcweir 		if (pBindings)
374*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
375*cdf0e10cSrcweir 	}
376*cdf0e10cSrcweir 	else
377*cdf0e10cSrcweir 		delete pUndo;
378*cdf0e10cSrcweir 
379*cdf0e10cSrcweir 	return bDone;
380*cdf0e10cSrcweir }
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveMarkInvalid(SCTAB nTab)
383*cdf0e10cSrcweir {
384*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
385*cdf0e10cSrcweir 
386*cdf0e10cSrcweir 	rDocShell.MakeDrawLayer();
387*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
388*cdf0e10cSrcweir 
389*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
390*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir 	Window* pWaitWin = rDocShell.GetActiveDialogParent();
393*cdf0e10cSrcweir 	if (pWaitWin)
394*cdf0e10cSrcweir 		pWaitWin->EnterWait();
395*cdf0e10cSrcweir 	if (bUndo)
396*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
397*cdf0e10cSrcweir 	sal_Bool bOverflow;
398*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).MarkInvalid( bOverflow );
399*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
400*cdf0e10cSrcweir 	if (bUndo)
401*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
402*cdf0e10cSrcweir 	if (pWaitWin)
403*cdf0e10cSrcweir 		pWaitWin->LeaveWait();
404*cdf0e10cSrcweir 	if (bDone)
405*cdf0e10cSrcweir 	{
406*cdf0e10cSrcweir 		if (pUndo && bUndo)
407*cdf0e10cSrcweir 		{
408*cdf0e10cSrcweir 			pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETINVALID ) );
409*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction( pUndo );
410*cdf0e10cSrcweir 		}
411*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
412*cdf0e10cSrcweir 		if ( bOverflow )
413*cdf0e10cSrcweir 		{
414*cdf0e10cSrcweir 			InfoBox( NULL,
415*cdf0e10cSrcweir 					ScGlobal::GetRscString( STR_DETINVALID_OVERFLOW ) ).Execute();
416*cdf0e10cSrcweir 		}
417*cdf0e10cSrcweir 	}
418*cdf0e10cSrcweir 	else
419*cdf0e10cSrcweir 		delete pUndo;
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir 	return bDone;
422*cdf0e10cSrcweir }
423*cdf0e10cSrcweir 
424*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveDelAll(SCTAB nTab)
425*cdf0e10cSrcweir {
426*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
427*cdf0e10cSrcweir 
428*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
429*cdf0e10cSrcweir 	ScDrawLayer* pModel = pDoc->GetDrawLayer();
430*cdf0e10cSrcweir 	if (!pModel)
431*cdf0e10cSrcweir 		return sal_False;
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
434*cdf0e10cSrcweir 
435*cdf0e10cSrcweir 	if (bUndo)
436*cdf0e10cSrcweir 		pModel->BeginCalcUndo();
437*cdf0e10cSrcweir 	sal_Bool bDone = ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_DETECTIVE );
438*cdf0e10cSrcweir 	SdrUndoGroup* pUndo = NULL;
439*cdf0e10cSrcweir 	if (bUndo)
440*cdf0e10cSrcweir 		pUndo = pModel->GetCalcUndo();
441*cdf0e10cSrcweir 	if (bDone)
442*cdf0e10cSrcweir 	{
443*cdf0e10cSrcweir 		ScDetOpList* pOldList = pDoc->GetDetOpList();
444*cdf0e10cSrcweir 		ScDetOpList* pUndoList = NULL;
445*cdf0e10cSrcweir 		if (bUndo)
446*cdf0e10cSrcweir 			pUndoList = pOldList ? new ScDetOpList(*pOldList) : NULL;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir 		pDoc->ClearDetectiveOperations();
449*cdf0e10cSrcweir 
450*cdf0e10cSrcweir 		if (bUndo)
451*cdf0e10cSrcweir 		{
452*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
453*cdf0e10cSrcweir 						new ScUndoDetective( &rDocShell, pUndo, NULL, pUndoList ) );
454*cdf0e10cSrcweir 		}
455*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
456*cdf0e10cSrcweir 		SfxBindings* pBindings = rDocShell.GetViewBindings();
457*cdf0e10cSrcweir 		if (pBindings)
458*cdf0e10cSrcweir 			pBindings->Invalidate( SID_DETECTIVE_REFRESH );
459*cdf0e10cSrcweir 	}
460*cdf0e10cSrcweir 	else
461*cdf0e10cSrcweir 		delete pUndo;
462*cdf0e10cSrcweir 
463*cdf0e10cSrcweir 	return bDone;
464*cdf0e10cSrcweir }
465*cdf0e10cSrcweir 
466*cdf0e10cSrcweir sal_Bool ScDocFunc::DetectiveRefresh( sal_Bool bAutomatic )
467*cdf0e10cSrcweir {
468*cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
469*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
470*cdf0e10cSrcweir 
471*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
472*cdf0e10cSrcweir 	ScDetOpList* pList = pDoc->GetDetOpList();
473*cdf0e10cSrcweir 	if ( pList && pList->Count() )
474*cdf0e10cSrcweir 	{
475*cdf0e10cSrcweir 		rDocShell.MakeDrawLayer();
476*cdf0e10cSrcweir 		ScDrawLayer* pModel = pDoc->GetDrawLayer();
477*cdf0e10cSrcweir 		if (bUndo)
478*cdf0e10cSrcweir 			pModel->BeginCalcUndo();
479*cdf0e10cSrcweir 
480*cdf0e10cSrcweir 		//	Loeschen auf allen Tabellen
481*cdf0e10cSrcweir 
482*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
483*cdf0e10cSrcweir 		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
484*cdf0e10cSrcweir 			ScDetectiveFunc( pDoc,nTab ).DeleteAll( SC_DET_ARROWS );	// don't remove circles
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir 		//	Wiederholen
487*cdf0e10cSrcweir 
488*cdf0e10cSrcweir 		sal_uInt16 nCount = pList->Count();
489*cdf0e10cSrcweir 		for (sal_uInt16 i=0; i<nCount; i++)
490*cdf0e10cSrcweir 		{
491*cdf0e10cSrcweir 			ScDetOpData* pData = (*pList)[i];
492*cdf0e10cSrcweir 			if (pData)
493*cdf0e10cSrcweir 			{
494*cdf0e10cSrcweir 				ScAddress aPos = pData->GetPos();
495*cdf0e10cSrcweir 				ScDetectiveFunc aFunc( pDoc, aPos.Tab() );
496*cdf0e10cSrcweir 				SCCOL nCol = aPos.Col();
497*cdf0e10cSrcweir 				SCROW nRow = aPos.Row();
498*cdf0e10cSrcweir 				switch (pData->GetOperation())
499*cdf0e10cSrcweir 				{
500*cdf0e10cSrcweir 					case SCDETOP_ADDSUCC:
501*cdf0e10cSrcweir 						aFunc.ShowSucc( nCol, nRow );
502*cdf0e10cSrcweir 						break;
503*cdf0e10cSrcweir 					case SCDETOP_DELSUCC:
504*cdf0e10cSrcweir 						aFunc.DeleteSucc( nCol, nRow );
505*cdf0e10cSrcweir 						break;
506*cdf0e10cSrcweir 					case SCDETOP_ADDPRED:
507*cdf0e10cSrcweir 						aFunc.ShowPred( nCol, nRow );
508*cdf0e10cSrcweir 						break;
509*cdf0e10cSrcweir 					case SCDETOP_DELPRED:
510*cdf0e10cSrcweir 						aFunc.DeletePred( nCol, nRow );
511*cdf0e10cSrcweir 						break;
512*cdf0e10cSrcweir 					case SCDETOP_ADDERROR:
513*cdf0e10cSrcweir 						aFunc.ShowError( nCol, nRow );
514*cdf0e10cSrcweir 						break;
515*cdf0e10cSrcweir 					default:
516*cdf0e10cSrcweir 						DBG_ERROR("falsche Op bei DetectiveRefresh");
517*cdf0e10cSrcweir 				}
518*cdf0e10cSrcweir 			}
519*cdf0e10cSrcweir 		}
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir 		if (bUndo)
522*cdf0e10cSrcweir 		{
523*cdf0e10cSrcweir 			SdrUndoGroup* pUndo = pModel->GetCalcUndo();
524*cdf0e10cSrcweir 			if (pUndo)
525*cdf0e10cSrcweir 			{
526*cdf0e10cSrcweir 				pUndo->SetComment( ScGlobal::GetRscString( STR_UNDO_DETREFRESH ) );
527*cdf0e10cSrcweir 				//	wenn automatisch, an letzte Aktion anhaengen
528*cdf0e10cSrcweir 				rDocShell.GetUndoManager()->AddUndoAction(
529*cdf0e10cSrcweir 												new ScUndoDraw( pUndo, &rDocShell ),
530*cdf0e10cSrcweir 												bAutomatic );
531*cdf0e10cSrcweir 			}
532*cdf0e10cSrcweir 		}
533*cdf0e10cSrcweir 		rDocShell.SetDrawModified();
534*cdf0e10cSrcweir 		bDone = sal_True;
535*cdf0e10cSrcweir 	}
536*cdf0e10cSrcweir 	return bDone;
537*cdf0e10cSrcweir }
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir //------------------------------------------------------------------------
540*cdf0e10cSrcweir 
541*cdf0e10cSrcweir sal_Bool ScDocFunc::DeleteContents( const ScMarkData& rMark, sal_uInt16 nFlags,
542*cdf0e10cSrcweir 									sal_Bool bRecord, sal_Bool bApi )
543*cdf0e10cSrcweir {
544*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
545*cdf0e10cSrcweir 
546*cdf0e10cSrcweir 	if ( !rMark.IsMarked() && !rMark.IsMultiMarked() )
547*cdf0e10cSrcweir 	{
548*cdf0e10cSrcweir 		DBG_ERROR("ScDocFunc::DeleteContents ohne Markierung");
549*cdf0e10cSrcweir 		return sal_False;
550*cdf0e10cSrcweir 	}
551*cdf0e10cSrcweir 
552*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
555*cdf0e10cSrcweir 		bRecord = sal_False;
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rMark );
558*cdf0e10cSrcweir 	if (!aTester.IsEditable())
559*cdf0e10cSrcweir 	{
560*cdf0e10cSrcweir 		if (!bApi)
561*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
562*cdf0e10cSrcweir 		return sal_False;
563*cdf0e10cSrcweir 	}
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir 	ScRange aMarkRange;
566*cdf0e10cSrcweir 	sal_Bool bSimple = sal_False;
567*cdf0e10cSrcweir 
568*cdf0e10cSrcweir 	ScMarkData aMultiMark = rMark;
569*cdf0e10cSrcweir 	aMultiMark.SetMarking(sal_False);		// fuer MarkToMulti
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
572*cdf0e10cSrcweir 	sal_Bool bMulti = !bSimple && aMultiMark.IsMultiMarked();
573*cdf0e10cSrcweir 	if (!bSimple)
574*cdf0e10cSrcweir 	{
575*cdf0e10cSrcweir 		aMultiMark.MarkToMulti();
576*cdf0e10cSrcweir 		aMultiMark.GetMultiMarkArea( aMarkRange );
577*cdf0e10cSrcweir 	}
578*cdf0e10cSrcweir 	ScRange aExtendedRange(aMarkRange);
579*cdf0e10cSrcweir 	if (!bSimple)
580*cdf0e10cSrcweir 	{
581*cdf0e10cSrcweir 		if ( pDoc->ExtendMerge( aExtendedRange, sal_True ) )
582*cdf0e10cSrcweir 			bMulti = sal_False;
583*cdf0e10cSrcweir 	}
584*cdf0e10cSrcweir 
585*cdf0e10cSrcweir 	// keine Objekte auf geschuetzten Tabellen
586*cdf0e10cSrcweir 	sal_Bool bObjects = sal_False;
587*cdf0e10cSrcweir 	if ( nFlags & IDF_OBJECTS )
588*cdf0e10cSrcweir 	{
589*cdf0e10cSrcweir 		bObjects = sal_True;
590*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
591*cdf0e10cSrcweir 		for (SCTAB nTab=0; nTab<nTabCount; nTab++)
592*cdf0e10cSrcweir 			if (aMultiMark.GetTableSelect(nTab) && pDoc->IsTabProtected(nTab))
593*cdf0e10cSrcweir 				bObjects = sal_False;
594*cdf0e10cSrcweir 	}
595*cdf0e10cSrcweir 
596*cdf0e10cSrcweir 	sal_uInt16 nExtFlags = 0;		// extra flags are needed only if attributes are deleted
597*cdf0e10cSrcweir 	if ( nFlags & IDF_ATTRIB )
598*cdf0e10cSrcweir 		rDocShell.UpdatePaintExt( nExtFlags, aMarkRange );
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 	//	Reihenfolge:
601*cdf0e10cSrcweir 	//	1) BeginDrawUndo
602*cdf0e10cSrcweir 	//	2) Objekte loeschen (DrawUndo wird gefuellt)
603*cdf0e10cSrcweir 	//	3) Inhalte fuer Undo kopieren und Undo-Aktion anlegen
604*cdf0e10cSrcweir 	//	4) Inhalte loeschen
605*cdf0e10cSrcweir 
606*cdf0e10cSrcweir     bool bDrawUndo = bObjects || (nFlags & IDF_NOTE);
607*cdf0e10cSrcweir     if (bRecord && bDrawUndo)
608*cdf0e10cSrcweir         pDoc->BeginDrawUndo();
609*cdf0e10cSrcweir 
610*cdf0e10cSrcweir 	if (bObjects)
611*cdf0e10cSrcweir 	{
612*cdf0e10cSrcweir 		if (bMulti)
613*cdf0e10cSrcweir 			pDoc->DeleteObjectsInSelection( aMultiMark );
614*cdf0e10cSrcweir 		else
615*cdf0e10cSrcweir 			pDoc->DeleteObjectsInArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
616*cdf0e10cSrcweir 									   aMarkRange.aEnd.Col(),   aMarkRange.aEnd.Row(),
617*cdf0e10cSrcweir 									   aMultiMark );
618*cdf0e10cSrcweir 	}
619*cdf0e10cSrcweir 
620*cdf0e10cSrcweir 	if ( bRecord )
621*cdf0e10cSrcweir 	{
622*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
623*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, aMarkRange.aStart.Tab(), aMarkRange.aEnd.Tab() );
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir 		//	bei "Format/Standard" alle Attribute kopieren, weil CopyToDocument
626*cdf0e10cSrcweir 		//	nur mit IDF_HARDATTR zu langsam ist:
627*cdf0e10cSrcweir 		sal_uInt16 nUndoDocFlags = nFlags;
628*cdf0e10cSrcweir 		if (nFlags & IDF_ATTRIB)
629*cdf0e10cSrcweir 			nUndoDocFlags |= IDF_ATTRIB;
630*cdf0e10cSrcweir 		if (nFlags & IDF_EDITATTR)			// Edit-Engine-Attribute
631*cdf0e10cSrcweir 			nUndoDocFlags |= IDF_STRING;	// -> Zellen werden geaendert
632*cdf0e10cSrcweir 		if (nFlags & IDF_NOTE)
633*cdf0e10cSrcweir 			nUndoDocFlags |= IDF_CONTENTS;	// #68795# copy all cells with their notes
634*cdf0e10cSrcweir         // note captions are handled in drawing undo
635*cdf0e10cSrcweir         nUndoDocFlags |= IDF_NOCAPTIONS;
636*cdf0e10cSrcweir 		pDoc->CopyToDocument( aExtendedRange, nUndoDocFlags, bMulti, pUndoDoc, &aMultiMark );
637*cdf0e10cSrcweir 	}
638*cdf0e10cSrcweir 
639*cdf0e10cSrcweir //!	HideAllCursors();	// falls Zusammenfassung aufgehoben wird
640*cdf0e10cSrcweir 	if (bSimple)
641*cdf0e10cSrcweir 		pDoc->DeleteArea( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
642*cdf0e10cSrcweir 						  aMarkRange.aEnd.Col(),   aMarkRange.aEnd.Row(),
643*cdf0e10cSrcweir 						  aMultiMark, nFlags );
644*cdf0e10cSrcweir 	else
645*cdf0e10cSrcweir 	{
646*cdf0e10cSrcweir 		pDoc->DeleteSelection( nFlags, aMultiMark );
647*cdf0e10cSrcweir //       aMultiMark.MarkToSimple();
648*cdf0e10cSrcweir 	}
649*cdf0e10cSrcweir 
650*cdf0e10cSrcweir     // add undo action after drawing undo is complete (objects and note captions)
651*cdf0e10cSrcweir     if( bRecord )
652*cdf0e10cSrcweir         rDocShell.GetUndoManager()->AddUndoAction(
653*cdf0e10cSrcweir             new ScUndoDeleteContents( &rDocShell, aMultiMark, aExtendedRange,
654*cdf0e10cSrcweir                                       pUndoDoc, bMulti, nFlags, bDrawUndo ) );
655*cdf0e10cSrcweir 
656*cdf0e10cSrcweir 	if (!AdjustRowHeight( aExtendedRange ))
657*cdf0e10cSrcweir 		rDocShell.PostPaint( aExtendedRange, PAINT_GRID, nExtFlags );
658*cdf0e10cSrcweir 	else if (nExtFlags & SC_PF_LINES)
659*cdf0e10cSrcweir 		lcl_PaintAbove( rDocShell, aExtendedRange );	// fuer Linien ueber dem Bereich
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir //	rDocShell.UpdateOle(GetViewData());		//! an der View?
662*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
663*cdf0e10cSrcweir //!	CellContentChanged();
664*cdf0e10cSrcweir //!	ShowAllCursors();
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir #if 0
667*cdf0e10cSrcweir 	//!	muss an der View bleiben !!!!
668*cdf0e10cSrcweir 	if ( nFlags & IDF_ATTRIB )
669*cdf0e10cSrcweir 	{
670*cdf0e10cSrcweir 		if ( nFlags & IDF_CONTENTS )
671*cdf0e10cSrcweir 			ForgetFormatArea();
672*cdf0e10cSrcweir 		else
673*cdf0e10cSrcweir 			StartFormatArea();				// Attribute loeschen ist auch Attributierung
674*cdf0e10cSrcweir 	}
675*cdf0e10cSrcweir #endif
676*cdf0e10cSrcweir 
677*cdf0e10cSrcweir 	return sal_True;
678*cdf0e10cSrcweir }
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir //------------------------------------------------------------------------
681*cdf0e10cSrcweir 
682*cdf0e10cSrcweir sal_Bool ScDocFunc::TransliterateText( const ScMarkData& rMark, sal_Int32 nType,
683*cdf0e10cSrcweir 									sal_Bool bRecord, sal_Bool bApi )
684*cdf0e10cSrcweir {
685*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
688*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
689*cdf0e10cSrcweir 		bRecord = sal_False;
690*cdf0e10cSrcweir 
691*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rMark );
692*cdf0e10cSrcweir 	if (!aTester.IsEditable())
693*cdf0e10cSrcweir 	{
694*cdf0e10cSrcweir 		if (!bApi)
695*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
696*cdf0e10cSrcweir 		return sal_False;
697*cdf0e10cSrcweir 	}
698*cdf0e10cSrcweir 
699*cdf0e10cSrcweir 	ScRange aMarkRange;
700*cdf0e10cSrcweir 	ScMarkData aMultiMark = rMark;
701*cdf0e10cSrcweir 	aMultiMark.SetMarking(sal_False);		// for MarkToMulti
702*cdf0e10cSrcweir 	aMultiMark.MarkToMulti();
703*cdf0e10cSrcweir 	aMultiMark.GetMultiMarkArea( aMarkRange );
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir 	if (bRecord)
706*cdf0e10cSrcweir 	{
707*cdf0e10cSrcweir 		SCTAB nStartTab = aMarkRange.aStart.Tab();
708*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
709*cdf0e10cSrcweir 
710*cdf0e10cSrcweir 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
711*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
712*cdf0e10cSrcweir 		for (SCTAB i=0; i<nTabCount; i++)
713*cdf0e10cSrcweir 			if (i != nStartTab && rMark.GetTableSelect(i))
714*cdf0e10cSrcweir 				pUndoDoc->AddUndoTab( i, i );
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir 		ScRange aCopyRange = aMarkRange;
717*cdf0e10cSrcweir 		aCopyRange.aStart.SetTab(0);
718*cdf0e10cSrcweir 		aCopyRange.aEnd.SetTab(nTabCount-1);
719*cdf0e10cSrcweir 		pDoc->CopyToDocument( aCopyRange, IDF_CONTENTS, sal_True, pUndoDoc, &aMultiMark );
720*cdf0e10cSrcweir 
721*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
722*cdf0e10cSrcweir 			new ScUndoTransliterate( &rDocShell, aMultiMark, pUndoDoc, nType ) );
723*cdf0e10cSrcweir 	}
724*cdf0e10cSrcweir 
725*cdf0e10cSrcweir 	pDoc->TransliterateText( aMultiMark, nType );
726*cdf0e10cSrcweir 
727*cdf0e10cSrcweir 	if (!AdjustRowHeight( aMarkRange ))
728*cdf0e10cSrcweir 		rDocShell.PostPaint( aMarkRange, PAINT_GRID );
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
731*cdf0e10cSrcweir 
732*cdf0e10cSrcweir 	return sal_True;
733*cdf0e10cSrcweir }
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir //------------------------------------------------------------------------
736*cdf0e10cSrcweir 
737*cdf0e10cSrcweir sal_Bool ScDocFunc::SetNormalString( const ScAddress& rPos, const String& rText, sal_Bool bApi )
738*cdf0e10cSrcweir {
739*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
740*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
741*cdf0e10cSrcweir 
742*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
743*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
744*cdf0e10cSrcweir 	if (!aTester.IsEditable())
745*cdf0e10cSrcweir 	{
746*cdf0e10cSrcweir 		if (!bApi)
747*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
748*cdf0e10cSrcweir 		return sal_False;
749*cdf0e10cSrcweir 	}
750*cdf0e10cSrcweir 
751*cdf0e10cSrcweir 	SCTAB* pTabs = NULL;
752*cdf0e10cSrcweir 	ScBaseCell** ppOldCells = NULL;
753*cdf0e10cSrcweir 	sal_Bool* pHasFormat = NULL;
754*cdf0e10cSrcweir 	sal_uLong* pOldFormats = NULL;
755*cdf0e10cSrcweir 	ScBaseCell* pDocCell = pDoc->GetCell( rPos );
756*cdf0e10cSrcweir 	sal_Bool bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
757*cdf0e10cSrcweir 	if (bUndo)
758*cdf0e10cSrcweir 	{
759*cdf0e10cSrcweir 		pTabs = new SCTAB[1];
760*cdf0e10cSrcweir 		pTabs[0] = rPos.Tab();
761*cdf0e10cSrcweir 		ppOldCells	= new ScBaseCell*[1];
762*cdf0e10cSrcweir         ppOldCells[0] = pDocCell ? pDocCell->CloneWithoutNote( *pDoc ) : 0;
763*cdf0e10cSrcweir 
764*cdf0e10cSrcweir 		pHasFormat = new sal_Bool[1];
765*cdf0e10cSrcweir 		pOldFormats = new sal_uLong[1];
766*cdf0e10cSrcweir 		const SfxPoolItem* pItem;
767*cdf0e10cSrcweir 		const ScPatternAttr* pPattern = pDoc->GetPattern( rPos.Col(),rPos.Row(),rPos.Tab() );
768*cdf0e10cSrcweir 		if ( SFX_ITEM_SET == pPattern->GetItemSet().GetItemState(
769*cdf0e10cSrcweir 								ATTR_VALUE_FORMAT,sal_False,&pItem) )
770*cdf0e10cSrcweir 		{
771*cdf0e10cSrcweir 			pHasFormat[0] = sal_True;
772*cdf0e10cSrcweir 			pOldFormats[0] = ((const SfxUInt32Item*)pItem)->GetValue();
773*cdf0e10cSrcweir 		}
774*cdf0e10cSrcweir 		else
775*cdf0e10cSrcweir 			pHasFormat[0] = sal_False;
776*cdf0e10cSrcweir 	}
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir 	pDoc->SetString( rPos.Col(), rPos.Row(), rPos.Tab(), rText );
779*cdf0e10cSrcweir 
780*cdf0e10cSrcweir 	if (bUndo)
781*cdf0e10cSrcweir 	{
782*cdf0e10cSrcweir 		//	wegen ChangeTracking darf UndoAction erst nach SetString angelegt werden
783*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(new ScUndoEnterData( &rDocShell, rPos.Col(),rPos.Row(),rPos.Tab(), 1,pTabs,
784*cdf0e10cSrcweir 									 ppOldCells, pHasFormat, pOldFormats, rText, NULL ) );
785*cdf0e10cSrcweir 	}
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir 	if ( bEditDeleted || pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) )
788*cdf0e10cSrcweir 		AdjustRowHeight( ScRange(rPos) );
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	rDocShell.PostPaintCell( rPos );
791*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir     // #107160# notify input handler here the same way as in PutCell
794*cdf0e10cSrcweir     if (bApi)
795*cdf0e10cSrcweir         NotifyInputHandler( rPos );
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir 	return sal_True;
798*cdf0e10cSrcweir }
799*cdf0e10cSrcweir 
800*cdf0e10cSrcweir sal_Bool ScDocFunc::PutCell( const ScAddress& rPos, ScBaseCell* pNewCell, sal_Bool bApi )
801*cdf0e10cSrcweir {
802*cdf0e10cSrcweir     ScDocShellModificator aModificator( rDocShell );
803*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
804*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
805*cdf0e10cSrcweir     sal_Bool bXMLLoading(pDoc->IsImportingXML());
806*cdf0e10cSrcweir 
807*cdf0e10cSrcweir     // #i925#; it is not neccessary to test whether the cell is editable on loading a XML document
808*cdf0e10cSrcweir     if (!bXMLLoading)
809*cdf0e10cSrcweir     {
810*cdf0e10cSrcweir 	    ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
811*cdf0e10cSrcweir 	    if (!aTester.IsEditable())
812*cdf0e10cSrcweir 	    {
813*cdf0e10cSrcweir 		    if (!bApi)
814*cdf0e10cSrcweir 			    rDocShell.ErrorMessage(aTester.GetMessageId());
815*cdf0e10cSrcweir 		    pNewCell->Delete();
816*cdf0e10cSrcweir 		    return sal_False;
817*cdf0e10cSrcweir 	    }
818*cdf0e10cSrcweir     }
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir     sal_Bool bEditCell = ( pNewCell->GetCellType() == CELLTYPE_EDIT );
821*cdf0e10cSrcweir 	ScBaseCell* pDocCell = pDoc->GetCell( rPos );
822*cdf0e10cSrcweir 	sal_Bool bEditDeleted = (pDocCell && pDocCell->GetCellType() == CELLTYPE_EDIT);
823*cdf0e10cSrcweir 	sal_Bool bHeight = ( bEditDeleted || bEditCell ||
824*cdf0e10cSrcweir 					pDoc->HasAttrib( ScRange(rPos), HASATTR_NEEDHEIGHT ) );
825*cdf0e10cSrcweir 
826*cdf0e10cSrcweir     ScBaseCell* pUndoCell = (bUndo && pDocCell) ? pDocCell->CloneWithoutNote( *pDoc, rPos ) : 0;
827*cdf0e10cSrcweir     ScBaseCell* pRedoCell = (bUndo && pNewCell) ? pNewCell->CloneWithoutNote( *pDoc, rPos ) : 0;
828*cdf0e10cSrcweir 
829*cdf0e10cSrcweir 	pDoc->PutCell( rPos, pNewCell );
830*cdf0e10cSrcweir 
831*cdf0e10cSrcweir 	//	wegen ChangeTracking darf UndoAction erst nach PutCell angelegt werden
832*cdf0e10cSrcweir 	if (bUndo)
833*cdf0e10cSrcweir 	{
834*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
835*cdf0e10cSrcweir 				new ScUndoPutCell( &rDocShell, rPos, pUndoCell, pRedoCell, bHeight ) );
836*cdf0e10cSrcweir 	}
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir 	if (bHeight)
839*cdf0e10cSrcweir 		AdjustRowHeight( ScRange(rPos) );
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir     if (!bXMLLoading)
842*cdf0e10cSrcweir     	rDocShell.PostPaintCell( rPos );
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir     aModificator.SetDocumentModified();
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir     // #i925#; it is not neccessary to notify on loading a XML document
847*cdf0e10cSrcweir     // #103934#; notify editline and cell in edit mode
848*cdf0e10cSrcweir     if (bApi && !bXMLLoading)
849*cdf0e10cSrcweir         NotifyInputHandler( rPos );
850*cdf0e10cSrcweir 
851*cdf0e10cSrcweir 	return sal_True;
852*cdf0e10cSrcweir }
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir void ScDocFunc::NotifyInputHandler( const ScAddress& rPos )
855*cdf0e10cSrcweir {
856*cdf0e10cSrcweir     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
857*cdf0e10cSrcweir     if ( pViewSh && pViewSh->GetViewData()->GetDocShell() == &rDocShell )
858*cdf0e10cSrcweir     {
859*cdf0e10cSrcweir         ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
860*cdf0e10cSrcweir         if ( pInputHdl && pInputHdl->GetCursorPos() == rPos )
861*cdf0e10cSrcweir         {
862*cdf0e10cSrcweir             sal_Bool bIsEditMode(pInputHdl->IsEditMode());
863*cdf0e10cSrcweir 
864*cdf0e10cSrcweir             // set modified if in editmode, because so the string is not set in the InputWindow like in the cell
865*cdf0e10cSrcweir             // (the cell shows the same like the InputWindow)
866*cdf0e10cSrcweir             if (bIsEditMode)
867*cdf0e10cSrcweir                 pInputHdl->SetModified();
868*cdf0e10cSrcweir             pViewSh->UpdateInputHandler(sal_False, !bIsEditMode);
869*cdf0e10cSrcweir         }
870*cdf0e10cSrcweir     }
871*cdf0e10cSrcweir }
872*cdf0e10cSrcweir 
873*cdf0e10cSrcweir 		struct ScMyRememberItem
874*cdf0e10cSrcweir 		{
875*cdf0e10cSrcweir 			sal_uInt16		nIndex;
876*cdf0e10cSrcweir 			SfxItemSet	aItemSet;
877*cdf0e10cSrcweir 
878*cdf0e10cSrcweir 			ScMyRememberItem(const SfxItemSet& rItemSet, sal_uInt16 nTempIndex) :
879*cdf0e10cSrcweir                 nIndex(nTempIndex), aItemSet(rItemSet) {}
880*cdf0e10cSrcweir 		};
881*cdf0e10cSrcweir 
882*cdf0e10cSrcweir 		typedef ::std::list<ScMyRememberItem*> ScMyRememberItemList;
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir sal_Bool ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngine, sal_Bool bInterpret, sal_Bool bApi )
885*cdf0e10cSrcweir {
886*cdf0e10cSrcweir 	//	PutData ruft PutCell oder SetNormalString
887*cdf0e10cSrcweir 
888*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
889*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
890*cdf0e10cSrcweir 	ScEditAttrTester aTester( &rEngine );
891*cdf0e10cSrcweir 	sal_Bool bEditCell = aTester.NeedsObject();
892*cdf0e10cSrcweir 	if ( bEditCell )
893*cdf0e10cSrcweir 	{
894*cdf0e10cSrcweir         // #i61702# With bLoseContent set, the content of rEngine isn't restored
895*cdf0e10cSrcweir         // (used in loading XML, where after the removeActionLock call the API obejct's
896*cdf0e10cSrcweir         // EditEngine isn't accessed again.
897*cdf0e10cSrcweir         sal_Bool bLoseContent = pDoc->IsImportingXML();
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir 		sal_Bool bUpdateMode(rEngine.GetUpdateMode());
900*cdf0e10cSrcweir 		if (bUpdateMode)
901*cdf0e10cSrcweir 			rEngine.SetUpdateMode(sal_False);
902*cdf0e10cSrcweir 
903*cdf0e10cSrcweir 		ScMyRememberItemList aRememberItems;
904*cdf0e10cSrcweir 		ScMyRememberItem* pRememberItem = NULL;
905*cdf0e10cSrcweir 
906*cdf0e10cSrcweir 		//	All paragraph attributes must be removed before calling CreateTextObject,
907*cdf0e10cSrcweir 		//	not only alignment, so the object doesn't contain the cell attributes as
908*cdf0e10cSrcweir 		//	paragraph attributes. Before remove the attributes store they in a list to
909*cdf0e10cSrcweir 		//	set they back to the EditEngine.
910*cdf0e10cSrcweir 		sal_uInt16 nCount = rEngine.GetParagraphCount();
911*cdf0e10cSrcweir 		for (sal_uInt16 i=0; i<nCount; i++)
912*cdf0e10cSrcweir 		{
913*cdf0e10cSrcweir 			const SfxItemSet& rOld = rEngine.GetParaAttribs( i );
914*cdf0e10cSrcweir 			if ( rOld.Count() )
915*cdf0e10cSrcweir 			{
916*cdf0e10cSrcweir                 if ( !bLoseContent )
917*cdf0e10cSrcweir                 {
918*cdf0e10cSrcweir                     pRememberItem = new ScMyRememberItem(rEngine.GetParaAttribs(i), i);
919*cdf0e10cSrcweir                     aRememberItems.push_back(pRememberItem);
920*cdf0e10cSrcweir                 }
921*cdf0e10cSrcweir 				rEngine.SetParaAttribs( i, SfxItemSet( *rOld.GetPool(), rOld.GetRanges() ) );
922*cdf0e10cSrcweir 			}
923*cdf0e10cSrcweir 		}
924*cdf0e10cSrcweir 
925*cdf0e10cSrcweir 		EditTextObject* pNewData = rEngine.CreateTextObject();
926*cdf0e10cSrcweir 		bRet = PutCell( rPos,
927*cdf0e10cSrcweir 						new ScEditCell( pNewData, pDoc, rEngine.GetEditTextObjectPool() ),
928*cdf0e10cSrcweir 						bApi );
929*cdf0e10cSrcweir 		delete pNewData;
930*cdf0e10cSrcweir 
931*cdf0e10cSrcweir 		// Set the paragraph attributes back to the EditEngine.
932*cdf0e10cSrcweir 		if (!aRememberItems.empty())
933*cdf0e10cSrcweir 		{
934*cdf0e10cSrcweir //            ScMyRememberItem* pRememberItem = NULL;
935*cdf0e10cSrcweir 			ScMyRememberItemList::iterator aItr = aRememberItems.begin();
936*cdf0e10cSrcweir 			while (aItr != aRememberItems.end())
937*cdf0e10cSrcweir 			{
938*cdf0e10cSrcweir 				pRememberItem = *aItr;
939*cdf0e10cSrcweir 				rEngine.SetParaAttribs(pRememberItem->nIndex, pRememberItem->aItemSet);
940*cdf0e10cSrcweir 				delete pRememberItem;
941*cdf0e10cSrcweir 				aItr = aRememberItems.erase(aItr);
942*cdf0e10cSrcweir 			}
943*cdf0e10cSrcweir 		}
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir         // #i61702# if the content isn't accessed, there's no need to set the UpdateMode again
946*cdf0e10cSrcweir         if ( bUpdateMode && !bLoseContent )
947*cdf0e10cSrcweir 			rEngine.SetUpdateMode(sal_True);
948*cdf0e10cSrcweir 	}
949*cdf0e10cSrcweir 	else
950*cdf0e10cSrcweir 	{
951*cdf0e10cSrcweir 		String aText = rEngine.GetText();
952*cdf0e10cSrcweir 		if ( bInterpret || !aText.Len() )
953*cdf0e10cSrcweir 			bRet = SetNormalString( rPos, aText, bApi );
954*cdf0e10cSrcweir 		else
955*cdf0e10cSrcweir 			bRet = PutCell( rPos, new ScStringCell( aText ), bApi );
956*cdf0e10cSrcweir 	}
957*cdf0e10cSrcweir 
958*cdf0e10cSrcweir 	if ( bRet && aTester.NeedsCellAttr() )
959*cdf0e10cSrcweir 	{
960*cdf0e10cSrcweir 		const SfxItemSet& rEditAttr = aTester.GetAttribs();
961*cdf0e10cSrcweir 		ScPatternAttr aPattern( pDoc->GetPool() );
962*cdf0e10cSrcweir 		aPattern.GetFromEditItemSet( &rEditAttr );
963*cdf0e10cSrcweir 		aPattern.DeleteUnchanged( pDoc->GetPattern( rPos.Col(), rPos.Row(), rPos.Tab() ) );
964*cdf0e10cSrcweir 		aPattern.GetItemSet().ClearItem( ATTR_HOR_JUSTIFY );	// wasn't removed above if no edit object
965*cdf0e10cSrcweir 		if ( aPattern.GetItemSet().Count() > 0 )
966*cdf0e10cSrcweir 		{
967*cdf0e10cSrcweir 			ScMarkData aMark;
968*cdf0e10cSrcweir 			aMark.SelectTable( rPos.Tab(), sal_True );
969*cdf0e10cSrcweir 			aMark.SetMarkArea( ScRange( rPos ) );
970*cdf0e10cSrcweir 			ApplyAttributes( aMark, aPattern, sal_True, bApi );
971*cdf0e10cSrcweir 		}
972*cdf0e10cSrcweir 	}
973*cdf0e10cSrcweir 
974*cdf0e10cSrcweir 	return bRet;
975*cdf0e10cSrcweir }
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
979*cdf0e10cSrcweir {
980*cdf0e10cSrcweir 	ScTokenArray* pCode = new ScTokenArray;
981*cdf0e10cSrcweir     pCode->AddString( rText );
982*cdf0e10cSrcweir     if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
983*cdf0e10cSrcweir         pCode->AddString( rFormulaNmsp );
984*cdf0e10cSrcweir 	return pCode;
985*cdf0e10cSrcweir }
986*cdf0e10cSrcweir 
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir ScBaseCell* ScDocFunc::InterpretEnglishString( const ScAddress& rPos,
989*cdf0e10cSrcweir         const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar, short* pRetFormatType )
990*cdf0e10cSrcweir {
991*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
992*cdf0e10cSrcweir 	ScBaseCell* pNewCell = NULL;
993*cdf0e10cSrcweir 
994*cdf0e10cSrcweir 	if ( rText.Len() > 1 && rText.GetChar(0) == '=' )
995*cdf0e10cSrcweir 	{
996*cdf0e10cSrcweir 		ScTokenArray* pCode;
997*cdf0e10cSrcweir 		if ( pDoc->IsImportingXML() )
998*cdf0e10cSrcweir 		{	// temporary formula string as string tokens
999*cdf0e10cSrcweir             pCode = lcl_ScDocFunc_CreateTokenArrayXML( rText, rFormulaNmsp, eGrammar );
1000*cdf0e10cSrcweir             pDoc->IncXMLImportedFormulaCount( rText.Len() );
1001*cdf0e10cSrcweir 		}
1002*cdf0e10cSrcweir 		else
1003*cdf0e10cSrcweir 		{
1004*cdf0e10cSrcweir 			ScCompiler aComp( pDoc, rPos );
1005*cdf0e10cSrcweir             aComp.SetGrammar(eGrammar);
1006*cdf0e10cSrcweir 			pCode = aComp.CompileString( rText );
1007*cdf0e10cSrcweir 		}
1008*cdf0e10cSrcweir 		pNewCell = new ScFormulaCell( pDoc, rPos, pCode, eGrammar, MM_NONE );
1009*cdf0e10cSrcweir 		delete pCode;	// Zell-ctor hat das TokenArray kopiert
1010*cdf0e10cSrcweir 	}
1011*cdf0e10cSrcweir 	else if ( rText.Len() > 1 && rText.GetChar(0) == '\'' )
1012*cdf0e10cSrcweir 	{
1013*cdf0e10cSrcweir 		//	for bEnglish, "'" at the beginning is always interpreted as text
1014*cdf0e10cSrcweir 		//	marker and stripped
1015*cdf0e10cSrcweir 		pNewCell = ScBaseCell::CreateTextCell( rText.Copy( 1 ), pDoc );
1016*cdf0e10cSrcweir 	}
1017*cdf0e10cSrcweir 	else		// (nur) auf englisches Zahlformat testen
1018*cdf0e10cSrcweir 	{
1019*cdf0e10cSrcweir 		SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1020*cdf0e10cSrcweir 		sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
1021*cdf0e10cSrcweir 		double fVal;
1022*cdf0e10cSrcweir 		if ( pFormatter->IsNumberFormat( rText, nEnglish, fVal ) )
1023*cdf0e10cSrcweir         {
1024*cdf0e10cSrcweir 			pNewCell = new ScValueCell( fVal );
1025*cdf0e10cSrcweir             // return the format type from the English format, so a localized format can be created
1026*cdf0e10cSrcweir             if ( pRetFormatType )
1027*cdf0e10cSrcweir                 *pRetFormatType = pFormatter->GetType( nEnglish );
1028*cdf0e10cSrcweir         }
1029*cdf0e10cSrcweir 		else if ( rText.Len() )
1030*cdf0e10cSrcweir 			pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );
1031*cdf0e10cSrcweir 
1032*cdf0e10cSrcweir 		//	das (englische) Zahlformat wird nicht gesetzt
1033*cdf0e10cSrcweir 		//!	passendes lokales Format suchen und setzen???
1034*cdf0e10cSrcweir 	}
1035*cdf0e10cSrcweir 
1036*cdf0e10cSrcweir 	return pNewCell;
1037*cdf0e10cSrcweir }
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir 
1040*cdf0e10cSrcweir sal_Bool ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText,
1041*cdf0e10cSrcweir         sal_Bool bInterpret, sal_Bool bEnglish, sal_Bool bApi,
1042*cdf0e10cSrcweir         const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
1043*cdf0e10cSrcweir {
1044*cdf0e10cSrcweir 	//	SetCellText ruft PutCell oder SetNormalString
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1047*cdf0e10cSrcweir 	ScBaseCell* pNewCell = NULL;
1048*cdf0e10cSrcweir 	if ( bInterpret )
1049*cdf0e10cSrcweir 	{
1050*cdf0e10cSrcweir 		if ( bEnglish )
1051*cdf0e10cSrcweir 		{
1052*cdf0e10cSrcweir             ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
1053*cdf0e10cSrcweir             if (bApi)
1054*cdf0e10cSrcweir                 pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir 			//	code moved to own method InterpretEnglishString because it is also used in
1057*cdf0e10cSrcweir 			//	ScCellRangeObj::setFormulaArray
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir             pNewCell = InterpretEnglishString( rPos, rText, rFormulaNmsp, eGrammar );
1060*cdf0e10cSrcweir 		}
1061*cdf0e10cSrcweir 		// sonst Null behalten -> SetString mit lokalen Formeln/Zahlformat
1062*cdf0e10cSrcweir 	}
1063*cdf0e10cSrcweir 	else if ( rText.Len() )
1064*cdf0e10cSrcweir     {
1065*cdf0e10cSrcweir         OSL_ENSURE( rFormulaNmsp.Len() == 0, "ScDocFunc::SetCellText - formula namespace, but do not interpret?" );
1066*cdf0e10cSrcweir 		pNewCell = ScBaseCell::CreateTextCell( rText, pDoc );	// immer Text
1067*cdf0e10cSrcweir     }
1068*cdf0e10cSrcweir 
1069*cdf0e10cSrcweir 	if (pNewCell)
1070*cdf0e10cSrcweir 		return PutCell( rPos, pNewCell, bApi );
1071*cdf0e10cSrcweir 	else
1072*cdf0e10cSrcweir 		return SetNormalString( rPos, rText, bApi );
1073*cdf0e10cSrcweir }
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir //------------------------------------------------------------------------
1076*cdf0e10cSrcweir 
1077*cdf0e10cSrcweir bool ScDocFunc::ShowNote( const ScAddress& rPos, bool bShow )
1078*cdf0e10cSrcweir {
1079*cdf0e10cSrcweir 	ScDocument& rDoc = *rDocShell.GetDocument();
1080*cdf0e10cSrcweir 	ScPostIt* pNote = rDoc.GetNote( rPos );
1081*cdf0e10cSrcweir     if( !pNote || (bShow == pNote->IsCaptionShown()) ) return false;
1082*cdf0e10cSrcweir 
1083*cdf0e10cSrcweir     // move the caption to internal or hidden layer and create undo action
1084*cdf0e10cSrcweir     pNote->ShowCaption( rPos, bShow );
1085*cdf0e10cSrcweir     if( rDoc.IsUndoEnabled() )
1086*cdf0e10cSrcweir         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideNote( rDocShell, rPos, bShow ) );
1087*cdf0e10cSrcweir 
1088*cdf0e10cSrcweir     if (rDoc.IsStreamValid(rPos.Tab()))
1089*cdf0e10cSrcweir         rDoc.SetStreamValid(rPos.Tab(), sal_False);
1090*cdf0e10cSrcweir 
1091*cdf0e10cSrcweir     rDocShell.SetDocumentModified();
1092*cdf0e10cSrcweir 
1093*cdf0e10cSrcweir     return true;
1094*cdf0e10cSrcweir }
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir //------------------------------------------------------------------------
1097*cdf0e10cSrcweir 
1098*cdf0e10cSrcweir bool ScDocFunc::SetNoteText( const ScAddress& rPos, const String& rText, sal_Bool bApi )
1099*cdf0e10cSrcweir {
1100*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
1101*cdf0e10cSrcweir 
1102*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1103*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1104*cdf0e10cSrcweir 	if (!aTester.IsEditable())
1105*cdf0e10cSrcweir 	{
1106*cdf0e10cSrcweir 		if (!bApi)
1107*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
1108*cdf0e10cSrcweir         return false;
1109*cdf0e10cSrcweir 	}
1110*cdf0e10cSrcweir 
1111*cdf0e10cSrcweir 	String aNewText = rText;
1112*cdf0e10cSrcweir 	aNewText.ConvertLineEnd();		//! ist das noetig ???
1113*cdf0e10cSrcweir 
1114*cdf0e10cSrcweir     if( ScPostIt* pNote = (aNewText.Len() > 0) ? pDoc->GetOrCreateNote( rPos ) : pDoc->GetNote( rPos ) )
1115*cdf0e10cSrcweir         pNote->SetText( rPos, aNewText );
1116*cdf0e10cSrcweir 
1117*cdf0e10cSrcweir 	//!	Undo !!!
1118*cdf0e10cSrcweir 
1119*cdf0e10cSrcweir     if (pDoc->IsStreamValid(rPos.Tab()))
1120*cdf0e10cSrcweir         pDoc->SetStreamValid(rPos.Tab(), sal_False);
1121*cdf0e10cSrcweir 
1122*cdf0e10cSrcweir 	rDocShell.PostPaintCell( rPos );
1123*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
1124*cdf0e10cSrcweir 
1125*cdf0e10cSrcweir     return true;
1126*cdf0e10cSrcweir }
1127*cdf0e10cSrcweir 
1128*cdf0e10cSrcweir //------------------------------------------------------------------------
1129*cdf0e10cSrcweir 
1130*cdf0e10cSrcweir bool ScDocFunc::ReplaceNote( const ScAddress& rPos, const String& rNoteText, const String* pAuthor, const String* pDate, sal_Bool bApi )
1131*cdf0e10cSrcweir {
1132*cdf0e10cSrcweir     bool bDone = false;
1133*cdf0e10cSrcweir 
1134*cdf0e10cSrcweir     ScDocShellModificator aModificator( rDocShell );
1135*cdf0e10cSrcweir     ScDocument& rDoc = *rDocShell.GetDocument();
1136*cdf0e10cSrcweir     ScEditableTester aTester( &rDoc, rPos.Tab(), rPos.Col(),rPos.Row(), rPos.Col(),rPos.Row() );
1137*cdf0e10cSrcweir     if (aTester.IsEditable())
1138*cdf0e10cSrcweir     {
1139*cdf0e10cSrcweir         ScDrawLayer* pDrawLayer = rDoc.GetDrawLayer();
1140*cdf0e10cSrcweir         ::svl::IUndoManager* pUndoMgr = (pDrawLayer && rDoc.IsUndoEnabled()) ? rDocShell.GetUndoManager() : 0;
1141*cdf0e10cSrcweir 
1142*cdf0e10cSrcweir         ScNoteData aOldData;
1143*cdf0e10cSrcweir         ScPostIt* pOldNote = rDoc.ReleaseNote( rPos );
1144*cdf0e10cSrcweir         if( pOldNote )
1145*cdf0e10cSrcweir         {
1146*cdf0e10cSrcweir             // ensure existing caption object before draw undo tracking starts
1147*cdf0e10cSrcweir             pOldNote->GetOrCreateCaption( rPos );
1148*cdf0e10cSrcweir             // rescue note data for undo
1149*cdf0e10cSrcweir             aOldData = pOldNote->GetNoteData();
1150*cdf0e10cSrcweir         }
1151*cdf0e10cSrcweir 
1152*cdf0e10cSrcweir         // collect drawing undo actions for deleting/inserting caption obejcts
1153*cdf0e10cSrcweir         if( pUndoMgr )
1154*cdf0e10cSrcweir             pDrawLayer->BeginCalcUndo();
1155*cdf0e10cSrcweir 
1156*cdf0e10cSrcweir         // delete the note (creates drawing undo action for the caption object)
1157*cdf0e10cSrcweir         delete pOldNote;
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir         // create new note (creates drawing undo action for the new caption object)
1160*cdf0e10cSrcweir         ScNoteData aNewData;
1161*cdf0e10cSrcweir         if( ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true ) )
1162*cdf0e10cSrcweir         {
1163*cdf0e10cSrcweir             if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
1164*cdf0e10cSrcweir             if( pDate ) pNewNote->SetDate( *pDate );
1165*cdf0e10cSrcweir             // rescue note data for undo
1166*cdf0e10cSrcweir             aNewData = pNewNote->GetNoteData();
1167*cdf0e10cSrcweir         }
1168*cdf0e10cSrcweir 
1169*cdf0e10cSrcweir         // create the undo action
1170*cdf0e10cSrcweir         if( pUndoMgr && (aOldData.mpCaption || aNewData.mpCaption) )
1171*cdf0e10cSrcweir             pUndoMgr->AddUndoAction( new ScUndoReplaceNote( rDocShell, rPos, aOldData, aNewData, pDrawLayer->GetCalcUndo() ) );
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir         // repaint cell (to make note marker visible)
1174*cdf0e10cSrcweir         rDocShell.PostPaintCell( rPos );
1175*cdf0e10cSrcweir 
1176*cdf0e10cSrcweir         if (rDoc.IsStreamValid(rPos.Tab()))
1177*cdf0e10cSrcweir             rDoc.SetStreamValid(rPos.Tab(), sal_False);
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir         aModificator.SetDocumentModified();
1180*cdf0e10cSrcweir         bDone = true;
1181*cdf0e10cSrcweir     }
1182*cdf0e10cSrcweir     else if (!bApi)
1183*cdf0e10cSrcweir     {
1184*cdf0e10cSrcweir         rDocShell.ErrorMessage(aTester.GetMessageId());
1185*cdf0e10cSrcweir     }
1186*cdf0e10cSrcweir 
1187*cdf0e10cSrcweir     return bDone;
1188*cdf0e10cSrcweir }
1189*cdf0e10cSrcweir 
1190*cdf0e10cSrcweir //------------------------------------------------------------------------
1191*cdf0e10cSrcweir 
1192*cdf0e10cSrcweir sal_Bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
1193*cdf0e10cSrcweir 									sal_Bool bRecord, sal_Bool bApi )
1194*cdf0e10cSrcweir {
1195*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1196*cdf0e10cSrcweir 	if ( bRecord && !pDoc->IsUndoEnabled() )
1197*cdf0e10cSrcweir 		bRecord = sal_False;
1198*cdf0e10cSrcweir 
1199*cdf0e10cSrcweir     sal_Bool bImportingXML = pDoc->IsImportingXML();
1200*cdf0e10cSrcweir     // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1201*cdf0e10cSrcweir     // #i62483# When loading XML, the check can be skipped altogether.
1202*cdf0e10cSrcweir 	sal_Bool bOnlyNotBecauseOfMatrix;
1203*cdf0e10cSrcweir     if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1204*cdf0e10cSrcweir 			&& !bOnlyNotBecauseOfMatrix )
1205*cdf0e10cSrcweir 	{
1206*cdf0e10cSrcweir 		if (!bApi)
1207*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PROTECTIONERR);
1208*cdf0e10cSrcweir 		return sal_False;
1209*cdf0e10cSrcweir 	}
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
1212*cdf0e10cSrcweir 
1213*cdf0e10cSrcweir 	//!	Umrandung
1214*cdf0e10cSrcweir 
1215*cdf0e10cSrcweir 	ScRange aMultiRange;
1216*cdf0e10cSrcweir 	sal_Bool bMulti = rMark.IsMultiMarked();
1217*cdf0e10cSrcweir 	if ( bMulti )
1218*cdf0e10cSrcweir 		rMark.GetMultiMarkArea( aMultiRange );
1219*cdf0e10cSrcweir 	else
1220*cdf0e10cSrcweir 		rMark.GetMarkArea( aMultiRange );
1221*cdf0e10cSrcweir 
1222*cdf0e10cSrcweir 	if ( bRecord )
1223*cdf0e10cSrcweir 	{
1224*cdf0e10cSrcweir 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1225*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, aMultiRange.aStart.Tab(), aMultiRange.aEnd.Tab() );
1226*cdf0e10cSrcweir 		pDoc->CopyToDocument( aMultiRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
1227*cdf0e10cSrcweir 
1228*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
1229*cdf0e10cSrcweir 			new ScUndoSelectionAttr(
1230*cdf0e10cSrcweir 					&rDocShell, rMark,
1231*cdf0e10cSrcweir 					aMultiRange.aStart.Col(), aMultiRange.aStart.Row(), aMultiRange.aStart.Tab(),
1232*cdf0e10cSrcweir 					aMultiRange.aEnd.Col(), aMultiRange.aEnd.Row(), aMultiRange.aEnd.Tab(),
1233*cdf0e10cSrcweir 					pUndoDoc, bMulti, &rPattern ) );
1234*cdf0e10cSrcweir 	}
1235*cdf0e10cSrcweir 
1236*cdf0e10cSrcweir 	// While loading XML it is not neccessary to ask HasAttrib. It needs too much time.
1237*cdf0e10cSrcweir 	sal_uInt16 nExtFlags = 0;
1238*cdf0e10cSrcweir 	if ( !bImportingXML )
1239*cdf0e10cSrcweir 		rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );		// content before the change
1240*cdf0e10cSrcweir 	pDoc->ApplySelectionPattern( rPattern, rMark );
1241*cdf0e10cSrcweir 	if ( !bImportingXML )
1242*cdf0e10cSrcweir 		rDocShell.UpdatePaintExt( nExtFlags, aMultiRange );		// content after the change
1243*cdf0e10cSrcweir 
1244*cdf0e10cSrcweir 	if (!AdjustRowHeight( aMultiRange ))
1245*cdf0e10cSrcweir 		rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
1246*cdf0e10cSrcweir 	else if (nExtFlags & SC_PF_LINES)
1247*cdf0e10cSrcweir 		lcl_PaintAbove( rDocShell, aMultiRange );	// fuer Linien ueber dem Bereich
1248*cdf0e10cSrcweir 
1249*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
1250*cdf0e10cSrcweir 
1251*cdf0e10cSrcweir 	return sal_True;
1252*cdf0e10cSrcweir }
1253*cdf0e10cSrcweir 
1254*cdf0e10cSrcweir 
1255*cdf0e10cSrcweir sal_Bool ScDocFunc::ApplyStyle( const ScMarkData& rMark, const String& rStyleName,
1256*cdf0e10cSrcweir 									sal_Bool bRecord, sal_Bool bApi )
1257*cdf0e10cSrcweir {
1258*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1259*cdf0e10cSrcweir 	if ( bRecord && !pDoc->IsUndoEnabled() )
1260*cdf0e10cSrcweir 		bRecord = sal_False;
1261*cdf0e10cSrcweir 
1262*cdf0e10cSrcweir     sal_Bool bImportingXML = pDoc->IsImportingXML();
1263*cdf0e10cSrcweir     // Cell formats can still be set if the range isn't editable only because of matrix formulas.
1264*cdf0e10cSrcweir     // #i62483# When loading XML, the check can be skipped altogether.
1265*cdf0e10cSrcweir 	sal_Bool bOnlyNotBecauseOfMatrix;
1266*cdf0e10cSrcweir     if ( !bImportingXML && !pDoc->IsSelectionEditable( rMark, &bOnlyNotBecauseOfMatrix )
1267*cdf0e10cSrcweir 			&& !bOnlyNotBecauseOfMatrix )
1268*cdf0e10cSrcweir 	{
1269*cdf0e10cSrcweir 		if (!bApi)
1270*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PROTECTIONERR);
1271*cdf0e10cSrcweir 		return sal_False;
1272*cdf0e10cSrcweir 	}
1273*cdf0e10cSrcweir 
1274*cdf0e10cSrcweir 	ScStyleSheet* pStyleSheet = (ScStyleSheet*) pDoc->GetStyleSheetPool()->Find(
1275*cdf0e10cSrcweir 												rStyleName, SFX_STYLE_FAMILY_PARA );
1276*cdf0e10cSrcweir 	if (!pStyleSheet)
1277*cdf0e10cSrcweir 		return sal_False;
1278*cdf0e10cSrcweir 
1279*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir 	ScRange aMultiRange;
1282*cdf0e10cSrcweir 	sal_Bool bMulti = rMark.IsMultiMarked();
1283*cdf0e10cSrcweir 	if ( bMulti )
1284*cdf0e10cSrcweir 		rMark.GetMultiMarkArea( aMultiRange );
1285*cdf0e10cSrcweir 	else
1286*cdf0e10cSrcweir 		rMark.GetMarkArea( aMultiRange );
1287*cdf0e10cSrcweir 
1288*cdf0e10cSrcweir 	if ( bRecord )
1289*cdf0e10cSrcweir 	{
1290*cdf0e10cSrcweir 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1291*cdf0e10cSrcweir 		SCTAB nStartTab = aMultiRange.aStart.Tab();
1292*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
1293*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
1294*cdf0e10cSrcweir 		for (SCTAB i=0; i<nTabCount; i++)
1295*cdf0e10cSrcweir 			if (i != nStartTab && rMark.GetTableSelect(i))
1296*cdf0e10cSrcweir 				pUndoDoc->AddUndoTab( i, i );
1297*cdf0e10cSrcweir 
1298*cdf0e10cSrcweir 		ScRange aCopyRange = aMultiRange;
1299*cdf0e10cSrcweir 		aCopyRange.aStart.SetTab(0);
1300*cdf0e10cSrcweir 		aCopyRange.aEnd.SetTab(nTabCount-1);
1301*cdf0e10cSrcweir 		pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, bMulti, pUndoDoc, &rMark );
1302*cdf0e10cSrcweir 
1303*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
1304*cdf0e10cSrcweir 			new ScUndoSelectionStyle(
1305*cdf0e10cSrcweir 					&rDocShell, rMark, aMultiRange, rStyleName, pUndoDoc ) );
1306*cdf0e10cSrcweir 
1307*cdf0e10cSrcweir 	}
1308*cdf0e10cSrcweir 
1309*cdf0e10cSrcweir //	sal_Bool bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
1310*cdf0e10cSrcweir //	pDoc->ApplySelectionPattern( rPattern, rMark );
1311*cdf0e10cSrcweir 
1312*cdf0e10cSrcweir 	pDoc->ApplySelectionStyle( (ScStyleSheet&)*pStyleSheet, rMark );
1313*cdf0e10cSrcweir 
1314*cdf0e10cSrcweir //	if (!bPaintExt)
1315*cdf0e10cSrcweir //		bPaintExt = pDoc->HasAttrib( aMultiRange, HASATTR_PAINTEXT );
1316*cdf0e10cSrcweir //	sal_uInt16 nExtFlags = bPaintExt ? SC_PF_LINES : 0;
1317*cdf0e10cSrcweir 	sal_uInt16 nExtFlags = 0;
1318*cdf0e10cSrcweir 	if (!AdjustRowHeight( aMultiRange ))
1319*cdf0e10cSrcweir 		rDocShell.PostPaint( aMultiRange, PAINT_GRID, nExtFlags );
1320*cdf0e10cSrcweir 	else if (nExtFlags & SC_PF_LINES)
1321*cdf0e10cSrcweir 		lcl_PaintAbove( rDocShell, aMultiRange );	// fuer Linien ueber dem Bereich
1322*cdf0e10cSrcweir 
1323*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
1324*cdf0e10cSrcweir 
1325*cdf0e10cSrcweir 	return sal_True;
1326*cdf0e10cSrcweir }
1327*cdf0e10cSrcweir 
1328*cdf0e10cSrcweir //------------------------------------------------------------------------
1329*cdf0e10cSrcweir 
1330*cdf0e10cSrcweir sal_Bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark, InsCellCmd eCmd,
1331*cdf0e10cSrcweir 								sal_Bool bRecord, sal_Bool bApi, sal_Bool bPartOfPaste )
1332*cdf0e10cSrcweir {
1333*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
1334*cdf0e10cSrcweir 
1335*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
1336*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
1337*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
1338*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
1339*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
1340*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
1341*cdf0e10cSrcweir 
1342*cdf0e10cSrcweir 	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
1343*cdf0e10cSrcweir 	{
1344*cdf0e10cSrcweir 		DBG_ERROR("invalid row in InsertCells");
1345*cdf0e10cSrcweir 		return sal_False;
1346*cdf0e10cSrcweir 	}
1347*cdf0e10cSrcweir 
1348*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1349*cdf0e10cSrcweir 	SCTAB nTabCount = pDoc->GetTableCount();
1350*cdf0e10cSrcweir 	SCCOL nPaintStartX = nStartCol;
1351*cdf0e10cSrcweir 	SCROW nPaintStartY = nStartRow;
1352*cdf0e10cSrcweir 	SCCOL nPaintEndX = nEndCol;
1353*cdf0e10cSrcweir 	SCROW nPaintEndY = nEndRow;
1354*cdf0e10cSrcweir 	sal_uInt16 nPaintFlags = PAINT_GRID;
1355*cdf0e10cSrcweir 	sal_Bool bSuccess;
1356*cdf0e10cSrcweir     SCTAB i;
1357*cdf0e10cSrcweir 
1358*cdf0e10cSrcweir     ScTabViewShell* pViewSh = rDocShell.GetBestViewShell();  //preserve current cursor position
1359*cdf0e10cSrcweir     SCCOL nCursorCol = 0;
1360*cdf0e10cSrcweir     SCROW nCursorRow = 0;
1361*cdf0e10cSrcweir     if( pViewSh )
1362*cdf0e10cSrcweir     {
1363*cdf0e10cSrcweir         nCursorCol = pViewSh->GetViewData()->GetCurX();
1364*cdf0e10cSrcweir         nCursorRow = pViewSh->GetViewData()->GetCurY();
1365*cdf0e10cSrcweir     }
1366*cdf0e10cSrcweir 
1367*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
1368*cdf0e10cSrcweir 		bRecord = sal_False;
1369*cdf0e10cSrcweir 
1370*cdf0e10cSrcweir     ScMarkData aMark;
1371*cdf0e10cSrcweir     if (pTabMark)
1372*cdf0e10cSrcweir         aMark = *pTabMark;
1373*cdf0e10cSrcweir     else
1374*cdf0e10cSrcweir     {
1375*cdf0e10cSrcweir         SCTAB nCount = 0;
1376*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
1377*cdf0e10cSrcweir         {
1378*cdf0e10cSrcweir             if( !pDoc->IsScenario(i) )
1379*cdf0e10cSrcweir             {
1380*cdf0e10cSrcweir                 nCount++;
1381*cdf0e10cSrcweir                 if( nCount == nEndTab+1 )
1382*cdf0e10cSrcweir                 {
1383*cdf0e10cSrcweir                     aMark.SelectTable( i, sal_True );
1384*cdf0e10cSrcweir                     break;
1385*cdf0e10cSrcweir                 }
1386*cdf0e10cSrcweir             }
1387*cdf0e10cSrcweir         }
1388*cdf0e10cSrcweir     }
1389*cdf0e10cSrcweir 
1390*cdf0e10cSrcweir     ScMarkData aFullMark( aMark );          // including scenario sheets
1391*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
1392*cdf0e10cSrcweir         if( aMark.GetTableSelect( i ) )
1393*cdf0e10cSrcweir         {
1394*cdf0e10cSrcweir             for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1395*cdf0e10cSrcweir                 aFullMark.SelectTable( j, sal_True );
1396*cdf0e10cSrcweir         }
1397*cdf0e10cSrcweir 
1398*cdf0e10cSrcweir     SCTAB nSelCount = aMark.GetSelectCount();
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir 	//	zugehoerige Szenarien auch anpassen
1401*cdf0e10cSrcweir 	// Test zusammengefasste
1402*cdf0e10cSrcweir 
1403*cdf0e10cSrcweir 	SCCOL nMergeTestStartX = nStartCol;
1404*cdf0e10cSrcweir 	SCROW nMergeTestStartY = nStartRow;
1405*cdf0e10cSrcweir 	SCCOL nMergeTestEndX = nEndCol;
1406*cdf0e10cSrcweir 	SCROW nMergeTestEndY = nEndRow;
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir     ScRange aExtendMergeRange( rRange );
1409*cdf0e10cSrcweir 
1410*cdf0e10cSrcweir     if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
1411*cdf0e10cSrcweir     {
1412*cdf0e10cSrcweir         pDoc->ExtendMerge( aExtendMergeRange );
1413*cdf0e10cSrcweir         pDoc->ExtendOverlapped( aExtendMergeRange );
1414*cdf0e10cSrcweir         nMergeTestEndX = aExtendMergeRange.aEnd.Col();
1415*cdf0e10cSrcweir         nMergeTestEndY = aExtendMergeRange.aEnd.Row();
1416*cdf0e10cSrcweir         nPaintEndX = nMergeTestEndX;
1417*cdf0e10cSrcweir         nPaintEndY = nMergeTestEndY;
1418*cdf0e10cSrcweir     }
1419*cdf0e10cSrcweir 
1420*cdf0e10cSrcweir 	if ( eCmd == INS_INSROWS )
1421*cdf0e10cSrcweir 	{
1422*cdf0e10cSrcweir 		nMergeTestStartX = 0;
1423*cdf0e10cSrcweir 		nMergeTestEndX = MAXCOL;
1424*cdf0e10cSrcweir 	}
1425*cdf0e10cSrcweir 	if ( eCmd == INS_INSCOLS )
1426*cdf0e10cSrcweir 	{
1427*cdf0e10cSrcweir 		nMergeTestStartY = 0;
1428*cdf0e10cSrcweir 		nMergeTestEndY = MAXROW;
1429*cdf0e10cSrcweir 	}
1430*cdf0e10cSrcweir 	if ( eCmd == INS_CELLSDOWN )
1431*cdf0e10cSrcweir 		nMergeTestEndY = MAXROW;
1432*cdf0e10cSrcweir 	if ( eCmd == INS_CELLSRIGHT )
1433*cdf0e10cSrcweir 		nMergeTestEndX = MAXCOL;
1434*cdf0e10cSrcweir 
1435*cdf0e10cSrcweir 	sal_Bool bNeedRefresh = sal_False;
1436*cdf0e10cSrcweir 
1437*cdf0e10cSrcweir 	SCCOL nEditTestEndX = (eCmd==INS_INSCOLS) ? MAXCOL : nMergeTestEndX;
1438*cdf0e10cSrcweir 	SCROW nEditTestEndY = (eCmd==INS_INSROWS) ? MAXROW : nMergeTestEndY;
1439*cdf0e10cSrcweir     ScEditableTester aTester( pDoc, nMergeTestStartX, nMergeTestStartY, nEditTestEndX, nEditTestEndY, aMark );
1440*cdf0e10cSrcweir 	if (!aTester.IsEditable())
1441*cdf0e10cSrcweir 	{
1442*cdf0e10cSrcweir 		if (!bApi)
1443*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
1444*cdf0e10cSrcweir 		return sal_False;
1445*cdf0e10cSrcweir 	}
1446*cdf0e10cSrcweir 
1447*cdf0e10cSrcweir 	WaitObject aWait( rDocShell.GetActiveDialogParent() );		// wichtig wegen TrackFormulas bei UpdateReference
1448*cdf0e10cSrcweir 
1449*cdf0e10cSrcweir 	ScDocument* pRefUndoDoc = NULL;
1450*cdf0e10cSrcweir 	ScRefUndoData* pUndoData = NULL;
1451*cdf0e10cSrcweir 	if ( bRecord )
1452*cdf0e10cSrcweir 	{
1453*cdf0e10cSrcweir 		pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1454*cdf0e10cSrcweir 		pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );
1455*cdf0e10cSrcweir 
1456*cdf0e10cSrcweir 		// pRefUndoDoc is filled in InsertCol / InsertRow
1457*cdf0e10cSrcweir 
1458*cdf0e10cSrcweir 		pUndoData = new ScRefUndoData( pDoc );
1459*cdf0e10cSrcweir 
1460*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();
1461*cdf0e10cSrcweir 	}
1462*cdf0e10cSrcweir 
1463*cdf0e10cSrcweir     // #i8302 : we unmerge overwhelming ranges, before insertion all the actions are put in the same ListAction
1464*cdf0e10cSrcweir     // the patch comes from mloiseleur and maoyg
1465*cdf0e10cSrcweir     sal_Bool bInsertMerge = sal_False;
1466*cdf0e10cSrcweir     std::vector<ScRange> qIncreaseRange;
1467*cdf0e10cSrcweir     String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTCELLS );
1468*cdf0e10cSrcweir     if (bRecord)
1469*cdf0e10cSrcweir         rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
1470*cdf0e10cSrcweir 
1471*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
1472*cdf0e10cSrcweir     {
1473*cdf0e10cSrcweir         if( aMark.GetTableSelect(i) )
1474*cdf0e10cSrcweir         {
1475*cdf0e10cSrcweir             if( pDoc->HasAttrib( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1476*cdf0e10cSrcweir             {
1477*cdf0e10cSrcweir                 if (eCmd==INS_CELLSRIGHT)
1478*cdf0e10cSrcweir                     bNeedRefresh = sal_True;
1479*cdf0e10cSrcweir 
1480*cdf0e10cSrcweir                 SCCOL nMergeStartX = nMergeTestStartX;
1481*cdf0e10cSrcweir                 SCROW nMergeStartY = nMergeTestStartY;
1482*cdf0e10cSrcweir                 SCCOL nMergeEndX   = nMergeTestEndX;
1483*cdf0e10cSrcweir                 SCROW nMergeEndY   = nMergeTestEndY;
1484*cdf0e10cSrcweir 
1485*cdf0e10cSrcweir                 pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
1486*cdf0e10cSrcweir                 pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
1487*cdf0e10cSrcweir 
1488*cdf0e10cSrcweir                 if(( eCmd == INS_CELLSDOWN && ( nMergeStartX != nMergeTestStartX || nMergeEndX != nMergeTestEndX )) ||
1489*cdf0e10cSrcweir                     (eCmd == INS_CELLSRIGHT && ( nMergeStartY != nMergeTestStartY || nMergeEndY != nMergeTestEndY )) )
1490*cdf0e10cSrcweir                 {
1491*cdf0e10cSrcweir                     if (!bApi)
1492*cdf0e10cSrcweir                         rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
1493*cdf0e10cSrcweir                     rDocShell.GetUndoManager()->LeaveListAction();
1494*cdf0e10cSrcweir                     return sal_False;
1495*cdf0e10cSrcweir                 }
1496*cdf0e10cSrcweir 
1497*cdf0e10cSrcweir                 SCCOL nTestCol = -1;
1498*cdf0e10cSrcweir                 SCROW nTestRow1 = -1;
1499*cdf0e10cSrcweir                 SCROW nTestRow2 = -1;
1500*cdf0e10cSrcweir 
1501*cdf0e10cSrcweir                 ScDocAttrIterator aTestIter( pDoc, i, nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY );
1502*cdf0e10cSrcweir                 ScRange aExtendRange( nMergeTestStartX, nMergeTestStartY, i, nMergeTestEndX, nMergeTestEndY, i );
1503*cdf0e10cSrcweir                 const ScPatternAttr* pPattern = NULL;
1504*cdf0e10cSrcweir                 const ScMergeAttr* pMergeFlag = NULL;
1505*cdf0e10cSrcweir                 const ScMergeFlagAttr* pMergeFlagAttr = NULL;
1506*cdf0e10cSrcweir                 while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
1507*cdf0e10cSrcweir                 {
1508*cdf0e10cSrcweir                     pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem(ATTR_MERGE);
1509*cdf0e10cSrcweir                     pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem(ATTR_MERGE_FLAG);
1510*cdf0e10cSrcweir                     sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
1511*cdf0e10cSrcweir                     if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
1512*cdf0e10cSrcweir                     {
1513*cdf0e10cSrcweir                         ScRange aRange( nTestCol, nTestRow1, i );
1514*cdf0e10cSrcweir                         pDoc->ExtendOverlapped(aRange);
1515*cdf0e10cSrcweir                         pDoc->ExtendMerge(aRange, sal_True, sal_True);
1516*cdf0e10cSrcweir 
1517*cdf0e10cSrcweir                         if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
1518*cdf0e10cSrcweir                         {
1519*cdf0e10cSrcweir                             for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
1520*cdf0e10cSrcweir                             {
1521*cdf0e10cSrcweir                                 ScRange aTestRange( nTestCol, nTestRow, i );
1522*cdf0e10cSrcweir                                 pDoc->ExtendOverlapped( aTestRange );
1523*cdf0e10cSrcweir                                 pDoc->ExtendMerge( aTestRange, sal_True, sal_True);
1524*cdf0e10cSrcweir                                 ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
1525*cdf0e10cSrcweir                                 if( !aExtendRange.In( aMergeRange ) )
1526*cdf0e10cSrcweir                                 {
1527*cdf0e10cSrcweir                                     qIncreaseRange.push_back( aTestRange );
1528*cdf0e10cSrcweir                                     bInsertMerge = sal_True;
1529*cdf0e10cSrcweir                                 }
1530*cdf0e10cSrcweir                             }
1531*cdf0e10cSrcweir                         }
1532*cdf0e10cSrcweir                         else
1533*cdf0e10cSrcweir                         {
1534*cdf0e10cSrcweir                             ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
1535*cdf0e10cSrcweir                             if( !aExtendRange.In( aMergeRange ) )
1536*cdf0e10cSrcweir                             {
1537*cdf0e10cSrcweir                                 qIncreaseRange.push_back( aRange );
1538*cdf0e10cSrcweir                             }
1539*cdf0e10cSrcweir                             bInsertMerge = sal_True;
1540*cdf0e10cSrcweir                         }
1541*cdf0e10cSrcweir                     }
1542*cdf0e10cSrcweir                 }
1543*cdf0e10cSrcweir 
1544*cdf0e10cSrcweir                 if( bInsertMerge )
1545*cdf0e10cSrcweir                 {
1546*cdf0e10cSrcweir                     if( eCmd == INS_INSROWS || eCmd == INS_CELLSDOWN )
1547*cdf0e10cSrcweir                     {
1548*cdf0e10cSrcweir                         nStartRow = aExtendMergeRange.aStart.Row();
1549*cdf0e10cSrcweir                         nEndRow = aExtendMergeRange.aEnd.Row();
1550*cdf0e10cSrcweir 
1551*cdf0e10cSrcweir                         if( eCmd == INS_CELLSDOWN )
1552*cdf0e10cSrcweir                             nEndCol = nMergeTestEndX;
1553*cdf0e10cSrcweir                         else
1554*cdf0e10cSrcweir                         {
1555*cdf0e10cSrcweir                             nStartCol = 0;
1556*cdf0e10cSrcweir                             nEndCol = MAXCOL;
1557*cdf0e10cSrcweir                         }
1558*cdf0e10cSrcweir                     }
1559*cdf0e10cSrcweir                     else if( eCmd == INS_CELLSRIGHT || eCmd == INS_INSCOLS )
1560*cdf0e10cSrcweir                     {
1561*cdf0e10cSrcweir 
1562*cdf0e10cSrcweir                         nStartCol = aExtendMergeRange.aStart.Col();
1563*cdf0e10cSrcweir                         nEndCol = aExtendMergeRange.aEnd.Col();
1564*cdf0e10cSrcweir                         if( eCmd == INS_CELLSRIGHT )
1565*cdf0e10cSrcweir                         {
1566*cdf0e10cSrcweir                             nEndRow = nMergeTestEndY;
1567*cdf0e10cSrcweir                         }
1568*cdf0e10cSrcweir                         else
1569*cdf0e10cSrcweir                         {
1570*cdf0e10cSrcweir                             nStartRow = 0;
1571*cdf0e10cSrcweir                             nEndRow = MAXROW;
1572*cdf0e10cSrcweir                         }
1573*cdf0e10cSrcweir                     }
1574*cdf0e10cSrcweir 
1575*cdf0e10cSrcweir                     if( !qIncreaseRange.empty() )
1576*cdf0e10cSrcweir                     {
1577*cdf0e10cSrcweir                         for( ::std::vector<ScRange>::const_iterator iIter( qIncreaseRange.begin()); iIter != qIncreaseRange.end(); iIter++ )
1578*cdf0e10cSrcweir                         {
1579*cdf0e10cSrcweir                             ScRange aRange( *iIter );
1580*cdf0e10cSrcweir                             if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
1581*cdf0e10cSrcweir                             {
1582*cdf0e10cSrcweir                                 UnmergeCells( aRange, sal_True, sal_True );
1583*cdf0e10cSrcweir                             }
1584*cdf0e10cSrcweir                         }
1585*cdf0e10cSrcweir                     }
1586*cdf0e10cSrcweir                 }
1587*cdf0e10cSrcweir                 else
1588*cdf0e10cSrcweir                 {
1589*cdf0e10cSrcweir                     if (!bApi)
1590*cdf0e10cSrcweir                         rDocShell.ErrorMessage(STR_MSSG_INSERTCELLS_0);
1591*cdf0e10cSrcweir                     rDocShell.GetUndoManager()->LeaveListAction();
1592*cdf0e10cSrcweir                     return sal_False;
1593*cdf0e10cSrcweir                 }
1594*cdf0e10cSrcweir             }
1595*cdf0e10cSrcweir         }
1596*cdf0e10cSrcweir     }
1597*cdf0e10cSrcweir 
1598*cdf0e10cSrcweir 	switch (eCmd)
1599*cdf0e10cSrcweir 	{
1600*cdf0e10cSrcweir 		case INS_CELLSDOWN:
1601*cdf0e10cSrcweir             bSuccess = pDoc->InsertRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
1602*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
1603*cdf0e10cSrcweir 			break;
1604*cdf0e10cSrcweir 		case INS_INSROWS:
1605*cdf0e10cSrcweir             bSuccess = pDoc->InsertRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &aFullMark );
1606*cdf0e10cSrcweir 			nPaintStartX = 0;
1607*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
1608*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
1609*cdf0e10cSrcweir 			nPaintFlags |= PAINT_LEFT;
1610*cdf0e10cSrcweir 			break;
1611*cdf0e10cSrcweir 		case INS_CELLSRIGHT:
1612*cdf0e10cSrcweir             bSuccess = pDoc->InsertCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
1613*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
1614*cdf0e10cSrcweir 			break;
1615*cdf0e10cSrcweir 		case INS_INSCOLS:
1616*cdf0e10cSrcweir             bSuccess = pDoc->InsertCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &aFullMark );
1617*cdf0e10cSrcweir 			nPaintStartY = 0;
1618*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
1619*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
1620*cdf0e10cSrcweir 			nPaintFlags |= PAINT_TOP;
1621*cdf0e10cSrcweir 			break;
1622*cdf0e10cSrcweir 		default:
1623*cdf0e10cSrcweir 			DBG_ERROR("Falscher Code beim Einfuegen");
1624*cdf0e10cSrcweir 			bSuccess = sal_False;
1625*cdf0e10cSrcweir 			break;
1626*cdf0e10cSrcweir 	}
1627*cdf0e10cSrcweir 
1628*cdf0e10cSrcweir 	if ( bSuccess )
1629*cdf0e10cSrcweir 	{
1630*cdf0e10cSrcweir         SCTAB* pTabs      = NULL;
1631*cdf0e10cSrcweir         SCTAB* pScenarios = NULL;
1632*cdf0e10cSrcweir         SCTAB  nUndoPos  = 0;
1633*cdf0e10cSrcweir 
1634*cdf0e10cSrcweir         if ( bRecord )
1635*cdf0e10cSrcweir         {
1636*cdf0e10cSrcweir             pTabs       = new SCTAB[nSelCount];
1637*cdf0e10cSrcweir             pScenarios  = new SCTAB[nSelCount];
1638*cdf0e10cSrcweir             nUndoPos    = 0;
1639*cdf0e10cSrcweir             for( i=0; i<nTabCount; i++ )
1640*cdf0e10cSrcweir             {
1641*cdf0e10cSrcweir                 if( aMark.GetTableSelect( i ) )
1642*cdf0e10cSrcweir                 {
1643*cdf0e10cSrcweir                     SCTAB nCount = 0;
1644*cdf0e10cSrcweir                     for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1645*cdf0e10cSrcweir                         nCount ++;
1646*cdf0e10cSrcweir 
1647*cdf0e10cSrcweir                     pScenarios[nUndoPos] = nCount;
1648*cdf0e10cSrcweir                     pTabs[nUndoPos] = i;
1649*cdf0e10cSrcweir                     nUndoPos ++;
1650*cdf0e10cSrcweir                 }
1651*cdf0e10cSrcweir             }
1652*cdf0e10cSrcweir 
1653*cdf0e10cSrcweir             if( !bInsertMerge )
1654*cdf0e10cSrcweir             {
1655*cdf0e10cSrcweir                 rDocShell.GetUndoManager()->LeaveListAction();
1656*cdf0e10cSrcweir             }
1657*cdf0e10cSrcweir 
1658*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertCells(
1659*cdf0e10cSrcweir                 &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),
1660*cdf0e10cSrcweir                 nUndoPos, pTabs, pScenarios, eCmd, pRefUndoDoc, pUndoData, bPartOfPaste ) );
1661*cdf0e10cSrcweir         }
1662*cdf0e10cSrcweir 
1663*cdf0e10cSrcweir         // #i8302 : we remerge growing ranges, with the new part inserted
1664*cdf0e10cSrcweir 
1665*cdf0e10cSrcweir         while( !qIncreaseRange.empty() )
1666*cdf0e10cSrcweir         {
1667*cdf0e10cSrcweir             ScRange aRange = qIncreaseRange.back();
1668*cdf0e10cSrcweir             if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
1669*cdf0e10cSrcweir             {
1670*cdf0e10cSrcweir                 switch (eCmd)
1671*cdf0e10cSrcweir                 {
1672*cdf0e10cSrcweir                     case INS_CELLSDOWN:
1673*cdf0e10cSrcweir                     case INS_INSROWS:
1674*cdf0e10cSrcweir                         aRange.aEnd.IncRow(static_cast<SCsCOL>(nEndRow-nStartRow+1));
1675*cdf0e10cSrcweir                         break;
1676*cdf0e10cSrcweir                     case INS_CELLSRIGHT:
1677*cdf0e10cSrcweir                     case INS_INSCOLS:
1678*cdf0e10cSrcweir                         aRange.aEnd.IncCol(static_cast<SCsCOL>(nEndCol-nStartCol+1));
1679*cdf0e10cSrcweir                         break;
1680*cdf0e10cSrcweir                     default:
1681*cdf0e10cSrcweir                         break;
1682*cdf0e10cSrcweir                 }
1683*cdf0e10cSrcweir                 MergeCells(aRange, sal_False, sal_True, sal_True);
1684*cdf0e10cSrcweir             }
1685*cdf0e10cSrcweir             qIncreaseRange.pop_back();
1686*cdf0e10cSrcweir         }
1687*cdf0e10cSrcweir 
1688*cdf0e10cSrcweir         if( bInsertMerge )
1689*cdf0e10cSrcweir             rDocShell.GetUndoManager()->LeaveListAction();
1690*cdf0e10cSrcweir 
1691*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
1692*cdf0e10cSrcweir         {
1693*cdf0e10cSrcweir             if( aMark.GetTableSelect( i ) )
1694*cdf0e10cSrcweir             {
1695*cdf0e10cSrcweir 		        if (bNeedRefresh)
1696*cdf0e10cSrcweir 			        pDoc->ExtendMerge( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i, sal_True );
1697*cdf0e10cSrcweir 		        else
1698*cdf0e10cSrcweir 			        pDoc->RefreshAutoFilter( nMergeTestStartX, nMergeTestStartY, nMergeTestEndX, nMergeTestEndY, i );
1699*cdf0e10cSrcweir 
1700*cdf0e10cSrcweir 		        if ( eCmd == INS_INSROWS || eCmd == INS_INSCOLS )
1701*cdf0e10cSrcweir 			        pDoc->UpdatePageBreaks( i );
1702*cdf0e10cSrcweir 
1703*cdf0e10cSrcweir 		        sal_uInt16 nExtFlags = 0;
1704*cdf0e10cSrcweir 		        rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
1705*cdf0e10cSrcweir 
1706*cdf0e10cSrcweir                 SCTAB nScenarioCount = 0;
1707*cdf0e10cSrcweir 
1708*cdf0e10cSrcweir                 for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1709*cdf0e10cSrcweir                     nScenarioCount ++;
1710*cdf0e10cSrcweir 
1711*cdf0e10cSrcweir 		        sal_Bool bAdjusted = ( eCmd == INS_INSROWS ) ? AdjustRowHeight(ScRange(0, nStartRow, i, MAXCOL, nEndRow, i+nScenarioCount )) :
1712*cdf0e10cSrcweir 				                                           AdjustRowHeight(ScRange(0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount ));
1713*cdf0e10cSrcweir 		        if (bAdjusted)
1714*cdf0e10cSrcweir 		        {
1715*cdf0e10cSrcweir 			        //	paint only what is not done by AdjustRowHeight
1716*cdf0e10cSrcweir 			        if (nPaintFlags & PAINT_TOP)
1717*cdf0e10cSrcweir 				        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
1718*cdf0e10cSrcweir 		        }
1719*cdf0e10cSrcweir 		        else
1720*cdf0e10cSrcweir 			        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags, nExtFlags );
1721*cdf0e10cSrcweir             }
1722*cdf0e10cSrcweir         }
1723*cdf0e10cSrcweir 		//aModificator.SetDocumentModified();
1724*cdf0e10cSrcweir 	}
1725*cdf0e10cSrcweir 	else
1726*cdf0e10cSrcweir 	{
1727*cdf0e10cSrcweir         if( bInsertMerge )
1728*cdf0e10cSrcweir         {
1729*cdf0e10cSrcweir             while( !qIncreaseRange.empty() )
1730*cdf0e10cSrcweir             {
1731*cdf0e10cSrcweir                 ScRange aRange = qIncreaseRange.back();
1732*cdf0e10cSrcweir                 MergeCells(aRange, sal_False, sal_True, sal_True);
1733*cdf0e10cSrcweir                 qIncreaseRange.pop_back();
1734*cdf0e10cSrcweir             }
1735*cdf0e10cSrcweir 
1736*cdf0e10cSrcweir             if( pViewSh )
1737*cdf0e10cSrcweir             {
1738*cdf0e10cSrcweir                 pViewSh->MarkRange( rRange, sal_False );
1739*cdf0e10cSrcweir                 pViewSh->SetCursor( nCursorCol, nCursorRow );
1740*cdf0e10cSrcweir             }
1741*cdf0e10cSrcweir         }
1742*cdf0e10cSrcweir 
1743*cdf0e10cSrcweir         rDocShell.GetUndoManager()->LeaveListAction();
1744*cdf0e10cSrcweir         rDocShell.GetUndoManager()->RemoveLastUndoAction();
1745*cdf0e10cSrcweir 
1746*cdf0e10cSrcweir 		delete pRefUndoDoc;
1747*cdf0e10cSrcweir 		delete pUndoData;
1748*cdf0e10cSrcweir 		if (!bApi)
1749*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_INSERT_FULL);		// Spalte/Zeile voll
1750*cdf0e10cSrcweir 	}
1751*cdf0e10cSrcweir 
1752*cdf0e10cSrcweir     aModificator.SetDocumentModified();
1753*cdf0e10cSrcweir 
1754*cdf0e10cSrcweir     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
1755*cdf0e10cSrcweir 	return bSuccess;
1756*cdf0e10cSrcweir }
1757*cdf0e10cSrcweir 
1758*cdf0e10cSrcweir sal_Bool ScDocFunc::DeleteCells( const ScRange& rRange, const ScMarkData* pTabMark, DelCellCmd eCmd,
1759*cdf0e10cSrcweir                              sal_Bool bRecord, sal_Bool bApi )
1760*cdf0e10cSrcweir {
1761*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
1762*cdf0e10cSrcweir 
1763*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
1764*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
1765*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
1766*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
1767*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
1768*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
1769*cdf0e10cSrcweir 
1770*cdf0e10cSrcweir 	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) )
1771*cdf0e10cSrcweir 	{
1772*cdf0e10cSrcweir 		DBG_ERROR("invalid row in DeleteCells");
1773*cdf0e10cSrcweir 		return sal_False;
1774*cdf0e10cSrcweir 	}
1775*cdf0e10cSrcweir 
1776*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
1777*cdf0e10cSrcweir 	SCTAB nTabCount = pDoc->GetTableCount();
1778*cdf0e10cSrcweir 	SCCOL nPaintStartX = nStartCol;
1779*cdf0e10cSrcweir 	SCROW nPaintStartY = nStartRow;
1780*cdf0e10cSrcweir 	SCCOL nPaintEndX = nEndCol;
1781*cdf0e10cSrcweir 	SCROW nPaintEndY = nEndRow;
1782*cdf0e10cSrcweir 	sal_uInt16 nPaintFlags = PAINT_GRID;
1783*cdf0e10cSrcweir     SCTAB i;
1784*cdf0e10cSrcweir 
1785*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
1786*cdf0e10cSrcweir 		bRecord = sal_False;
1787*cdf0e10cSrcweir 
1788*cdf0e10cSrcweir     ScMarkData aMark;
1789*cdf0e10cSrcweir     if (pTabMark)
1790*cdf0e10cSrcweir         aMark = *pTabMark;
1791*cdf0e10cSrcweir     else
1792*cdf0e10cSrcweir     {
1793*cdf0e10cSrcweir         SCTAB nCount = 0;
1794*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
1795*cdf0e10cSrcweir         {
1796*cdf0e10cSrcweir             if( !pDoc->IsScenario(i) )
1797*cdf0e10cSrcweir             {
1798*cdf0e10cSrcweir                 nCount++;
1799*cdf0e10cSrcweir                 if( nCount == nEndTab+1 )
1800*cdf0e10cSrcweir                 {
1801*cdf0e10cSrcweir                     aMark.SelectTable( i, sal_True );
1802*cdf0e10cSrcweir                     break;
1803*cdf0e10cSrcweir                 }
1804*cdf0e10cSrcweir             }
1805*cdf0e10cSrcweir         }
1806*cdf0e10cSrcweir     }
1807*cdf0e10cSrcweir 
1808*cdf0e10cSrcweir     ScMarkData aFullMark( aMark );          // including scenario sheets
1809*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
1810*cdf0e10cSrcweir         if( aMark.GetTableSelect( i ) )
1811*cdf0e10cSrcweir         {
1812*cdf0e10cSrcweir             for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
1813*cdf0e10cSrcweir                 aFullMark.SelectTable( j, sal_True );
1814*cdf0e10cSrcweir         }
1815*cdf0e10cSrcweir 
1816*cdf0e10cSrcweir     SCTAB nSelCount = aMark.GetSelectCount();
1817*cdf0e10cSrcweir 
1818*cdf0e10cSrcweir 	SCCOL nUndoStartX = nStartCol;
1819*cdf0e10cSrcweir 	SCROW nUndoStartY = nStartRow;
1820*cdf0e10cSrcweir 	SCCOL nUndoEndX = nEndCol;
1821*cdf0e10cSrcweir 	SCROW nUndoEndY = nEndRow;
1822*cdf0e10cSrcweir 
1823*cdf0e10cSrcweir     ScRange aExtendMergeRange( rRange );
1824*cdf0e10cSrcweir 
1825*cdf0e10cSrcweir     if( rRange.aStart == rRange.aEnd && pDoc->HasAttrib(rRange, HASATTR_MERGED) )
1826*cdf0e10cSrcweir     {
1827*cdf0e10cSrcweir         pDoc->ExtendMerge( aExtendMergeRange );
1828*cdf0e10cSrcweir         pDoc->ExtendOverlapped( aExtendMergeRange );
1829*cdf0e10cSrcweir         nUndoEndX = aExtendMergeRange.aEnd.Col();
1830*cdf0e10cSrcweir         nUndoEndY = aExtendMergeRange.aEnd.Row();
1831*cdf0e10cSrcweir         nPaintEndX = nUndoEndX;
1832*cdf0e10cSrcweir         nPaintEndY = nUndoEndY;
1833*cdf0e10cSrcweir     }
1834*cdf0e10cSrcweir 
1835*cdf0e10cSrcweir 	if (eCmd==DEL_DELROWS)
1836*cdf0e10cSrcweir 	{
1837*cdf0e10cSrcweir 		nUndoStartX = 0;
1838*cdf0e10cSrcweir 		nUndoEndX = MAXCOL;
1839*cdf0e10cSrcweir 	}
1840*cdf0e10cSrcweir 	if (eCmd==DEL_DELCOLS)
1841*cdf0e10cSrcweir 	{
1842*cdf0e10cSrcweir 		nUndoStartY = 0;
1843*cdf0e10cSrcweir 		nUndoEndY = MAXROW;
1844*cdf0e10cSrcweir 	}
1845*cdf0e10cSrcweir 					// Test Zellschutz
1846*cdf0e10cSrcweir 
1847*cdf0e10cSrcweir 	SCCOL nEditTestEndX = nUndoEndX;
1848*cdf0e10cSrcweir 	if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
1849*cdf0e10cSrcweir         nEditTestEndX = MAXCOL;
1850*cdf0e10cSrcweir 	SCROW nEditTestEndY = nUndoEndY;
1851*cdf0e10cSrcweir 	if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
1852*cdf0e10cSrcweir         nEditTestEndY = MAXROW;
1853*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nUndoStartX, nUndoStartY, nEditTestEndX, nEditTestEndY, aMark );
1854*cdf0e10cSrcweir 	if (!aTester.IsEditable())
1855*cdf0e10cSrcweir 	{
1856*cdf0e10cSrcweir 		if (!bApi)
1857*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
1858*cdf0e10cSrcweir 		return sal_False;
1859*cdf0e10cSrcweir 	}
1860*cdf0e10cSrcweir 
1861*cdf0e10cSrcweir 					// Test zusammengefasste
1862*cdf0e10cSrcweir 
1863*cdf0e10cSrcweir 	SCCOL nMergeTestEndX = (eCmd==DEL_CELLSLEFT) ? MAXCOL : nUndoEndX;
1864*cdf0e10cSrcweir 	SCROW nMergeTestEndY = (eCmd==DEL_CELLSUP)   ? MAXROW : nUndoEndY;
1865*cdf0e10cSrcweir     SCCOL nExtendStartCol = nUndoStartX;
1866*cdf0e10cSrcweir     SCROW nExtendStartRow = nUndoStartY;
1867*cdf0e10cSrcweir 	sal_Bool bNeedRefresh = sal_False;
1868*cdf0e10cSrcweir 
1869*cdf0e10cSrcweir     //Issue 8302 want to be able to insert into the middle of merged cells
1870*cdf0e10cSrcweir     //the patch comes from maoyg
1871*cdf0e10cSrcweir     ::std::vector<ScRange> qDecreaseRange;
1872*cdf0e10cSrcweir     sal_Bool bDeletingMerge = sal_False;
1873*cdf0e10cSrcweir     String aUndo = ScGlobal::GetRscString( STR_UNDO_DELETECELLS );
1874*cdf0e10cSrcweir     if (bRecord)
1875*cdf0e10cSrcweir         rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
1876*cdf0e10cSrcweir 
1877*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
1878*cdf0e10cSrcweir     {
1879*cdf0e10cSrcweir         if( aMark.GetTableSelect(i) )
1880*cdf0e10cSrcweir         {
1881*cdf0e10cSrcweir 	        if ( pDoc->HasAttrib( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i, HASATTR_MERGED | HASATTR_OVERLAPPED ))
1882*cdf0e10cSrcweir             {
1883*cdf0e10cSrcweir 		        SCCOL nMergeStartX = nUndoStartX;
1884*cdf0e10cSrcweir 		        SCROW nMergeStartY = nUndoStartY;
1885*cdf0e10cSrcweir 		        SCCOL nMergeEndX   = nMergeTestEndX;
1886*cdf0e10cSrcweir 		        SCROW nMergeEndY   = nMergeTestEndY;
1887*cdf0e10cSrcweir 
1888*cdf0e10cSrcweir 		        pDoc->ExtendMerge( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
1889*cdf0e10cSrcweir 		        pDoc->ExtendOverlapped( nMergeStartX, nMergeStartY, nMergeEndX, nMergeEndY, i );
1890*cdf0e10cSrcweir                 if( ( eCmd == DEL_CELLSUP && ( nMergeStartX != nUndoStartX || nMergeEndX != nMergeTestEndX))||
1891*cdf0e10cSrcweir                     ( eCmd == DEL_CELLSLEFT && ( nMergeStartY != nUndoStartY || nMergeEndY != nMergeTestEndY)))
1892*cdf0e10cSrcweir                 {
1893*cdf0e10cSrcweir                     if (!bApi)
1894*cdf0e10cSrcweir                         rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
1895*cdf0e10cSrcweir                     rDocShell.GetUndoManager()->LeaveListAction();
1896*cdf0e10cSrcweir                     return sal_False;
1897*cdf0e10cSrcweir                 }
1898*cdf0e10cSrcweir 
1899*cdf0e10cSrcweir                 nExtendStartCol = nMergeStartX;
1900*cdf0e10cSrcweir                 nExtendStartRow = nMergeStartY;
1901*cdf0e10cSrcweir                 SCCOL nTestCol = -1;
1902*cdf0e10cSrcweir                 SCROW nTestRow1 = -1;
1903*cdf0e10cSrcweir                 SCROW nTestRow2 = -1;
1904*cdf0e10cSrcweir 
1905*cdf0e10cSrcweir                 ScDocAttrIterator aTestIter( pDoc, i, nUndoStartX, nUndoStartY, nMergeTestEndX, nMergeTestEndY );
1906*cdf0e10cSrcweir                 ScRange aExtendRange( nUndoStartX, nUndoStartY, i, nMergeTestEndX, nMergeTestEndY, i );
1907*cdf0e10cSrcweir                 const ScPatternAttr* pPattern = NULL;
1908*cdf0e10cSrcweir                 const ScMergeAttr* pMergeFlag = NULL;
1909*cdf0e10cSrcweir                 const ScMergeFlagAttr* pMergeFlagAttr = NULL;
1910*cdf0e10cSrcweir                 while ( ( pPattern = aTestIter.GetNext( nTestCol, nTestRow1, nTestRow2 ) ) != NULL )
1911*cdf0e10cSrcweir                 {
1912*cdf0e10cSrcweir                     pMergeFlag = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE );
1913*cdf0e10cSrcweir                     pMergeFlagAttr = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG );
1914*cdf0e10cSrcweir                     sal_Int16 nNewFlags = pMergeFlagAttr->GetValue() & ( SC_MF_HOR | SC_MF_VER );
1915*cdf0e10cSrcweir                     if( ( pMergeFlag && pMergeFlag->IsMerged() ) || nNewFlags == SC_MF_HOR || nNewFlags == SC_MF_VER )
1916*cdf0e10cSrcweir                     {
1917*cdf0e10cSrcweir                         ScRange aRange( nTestCol, nTestRow1, i );
1918*cdf0e10cSrcweir                         pDoc->ExtendOverlapped( aRange );
1919*cdf0e10cSrcweir                         pDoc->ExtendMerge( aRange, sal_True, sal_True );
1920*cdf0e10cSrcweir 
1921*cdf0e10cSrcweir                         if( nTestRow1 < nTestRow2 && nNewFlags == SC_MF_HOR )
1922*cdf0e10cSrcweir                         {
1923*cdf0e10cSrcweir                             for( SCROW nTestRow = nTestRow1; nTestRow <= nTestRow2; nTestRow++ )
1924*cdf0e10cSrcweir                             {
1925*cdf0e10cSrcweir                                 ScRange aTestRange( nTestCol, nTestRow, i );
1926*cdf0e10cSrcweir                                 pDoc->ExtendOverlapped( aTestRange );
1927*cdf0e10cSrcweir                                 pDoc->ExtendMerge( aTestRange, sal_True, sal_True);
1928*cdf0e10cSrcweir                                 ScRange aMergeRange( aTestRange.aStart.Col(),aTestRange.aStart.Row(), i );
1929*cdf0e10cSrcweir                                 if( !aExtendRange.In( aMergeRange ) )
1930*cdf0e10cSrcweir                                 {
1931*cdf0e10cSrcweir                                     qDecreaseRange.push_back( aTestRange );
1932*cdf0e10cSrcweir                                     bDeletingMerge = sal_True;
1933*cdf0e10cSrcweir                                 }
1934*cdf0e10cSrcweir                             }
1935*cdf0e10cSrcweir                         }
1936*cdf0e10cSrcweir                         else
1937*cdf0e10cSrcweir                         {
1938*cdf0e10cSrcweir                             ScRange aMergeRange( aRange.aStart.Col(),aRange.aStart.Row(), i );
1939*cdf0e10cSrcweir                             if( !aExtendRange.In( aMergeRange ) )
1940*cdf0e10cSrcweir                             {
1941*cdf0e10cSrcweir                                 qDecreaseRange.push_back( aRange );
1942*cdf0e10cSrcweir                             }
1943*cdf0e10cSrcweir                             bDeletingMerge = sal_True;
1944*cdf0e10cSrcweir                         }
1945*cdf0e10cSrcweir                     }
1946*cdf0e10cSrcweir                 }
1947*cdf0e10cSrcweir 
1948*cdf0e10cSrcweir                 if( bDeletingMerge )
1949*cdf0e10cSrcweir                 {
1950*cdf0e10cSrcweir 
1951*cdf0e10cSrcweir                     if( eCmd == DEL_DELROWS || eCmd == DEL_CELLSUP )
1952*cdf0e10cSrcweir                     {
1953*cdf0e10cSrcweir                         nStartRow = aExtendMergeRange.aStart.Row();
1954*cdf0e10cSrcweir                         nEndRow = aExtendMergeRange.aEnd.Row();
1955*cdf0e10cSrcweir                         bNeedRefresh = sal_True;
1956*cdf0e10cSrcweir 
1957*cdf0e10cSrcweir                         if( eCmd == DEL_CELLSUP )
1958*cdf0e10cSrcweir                         {
1959*cdf0e10cSrcweir                             nEndCol = aExtendMergeRange.aEnd.Col();
1960*cdf0e10cSrcweir                         }
1961*cdf0e10cSrcweir                         else
1962*cdf0e10cSrcweir                         {
1963*cdf0e10cSrcweir                             nStartCol = 0;
1964*cdf0e10cSrcweir                             nEndCol = MAXCOL;
1965*cdf0e10cSrcweir                         }
1966*cdf0e10cSrcweir                     }
1967*cdf0e10cSrcweir                     else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
1968*cdf0e10cSrcweir                     {
1969*cdf0e10cSrcweir 
1970*cdf0e10cSrcweir                         nStartCol = aExtendMergeRange.aStart.Col();
1971*cdf0e10cSrcweir                         nEndCol = aExtendMergeRange.aEnd.Col();
1972*cdf0e10cSrcweir                         if( eCmd == DEL_CELLSLEFT )
1973*cdf0e10cSrcweir                         {
1974*cdf0e10cSrcweir                             nEndRow = aExtendMergeRange.aEnd.Row();
1975*cdf0e10cSrcweir                             bNeedRefresh = sal_True;
1976*cdf0e10cSrcweir                         }
1977*cdf0e10cSrcweir                         else
1978*cdf0e10cSrcweir                         {
1979*cdf0e10cSrcweir                             nStartRow = 0;
1980*cdf0e10cSrcweir                             nEndRow = MAXROW;
1981*cdf0e10cSrcweir                         }
1982*cdf0e10cSrcweir                     }
1983*cdf0e10cSrcweir 
1984*cdf0e10cSrcweir                     if( !qDecreaseRange.empty() )
1985*cdf0e10cSrcweir                     {
1986*cdf0e10cSrcweir                         for( ::std::vector<ScRange>::const_iterator iIter( qDecreaseRange.begin()); iIter != qDecreaseRange.end(); iIter++ )
1987*cdf0e10cSrcweir                         {
1988*cdf0e10cSrcweir                             ScRange aRange( *iIter );
1989*cdf0e10cSrcweir                             if( pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
1990*cdf0e10cSrcweir                             {
1991*cdf0e10cSrcweir                                 UnmergeCells( aRange, sal_True, sal_True );
1992*cdf0e10cSrcweir                             }
1993*cdf0e10cSrcweir                         }
1994*cdf0e10cSrcweir                     }
1995*cdf0e10cSrcweir                 }
1996*cdf0e10cSrcweir                 else
1997*cdf0e10cSrcweir                 {
1998*cdf0e10cSrcweir                     if (!bApi)
1999*cdf0e10cSrcweir                         rDocShell.ErrorMessage(STR_MSSG_DELETECELLS_0);
2000*cdf0e10cSrcweir                     rDocShell.GetUndoManager()->LeaveListAction();
2001*cdf0e10cSrcweir                     return sal_False;
2002*cdf0e10cSrcweir                 }
2003*cdf0e10cSrcweir 	        }
2004*cdf0e10cSrcweir         }
2005*cdf0e10cSrcweir     }
2006*cdf0e10cSrcweir 
2007*cdf0e10cSrcweir 	//
2008*cdf0e10cSrcweir 	//		ausfuehren
2009*cdf0e10cSrcweir 	//
2010*cdf0e10cSrcweir 
2011*cdf0e10cSrcweir 	WaitObject aWait( rDocShell.GetActiveDialogParent() );		// wichtig wegen TrackFormulas bei UpdateReference
2012*cdf0e10cSrcweir 
2013*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
2014*cdf0e10cSrcweir 	ScDocument* pRefUndoDoc = NULL;
2015*cdf0e10cSrcweir 	ScRefUndoData* pUndoData = NULL;
2016*cdf0e10cSrcweir 	if ( bRecord )
2017*cdf0e10cSrcweir 	{
2018*cdf0e10cSrcweir         // With the fix for #101329#, UpdateRef always puts cells into pRefUndoDoc at their old position,
2019*cdf0e10cSrcweir         // so it's no longer necessary to copy more than the deleted range into pUndoDoc.
2020*cdf0e10cSrcweir 
2021*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2022*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, 0, nTabCount-1, (eCmd==DEL_DELCOLS), (eCmd==DEL_DELROWS) );
2023*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
2024*cdf0e10cSrcweir         {
2025*cdf0e10cSrcweir             if( aMark.GetTableSelect( i ) )
2026*cdf0e10cSrcweir             {
2027*cdf0e10cSrcweir                 SCTAB nScenarioCount = 0;
2028*cdf0e10cSrcweir 
2029*cdf0e10cSrcweir                 for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2030*cdf0e10cSrcweir                     nScenarioCount ++;
2031*cdf0e10cSrcweir 
2032*cdf0e10cSrcweir                 pDoc->CopyToDocument( nUndoStartX, nUndoStartY, i, nUndoEndX, nUndoEndY, i+nScenarioCount,
2033*cdf0e10cSrcweir                     IDF_ALL | IDF_NOCAPTIONS, sal_False, pUndoDoc );
2034*cdf0e10cSrcweir             }
2035*cdf0e10cSrcweir         }
2036*cdf0e10cSrcweir 
2037*cdf0e10cSrcweir 		pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2038*cdf0e10cSrcweir 		pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );
2039*cdf0e10cSrcweir 
2040*cdf0e10cSrcweir 		pUndoData = new ScRefUndoData( pDoc );
2041*cdf0e10cSrcweir 
2042*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();
2043*cdf0e10cSrcweir 	}
2044*cdf0e10cSrcweir 
2045*cdf0e10cSrcweir 	sal_uInt16 nExtFlags = 0;
2046*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
2047*cdf0e10cSrcweir     {
2048*cdf0e10cSrcweir         if( aMark.GetTableSelect( i ) )
2049*cdf0e10cSrcweir             rDocShell.UpdatePaintExt( nExtFlags, nStartCol, nStartRow, i, nEndCol, nEndRow, i );
2050*cdf0e10cSrcweir     }
2051*cdf0e10cSrcweir 
2052*cdf0e10cSrcweir 	sal_Bool bUndoOutline = sal_False;
2053*cdf0e10cSrcweir 	switch (eCmd)
2054*cdf0e10cSrcweir 	{
2055*cdf0e10cSrcweir 		case DEL_CELLSUP:
2056*cdf0e10cSrcweir             pDoc->DeleteRow( nStartCol, 0, nEndCol, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, NULL, &aFullMark );
2057*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2058*cdf0e10cSrcweir 			break;
2059*cdf0e10cSrcweir 		case DEL_DELROWS:
2060*cdf0e10cSrcweir             pDoc->DeleteRow( 0, 0, MAXCOL, MAXTAB, nStartRow, static_cast<SCSIZE>(nEndRow-nStartRow+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
2061*cdf0e10cSrcweir 			nPaintStartX = 0;
2062*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2063*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2064*cdf0e10cSrcweir 			nPaintFlags |= PAINT_LEFT;
2065*cdf0e10cSrcweir 			break;
2066*cdf0e10cSrcweir 		case DEL_CELLSLEFT:
2067*cdf0e10cSrcweir             pDoc->DeleteCol( nStartRow, 0, nEndRow, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, NULL, &aFullMark );
2068*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2069*cdf0e10cSrcweir 			break;
2070*cdf0e10cSrcweir 		case DEL_DELCOLS:
2071*cdf0e10cSrcweir             pDoc->DeleteCol( 0, 0, MAXROW, MAXTAB, nStartCol, static_cast<SCSIZE>(nEndCol-nStartCol+1), pRefUndoDoc, &bUndoOutline, &aFullMark );
2072*cdf0e10cSrcweir 			nPaintStartY = 0;
2073*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2074*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2075*cdf0e10cSrcweir 			nPaintFlags |= PAINT_TOP;
2076*cdf0e10cSrcweir 			break;
2077*cdf0e10cSrcweir 		default:
2078*cdf0e10cSrcweir 			DBG_ERROR("Falscher Code beim Loeschen");
2079*cdf0e10cSrcweir 			break;
2080*cdf0e10cSrcweir 	}
2081*cdf0e10cSrcweir 
2082*cdf0e10cSrcweir 	//!	Test, ob Outline in Groesse geaendert
2083*cdf0e10cSrcweir 
2084*cdf0e10cSrcweir 	if ( bRecord )
2085*cdf0e10cSrcweir 	{
2086*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
2087*cdf0e10cSrcweir             if( aFullMark.GetTableSelect( i ) )
2088*cdf0e10cSrcweir                 pRefUndoDoc->DeleteAreaTab(nUndoStartX,nUndoStartY,nUndoEndX,nUndoEndY, i, IDF_ALL);
2089*cdf0e10cSrcweir 
2090*cdf0e10cSrcweir 			//	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2091*cdf0e10cSrcweir 		pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );
2092*cdf0e10cSrcweir 
2093*cdf0e10cSrcweir 			//	kopieren mit bColRowFlags=sal_False (#54194#)
2094*cdf0e10cSrcweir 		pRefUndoDoc->CopyToDocument(0,0,0,MAXCOL,MAXROW,MAXTAB,IDF_FORMULA,sal_False,pUndoDoc,NULL,sal_False);
2095*cdf0e10cSrcweir 		delete pRefUndoDoc;
2096*cdf0e10cSrcweir 
2097*cdf0e10cSrcweir         SCTAB* pTabs      = new SCTAB[nSelCount];
2098*cdf0e10cSrcweir         SCTAB* pScenarios = new SCTAB[nSelCount];
2099*cdf0e10cSrcweir         SCTAB   nUndoPos  = 0;
2100*cdf0e10cSrcweir 
2101*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
2102*cdf0e10cSrcweir         {
2103*cdf0e10cSrcweir             if( aMark.GetTableSelect( i ) )
2104*cdf0e10cSrcweir             {
2105*cdf0e10cSrcweir                 SCTAB nCount = 0;
2106*cdf0e10cSrcweir                 for( SCTAB j=i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2107*cdf0e10cSrcweir                     nCount ++;
2108*cdf0e10cSrcweir 
2109*cdf0e10cSrcweir                 pScenarios[nUndoPos] = nCount;
2110*cdf0e10cSrcweir                 pTabs[nUndoPos] = i;
2111*cdf0e10cSrcweir                 nUndoPos ++;
2112*cdf0e10cSrcweir             }
2113*cdf0e10cSrcweir         }
2114*cdf0e10cSrcweir 
2115*cdf0e10cSrcweir         if( !bDeletingMerge )
2116*cdf0e10cSrcweir         {
2117*cdf0e10cSrcweir             rDocShell.GetUndoManager()->LeaveListAction();
2118*cdf0e10cSrcweir         }
2119*cdf0e10cSrcweir 
2120*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoDeleteCells(
2121*cdf0e10cSrcweir             &rDocShell, ScRange( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab ),nUndoPos, pTabs, pScenarios,
2122*cdf0e10cSrcweir 			eCmd, pUndoDoc, pUndoData ) );
2123*cdf0e10cSrcweir 	}
2124*cdf0e10cSrcweir 
2125*cdf0e10cSrcweir     // #i8302 want to be able to insert into the middle of merged cells
2126*cdf0e10cSrcweir     // the patch comes from maoyg
2127*cdf0e10cSrcweir 
2128*cdf0e10cSrcweir     while( !qDecreaseRange.empty() )
2129*cdf0e10cSrcweir     {
2130*cdf0e10cSrcweir         ScRange aRange = qDecreaseRange.back();
2131*cdf0e10cSrcweir 
2132*cdf0e10cSrcweir         long nDecreaseRowCount = 0;
2133*cdf0e10cSrcweir         long nDecreaseColCount = 0;
2134*cdf0e10cSrcweir         if( eCmd == DEL_CELLSUP || eCmd == DEL_DELROWS )
2135*cdf0e10cSrcweir         {
2136*cdf0e10cSrcweir             if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2137*cdf0e10cSrcweir                 nDecreaseRowCount = nEndRow-nStartRow+1;
2138*cdf0e10cSrcweir             else if( nStartRow >= aRange.aStart.Row() && nStartRow <= aRange.aEnd.Row() && nEndRow >= aRange.aStart.Row() && nEndRow >= aRange.aEnd.Row() )
2139*cdf0e10cSrcweir                 nDecreaseRowCount = aRange.aEnd.Row()-nStartRow+1;
2140*cdf0e10cSrcweir             else if( nStartRow >= aRange.aStart.Row() && nStartRow >= aRange.aEnd.Row() && nEndRow>= aRange.aStart.Row() && nEndRow <= aRange.aEnd.Row() )
2141*cdf0e10cSrcweir                 nDecreaseRowCount = aRange.aEnd.Row()-nEndRow+1;
2142*cdf0e10cSrcweir         }
2143*cdf0e10cSrcweir         else if( eCmd == DEL_CELLSLEFT || eCmd == DEL_DELCOLS )
2144*cdf0e10cSrcweir         {
2145*cdf0e10cSrcweir             if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2146*cdf0e10cSrcweir                 nDecreaseColCount = nEndCol-nStartCol+1;
2147*cdf0e10cSrcweir             else if( nStartCol >= aRange.aStart.Col() && nStartCol <= aRange.aEnd.Col() && nEndCol >= aRange.aStart.Col() && nEndCol >= aRange.aEnd.Col() )
2148*cdf0e10cSrcweir                 nDecreaseColCount = aRange.aEnd.Col()-nStartCol+1;
2149*cdf0e10cSrcweir             else if( nStartCol >= aRange.aStart.Col() && nStartCol >= aRange.aEnd.Col() && nEndCol>= aRange.aStart.Col() && nEndCol <= aRange.aEnd.Col() )
2150*cdf0e10cSrcweir                 nDecreaseColCount = aRange.aEnd.Col()-nEndCol+1;
2151*cdf0e10cSrcweir         }
2152*cdf0e10cSrcweir 
2153*cdf0e10cSrcweir         switch (eCmd)
2154*cdf0e10cSrcweir         {
2155*cdf0e10cSrcweir             case DEL_CELLSUP:
2156*cdf0e10cSrcweir             case DEL_DELROWS:
2157*cdf0e10cSrcweir                 aRange.aEnd.SetRow(static_cast<SCsCOL>( aRange.aEnd.Row()-nDecreaseRowCount));
2158*cdf0e10cSrcweir                 break;
2159*cdf0e10cSrcweir             case DEL_CELLSLEFT:
2160*cdf0e10cSrcweir             case DEL_DELCOLS:
2161*cdf0e10cSrcweir                 aRange.aEnd.SetCol(static_cast<SCsCOL>( aRange.aEnd.Col()-nDecreaseColCount));
2162*cdf0e10cSrcweir                 break;
2163*cdf0e10cSrcweir             default:
2164*cdf0e10cSrcweir                 break;
2165*cdf0e10cSrcweir         }
2166*cdf0e10cSrcweir 
2167*cdf0e10cSrcweir         if( !pDoc->HasAttrib( aRange, HASATTR_OVERLAPPED | HASATTR_MERGED ) )
2168*cdf0e10cSrcweir         {
2169*cdf0e10cSrcweir             MergeCells( aRange, sal_False, sal_True, sal_True );
2170*cdf0e10cSrcweir         }
2171*cdf0e10cSrcweir         qDecreaseRange.pop_back();
2172*cdf0e10cSrcweir     }
2173*cdf0e10cSrcweir 
2174*cdf0e10cSrcweir     if( bDeletingMerge )
2175*cdf0e10cSrcweir         rDocShell.GetUndoManager()->LeaveListAction();
2176*cdf0e10cSrcweir 
2177*cdf0e10cSrcweir 	if ( bNeedRefresh )
2178*cdf0e10cSrcweir 	{
2179*cdf0e10cSrcweir         // #i51445# old merge flag attributes must be deleted also for single cells,
2180*cdf0e10cSrcweir         // not only for whole columns/rows
2181*cdf0e10cSrcweir 
2182*cdf0e10cSrcweir         if ( eCmd==DEL_DELCOLS || eCmd==DEL_CELLSLEFT )
2183*cdf0e10cSrcweir             nMergeTestEndX = MAXCOL;
2184*cdf0e10cSrcweir         if ( eCmd==DEL_DELROWS || eCmd==DEL_CELLSUP )
2185*cdf0e10cSrcweir             nMergeTestEndY = MAXROW;
2186*cdf0e10cSrcweir 		ScPatternAttr aPattern( pDoc->GetPool() );
2187*cdf0e10cSrcweir 		aPattern.GetItemSet().Put( ScMergeFlagAttr() );
2188*cdf0e10cSrcweir 
2189*cdf0e10cSrcweir         pDoc->ApplyPatternArea( nExtendStartCol, nExtendStartRow, nMergeTestEndX, nMergeTestEndY, aMark, aPattern );
2190*cdf0e10cSrcweir 
2191*cdf0e10cSrcweir         for( i=0; i<nTabCount; i++ )
2192*cdf0e10cSrcweir         {
2193*cdf0e10cSrcweir             if( aMark.GetTableSelect( i ) )
2194*cdf0e10cSrcweir             {
2195*cdf0e10cSrcweir                 SCTAB nScenarioCount = 0;
2196*cdf0e10cSrcweir 
2197*cdf0e10cSrcweir                 for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2198*cdf0e10cSrcweir                     nScenarioCount ++;
2199*cdf0e10cSrcweir 
2200*cdf0e10cSrcweir                 ScRange aMergedRange( nExtendStartCol, nExtendStartRow, i, nMergeTestEndX, nMergeTestEndY, i+nScenarioCount );
2201*cdf0e10cSrcweir                 pDoc->ExtendMerge( aMergedRange, sal_True );
2202*cdf0e10cSrcweir             }
2203*cdf0e10cSrcweir         }
2204*cdf0e10cSrcweir 	}
2205*cdf0e10cSrcweir 
2206*cdf0e10cSrcweir     for( i=0; i<nTabCount; i++ )
2207*cdf0e10cSrcweir     {
2208*cdf0e10cSrcweir         if( aMark.GetTableSelect( i ) )
2209*cdf0e10cSrcweir         {
2210*cdf0e10cSrcweir 	        if ( eCmd == DEL_DELCOLS || eCmd == DEL_DELROWS )
2211*cdf0e10cSrcweir                 pDoc->UpdatePageBreaks( i );
2212*cdf0e10cSrcweir 
2213*cdf0e10cSrcweir 	        rDocShell.UpdatePaintExt( nExtFlags, nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i );
2214*cdf0e10cSrcweir 
2215*cdf0e10cSrcweir             SCTAB nScenarioCount = 0;
2216*cdf0e10cSrcweir 
2217*cdf0e10cSrcweir             for( SCTAB j = i+1; j<nTabCount && pDoc->IsScenario(j); j++ )
2218*cdf0e10cSrcweir                 nScenarioCount ++;
2219*cdf0e10cSrcweir 
2220*cdf0e10cSrcweir 	        //	ganze Zeilen loeschen: nichts anpassen
2221*cdf0e10cSrcweir 	        if ( eCmd == DEL_DELROWS || !AdjustRowHeight(ScRange( 0, nPaintStartY, i, MAXCOL, nPaintEndY, i+nScenarioCount )) )
2222*cdf0e10cSrcweir 		        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, nPaintFlags,  nExtFlags );
2223*cdf0e10cSrcweir     	    else
2224*cdf0e10cSrcweir 	        {
2225*cdf0e10cSrcweir 		        //	paint only what is not done by AdjustRowHeight
2226*cdf0e10cSrcweir 		        if (nExtFlags & SC_PF_LINES)
2227*cdf0e10cSrcweir 			        lcl_PaintAbove( rDocShell, ScRange( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount) );
2228*cdf0e10cSrcweir 		        if (nPaintFlags & PAINT_TOP)
2229*cdf0e10cSrcweir 			        rDocShell.PostPaint( nPaintStartX, nPaintStartY, i, nPaintEndX, nPaintEndY, i+nScenarioCount, PAINT_TOP );
2230*cdf0e10cSrcweir 	        }
2231*cdf0e10cSrcweir         }
2232*cdf0e10cSrcweir     }
2233*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
2234*cdf0e10cSrcweir 
2235*cdf0e10cSrcweir     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2236*cdf0e10cSrcweir 
2237*cdf0e10cSrcweir 	return sal_True;
2238*cdf0e10cSrcweir }
2239*cdf0e10cSrcweir 
2240*cdf0e10cSrcweir sal_Bool ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos,
2241*cdf0e10cSrcweir 								sal_Bool bCut, sal_Bool bRecord, sal_Bool bPaint, sal_Bool bApi )
2242*cdf0e10cSrcweir {
2243*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2244*cdf0e10cSrcweir 
2245*cdf0e10cSrcweir 	SCCOL nStartCol = rSource.aStart.Col();
2246*cdf0e10cSrcweir 	SCROW nStartRow = rSource.aStart.Row();
2247*cdf0e10cSrcweir 	SCTAB nStartTab = rSource.aStart.Tab();
2248*cdf0e10cSrcweir 	SCCOL nEndCol = rSource.aEnd.Col();
2249*cdf0e10cSrcweir 	SCROW nEndRow = rSource.aEnd.Row();
2250*cdf0e10cSrcweir 	SCTAB nEndTab = rSource.aEnd.Tab();
2251*cdf0e10cSrcweir 	SCCOL nDestCol = rDestPos.Col();
2252*cdf0e10cSrcweir 	SCROW nDestRow = rDestPos.Row();
2253*cdf0e10cSrcweir 	SCTAB nDestTab = rDestPos.Tab();
2254*cdf0e10cSrcweir 
2255*cdf0e10cSrcweir 	if ( !ValidRow(nStartRow) || !ValidRow(nEndRow) || !ValidRow(nDestRow) )
2256*cdf0e10cSrcweir 	{
2257*cdf0e10cSrcweir 		DBG_ERROR("invalid row in MoveBlock");
2258*cdf0e10cSrcweir 		return sal_False;
2259*cdf0e10cSrcweir 	}
2260*cdf0e10cSrcweir 
2261*cdf0e10cSrcweir 	//	zugehoerige Szenarien auch anpassen - nur wenn innerhalb einer Tabelle verschoben wird!
2262*cdf0e10cSrcweir 	sal_Bool bScenariosAdded = sal_False;
2263*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2264*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
2265*cdf0e10cSrcweir 		bRecord = sal_False;
2266*cdf0e10cSrcweir 
2267*cdf0e10cSrcweir 	SCTAB nTabCount = pDoc->GetTableCount();
2268*cdf0e10cSrcweir 	if ( nDestTab == nStartTab && !pDoc->IsScenario(nEndTab) )
2269*cdf0e10cSrcweir 		while ( nEndTab+1 < nTabCount && pDoc->IsScenario(nEndTab+1) )
2270*cdf0e10cSrcweir 		{
2271*cdf0e10cSrcweir 			++nEndTab;
2272*cdf0e10cSrcweir 			bScenariosAdded = sal_True;
2273*cdf0e10cSrcweir 		}
2274*cdf0e10cSrcweir 
2275*cdf0e10cSrcweir 	SCTAB nSrcTabCount = nEndTab-nStartTab+1;
2276*cdf0e10cSrcweir 	SCTAB nDestEndTab = nDestTab+nSrcTabCount-1;
2277*cdf0e10cSrcweir 	SCTAB nTab;
2278*cdf0e10cSrcweir 
2279*cdf0e10cSrcweir 	ScDocument* pClipDoc = new ScDocument( SCDOCMODE_CLIP );
2280*cdf0e10cSrcweir 
2281*cdf0e10cSrcweir 	ScMarkData aSourceMark;
2282*cdf0e10cSrcweir 	for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2283*cdf0e10cSrcweir 		aSourceMark.SelectTable( nTab, sal_True );		// Source selektieren
2284*cdf0e10cSrcweir 	aSourceMark.SetMarkArea( rSource );
2285*cdf0e10cSrcweir 
2286*cdf0e10cSrcweir 	ScDocShellRef aDragShellRef;
2287*cdf0e10cSrcweir 	if ( pDoc->HasOLEObjectsInArea( rSource ) )
2288*cdf0e10cSrcweir 	{
2289*cdf0e10cSrcweir 		aDragShellRef = new ScDocShell;		// DocShell needs a Ref immediately
2290*cdf0e10cSrcweir 		aDragShellRef->DoInitNew(NULL);
2291*cdf0e10cSrcweir 	}
2292*cdf0e10cSrcweir 	ScDrawLayer::SetGlobalDrawPersist(aDragShellRef);
2293*cdf0e10cSrcweir 
2294*cdf0e10cSrcweir     ScClipParam aClipParam(ScRange(nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nStartTab), bCut);
2295*cdf0e10cSrcweir     pDoc->CopyToClip(aClipParam, pClipDoc, &aSourceMark, false, bScenariosAdded, true);
2296*cdf0e10cSrcweir 
2297*cdf0e10cSrcweir 	ScDrawLayer::SetGlobalDrawPersist(NULL);
2298*cdf0e10cSrcweir 
2299*cdf0e10cSrcweir 	SCCOL nOldEndCol = nEndCol;
2300*cdf0e10cSrcweir 	SCROW nOldEndRow = nEndRow;
2301*cdf0e10cSrcweir 	sal_Bool bClipOver = sal_False;
2302*cdf0e10cSrcweir 	for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2303*cdf0e10cSrcweir 	{
2304*cdf0e10cSrcweir 		SCCOL nTmpEndCol = nOldEndCol;
2305*cdf0e10cSrcweir 		SCROW nTmpEndRow = nOldEndRow;
2306*cdf0e10cSrcweir 		if (pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab ))
2307*cdf0e10cSrcweir 			bClipOver = sal_True;
2308*cdf0e10cSrcweir 		if ( nTmpEndCol > nEndCol ) nEndCol = nTmpEndCol;
2309*cdf0e10cSrcweir 		if ( nTmpEndRow > nEndRow ) nEndRow = nTmpEndRow;
2310*cdf0e10cSrcweir 	}
2311*cdf0e10cSrcweir 
2312*cdf0e10cSrcweir 	SCCOL nDestEndCol = nDestCol + ( nOldEndCol-nStartCol );
2313*cdf0e10cSrcweir 	SCROW nDestEndRow = nDestRow + ( nOldEndRow-nStartRow );
2314*cdf0e10cSrcweir 
2315*cdf0e10cSrcweir 	SCCOL nUndoEndCol = nDestCol + ( nEndCol-nStartCol );		// erweitert im Zielblock
2316*cdf0e10cSrcweir 	SCROW nUndoEndRow = nDestRow + ( nEndRow-nStartRow );
2317*cdf0e10cSrcweir 
2318*cdf0e10cSrcweir 	sal_Bool bIncludeFiltered = bCut;
2319*cdf0e10cSrcweir 	if ( !bIncludeFiltered )
2320*cdf0e10cSrcweir 	{
2321*cdf0e10cSrcweir 		//	adjust sizes to include only non-filtered rows
2322*cdf0e10cSrcweir 
2323*cdf0e10cSrcweir         SCCOL nClipX;
2324*cdf0e10cSrcweir         SCROW nClipY;
2325*cdf0e10cSrcweir         pClipDoc->GetClipArea( nClipX, nClipY, sal_False );
2326*cdf0e10cSrcweir 		SCROW nUndoAdd = nUndoEndRow - nDestEndRow;
2327*cdf0e10cSrcweir 		nDestEndRow = nDestRow + nClipY;
2328*cdf0e10cSrcweir 		nUndoEndRow = nDestEndRow + nUndoAdd;
2329*cdf0e10cSrcweir 	}
2330*cdf0e10cSrcweir 
2331*cdf0e10cSrcweir 	if (!ValidCol(nUndoEndCol) || !ValidRow(nUndoEndRow))
2332*cdf0e10cSrcweir 	{
2333*cdf0e10cSrcweir 		if (!bApi)
2334*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PASTE_FULL);
2335*cdf0e10cSrcweir 		delete pClipDoc;
2336*cdf0e10cSrcweir 		return sal_False;
2337*cdf0e10cSrcweir 	}
2338*cdf0e10cSrcweir 
2339*cdf0e10cSrcweir 	//	Test auf Zellschutz
2340*cdf0e10cSrcweir 
2341*cdf0e10cSrcweir 	ScEditableTester aTester;
2342*cdf0e10cSrcweir 	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2343*cdf0e10cSrcweir 		aTester.TestBlock( pDoc, nTab, nDestCol,nDestRow, nUndoEndCol,nUndoEndRow );
2344*cdf0e10cSrcweir 	if (bCut)
2345*cdf0e10cSrcweir 		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2346*cdf0e10cSrcweir 			aTester.TestBlock( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
2347*cdf0e10cSrcweir 
2348*cdf0e10cSrcweir 	if (!aTester.IsEditable())
2349*cdf0e10cSrcweir 	{
2350*cdf0e10cSrcweir 		if (!bApi)
2351*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
2352*cdf0e10cSrcweir 		delete pClipDoc;
2353*cdf0e10cSrcweir 		return sal_False;
2354*cdf0e10cSrcweir 	}
2355*cdf0e10cSrcweir 
2356*cdf0e10cSrcweir 	//	Test auf zusammengefasste - beim Verschieben erst nach dem Loeschen
2357*cdf0e10cSrcweir 
2358*cdf0e10cSrcweir 	if (bClipOver && !bCut)
2359*cdf0e10cSrcweir 		if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab, nUndoEndCol,nUndoEndRow,nDestEndTab,
2360*cdf0e10cSrcweir 								HASATTR_MERGED | HASATTR_OVERLAPPED ))
2361*cdf0e10cSrcweir 		{		// "Zusammenfassen nicht verschachteln !"
2362*cdf0e10cSrcweir 			if (!bApi)
2363*cdf0e10cSrcweir 				rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
2364*cdf0e10cSrcweir 			delete pClipDoc;
2365*cdf0e10cSrcweir 			return sal_False;
2366*cdf0e10cSrcweir 		}
2367*cdf0e10cSrcweir 
2368*cdf0e10cSrcweir 	//	Are there borders in the cells? (for painting)
2369*cdf0e10cSrcweir 
2370*cdf0e10cSrcweir 	sal_uInt16 nSourceExt = 0;
2371*cdf0e10cSrcweir 	rDocShell.UpdatePaintExt( nSourceExt, nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab );
2372*cdf0e10cSrcweir 	sal_uInt16 nDestExt = 0;
2373*cdf0e10cSrcweir 	rDocShell.UpdatePaintExt( nDestExt, nDestCol,nDestRow,nDestTab, nDestEndCol,nDestEndRow,nDestEndTab );
2374*cdf0e10cSrcweir 
2375*cdf0e10cSrcweir 	//
2376*cdf0e10cSrcweir 	//	ausfuehren
2377*cdf0e10cSrcweir 	//
2378*cdf0e10cSrcweir 
2379*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
2380*cdf0e10cSrcweir 	ScDocument* pRefUndoDoc = NULL;
2381*cdf0e10cSrcweir 	ScRefUndoData* pUndoData = NULL;
2382*cdf0e10cSrcweir 	if (bRecord)
2383*cdf0e10cSrcweir 	{
2384*cdf0e10cSrcweir 		sal_Bool bWholeCols = ( nStartRow == 0 && nEndRow == MAXROW );
2385*cdf0e10cSrcweir 		sal_Bool bWholeRows = ( nStartCol == 0 && nEndCol == MAXCOL );
2386*cdf0e10cSrcweir         sal_uInt16 nUndoFlags = (IDF_ALL & ~IDF_OBJECTS) | IDF_NOCAPTIONS;
2387*cdf0e10cSrcweir 
2388*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2389*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bWholeCols, bWholeRows );
2390*cdf0e10cSrcweir 
2391*cdf0e10cSrcweir 		if (bCut)
2392*cdf0e10cSrcweir 		{
2393*cdf0e10cSrcweir 			pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
2394*cdf0e10cSrcweir                                     nUndoFlags, sal_False, pUndoDoc );
2395*cdf0e10cSrcweir 			pRefUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2396*cdf0e10cSrcweir 			pRefUndoDoc->InitUndo( pDoc, 0, nTabCount-1, sal_False, sal_False );
2397*cdf0e10cSrcweir 		}
2398*cdf0e10cSrcweir 
2399*cdf0e10cSrcweir 		if ( nDestTab != nStartTab )
2400*cdf0e10cSrcweir 			pUndoDoc->AddUndoTab( nDestTab, nDestEndTab, bWholeCols, bWholeRows );
2401*cdf0e10cSrcweir 		pDoc->CopyToDocument( nDestCol, nDestRow, nDestTab,
2402*cdf0e10cSrcweir 									nDestEndCol, nDestEndRow, nDestEndTab,
2403*cdf0e10cSrcweir                                     nUndoFlags, sal_False, pUndoDoc );
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir 		pUndoData = new ScRefUndoData( pDoc );
2406*cdf0e10cSrcweir 
2407*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();
2408*cdf0e10cSrcweir 	}
2409*cdf0e10cSrcweir 
2410*cdf0e10cSrcweir 	sal_Bool bSourceHeight = sal_False;		// Hoehen angepasst?
2411*cdf0e10cSrcweir 	if (bCut)
2412*cdf0e10cSrcweir 	{
2413*cdf0e10cSrcweir 		ScMarkData aDelMark;	// only for tables
2414*cdf0e10cSrcweir 		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2415*cdf0e10cSrcweir 		{
2416*cdf0e10cSrcweir 			pDoc->DeleteAreaTab( nStartCol,nStartRow, nOldEndCol,nOldEndRow, nTab, IDF_ALL );
2417*cdf0e10cSrcweir 			aDelMark.SelectTable( nTab, sal_True );
2418*cdf0e10cSrcweir 		}
2419*cdf0e10cSrcweir 		pDoc->DeleteObjectsInArea( nStartCol,nStartRow, nOldEndCol,nOldEndRow, aDelMark );
2420*cdf0e10cSrcweir 
2421*cdf0e10cSrcweir 		//	Test auf zusammengefasste
2422*cdf0e10cSrcweir 
2423*cdf0e10cSrcweir 		if (bClipOver)
2424*cdf0e10cSrcweir 			if (pDoc->HasAttrib( nDestCol,nDestRow,nDestTab,
2425*cdf0e10cSrcweir 									nUndoEndCol,nUndoEndRow,nDestEndTab,
2426*cdf0e10cSrcweir 									HASATTR_MERGED | HASATTR_OVERLAPPED ))
2427*cdf0e10cSrcweir 			{
2428*cdf0e10cSrcweir 				pDoc->CopyFromClip( rSource, aSourceMark, IDF_ALL, pRefUndoDoc, pClipDoc );
2429*cdf0e10cSrcweir 				for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2430*cdf0e10cSrcweir 				{
2431*cdf0e10cSrcweir 					SCCOL nTmpEndCol = nEndCol;
2432*cdf0e10cSrcweir 					SCROW nTmpEndRow = nEndRow;
2433*cdf0e10cSrcweir 					pDoc->ExtendMerge( nStartCol, nStartRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
2434*cdf0e10cSrcweir 				}
2435*cdf0e10cSrcweir 
2436*cdf0e10cSrcweir 				//	Fehlermeldung erst nach dem Wiederherstellen des Inhalts
2437*cdf0e10cSrcweir 				if (!bApi)		// "Zusammenfassen nicht verschachteln !"
2438*cdf0e10cSrcweir 					rDocShell.ErrorMessage(STR_MSSG_MOVEBLOCKTO_0);
2439*cdf0e10cSrcweir 
2440*cdf0e10cSrcweir 				delete pUndoDoc;
2441*cdf0e10cSrcweir 				delete pRefUndoDoc;
2442*cdf0e10cSrcweir 				delete pUndoData;
2443*cdf0e10cSrcweir 				delete pClipDoc;
2444*cdf0e10cSrcweir 				return sal_False;
2445*cdf0e10cSrcweir 			}
2446*cdf0e10cSrcweir 
2447*cdf0e10cSrcweir 		bSourceHeight = AdjustRowHeight( rSource, sal_False );
2448*cdf0e10cSrcweir 	}
2449*cdf0e10cSrcweir 
2450*cdf0e10cSrcweir 	ScRange aPasteDest( nDestCol, nDestRow, nDestTab, nDestEndCol, nDestEndRow, nDestEndTab );
2451*cdf0e10cSrcweir 
2452*cdf0e10cSrcweir 	ScMarkData aDestMark;
2453*cdf0e10cSrcweir 	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2454*cdf0e10cSrcweir 		aDestMark.SelectTable( nTab, sal_True );		// Destination selektieren
2455*cdf0e10cSrcweir 	aDestMark.SetMarkArea( aPasteDest );
2456*cdf0e10cSrcweir 
2457*cdf0e10cSrcweir     /*  Do not copy cell notes and drawing objects here. While pasting, the
2458*cdf0e10cSrcweir         function ScDocument::UpdateReference() is called which calls
2459*cdf0e10cSrcweir         ScDrawLayer::MoveCells() which may move away inserted objects to wrong
2460*cdf0e10cSrcweir         positions (e.g. if source and destination range overlaps). Cell notes
2461*cdf0e10cSrcweir         and drawing objects are pasted below after doing all adjusting. */
2462*cdf0e10cSrcweir     pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_ALL & ~(IDF_NOTE | IDF_OBJECTS),
2463*cdf0e10cSrcweir 						pRefUndoDoc, pClipDoc, sal_True, sal_False, bIncludeFiltered );
2464*cdf0e10cSrcweir 
2465*cdf0e10cSrcweir 	// skipped rows and merged cells don't mix
2466*cdf0e10cSrcweir 	if ( !bIncludeFiltered && pClipDoc->HasClipFilteredRows() )
2467*cdf0e10cSrcweir 		UnmergeCells( aPasteDest, sal_False, sal_True );
2468*cdf0e10cSrcweir 
2469*cdf0e10cSrcweir 	VirtualDevice aVirtDev;
2470*cdf0e10cSrcweir 	sal_Bool bDestHeight = AdjustRowHeight(
2471*cdf0e10cSrcweir 							ScRange( 0,nDestRow,nDestTab, MAXCOL,nDestEndRow,nDestEndTab ),
2472*cdf0e10cSrcweir 							sal_False );
2473*cdf0e10cSrcweir 
2474*cdf0e10cSrcweir     /*  Paste cell notes and drawing objects after adjusting formula references
2475*cdf0e10cSrcweir         and row heights. There are no cell notes or drawing objects, if the
2476*cdf0e10cSrcweir         clipdoc does not contain a drawing layer.
2477*cdf0e10cSrcweir         #i102056# Passing IDF_NOTE only would overwrite cell contents with
2478*cdf0e10cSrcweir         empty note cells, therefore the special modifier IDF_ADDNOTES is passed
2479*cdf0e10cSrcweir         here too which changes the behaviour of ScColumn::CopyFromClip() to not
2480*cdf0e10cSrcweir         touch existing cells. */
2481*cdf0e10cSrcweir 	if ( pClipDoc->GetDrawLayer() )
2482*cdf0e10cSrcweir         pDoc->CopyFromClip( aPasteDest, aDestMark, IDF_NOTE | IDF_ADDNOTES | IDF_OBJECTS,
2483*cdf0e10cSrcweir 							pRefUndoDoc, pClipDoc, sal_True, sal_False, bIncludeFiltered );
2484*cdf0e10cSrcweir 
2485*cdf0e10cSrcweir 	if (bRecord)
2486*cdf0e10cSrcweir 	{
2487*cdf0e10cSrcweir 		if (pRefUndoDoc)
2488*cdf0e10cSrcweir 		{
2489*cdf0e10cSrcweir 				//	alle Tabellen anlegen, damit Formeln kopiert werden koennen:
2490*cdf0e10cSrcweir 			pUndoDoc->AddUndoTab( 0, nTabCount-1, sal_False, sal_False );
2491*cdf0e10cSrcweir 
2492*cdf0e10cSrcweir 			pRefUndoDoc->DeleteArea( nDestCol, nDestRow, nDestEndCol, nDestEndRow, aSourceMark, IDF_ALL );
2493*cdf0e10cSrcweir 			//	kopieren mit bColRowFlags=sal_False (#54194#)
2494*cdf0e10cSrcweir 			pRefUndoDoc->CopyToDocument( 0, 0, 0, MAXCOL, MAXROW, MAXTAB,
2495*cdf0e10cSrcweir 											IDF_FORMULA, sal_False, pUndoDoc, NULL, sal_False );
2496*cdf0e10cSrcweir 			delete pRefUndoDoc;
2497*cdf0e10cSrcweir 		}
2498*cdf0e10cSrcweir 
2499*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
2500*cdf0e10cSrcweir 			new ScUndoDragDrop( &rDocShell, ScRange(
2501*cdf0e10cSrcweir 									nStartCol, nStartRow, nStartTab,
2502*cdf0e10cSrcweir 									nOldEndCol, nOldEndRow, nEndTab ),
2503*cdf0e10cSrcweir 								ScAddress( nDestCol, nDestRow, nDestTab ),
2504*cdf0e10cSrcweir 								bCut, pUndoDoc, pUndoData, bScenariosAdded ) );
2505*cdf0e10cSrcweir 	}
2506*cdf0e10cSrcweir 
2507*cdf0e10cSrcweir 	SCCOL nDestPaintEndCol = nDestEndCol;
2508*cdf0e10cSrcweir 	SCROW nDestPaintEndRow = nDestEndRow;
2509*cdf0e10cSrcweir 	for (nTab=nDestTab; nTab<=nDestEndTab; nTab++)
2510*cdf0e10cSrcweir 	{
2511*cdf0e10cSrcweir 		SCCOL nTmpEndCol = nDestEndCol;
2512*cdf0e10cSrcweir 		SCROW nTmpEndRow = nDestEndRow;
2513*cdf0e10cSrcweir 		pDoc->ExtendMerge( nDestCol, nDestRow, nTmpEndCol, nTmpEndRow, nTab, sal_True );
2514*cdf0e10cSrcweir 		if (nTmpEndCol > nDestPaintEndCol) nDestPaintEndCol = nTmpEndCol;
2515*cdf0e10cSrcweir 		if (nTmpEndRow > nDestPaintEndRow) nDestPaintEndRow = nTmpEndRow;
2516*cdf0e10cSrcweir 	}
2517*cdf0e10cSrcweir 
2518*cdf0e10cSrcweir 	if (bCut)
2519*cdf0e10cSrcweir 		for (nTab=nStartTab; nTab<=nEndTab; nTab++)
2520*cdf0e10cSrcweir 			pDoc->RefreshAutoFilter( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
2521*cdf0e10cSrcweir 
2522*cdf0e10cSrcweir 	if (bPaint)
2523*cdf0e10cSrcweir 	{
2524*cdf0e10cSrcweir 			//	Zielbereich:
2525*cdf0e10cSrcweir 
2526*cdf0e10cSrcweir 		SCCOL nPaintStartX = nDestCol;
2527*cdf0e10cSrcweir 		SCROW nPaintStartY = nDestRow;
2528*cdf0e10cSrcweir 		SCCOL nPaintEndX = nDestPaintEndCol;
2529*cdf0e10cSrcweir 		SCROW nPaintEndY = nDestPaintEndRow;
2530*cdf0e10cSrcweir 		sal_uInt16 nFlags = PAINT_GRID;
2531*cdf0e10cSrcweir 
2532*cdf0e10cSrcweir 		if ( nStartRow==0 && nEndRow==MAXROW )		// Breiten mitkopiert?
2533*cdf0e10cSrcweir 		{
2534*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2535*cdf0e10cSrcweir 			nPaintStartY = 0;
2536*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2537*cdf0e10cSrcweir 			nFlags |= PAINT_TOP;
2538*cdf0e10cSrcweir 		}
2539*cdf0e10cSrcweir 		if ( bDestHeight || ( nStartCol == 0 && nEndCol == MAXCOL ) )
2540*cdf0e10cSrcweir 		{
2541*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2542*cdf0e10cSrcweir 			nPaintStartX = 0;
2543*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2544*cdf0e10cSrcweir 			nFlags |= PAINT_LEFT;
2545*cdf0e10cSrcweir 		}
2546*cdf0e10cSrcweir 		if ( bScenariosAdded )
2547*cdf0e10cSrcweir 		{
2548*cdf0e10cSrcweir 			nPaintStartX = 0;
2549*cdf0e10cSrcweir             nPaintStartY = 0;
2550*cdf0e10cSrcweir 			nPaintEndX = MAXCOL;
2551*cdf0e10cSrcweir 			nPaintEndY = MAXROW;
2552*cdf0e10cSrcweir 		}
2553*cdf0e10cSrcweir 
2554*cdf0e10cSrcweir 		rDocShell.PostPaint( nPaintStartX,nPaintStartY,nDestTab,
2555*cdf0e10cSrcweir 							nPaintEndX,nPaintEndY,nDestEndTab, nFlags, nSourceExt | nDestExt );
2556*cdf0e10cSrcweir 
2557*cdf0e10cSrcweir 		if ( bCut )
2558*cdf0e10cSrcweir 		{
2559*cdf0e10cSrcweir 				//	Quellbereich:
2560*cdf0e10cSrcweir 
2561*cdf0e10cSrcweir 			nPaintStartX = nStartCol;
2562*cdf0e10cSrcweir 			nPaintStartY = nStartRow;
2563*cdf0e10cSrcweir 			nPaintEndX = nEndCol;
2564*cdf0e10cSrcweir 			nPaintEndY = nEndRow;
2565*cdf0e10cSrcweir 			nFlags = PAINT_GRID;
2566*cdf0e10cSrcweir 
2567*cdf0e10cSrcweir 			if ( bSourceHeight )
2568*cdf0e10cSrcweir 			{
2569*cdf0e10cSrcweir 				nPaintEndY = MAXROW;
2570*cdf0e10cSrcweir 				nPaintStartX = 0;
2571*cdf0e10cSrcweir 				nPaintEndX = MAXCOL;
2572*cdf0e10cSrcweir 				nFlags |= PAINT_LEFT;
2573*cdf0e10cSrcweir 			}
2574*cdf0e10cSrcweir 			if ( bScenariosAdded )
2575*cdf0e10cSrcweir 			{
2576*cdf0e10cSrcweir 				nPaintStartX = 0;
2577*cdf0e10cSrcweir                 nPaintStartY = 0;
2578*cdf0e10cSrcweir 				nPaintEndX = MAXCOL;
2579*cdf0e10cSrcweir 				nPaintEndY = MAXROW;
2580*cdf0e10cSrcweir 			}
2581*cdf0e10cSrcweir 
2582*cdf0e10cSrcweir 			rDocShell.PostPaint( nPaintStartX,nPaintStartY,nStartTab,
2583*cdf0e10cSrcweir 								nPaintEndX,nPaintEndY,nEndTab, nFlags, nSourceExt );
2584*cdf0e10cSrcweir 		}
2585*cdf0e10cSrcweir 	}
2586*cdf0e10cSrcweir 
2587*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
2588*cdf0e10cSrcweir 
2589*cdf0e10cSrcweir     SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2590*cdf0e10cSrcweir 
2591*cdf0e10cSrcweir 	delete pClipDoc;
2592*cdf0e10cSrcweir 	return sal_True;
2593*cdf0e10cSrcweir }
2594*cdf0e10cSrcweir 
2595*cdf0e10cSrcweir //------------------------------------------------------------------------
2596*cdf0e10cSrcweir uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName )
2597*cdf0e10cSrcweir {
2598*cdf0e10cSrcweir     uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY);
2599*cdf0e10cSrcweir     uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess;
2600*cdf0e10cSrcweir     uno::Reference< uno::XInterface > xDocModuleApiObject;
2601*cdf0e10cSrcweir     if ( xSF.is() )
2602*cdf0e10cSrcweir     {
2603*cdf0e10cSrcweir         xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY );
2604*cdf0e10cSrcweir         xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY );
2605*cdf0e10cSrcweir     }
2606*cdf0e10cSrcweir     return xDocModuleApiObject;
2607*cdf0e10cSrcweir 
2608*cdf0e10cSrcweir }
2609*cdf0e10cSrcweir 
2610*cdf0e10cSrcweir script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule )
2611*cdf0e10cSrcweir {
2612*cdf0e10cSrcweir     script::ModuleInfo sModuleInfo;
2613*cdf0e10cSrcweir     sModuleInfo.ModuleType = script::ModuleType::DOCUMENT;
2614*cdf0e10cSrcweir     sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule );
2615*cdf0e10cSrcweir     return sModuleInfo;
2616*cdf0e10cSrcweir }
2617*cdf0e10cSrcweir 
2618*cdf0e10cSrcweir void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sSource )
2619*cdf0e10cSrcweir {
2620*cdf0e10cSrcweir     SfxObjectShell& rDocSh = *rDoc.GetDocumentShell();
2621*cdf0e10cSrcweir     uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
2622*cdf0e10cSrcweir     DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
2623*cdf0e10cSrcweir 
2624*cdf0e10cSrcweir     uno::Reference< container::XNameContainer > xLib;
2625*cdf0e10cSrcweir     if( xLibContainer.is() )
2626*cdf0e10cSrcweir     {
2627*cdf0e10cSrcweir         String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2628*cdf0e10cSrcweir         if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
2629*cdf0e10cSrcweir             aLibName = rDocSh.GetBasicManager()->GetName();
2630*cdf0e10cSrcweir         uno::Any aLibAny = xLibContainer->getByName( aLibName );
2631*cdf0e10cSrcweir         aLibAny >>= xLib;
2632*cdf0e10cSrcweir     }
2633*cdf0e10cSrcweir     if( xLib.is() )
2634*cdf0e10cSrcweir     {
2635*cdf0e10cSrcweir         // if the Module with codename exists then find a new name
2636*cdf0e10cSrcweir         sal_Int32 nNum = 0;
2637*cdf0e10cSrcweir         String genModuleName;
2638*cdf0e10cSrcweir         if ( sModuleName.Len() )
2639*cdf0e10cSrcweir             sModuleName = sModuleName;
2640*cdf0e10cSrcweir         else
2641*cdf0e10cSrcweir         {
2642*cdf0e10cSrcweir              genModuleName = String::CreateFromAscii( "Sheet1" );
2643*cdf0e10cSrcweir              nNum = 1;
2644*cdf0e10cSrcweir         }
2645*cdf0e10cSrcweir         while( xLib->hasByName( genModuleName  ) )
2646*cdf0e10cSrcweir             genModuleName = rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( ++nNum );
2647*cdf0e10cSrcweir 
2648*cdf0e10cSrcweir         uno::Any aSourceAny;
2649*cdf0e10cSrcweir         rtl::OUString sTmpSource = sSource;
2650*cdf0e10cSrcweir         if ( sTmpSource.getLength() == 0 )
2651*cdf0e10cSrcweir             sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" ));
2652*cdf0e10cSrcweir         aSourceAny <<= sTmpSource;
2653*cdf0e10cSrcweir         uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
2654*cdf0e10cSrcweir         if ( xVBAModuleInfo.is() )
2655*cdf0e10cSrcweir         {
2656*cdf0e10cSrcweir             rDoc.SetCodeName( nTab, genModuleName );
2657*cdf0e10cSrcweir             script::ModuleInfo sModuleInfo = lcl_InitModuleInfo(  rDocSh, genModuleName );
2658*cdf0e10cSrcweir             xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo );
2659*cdf0e10cSrcweir             xLib->insertByName( genModuleName, aSourceAny );
2660*cdf0e10cSrcweir         }
2661*cdf0e10cSrcweir 
2662*cdf0e10cSrcweir     }
2663*cdf0e10cSrcweir }
2664*cdf0e10cSrcweir 
2665*cdf0e10cSrcweir void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName )
2666*cdf0e10cSrcweir {
2667*cdf0e10cSrcweir     uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer();
2668*cdf0e10cSrcweir     DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" );
2669*cdf0e10cSrcweir 
2670*cdf0e10cSrcweir     uno::Reference< container::XNameContainer > xLib;
2671*cdf0e10cSrcweir     if( xLibContainer.is() )
2672*cdf0e10cSrcweir     {
2673*cdf0e10cSrcweir         String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) );
2674*cdf0e10cSrcweir         if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() )
2675*cdf0e10cSrcweir             aLibName = rDocSh.GetBasicManager()->GetName();
2676*cdf0e10cSrcweir         uno::Any aLibAny = xLibContainer->getByName( aLibName );
2677*cdf0e10cSrcweir         aLibAny >>= xLib;
2678*cdf0e10cSrcweir     }
2679*cdf0e10cSrcweir     if( xLib.is() )
2680*cdf0e10cSrcweir     {
2681*cdf0e10cSrcweir         uno::Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY );
2682*cdf0e10cSrcweir         if( xLib->hasByName( sModuleName ) )
2683*cdf0e10cSrcweir             xLib->removeByName( sModuleName );
2684*cdf0e10cSrcweir         if ( xVBAModuleInfo.is() )
2685*cdf0e10cSrcweir             xVBAModuleInfo->removeModuleInfo( sModuleName );
2686*cdf0e10cSrcweir 
2687*cdf0e10cSrcweir     }
2688*cdf0e10cSrcweir }
2689*cdf0e10cSrcweir 
2690*cdf0e10cSrcweir 
2691*cdf0e10cSrcweir sal_Bool ScDocFunc::InsertTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
2692*cdf0e10cSrcweir {
2693*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
2694*cdf0e10cSrcweir 	WaitObject aWait( rDocShell.GetActiveDialogParent() );
2695*cdf0e10cSrcweir 
2696*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2697*cdf0e10cSrcweir 
2698*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2699*cdf0e10cSrcweir 
2700*cdf0e10cSrcweir 
2701*cdf0e10cSrcweir     // Strange loop, also basic is loaded too early ( InsertTable )
2702*cdf0e10cSrcweir     // is called via the xml import for sheets in described in odf
2703*cdf0e10cSrcweir     sal_Bool bInsertDocModule = false;
2704*cdf0e10cSrcweir 
2705*cdf0e10cSrcweir     if(  !rDocShell.GetDocument()->IsImportingXML() )
2706*cdf0e10cSrcweir     {
2707*cdf0e10cSrcweir         bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false;
2708*cdf0e10cSrcweir     }
2709*cdf0e10cSrcweir 	if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) )
2710*cdf0e10cSrcweir 		bRecord = sal_False;
2711*cdf0e10cSrcweir 
2712*cdf0e10cSrcweir 	if (bRecord)
2713*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();							//	InsertTab erzeugt ein SdrUndoNewPage
2714*cdf0e10cSrcweir 
2715*cdf0e10cSrcweir 	SCTAB nTabCount = pDoc->GetTableCount();
2716*cdf0e10cSrcweir 	sal_Bool bAppend = ( nTab >= nTabCount );
2717*cdf0e10cSrcweir 	if ( bAppend )
2718*cdf0e10cSrcweir 		nTab = nTabCount;		// wichtig fuer Undo
2719*cdf0e10cSrcweir 
2720*cdf0e10cSrcweir 	if (pDoc->InsertTab( nTab, rName ))
2721*cdf0e10cSrcweir 	{
2722*cdf0e10cSrcweir 		String sCodeName;
2723*cdf0e10cSrcweir 		if (bRecord)
2724*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
2725*cdf0e10cSrcweir 						new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName));
2726*cdf0e10cSrcweir 		//	Views updaten:
2727*cdf0e10cSrcweir         // Only insert vba modules if vba mode ( and not currently importing XML )
2728*cdf0e10cSrcweir         if( bInsertDocModule )
2729*cdf0e10cSrcweir         {
2730*cdf0e10cSrcweir             String sSource;
2731*cdf0e10cSrcweir             VBA_InsertModule( *pDoc, nTab, sCodeName, sSource );
2732*cdf0e10cSrcweir         }
2733*cdf0e10cSrcweir 		rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) );
2734*cdf0e10cSrcweir 
2735*cdf0e10cSrcweir 		rDocShell.PostPaintExtras();
2736*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
2737*cdf0e10cSrcweir 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2738*cdf0e10cSrcweir 		bSuccess = sal_True;
2739*cdf0e10cSrcweir 	}
2740*cdf0e10cSrcweir 	else if (!bApi)
2741*cdf0e10cSrcweir 		rDocShell.ErrorMessage(STR_TABINSERT_ERROR);
2742*cdf0e10cSrcweir 
2743*cdf0e10cSrcweir 	return bSuccess;
2744*cdf0e10cSrcweir }
2745*cdf0e10cSrcweir 
2746*cdf0e10cSrcweir sal_Bool ScDocFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord, sal_Bool /* bApi */ )
2747*cdf0e10cSrcweir {
2748*cdf0e10cSrcweir 	WaitObject aWait( rDocShell.GetActiveDialogParent() );
2749*cdf0e10cSrcweir 
2750*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
2753*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2754*cdf0e10cSrcweir     sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false;
2755*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
2756*cdf0e10cSrcweir 		bRecord = sal_False;
2757*cdf0e10cSrcweir     if ( bVbaEnabled )
2758*cdf0e10cSrcweir         bRecord = sal_False;
2759*cdf0e10cSrcweir 	sal_Bool bWasLinked = pDoc->IsLinked(nTab);
2760*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
2761*cdf0e10cSrcweir 	ScRefUndoData* pUndoData = NULL;
2762*cdf0e10cSrcweir 	if (bRecord)
2763*cdf0e10cSrcweir 	{
2764*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2765*cdf0e10cSrcweir 		SCTAB nCount = pDoc->GetTableCount();
2766*cdf0e10cSrcweir 
2767*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );		// nur nTab mit Flags
2768*cdf0e10cSrcweir 		pUndoDoc->AddUndoTab( 0, nCount-1 );					// alle Tabs fuer Referenzen
2769*cdf0e10cSrcweir 
2770*cdf0e10cSrcweir 		pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
2771*cdf0e10cSrcweir 		String aOldName;
2772*cdf0e10cSrcweir 		pDoc->GetName( nTab, aOldName );
2773*cdf0e10cSrcweir 		pUndoDoc->RenameTab( nTab, aOldName, sal_False );
2774*cdf0e10cSrcweir 		if (bWasLinked)
2775*cdf0e10cSrcweir 			pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2776*cdf0e10cSrcweir 								pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2777*cdf0e10cSrcweir 								pDoc->GetLinkTab(nTab),
2778*cdf0e10cSrcweir 								pDoc->GetLinkRefreshDelay(nTab) );
2779*cdf0e10cSrcweir 
2780*cdf0e10cSrcweir 		if ( pDoc->IsScenario(nTab) )
2781*cdf0e10cSrcweir 		{
2782*cdf0e10cSrcweir 			pUndoDoc->SetScenario( nTab, sal_True );
2783*cdf0e10cSrcweir 			String aComment;
2784*cdf0e10cSrcweir 			Color  aColor;
2785*cdf0e10cSrcweir 			sal_uInt16 nScenFlags;
2786*cdf0e10cSrcweir 			pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2787*cdf0e10cSrcweir 			pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2788*cdf0e10cSrcweir 			sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2789*cdf0e10cSrcweir 			pUndoDoc->SetActiveScenario( nTab, bActive );
2790*cdf0e10cSrcweir 		}
2791*cdf0e10cSrcweir 		pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2792*cdf0e10cSrcweir         pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
2793*cdf0e10cSrcweir         pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2794*cdf0e10cSrcweir 
2795*cdf0e10cSrcweir 		//	Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
2796*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();							//	DeleteTab erzeugt ein SdrUndoDelPage
2797*cdf0e10cSrcweir 
2798*cdf0e10cSrcweir 		pUndoData = new ScRefUndoData( pDoc );
2799*cdf0e10cSrcweir 	}
2800*cdf0e10cSrcweir 
2801*cdf0e10cSrcweir     String sCodeName;
2802*cdf0e10cSrcweir     sal_Bool bHasCodeName = pDoc->GetCodeName( nTab, sCodeName );
2803*cdf0e10cSrcweir 	if (pDoc->DeleteTab( nTab, pUndoDoc ))
2804*cdf0e10cSrcweir 	{
2805*cdf0e10cSrcweir 		if (bRecord)
2806*cdf0e10cSrcweir 		{
2807*cdf0e10cSrcweir 			SvShorts theTabs;
2808*cdf0e10cSrcweir 			theTabs.push_back(nTab);
2809*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
2810*cdf0e10cSrcweir 						new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData ));
2811*cdf0e10cSrcweir 		}
2812*cdf0e10cSrcweir 		//	Views updaten:
2813*cdf0e10cSrcweir         if( bVbaEnabled )
2814*cdf0e10cSrcweir         {
2815*cdf0e10cSrcweir             if( bHasCodeName )
2816*cdf0e10cSrcweir             {
2817*cdf0e10cSrcweir                 VBA_DeleteModule( rDocShell, sCodeName );
2818*cdf0e10cSrcweir             }
2819*cdf0e10cSrcweir         }
2820*cdf0e10cSrcweir 		rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) );
2821*cdf0e10cSrcweir 
2822*cdf0e10cSrcweir 		if (bWasLinked)
2823*cdf0e10cSrcweir 		{
2824*cdf0e10cSrcweir 			rDocShell.UpdateLinks();				// Link-Manager updaten
2825*cdf0e10cSrcweir 			SfxBindings* pBindings = rDocShell.GetViewBindings();
2826*cdf0e10cSrcweir 			if (pBindings)
2827*cdf0e10cSrcweir 				pBindings->Invalidate(SID_LINKS);
2828*cdf0e10cSrcweir 		}
2829*cdf0e10cSrcweir 
2830*cdf0e10cSrcweir 		rDocShell.PostPaintExtras();
2831*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
2832*cdf0e10cSrcweir 
2833*cdf0e10cSrcweir         SfxApplication* pSfxApp = SFX_APP();                                // Navigator
2834*cdf0e10cSrcweir         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2835*cdf0e10cSrcweir         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2836*cdf0e10cSrcweir         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2837*cdf0e10cSrcweir 
2838*cdf0e10cSrcweir 		bSuccess = sal_True;
2839*cdf0e10cSrcweir 	}
2840*cdf0e10cSrcweir 	else
2841*cdf0e10cSrcweir 	{
2842*cdf0e10cSrcweir 		delete pUndoDoc;
2843*cdf0e10cSrcweir 		delete pUndoData;
2844*cdf0e10cSrcweir 	}
2845*cdf0e10cSrcweir 	return bSuccess;
2846*cdf0e10cSrcweir }
2847*cdf0e10cSrcweir 
2848*cdf0e10cSrcweir sal_Bool ScDocFunc::SetTableVisible( SCTAB nTab, sal_Bool bVisible, sal_Bool bApi )
2849*cdf0e10cSrcweir {
2850*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2851*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
2852*cdf0e10cSrcweir 	if ( pDoc->IsVisible( nTab ) == bVisible )
2853*cdf0e10cSrcweir 		return sal_True;								// nichts zu tun - ok
2854*cdf0e10cSrcweir 
2855*cdf0e10cSrcweir 	if ( !pDoc->IsDocEditable() )
2856*cdf0e10cSrcweir 	{
2857*cdf0e10cSrcweir 		if (!bApi)
2858*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PROTECTIONERR);
2859*cdf0e10cSrcweir 		return sal_False;
2860*cdf0e10cSrcweir 	}
2861*cdf0e10cSrcweir 
2862*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2863*cdf0e10cSrcweir 
2864*cdf0e10cSrcweir 	if ( !bVisible && !pDoc->IsImportingXML() )     // #i57869# allow hiding in any order for loading
2865*cdf0e10cSrcweir 	{
2866*cdf0e10cSrcweir 		//	nicht alle Tabellen ausblenden
2867*cdf0e10cSrcweir 
2868*cdf0e10cSrcweir 		sal_uInt16 nVisCount = 0;
2869*cdf0e10cSrcweir 		SCTAB nCount = pDoc->GetTableCount();
2870*cdf0e10cSrcweir 		for (SCTAB i=0; i<nCount; i++)
2871*cdf0e10cSrcweir 			if (pDoc->IsVisible(i))
2872*cdf0e10cSrcweir 				++nVisCount;
2873*cdf0e10cSrcweir 
2874*cdf0e10cSrcweir 		if (nVisCount <= 1)
2875*cdf0e10cSrcweir 		{
2876*cdf0e10cSrcweir 			if (!bApi)
2877*cdf0e10cSrcweir 				rDocShell.ErrorMessage(STR_PROTECTIONERR);	//!	eigene Meldung?
2878*cdf0e10cSrcweir 			return sal_False;
2879*cdf0e10cSrcweir 		}
2880*cdf0e10cSrcweir 	}
2881*cdf0e10cSrcweir 
2882*cdf0e10cSrcweir 	pDoc->SetVisible( nTab, bVisible );
2883*cdf0e10cSrcweir 	if (bUndo)
2884*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( &rDocShell, nTab, bVisible ) );
2885*cdf0e10cSrcweir 
2886*cdf0e10cSrcweir 	//	Views updaten:
2887*cdf0e10cSrcweir 	if (!bVisible)
2888*cdf0e10cSrcweir 		rDocShell.Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
2889*cdf0e10cSrcweir 
2890*cdf0e10cSrcweir 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2891*cdf0e10cSrcweir 	rDocShell.PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2892*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
2893*cdf0e10cSrcweir 
2894*cdf0e10cSrcweir 	return sal_True;
2895*cdf0e10cSrcweir }
2896*cdf0e10cSrcweir 
2897*cdf0e10cSrcweir sal_Bool ScDocFunc::SetLayoutRTL( SCTAB nTab, sal_Bool bRTL, sal_Bool /* bApi */ )
2898*cdf0e10cSrcweir {
2899*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2900*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
2901*cdf0e10cSrcweir 	if ( pDoc->IsLayoutRTL( nTab ) == bRTL )
2902*cdf0e10cSrcweir 		return sal_True;								// nothing to do - ok
2903*cdf0e10cSrcweir 
2904*cdf0e10cSrcweir 	//!	protection (sheet or document?)
2905*cdf0e10cSrcweir 
2906*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2907*cdf0e10cSrcweir 
2908*cdf0e10cSrcweir 	pDoc->SetLayoutRTL( nTab, bRTL );
2909*cdf0e10cSrcweir 
2910*cdf0e10cSrcweir 	if (bUndo)
2911*cdf0e10cSrcweir 	{
2912*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoLayoutRTL( &rDocShell, nTab, bRTL ) );
2913*cdf0e10cSrcweir 	}
2914*cdf0e10cSrcweir 
2915*cdf0e10cSrcweir 	rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
2916*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
2917*cdf0e10cSrcweir 
2918*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
2919*cdf0e10cSrcweir 	if (pBindings)
2920*cdf0e10cSrcweir 	{
2921*cdf0e10cSrcweir 		pBindings->Invalidate( FID_TAB_RTL );
2922*cdf0e10cSrcweir 		pBindings->Invalidate( SID_ATTR_SIZE );
2923*cdf0e10cSrcweir 	}
2924*cdf0e10cSrcweir 
2925*cdf0e10cSrcweir 	return sal_True;
2926*cdf0e10cSrcweir }
2927*cdf0e10cSrcweir 
2928*cdf0e10cSrcweir //UNUSED2009-05 sal_Bool ScDocFunc::SetGrammar( formula::FormulaGrammar::Grammar eGrammar )
2929*cdf0e10cSrcweir //UNUSED2009-05 {
2930*cdf0e10cSrcweir //UNUSED2009-05     ScDocument* pDoc = rDocShell.GetDocument();
2931*cdf0e10cSrcweir //UNUSED2009-05
2932*cdf0e10cSrcweir //UNUSED2009-05     if ( pDoc->GetGrammar() == eGrammar )
2933*cdf0e10cSrcweir //UNUSED2009-05         return sal_True;
2934*cdf0e10cSrcweir //UNUSED2009-05
2935*cdf0e10cSrcweir //UNUSED2009-05     sal_Bool bUndo(pDoc->IsUndoEnabled());
2936*cdf0e10cSrcweir //UNUSED2009-05     ScDocShellModificator aModificator( rDocShell );
2937*cdf0e10cSrcweir //UNUSED2009-05
2938*cdf0e10cSrcweir //UNUSED2009-05     pDoc->SetGrammar( eGrammar );
2939*cdf0e10cSrcweir //UNUSED2009-05
2940*cdf0e10cSrcweir //UNUSED2009-05     if (bUndo)
2941*cdf0e10cSrcweir //UNUSED2009-05     {
2942*cdf0e10cSrcweir //UNUSED2009-05         rDocShell.GetUndoManager()->AddUndoAction( new ScUndoSetGrammar( &rDocShell, eGrammar ) );
2943*cdf0e10cSrcweir //UNUSED2009-05     }
2944*cdf0e10cSrcweir //UNUSED2009-05
2945*cdf0e10cSrcweir //UNUSED2009-05     rDocShell.PostPaint( 0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_ALL );
2946*cdf0e10cSrcweir //UNUSED2009-05
2947*cdf0e10cSrcweir //UNUSED2009-05     ScTabViewShell* pViewSh = ScTabViewShell::GetActiveViewShell();
2948*cdf0e10cSrcweir //UNUSED2009-05     if (NULL != pViewSh)
2949*cdf0e10cSrcweir //UNUSED2009-05     {
2950*cdf0e10cSrcweir //UNUSED2009-05         pViewSh->UpdateInputHandler( sal_False, sal_False );
2951*cdf0e10cSrcweir //UNUSED2009-05     }
2952*cdf0e10cSrcweir //UNUSED2009-05
2953*cdf0e10cSrcweir //UNUSED2009-05     aModificator.SetDocumentModified();
2954*cdf0e10cSrcweir //UNUSED2009-05
2955*cdf0e10cSrcweir //UNUSED2009-05     SfxBindings* pBindings = rDocShell.GetViewBindings();
2956*cdf0e10cSrcweir //UNUSED2009-05     if (pBindings)
2957*cdf0e10cSrcweir //UNUSED2009-05     {
2958*cdf0e10cSrcweir //UNUSED2009-05         // erAck: 2006-09-07T22:19+0200  commented out in CWS scr1c1
2959*cdf0e10cSrcweir //UNUSED2009-05         //pBindings->Invalidate( FID_TAB_USE_R1C1 );
2960*cdf0e10cSrcweir //UNUSED2009-05     }
2961*cdf0e10cSrcweir //UNUSED2009-05
2962*cdf0e10cSrcweir //UNUSED2009-05     return sal_True;
2963*cdf0e10cSrcweir //UNUSED2009-05 }
2964*cdf0e10cSrcweir 
2965*cdf0e10cSrcweir sal_Bool ScDocFunc::RenameTable( SCTAB nTab, const String& rName, sal_Bool bRecord, sal_Bool bApi )
2966*cdf0e10cSrcweir {
2967*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
2968*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
2969*cdf0e10cSrcweir 		bRecord = sal_False;
2970*cdf0e10cSrcweir 	if ( !pDoc->IsDocEditable() )
2971*cdf0e10cSrcweir 	{
2972*cdf0e10cSrcweir 		if (!bApi)
2973*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PROTECTIONERR);
2974*cdf0e10cSrcweir 		return sal_False;
2975*cdf0e10cSrcweir 	}
2976*cdf0e10cSrcweir 
2977*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
2978*cdf0e10cSrcweir 
2979*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
2980*cdf0e10cSrcweir 	String sOldName;
2981*cdf0e10cSrcweir 	pDoc->GetName(nTab, sOldName);
2982*cdf0e10cSrcweir 	if (pDoc->RenameTab( nTab, rName ))
2983*cdf0e10cSrcweir 	{
2984*cdf0e10cSrcweir 		if (bRecord)
2985*cdf0e10cSrcweir 		{
2986*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
2987*cdf0e10cSrcweir 							new ScUndoRenameTab( &rDocShell, nTab, sOldName, rName));
2988*cdf0e10cSrcweir 		}
2989*cdf0e10cSrcweir 		rDocShell.PostPaintExtras();
2990*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
2991*cdf0e10cSrcweir 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2992*cdf0e10cSrcweir 
2993*cdf0e10cSrcweir 		bSuccess = sal_True;
2994*cdf0e10cSrcweir 	}
2995*cdf0e10cSrcweir 	return bSuccess;
2996*cdf0e10cSrcweir }
2997*cdf0e10cSrcweir 
2998*cdf0e10cSrcweir bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi )
2999*cdf0e10cSrcweir {
3000*cdf0e10cSrcweir 
3001*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
3002*cdf0e10cSrcweir     if (bRecord && !pDoc->IsUndoEnabled())
3003*cdf0e10cSrcweir         bRecord = false;
3004*cdf0e10cSrcweir     if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) )
3005*cdf0e10cSrcweir     {
3006*cdf0e10cSrcweir         if (!bApi)
3007*cdf0e10cSrcweir             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is...
3008*cdf0e10cSrcweir         return false;
3009*cdf0e10cSrcweir     }
3010*cdf0e10cSrcweir 
3011*cdf0e10cSrcweir     Color aOldTabBgColor;
3012*cdf0e10cSrcweir     aOldTabBgColor = pDoc->GetTabBgColor(nTab);
3013*cdf0e10cSrcweir 
3014*cdf0e10cSrcweir     bool bSuccess = false;
3015*cdf0e10cSrcweir     pDoc->SetTabBgColor(nTab, rColor);
3016*cdf0e10cSrcweir     if ( pDoc->GetTabBgColor(nTab) == rColor)
3017*cdf0e10cSrcweir         bSuccess = true;
3018*cdf0e10cSrcweir     if (bSuccess)
3019*cdf0e10cSrcweir     {
3020*cdf0e10cSrcweir         if (bRecord)
3021*cdf0e10cSrcweir         {
3022*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction(
3023*cdf0e10cSrcweir                 new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor));
3024*cdf0e10cSrcweir         }
3025*cdf0e10cSrcweir         rDocShell.PostPaintExtras();
3026*cdf0e10cSrcweir         ScDocShellModificator aModificator( rDocShell );
3027*cdf0e10cSrcweir         aModificator.SetDocumentModified();
3028*cdf0e10cSrcweir         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
3029*cdf0e10cSrcweir 
3030*cdf0e10cSrcweir         bSuccess = true;
3031*cdf0e10cSrcweir     }
3032*cdf0e10cSrcweir     return bSuccess;
3033*cdf0e10cSrcweir }
3034*cdf0e10cSrcweir 
3035*cdf0e10cSrcweir bool ScDocFunc::SetTabBgColor(
3036*cdf0e10cSrcweir     ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi )
3037*cdf0e10cSrcweir {
3038*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
3039*cdf0e10cSrcweir     if (bRecord && !pDoc->IsUndoEnabled())
3040*cdf0e10cSrcweir         bRecord = false;
3041*cdf0e10cSrcweir 
3042*cdf0e10cSrcweir     if ( !pDoc->IsDocEditable() )
3043*cdf0e10cSrcweir     {
3044*cdf0e10cSrcweir         if (!bApi)
3045*cdf0e10cSrcweir             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3046*cdf0e10cSrcweir         return false;
3047*cdf0e10cSrcweir     }
3048*cdf0e10cSrcweir 
3049*cdf0e10cSrcweir     sal_uInt16 nTab;
3050*cdf0e10cSrcweir     Color aNewTabBgColor;
3051*cdf0e10cSrcweir     bool bSuccess = true;
3052*cdf0e10cSrcweir     size_t nTabProtectCount = 0;
3053*cdf0e10cSrcweir     size_t nTabListCount = rUndoTabColorList.size();
3054*cdf0e10cSrcweir     for ( size_t i = 0; i < nTabListCount; ++i )
3055*cdf0e10cSrcweir     {
3056*cdf0e10cSrcweir         ScUndoTabColorInfo& rInfo = rUndoTabColorList[i];
3057*cdf0e10cSrcweir         nTab = rInfo.mnTabId;
3058*cdf0e10cSrcweir         if ( !pDoc->IsTabProtected(nTab) )
3059*cdf0e10cSrcweir         {
3060*cdf0e10cSrcweir             aNewTabBgColor = rInfo.maNewTabBgColor;
3061*cdf0e10cSrcweir             rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab);
3062*cdf0e10cSrcweir             pDoc->SetTabBgColor(nTab, aNewTabBgColor);
3063*cdf0e10cSrcweir             if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor)
3064*cdf0e10cSrcweir             {
3065*cdf0e10cSrcweir                 bSuccess = false;
3066*cdf0e10cSrcweir                 break;
3067*cdf0e10cSrcweir             }
3068*cdf0e10cSrcweir         }
3069*cdf0e10cSrcweir         else
3070*cdf0e10cSrcweir         {
3071*cdf0e10cSrcweir             nTabProtectCount++;
3072*cdf0e10cSrcweir         }
3073*cdf0e10cSrcweir     }
3074*cdf0e10cSrcweir 
3075*cdf0e10cSrcweir     if ( nTabProtectCount == nTabListCount )
3076*cdf0e10cSrcweir     {
3077*cdf0e10cSrcweir         if (!bApi)
3078*cdf0e10cSrcweir             rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error...
3079*cdf0e10cSrcweir         return false;
3080*cdf0e10cSrcweir     }
3081*cdf0e10cSrcweir 
3082*cdf0e10cSrcweir     if (bSuccess)
3083*cdf0e10cSrcweir     {
3084*cdf0e10cSrcweir         if (bRecord)
3085*cdf0e10cSrcweir         {
3086*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction(
3087*cdf0e10cSrcweir                 new ScUndoTabColor( &rDocShell, rUndoTabColorList));
3088*cdf0e10cSrcweir         }
3089*cdf0e10cSrcweir         rDocShell.PostPaintExtras();
3090*cdf0e10cSrcweir         ScDocShellModificator aModificator( rDocShell );
3091*cdf0e10cSrcweir         aModificator.SetDocumentModified();
3092*cdf0e10cSrcweir     }
3093*cdf0e10cSrcweir     return bSuccess;
3094*cdf0e10cSrcweir }
3095*cdf0e10cSrcweir 
3096*cdf0e10cSrcweir //------------------------------------------------------------------------
3097*cdf0e10cSrcweir 
3098*cdf0e10cSrcweir //!	SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!!
3099*cdf0e10cSrcweir //!	Probleme:
3100*cdf0e10cSrcweir //!	- Optimale Hoehe fuer Edit-Zellen ist unterschiedlich zwischen Drucker und Bildschirm
3101*cdf0e10cSrcweir //!	- Optimale Breite braucht Selektion, um evtl. nur selektierte Zellen zu beruecksichtigen
3102*cdf0e10cSrcweir 
3103*cdf0e10cSrcweir sal_uInt16 lcl_GetOptimalColWidth( ScDocShell& rDocShell, SCCOL nCol, SCTAB nTab, sal_Bool bFormula )
3104*cdf0e10cSrcweir {
3105*cdf0e10cSrcweir 	sal_uInt16 nTwips = 0;
3106*cdf0e10cSrcweir 
3107*cdf0e10cSrcweir 	ScSizeDeviceProvider aProv(&rDocShell);
3108*cdf0e10cSrcweir 	OutputDevice* pDev = aProv.GetDevice();			// has pixel MapMode
3109*cdf0e10cSrcweir 	double nPPTX = aProv.GetPPTX();
3110*cdf0e10cSrcweir 	double nPPTY = aProv.GetPPTY();
3111*cdf0e10cSrcweir 
3112*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3113*cdf0e10cSrcweir 	Fraction aOne(1,1);
3114*cdf0e10cSrcweir 	nTwips = pDoc->GetOptimalColWidth( nCol, nTab, pDev, nPPTX, nPPTY, aOne, aOne,
3115*cdf0e10cSrcweir 										bFormula, NULL );
3116*cdf0e10cSrcweir 
3117*cdf0e10cSrcweir 	return nTwips;
3118*cdf0e10cSrcweir }
3119*cdf0e10cSrcweir 
3120*cdf0e10cSrcweir sal_Bool ScDocFunc::SetWidthOrHeight( sal_Bool bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRanges, SCTAB nTab,
3121*cdf0e10cSrcweir 										ScSizeMode eMode, sal_uInt16 nSizeTwips,
3122*cdf0e10cSrcweir 										sal_Bool bRecord, sal_Bool bApi )
3123*cdf0e10cSrcweir {
3124*cdf0e10cSrcweir     ScDocShellModificator aModificator( rDocShell );
3125*cdf0e10cSrcweir 
3126*cdf0e10cSrcweir 	if (!nRangeCnt)
3127*cdf0e10cSrcweir 		return sal_True;
3128*cdf0e10cSrcweir 
3129*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3130*cdf0e10cSrcweir 	if ( bRecord && !pDoc->IsUndoEnabled() )
3131*cdf0e10cSrcweir 		bRecord = sal_False;
3132*cdf0e10cSrcweir 
3133*cdf0e10cSrcweir     // import into read-only document is possible
3134*cdf0e10cSrcweir     if ( !pDoc->IsChangeReadOnlyEnabled() && !rDocShell.IsEditable() )
3135*cdf0e10cSrcweir 	{
3136*cdf0e10cSrcweir 		if (!bApi)
3137*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_PROTECTIONERR);		//! eigene Meldung?
3138*cdf0e10cSrcweir 		return sal_False;
3139*cdf0e10cSrcweir 	}
3140*cdf0e10cSrcweir 
3141*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3142*cdf0e10cSrcweir 	SCCOLROW nStart = pRanges[0];
3143*cdf0e10cSrcweir 	SCCOLROW nEnd = pRanges[2*nRangeCnt-1];
3144*cdf0e10cSrcweir 
3145*cdf0e10cSrcweir 	sal_Bool bFormula = sal_False;
3146*cdf0e10cSrcweir 	if ( eMode == SC_SIZE_OPTIMAL )
3147*cdf0e10cSrcweir 	{
3148*cdf0e10cSrcweir 		//!	Option "Formeln anzeigen" - woher nehmen?
3149*cdf0e10cSrcweir 	}
3150*cdf0e10cSrcweir 
3151*cdf0e10cSrcweir 	ScDocument* 	pUndoDoc = NULL;
3152*cdf0e10cSrcweir 	ScOutlineTable* pUndoTab = NULL;
3153*cdf0e10cSrcweir 	SCCOLROW*		pUndoRanges = NULL;
3154*cdf0e10cSrcweir 
3155*cdf0e10cSrcweir 	if ( bRecord )
3156*cdf0e10cSrcweir 	{
3157*cdf0e10cSrcweir 		pDoc->BeginDrawUndo();							// Drawing Updates
3158*cdf0e10cSrcweir 
3159*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3160*cdf0e10cSrcweir 		if (bWidth)
3161*cdf0e10cSrcweir 		{
3162*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_False );
3163*cdf0e10cSrcweir 			pDoc->CopyToDocument( static_cast<SCCOL>(nStart), 0, nTab, static_cast<SCCOL>(nEnd), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc );
3164*cdf0e10cSrcweir 		}
3165*cdf0e10cSrcweir 		else
3166*cdf0e10cSrcweir 		{
3167*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True );
3168*cdf0e10cSrcweir 			pDoc->CopyToDocument( 0, static_cast<SCROW>(nStart), nTab, MAXCOL, static_cast<SCROW>(nEnd), nTab, IDF_NONE, sal_False, pUndoDoc );
3169*cdf0e10cSrcweir 		}
3170*cdf0e10cSrcweir 
3171*cdf0e10cSrcweir 		pUndoRanges = new SCCOLROW[ 2*nRangeCnt ];
3172*cdf0e10cSrcweir 		memmove( pUndoRanges, pRanges, 2*nRangeCnt*sizeof(SCCOLROW) );
3173*cdf0e10cSrcweir 
3174*cdf0e10cSrcweir 		ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab );
3175*cdf0e10cSrcweir 		if (pTable)
3176*cdf0e10cSrcweir 			pUndoTab = new ScOutlineTable( *pTable );
3177*cdf0e10cSrcweir 	}
3178*cdf0e10cSrcweir 
3179*cdf0e10cSrcweir 	sal_Bool bShow = nSizeTwips > 0 || eMode != SC_SIZE_DIRECT;
3180*cdf0e10cSrcweir 	sal_Bool bOutline = sal_False;
3181*cdf0e10cSrcweir 
3182*cdf0e10cSrcweir 	pDoc->IncSizeRecalcLevel( nTab );		// nicht fuer jede Spalte einzeln
3183*cdf0e10cSrcweir 	for (SCCOLROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
3184*cdf0e10cSrcweir 	{
3185*cdf0e10cSrcweir 		SCCOLROW nStartNo = *(pRanges++);
3186*cdf0e10cSrcweir 		SCCOLROW nEndNo = *(pRanges++);
3187*cdf0e10cSrcweir 
3188*cdf0e10cSrcweir 		if ( !bWidth )						// Hoehen immer blockweise
3189*cdf0e10cSrcweir 		{
3190*cdf0e10cSrcweir 			if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
3191*cdf0e10cSrcweir 			{
3192*cdf0e10cSrcweir 				sal_Bool bAll = ( eMode==SC_SIZE_OPTIMAL );
3193*cdf0e10cSrcweir 				if (!bAll)
3194*cdf0e10cSrcweir 				{
3195*cdf0e10cSrcweir 					//	fuer alle eingeblendeten CR_MANUALSIZE loeschen,
3196*cdf0e10cSrcweir 					//	dann SetOptimalHeight mit bShrink = FALSE
3197*cdf0e10cSrcweir 					for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++)
3198*cdf0e10cSrcweir 					{
3199*cdf0e10cSrcweir 						sal_uInt8 nOld = pDoc->GetRowFlags(nRow,nTab);
3200*cdf0e10cSrcweir 						SCROW nLastRow = -1;
3201*cdf0e10cSrcweir 						bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow);
3202*cdf0e10cSrcweir 						if ( !bHidden && ( nOld & CR_MANUALSIZE ) )
3203*cdf0e10cSrcweir 							pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE );
3204*cdf0e10cSrcweir 					}
3205*cdf0e10cSrcweir 				}
3206*cdf0e10cSrcweir 
3207*cdf0e10cSrcweir 				ScSizeDeviceProvider aProv( &rDocShell );
3208*cdf0e10cSrcweir 				Fraction aOne(1,1);
3209*cdf0e10cSrcweir 				pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
3210*cdf0e10cSrcweir 										aProv.GetPPTX(), aProv.GetPPTY(), aOne, aOne, bAll );
3211*cdf0e10cSrcweir 
3212*cdf0e10cSrcweir 				if (bAll)
3213*cdf0e10cSrcweir 					pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
3214*cdf0e10cSrcweir 
3215*cdf0e10cSrcweir 				//	Manual-Flag wird bei bAll=sal_True schon in SetOptimalHeight gesetzt
3216*cdf0e10cSrcweir 				//	(an bei Extra-Height, sonst aus).
3217*cdf0e10cSrcweir 			}
3218*cdf0e10cSrcweir 			else if ( eMode==SC_SIZE_DIRECT || eMode==SC_SIZE_ORIGINAL )
3219*cdf0e10cSrcweir 			{
3220*cdf0e10cSrcweir 				if (nSizeTwips)
3221*cdf0e10cSrcweir 				{
3222*cdf0e10cSrcweir 					pDoc->SetRowHeightRange( nStartNo, nEndNo, nTab, nSizeTwips );
3223*cdf0e10cSrcweir 					pDoc->SetManualHeight( nStartNo, nEndNo, nTab, sal_True );			// height was set manually
3224*cdf0e10cSrcweir 				}
3225*cdf0e10cSrcweir 				if ( eMode != SC_SIZE_ORIGINAL )
3226*cdf0e10cSrcweir 					pDoc->ShowRows( nStartNo, nEndNo, nTab, nSizeTwips != 0 );
3227*cdf0e10cSrcweir 			}
3228*cdf0e10cSrcweir 			else if ( eMode==SC_SIZE_SHOW )
3229*cdf0e10cSrcweir 			{
3230*cdf0e10cSrcweir 				pDoc->ShowRows( nStartNo, nEndNo, nTab, sal_True );
3231*cdf0e10cSrcweir 			}
3232*cdf0e10cSrcweir 		}
3233*cdf0e10cSrcweir 		else								// Spaltenbreiten
3234*cdf0e10cSrcweir 		{
3235*cdf0e10cSrcweir 			for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++)
3236*cdf0e10cSrcweir 			{
3237*cdf0e10cSrcweir                 SCCOL nLastCol = -1;
3238*cdf0e10cSrcweir                 if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab, nLastCol) )
3239*cdf0e10cSrcweir 				{
3240*cdf0e10cSrcweir 					sal_uInt16 nThisSize = nSizeTwips;
3241*cdf0e10cSrcweir 
3242*cdf0e10cSrcweir 					if ( eMode==SC_SIZE_OPTIMAL || eMode==SC_SIZE_VISOPT )
3243*cdf0e10cSrcweir 						nThisSize = nSizeTwips +
3244*cdf0e10cSrcweir 									lcl_GetOptimalColWidth( rDocShell, nCol, nTab, bFormula );
3245*cdf0e10cSrcweir 					if ( nThisSize )
3246*cdf0e10cSrcweir 						pDoc->SetColWidth( nCol, nTab, nThisSize );
3247*cdf0e10cSrcweir 
3248*cdf0e10cSrcweir 					if ( eMode != SC_SIZE_ORIGINAL )
3249*cdf0e10cSrcweir 						pDoc->ShowCol( nCol, nTab, bShow );
3250*cdf0e10cSrcweir 				}
3251*cdf0e10cSrcweir 			}
3252*cdf0e10cSrcweir 		}
3253*cdf0e10cSrcweir 
3254*cdf0e10cSrcweir 							//	adjust outlines
3255*cdf0e10cSrcweir 
3256*cdf0e10cSrcweir 		if ( eMode != SC_SIZE_ORIGINAL )
3257*cdf0e10cSrcweir 		{
3258*cdf0e10cSrcweir 			if (bWidth)
3259*cdf0e10cSrcweir                 bOutline = bOutline || pDoc->UpdateOutlineCol(
3260*cdf0e10cSrcweir                         static_cast<SCCOL>(nStartNo),
3261*cdf0e10cSrcweir                         static_cast<SCCOL>(nEndNo), nTab, bShow );
3262*cdf0e10cSrcweir 			else
3263*cdf0e10cSrcweir                 bOutline = bOutline || pDoc->UpdateOutlineRow(
3264*cdf0e10cSrcweir                         static_cast<SCROW>(nStartNo),
3265*cdf0e10cSrcweir                         static_cast<SCROW>(nEndNo), nTab, bShow );
3266*cdf0e10cSrcweir 		}
3267*cdf0e10cSrcweir 	}
3268*cdf0e10cSrcweir 	pDoc->DecSizeRecalcLevel( nTab );		// nicht fuer jede Spalte einzeln
3269*cdf0e10cSrcweir 
3270*cdf0e10cSrcweir 	if (!bOutline)
3271*cdf0e10cSrcweir 		DELETEZ(pUndoTab);
3272*cdf0e10cSrcweir 
3273*cdf0e10cSrcweir 	if (bRecord)
3274*cdf0e10cSrcweir 	{
3275*cdf0e10cSrcweir 		ScMarkData aMark;
3276*cdf0e10cSrcweir 		aMark.SelectOneTable( nTab );
3277*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
3278*cdf0e10cSrcweir 			new ScUndoWidthOrHeight( &rDocShell, aMark,
3279*cdf0e10cSrcweir 									 nStart, nTab, nEnd, nTab,
3280*cdf0e10cSrcweir 									 pUndoDoc, nRangeCnt, pUndoRanges,
3281*cdf0e10cSrcweir 									 pUndoTab, eMode, nSizeTwips, bWidth ) );
3282*cdf0e10cSrcweir 	}
3283*cdf0e10cSrcweir 
3284*cdf0e10cSrcweir 	pDoc->UpdatePageBreaks( nTab );
3285*cdf0e10cSrcweir 
3286*cdf0e10cSrcweir 	rDocShell.PostPaint(0,0,nTab,MAXCOL,MAXROW,nTab,PAINT_ALL);
3287*cdf0e10cSrcweir     aModificator.SetDocumentModified();
3288*cdf0e10cSrcweir 
3289*cdf0e10cSrcweir 	return bSuccess;
3290*cdf0e10cSrcweir }
3291*cdf0e10cSrcweir 
3292*cdf0e10cSrcweir 
3293*cdf0e10cSrcweir sal_Bool ScDocFunc::InsertPageBreak( sal_Bool bColumn, const ScAddress& rPos,
3294*cdf0e10cSrcweir                                 sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
3295*cdf0e10cSrcweir {
3296*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3297*cdf0e10cSrcweir 
3298*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3299*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
3300*cdf0e10cSrcweir 		bRecord = sal_False;
3301*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
3302*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
3303*cdf0e10cSrcweir 
3304*cdf0e10cSrcweir     SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3305*cdf0e10cSrcweir         static_cast<SCCOLROW>(rPos.Row());
3306*cdf0e10cSrcweir 	if (nPos == 0)
3307*cdf0e10cSrcweir 		return sal_False;					// erste Spalte / Zeile
3308*cdf0e10cSrcweir 
3309*cdf0e10cSrcweir     ScBreakType nBreak = bColumn ?
3310*cdf0e10cSrcweir         pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) :
3311*cdf0e10cSrcweir         pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
3312*cdf0e10cSrcweir     if (nBreak & BREAK_MANUAL)
3313*cdf0e10cSrcweir         return true;
3314*cdf0e10cSrcweir 
3315*cdf0e10cSrcweir 	if (bRecord)
3316*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
3317*cdf0e10cSrcweir 			new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, sal_True ) );
3318*cdf0e10cSrcweir 
3319*cdf0e10cSrcweir     if (bColumn)
3320*cdf0e10cSrcweir         pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3321*cdf0e10cSrcweir     else
3322*cdf0e10cSrcweir         pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3323*cdf0e10cSrcweir 
3324*cdf0e10cSrcweir     pDoc->InvalidatePageBreaks(nTab);
3325*cdf0e10cSrcweir 	pDoc->UpdatePageBreaks( nTab );
3326*cdf0e10cSrcweir 
3327*cdf0e10cSrcweir     if (pDoc->IsStreamValid(nTab))
3328*cdf0e10cSrcweir         pDoc->SetStreamValid(nTab, sal_False);
3329*cdf0e10cSrcweir 
3330*cdf0e10cSrcweir 	if (bColumn)
3331*cdf0e10cSrcweir 	{
3332*cdf0e10cSrcweir 		rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3333*cdf0e10cSrcweir 		if (pBindings)
3334*cdf0e10cSrcweir 		{
3335*cdf0e10cSrcweir 			pBindings->Invalidate( FID_INS_COLBRK );
3336*cdf0e10cSrcweir 			pBindings->Invalidate( FID_DEL_COLBRK );
3337*cdf0e10cSrcweir 		}
3338*cdf0e10cSrcweir 	}
3339*cdf0e10cSrcweir 	else
3340*cdf0e10cSrcweir 	{
3341*cdf0e10cSrcweir 		rDocShell.PostPaint( 0, static_cast<SCROW>(nPos)-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3342*cdf0e10cSrcweir 		if (pBindings)
3343*cdf0e10cSrcweir 		{
3344*cdf0e10cSrcweir 			pBindings->Invalidate( FID_INS_ROWBRK );
3345*cdf0e10cSrcweir 			pBindings->Invalidate( FID_DEL_ROWBRK );
3346*cdf0e10cSrcweir 		}
3347*cdf0e10cSrcweir 	}
3348*cdf0e10cSrcweir 	if (pBindings)
3349*cdf0e10cSrcweir 		pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3350*cdf0e10cSrcweir 
3351*cdf0e10cSrcweir 	if (bSetModified)
3352*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
3353*cdf0e10cSrcweir 
3354*cdf0e10cSrcweir 	return sal_True;
3355*cdf0e10cSrcweir }
3356*cdf0e10cSrcweir 
3357*cdf0e10cSrcweir sal_Bool ScDocFunc::RemovePageBreak( sal_Bool bColumn, const ScAddress& rPos,
3358*cdf0e10cSrcweir                                 sal_Bool bRecord, sal_Bool bSetModified, sal_Bool /* bApi */ )
3359*cdf0e10cSrcweir {
3360*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3361*cdf0e10cSrcweir 
3362*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3363*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
3364*cdf0e10cSrcweir 		bRecord = sal_False;
3365*cdf0e10cSrcweir 	SCTAB nTab = rPos.Tab();
3366*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
3367*cdf0e10cSrcweir 
3368*cdf0e10cSrcweir     SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) :
3369*cdf0e10cSrcweir         static_cast<SCCOLROW>(rPos.Row());
3370*cdf0e10cSrcweir 
3371*cdf0e10cSrcweir     ScBreakType nBreak;
3372*cdf0e10cSrcweir     if (bColumn)
3373*cdf0e10cSrcweir         nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab);
3374*cdf0e10cSrcweir     else
3375*cdf0e10cSrcweir         nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab);
3376*cdf0e10cSrcweir     if ((nBreak & BREAK_MANUAL) == 0)
3377*cdf0e10cSrcweir         // There is no manual break.
3378*cdf0e10cSrcweir         return false;
3379*cdf0e10cSrcweir 
3380*cdf0e10cSrcweir 	if (bRecord)
3381*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
3382*cdf0e10cSrcweir 			new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, sal_False ) );
3383*cdf0e10cSrcweir 
3384*cdf0e10cSrcweir     if (bColumn)
3385*cdf0e10cSrcweir         pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true);
3386*cdf0e10cSrcweir     else
3387*cdf0e10cSrcweir         pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true);
3388*cdf0e10cSrcweir 
3389*cdf0e10cSrcweir 	pDoc->UpdatePageBreaks( nTab );
3390*cdf0e10cSrcweir 
3391*cdf0e10cSrcweir     if (pDoc->IsStreamValid(nTab))
3392*cdf0e10cSrcweir         pDoc->SetStreamValid(nTab, sal_False);
3393*cdf0e10cSrcweir 
3394*cdf0e10cSrcweir 	if (bColumn)
3395*cdf0e10cSrcweir 	{
3396*cdf0e10cSrcweir 		rDocShell.PostPaint( static_cast<SCCOL>(nPos)-1, 0, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3397*cdf0e10cSrcweir 		if (pBindings)
3398*cdf0e10cSrcweir 		{
3399*cdf0e10cSrcweir 			pBindings->Invalidate( FID_INS_COLBRK );
3400*cdf0e10cSrcweir 			pBindings->Invalidate( FID_DEL_COLBRK );
3401*cdf0e10cSrcweir 		}
3402*cdf0e10cSrcweir 	}
3403*cdf0e10cSrcweir 	else
3404*cdf0e10cSrcweir 	{
3405*cdf0e10cSrcweir 		rDocShell.PostPaint( 0, nPos-1, nTab, MAXCOL, MAXROW, nTab, PAINT_GRID );
3406*cdf0e10cSrcweir 		if (pBindings)
3407*cdf0e10cSrcweir 		{
3408*cdf0e10cSrcweir 			pBindings->Invalidate( FID_INS_ROWBRK );
3409*cdf0e10cSrcweir 			pBindings->Invalidate( FID_DEL_ROWBRK );
3410*cdf0e10cSrcweir 		}
3411*cdf0e10cSrcweir 	}
3412*cdf0e10cSrcweir 	if (pBindings)
3413*cdf0e10cSrcweir 		pBindings->Invalidate( FID_DEL_MANUALBREAKS );
3414*cdf0e10cSrcweir 
3415*cdf0e10cSrcweir 	if (bSetModified)
3416*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
3417*cdf0e10cSrcweir 
3418*cdf0e10cSrcweir 	return sal_True;
3419*cdf0e10cSrcweir }
3420*cdf0e10cSrcweir 
3421*cdf0e10cSrcweir //------------------------------------------------------------------------
3422*cdf0e10cSrcweir 
3423*cdf0e10cSrcweir void ScDocFunc::ProtectSheet( SCTAB nTab, const ScTableProtection& rProtect )
3424*cdf0e10cSrcweir {
3425*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
3426*cdf0e10cSrcweir 
3427*cdf0e10cSrcweir     pDoc->SetTabProtection(nTab, &rProtect);
3428*cdf0e10cSrcweir     if (pDoc->IsUndoEnabled())
3429*cdf0e10cSrcweir     {
3430*cdf0e10cSrcweir         ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
3431*cdf0e10cSrcweir         DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3432*cdf0e10cSrcweir         if (pProtect)
3433*cdf0e10cSrcweir         {
3434*cdf0e10cSrcweir             ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
3435*cdf0e10cSrcweir             p->setProtected(true); // just in case ...
3436*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction(
3437*cdf0e10cSrcweir                 new ScUndoTabProtect(&rDocShell, nTab, p) );
3438*cdf0e10cSrcweir 
3439*cdf0e10cSrcweir             // ownership of auto_ptr now transferred to ScUndoTabProtect.
3440*cdf0e10cSrcweir         }
3441*cdf0e10cSrcweir     }
3442*cdf0e10cSrcweir 
3443*cdf0e10cSrcweir     rDocShell.PostPaintGridAll();
3444*cdf0e10cSrcweir     ScDocShellModificator aModificator(rDocShell);
3445*cdf0e10cSrcweir     aModificator.SetDocumentModified();
3446*cdf0e10cSrcweir }
3447*cdf0e10cSrcweir 
3448*cdf0e10cSrcweir sal_Bool ScDocFunc::Protect( SCTAB nTab, const String& rPassword, sal_Bool /*bApi*/ )
3449*cdf0e10cSrcweir {
3450*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
3451*cdf0e10cSrcweir     if (nTab == TABLEID_DOC)
3452*cdf0e10cSrcweir     {
3453*cdf0e10cSrcweir         // document protection
3454*cdf0e10cSrcweir         ScDocProtection aProtection;
3455*cdf0e10cSrcweir         aProtection.setProtected(true);
3456*cdf0e10cSrcweir         aProtection.setPassword(rPassword);
3457*cdf0e10cSrcweir         pDoc->SetDocProtection(&aProtection);
3458*cdf0e10cSrcweir         if (pDoc->IsUndoEnabled())
3459*cdf0e10cSrcweir         {
3460*cdf0e10cSrcweir             ScDocProtection* pProtect = pDoc->GetDocProtection();
3461*cdf0e10cSrcweir             DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScDocProtection pointer is NULL!");
3462*cdf0e10cSrcweir             if (pProtect)
3463*cdf0e10cSrcweir             {
3464*cdf0e10cSrcweir                 ::std::auto_ptr<ScDocProtection> p(new ScDocProtection(*pProtect));
3465*cdf0e10cSrcweir                 p->setProtected(true); // just in case ...
3466*cdf0e10cSrcweir                 rDocShell.GetUndoManager()->AddUndoAction(
3467*cdf0e10cSrcweir                     new ScUndoDocProtect(&rDocShell, p) );
3468*cdf0e10cSrcweir                 // ownership of auto_ptr is transferred to ScUndoDocProtect.
3469*cdf0e10cSrcweir             }
3470*cdf0e10cSrcweir         }
3471*cdf0e10cSrcweir     }
3472*cdf0e10cSrcweir     else
3473*cdf0e10cSrcweir     {
3474*cdf0e10cSrcweir         // sheet protection
3475*cdf0e10cSrcweir 
3476*cdf0e10cSrcweir         ScTableProtection aProtection;
3477*cdf0e10cSrcweir         aProtection.setProtected(true);
3478*cdf0e10cSrcweir         aProtection.setPassword(rPassword);
3479*cdf0e10cSrcweir         pDoc->SetTabProtection(nTab, &aProtection);
3480*cdf0e10cSrcweir         if (pDoc->IsUndoEnabled())
3481*cdf0e10cSrcweir         {
3482*cdf0e10cSrcweir             ScTableProtection* pProtect = pDoc->GetTabProtection(nTab);
3483*cdf0e10cSrcweir             DBG_ASSERT(pProtect, "ScDocFunc::Unprotect: ScTableProtection pointer is NULL!");
3484*cdf0e10cSrcweir             if (pProtect)
3485*cdf0e10cSrcweir             {
3486*cdf0e10cSrcweir                 ::std::auto_ptr<ScTableProtection> p(new ScTableProtection(*pProtect));
3487*cdf0e10cSrcweir                 p->setProtected(true); // just in case ...
3488*cdf0e10cSrcweir                 rDocShell.GetUndoManager()->AddUndoAction(
3489*cdf0e10cSrcweir                     new ScUndoTabProtect(&rDocShell, nTab, p) );
3490*cdf0e10cSrcweir                 // ownership of auto_ptr now transferred to ScUndoTabProtect.
3491*cdf0e10cSrcweir             }
3492*cdf0e10cSrcweir         }
3493*cdf0e10cSrcweir     }
3494*cdf0e10cSrcweir 
3495*cdf0e10cSrcweir     rDocShell.PostPaintGridAll();
3496*cdf0e10cSrcweir     ScDocShellModificator aModificator( rDocShell );
3497*cdf0e10cSrcweir     aModificator.SetDocumentModified();
3498*cdf0e10cSrcweir 
3499*cdf0e10cSrcweir     return true;
3500*cdf0e10cSrcweir }
3501*cdf0e10cSrcweir 
3502*cdf0e10cSrcweir sal_Bool ScDocFunc::Unprotect( SCTAB nTab, const String& rPassword, sal_Bool bApi )
3503*cdf0e10cSrcweir {
3504*cdf0e10cSrcweir     ScDocument* pDoc = rDocShell.GetDocument();
3505*cdf0e10cSrcweir 
3506*cdf0e10cSrcweir     if (nTab == TABLEID_DOC)
3507*cdf0e10cSrcweir     {
3508*cdf0e10cSrcweir         // document protection
3509*cdf0e10cSrcweir 
3510*cdf0e10cSrcweir         ScDocProtection* pDocProtect = pDoc->GetDocProtection();
3511*cdf0e10cSrcweir         if (!pDocProtect || !pDocProtect->isProtected())
3512*cdf0e10cSrcweir             // already unprotected (should not happen)!
3513*cdf0e10cSrcweir             return true;
3514*cdf0e10cSrcweir 
3515*cdf0e10cSrcweir         // save the protection state before unprotect (for undo).
3516*cdf0e10cSrcweir         ::std::auto_ptr<ScDocProtection> pProtectCopy(new ScDocProtection(*pDocProtect));
3517*cdf0e10cSrcweir 
3518*cdf0e10cSrcweir         if (!pDocProtect->verifyPassword(rPassword))
3519*cdf0e10cSrcweir         {
3520*cdf0e10cSrcweir             if (!bApi)
3521*cdf0e10cSrcweir             {
3522*cdf0e10cSrcweir                 InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
3523*cdf0e10cSrcweir                 aBox.Execute();
3524*cdf0e10cSrcweir             }
3525*cdf0e10cSrcweir             return false;
3526*cdf0e10cSrcweir         }
3527*cdf0e10cSrcweir 
3528*cdf0e10cSrcweir         pDoc->SetDocProtection(NULL);
3529*cdf0e10cSrcweir         if (pDoc->IsUndoEnabled())
3530*cdf0e10cSrcweir         {
3531*cdf0e10cSrcweir             pProtectCopy->setProtected(false);
3532*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction(
3533*cdf0e10cSrcweir                 new ScUndoDocProtect(&rDocShell, pProtectCopy) );
3534*cdf0e10cSrcweir             // ownership of auto_ptr now transferred to ScUndoDocProtect.
3535*cdf0e10cSrcweir         }
3536*cdf0e10cSrcweir     }
3537*cdf0e10cSrcweir     else
3538*cdf0e10cSrcweir     {
3539*cdf0e10cSrcweir         // sheet protection
3540*cdf0e10cSrcweir 
3541*cdf0e10cSrcweir         ScTableProtection* pTabProtect = pDoc->GetTabProtection(nTab);
3542*cdf0e10cSrcweir         if (!pTabProtect || !pTabProtect->isProtected())
3543*cdf0e10cSrcweir             // already unprotected (should not happen)!
3544*cdf0e10cSrcweir             return true;
3545*cdf0e10cSrcweir 
3546*cdf0e10cSrcweir         // save the protection state before unprotect (for undo).
3547*cdf0e10cSrcweir         ::std::auto_ptr<ScTableProtection> pProtectCopy(new ScTableProtection(*pTabProtect));
3548*cdf0e10cSrcweir         if (!pTabProtect->verifyPassword(rPassword))
3549*cdf0e10cSrcweir         {
3550*cdf0e10cSrcweir             if (!bApi)
3551*cdf0e10cSrcweir             {
3552*cdf0e10cSrcweir                 InfoBox aBox( rDocShell.GetActiveDialogParent(), String( ScResId( SCSTR_WRONGPASSWORD ) ) );
3553*cdf0e10cSrcweir                 aBox.Execute();
3554*cdf0e10cSrcweir             }
3555*cdf0e10cSrcweir             return false;
3556*cdf0e10cSrcweir         }
3557*cdf0e10cSrcweir 
3558*cdf0e10cSrcweir         pDoc->SetTabProtection(nTab, NULL);
3559*cdf0e10cSrcweir         if (pDoc->IsUndoEnabled())
3560*cdf0e10cSrcweir         {
3561*cdf0e10cSrcweir             pProtectCopy->setProtected(false);
3562*cdf0e10cSrcweir             rDocShell.GetUndoManager()->AddUndoAction(
3563*cdf0e10cSrcweir                 new ScUndoTabProtect(&rDocShell, nTab, pProtectCopy) );
3564*cdf0e10cSrcweir             // ownership of auto_ptr now transferred to ScUndoTabProtect.
3565*cdf0e10cSrcweir         }
3566*cdf0e10cSrcweir     }
3567*cdf0e10cSrcweir 
3568*cdf0e10cSrcweir     rDocShell.PostPaintGridAll();
3569*cdf0e10cSrcweir     ScDocShellModificator aModificator( rDocShell );
3570*cdf0e10cSrcweir     aModificator.SetDocumentModified();
3571*cdf0e10cSrcweir 
3572*cdf0e10cSrcweir     return true;
3573*cdf0e10cSrcweir }
3574*cdf0e10cSrcweir 
3575*cdf0e10cSrcweir //------------------------------------------------------------------------
3576*cdf0e10cSrcweir 
3577*cdf0e10cSrcweir sal_Bool ScDocFunc::ClearItems( const ScMarkData& rMark, const sal_uInt16* pWhich, sal_Bool bApi )
3578*cdf0e10cSrcweir {
3579*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3580*cdf0e10cSrcweir 
3581*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3582*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
3583*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rMark );
3584*cdf0e10cSrcweir 	if (!aTester.IsEditable())
3585*cdf0e10cSrcweir 	{
3586*cdf0e10cSrcweir 		if (!bApi)
3587*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
3588*cdf0e10cSrcweir 		return sal_False;
3589*cdf0e10cSrcweir 	}
3590*cdf0e10cSrcweir 
3591*cdf0e10cSrcweir 	//	#i12940# ClearItems is called (from setPropertyToDefault) directly with uno object's cached
3592*cdf0e10cSrcweir 	//	MarkData (GetMarkData), so rMark must be changed to multi selection for ClearSelectionItems
3593*cdf0e10cSrcweir 	//	here.
3594*cdf0e10cSrcweir 
3595*cdf0e10cSrcweir 	ScRange aMarkRange;
3596*cdf0e10cSrcweir 	ScMarkData aMultiMark = rMark;
3597*cdf0e10cSrcweir 	aMultiMark.SetMarking(sal_False);		// for MarkToMulti
3598*cdf0e10cSrcweir 	aMultiMark.MarkToMulti();
3599*cdf0e10cSrcweir 	aMultiMark.GetMultiMarkArea( aMarkRange );
3600*cdf0e10cSrcweir 
3601*cdf0e10cSrcweir //	if (bRecord)
3602*cdf0e10cSrcweir 	if (bUndo)
3603*cdf0e10cSrcweir 	{
3604*cdf0e10cSrcweir 		SCTAB nStartTab = aMarkRange.aStart.Tab();
3605*cdf0e10cSrcweir 		SCTAB nEndTab = aMarkRange.aEnd.Tab();
3606*cdf0e10cSrcweir 
3607*cdf0e10cSrcweir 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3608*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
3609*cdf0e10cSrcweir 		pDoc->CopyToDocument( aMarkRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&aMultiMark );
3610*cdf0e10cSrcweir 
3611*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
3612*cdf0e10cSrcweir 			new ScUndoClearItems( &rDocShell, aMultiMark, pUndoDoc, pWhich ) );
3613*cdf0e10cSrcweir 	}
3614*cdf0e10cSrcweir 
3615*cdf0e10cSrcweir 	pDoc->ClearSelectionItems( pWhich, aMultiMark );
3616*cdf0e10cSrcweir 
3617*cdf0e10cSrcweir 	rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3618*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
3619*cdf0e10cSrcweir 
3620*cdf0e10cSrcweir 	//!	Bindings-Invalidate etc.?
3621*cdf0e10cSrcweir 
3622*cdf0e10cSrcweir 	return sal_True;
3623*cdf0e10cSrcweir }
3624*cdf0e10cSrcweir 
3625*cdf0e10cSrcweir sal_Bool ScDocFunc::ChangeIndent( const ScMarkData& rMark, sal_Bool bIncrement, sal_Bool bApi )
3626*cdf0e10cSrcweir {
3627*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3628*cdf0e10cSrcweir 
3629*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3630*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
3631*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, rMark );
3632*cdf0e10cSrcweir 	if (!aTester.IsEditable())
3633*cdf0e10cSrcweir 	{
3634*cdf0e10cSrcweir 		if (!bApi)
3635*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
3636*cdf0e10cSrcweir 		return sal_False;
3637*cdf0e10cSrcweir 	}
3638*cdf0e10cSrcweir 
3639*cdf0e10cSrcweir 	ScRange aMarkRange;
3640*cdf0e10cSrcweir 	rMark.GetMultiMarkArea( aMarkRange );
3641*cdf0e10cSrcweir 
3642*cdf0e10cSrcweir //	if (bRecord)
3643*cdf0e10cSrcweir 	if (bUndo)
3644*cdf0e10cSrcweir 	{
3645*cdf0e10cSrcweir 		SCTAB nStartTab = aMarkRange.aStart.Tab();
3646*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
3647*cdf0e10cSrcweir 
3648*cdf0e10cSrcweir 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3649*cdf0e10cSrcweir 		pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab );
3650*cdf0e10cSrcweir 		for (SCTAB i=0; i<nTabCount; i++)
3651*cdf0e10cSrcweir 			if (i != nStartTab && rMark.GetTableSelect(i))
3652*cdf0e10cSrcweir 				pUndoDoc->AddUndoTab( i, i );
3653*cdf0e10cSrcweir 
3654*cdf0e10cSrcweir 		ScRange aCopyRange = aMarkRange;
3655*cdf0e10cSrcweir 		aCopyRange.aStart.SetTab(0);
3656*cdf0e10cSrcweir 		aCopyRange.aEnd.SetTab(nTabCount-1);
3657*cdf0e10cSrcweir 		pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_True, pUndoDoc, (ScMarkData*)&rMark );
3658*cdf0e10cSrcweir 
3659*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
3660*cdf0e10cSrcweir 			new ScUndoIndent( &rDocShell, rMark, pUndoDoc, bIncrement ) );
3661*cdf0e10cSrcweir 	}
3662*cdf0e10cSrcweir 
3663*cdf0e10cSrcweir 	pDoc->ChangeSelectionIndent( bIncrement, rMark );
3664*cdf0e10cSrcweir 
3665*cdf0e10cSrcweir 	rDocShell.PostPaint( aMarkRange, PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3666*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
3667*cdf0e10cSrcweir 
3668*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
3669*cdf0e10cSrcweir 	if (pBindings)
3670*cdf0e10cSrcweir 	{
3671*cdf0e10cSrcweir 		pBindings->Invalidate( SID_ALIGNLEFT );			// ChangeIndent setzt auf links
3672*cdf0e10cSrcweir 		pBindings->Invalidate( SID_ALIGNRIGHT );
3673*cdf0e10cSrcweir 		pBindings->Invalidate( SID_ALIGNBLOCK );
3674*cdf0e10cSrcweir 		pBindings->Invalidate( SID_ALIGNCENTERHOR );
3675*cdf0e10cSrcweir         // pseudo slots for Format menu
3676*cdf0e10cSrcweir         pBindings->Invalidate( SID_ALIGN_ANY_HDEFAULT );
3677*cdf0e10cSrcweir         pBindings->Invalidate( SID_ALIGN_ANY_LEFT );
3678*cdf0e10cSrcweir         pBindings->Invalidate( SID_ALIGN_ANY_HCENTER );
3679*cdf0e10cSrcweir         pBindings->Invalidate( SID_ALIGN_ANY_RIGHT );
3680*cdf0e10cSrcweir         pBindings->Invalidate( SID_ALIGN_ANY_JUSTIFIED );
3681*cdf0e10cSrcweir 	}
3682*cdf0e10cSrcweir 
3683*cdf0e10cSrcweir 	return sal_True;
3684*cdf0e10cSrcweir }
3685*cdf0e10cSrcweir 
3686*cdf0e10cSrcweir sal_Bool ScDocFunc::AutoFormat( const ScRange& rRange, const ScMarkData* pTabMark,
3687*cdf0e10cSrcweir 							sal_uInt16 nFormatNo, sal_Bool bRecord, sal_Bool bApi )
3688*cdf0e10cSrcweir {
3689*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3690*cdf0e10cSrcweir 
3691*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3692*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3693*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
3694*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
3695*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
3696*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
3697*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
3698*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
3699*cdf0e10cSrcweir 
3700*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
3701*cdf0e10cSrcweir 		bRecord = sal_False;
3702*cdf0e10cSrcweir 	ScMarkData aMark;
3703*cdf0e10cSrcweir 	if (pTabMark)
3704*cdf0e10cSrcweir 		aMark = *pTabMark;
3705*cdf0e10cSrcweir 	else
3706*cdf0e10cSrcweir 	{
3707*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
3708*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
3709*cdf0e10cSrcweir 	}
3710*cdf0e10cSrcweir 
3711*cdf0e10cSrcweir 	ScAutoFormat* pAutoFormat = ScGlobal::GetAutoFormat();
3712*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
3713*cdf0e10cSrcweir 	if ( pAutoFormat && nFormatNo < pAutoFormat->GetCount() && aTester.IsEditable() )
3714*cdf0e10cSrcweir 	{
3715*cdf0e10cSrcweir 		WaitObject aWait( rDocShell.GetActiveDialogParent() );
3716*cdf0e10cSrcweir 
3717*cdf0e10cSrcweir 		sal_Bool bSize = (*pAutoFormat)[nFormatNo]->GetIncludeWidthHeight();
3718*cdf0e10cSrcweir 
3719*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
3720*cdf0e10cSrcweir 		ScDocument* pUndoDoc = NULL;
3721*cdf0e10cSrcweir 		if ( bRecord )
3722*cdf0e10cSrcweir 		{
3723*cdf0e10cSrcweir 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3724*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nStartTab, nStartTab, bSize, bSize );
3725*cdf0e10cSrcweir 			for (SCTAB i=0; i<nTabCount; i++)
3726*cdf0e10cSrcweir 				if (i != nStartTab && aMark.GetTableSelect(i))
3727*cdf0e10cSrcweir 					pUndoDoc->AddUndoTab( i, i, bSize, bSize );
3728*cdf0e10cSrcweir 
3729*cdf0e10cSrcweir 			ScRange aCopyRange = rRange;
3730*cdf0e10cSrcweir 			aCopyRange.aStart.SetTab(0);
3731*cdf0e10cSrcweir 			aCopyRange.aStart.SetTab(nTabCount-1);
3732*cdf0e10cSrcweir 			pDoc->CopyToDocument( aCopyRange, IDF_ATTRIB, sal_False, pUndoDoc, &aMark );
3733*cdf0e10cSrcweir 			if (bSize)
3734*cdf0e10cSrcweir 			{
3735*cdf0e10cSrcweir 				pDoc->CopyToDocument( nStartCol,0,0, nEndCol,MAXROW,nTabCount-1,
3736*cdf0e10cSrcweir 															IDF_NONE, sal_False, pUndoDoc, &aMark );
3737*cdf0e10cSrcweir 				pDoc->CopyToDocument( 0,nStartRow,0, MAXCOL,nEndRow,nTabCount-1,
3738*cdf0e10cSrcweir 															IDF_NONE, sal_False, pUndoDoc, &aMark );
3739*cdf0e10cSrcweir 			}
3740*cdf0e10cSrcweir 			pDoc->BeginDrawUndo();
3741*cdf0e10cSrcweir 		}
3742*cdf0e10cSrcweir 
3743*cdf0e10cSrcweir 		pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, aMark );
3744*cdf0e10cSrcweir 
3745*cdf0e10cSrcweir 		if (bSize)
3746*cdf0e10cSrcweir 		{
3747*cdf0e10cSrcweir /*			SCCOL nCols[2];
3748*cdf0e10cSrcweir 			nCols[0] = nStartCol;
3749*cdf0e10cSrcweir 			nCols[1] = nEndCol;
3750*cdf0e10cSrcweir 			SCROW nRows[2];
3751*cdf0e10cSrcweir 			nRows[0] = nStartRow;
3752*cdf0e10cSrcweir 			nRows[1] = nEndRow;
3753*cdf0e10cSrcweir */
3754*cdf0e10cSrcweir 			SCCOLROW nCols[2] = { nStartCol, nEndCol };
3755*cdf0e10cSrcweir 			SCCOLROW nRows[2] = { nStartRow, nEndRow };
3756*cdf0e10cSrcweir 
3757*cdf0e10cSrcweir 			for (SCTAB nTab=0; nTab<nTabCount; nTab++)
3758*cdf0e10cSrcweir 				if (aMark.GetTableSelect(nTab))
3759*cdf0e10cSrcweir 				{
3760*cdf0e10cSrcweir                     SetWidthOrHeight( sal_True, 1,nCols, nTab, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_True);
3761*cdf0e10cSrcweir                     SetWidthOrHeight( sal_False,1,nRows, nTab, SC_SIZE_VISOPT, 0, sal_False, sal_False);
3762*cdf0e10cSrcweir 					rDocShell.PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab,
3763*cdf0e10cSrcweir 									PAINT_GRID | PAINT_LEFT | PAINT_TOP );
3764*cdf0e10cSrcweir 				}
3765*cdf0e10cSrcweir 		}
3766*cdf0e10cSrcweir 		else
3767*cdf0e10cSrcweir 		{
3768*cdf0e10cSrcweir 			for (SCTAB nTab=0; nTab<nTabCount; nTab++)
3769*cdf0e10cSrcweir 				if (aMark.GetTableSelect(nTab))
3770*cdf0e10cSrcweir 				{
3771*cdf0e10cSrcweir 					sal_Bool bAdj = AdjustRowHeight( ScRange(nStartCol, nStartRow, nTab,
3772*cdf0e10cSrcweir 														nEndCol, nEndRow, nTab), sal_False );
3773*cdf0e10cSrcweir 					if (bAdj)
3774*cdf0e10cSrcweir 						rDocShell.PostPaint( 0,nStartRow,nTab, MAXCOL,MAXROW,nTab,
3775*cdf0e10cSrcweir 											PAINT_GRID | PAINT_LEFT );
3776*cdf0e10cSrcweir 					else
3777*cdf0e10cSrcweir 						rDocShell.PostPaint( nStartCol, nStartRow, nTab,
3778*cdf0e10cSrcweir 											nEndCol, nEndRow, nTab, PAINT_GRID );
3779*cdf0e10cSrcweir 				}
3780*cdf0e10cSrcweir 		}
3781*cdf0e10cSrcweir 
3782*cdf0e10cSrcweir 		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
3783*cdf0e10cSrcweir 		{
3784*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
3785*cdf0e10cSrcweir 				new ScUndoAutoFormat( &rDocShell, rRange, pUndoDoc, aMark, bSize, nFormatNo ) );
3786*cdf0e10cSrcweir 		}
3787*cdf0e10cSrcweir 
3788*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
3789*cdf0e10cSrcweir 	}
3790*cdf0e10cSrcweir 	else if (!bApi)
3791*cdf0e10cSrcweir 		rDocShell.ErrorMessage(aTester.GetMessageId());
3792*cdf0e10cSrcweir 
3793*cdf0e10cSrcweir 	return bSuccess;
3794*cdf0e10cSrcweir }
3795*cdf0e10cSrcweir 
3796*cdf0e10cSrcweir //------------------------------------------------------------------------
3797*cdf0e10cSrcweir 
3798*cdf0e10cSrcweir sal_Bool ScDocFunc::EnterMatrix( const ScRange& rRange, const ScMarkData* pTabMark,
3799*cdf0e10cSrcweir         const ScTokenArray* pTokenArray, const String& rString, sal_Bool bApi, sal_Bool bEnglish,
3800*cdf0e10cSrcweir         const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
3801*cdf0e10cSrcweir {
3802*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3803*cdf0e10cSrcweir 
3804*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3805*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3806*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
3807*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
3808*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
3809*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
3810*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
3811*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
3812*cdf0e10cSrcweir 
3813*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
3814*cdf0e10cSrcweir 
3815*cdf0e10cSrcweir 	ScMarkData aMark;
3816*cdf0e10cSrcweir 	if (pTabMark)
3817*cdf0e10cSrcweir 		aMark = *pTabMark;
3818*cdf0e10cSrcweir 	else
3819*cdf0e10cSrcweir 	{
3820*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
3821*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
3822*cdf0e10cSrcweir 	}
3823*cdf0e10cSrcweir 
3824*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
3825*cdf0e10cSrcweir 	if ( aTester.IsEditable() )
3826*cdf0e10cSrcweir 	{
3827*cdf0e10cSrcweir 		WaitObject aWait( rDocShell.GetActiveDialogParent() );
3828*cdf0e10cSrcweir 
3829*cdf0e10cSrcweir         ScDocument* pUndoDoc = NULL;
3830*cdf0e10cSrcweir //		if (bRecord)	// immer
3831*cdf0e10cSrcweir 		if (bUndo)
3832*cdf0e10cSrcweir 		{
3833*cdf0e10cSrcweir 			//!	auch bei Undo selektierte Tabellen beruecksichtigen
3834*cdf0e10cSrcweir 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3835*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
3836*cdf0e10cSrcweir             pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );
3837*cdf0e10cSrcweir 		}
3838*cdf0e10cSrcweir 
3839*cdf0e10cSrcweir         // use TokenArray if given, string (and flags) otherwise
3840*cdf0e10cSrcweir         if ( pTokenArray )
3841*cdf0e10cSrcweir         {
3842*cdf0e10cSrcweir             pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
3843*cdf0e10cSrcweir                     aMark, EMPTY_STRING, pTokenArray, eGrammar);
3844*cdf0e10cSrcweir         }
3845*cdf0e10cSrcweir         else if ( pDoc->IsImportingXML() )
3846*cdf0e10cSrcweir 		{
3847*cdf0e10cSrcweir             ScTokenArray* pCode = lcl_ScDocFunc_CreateTokenArrayXML( rString, rFormulaNmsp, eGrammar );
3848*cdf0e10cSrcweir             pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
3849*cdf0e10cSrcweir                     aMark, EMPTY_STRING, pCode, eGrammar);
3850*cdf0e10cSrcweir 			delete pCode;
3851*cdf0e10cSrcweir             pDoc->IncXMLImportedFormulaCount( rString.Len() );
3852*cdf0e10cSrcweir 		}
3853*cdf0e10cSrcweir 		else if (bEnglish)
3854*cdf0e10cSrcweir         {
3855*cdf0e10cSrcweir 			ScCompiler aComp( pDoc, rRange.aStart);
3856*cdf0e10cSrcweir             aComp.SetGrammar(eGrammar);
3857*cdf0e10cSrcweir 			ScTokenArray* pCode = aComp.CompileString( rString );
3858*cdf0e10cSrcweir             pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
3859*cdf0e10cSrcweir                     aMark, EMPTY_STRING, pCode, eGrammar);
3860*cdf0e10cSrcweir 			delete pCode;
3861*cdf0e10cSrcweir         }
3862*cdf0e10cSrcweir         else
3863*cdf0e10cSrcweir             pDoc->InsertMatrixFormula( nStartCol, nStartRow, nEndCol, nEndRow,
3864*cdf0e10cSrcweir                     aMark, rString, NULL, eGrammar);
3865*cdf0e10cSrcweir 
3866*cdf0e10cSrcweir //		if (bRecord)	// immer
3867*cdf0e10cSrcweir 		if (bUndo)
3868*cdf0e10cSrcweir 		{
3869*cdf0e10cSrcweir 			//!	auch bei Undo selektierte Tabellen beruecksichtigen
3870*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
3871*cdf0e10cSrcweir 				new ScUndoEnterMatrix( &rDocShell, rRange, pUndoDoc, rString ) );
3872*cdf0e10cSrcweir 		}
3873*cdf0e10cSrcweir 
3874*cdf0e10cSrcweir 		//	Err522 beim Paint von DDE-Formeln werden jetzt beim Interpretieren abgefangen
3875*cdf0e10cSrcweir 		rDocShell.PostPaint( nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab, PAINT_GRID );
3876*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
3877*cdf0e10cSrcweir 
3878*cdf0e10cSrcweir 		bSuccess = sal_True;
3879*cdf0e10cSrcweir 	}
3880*cdf0e10cSrcweir 	else if (!bApi)
3881*cdf0e10cSrcweir 		rDocShell.ErrorMessage(aTester.GetMessageId());
3882*cdf0e10cSrcweir 
3883*cdf0e10cSrcweir 	return bSuccess;
3884*cdf0e10cSrcweir }
3885*cdf0e10cSrcweir 
3886*cdf0e10cSrcweir //------------------------------------------------------------------------
3887*cdf0e10cSrcweir 
3888*cdf0e10cSrcweir sal_Bool ScDocFunc::TabOp( const ScRange& rRange, const ScMarkData* pTabMark,
3889*cdf0e10cSrcweir 							const ScTabOpParam& rParam, sal_Bool bRecord, sal_Bool bApi )
3890*cdf0e10cSrcweir {
3891*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3892*cdf0e10cSrcweir 
3893*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3894*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3895*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
3896*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
3897*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
3898*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
3899*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
3900*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
3901*cdf0e10cSrcweir 
3902*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
3903*cdf0e10cSrcweir 		bRecord = sal_False;
3904*cdf0e10cSrcweir 
3905*cdf0e10cSrcweir 	ScMarkData aMark;
3906*cdf0e10cSrcweir 	if (pTabMark)
3907*cdf0e10cSrcweir 		aMark = *pTabMark;
3908*cdf0e10cSrcweir 	else
3909*cdf0e10cSrcweir 	{
3910*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
3911*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
3912*cdf0e10cSrcweir 	}
3913*cdf0e10cSrcweir 
3914*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
3915*cdf0e10cSrcweir 	if ( aTester.IsEditable() )
3916*cdf0e10cSrcweir 	{
3917*cdf0e10cSrcweir 		WaitObject aWait( rDocShell.GetActiveDialogParent() );
3918*cdf0e10cSrcweir 		pDoc->SetDirty( rRange );
3919*cdf0e10cSrcweir 		if ( bRecord )
3920*cdf0e10cSrcweir 		{
3921*cdf0e10cSrcweir 			//!	auch bei Undo selektierte Tabellen beruecksichtigen
3922*cdf0e10cSrcweir 			ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
3923*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
3924*cdf0e10cSrcweir             pDoc->CopyToDocument( rRange, IDF_ALL & ~IDF_NOTE, sal_False, pUndoDoc );
3925*cdf0e10cSrcweir 
3926*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
3927*cdf0e10cSrcweir 					new ScUndoTabOp( &rDocShell,
3928*cdf0e10cSrcweir 									 nStartCol, nStartRow, nStartTab,
3929*cdf0e10cSrcweir 									 nEndCol, nEndRow, nEndTab, pUndoDoc,
3930*cdf0e10cSrcweir 									 rParam.aRefFormulaCell,
3931*cdf0e10cSrcweir 									 rParam.aRefFormulaEnd,
3932*cdf0e10cSrcweir 									 rParam.aRefRowCell,
3933*cdf0e10cSrcweir 									 rParam.aRefColCell,
3934*cdf0e10cSrcweir 									 rParam.nMode) );
3935*cdf0e10cSrcweir 		}
3936*cdf0e10cSrcweir 		pDoc->InsertTableOp(rParam, nStartCol, nStartRow, nEndCol, nEndRow, aMark);
3937*cdf0e10cSrcweir 		rDocShell.PostPaintGridAll();
3938*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
3939*cdf0e10cSrcweir 		bSuccess = sal_True;
3940*cdf0e10cSrcweir 	}
3941*cdf0e10cSrcweir 	else if (!bApi)
3942*cdf0e10cSrcweir 		rDocShell.ErrorMessage(aTester.GetMessageId());
3943*cdf0e10cSrcweir 
3944*cdf0e10cSrcweir 	return bSuccess;
3945*cdf0e10cSrcweir }
3946*cdf0e10cSrcweir 
3947*cdf0e10cSrcweir //------------------------------------------------------------------------
3948*cdf0e10cSrcweir 
3949*cdf0e10cSrcweir inline ScDirection DirFromFillDir( FillDir eDir )
3950*cdf0e10cSrcweir {
3951*cdf0e10cSrcweir 	if (eDir==FILL_TO_BOTTOM)
3952*cdf0e10cSrcweir 		return DIR_BOTTOM;
3953*cdf0e10cSrcweir 	else if (eDir==FILL_TO_RIGHT)
3954*cdf0e10cSrcweir 		return DIR_RIGHT;
3955*cdf0e10cSrcweir 	else if (eDir==FILL_TO_TOP)
3956*cdf0e10cSrcweir 		return DIR_TOP;
3957*cdf0e10cSrcweir 	else // if (eDir==FILL_TO_LEFT)
3958*cdf0e10cSrcweir 		return DIR_LEFT;
3959*cdf0e10cSrcweir }
3960*cdf0e10cSrcweir 
3961*cdf0e10cSrcweir sal_Bool ScDocFunc::FillSimple( const ScRange& rRange, const ScMarkData* pTabMark,
3962*cdf0e10cSrcweir 							FillDir eDir, sal_Bool bRecord, sal_Bool bApi )
3963*cdf0e10cSrcweir {
3964*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
3965*cdf0e10cSrcweir 
3966*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
3967*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
3968*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
3969*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
3970*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
3971*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
3972*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
3973*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
3974*cdf0e10cSrcweir 
3975*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
3976*cdf0e10cSrcweir 		bRecord = sal_False;
3977*cdf0e10cSrcweir 
3978*cdf0e10cSrcweir 	ScMarkData aMark;
3979*cdf0e10cSrcweir 	if (pTabMark)
3980*cdf0e10cSrcweir 		aMark = *pTabMark;
3981*cdf0e10cSrcweir 	else
3982*cdf0e10cSrcweir 	{
3983*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
3984*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
3985*cdf0e10cSrcweir 	}
3986*cdf0e10cSrcweir 
3987*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
3988*cdf0e10cSrcweir 	if ( aTester.IsEditable() )
3989*cdf0e10cSrcweir 	{
3990*cdf0e10cSrcweir 		WaitObject aWait( rDocShell.GetActiveDialogParent() );
3991*cdf0e10cSrcweir 
3992*cdf0e10cSrcweir 		ScRange aSourceArea = rRange;
3993*cdf0e10cSrcweir 		ScRange aDestArea   = rRange;
3994*cdf0e10cSrcweir 
3995*cdf0e10cSrcweir         SCCOLROW nCount = 0;
3996*cdf0e10cSrcweir 		switch (eDir)
3997*cdf0e10cSrcweir 		{
3998*cdf0e10cSrcweir 			case FILL_TO_BOTTOM:
3999*cdf0e10cSrcweir 				nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4000*cdf0e10cSrcweir 				aSourceArea.aEnd.SetRow( aSourceArea.aStart.Row() );
4001*cdf0e10cSrcweir 				break;
4002*cdf0e10cSrcweir 			case FILL_TO_RIGHT:
4003*cdf0e10cSrcweir 				nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4004*cdf0e10cSrcweir 				aSourceArea.aEnd.SetCol( aSourceArea.aStart.Col() );
4005*cdf0e10cSrcweir 				break;
4006*cdf0e10cSrcweir 			case FILL_TO_TOP:
4007*cdf0e10cSrcweir 				nCount = aSourceArea.aEnd.Row()-aSourceArea.aStart.Row();
4008*cdf0e10cSrcweir 				aSourceArea.aStart.SetRow( aSourceArea.aEnd.Row() );
4009*cdf0e10cSrcweir 				break;
4010*cdf0e10cSrcweir 			case FILL_TO_LEFT:
4011*cdf0e10cSrcweir 				nCount = aSourceArea.aEnd.Col()-aSourceArea.aStart.Col();
4012*cdf0e10cSrcweir 				aSourceArea.aStart.SetCol( aSourceArea.aEnd.Col() );
4013*cdf0e10cSrcweir 				break;
4014*cdf0e10cSrcweir 		}
4015*cdf0e10cSrcweir 
4016*cdf0e10cSrcweir 		ScDocument* pUndoDoc = NULL;
4017*cdf0e10cSrcweir 		if ( bRecord )
4018*cdf0e10cSrcweir 		{
4019*cdf0e10cSrcweir 			SCTAB nTabCount = pDoc->GetTableCount();
4020*cdf0e10cSrcweir             SCTAB nDestStartTab = aDestArea.aStart.Tab();
4021*cdf0e10cSrcweir 
4022*cdf0e10cSrcweir 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4023*cdf0e10cSrcweir             pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4024*cdf0e10cSrcweir 			for (SCTAB i=0; i<nTabCount; i++)
4025*cdf0e10cSrcweir                 if (i != nDestStartTab && aMark.GetTableSelect(i))
4026*cdf0e10cSrcweir 					pUndoDoc->AddUndoTab( i, i );
4027*cdf0e10cSrcweir 
4028*cdf0e10cSrcweir 			ScRange aCopyRange = aDestArea;
4029*cdf0e10cSrcweir 			aCopyRange.aStart.SetTab(0);
4030*cdf0e10cSrcweir 			aCopyRange.aEnd.SetTab(nTabCount-1);
4031*cdf0e10cSrcweir             pDoc->CopyToDocument( aCopyRange, IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
4032*cdf0e10cSrcweir 		}
4033*cdf0e10cSrcweir 
4034*cdf0e10cSrcweir 		pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4035*cdf0e10cSrcweir 					aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
4036*cdf0e10cSrcweir 					nCount, eDir, FILL_SIMPLE );
4037*cdf0e10cSrcweir 		AdjustRowHeight(rRange);
4038*cdf0e10cSrcweir 
4039*cdf0e10cSrcweir 		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
4040*cdf0e10cSrcweir 		{
4041*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
4042*cdf0e10cSrcweir 				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4043*cdf0e10cSrcweir 									eDir, FILL_SIMPLE, FILL_DAY, MAXDOUBLE, 1.0, 1e307,
4044*cdf0e10cSrcweir 									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
4045*cdf0e10cSrcweir 		}
4046*cdf0e10cSrcweir 
4047*cdf0e10cSrcweir 		rDocShell.PostPaintGridAll();
4048*cdf0e10cSrcweir //		rDocShell.PostPaintDataChanged();
4049*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
4050*cdf0e10cSrcweir 
4051*cdf0e10cSrcweir 		bSuccess = sal_True;
4052*cdf0e10cSrcweir 	}
4053*cdf0e10cSrcweir 	else if (!bApi)
4054*cdf0e10cSrcweir 		rDocShell.ErrorMessage(aTester.GetMessageId());
4055*cdf0e10cSrcweir 
4056*cdf0e10cSrcweir 	return bSuccess;
4057*cdf0e10cSrcweir }
4058*cdf0e10cSrcweir 
4059*cdf0e10cSrcweir sal_Bool ScDocFunc::FillSeries( const ScRange& rRange, const ScMarkData* pTabMark,
4060*cdf0e10cSrcweir 							FillDir	eDir, FillCmd eCmd, FillDateCmd	eDateCmd,
4061*cdf0e10cSrcweir 							double fStart, double fStep, double fMax,
4062*cdf0e10cSrcweir 							sal_Bool bRecord, sal_Bool bApi )
4063*cdf0e10cSrcweir {
4064*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4065*cdf0e10cSrcweir 
4066*cdf0e10cSrcweir 	sal_Bool bSuccess = sal_False;
4067*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4068*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
4069*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
4070*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
4071*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
4072*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
4073*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
4074*cdf0e10cSrcweir 
4075*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
4076*cdf0e10cSrcweir 		bRecord = sal_False;
4077*cdf0e10cSrcweir 
4078*cdf0e10cSrcweir 	ScMarkData aMark;
4079*cdf0e10cSrcweir 	if (pTabMark)
4080*cdf0e10cSrcweir 		aMark = *pTabMark;
4081*cdf0e10cSrcweir 	else
4082*cdf0e10cSrcweir 	{
4083*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4084*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
4085*cdf0e10cSrcweir 	}
4086*cdf0e10cSrcweir 
4087*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nStartCol,nStartRow, nEndCol,nEndRow, aMark );
4088*cdf0e10cSrcweir 	if ( aTester.IsEditable() )
4089*cdf0e10cSrcweir 	{
4090*cdf0e10cSrcweir 		WaitObject aWait( rDocShell.GetActiveDialogParent() );
4091*cdf0e10cSrcweir 
4092*cdf0e10cSrcweir 		ScRange aSourceArea = rRange;
4093*cdf0e10cSrcweir 		ScRange aDestArea   = rRange;
4094*cdf0e10cSrcweir 
4095*cdf0e10cSrcweir 		SCSIZE nCount = pDoc->GetEmptyLinesInBlock(
4096*cdf0e10cSrcweir 				aSourceArea.aStart.Col(), aSourceArea.aStart.Row(), aSourceArea.aStart.Tab(),
4097*cdf0e10cSrcweir 				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aSourceArea.aEnd.Tab(),
4098*cdf0e10cSrcweir 				DirFromFillDir(eDir) );
4099*cdf0e10cSrcweir 
4100*cdf0e10cSrcweir 		//	#27665# mindestens eine Zeile/Spalte als Quellbereich behalten:
4101*cdf0e10cSrcweir 		SCSIZE nTotLines = ( eDir == FILL_TO_BOTTOM || eDir == FILL_TO_TOP ) ?
4102*cdf0e10cSrcweir             static_cast<SCSIZE>( aSourceArea.aEnd.Row() - aSourceArea.aStart.Row() + 1 ) :
4103*cdf0e10cSrcweir             static_cast<SCSIZE>( aSourceArea.aEnd.Col() - aSourceArea.aStart.Col() + 1 );
4104*cdf0e10cSrcweir 		if ( nCount >= nTotLines )
4105*cdf0e10cSrcweir 			nCount = nTotLines - 1;
4106*cdf0e10cSrcweir 
4107*cdf0e10cSrcweir 		switch (eDir)
4108*cdf0e10cSrcweir 		{
4109*cdf0e10cSrcweir 			case FILL_TO_BOTTOM:
4110*cdf0e10cSrcweir                 aSourceArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() - nCount ) );
4111*cdf0e10cSrcweir 				break;
4112*cdf0e10cSrcweir 			case FILL_TO_RIGHT:
4113*cdf0e10cSrcweir                 aSourceArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() - nCount ) );
4114*cdf0e10cSrcweir 				break;
4115*cdf0e10cSrcweir 			case FILL_TO_TOP:
4116*cdf0e10cSrcweir                 aSourceArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() + nCount ) );
4117*cdf0e10cSrcweir 				break;
4118*cdf0e10cSrcweir 			case FILL_TO_LEFT:
4119*cdf0e10cSrcweir                 aSourceArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() + nCount ) );
4120*cdf0e10cSrcweir 				break;
4121*cdf0e10cSrcweir 		}
4122*cdf0e10cSrcweir 
4123*cdf0e10cSrcweir 		ScDocument* pUndoDoc = NULL;
4124*cdf0e10cSrcweir 		if ( bRecord )
4125*cdf0e10cSrcweir 		{
4126*cdf0e10cSrcweir 			SCTAB nTabCount = pDoc->GetTableCount();
4127*cdf0e10cSrcweir             SCTAB nDestStartTab = aDestArea.aStart.Tab();
4128*cdf0e10cSrcweir 
4129*cdf0e10cSrcweir 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4130*cdf0e10cSrcweir             pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4131*cdf0e10cSrcweir 			for (SCTAB i=0; i<nTabCount; i++)
4132*cdf0e10cSrcweir                 if (i != nDestStartTab && aMark.GetTableSelect(i))
4133*cdf0e10cSrcweir 					pUndoDoc->AddUndoTab( i, i );
4134*cdf0e10cSrcweir 
4135*cdf0e10cSrcweir 			pDoc->CopyToDocument(
4136*cdf0e10cSrcweir 				aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4137*cdf0e10cSrcweir 				aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4138*cdf0e10cSrcweir                 IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
4139*cdf0e10cSrcweir 		}
4140*cdf0e10cSrcweir 
4141*cdf0e10cSrcweir 		if (aDestArea.aStart.Col() <= aDestArea.aEnd.Col() &&
4142*cdf0e10cSrcweir 			aDestArea.aStart.Row() <= aDestArea.aEnd.Row())
4143*cdf0e10cSrcweir 		{
4144*cdf0e10cSrcweir 			if ( fStart != MAXDOUBLE )
4145*cdf0e10cSrcweir 			{
4146*cdf0e10cSrcweir 				SCCOL nValX = (eDir == FILL_TO_LEFT) ? aDestArea.aEnd.Col() : aDestArea.aStart.Col();
4147*cdf0e10cSrcweir 				SCROW nValY = (eDir == FILL_TO_TOP ) ? aDestArea.aEnd.Row() : aDestArea.aStart.Row();
4148*cdf0e10cSrcweir 				SCTAB nTab = aDestArea.aStart.Tab();
4149*cdf0e10cSrcweir 				pDoc->SetValue( nValX, nValY, nTab, fStart );
4150*cdf0e10cSrcweir 			}
4151*cdf0e10cSrcweir 			pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4152*cdf0e10cSrcweir 						aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
4153*cdf0e10cSrcweir 						nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4154*cdf0e10cSrcweir 			AdjustRowHeight(rRange);
4155*cdf0e10cSrcweir 
4156*cdf0e10cSrcweir 			rDocShell.PostPaintGridAll();
4157*cdf0e10cSrcweir //			rDocShell.PostPaintDataChanged();
4158*cdf0e10cSrcweir 			aModificator.SetDocumentModified();
4159*cdf0e10cSrcweir 		}
4160*cdf0e10cSrcweir 
4161*cdf0e10cSrcweir 		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
4162*cdf0e10cSrcweir 		{
4163*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
4164*cdf0e10cSrcweir 				new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4165*cdf0e10cSrcweir 									eDir, eCmd, eDateCmd, fStart, fStep, fMax,
4166*cdf0e10cSrcweir 									pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
4167*cdf0e10cSrcweir 		}
4168*cdf0e10cSrcweir 
4169*cdf0e10cSrcweir 		bSuccess = sal_True;
4170*cdf0e10cSrcweir 	}
4171*cdf0e10cSrcweir 	else if (!bApi)
4172*cdf0e10cSrcweir 		rDocShell.ErrorMessage(aTester.GetMessageId());
4173*cdf0e10cSrcweir 
4174*cdf0e10cSrcweir 	return bSuccess;
4175*cdf0e10cSrcweir }
4176*cdf0e10cSrcweir 
4177*cdf0e10cSrcweir sal_Bool ScDocFunc::FillAuto( ScRange& rRange, const ScMarkData* pTabMark,
4178*cdf0e10cSrcweir 							FillDir eDir, sal_uLong nCount, sal_Bool bRecord, sal_Bool bApi )
4179*cdf0e10cSrcweir {
4180*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4181*cdf0e10cSrcweir 
4182*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4183*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
4184*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
4185*cdf0e10cSrcweir 	SCTAB nStartTab = rRange.aStart.Tab();
4186*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
4187*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
4188*cdf0e10cSrcweir 	SCTAB nEndTab = rRange.aEnd.Tab();
4189*cdf0e10cSrcweir 
4190*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
4191*cdf0e10cSrcweir 		bRecord = sal_False;
4192*cdf0e10cSrcweir 
4193*cdf0e10cSrcweir 	ScMarkData aMark;
4194*cdf0e10cSrcweir 	if (pTabMark)
4195*cdf0e10cSrcweir 		aMark = *pTabMark;
4196*cdf0e10cSrcweir 	else
4197*cdf0e10cSrcweir 	{
4198*cdf0e10cSrcweir 		for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
4199*cdf0e10cSrcweir 			aMark.SelectTable( nTab, sal_True );
4200*cdf0e10cSrcweir 	}
4201*cdf0e10cSrcweir 
4202*cdf0e10cSrcweir 	ScRange aSourceArea = rRange;
4203*cdf0e10cSrcweir 	ScRange aDestArea   = rRange;
4204*cdf0e10cSrcweir 
4205*cdf0e10cSrcweir 	FillCmd		eCmd = FILL_AUTO;
4206*cdf0e10cSrcweir 	FillDateCmd	eDateCmd = FILL_DAY;
4207*cdf0e10cSrcweir 	double		fStep = 1.0;
4208*cdf0e10cSrcweir 	double		fMax = MAXDOUBLE;
4209*cdf0e10cSrcweir 
4210*cdf0e10cSrcweir 	switch (eDir)
4211*cdf0e10cSrcweir 	{
4212*cdf0e10cSrcweir 		case FILL_TO_BOTTOM:
4213*cdf0e10cSrcweir             aDestArea.aEnd.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aEnd.Row() + nCount ) );
4214*cdf0e10cSrcweir 			break;
4215*cdf0e10cSrcweir 		case FILL_TO_TOP:
4216*cdf0e10cSrcweir             if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Row() ))
4217*cdf0e10cSrcweir 			{
4218*cdf0e10cSrcweir 				DBG_ERROR("FillAuto: Row < 0");
4219*cdf0e10cSrcweir 				nCount = aSourceArea.aStart.Row();
4220*cdf0e10cSrcweir 			}
4221*cdf0e10cSrcweir             aDestArea.aStart.SetRow( sal::static_int_cast<SCROW>( aSourceArea.aStart.Row() - nCount ) );
4222*cdf0e10cSrcweir 			break;
4223*cdf0e10cSrcweir 		case FILL_TO_RIGHT:
4224*cdf0e10cSrcweir             aDestArea.aEnd.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aEnd.Col() + nCount ) );
4225*cdf0e10cSrcweir 			break;
4226*cdf0e10cSrcweir 		case FILL_TO_LEFT:
4227*cdf0e10cSrcweir             if (nCount > sal::static_int_cast<sal_uLong>( aSourceArea.aStart.Col() ))
4228*cdf0e10cSrcweir 			{
4229*cdf0e10cSrcweir 				DBG_ERROR("FillAuto: Col < 0");
4230*cdf0e10cSrcweir 				nCount = aSourceArea.aStart.Col();
4231*cdf0e10cSrcweir 			}
4232*cdf0e10cSrcweir             aDestArea.aStart.SetCol( sal::static_int_cast<SCCOL>( aSourceArea.aStart.Col() - nCount ) );
4233*cdf0e10cSrcweir 			break;
4234*cdf0e10cSrcweir 		default:
4235*cdf0e10cSrcweir 			DBG_ERROR("Falsche Richtung bei FillAuto");
4236*cdf0e10cSrcweir 			break;
4237*cdf0e10cSrcweir 	}
4238*cdf0e10cSrcweir 
4239*cdf0e10cSrcweir 	//		Zellschutz testen
4240*cdf0e10cSrcweir 	//!		Quellbereich darf geschuetzt sein !!!
4241*cdf0e10cSrcweir 	//!		aber kein Matrixfragment enthalten !!!
4242*cdf0e10cSrcweir 
4243*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, aDestArea );
4244*cdf0e10cSrcweir 	if ( !aTester.IsEditable() )
4245*cdf0e10cSrcweir 	{
4246*cdf0e10cSrcweir 		if (!bApi)
4247*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
4248*cdf0e10cSrcweir 		return sal_False;
4249*cdf0e10cSrcweir 	}
4250*cdf0e10cSrcweir 
4251*cdf0e10cSrcweir 	if ( pDoc->HasSelectedBlockMatrixFragment( nStartCol, nStartRow,
4252*cdf0e10cSrcweir 			nEndCol, nEndRow, aMark ) )
4253*cdf0e10cSrcweir 	{
4254*cdf0e10cSrcweir 		if (!bApi)
4255*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_MATRIXFRAGMENTERR);
4256*cdf0e10cSrcweir 		return sal_False;
4257*cdf0e10cSrcweir 	}
4258*cdf0e10cSrcweir 
4259*cdf0e10cSrcweir 	WaitObject aWait( rDocShell.GetActiveDialogParent() );
4260*cdf0e10cSrcweir 
4261*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
4262*cdf0e10cSrcweir 	if ( bRecord )
4263*cdf0e10cSrcweir 	{
4264*cdf0e10cSrcweir 		SCTAB nTabCount = pDoc->GetTableCount();
4265*cdf0e10cSrcweir         SCTAB nDestStartTab = aDestArea.aStart.Tab();
4266*cdf0e10cSrcweir 
4267*cdf0e10cSrcweir 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4268*cdf0e10cSrcweir         pUndoDoc->InitUndo( pDoc, nDestStartTab, nDestStartTab );
4269*cdf0e10cSrcweir 		for (SCTAB i=0; i<nTabCount; i++)
4270*cdf0e10cSrcweir             if (i != nDestStartTab && aMark.GetTableSelect(i))
4271*cdf0e10cSrcweir 				pUndoDoc->AddUndoTab( i, i );
4272*cdf0e10cSrcweir 
4273*cdf0e10cSrcweir         // do not clone note captions in undo document
4274*cdf0e10cSrcweir 		pDoc->CopyToDocument(
4275*cdf0e10cSrcweir 			aDestArea.aStart.Col(), aDestArea.aStart.Row(), 0,
4276*cdf0e10cSrcweir 			aDestArea.aEnd.Col(), aDestArea.aEnd.Row(), nTabCount-1,
4277*cdf0e10cSrcweir             IDF_AUTOFILL, sal_False, pUndoDoc, &aMark );
4278*cdf0e10cSrcweir 	}
4279*cdf0e10cSrcweir 
4280*cdf0e10cSrcweir 	pDoc->Fill( aSourceArea.aStart.Col(), aSourceArea.aStart.Row(),
4281*cdf0e10cSrcweir 				aSourceArea.aEnd.Col(), aSourceArea.aEnd.Row(), aMark,
4282*cdf0e10cSrcweir 				nCount, eDir, eCmd, eDateCmd, fStep, fMax );
4283*cdf0e10cSrcweir 
4284*cdf0e10cSrcweir 	AdjustRowHeight(aDestArea);
4285*cdf0e10cSrcweir 
4286*cdf0e10cSrcweir 	if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
4287*cdf0e10cSrcweir 	{
4288*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
4289*cdf0e10cSrcweir 			new ScUndoAutoFill( &rDocShell, aDestArea, aSourceArea, pUndoDoc, aMark,
4290*cdf0e10cSrcweir 								eDir, eCmd, eDateCmd, MAXDOUBLE, fStep, fMax,
4291*cdf0e10cSrcweir 								pDoc->GetRangeName()->GetSharedMaxIndex()+1 ) );
4292*cdf0e10cSrcweir 	}
4293*cdf0e10cSrcweir 
4294*cdf0e10cSrcweir 	rDocShell.PostPaintGridAll();
4295*cdf0e10cSrcweir //	rDocShell.PostPaintDataChanged();
4296*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
4297*cdf0e10cSrcweir 
4298*cdf0e10cSrcweir 	rRange = aDestArea;			// Zielbereich zurueckgeben (zum Markieren)
4299*cdf0e10cSrcweir 	return sal_True;
4300*cdf0e10cSrcweir }
4301*cdf0e10cSrcweir 
4302*cdf0e10cSrcweir //------------------------------------------------------------------------
4303*cdf0e10cSrcweir 
4304*cdf0e10cSrcweir sal_Bool ScDocFunc::MergeCells( const ScRange& rRange, sal_Bool bContents, sal_Bool bRecord, sal_Bool bApi )
4305*cdf0e10cSrcweir {
4306*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4307*cdf0e10cSrcweir 
4308*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4309*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
4310*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
4311*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
4312*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
4313*cdf0e10cSrcweir 	SCTAB nTab = rRange.aStart.Tab();
4314*cdf0e10cSrcweir 
4315*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
4316*cdf0e10cSrcweir 		bRecord = sal_False;
4317*cdf0e10cSrcweir 
4318*cdf0e10cSrcweir 	ScEditableTester aTester( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
4319*cdf0e10cSrcweir 	if (!aTester.IsEditable())
4320*cdf0e10cSrcweir 	{
4321*cdf0e10cSrcweir 		if (!bApi)
4322*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
4323*cdf0e10cSrcweir 		return sal_False;
4324*cdf0e10cSrcweir 	}
4325*cdf0e10cSrcweir 
4326*cdf0e10cSrcweir 	if ( nStartCol == nEndCol && nStartRow == nEndRow )
4327*cdf0e10cSrcweir 	{
4328*cdf0e10cSrcweir 		// nichts zu tun
4329*cdf0e10cSrcweir 		return sal_True;
4330*cdf0e10cSrcweir 	}
4331*cdf0e10cSrcweir 
4332*cdf0e10cSrcweir 	if ( pDoc->HasAttrib( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
4333*cdf0e10cSrcweir 							HASATTR_MERGED | HASATTR_OVERLAPPED ) )
4334*cdf0e10cSrcweir 	{
4335*cdf0e10cSrcweir 		// "Zusammenfassen nicht verschachteln !"
4336*cdf0e10cSrcweir 		if (!bApi)
4337*cdf0e10cSrcweir 			rDocShell.ErrorMessage(STR_MSSG_MERGECELLS_0);
4338*cdf0e10cSrcweir 		return sal_False;
4339*cdf0e10cSrcweir 	}
4340*cdf0e10cSrcweir 
4341*cdf0e10cSrcweir 	sal_Bool bNeedContents = bContents &&
4342*cdf0e10cSrcweir 			( !pDoc->IsBlockEmpty( nTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
4343*cdf0e10cSrcweir 			  !pDoc->IsBlockEmpty( nTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) );
4344*cdf0e10cSrcweir 
4345*cdf0e10cSrcweir     ScDocument* pUndoDoc = 0;
4346*cdf0e10cSrcweir 	if (bRecord)
4347*cdf0e10cSrcweir 	{
4348*cdf0e10cSrcweir         // test if the range contains other notes which also implies that we need an undo document
4349*cdf0e10cSrcweir         bool bHasNotes = false;
4350*cdf0e10cSrcweir         for( ScAddress aPos( nStartCol, nStartRow, nTab ); !bHasNotes && (aPos.Col() <= nEndCol); aPos.IncCol() )
4351*cdf0e10cSrcweir             for( aPos.SetRow( nStartRow ); !bHasNotes && (aPos.Row() <= nEndRow); aPos.IncRow() )
4352*cdf0e10cSrcweir                 bHasNotes = ((aPos.Col() != nStartCol) || (aPos.Row() != nStartRow)) && (pDoc->GetNote( aPos ) != 0);
4353*cdf0e10cSrcweir 
4354*cdf0e10cSrcweir 		if (bNeedContents || bHasNotes)
4355*cdf0e10cSrcweir 		{
4356*cdf0e10cSrcweir 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4357*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nTab, nTab );
4358*cdf0e10cSrcweir             // note captions are collected by drawing undo
4359*cdf0e10cSrcweir 			pDoc->CopyToDocument( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab,
4360*cdf0e10cSrcweir                                     IDF_ALL|IDF_NOCAPTIONS, sal_False, pUndoDoc );
4361*cdf0e10cSrcweir 		}
4362*cdf0e10cSrcweir         if( bHasNotes )
4363*cdf0e10cSrcweir             pDoc->BeginDrawUndo();
4364*cdf0e10cSrcweir 	}
4365*cdf0e10cSrcweir 
4366*cdf0e10cSrcweir 	if (bNeedContents)
4367*cdf0e10cSrcweir 		pDoc->DoMergeContents( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
4368*cdf0e10cSrcweir 	pDoc->DoMerge( nTab, nStartCol,nStartRow, nEndCol,nEndRow );
4369*cdf0e10cSrcweir 
4370*cdf0e10cSrcweir     if( bRecord )
4371*cdf0e10cSrcweir     {
4372*cdf0e10cSrcweir         SdrUndoGroup* pDrawUndo = pDoc->GetDrawLayer() ? pDoc->GetDrawLayer()->GetCalcUndo() : 0;
4373*cdf0e10cSrcweir         rDocShell.GetUndoManager()->AddUndoAction(
4374*cdf0e10cSrcweir             new ScUndoMerge( &rDocShell,
4375*cdf0e10cSrcweir                             nStartCol, nStartRow, nTab,
4376*cdf0e10cSrcweir                             nEndCol, nEndRow, nTab, bNeedContents, pUndoDoc, pDrawUndo ) );
4377*cdf0e10cSrcweir     }
4378*cdf0e10cSrcweir 
4379*cdf0e10cSrcweir 	if ( !AdjustRowHeight( ScRange( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab ) ) )
4380*cdf0e10cSrcweir 		rDocShell.PostPaint( nStartCol, nStartRow, nTab,
4381*cdf0e10cSrcweir 											nEndCol, nEndRow, nTab, PAINT_GRID );
4382*cdf0e10cSrcweir 	if (bNeedContents)
4383*cdf0e10cSrcweir 		pDoc->SetDirty( rRange );
4384*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
4385*cdf0e10cSrcweir 
4386*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
4387*cdf0e10cSrcweir 	if (pBindings)
4388*cdf0e10cSrcweir 	{
4389*cdf0e10cSrcweir 		pBindings->Invalidate( FID_MERGE_ON );
4390*cdf0e10cSrcweir 		pBindings->Invalidate( FID_MERGE_OFF );
4391*cdf0e10cSrcweir         pBindings->Invalidate( FID_MERGE_TOGGLE );
4392*cdf0e10cSrcweir 	}
4393*cdf0e10cSrcweir 
4394*cdf0e10cSrcweir 	return sal_True;
4395*cdf0e10cSrcweir }
4396*cdf0e10cSrcweir 
4397*cdf0e10cSrcweir sal_Bool ScDocFunc::UnmergeCells( const ScRange& rRange, sal_Bool bRecord, sal_Bool bApi )
4398*cdf0e10cSrcweir {
4399*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4400*cdf0e10cSrcweir 
4401*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4402*cdf0e10cSrcweir 	SCTAB nTab = rRange.aStart.Tab();
4403*cdf0e10cSrcweir 
4404*cdf0e10cSrcweir 	if (bRecord && !pDoc->IsUndoEnabled())
4405*cdf0e10cSrcweir 		bRecord = sal_False;
4406*cdf0e10cSrcweir 
4407*cdf0e10cSrcweir 	if ( pDoc->HasAttrib( rRange, HASATTR_MERGED ) )
4408*cdf0e10cSrcweir 	{
4409*cdf0e10cSrcweir 		ScRange aExtended = rRange;
4410*cdf0e10cSrcweir 		pDoc->ExtendMerge( aExtended );
4411*cdf0e10cSrcweir 		ScRange aRefresh = aExtended;
4412*cdf0e10cSrcweir 		pDoc->ExtendOverlapped( aRefresh );
4413*cdf0e10cSrcweir 
4414*cdf0e10cSrcweir 		if (bRecord)
4415*cdf0e10cSrcweir 		{
4416*cdf0e10cSrcweir 			ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4417*cdf0e10cSrcweir 			pUndoDoc->InitUndo( pDoc, nTab, nTab );
4418*cdf0e10cSrcweir 			pDoc->CopyToDocument( aExtended, IDF_ATTRIB, sal_False, pUndoDoc );
4419*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->AddUndoAction(
4420*cdf0e10cSrcweir 				new ScUndoRemoveMerge( &rDocShell, rRange, pUndoDoc ) );
4421*cdf0e10cSrcweir 		}
4422*cdf0e10cSrcweir 
4423*cdf0e10cSrcweir 		const SfxPoolItem& rDefAttr = pDoc->GetPool()->GetDefaultItem( ATTR_MERGE );
4424*cdf0e10cSrcweir 		ScPatternAttr aPattern( pDoc->GetPool() );
4425*cdf0e10cSrcweir 		aPattern.GetItemSet().Put( rDefAttr );
4426*cdf0e10cSrcweir 		pDoc->ApplyPatternAreaTab( rRange.aStart.Col(), rRange.aStart.Row(),
4427*cdf0e10cSrcweir 									rRange.aEnd.Col(), rRange.aEnd.Row(), nTab,
4428*cdf0e10cSrcweir 									aPattern );
4429*cdf0e10cSrcweir 
4430*cdf0e10cSrcweir 		pDoc->RemoveFlagsTab( aExtended.aStart.Col(), aExtended.aStart.Row(),
4431*cdf0e10cSrcweir 								aExtended.aEnd.Col(), aExtended.aEnd.Row(), nTab,
4432*cdf0e10cSrcweir 								SC_MF_HOR | SC_MF_VER );
4433*cdf0e10cSrcweir 
4434*cdf0e10cSrcweir 		pDoc->ExtendMerge( aRefresh, sal_True, sal_False );
4435*cdf0e10cSrcweir 
4436*cdf0e10cSrcweir 		if ( !AdjustRowHeight( aExtended ) )
4437*cdf0e10cSrcweir 			rDocShell.PostPaint( aExtended, PAINT_GRID );
4438*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
4439*cdf0e10cSrcweir 	}
4440*cdf0e10cSrcweir 	else if (!bApi)
4441*cdf0e10cSrcweir 		Sound::Beep();		//! sal_False zurueck???
4442*cdf0e10cSrcweir 
4443*cdf0e10cSrcweir 	return sal_True;
4444*cdf0e10cSrcweir }
4445*cdf0e10cSrcweir 
4446*cdf0e10cSrcweir //------------------------------------------------------------------------
4447*cdf0e10cSrcweir 
4448*cdf0e10cSrcweir sal_Bool ScDocFunc::ModifyRangeNames( const ScRangeName& rNewRanges, sal_Bool bApi )
4449*cdf0e10cSrcweir {
4450*cdf0e10cSrcweir     return SetNewRangeNames( new ScRangeName( rNewRanges ), bApi );
4451*cdf0e10cSrcweir }
4452*cdf0e10cSrcweir 
4453*cdf0e10cSrcweir sal_Bool ScDocFunc::SetNewRangeNames( ScRangeName* pNewRanges, sal_Bool /* bApi */ )     // takes ownership of pNewRanges
4454*cdf0e10cSrcweir {
4455*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4456*cdf0e10cSrcweir 
4457*cdf0e10cSrcweir     DBG_ASSERT( pNewRanges, "pNewRanges is 0" );
4458*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4459*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
4460*cdf0e10cSrcweir 
4461*cdf0e10cSrcweir 	if (bUndo)
4462*cdf0e10cSrcweir 	{
4463*cdf0e10cSrcweir 		ScRangeName* pOld = pDoc->GetRangeName();
4464*cdf0e10cSrcweir 		ScRangeName* pUndoRanges = new ScRangeName(*pOld);
4465*cdf0e10cSrcweir 		ScRangeName* pRedoRanges = new ScRangeName(*pNewRanges);
4466*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction(
4467*cdf0e10cSrcweir 			new ScUndoRangeNames( &rDocShell, pUndoRanges, pRedoRanges ) );
4468*cdf0e10cSrcweir 	}
4469*cdf0e10cSrcweir 
4470*cdf0e10cSrcweir     // #i55926# While loading XML, formula cells only have a single string token,
4471*cdf0e10cSrcweir     // so CompileNameFormula would never find any name (index) tokens, and would
4472*cdf0e10cSrcweir     // unnecessarily loop through all cells.
4473*cdf0e10cSrcweir     sal_Bool bCompile = ( !pDoc->IsImportingXML() && pDoc->GetNamedRangesLockCount() == 0 );
4474*cdf0e10cSrcweir 
4475*cdf0e10cSrcweir     if ( bCompile )
4476*cdf0e10cSrcweir         pDoc->CompileNameFormula( sal_True );	// CreateFormulaString
4477*cdf0e10cSrcweir     pDoc->SetRangeName( pNewRanges );       // takes ownership
4478*cdf0e10cSrcweir     if ( bCompile )
4479*cdf0e10cSrcweir         pDoc->CompileNameFormula( sal_False );	// CompileFormulaString
4480*cdf0e10cSrcweir 
4481*cdf0e10cSrcweir 	aModificator.SetDocumentModified();
4482*cdf0e10cSrcweir 
4483*cdf0e10cSrcweir     // #i114072# don't broadcast while loading a file
4484*cdf0e10cSrcweir     // (navigator and input line for other open documents would be notified)
4485*cdf0e10cSrcweir     if ( bCompile )
4486*cdf0e10cSrcweir         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
4487*cdf0e10cSrcweir 
4488*cdf0e10cSrcweir 	return sal_True;
4489*cdf0e10cSrcweir }
4490*cdf0e10cSrcweir 
4491*cdf0e10cSrcweir //------------------------------------------------------------------------
4492*cdf0e10cSrcweir 
4493*cdf0e10cSrcweir void ScDocFunc::CreateOneName( ScRangeName& rList,
4494*cdf0e10cSrcweir 								SCCOL nPosX, SCROW nPosY, SCTAB nTab,
4495*cdf0e10cSrcweir 								SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2,
4496*cdf0e10cSrcweir 								sal_Bool& rCancel, sal_Bool bApi )
4497*cdf0e10cSrcweir {
4498*cdf0e10cSrcweir 	if (rCancel)
4499*cdf0e10cSrcweir 		return;
4500*cdf0e10cSrcweir 
4501*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4502*cdf0e10cSrcweir 	if (!pDoc->HasValueData( nPosX, nPosY, nTab ))
4503*cdf0e10cSrcweir 	{
4504*cdf0e10cSrcweir 		String aName;
4505*cdf0e10cSrcweir 		pDoc->GetString( nPosX, nPosY, nTab, aName );
4506*cdf0e10cSrcweir 		ScRangeData::MakeValidName(aName);
4507*cdf0e10cSrcweir 		if (aName.Len())
4508*cdf0e10cSrcweir 		{
4509*cdf0e10cSrcweir 			String aContent;
4510*cdf0e10cSrcweir             ScRange( nX1, nY1, nTab, nX2, nY2, nTab ).Format( aContent, SCR_ABS_3D, pDoc );
4511*cdf0e10cSrcweir 
4512*cdf0e10cSrcweir 			sal_Bool bInsert = sal_False;
4513*cdf0e10cSrcweir 			sal_uInt16 nOldPos;
4514*cdf0e10cSrcweir 			if (rList.SearchName( aName, nOldPos ))			// vorhanden ?
4515*cdf0e10cSrcweir 			{
4516*cdf0e10cSrcweir 				ScRangeData* pOld = rList[nOldPos];
4517*cdf0e10cSrcweir 				String aOldStr;
4518*cdf0e10cSrcweir 				pOld->GetSymbol( aOldStr );
4519*cdf0e10cSrcweir 				if (aOldStr != aContent)
4520*cdf0e10cSrcweir 				{
4521*cdf0e10cSrcweir 					if (bApi)
4522*cdf0e10cSrcweir 						bInsert = sal_True;		// per API nicht nachfragen
4523*cdf0e10cSrcweir 					else
4524*cdf0e10cSrcweir 					{
4525*cdf0e10cSrcweir 						String aTemplate = ScGlobal::GetRscString( STR_CREATENAME_REPLACE );
4526*cdf0e10cSrcweir 
4527*cdf0e10cSrcweir 						String aMessage = aTemplate.GetToken( 0, '#' );
4528*cdf0e10cSrcweir 						aMessage += aName;
4529*cdf0e10cSrcweir 						aMessage += aTemplate.GetToken( 1, '#' );
4530*cdf0e10cSrcweir 
4531*cdf0e10cSrcweir 						short nResult = QueryBox( rDocShell.GetActiveDialogParent(),
4532*cdf0e10cSrcweir 													WinBits(WB_YES_NO_CANCEL | WB_DEF_YES),
4533*cdf0e10cSrcweir 													aMessage ).Execute();
4534*cdf0e10cSrcweir 						if ( nResult == RET_YES )
4535*cdf0e10cSrcweir 						{
4536*cdf0e10cSrcweir 							rList.AtFree(nOldPos);
4537*cdf0e10cSrcweir 							bInsert = sal_True;
4538*cdf0e10cSrcweir 						}
4539*cdf0e10cSrcweir 						else if ( nResult == RET_CANCEL )
4540*cdf0e10cSrcweir 							rCancel = sal_True;
4541*cdf0e10cSrcweir 					}
4542*cdf0e10cSrcweir 				}
4543*cdf0e10cSrcweir 			}
4544*cdf0e10cSrcweir 			else
4545*cdf0e10cSrcweir 				bInsert = sal_True;
4546*cdf0e10cSrcweir 
4547*cdf0e10cSrcweir 			if (bInsert)
4548*cdf0e10cSrcweir 			{
4549*cdf0e10cSrcweir                 ScRangeData* pData = new ScRangeData( pDoc, aName, aContent,
4550*cdf0e10cSrcweir                         ScAddress( nPosX, nPosY, nTab));
4551*cdf0e10cSrcweir 				if (!rList.Insert(pData))
4552*cdf0e10cSrcweir 				{
4553*cdf0e10cSrcweir 					DBG_ERROR("nanu?");
4554*cdf0e10cSrcweir 					delete pData;
4555*cdf0e10cSrcweir 				}
4556*cdf0e10cSrcweir 			}
4557*cdf0e10cSrcweir 		}
4558*cdf0e10cSrcweir 	}
4559*cdf0e10cSrcweir }
4560*cdf0e10cSrcweir 
4561*cdf0e10cSrcweir sal_Bool ScDocFunc::CreateNames( const ScRange& rRange, sal_uInt16 nFlags, sal_Bool bApi )
4562*cdf0e10cSrcweir {
4563*cdf0e10cSrcweir 	if (!nFlags)
4564*cdf0e10cSrcweir 		return sal_False;		// war nix
4565*cdf0e10cSrcweir 
4566*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4567*cdf0e10cSrcweir 
4568*cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
4569*cdf0e10cSrcweir 	SCCOL nStartCol = rRange.aStart.Col();
4570*cdf0e10cSrcweir 	SCROW nStartRow = rRange.aStart.Row();
4571*cdf0e10cSrcweir 	SCCOL nEndCol = rRange.aEnd.Col();
4572*cdf0e10cSrcweir 	SCROW nEndRow = rRange.aEnd.Row();
4573*cdf0e10cSrcweir 	SCTAB nTab = rRange.aStart.Tab();
4574*cdf0e10cSrcweir 	DBG_ASSERT(rRange.aEnd.Tab() == nTab, "CreateNames: mehrere Tabellen geht nicht");
4575*cdf0e10cSrcweir 
4576*cdf0e10cSrcweir 	sal_Bool bValid = sal_True;
4577*cdf0e10cSrcweir 	if ( nFlags & ( NAME_TOP | NAME_BOTTOM ) )
4578*cdf0e10cSrcweir 		if ( nStartRow == nEndRow )
4579*cdf0e10cSrcweir 			bValid = sal_False;
4580*cdf0e10cSrcweir 	if ( nFlags & ( NAME_LEFT | NAME_RIGHT ) )
4581*cdf0e10cSrcweir 		if ( nStartCol == nEndCol )
4582*cdf0e10cSrcweir 			bValid = sal_False;
4583*cdf0e10cSrcweir 
4584*cdf0e10cSrcweir 	if (bValid)
4585*cdf0e10cSrcweir 	{
4586*cdf0e10cSrcweir 		ScDocument* pDoc = rDocShell.GetDocument();
4587*cdf0e10cSrcweir 		ScRangeName* pNames = pDoc->GetRangeName();
4588*cdf0e10cSrcweir 		if (!pNames)
4589*cdf0e10cSrcweir 			return sal_False;	// soll nicht sein
4590*cdf0e10cSrcweir 		ScRangeName aNewRanges( *pNames );
4591*cdf0e10cSrcweir 
4592*cdf0e10cSrcweir 		sal_Bool bTop    = ( ( nFlags & NAME_TOP ) != 0 );
4593*cdf0e10cSrcweir 		sal_Bool bLeft   = ( ( nFlags & NAME_LEFT ) != 0 );
4594*cdf0e10cSrcweir 		sal_Bool bBottom = ( ( nFlags & NAME_BOTTOM ) != 0 );
4595*cdf0e10cSrcweir 		sal_Bool bRight  = ( ( nFlags & NAME_RIGHT ) != 0 );
4596*cdf0e10cSrcweir 
4597*cdf0e10cSrcweir 		SCCOL nContX1 = nStartCol;
4598*cdf0e10cSrcweir 		SCROW nContY1 = nStartRow;
4599*cdf0e10cSrcweir 		SCCOL nContX2 = nEndCol;
4600*cdf0e10cSrcweir 		SCROW nContY2 = nEndRow;
4601*cdf0e10cSrcweir 
4602*cdf0e10cSrcweir 		if ( bTop )
4603*cdf0e10cSrcweir 			++nContY1;
4604*cdf0e10cSrcweir 		if ( bLeft )
4605*cdf0e10cSrcweir 			++nContX1;
4606*cdf0e10cSrcweir 		if ( bBottom )
4607*cdf0e10cSrcweir 			--nContY2;
4608*cdf0e10cSrcweir 		if ( bRight )
4609*cdf0e10cSrcweir 			--nContX2;
4610*cdf0e10cSrcweir 
4611*cdf0e10cSrcweir 		sal_Bool bCancel = sal_False;
4612*cdf0e10cSrcweir         SCCOL i;
4613*cdf0e10cSrcweir         SCROW j;
4614*cdf0e10cSrcweir 
4615*cdf0e10cSrcweir 		if ( bTop )
4616*cdf0e10cSrcweir 			for (i=nContX1; i<=nContX2; i++)
4617*cdf0e10cSrcweir 				CreateOneName( aNewRanges, i,nStartRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
4618*cdf0e10cSrcweir 		if ( bLeft )
4619*cdf0e10cSrcweir 			for (j=nContY1; j<=nContY2; j++)
4620*cdf0e10cSrcweir 				CreateOneName( aNewRanges, nStartCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
4621*cdf0e10cSrcweir 		if ( bBottom )
4622*cdf0e10cSrcweir 			for (i=nContX1; i<=nContX2; i++)
4623*cdf0e10cSrcweir 				CreateOneName( aNewRanges, i,nEndRow,nTab, i,nContY1,i,nContY2, bCancel, bApi );
4624*cdf0e10cSrcweir 		if ( bRight )
4625*cdf0e10cSrcweir 			for (j=nContY1; j<=nContY2; j++)
4626*cdf0e10cSrcweir 				CreateOneName( aNewRanges, nEndCol,j,nTab, nContX1,j,nContX2,j, bCancel, bApi );
4627*cdf0e10cSrcweir 
4628*cdf0e10cSrcweir 		if ( bTop && bLeft )
4629*cdf0e10cSrcweir 			CreateOneName( aNewRanges, nStartCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
4630*cdf0e10cSrcweir 		if ( bTop && bRight )
4631*cdf0e10cSrcweir 			CreateOneName( aNewRanges, nEndCol,nStartRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
4632*cdf0e10cSrcweir 		if ( bBottom && bLeft )
4633*cdf0e10cSrcweir 			CreateOneName( aNewRanges, nStartCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
4634*cdf0e10cSrcweir 		if ( bBottom && bRight )
4635*cdf0e10cSrcweir 			CreateOneName( aNewRanges, nEndCol,nEndRow,nTab, nContX1,nContY1,nContX2,nContY2, bCancel, bApi );
4636*cdf0e10cSrcweir 
4637*cdf0e10cSrcweir 		bDone = ModifyRangeNames( aNewRanges, bApi );
4638*cdf0e10cSrcweir 
4639*cdf0e10cSrcweir 		aModificator.SetDocumentModified();
4640*cdf0e10cSrcweir 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
4641*cdf0e10cSrcweir 	}
4642*cdf0e10cSrcweir 
4643*cdf0e10cSrcweir 	return bDone;
4644*cdf0e10cSrcweir }
4645*cdf0e10cSrcweir 
4646*cdf0e10cSrcweir //------------------------------------------------------------------------
4647*cdf0e10cSrcweir 
4648*cdf0e10cSrcweir sal_Bool ScDocFunc::InsertNameList( const ScAddress& rStartPos, sal_Bool bApi )
4649*cdf0e10cSrcweir {
4650*cdf0e10cSrcweir 	ScDocShellModificator aModificator( rDocShell );
4651*cdf0e10cSrcweir 
4652*cdf0e10cSrcweir 
4653*cdf0e10cSrcweir 	sal_Bool bDone = sal_False;
4654*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4655*cdf0e10cSrcweir 	const sal_Bool bRecord = pDoc->IsUndoEnabled();
4656*cdf0e10cSrcweir 	SCTAB nTab = rStartPos.Tab();
4657*cdf0e10cSrcweir 	ScDocument* pUndoDoc = NULL;
4658*cdf0e10cSrcweir 
4659*cdf0e10cSrcweir 	ScRangeName* pList = pDoc->GetRangeName();
4660*cdf0e10cSrcweir 	sal_uInt16 nCount = pList->GetCount();
4661*cdf0e10cSrcweir 	sal_uInt16 nValidCount = 0;
4662*cdf0e10cSrcweir 	sal_uInt16 i;
4663*cdf0e10cSrcweir 	for (i=0; i<nCount; i++)
4664*cdf0e10cSrcweir 	{
4665*cdf0e10cSrcweir 		ScRangeData* pData = (*pList)[i];
4666*cdf0e10cSrcweir 		if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
4667*cdf0e10cSrcweir 			++nValidCount;
4668*cdf0e10cSrcweir 	}
4669*cdf0e10cSrcweir 
4670*cdf0e10cSrcweir 	if (nValidCount)
4671*cdf0e10cSrcweir 	{
4672*cdf0e10cSrcweir 		SCCOL nStartCol = rStartPos.Col();
4673*cdf0e10cSrcweir 		SCROW nStartRow = rStartPos.Row();
4674*cdf0e10cSrcweir 		SCCOL nEndCol = nStartCol + 1;
4675*cdf0e10cSrcweir 		SCROW nEndRow = nStartRow + static_cast<SCROW>(nValidCount) - 1;
4676*cdf0e10cSrcweir 
4677*cdf0e10cSrcweir 		ScEditableTester aTester( pDoc, nTab, nStartCol,nStartRow, nEndCol,nEndRow );
4678*cdf0e10cSrcweir 		if (aTester.IsEditable())
4679*cdf0e10cSrcweir 		{
4680*cdf0e10cSrcweir 			if (bRecord)
4681*cdf0e10cSrcweir 			{
4682*cdf0e10cSrcweir 				pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
4683*cdf0e10cSrcweir 				pUndoDoc->InitUndo( pDoc, nTab, nTab );
4684*cdf0e10cSrcweir 				pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
4685*cdf0e10cSrcweir 										IDF_ALL, sal_False, pUndoDoc );
4686*cdf0e10cSrcweir 
4687*cdf0e10cSrcweir 				pDoc->BeginDrawUndo();		// wegen Hoehenanpassung
4688*cdf0e10cSrcweir 			}
4689*cdf0e10cSrcweir 
4690*cdf0e10cSrcweir 			ScRangeData** ppSortArray = new ScRangeData* [ nValidCount ];
4691*cdf0e10cSrcweir 			sal_uInt16 j = 0;
4692*cdf0e10cSrcweir 			for (i=0; i<nCount; i++)
4693*cdf0e10cSrcweir 			{
4694*cdf0e10cSrcweir 				ScRangeData* pData = (*pList)[i];
4695*cdf0e10cSrcweir 				if ( !pData->HasType( RT_DATABASE ) && !pData->HasType( RT_SHARED ) )
4696*cdf0e10cSrcweir 					ppSortArray[j++] = pData;
4697*cdf0e10cSrcweir 			}
4698*cdf0e10cSrcweir #ifndef ICC
4699*cdf0e10cSrcweir 			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
4700*cdf0e10cSrcweir 				&ScRangeData_QsortNameCompare );
4701*cdf0e10cSrcweir #else
4702*cdf0e10cSrcweir 			qsort( (void*)ppSortArray, nValidCount, sizeof(ScRangeData*),
4703*cdf0e10cSrcweir 				ICCQsortNameCompare );
4704*cdf0e10cSrcweir #endif
4705*cdf0e10cSrcweir 			String aName;
4706*cdf0e10cSrcweir 			rtl::OUStringBuffer aContent;
4707*cdf0e10cSrcweir 			String aFormula;
4708*cdf0e10cSrcweir 			SCROW nOutRow = nStartRow;
4709*cdf0e10cSrcweir 			for (j=0; j<nValidCount; j++)
4710*cdf0e10cSrcweir 			{
4711*cdf0e10cSrcweir 				ScRangeData* pData = ppSortArray[j];
4712*cdf0e10cSrcweir 				pData->GetName(aName);
4713*cdf0e10cSrcweir 				// relative Referenzen Excel-konform auf die linke Spalte anpassen:
4714*cdf0e10cSrcweir 				pData->UpdateSymbol(aContent, ScAddress( nStartCol, nOutRow, nTab ));
4715*cdf0e10cSrcweir 				aFormula = '=';
4716*cdf0e10cSrcweir 				aFormula += aContent;
4717*cdf0e10cSrcweir 				pDoc->PutCell( nStartCol,nOutRow,nTab, new ScStringCell( aName ) );
4718*cdf0e10cSrcweir 				pDoc->PutCell( nEndCol  ,nOutRow,nTab, new ScStringCell( aFormula ) );
4719*cdf0e10cSrcweir 				++nOutRow;
4720*cdf0e10cSrcweir 			}
4721*cdf0e10cSrcweir 
4722*cdf0e10cSrcweir 			delete [] ppSortArray;
4723*cdf0e10cSrcweir 
4724*cdf0e10cSrcweir 			if (bRecord)
4725*cdf0e10cSrcweir 			{
4726*cdf0e10cSrcweir 				ScDocument* pRedoDoc = new ScDocument( SCDOCMODE_UNDO );
4727*cdf0e10cSrcweir 				pRedoDoc->InitUndo( pDoc, nTab, nTab );
4728*cdf0e10cSrcweir 				pDoc->CopyToDocument( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
4729*cdf0e10cSrcweir 										IDF_ALL, sal_False, pRedoDoc );
4730*cdf0e10cSrcweir 
4731*cdf0e10cSrcweir 				rDocShell.GetUndoManager()->AddUndoAction(
4732*cdf0e10cSrcweir 					new ScUndoListNames( &rDocShell,
4733*cdf0e10cSrcweir 								ScRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab ),
4734*cdf0e10cSrcweir 								pUndoDoc, pRedoDoc ) );
4735*cdf0e10cSrcweir 			}
4736*cdf0e10cSrcweir 
4737*cdf0e10cSrcweir 			if (!AdjustRowHeight(ScRange(0,nStartRow,nTab,MAXCOL,nEndRow,nTab)))
4738*cdf0e10cSrcweir 				rDocShell.PostPaint( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab, PAINT_GRID );
4739*cdf0e10cSrcweir //!			rDocShell.UpdateOle(GetViewData());
4740*cdf0e10cSrcweir 			aModificator.SetDocumentModified();
4741*cdf0e10cSrcweir 			bDone = sal_True;
4742*cdf0e10cSrcweir 		}
4743*cdf0e10cSrcweir 		else if (!bApi)
4744*cdf0e10cSrcweir 			rDocShell.ErrorMessage(aTester.GetMessageId());
4745*cdf0e10cSrcweir 	}
4746*cdf0e10cSrcweir 	return bDone;
4747*cdf0e10cSrcweir }
4748*cdf0e10cSrcweir 
4749*cdf0e10cSrcweir //------------------------------------------------------------------------
4750*cdf0e10cSrcweir 
4751*cdf0e10cSrcweir sal_Bool ScDocFunc::ResizeMatrix( const ScRange& rOldRange, const ScAddress& rNewEnd, sal_Bool bApi )
4752*cdf0e10cSrcweir {
4753*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4754*cdf0e10cSrcweir 	SCCOL nStartCol = rOldRange.aStart.Col();
4755*cdf0e10cSrcweir 	SCROW nStartRow = rOldRange.aStart.Row();
4756*cdf0e10cSrcweir 	SCTAB nTab = rOldRange.aStart.Tab();
4757*cdf0e10cSrcweir 
4758*cdf0e10cSrcweir 	sal_Bool bUndo(pDoc->IsUndoEnabled());
4759*cdf0e10cSrcweir 
4760*cdf0e10cSrcweir 	sal_Bool bRet = sal_False;
4761*cdf0e10cSrcweir 
4762*cdf0e10cSrcweir 	String aFormula;
4763*cdf0e10cSrcweir 	pDoc->GetFormula( nStartCol, nStartRow, nTab, aFormula );
4764*cdf0e10cSrcweir 	if ( aFormula.GetChar(0) == '{' && aFormula.GetChar(aFormula.Len()-1) == '}' )
4765*cdf0e10cSrcweir 	{
4766*cdf0e10cSrcweir 		String aUndo = ScGlobal::GetRscString( STR_UNDO_RESIZEMATRIX );
4767*cdf0e10cSrcweir 		if (bUndo)
4768*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
4769*cdf0e10cSrcweir 
4770*cdf0e10cSrcweir 		aFormula.Erase(0,1);
4771*cdf0e10cSrcweir 		aFormula.Erase(aFormula.Len()-1,1);
4772*cdf0e10cSrcweir 
4773*cdf0e10cSrcweir 		ScMarkData aMark;
4774*cdf0e10cSrcweir 		aMark.SetMarkArea( rOldRange );
4775*cdf0e10cSrcweir 		aMark.SelectTable( nTab, sal_True );
4776*cdf0e10cSrcweir 		ScRange aNewRange( rOldRange.aStart, rNewEnd );
4777*cdf0e10cSrcweir 
4778*cdf0e10cSrcweir 		if ( DeleteContents( aMark, IDF_CONTENTS, sal_True, bApi ) )
4779*cdf0e10cSrcweir 		{
4780*cdf0e10cSrcweir             // GRAM_PODF_A1 for API compatibility.
4781*cdf0e10cSrcweir             bRet = EnterMatrix( aNewRange, &aMark, NULL, aFormula, bApi, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
4782*cdf0e10cSrcweir 			if (!bRet)
4783*cdf0e10cSrcweir 			{
4784*cdf0e10cSrcweir 				//	versuchen, alten Zustand wiederherzustellen
4785*cdf0e10cSrcweir                 EnterMatrix( rOldRange, &aMark, NULL, aFormula, bApi, sal_False, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 );
4786*cdf0e10cSrcweir 			}
4787*cdf0e10cSrcweir 		}
4788*cdf0e10cSrcweir 
4789*cdf0e10cSrcweir 		if (bUndo)
4790*cdf0e10cSrcweir 			rDocShell.GetUndoManager()->LeaveListAction();
4791*cdf0e10cSrcweir 	}
4792*cdf0e10cSrcweir 
4793*cdf0e10cSrcweir 	return bRet;
4794*cdf0e10cSrcweir }
4795*cdf0e10cSrcweir 
4796*cdf0e10cSrcweir //------------------------------------------------------------------------
4797*cdf0e10cSrcweir 
4798*cdf0e10cSrcweir sal_Bool ScDocFunc::InsertAreaLink( const String& rFile, const String& rFilter,
4799*cdf0e10cSrcweir 								const String& rOptions, const String& rSource,
4800*cdf0e10cSrcweir 								const ScRange& rDestRange, sal_uLong nRefresh,
4801*cdf0e10cSrcweir                                 sal_Bool bFitBlock, sal_Bool bApi )
4802*cdf0e10cSrcweir {
4803*cdf0e10cSrcweir 	//!	auch fuer ScViewFunc::InsertAreaLink benutzen!
4804*cdf0e10cSrcweir 
4805*cdf0e10cSrcweir 	ScDocument* pDoc = rDocShell.GetDocument();
4806*cdf0e10cSrcweir 	sal_Bool bUndo (pDoc->IsUndoEnabled());
4807*cdf0e10cSrcweir 
4808*cdf0e10cSrcweir     sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
4809*cdf0e10cSrcweir 
4810*cdf0e10cSrcweir     //  #i52120# if other area links exist at the same start position,
4811*cdf0e10cSrcweir     //  remove them first (file format specifies only one link definition
4812*cdf0e10cSrcweir     //  for a cell)
4813*cdf0e10cSrcweir 
4814*cdf0e10cSrcweir     sal_uInt16 nLinkCount = pLinkManager->GetLinks().Count();
4815*cdf0e10cSrcweir     sal_uInt16 nRemoved = 0;
4816*cdf0e10cSrcweir     sal_uInt16 nLinkPos = 0;
4817*cdf0e10cSrcweir     while (nLinkPos<nLinkCount)
4818*cdf0e10cSrcweir     {
4819*cdf0e10cSrcweir         ::sfx2::SvBaseLink* pBase = *pLinkManager->GetLinks()[nLinkPos];
4820*cdf0e10cSrcweir         if ( pBase->ISA(ScAreaLink) &&
4821*cdf0e10cSrcweir              static_cast<ScAreaLink*>(pBase)->GetDestArea().aStart == rDestRange.aStart )
4822*cdf0e10cSrcweir         {
4823*cdf0e10cSrcweir             if ( bUndo )
4824*cdf0e10cSrcweir             {
4825*cdf0e10cSrcweir                 if ( !nRemoved )
4826*cdf0e10cSrcweir                 {
4827*cdf0e10cSrcweir                     // group all remove and the insert action
4828*cdf0e10cSrcweir                     String aUndo = ScGlobal::GetRscString( STR_UNDO_INSERTAREALINK );
4829*cdf0e10cSrcweir                     rDocShell.GetUndoManager()->EnterListAction( aUndo, aUndo );
4830*cdf0e10cSrcweir                 }
4831*cdf0e10cSrcweir 
4832*cdf0e10cSrcweir                 ScAreaLink* pOldArea = static_cast<ScAreaLink*>(pBase);
4833*cdf0e10cSrcweir                 rDocShell.GetUndoManager()->AddUndoAction(
4834*cdf0e10cSrcweir                     new ScUndoRemoveAreaLink( &rDocShell,
4835*cdf0e10cSrcweir                         pOldArea->GetFile(), pOldArea->GetFilter(), pOldArea->GetOptions(),
4836*cdf0e10cSrcweir                         pOldArea->GetSource(), pOldArea->GetDestArea(), pOldArea->GetRefreshDelay() ) );
4837*cdf0e10cSrcweir             }
4838*cdf0e10cSrcweir             pLinkManager->Remove( pBase );
4839*cdf0e10cSrcweir             nLinkCount = pLinkManager->GetLinks().Count();
4840*cdf0e10cSrcweir             ++nRemoved;
4841*cdf0e10cSrcweir         }
4842*cdf0e10cSrcweir         else
4843*cdf0e10cSrcweir             ++nLinkPos;
4844*cdf0e10cSrcweir     }
4845*cdf0e10cSrcweir 
4846*cdf0e10cSrcweir 	String aFilterName = rFilter;
4847*cdf0e10cSrcweir 	String aNewOptions = rOptions;
4848*cdf0e10cSrcweir 	if (!aFilterName.Len())
4849*cdf0e10cSrcweir         ScDocumentLoader::GetFilterName( rFile, aFilterName, aNewOptions, sal_True, !bApi );
4850*cdf0e10cSrcweir 
4851*cdf0e10cSrcweir 	//	remove application prefix from filter name here, so the filter options
4852*cdf0e10cSrcweir 	//	aren't reset when the filter name is changed in ScAreaLink::DataChanged
4853*cdf0e10cSrcweir 	ScDocumentLoader::RemoveAppPrefix( aFilterName );
4854*cdf0e10cSrcweir 
4855*cdf0e10cSrcweir 	ScAreaLink* pLink = new ScAreaLink( &rDocShell, rFile, aFilterName,
4856*cdf0e10cSrcweir 										aNewOptions, rSource, rDestRange, nRefresh );
4857*cdf0e10cSrcweir 	pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, rFile, &aFilterName, &rSource );
4858*cdf0e10cSrcweir 
4859*cdf0e10cSrcweir 	//	Undo fuer den leeren Link
4860*cdf0e10cSrcweir 
4861*cdf0e10cSrcweir 	if (bUndo)
4862*cdf0e10cSrcweir     {
4863*cdf0e10cSrcweir 		rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertAreaLink( &rDocShell,
4864*cdf0e10cSrcweir 													rFile, aFilterName, aNewOptions,
4865*cdf0e10cSrcweir 													rSource, rDestRange, nRefresh ) );
4866*cdf0e10cSrcweir         if ( nRemoved )
4867*cdf0e10cSrcweir             rDocShell.GetUndoManager()->LeaveListAction();  // undo for link update is still separate
4868*cdf0e10cSrcweir     }
4869*cdf0e10cSrcweir 
4870*cdf0e10cSrcweir 	//	Update hat sein eigenes Undo
4871*cdf0e10cSrcweir     if (pDoc->IsExecuteLinkEnabled())
4872*cdf0e10cSrcweir     {
4873*cdf0e10cSrcweir         pLink->SetDoInsert(bFitBlock);	// beim ersten Update ggf. nichts einfuegen
4874*cdf0e10cSrcweir         pLink->Update();				// kein SetInCreate -> Update ausfuehren
4875*cdf0e10cSrcweir     }
4876*cdf0e10cSrcweir 	pLink->SetDoInsert(sal_True);		// Default = sal_True
4877*cdf0e10cSrcweir 
4878*cdf0e10cSrcweir 	SfxBindings* pBindings = rDocShell.GetViewBindings();
4879*cdf0e10cSrcweir 	if (pBindings)
4880*cdf0e10cSrcweir 		pBindings->Invalidate( SID_LINKS );
4881*cdf0e10cSrcweir 
4882*cdf0e10cSrcweir 	SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );		// Navigator
4883*cdf0e10cSrcweir 
4884*cdf0e10cSrcweir 	return sal_True;
4885*cdf0e10cSrcweir }
4886*cdf0e10cSrcweir 
4887*cdf0e10cSrcweir 
4888*cdf0e10cSrcweir 
4889*cdf0e10cSrcweir 
4890