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