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