xref: /AOO41X/main/sc/source/ui/view/viewfun2.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sc.hxx"
30 
31 // INCLUDE ---------------------------------------------------------------
32 
33 #include "scitems.hxx"
34 #include <editeng/eeitem.hxx>
35 
36 #include <sfx2/app.hxx>
37 #define _SVSTDARR_STRINGS
38 #include <editeng/boxitem.hxx>
39 #include <editeng/fontitem.hxx>
40 #include <editeng/scripttypeitem.hxx>
41 #include <svl/srchitem.hxx>
42 #include <sfx2/linkmgr.hxx>
43 #include <sfx2/dispatch.hxx>
44 #include <sfx2/docfilt.hxx>
45 #include <sfx2/docfile.hxx>
46 #include <sfx2/objitem.hxx>
47 #include <sfx2/viewfrm.hxx>
48 #include <svl/stritem.hxx>
49 #include <svl/zforlist.hxx>
50 #include <svl/svstdarr.hxx>
51 #include <vcl/msgbox.hxx>
52 #include <vcl/sound.hxx>
53 #include <vcl/waitobj.hxx>
54 
55 #include "viewfunc.hxx"
56 
57 #include "sc.hrc"
58 #include "globstr.hrc"
59 
60 #include "attrib.hxx"
61 #include "autoform.hxx"
62 #include "cell.hxx"					// EnterAutoSum
63 #include "compiler.hxx"
64 #include "docfunc.hxx"
65 #include "docpool.hxx"
66 #include "docsh.hxx"
67 #include "global.hxx"
68 #include "patattr.hxx"
69 #include "printfun.hxx"
70 #include "rangenam.hxx"
71 #include "rangeutl.hxx"
72 #include "refundo.hxx"
73 #include "tablink.hxx"
74 #include "tabvwsh.hxx"
75 #include "uiitems.hxx"
76 #include "undoblk.hxx"
77 #include "undocell.hxx"
78 #include "undotab.hxx"
79 #include "sizedev.hxx"
80 #include "editable.hxx"
81 #include "scmod.hxx"
82 #include "inputhdl.hxx"
83 #include "inputwin.hxx"
84 #include "funcdesc.hxx"
85 #include "docuno.hxx"
86 #include "charthelper.hxx"
87 #include "tabbgcolor.hxx"
88 
89 #include <basic/sbstar.hxx>
90 #include <com/sun/star/container/XNameContainer.hpp>
91 #include <com/sun/star/script/XLibraryContainer.hpp>
92 using namespace com::sun::star;
93 
94 // helper func defined in docfunc.cxx
95 void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName );
96 
97 // STATIC DATA ---------------------------------------------------------------
98 
99 
100 //----------------------------------------------------------------------------
101 
102 sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
103 {
104 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
105 	if (!pMarkData)
106 		pMarkData = &GetViewData()->GetMarkData();
107 
108 	ScDocument* pDoc = pDocSh->GetDocument();
109 	SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
110 	SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
111 	if (nRangeCnt == 0)
112 	{
113 		pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
114 		nRangeCnt = 1;
115 	}
116 
117 	double nPPTX = GetViewData()->GetPPTX();
118 	double nPPTY = GetViewData()->GetPPTY();
119 	Fraction aZoomX = GetViewData()->GetZoomX();
120 	Fraction aZoomY = GetViewData()->GetZoomY();
121 
122 	ScSizeDeviceProvider aProv(pDocSh);
123 	if (aProv.IsPrinter())
124 	{
125 		nPPTX = aProv.GetPPTX();
126 		nPPTY = aProv.GetPPTY();
127 		aZoomX = aZoomY = Fraction( 1, 1 );
128 	}
129 
130 	sal_Bool bAnyChanged = sal_False;
131 	SCTAB nTabCount = pDoc->GetTableCount();
132 	for (SCTAB nTab=0; nTab<nTabCount; nTab++)
133 	{
134 		if (pMarkData->GetTableSelect(nTab))
135 		{
136 			SCCOLROW* pOneRange = pRanges;
137 			sal_Bool bChanged = sal_False;
138             SCROW nPaintY = 0;
139 			for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
140 			{
141 				SCROW nStartNo = *(pOneRange++);
142 				SCROW nEndNo = *(pOneRange++);
143 				if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
144 											nPPTX, nPPTY, aZoomX, aZoomY, sal_False ))
145 				{
146 					if (!bChanged)
147 						nPaintY = nStartNo;
148 					bAnyChanged = bChanged = sal_True;
149 				}
150 			}
151 			if ( bPaint && bChanged )
152 				pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
153 													PAINT_GRID | PAINT_LEFT );
154 		}
155 	}
156 	delete[] pRanges;
157 
158 	if ( bPaint && bAnyChanged )
159 		pDocSh->UpdateOle(GetViewData());
160 
161 	return bAnyChanged;
162 }
163 
164 
165 //----------------------------------------------------------------------------
166 
167 sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
168 {
169 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
170 	ScDocument* pDoc = pDocSh->GetDocument();
171 	SCTAB nTab = GetViewData()->GetTabNo();
172 	double nPPTX = GetViewData()->GetPPTX();
173 	double nPPTY = GetViewData()->GetPPTY();
174 	Fraction aZoomX = GetViewData()->GetZoomX();
175 	Fraction aZoomY = GetViewData()->GetZoomY();
176     sal_uInt16 nOldPixel = 0;
177 	if (nStartRow == nEndRow)
178 		nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
179 
180 	ScSizeDeviceProvider aProv(pDocSh);
181 	if (aProv.IsPrinter())
182 	{
183 		nPPTX = aProv.GetPPTX();
184 		nPPTY = aProv.GetPPTY();
185 		aZoomX = aZoomY = Fraction( 1, 1 );
186 	}
187 	sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
188 											nPPTX, nPPTY, aZoomX, aZoomY, sal_False );
189 
190 	if (bChanged && ( nStartRow == nEndRow ))
191 	{
192 		sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
193 		if ( nNewPixel == nOldPixel )
194 			bChanged = sal_False;
195 	}
196 
197 	if ( bPaint && bChanged )
198 		pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
199 											PAINT_GRID | PAINT_LEFT );
200 
201 	return bChanged;
202 }
203 
204 
205 //----------------------------------------------------------------------------
206 
207 enum ScAutoSum
208 {
209 	ScAutoSumNone = 0,
210 	ScAutoSumData,
211 	ScAutoSumSum
212 };
213 
214 
215 ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
216 		SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
217 {
218 	ScBaseCell* pCell;
219 	pDoc->GetCell( nCol, nRow, nTab, pCell );
220 	if ( pCell && pCell->HasValueData() )
221 	{
222 		if ( pCell->GetCellType() == CELLTYPE_FORMULA )
223 		{
224 			ScTokenArray* pCode = ((ScFormulaCell*)pCell)->GetCode();
225 			if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
226 			{
227 				if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
228 						ScAddress( nCol, nRow, nTab ), eDir ) )
229 					return ScAutoSumSum;
230 			}
231 		}
232 		return ScAutoSumData;
233 	}
234 	return ScAutoSumNone;
235 }
236 
237 
238 //----------------------------------------------------------------------------
239 
240 #define SC_AUTOSUM_MAXCOUNT		20
241 
242 ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
243 		SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
244 {
245 	sal_uInt16 nCount = 0;
246 	while (nCount < SC_AUTOSUM_MAXCOUNT)
247 	{
248 		if ( eDir == DIR_TOP )
249 		{
250 			if (nRow > 0)
251 				--nRow;
252 			else
253 				return ScAutoSumNone;
254 		}
255 		else
256 		{
257 			if (nCol > 0)
258 				--nCol;
259 			else
260 				return ScAutoSumNone;
261 		}
262 		ScAutoSum eSum;
263 		if ( (eSum = lcl_IsAutoSumData(
264 				pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
265 			return eSum;
266 		++nCount;
267 	}
268 	return ScAutoSumNone;
269 }
270 
271 #undef SC_AUTOSUM_MAXCOUNT
272 
273 //----------------------------------------------------------------------------
274 
275 bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
276                                    SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
277 {
278     const SCROW nTmp = nRow;
279     ScAutoSum eSkip = ScAutoSumNone;
280     while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
281             nRow > nMinRow )
282     {
283         --nRow;
284     }
285     if ( eSkip == ScAutoSumSum && nRow < nTmp )
286     {
287         return true;
288     }
289     return false;
290 }
291 
292 //----------------------------------------------------------------------------
293 
294 bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
295                                 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
296 {
297     const SCCOL nTmp = nCol;
298     ScAutoSum eSkip = ScAutoSumNone;
299     while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
300             nCol > nMinCol )
301     {
302         --nCol;
303     }
304     if ( eSkip == ScAutoSumSum && nCol < nTmp )
305     {
306         return true;
307     }
308     return false;
309 }
310 
311 //----------------------------------------------------------------------------
312 
313 bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
314 {
315     const ScAddress aStart = rRange.aStart;
316     const ScAddress aEnd = rRange.aEnd;
317     if ( aStart.Col() != aEnd.Col() )
318     {
319         return false;
320     }
321 
322     const SCTAB nTab = aEnd.Tab();
323     const SCCOL nCol = aEnd.Col();
324     SCROW nEndRow = aEnd.Row();
325     SCROW nStartRow = nEndRow;
326     SCCOLROW nExtend = 0;
327     const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
328 
329     if ( eSum == ScAutoSumSum )
330     {
331         bool bContinue = false;
332         do
333         {
334             rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
335             nEndRow = static_cast< SCROW >( nExtend );
336             if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
337             {
338                 nStartRow = nEndRow;
339             }
340         } while ( bContinue );
341     }
342     else
343     {
344         while ( nStartRow > aStart.Row() &&
345                 lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
346         {
347             --nStartRow;
348         }
349         rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
350     }
351 
352     return true;
353 }
354 
355 //----------------------------------------------------------------------------
356 
357 bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
358 {
359     const ScAddress aStart = rRange.aStart;
360     const ScAddress aEnd = rRange.aEnd;
361     if ( aStart.Row() != aEnd.Row() )
362     {
363         return false;
364     }
365 
366     const SCTAB nTab = aEnd.Tab();
367     const SCROW nRow = aEnd.Row();
368     SCCOL nEndCol = aEnd.Col();
369     SCCOL nStartCol = nEndCol;
370     SCCOLROW nExtend = 0;
371     const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
372 
373     if ( eSum == ScAutoSumSum )
374     {
375         bool bContinue = false;
376         do
377         {
378             rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
379             nEndCol = static_cast< SCCOL >( nExtend );
380             if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
381             {
382                 nStartCol = nEndCol;
383             }
384         } while ( bContinue );
385     }
386     else
387     {
388         while ( nStartCol > aStart.Col() &&
389                 lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
390         {
391             --nStartCol;
392         }
393         rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
394     }
395 
396     return true;
397 }
398 
399 //----------------------------------------------------------------------------
400 
401 sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
402 {
403 	ScDocument* pDoc = GetViewData()->GetDocument();
404 	SCTAB nTab = GetViewData()->GetTabNo();
405 
406 	SCCOL nCol = GetViewData()->GetCurX();
407 	SCROW nRow = GetViewData()->GetCurY();
408 
409 	SCCOL nStartCol = nCol;
410 	SCROW nStartRow = nRow;
411 	SCCOL nEndCol	 = nCol;
412 	SCROW nEndRow	 = nRow;
413 	SCCOL nSeekCol	 = nCol;
414 	SCROW nSeekRow	 = nRow;
415 	SCCOLROW nExtend;		// wird per Reference gueltig bei ScAutoSumSum
416 
417 	sal_Bool bCol = sal_False;
418 	sal_Bool bRow = sal_False;
419 
420 	ScAutoSum eSum;
421 	if ( nRow != 0
422 			&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
423 				DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
424 			&& ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
425 				DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
426 		)
427 	{
428 		bRow = sal_True;
429 		nSeekRow = nRow - 1;
430 	}
431 	else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
432 			DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
433 	{
434 		bCol = sal_True;
435 		nSeekCol = nCol - 1;
436 	}
437     else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
438 		bRow = sal_True;
439     else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
440 		bCol = sal_True;
441 
442 	if ( bCol || bRow )
443 	{
444 		if ( bRow )
445 		{
446 			nStartRow = nSeekRow;		// nSeekRow evtl. per Reference angepasst
447 			if ( eSum == ScAutoSumSum )
448 				nEndRow = nStartRow;		// nur Summen summieren
449 			else
450 				nEndRow = nRow - 1;		// Datenbereich evtl. nach unten erweitern
451 		}
452 		else
453 		{
454 			nStartCol = nSeekCol;		// nSeekCol evtl. per Reference angepasst
455 			if ( eSum == ScAutoSumSum )
456 				nEndCol = nStartCol;		// nur Summen summieren
457 			else
458 				nEndCol = nCol - 1;		// Datenbereich evtl. nach rechts erweitern
459 		}
460 		sal_Bool bContinue = sal_False;
461 		do
462 		{
463 			if ( eSum == ScAutoSumData )
464 			{
465 				if ( bRow )
466 				{
467 					while ( nStartRow != 0 && lcl_IsAutoSumData(	pDoc, nCol,
468 							nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
469 						--nStartRow;
470 				}
471 				else
472 				{
473 					while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
474 							nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
475 						--nStartCol;
476 				}
477 			}
478 			rRangeList.Append(
479 				ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
480 			if ( eSum == ScAutoSumSum )
481 			{
482 				if ( bRow )
483 				{
484                     nEndRow = static_cast< SCROW >( nExtend );
485                     if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
486                     {
487                         nStartRow = nEndRow;
488                     }
489 				}
490 				else
491 				{
492                     nEndCol = static_cast< SCCOL >( nExtend );
493                     if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
494                     {
495                         nStartCol = nEndCol;
496                     }
497 				}
498 			}
499 		} while ( bContinue );
500 		return sal_True;
501 	}
502 	return sal_False;
503 }
504 
505 //----------------------------------------------------------------------------
506 
507 void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, sal_Bool bSubTotal)		// Block mit Summen fuellen
508 {
509     String aFormula = GetAutoSumFormula( rRangeList, bSubTotal );
510 	EnterBlock( aFormula, NULL );
511 }
512 
513 //----------------------------------------------------------------------------
514 
515 bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
516 {
517 	ScDocument* pDoc = GetViewData()->GetDocument();
518     const SCTAB nTab = rRange.aStart.Tab();
519     SCCOL nStartCol = rRange.aStart.Col();
520     SCROW nStartRow = rRange.aStart.Row();
521     const SCCOL nEndCol = rRange.aEnd.Col();
522     const SCROW nEndRow = rRange.aEnd.Row();
523     SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
524 
525     // ignore rows at the top of the given range which don't contain autosum data
526     bool bRowData = false;
527     for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
528     {
529         for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
530         {
531             if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
532             {
533                 bRowData = true;
534                 break;
535             }
536         }
537         if ( bRowData )
538         {
539             nStartRow = nRow;
540             break;
541         }
542     }
543     if ( !bRowData )
544     {
545         return false;
546     }
547 
548     // ignore columns at the left of the given range which don't contain autosum data
549     bool bColData = false;
550     for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
551     {
552         for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
553         {
554             if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
555             {
556                 bColData = true;
557                 break;
558             }
559         }
560         if ( bColData )
561         {
562             nStartCol = nCol;
563             break;
564         }
565     }
566     if ( !bColData )
567     {
568         return false;
569     }
570 
571     const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
572     const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
573     bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
574     bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
575 
576     // find an empty row for entering the result
577     SCROW nInsRow = nEndRow;
578     if ( bRow && !bEndRowEmpty )
579     {
580         if ( nInsRow < MAXROW )
581         {
582             ++nInsRow;
583             while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
584             {
585                 if ( nInsRow < MAXROW )
586                 {
587                     ++nInsRow;
588                 }
589                 else
590                 {
591                     bRow = false;
592                     break;
593                 }
594             }
595         }
596         else
597         {
598             bRow = false;
599         }
600     }
601 
602     // find an empty column for entering the result
603     SCCOL nInsCol = nEndCol;
604     if ( bCol && !bEndColEmpty )
605     {
606         if ( nInsCol < MAXCOL )
607         {
608             ++nInsCol;
609             while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
610             {
611                 if ( nInsCol < MAXCOL )
612                 {
613                     ++nInsCol;
614                 }
615                 else
616                 {
617                     bCol = false;
618                     break;
619                 }
620             }
621         }
622         else
623         {
624             bCol = false;
625         }
626     }
627 
628     if ( !bRow && !bCol )
629     {
630         return false;
631     }
632 
633     SCCOL nMarkEndCol = nEndCol;
634     SCROW nMarkEndRow = nEndRow;
635 
636     if ( bRow )
637     {
638         // calculate the row sums for all columns of the given range
639 
640         SCROW nSumEndRow = nEndRow;
641 
642         if ( bEndRowEmpty )
643         {
644             // the last row of the given range is empty;
645             // don't take into account for calculating the autosum
646             --nSumEndRow;
647         }
648         else
649         {
650             // increase mark range
651             ++nMarkEndRow;
652         }
653 
654         for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
655         {
656             if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
657             {
658                 ScRangeList aRangeList;
659                 const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
660                 if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
661                 {
662                     const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
663                     EnterData( nCol, nInsRow, nTab, aFormula );
664                 }
665             }
666         }
667     }
668 
669     if ( bCol )
670     {
671         // calculate the column sums for all rows of the given range
672 
673         SCCOL nSumEndCol = nEndCol;
674 
675         if ( bEndColEmpty )
676         {
677             // the last column of the given range is empty;
678             // don't take into account for calculating the autosum
679             --nSumEndCol;
680         }
681         else
682         {
683             // increase mark range
684             ++nMarkEndCol;
685         }
686 
687         for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
688         {
689             if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
690             {
691                 ScRangeList aRangeList;
692                 const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
693                 if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
694                 {
695                     const String aFormula = GetAutoSumFormula( aRangeList, bSubTotal );
696                     EnterData( nInsCol, nRow, nTab, aFormula );
697                 }
698             }
699         }
700     }
701 
702     // set new mark range and cursor position
703     const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
704     MarkRange( aMarkRange, sal_False, bContinue );
705     if ( bSetCursor )
706     {
707         SetCursor( nMarkEndCol, nMarkEndRow );
708     }
709 
710     return true;
711 }
712 
713 //----------------------------------------------------------------------------
714 
715 String ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal )
716 {
717     String aFormula = '=';
718     ScFunctionMgr* pFuncMgr = ScGlobal::GetStarCalcFunctionMgr();
719     const ScFuncDesc* pDesc = NULL;
720     if ( bSubTotal )
721     {
722         pDesc = pFuncMgr->Get( SC_OPCODE_SUB_TOTAL );
723     }
724     else
725     {
726         pDesc = pFuncMgr->Get( SC_OPCODE_SUM );
727     }
728     if ( pDesc && pDesc->pFuncName )
729     {
730         aFormula += *pDesc->pFuncName;
731         if ( bSubTotal )
732         {
733             aFormula.AppendAscii( RTL_CONSTASCII_STRINGPARAM( "(9;" ) );
734         }
735         else
736         {
737             aFormula += '(';
738         }
739         ScDocument* pDoc = GetViewData()->GetDocument();
740         String aRef;
741         rRangeList.Format( aRef, SCA_VALID, pDoc );
742         aFormula += aRef;
743         aFormula += ')';
744     }
745     return aFormula;
746 }
747 
748 //----------------------------------------------------------------------------
749 
750 void ScViewFunc::EnterBlock( const String& rString, const EditTextObject* pData )
751 {
752 	//	Mehrfachselektion vorher abfragen...
753 
754 	SCCOL nCol = GetViewData()->GetCurX();
755 	SCROW nRow = GetViewData()->GetCurY();
756 	SCTAB nTab = GetViewData()->GetTabNo();
757 	ScMarkData& rMark = GetViewData()->GetMarkData();
758 	if ( rMark.IsMultiMarked() )
759 	{
760 		rMark.MarkToSimple();
761 		if ( rMark.IsMultiMarked() )
762 		{		// "Einfuegen auf Mehrfachselektion nicht moeglich"
763 			ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
764 
765 			//	insert into single cell
766 			if ( pData )
767 				EnterData( nCol, nRow, nTab, pData );
768 			else
769 				EnterData( nCol, nRow, nTab, rString );
770 			return;
771 		}
772 	}
773 
774 	ScDocument* pDoc = GetViewData()->GetDocument();
775 	String aNewStr = rString;
776 	if ( pData )
777 	{
778 		const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
779 		ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
780 		aEngine.SetText(*pData);
781 
782 		ScEditAttrTester aTester( &aEngine );
783 		if (!aTester.NeedsObject())
784 		{
785 			aNewStr = aEngine.GetText();
786 			pData = NULL;
787 		}
788 	}
789 
790 	//	Einfuegen per PasteFromClip
791 
792 	WaitObject aWait( GetFrameWin() );
793 
794 	ScAddress aPos( nCol, nRow, nTab );
795 
796 	ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
797 	pInsDoc->ResetClip( pDoc, nTab );
798 
799 	if (aNewStr.GetChar(0) == '=')						// Formel ?
800 	{
801 		//	SetString geht nicht, weil in Clipboard-Dokumenten nicht kompiliert wird!
802 		ScFormulaCell* pFCell = new ScFormulaCell( pDoc, aPos, aNewStr );
803 		pInsDoc->PutCell( nCol, nRow, nTab, pFCell );
804 	}
805 	else if ( pData )
806 		pInsDoc->PutCell( nCol, nRow, nTab, new ScEditCell( pData, pDoc, NULL ) );
807 	else
808 		pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
809 
810 	pInsDoc->SetClipArea( ScRange(aPos) );
811 	// auf Block einfuegen, mit Undo etc.
812 	if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, sal_False, sal_False,
813 			sal_False, INS_NONE, IDF_ATTRIB ) )
814 	{
815 		const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
816 			nCol, nRow, nTab, ATTR_VALUE_FORMAT );
817 		if ( pItem )
818 		{	// Numberformat setzen wenn inkompatibel
819 			// MarkData wurde bereits in PasteFromClip MarkToSimple'ed
820 			ScRange aRange;
821 			rMark.GetMarkArea( aRange );
822 			ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
823 			pPattern->GetItemSet().Put( *pItem );
824 			short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
825 			pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
826 				*pPattern, nNewType );
827 			delete pPattern;
828 		}
829 	}
830 
831 	delete pInsDoc;
832 }
833 
834 
835 //----------------------------------------------------------------------------
836 
837 //UNUSED2008-05  void ScViewFunc::PaintWidthHeight( sal_Bool bColumns, SCCOLROW nStart, SCCOLROW nEnd )
838 //UNUSED2008-05  {
839 //UNUSED2008-05      SCTAB nTab = GetViewData()->GetTabNo();
840 //UNUSED2008-05      ScDocument* pDoc = GetViewData()->GetDocument();
841 //UNUSED2008-05
842 //UNUSED2008-05      sal_uInt16 nParts = PAINT_GRID;
843 //UNUSED2008-05      SCCOL nStartCol = 0;
844 //UNUSED2008-05      SCROW nStartRow = 0;
845 //UNUSED2008-05      SCCOL nEndCol = MAXCOL;         // fuer Test auf Merge
846 //UNUSED2008-05      SCROW nEndRow = MAXROW;
847 //UNUSED2008-05      if ( bColumns )
848 //UNUSED2008-05      {
849 //UNUSED2008-05          nParts |= PAINT_TOP;
850 //UNUSED2008-05          nStartCol = static_cast<SCCOL>(nStart);
851 //UNUSED2008-05          nEndCol = static_cast<SCCOL>(nEnd);
852 //UNUSED2008-05      }
853 //UNUSED2008-05      else
854 //UNUSED2008-05      {
855 //UNUSED2008-05          nParts |= PAINT_LEFT;
856 //UNUSED2008-05          nStartRow = nStart;
857 //UNUSED2008-05          nEndRow = nEnd;
858 //UNUSED2008-05      }
859 //UNUSED2008-05      if (pDoc->HasAttrib( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab,
860 //UNUSED2008-05                           HASATTR_MERGED | HASATTR_OVERLAPPED ))
861 //UNUSED2008-05      {
862 //UNUSED2008-05          nStartCol = 0;
863 //UNUSED2008-05          nStartRow = 0;
864 //UNUSED2008-05      }
865 //UNUSED2008-05      GetViewData()->GetDocShell()->PostPaint( nStartCol,nStartRow,nTab, MAXCOL,MAXROW,nTab, nParts );
866 //UNUSED2008-05  }
867 
868 
869 //----------------------------------------------------------------------------
870 //	manueller Seitenumbruch
871 
872 void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
873 									sal_Bool bSetModified )
874 {
875 	SCTAB nTab = GetViewData()->GetTabNo();
876 	ScAddress aCursor;
877 	if (pPos)
878 		aCursor = *pPos;
879 	else
880 		aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
881 
882 	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
883 						InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );
884 
885 	if ( bSuccess && bSetModified )
886 		UpdatePageBreakData( sal_True );	// fuer PageBreak-Modus
887 }
888 
889 
890 //----------------------------------------------------------------------------
891 
892 void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
893 									sal_Bool bSetModified )
894 {
895 	SCTAB nTab = GetViewData()->GetTabNo();
896 	ScAddress aCursor;
897 	if (pPos)
898 		aCursor = *pPos;
899 	else
900 		aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
901 
902 	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
903 						RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, sal_False );
904 
905 	if ( bSuccess && bSetModified )
906 		UpdatePageBreakData( sal_True );	// fuer PageBreak-Modus
907 }
908 
909 //----------------------------------------------------------------------------
910 
911 void ScViewFunc::RemoveManualBreaks()
912 {
913 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
914 	ScDocument* pDoc = pDocSh->GetDocument();
915 	SCTAB nTab = GetViewData()->GetTabNo();
916 	sal_Bool bUndo(pDoc->IsUndoEnabled());
917 
918 	if (bUndo)
919 	{
920 		ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
921 		pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
922 		pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, sal_False, pUndoDoc );
923 		pDocSh->GetUndoManager()->AddUndoAction(
924 								new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
925 	}
926 
927 	pDoc->RemoveManualBreaks(nTab);
928 	pDoc->UpdatePageBreaks(nTab);
929 
930 	UpdatePageBreakData( sal_True );
931 	pDocSh->SetDocumentModified();
932 	pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
933 }
934 
935 //----------------------------------------------------------------------------
936 
937 void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
938 {
939 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
940 	SCTAB nTab = GetViewData()->GetTabNo();
941 	pDocSh->SetPrintZoom( nTab, nScale, nPages );
942 }
943 
944 void ScViewFunc::AdjustPrintZoom()
945 {
946 	ScRange aRange;
947 	if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
948 		GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
949 	GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
950 }
951 
952 //----------------------------------------------------------------------------
953 
954 void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const String* pPrint,
955 								const String* pRepCol, const String* pRepRow,
956 								sal_Bool bAddPrint )
957 {
958 	//	on all selected tables
959 
960 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
961 	ScDocument* pDoc	= pDocSh->GetDocument();
962 	SCTAB nTabCount	= pDoc->GetTableCount();
963 	ScMarkData& rMark	= GetViewData()->GetMarkData();
964 	SCTAB nTab;
965 	sal_Bool bUndo (pDoc->IsUndoEnabled());
966 
967 	ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
968 
969     ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
970 
971 	for (nTab=0; nTab<nTabCount; nTab++)
972 		if (rMark.GetTableSelect(nTab))
973 		{
974 			ScRange aRange( 0,0,nTab );
975 
976 			//	print ranges
977 
978             if( !bAddPrint )
979                 pDoc->ClearPrintRanges( nTab );
980 
981             if( bEntireSheet )
982             {
983                 pDoc->SetPrintEntireSheet( nTab );
984             }
985             else if ( pPrint )
986 			{
987                 if ( pPrint->Len() )
988 				{
989                     const sal_Unicode sep = ScCompiler::GetNativeSymbol(ocSep).GetChar(0);
990                     sal_uInt16 nTCount = pPrint->GetTokenCount(sep);
991 					for (sal_uInt16 i=0; i<nTCount; i++)
992 					{
993 						String aToken = pPrint->GetToken(i, sep);
994 						if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
995                             pDoc->AddPrintRange( nTab, aRange );
996 					}
997 				}
998 			}
999             else    // NULL = use selection (print range is always set), use empty string to delete all ranges
1000 			{
1001 				if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
1002 				{
1003                     pDoc->AddPrintRange( nTab, aRange );
1004 				}
1005 				else if ( rMark.IsMultiMarked() )
1006 				{
1007 					rMark.MarkToMulti();
1008 					ScRangeListRef aList( new ScRangeList );
1009 					rMark.FillRangeListWithMarks( aList, sal_False );
1010 					sal_uInt16 nCnt = (sal_uInt16) aList->Count();
1011 					if ( nCnt )
1012 					{
1013 						ScRangePtr pR;
1014 						sal_uInt16 i;
1015 						for ( pR = aList->First(), i=0; i < nCnt;
1016 							  pR = aList->Next(), i++ )
1017 						{
1018                             pDoc->AddPrintRange( nTab, *pR );
1019 						}
1020 					}
1021 				}
1022 			}
1023 
1024 			//	repeat columns
1025 
1026 			if ( pRepCol )
1027 			{
1028 				if ( !pRepCol->Len() )
1029 					pDoc->SetRepeatColRange( nTab, NULL );
1030 				else
1031 					if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
1032 						pDoc->SetRepeatColRange( nTab, &aRange );
1033 			}
1034 
1035 			//	repeat rows
1036 
1037 			if ( pRepRow )
1038 			{
1039 				if ( !pRepRow->Len() )
1040 					pDoc->SetRepeatRowRange( nTab, NULL );
1041 				else
1042 					if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
1043 						pDoc->SetRepeatRowRange( nTab, &aRange );
1044 			}
1045 		}
1046 
1047 	//	undo (for all tables)
1048 	if (bUndo)
1049 	{
1050 		SCTAB nCurTab = GetViewData()->GetTabNo();
1051 		ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
1052 		pDocSh->GetUndoManager()->AddUndoAction(
1053 					new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
1054 	}
1055 
1056 	//	update page breaks
1057 
1058 	for (nTab=0; nTab<nTabCount; nTab++)
1059 		if (rMark.GetTableSelect(nTab))
1060 			ScPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ).UpdatePages();
1061 
1062 	SfxBindings& rBindings = GetViewData()->GetBindings();
1063 	rBindings.Invalidate( SID_DELETE_PRINTAREA );
1064 
1065 	pDocSh->SetDocumentModified();
1066 }
1067 
1068 //----------------------------------------------------------------------------
1069 //	Zellen zusammenfassen
1070 
1071 sal_Bool ScViewFunc::TestMergeCells()			// Vorab-Test (fuer Menue)
1072 {
1073 	//	simple test: sal_True if there's a selection but no multi selection and not filtered
1074 
1075 	const ScMarkData& rMark = GetViewData()->GetMarkData();
1076 	if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1077 	{
1078         ScRange aDummy;
1079         return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
1080 	}
1081 	else
1082 		return sal_False;
1083 }
1084 
1085 
1086 //----------------------------------------------------------------------------
1087 
1088 sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord )
1089 {
1090 	//	Editable- und Verschachtelungs-Abfrage muss vorneweg sein (auch in DocFunc),
1091 	//	damit dann nicht die Inhalte-QueryBox kommt
1092 	ScEditableTester aTester( this );
1093 	if (!aTester.IsEditable())
1094 	{
1095 		ErrorMessage(aTester.GetMessageId());
1096 		return sal_False;
1097 	}
1098 
1099 	ScMarkData& rMark = GetViewData()->GetMarkData();
1100 	rMark.MarkToSimple();
1101 	if (!rMark.IsMarked())
1102 	{
1103 		ErrorMessage(STR_NOMULTISELECT);
1104 		return sal_False;
1105 	}
1106 
1107 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
1108 	ScDocument* pDoc = pDocSh->GetDocument();
1109 
1110 	ScRange aMarkRange;
1111 	rMark.GetMarkArea( aMarkRange );
1112 	SCCOL nStartCol = aMarkRange.aStart.Col();
1113 	SCROW nStartRow = aMarkRange.aStart.Row();
1114 	SCTAB nStartTab = aMarkRange.aStart.Tab();
1115 	SCCOL nEndCol = aMarkRange.aEnd.Col();
1116 	SCROW nEndRow = aMarkRange.aEnd.Row();
1117 	SCTAB nEndTab = aMarkRange.aEnd.Tab();
1118 	if ( nStartCol == nEndCol && nStartRow == nEndRow )
1119 	{
1120 		// nichts zu tun
1121 		return sal_True;
1122 	}
1123 
1124 	if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1125 							HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1126 	{		// "Zusammenfassen nicht verschachteln !"
1127 		ErrorMessage(STR_MSSG_MERGECELLS_0);
1128 		return sal_False;
1129 	}
1130 
1131 	sal_Bool bOk = sal_True;
1132 
1133 	if ( !pDoc->IsBlockEmpty( nStartTab, nStartCol,nStartRow+1, nStartCol,nEndRow, true ) ||
1134 		 !pDoc->IsBlockEmpty( nStartTab, nStartCol+1,nStartRow, nEndCol,nEndRow, true ) )
1135 	{
1136 		if (!bApi)
1137 		{
1138 			MessBox aBox( GetViewData()->GetDialogParent(),
1139 							WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
1140 							ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
1141 							ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
1142 			sal_uInt16 nRetVal = aBox.Execute();
1143 
1144 			if ( nRetVal == RET_YES )
1145 				rDoContents = sal_True;
1146 			else if ( nRetVal == RET_CANCEL )
1147 				bOk = sal_False;
1148 		}
1149 	}
1150 
1151 	if (bOk)
1152 	{
1153 		HideCursor();
1154 		bOk = pDocSh->GetDocFunc().MergeCells( aMarkRange, rDoContents, bRecord, bApi );
1155 		ShowCursor();
1156 
1157 		if (bOk)
1158 		{
1159 			SetCursor( nStartCol, nStartRow );
1160 			//DoneBlockMode( sal_False);
1161 			Unmark();
1162 
1163 			pDocSh->UpdateOle(GetViewData());
1164 			UpdateInputLine();
1165 		}
1166 	}
1167 
1168 	return bOk;
1169 }
1170 
1171 
1172 //----------------------------------------------------------------------------
1173 
1174 sal_Bool ScViewFunc::TestRemoveMerge()
1175 {
1176 	sal_Bool bMerged = sal_False;
1177 	ScRange aRange;
1178 	if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1179 	{
1180 		ScDocument* pDoc = GetViewData()->GetDocument();
1181 		if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1182 			bMerged = sal_True;
1183 	}
1184 	return bMerged;
1185 }
1186 
1187 
1188 //----------------------------------------------------------------------------
1189 
1190 sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
1191 {
1192 	ScRange aRange;
1193     ScEditableTester aTester( this );
1194     if (!aTester.IsEditable())
1195     {
1196         ErrorMessage(aTester.GetMessageId());
1197         return sal_False;
1198     }
1199 	else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1200 	{
1201         ScRange aExtended( aRange );
1202         GetViewData()->GetDocument()->ExtendMerge( aExtended );
1203 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1204 
1205 		HideCursor();
1206 		sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells( aRange, bRecord, sal_False );
1207         MarkRange( aExtended );
1208 		ShowCursor();
1209 
1210 		if (bOk)
1211 			pDocSh->UpdateOle(GetViewData());
1212 	}
1213 	return sal_True;		//! bOk ??
1214 }
1215 
1216 //----------------------------------------------------------------------------
1217 
1218 void ScViewFunc::FillSimple( FillDir eDir, sal_Bool bRecord )
1219 {
1220 	ScRange aRange;
1221 	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1222 	{
1223 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1224 		const ScMarkData& rMark = GetViewData()->GetMarkData();
1225 		sal_Bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, sal_False );
1226 		if (bSuccess)
1227 		{
1228 			pDocSh->UpdateOle(GetViewData());
1229 			UpdateScrollBars();
1230 		}
1231 	}
1232 	else
1233 		ErrorMessage(STR_NOMULTISELECT);
1234 }
1235 
1236 //----------------------------------------------------------------------------
1237 
1238 void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1239 							 double fStart, double fStep, double fMax, sal_Bool bRecord )
1240 {
1241 	ScRange aRange;
1242 	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1243 	{
1244 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1245 		const ScMarkData& rMark = GetViewData()->GetMarkData();
1246 		sal_Bool bSuccess = pDocSh->GetDocFunc().
1247 						FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
1248 									fStart, fStep, fMax, bRecord, sal_False );
1249 		if (bSuccess)
1250 		{
1251 			pDocSh->UpdateOle(GetViewData());
1252 			UpdateScrollBars();
1253 
1254             // #i97876# Spreadsheet data changes are not notified
1255             ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1256             if ( pModelObj && pModelObj->HasChangesListeners() )
1257             {
1258                 ScRangeList aChangeRanges;
1259                 aChangeRanges.Append( aRange );
1260                 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
1261             }
1262 		}
1263 	}
1264 	else
1265 		ErrorMessage(STR_NOMULTISELECT);
1266 }
1267 
1268 //----------------------------------------------------------------------------
1269 
1270 void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
1271 							SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
1272 {
1273 	SCTAB nTab = GetViewData()->GetTabNo();
1274 	ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
1275     ScRange aSourceRange( aRange );
1276 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
1277 	const ScMarkData& rMark = GetViewData()->GetMarkData();
1278 	sal_Bool bSuccess = pDocSh->GetDocFunc().
1279 					FillAuto( aRange, &rMark, eDir, nCount, bRecord, sal_False );
1280 	if (bSuccess)
1281 	{
1282 		MarkRange( aRange, sal_False );			// aRange ist in FillAuto veraendert worden
1283 		pDocSh->UpdateOle(GetViewData());
1284 		UpdateScrollBars();
1285 
1286         // #i97876# Spreadsheet data changes are not notified
1287         ScModelObj* pModelObj = ScModelObj::getImplementation( pDocSh->GetModel() );
1288         if ( pModelObj && pModelObj->HasChangesListeners() )
1289         {
1290             ScRangeList aChangeRanges;
1291             ScRange aChangeRange( aRange );
1292             switch ( eDir )
1293             {
1294                 case FILL_TO_BOTTOM:
1295                     {
1296                         aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
1297                     }
1298                     break;
1299                 case FILL_TO_TOP:
1300                     {
1301                         aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
1302                     }
1303                     break;
1304                 case FILL_TO_RIGHT:
1305                     {
1306                         aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
1307                     }
1308                     break;
1309                 case FILL_TO_LEFT:
1310                     {
1311                         aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
1312                     }
1313                     break;
1314                 default:
1315                     {
1316 
1317                     }
1318                     break;
1319             }
1320             aChangeRanges.Append( aChangeRange );
1321             pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cell-change" ) ), aChangeRanges );
1322         }
1323 	}
1324 }
1325 
1326 //----------------------------------------------------------------------------
1327 
1328 void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
1329 {
1330 	//! allow source sheet to be protected
1331 	ScEditableTester aTester( this );
1332 	if (!aTester.IsEditable())
1333 	{
1334 		ErrorMessage(aTester.GetMessageId());
1335 		return;
1336 	}
1337 
1338 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
1339 	ScDocument* pDoc = pDocSh->GetDocument();
1340 	ScMarkData& rMark = GetViewData()->GetMarkData();
1341 	SCTAB nTab = GetViewData()->GetTabNo();
1342 	sal_Bool bUndo(pDoc->IsUndoEnabled());
1343 
1344 	ScRange aMarkRange;
1345 	rMark.MarkToSimple();
1346 	sal_Bool bMulti = rMark.IsMultiMarked();
1347 	if (bMulti)
1348 		rMark.GetMultiMarkArea( aMarkRange );
1349 	else if (rMark.IsMarked())
1350 		rMark.GetMarkArea( aMarkRange );
1351 	else
1352 		aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
1353 
1354 	ScDocument* pUndoDoc = NULL;
1355 //	if ( bRecord )
1356 	if (bUndo)
1357 	{
1358 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1359 		pUndoDoc->InitUndo( pDoc, nTab, nTab );
1360 //		pUndoDoc->SelectTable( nTab, sal_True );		// nur fuer Markierung
1361 
1362 		SCTAB nTabCount = pDoc->GetTableCount();
1363 		for (SCTAB i=0; i<nTabCount; i++)
1364 			if (i != nTab && rMark.GetTableSelect(i))
1365 			{
1366 				pUndoDoc->AddUndoTab( i, i );
1367 				aMarkRange.aStart.SetTab( i );
1368 				aMarkRange.aEnd.SetTab( i );
1369 				pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
1370 //				pUndoDoc->SelectTable( i, sal_True );
1371 			}
1372 	}
1373 
1374 	if (bMulti)
1375 		pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1376 	else
1377 	{
1378 		aMarkRange.aStart.SetTab( nTab );
1379 		aMarkRange.aEnd.SetTab( nTab );
1380 		pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1381 	}
1382 
1383 //	if ( bRecord )
1384 	if (bUndo)
1385 	{	//! fuer ChangeTrack erst zum Schluss
1386 		pDocSh->GetUndoManager()->AddUndoAction(
1387 			new ScUndoFillTable( pDocSh, rMark,
1388 								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
1389 								aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
1390 								pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
1391 	}
1392 
1393 	pDocSh->PostPaintGridAll();
1394 	pDocSh->PostDataChanged();
1395 }
1396 
1397 //----------------------------------------------------------------------------
1398 
1399 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1400 
1401 	Extends a current selection down to the last non-empty cell of an adjacent
1402 	column when the lower-right corner of the selection is double-clicked.  It
1403 	uses a left-adjoining non-empty column as a guide if such is available,
1404 	otherwise a right-adjoining non-empty column is used.
1405 
1406 	@author Kohei Yoshida (kohei@openoffice.org)
1407 
1408 	@return No return value
1409 
1410 	@see #i12313#
1411 */
1412 void ScViewFunc::FillCrossDblClick()
1413 {
1414 	ScRange aRange;
1415 	GetViewData()->GetSimpleArea( aRange );
1416 	aRange.Justify();
1417 
1418 	SCTAB nTab = GetViewData()->GetCurPos().Tab();
1419 	SCCOL nStartX = aRange.aStart.Col();
1420 	SCROW nStartY = aRange.aStart.Row();
1421 	SCCOL nEndX   = aRange.aEnd.Col();
1422 	SCROW nEndY   = aRange.aEnd.Row();
1423 
1424 	ScDocument* pDoc = GetViewData()->GetDocument();
1425 
1426 	// Make sure the selection is not empty
1427 	if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
1428 		return;
1429 
1430 	if ( nEndY < MAXROW )
1431 	{
1432 		if ( nStartX > 0 )
1433 		{
1434 			SCCOL nMovX = nStartX - 1;
1435 			SCROW nMovY = nStartY;
1436 
1437 			if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1438 				 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1439 			{
1440 				pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
1441 
1442 				if ( nMovY > nEndY )
1443 				{
1444 					FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1445 							  nMovY - nEndY );
1446 					return;
1447 				}
1448 			}
1449 		}
1450 
1451 		if ( nEndX < MAXCOL )
1452 		{
1453 			SCCOL nMovX = nEndX + 1;
1454 			SCROW nMovY = nStartY;
1455 
1456 			if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1457 				 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1458 			{
1459 				pDoc->FindAreaPos( nMovX, nMovY, nTab, 0, 1 );
1460 
1461 				if ( nMovY > nEndY )
1462 				{
1463 					FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1464 							  nMovY - nEndY );
1465 					return;
1466 				}
1467 			}
1468 		}
1469 	}
1470 }
1471 
1472 //----------------------------------------------------------------------------
1473 
1474 void ScViewFunc::TransliterateText( sal_Int32 nType )
1475 {
1476 	ScMarkData aFuncMark = GetViewData()->GetMarkData();
1477 	if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1478 	{
1479 		//	no selection -> use cursor position
1480 
1481 		ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
1482 		aFuncMark.SetMarkArea( ScRange( aCursor ) );
1483 	}
1484 
1485 	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1486 						TransliterateText( aFuncMark, nType, sal_True, sal_False );
1487 	if (bSuccess)
1488 	{
1489 		GetViewData()->GetViewShell()->UpdateInputHandler();
1490 	}
1491 }
1492 
1493 //----------------------------------------------------------------------------
1494 //	AutoFormat
1495 
1496 ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
1497 {
1498 	ScAutoFormatData* pData = NULL;
1499 	SCCOL nStartCol;
1500 	SCROW nStartRow;
1501 	SCTAB nStartTab;
1502 	SCCOL nEndCol;
1503 	SCROW nEndRow;
1504 	SCTAB nEndTab;
1505 	if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1506 	{
1507 		if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
1508 		{
1509 			ScDocument* pDoc = GetViewData()->GetDocument();
1510 			pData = new ScAutoFormatData;
1511 			pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
1512 		}
1513 	}
1514 	return pData;
1515 }
1516 
1517 
1518 //----------------------------------------------------------------------------
1519 
1520 void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
1521 {
1522 #if 1
1523 
1524 	ScRange aRange;
1525 	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1526 	{
1527 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1528 		ScMarkData& rMark = GetViewData()->GetMarkData();
1529 
1530 		sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, sal_False );
1531 		if (bSuccess)
1532 			pDocSh->UpdateOle(GetViewData());
1533 	}
1534 	else
1535 		ErrorMessage(STR_NOMULTISELECT);
1536 
1537 #else
1538 
1539 	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
1540 	sal_Bool bOnlyNotBecauseOfMatrix;
1541 	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
1542 	{
1543 		ErrorMessage(STR_PROTECTIONERR);
1544 		return;
1545 	}
1546 
1547 	SCCOL nStartCol;
1548 	SCROW nStartRow;
1549 	SCTAB nStartTab;
1550 	SCCOL nEndCol;
1551 	SCROW nEndRow;
1552 	SCTAB nEndTab;
1553 
1554 	if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1555 	{
1556 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1557 		ScDocument* pDoc = pDocSh->GetDocument();
1558 		ScMarkData& rMark = GetViewData()->GetMarkData();
1559 		sal_Bool bSize = (*ScGlobal::GetAutoFormat())[nFormatNo]->GetIncludeWidthHeight();
1560 		if (bRecord && !pDoc->IsUndoEnabled())
1561 			bRecord = sal_False;
1562 
1563 		ScDocument* pUndoDoc = NULL;
1564 		if ( bRecord )
1565 		{
1566 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1567 			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab, bSize, bSize );
1568 			pDoc->CopyToDocument( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1569 									IDF_ATTRIB, sal_False, pUndoDoc );
1570 			if (bSize)
1571 			{
1572 				pDoc->CopyToDocument( nStartCol,0,nStartTab, nEndCol,MAXROW,nEndTab,
1573 															IDF_NONE, sal_False, pUndoDoc );
1574 				pDoc->CopyToDocument( 0,nStartRow,nStartTab, MAXCOL,nEndRow,nEndTab,
1575 															IDF_NONE, sal_False, pUndoDoc );
1576 			}
1577 			pDoc->BeginDrawUndo();
1578 		}
1579 
1580 		GetFrameWin()->EnterWait();
1581 		pDoc->AutoFormat( nStartCol, nStartRow, nEndCol, nEndRow, nFormatNo, rMark );
1582 		GetFrameWin()->LeaveWait();
1583 
1584 		if (bSize)
1585 		{
1586 			SetMarkedWidthOrHeight( sal_True, SC_SIZE_VISOPT, STD_EXTRA_WIDTH, sal_False, sal_False );
1587 			SetMarkedWidthOrHeight( sal_False, SC_SIZE_VISOPT, 0, sal_False, sal_False );
1588 			pDocSh->PostPaint( 0,0,nStartTab, MAXCOL,MAXROW,nStartTab,
1589 									PAINT_GRID | PAINT_LEFT | PAINT_TOP );
1590 		}
1591 		else
1592 		{
1593 			sal_Bool bAdj = AdjustBlockHeight( sal_False );
1594 			if (bAdj)
1595 				pDocSh->PostPaint( 0,nStartRow,nStartTab, MAXCOL,MAXROW,nStartTab,
1596 									PAINT_GRID | PAINT_LEFT );
1597 			else
1598 				pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
1599 									nEndCol, nEndRow, nEndTab, PAINT_GRID );
1600 		}
1601 
1602 		if ( bRecord )		// Draw-Undo erst jetzt verfuegbar
1603 		{
1604 			pDocSh->GetUndoManager()->AddUndoAction(
1605 				new ScUndoAutoFormat( pDocSh,
1606 						ScRange(nStartCol,nStartRow,nStartTab, nEndCol,nEndRow,nEndTab),
1607 						pUndoDoc, rMark, bSize, nFormatNo ) );
1608 		}
1609 
1610 		pDocSh->UpdateOle(GetViewData());
1611 		pDocSh->SetDocumentModified();
1612 	}
1613 	else
1614 		ErrorMessage(STR_NOMULTISELECT);
1615 
1616 #endif
1617 }
1618 
1619 
1620 //----------------------------------------------------------------------------
1621 //	Suchen & Ersetzen
1622 
1623 void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
1624 										sal_Bool bAddUndo, sal_Bool bIsApi )
1625 {
1626 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
1627 	ScDocument* pDoc = pDocSh->GetDocument();
1628 	ScMarkData& rMark = GetViewData()->GetMarkData();
1629 	if (bAddUndo && !pDoc->IsUndoEnabled())
1630 		bAddUndo = sal_False;
1631 
1632 	SCCOL nCol = GetViewData()->GetCurX();
1633 	SCROW nRow = GetViewData()->GetCurY();
1634 	SCTAB nTab = GetViewData()->GetTabNo();
1635 //    sal_Bool bAttrib = pSearchItem->GetPattern();
1636 	sal_uInt16 nCommand = pSearchItem->GetCommand();
1637 	sal_Bool bAllTables = pSearchItem->IsAllTables();
1638 	sal_Bool* pOldSelectedTables = NULL;
1639 	sal_uInt16 nOldSelectedCount = 0;
1640 	SCTAB nOldTab = nTab;
1641 	SCTAB nLastTab = pDoc->GetTableCount() - 1;
1642 	SCTAB nStartTab, nEndTab;
1643 	if ( bAllTables )
1644 	{
1645 		nStartTab = 0;
1646 		nEndTab = nLastTab;
1647 		pOldSelectedTables = new sal_Bool [ nEndTab + 1 ];
1648 		for ( SCTAB j = 0; j <= nEndTab; j++ )
1649 		{
1650 			pOldSelectedTables[j] = rMark.GetTableSelect( j );
1651 			if ( pOldSelectedTables[j] )
1652 				++nOldSelectedCount;
1653 		}
1654 	}
1655 	else
1656 	{	//! mindestens eine ist immer selektiert
1657 		nStartTab = nEndTab = rMark.GetFirstSelected();
1658 		for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
1659 		{
1660 			if ( rMark.GetTableSelect( j ) )
1661 				nEndTab = j;
1662 		}
1663 	}
1664 
1665 	if (   nCommand == SVX_SEARCHCMD_REPLACE
1666 		|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1667 	{
1668 		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1669 		{
1670 			if ( (bAllTables || rMark.GetTableSelect( j )) &&
1671 					pDoc->IsTabProtected( j ) )
1672 			{
1673 				if ( pOldSelectedTables )
1674 					delete [] pOldSelectedTables;
1675 				ErrorMessage(STR_PROTECTIONERR);
1676 				return;
1677 			}
1678 		}
1679 	}
1680 
1681 	if (   nCommand == SVX_SEARCHCMD_FIND
1682 		|| nCommand == SVX_SEARCHCMD_FIND_ALL)
1683 		bAddUndo = sal_False;
1684 
1685 	//!		bAttrib bei Undo beruecksichtigen !!!
1686 
1687 	ScDocument* pUndoDoc = NULL;
1688 	ScMarkData* pUndoMark = NULL;
1689 	String aUndoStr;
1690 	if (bAddUndo)
1691 	{
1692 		pUndoMark = new ScMarkData( rMark );				// Markierung wird veraendert
1693 		if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1694 		{
1695 			pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1696 			pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
1697 		}
1698 	}
1699 
1700 	if ( bAllTables )
1701 	{	//! alles selektieren, erst nachdem pUndoMark erzeugt wurde
1702 		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1703 		{
1704 			rMark.SelectTable( j, sal_True );
1705 		}
1706 	}
1707 
1708 	DoneBlockMode(sal_True);				// Markierung nicht loeschen!
1709 	InitOwnBlockMode();
1710 
1711 	//	wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
1712 	sal_Bool bFirst = sal_True;
1713 	if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward()  )
1714 		bFirst = sal_False;
1715 
1716 	sal_Bool bFound = sal_False;
1717 	while (sal_True)
1718 	{
1719 		GetFrameWin()->EnterWait();
1720 		if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
1721 		{
1722 			bFound = sal_True;
1723 			bFirst = sal_True;
1724 			if (bAddUndo)
1725 			{
1726 				GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1727 					new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
1728 										nCol, nRow, nTab,
1729 										aUndoStr, pUndoDoc, pSearchItem ) );
1730 				pUndoDoc = NULL;
1731 			}
1732 
1733 			break;					// Abbruch while True
1734 		}
1735 		else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
1736 				nCommand == SVX_SEARCHCMD_REPLACE) )
1737 		{
1738 			bFirst = sal_False;
1739 			sal_uInt16 nRetVal;
1740 			GetFrameWin()->LeaveWait();
1741 			if ( bIsApi )
1742 				nRetVal = RET_NO;
1743 			else
1744 			{
1745 				//	Suchen-Dialog als Parent, wenn vorhanden
1746 				Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1747 				sal_uInt16 nStrId;
1748 				if ( pSearchItem->GetBackward() )
1749 				{
1750 					if ( nStartTab == nEndTab )
1751 						nStrId = STR_MSSG_SEARCHANDREPLACE_1;
1752 					else
1753 						nStrId = STR_MSSG_SEARCHANDREPLACE_4;
1754 				}
1755 				else
1756 				{
1757 					if ( nStartTab == nEndTab )
1758 						nStrId = STR_MSSG_SEARCHANDREPLACE_2;
1759 					else
1760 						nStrId = STR_MSSG_SEARCHANDREPLACE_5;
1761 				}
1762 				MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
1763 								ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
1764 								ScGlobal::GetRscString( nStrId ) );
1765 				nRetVal = aBox.Execute();
1766 			}
1767 
1768 			if ( nRetVal == RET_YES )
1769 			{
1770 				ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
1771 				if (pSearchItem->GetBackward())
1772 					nTab = nEndTab;
1773 				else
1774 					nTab = nStartTab;
1775 			}
1776 			else
1777 			{
1778 				break;					// Abbruch while True
1779 			}
1780 		}
1781 		else							// nichts gefunden
1782 		{
1783 			if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1784 			{
1785 				pDocSh->PostPaintGridAll();								// Markierung
1786 			}
1787 
1788 			GetFrameWin()->LeaveWait();
1789 			if (!bIsApi)
1790 			{
1791 				//	Suchen-Dialog als Parent, wenn vorhanden
1792 				Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1793 				// "nichts gefunden"
1794 				InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
1795 				aBox.Execute();
1796 			}
1797 
1798 			break;						// Abbruch while True
1799 		}
1800 	}								// of while sal_True
1801 
1802 	if ( pOldSelectedTables )
1803 	{	// urspruenglich selektierte Tabellen wiederherstellen
1804 		for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1805 		{
1806 			rMark.SelectTable( j, pOldSelectedTables[j] );
1807 		}
1808 		if ( bFound )
1809 		{	// durch Fundstelle neu selektierte Tabelle bleibt
1810 			rMark.SelectTable( nTab, sal_True );
1811 			// wenn vorher nur eine selektiert war, ist es ein Tausch
1812 			//! wenn nicht, ist jetzt evtl. eine mehr selektiert
1813 			if ( nOldSelectedCount == 1 && nTab != nOldTab )
1814 				rMark.SelectTable( nOldTab, sal_False );
1815 		}
1816 		delete [] pOldSelectedTables;
1817 	}
1818 
1819     MarkDataChanged();
1820 
1821 	if ( bFound )
1822 	{
1823 		if ( nTab != GetViewData()->GetTabNo() )
1824 			SetTabNo( nTab );
1825 
1826 		//	wenn nichts markiert ist, DoneBlockMode, damit von hier aus
1827 		//	direkt per Shift-Cursor markiert werden kann:
1828 		if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1829 			DoneBlockMode(sal_True);
1830 
1831 		AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
1832 		SetCursor( nCol, nRow, sal_True );
1833 
1834 		if (   nCommand == SVX_SEARCHCMD_REPLACE
1835 			|| nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1836 		{
1837 			if ( nCommand == SVX_SEARCHCMD_REPLACE )
1838 				pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
1839 			else
1840 				pDocSh->PostPaintGridAll();
1841 			pDocSh->SetDocumentModified();
1842 		}
1843 		else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
1844 			pDocSh->PostPaintGridAll();								// Markierung
1845 		GetFrameWin()->LeaveWait();
1846 	}
1847 
1848 	delete pUndoDoc;			// loeschen wenn nicht benutzt
1849 	delete pUndoMark;			// kann immer geloescht werden
1850 }
1851 
1852 
1853 //----------------------------------------------------------------------------
1854 //	Zielwertsuche
1855 
1856 void ScViewFunc::Solve( const ScSolveParam& rParam )
1857 {
1858 	ScDocument* pDoc = GetViewData()->GetDocument();
1859 
1860 	SCCOL nDestCol = rParam.aRefVariableCell.Col();
1861 	SCROW nDestRow = rParam.aRefVariableCell.Row();
1862 	SCTAB nDestTab = rParam.aRefVariableCell.Tab();
1863 
1864 	ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
1865 	if (!aTester.IsEditable())
1866 	{
1867 		ErrorMessage(aTester.GetMessageId());
1868 		return;
1869 	}
1870 
1871 	if ( pDoc )
1872 	{
1873 		String  aTargetValStr;
1874 		if ( rParam.pStrTargetVal != NULL )
1875 			aTargetValStr = *(rParam.pStrTargetVal);
1876 
1877 		String  aMsgStr;
1878 		String	aResStr;
1879 		double	nSolveResult;
1880 
1881 		GetFrameWin()->EnterWait();
1882 
1883 		sal_Bool  	bExact =
1884 					pDoc->Solver(
1885 						rParam.aRefFormulaCell.Col(),
1886 						rParam.aRefFormulaCell.Row(),
1887 						rParam.aRefFormulaCell.Tab(),
1888 						nDestCol, nDestRow, nDestTab,
1889 						aTargetValStr,
1890 						nSolveResult );
1891 
1892 		GetFrameWin()->LeaveWait();
1893 
1894 		SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1895 		sal_uLong nFormat = 0;
1896 		const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
1897 		if ( pPattern )
1898 			nFormat = pPattern->GetNumberFormat( pFormatter );
1899 		Color* p;
1900 		pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
1901 
1902 		if ( bExact )
1903 		{
1904 			aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
1905 			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
1906 			aMsgStr += String( aResStr );
1907 			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
1908 		}
1909 		else
1910 		{
1911 			aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
1912 			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
1913 			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
1914 			aMsgStr += String( aResStr );
1915 			aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
1916 		}
1917 
1918 		MessBox aBox( GetViewData()->GetDialogParent(),
1919 						WinBits(WB_YES_NO | WB_DEF_NO),
1920 						ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
1921 		sal_uInt16 nRetVal = aBox.Execute();
1922 
1923 		if ( RET_YES == nRetVal )
1924 			EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
1925 
1926 		GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
1927 	}
1928 }
1929 
1930 
1931 //----------------------------------------------------------------------------
1932 //	Mehrfachoperation
1933 
1934 void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
1935 {
1936 	ScRange aRange;
1937 	if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1938 	{
1939 		ScDocShell* pDocSh = GetViewData()->GetDocShell();
1940 		ScMarkData& rMark = GetViewData()->GetMarkData();
1941 		pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False );
1942 	}
1943 	else
1944 		ErrorMessage(STR_NOMULTISELECT);
1945 }
1946 
1947 
1948 //----------------------------------------------------------------------------
1949 
1950 void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
1951 									const Color& rColor, sal_uInt16 nFlags )
1952 {
1953 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
1954 	ScMarkData&	rMark	= GetViewData()->GetMarkData();
1955 	SCTAB		nTab	= GetViewData()->GetTabNo();
1956 
1957 	SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
1958 	if (nFlags & SC_SCENARIO_COPYALL)
1959 		SetTabNo( nNewTab, sal_True );			// SC_SCENARIO_COPYALL -> sichtbar
1960 	else
1961 	{
1962 		SfxBindings& rBindings = GetViewData()->GetBindings();
1963 		rBindings.Invalidate( SID_STATUS_DOCPOS );		// Statusbar
1964 		rBindings.Invalidate( SID_TABLES_COUNT );
1965 		rBindings.Invalidate( SID_SELECT_SCENARIO );
1966 		rBindings.Invalidate( FID_TABLE_SHOW );
1967 	}
1968 }
1969 
1970 
1971 //----------------------------------------------------------------------------
1972 
1973 void ScViewFunc::ExtendScenario()
1974 {
1975 	ScEditableTester aTester( this );
1976 	if (!aTester.IsEditable())
1977 	{
1978 		ErrorMessage(aTester.GetMessageId());
1979 		return;
1980 	}
1981 
1982 		//	Undo: Attribute anwenden
1983 
1984 	ScDocument* pDoc = GetViewData()->GetDocument();
1985 	ScPatternAttr aPattern( pDoc->GetPool() );
1986 	aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
1987 	aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
1988 	ApplySelectionPattern(aPattern);
1989 }
1990 
1991 
1992 //----------------------------------------------------------------------------
1993 
1994 void ScViewFunc::UseScenario( const String& rName )
1995 {
1996 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
1997 	SCTAB		nTab	= GetViewData()->GetTabNo();
1998 
1999 	DoneBlockMode();
2000 	InitOwnBlockMode();
2001 	pDocSh->UseScenario( nTab, rName );
2002 }
2003 
2004 
2005 //----------------------------------------------------------------------------
2006 //	Tabelle einfuegen
2007 
2008 sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
2009 {
2010 	//	Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2011 	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2012 						InsertTable( nTab, rName, bRecord, sal_False );
2013 	if (bSuccess)
2014 		SetTabNo( nTab, sal_True );
2015 
2016 	return bSuccess;
2017 }
2018 
2019 //----------------------------------------------------------------------------
2020 //	Tabellen einfuegen
2021 
2022 sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
2023 											SCTAB nCount, sal_Bool bRecord )
2024 {
2025 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
2026 	ScDocument* pDoc 	= pDocSh->GetDocument();
2027 	if (bRecord && !pDoc->IsUndoEnabled())
2028 		bRecord = sal_False;
2029 
2030 	SvStrings *pNameList= NULL;
2031 
2032 	WaitObject aWait( GetFrameWin() );
2033 
2034 	if (bRecord)
2035 	{
2036 		pNameList= new SvStrings;
2037 		pDoc->BeginDrawUndo();							//	InsertTab erzeugt ein SdrUndoNewPage
2038 	}
2039 
2040 	sal_Bool bFlag=sal_False;
2041 
2042 	String aValTabName;
2043 	String *pStr;
2044 
2045 	for(SCTAB i=0;i<nCount;i++)
2046 	{
2047 		if(pNames!=NULL)
2048 		{
2049 			pStr=pNames->GetObject(static_cast<sal_uInt16>(i));
2050 		}
2051 		else
2052 		{
2053 			aValTabName.Erase();
2054 			pDoc->CreateValidTabName( aValTabName);
2055 			pStr=&aValTabName;
2056 		}
2057 
2058 		if(pDoc->InsertTab( nTab+i,*pStr))
2059 		{
2060 			bFlag=sal_True;
2061 			pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
2062 		}
2063 		else
2064 		{
2065 			break;
2066 		}
2067 
2068 		if(pNameList!=NULL)
2069 			pNameList->Insert(new String(*pStr),pNameList->Count());
2070 
2071 	}
2072 
2073 	if (bFlag)
2074 	{
2075 		if (bRecord)
2076 			pDocSh->GetUndoManager()->AddUndoAction(
2077 						new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList));
2078 
2079 		//	Views updaten:
2080 
2081 		SetTabNo( nTab, sal_True );
2082 		pDocSh->PostPaintExtras();
2083 		pDocSh->SetDocumentModified();
2084 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2085 		return sal_True;
2086 	}
2087 	else
2088 	{
2089 		return sal_False;
2090 	}
2091 }
2092 
2093 
2094 //----------------------------------------------------------------------------
2095 
2096 sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
2097 {
2098 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
2099 	ScDocument* pDoc   = pDocSh->GetDocument();
2100 	if (bRecord && !pDoc->IsUndoEnabled())
2101 		bRecord = sal_False;
2102 
2103 	WaitObject aWait( GetFrameWin() );
2104 
2105 	if (bRecord)
2106 		pDoc->BeginDrawUndo();							//	InsertTab erzeugt ein SdrUndoNewPage
2107 
2108 	if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
2109 	{
2110 		SCTAB nTab = pDoc->GetTableCount()-1;
2111 		if (bRecord)
2112 			pDocSh->GetUndoManager()->AddUndoAction(
2113 						new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2114 		GetViewData()->InsertTab( nTab );
2115 		SetTabNo( nTab, sal_True );
2116 		pDocSh->PostPaintExtras();
2117 		pDocSh->SetDocumentModified();
2118 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2119 		return sal_True;
2120 	}
2121 	else
2122 	{
2123 		return sal_False;
2124 	}
2125 }
2126 
2127 
2128 //----------------------------------------------------------------------------
2129 
2130 sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2131 {
2132 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
2133 	ScDocument* pDoc 	= pDocSh->GetDocument();
2134 
2135 	sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False );
2136 	if (bSuccess)
2137 	{
2138 		SCTAB nNewTab = nTab;
2139 		if ( nNewTab >= pDoc->GetTableCount() )
2140 			--nNewTab;
2141 		SetTabNo( nNewTab, sal_True );
2142 	}
2143 	return bSuccess;
2144 }
2145 
2146 sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord )
2147 {
2148 	ScDocShell* pDocSh	= GetViewData()->GetDocShell();
2149 	ScDocument* pDoc 	= pDocSh->GetDocument();
2150     sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False;
2151 	SCTAB		nNewTab = TheTabs.front();
2152 	WaitObject aWait( GetFrameWin() );
2153 	if (bRecord && !pDoc->IsUndoEnabled())
2154 		bRecord = sal_False;
2155 
2156 	while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2157 		--nNewTab;
2158 
2159 	sal_Bool bWasLinked = sal_False;
2160 	ScDocument* pUndoDoc = NULL;
2161 	ScRefUndoData* pUndoData = NULL;
2162 	if (bRecord)
2163 	{
2164 		pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2165 //		pUndoDoc->InitDrawLayer( pDocSh );
2166 		SCTAB nCount = pDoc->GetTableCount();
2167 
2168 //		pUndoDoc->InitUndo( pDoc, 0, nCount-1 );		// incl. Ref.
2169 
2170 		String aOldName;
2171         for (size_t i = 0; i < TheTabs.size(); i++)
2172         {
2173             SCTAB nTab = TheTabs[i];
2174 			if (i==0)
2175 				pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True );	// incl. Spalten/Zeilenflags
2176 			else
2177 				pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True );		// incl. Spalten/Zeilenflags
2178 
2179 			pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
2180 			pDoc->GetName( nTab, aOldName );
2181 			pUndoDoc->RenameTab( nTab, aOldName, sal_False );
2182 			if (pDoc->IsLinked(nTab))
2183 			{
2184 				bWasLinked = sal_True;
2185 				pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2186 									pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2187 									pDoc->GetLinkTab(nTab),
2188 									pDoc->GetLinkRefreshDelay(nTab) );
2189 			}
2190 			if ( pDoc->IsScenario(nTab) )
2191 			{
2192 				pUndoDoc->SetScenario( nTab, sal_True );
2193 				String aComment;
2194 				Color  aColor;
2195 				sal_uInt16 nScenFlags;
2196 				pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2197 				pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2198 				sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2199 				pUndoDoc->SetActiveScenario( nTab, bActive );
2200 			}
2201 			pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2202             pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
2203             pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2204 
2205 			if ( pDoc->IsTabProtected( nTab ) )
2206                 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
2207 
2208 			//	Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
2209 			//		pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2210 		}
2211 
2212 		pUndoDoc->AddUndoTab( 0, nCount-1 );			//	alle Tabs fuer Referenzen
2213 
2214 		pDoc->BeginDrawUndo();							//	DeleteTab erzeugt ein SdrUndoDelPage
2215 
2216 		pUndoData = new ScRefUndoData( pDoc );
2217 	}
2218 
2219 	sal_Bool bDelDone = sal_False;
2220 
2221     for (size_t i = TheTabs.size(); i > 0; i--)
2222     {
2223         String sCodeName;
2224         sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName );
2225         if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc ))
2226 		{
2227 			bDelDone = sal_True;
2228             if( bVbaEnabled )
2229             {
2230                 if( bHasCodeName )
2231                 {
2232                     VBA_DeleteModule( *pDocSh, sCodeName );
2233                 }
2234             }
2235             pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) );
2236 		}
2237 	}
2238 	if (bRecord)
2239 	{
2240 		pDocSh->GetUndoManager()->AddUndoAction(
2241 					new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
2242 											pUndoDoc, pUndoData ));
2243 	}
2244 
2245 
2246 	if (bDelDone)
2247 	{
2248 		if ( nNewTab >= pDoc->GetTableCount() )
2249 			nNewTab = pDoc->GetTableCount() - 1;
2250 
2251 		SetTabNo( nNewTab, sal_True );
2252 
2253 		if (bWasLinked)
2254 		{
2255 			pDocSh->UpdateLinks();				// Link-Manager updaten
2256 			GetViewData()->GetBindings().Invalidate(SID_LINKS);
2257 		}
2258 
2259 		pDocSh->PostPaintExtras();
2260 		pDocSh->SetDocumentModified();
2261 
2262         SfxApplication* pSfxApp = SFX_APP();                                // Navigator
2263         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2264         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2265         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2266 	}
2267 	else
2268 	{
2269 		delete pUndoDoc;
2270 		delete pUndoData;
2271 	}
2272 	return bDelDone;
2273 }
2274 
2275 
2276 //----------------------------------------------------------------------------
2277 
2278 sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2279 {
2280 	//	Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2281 	sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2282 						RenameTable( nTab, rName, sal_True, sal_False );
2283 	if (bSuccess)
2284 	{
2285 		//	Der Tabellenname koennte in einer Formel vorkommen...
2286 		GetViewData()->GetViewShell()->UpdateInputHandler();
2287 	}
2288 	return bSuccess;
2289 }
2290 
2291 
2292 //----------------------------------------------------------------------------
2293 
2294 bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
2295 {
2296     bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False );
2297     if (bSuccess)
2298     {
2299         GetViewData()->GetViewShell()->UpdateInputHandler();
2300     }
2301     return bSuccess;
2302 }
2303 
2304 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
2305 {
2306     bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False );
2307     if (bSuccess)
2308     {
2309         GetViewData()->GetViewShell()->UpdateInputHandler();
2310     }
2311     return bSuccess;
2312 }
2313 
2314 //----------------------------------------------------------------------------
2315 
2316 void ScViewFunc::InsertAreaLink( const String& rFile,
2317 									const String& rFilter, const String& rOptions,
2318 									const String& rSource, sal_uLong nRefresh )
2319 {
2320 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
2321 	SCCOL nPosX = GetViewData()->GetCurX();
2322 	SCROW nPosY = GetViewData()->GetCurY();
2323 	SCTAB nTab = GetViewData()->GetTabNo();
2324 	ScAddress aPos( nPosX, nPosY, nTab );
2325 
2326     pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False );
2327 }
2328 
2329 
2330 //----------------------------------------------------------------------------
2331 
2332 void ScViewFunc::InsertTableLink( const String& rFile,
2333 									const String& rFilter, const String& rOptions,
2334 									const String& rTabName )
2335 {
2336 	String aFilterName = rFilter;
2337 	String aOpt = rOptions;
2338 	ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
2339 	if (!aLoader.IsError())
2340 	{
2341 		ScDocShell* pSrcSh = aLoader.GetDocShell();
2342 		ScDocument* pSrcDoc = pSrcSh->GetDocument();
2343 		SCTAB nTab = MAXTAB+1;
2344 		if (!rTabName.Len())				// kein Name angegeben -> erste Tabelle
2345 			nTab = 0;
2346 		else
2347 		{
2348 			String aTemp;
2349 			SCTAB nCount = pSrcDoc->GetTableCount();
2350 			for (SCTAB i=0; i<nCount; i++)
2351 			{
2352 				pSrcDoc->GetName( i, aTemp );
2353 				if ( aTemp == rTabName )
2354 					nTab = i;
2355 			}
2356 		}
2357 
2358 		if ( nTab <= MAXTAB )
2359 			ImportTables( pSrcSh, 1, &nTab, sal_True,
2360 						GetViewData()->GetTabNo() );
2361 	}
2362 }
2363 
2364 
2365 //----------------------------------------------------------------------------
2366 //	Tabellen aus anderem Dokument kopieren / linken
2367 
2368 void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
2369 								SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2370 {
2371 	ScDocument* pSrcDoc = pSrcShell->GetDocument();
2372 
2373 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
2374 	ScDocument* pDoc = pDocSh->GetDocument();
2375 	sal_Bool bUndo(pDoc->IsUndoEnabled());
2376 	//SCTAB nTab = GetViewData()->GetTabNo();
2377 
2378 	sal_Bool bError = sal_False;
2379 	sal_Bool bRefs = sal_False;
2380 	sal_Bool bName = sal_False;
2381 
2382 	if (pSrcDoc->GetDrawLayer())
2383 		pDocSh->MakeDrawLayer();
2384 
2385 	if (bUndo)
2386 		pDoc->BeginDrawUndo();			// drawing layer must do its own undo actions
2387 
2388 	SCTAB nInsCount = 0;
2389 	SCTAB i;
2390 	for( i=0; i<nCount; i++ )
2391 	{	// #63304# insert sheets first and update all references
2392 		String aName;
2393 		pSrcDoc->GetName( pSrcTabs[i], aName );
2394 		pDoc->CreateValidTabName( aName );
2395 		if ( !pDoc->InsertTab( nTab+i, aName ) )
2396 		{
2397 			bError = sal_True;		// total error
2398 			break;	// for
2399 		}
2400 		++nInsCount;
2401 	}
2402 	for (i=0; i<nCount && !bError; i++)
2403 	{
2404 		SCTAB nSrcTab = pSrcTabs[i];
2405 		SCTAB nDestTab1=nTab+i;
2406 		sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
2407 			sal_False );		// no insert
2408 
2409 		switch (nErrVal)
2410 		{
2411 			case 0:						// interner Fehler oder voll Fehler
2412 				bError = sal_True;
2413 				break;
2414 			case 2:
2415 				bRefs = sal_True;
2416 				break;
2417 			case 3:
2418 				bName = sal_True;
2419 				break;
2420 			case 4:
2421 				bRefs = bName = sal_True;
2422 				break;
2423 		}
2424 
2425 		// TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2426 		if ( !bError )
2427 			pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
2428 
2429 		if(!bError &&pSrcDoc->IsScenario(nSrcTab))
2430 		{
2431 			String aComment;
2432 			Color  aColor;
2433 			sal_uInt16 nFlags;
2434 
2435 			pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
2436 			pDoc->SetScenario( nDestTab1,sal_True);
2437 			pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
2438 			sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab );
2439 			pDoc->SetActiveScenario( nDestTab1, bActive );
2440 			sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab);
2441 			pDoc->SetVisible(nDestTab1,bVisible );
2442 
2443 		}
2444 	}
2445 
2446 	if (bLink)
2447 	{
2448 		sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2449 
2450 		SfxMedium* pMed = pSrcShell->GetMedium();
2451 		String aFileName = pMed->GetName();
2452 		String aFilterName;
2453 		if (pMed->GetFilter())
2454 			aFilterName = pMed->GetFilter()->GetFilterName();
2455 		String aOptions = ScDocumentLoader::GetOptions(*pMed);
2456 
2457 		sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2458 
2459 		sal_uLong nRefresh = 0;
2460 		String aTabStr;
2461 		for (i=0; i<nInsCount; i++)
2462 		{
2463 			pSrcDoc->GetName( pSrcTabs[i], aTabStr );
2464 			pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2465 						aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2466 		}
2467 
2468 		if (!bWasThere)			// Link pro Quelldokument nur einmal eintragen
2469 		{
2470 			ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2471 			pLink->SetInCreate( sal_True );
2472 			pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
2473 			pLink->Update();
2474 			pLink->SetInCreate( sal_False );
2475 
2476 			SfxBindings& rBindings = GetViewData()->GetBindings();
2477 			rBindings.Invalidate( SID_LINKS );
2478 		}
2479 	}
2480 
2481 
2482 	if (bUndo)
2483 	{
2484 		pDocSh->GetUndoManager()->AddUndoAction(
2485 				new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
2486 	}
2487 
2488 	for (i=0; i<nInsCount; i++)
2489 		GetViewData()->InsertTab(nTab);
2490 	SetTabNo(nTab,sal_True);
2491 	pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2492 								PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
2493 
2494 	SfxApplication* pSfxApp = SFX_APP();
2495 	pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2496 	pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
2497 
2498 	pDocSh->PostPaintExtras();
2499 	pDocSh->PostPaintGridAll();
2500 	pDocSh->SetDocumentModified();
2501 
2502 	if (bRefs)
2503 		ErrorMessage(STR_ABSREFLOST);
2504 	if (bName)
2505 		ErrorMessage(STR_NAMECONFLICT);
2506 }
2507 
2508 
2509 //----------------------------------------------------------------------------
2510 //	Tabelle in anderes Dokument verschieben / kopieren
2511 
2512 void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy )
2513 {
2514 	ScDocument* pDoc	   = GetViewData()->GetDocument();
2515 	ScDocShell* pDocShell  = GetViewData()->GetDocShell();
2516 	ScDocument*	pDestDoc   = NULL;
2517 	ScDocShell* pDestShell = NULL;
2518 	ScTabViewShell* pDestViewSh = NULL;
2519 	sal_Bool bUndo (pDoc->IsUndoEnabled());
2520 
2521 	sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW );
2522 	if ( bNewDoc )
2523 	{
2524         nDestTab = 0;           // als erstes einfuegen
2525 
2526 		//	ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
2527 
2528 		String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
2529 		aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP ));				// "scalc"
2530 		SfxStringItem aItem( SID_FILE_NAME, aUrl );
2531 		SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
2532 
2533 		const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
2534 					SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
2535 		if ( pRetItem )
2536 		{
2537 			if ( pRetItem->ISA( SfxObjectItem ) )
2538 				pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
2539 			else if ( pRetItem->ISA( SfxViewFrameItem ) )
2540 			{
2541 				SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
2542 				if (pFrm)
2543 					pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2544 			}
2545 			if (pDestShell)
2546 				pDestViewSh = pDestShell->GetBestViewShell();
2547 		}
2548 	}
2549 	else
2550 		pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
2551 
2552 	if (!pDestShell)
2553 	{
2554 		DBG_ERROR("Dest-Doc nicht gefunden !!!");
2555 		return;
2556 	}
2557 
2558 	pDestDoc = pDestShell->GetDocument();
2559 
2560 	SCTAB nTab = GetViewData()->GetTabNo();
2561 
2562 	if (pDestDoc != pDoc)
2563 	{
2564 		if (bNewDoc)
2565 		{
2566 			while (pDestDoc->GetTableCount() > 1)
2567 				pDestDoc->DeleteTab(0);
2568 			pDestDoc->RenameTab( 0,
2569 						String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
2570 						sal_False );
2571 		}
2572 
2573 		ScMarkData& rMark		= GetViewData()->GetMarkData();
2574 		SCTAB		nTabCount	= pDoc->GetTableCount();
2575 		SCTAB		nTabSelCount = rMark.GetSelectCount();
2576 
2577 		SvShorts	TheTabs;
2578 
2579 		for(SCTAB i=0;i<nTabCount;i++)
2580 		{
2581 			if(rMark.GetTableSelect(i))
2582 			{
2583 				String aTabName;
2584 				pDoc->GetName( i, aTabName);
2585 				TheTabs.push_back(i);
2586 				for(SCTAB j=i+1;j<nTabCount;j++)
2587 				{
2588 					if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2589 					{
2590 						pDoc->GetName( j, aTabName);
2591 						TheTabs.push_back(j);
2592 						i=j;
2593 					}
2594 					else break;
2595 				}
2596 			}
2597 		}
2598 
2599 		GetFrameWin()->EnterWait();
2600 
2601 		if (pDoc->GetDrawLayer())
2602 			pDestShell->MakeDrawLayer();
2603 
2604 		if (!bNewDoc && bUndo)
2605 			pDestDoc->BeginDrawUndo();		// drawing layer must do its own undo actions
2606 
2607 		sal_uLong nErrVal =1;
2608 		if(nDestTab==SC_TAB_APPEND)
2609             nDestTab=pDestDoc->GetTableCount();
2610 		SCTAB nDestTab1=nDestTab;
2611 		for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ )
2612 		{	// #63304# insert sheets first and update all references
2613 			String aName;
2614 			pDoc->GetName( TheTabs[j], aName );
2615 			pDestDoc->CreateValidTabName( aName );
2616 			if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
2617 			{
2618 				nErrVal = 0;		// total error
2619 				break;	// for
2620 			}
2621 		}
2622 		if ( nErrVal > 0 )
2623 		{
2624 			nDestTab1 = nDestTab;
2625 			for(size_t i=0;i<TheTabs.size();i++)
2626 			{
2627 				nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
2628 					sal_False );		// no insert
2629 
2630 				// TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2631 				if ( nErrVal > 0 )
2632 					pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
2633 
2634 				if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
2635 				{
2636 					String aComment;
2637 					Color  aColor;
2638 					sal_uInt16 nFlags;
2639 
2640 					pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
2641 					pDestDoc->SetScenario(nDestTab1,sal_True);
2642 					pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2643 					sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]);
2644 					pDestDoc->SetActiveScenario(nDestTab1, bActive );
2645 
2646 					sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]);
2647 					pDestDoc->SetVisible(nDestTab1,bVisible );
2648 
2649 				}
2650 
2651 				if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
2652                     pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
2653 
2654 				nDestTab1++;
2655 			}
2656 		}
2657 		String sName;
2658 		if (!bNewDoc && bUndo)
2659 		{
2660 			pDestDoc->GetName(nDestTab, sName);
2661 			pDestShell->GetUndoManager()->AddUndoAction(
2662                             new ScUndoImportTab( pDestShell, nDestTab,
2663                                 static_cast<SCTAB>(TheTabs.size()), sal_False));
2664 
2665 		}
2666 		else
2667 		{
2668 			pDestShell->GetUndoManager()->Clear();
2669 		}
2670 
2671 		GetFrameWin()->LeaveWait();
2672 		switch (nErrVal)
2673 		{
2674 			case 0:						// interner Fehler oder voll Fehler
2675 			{
2676 				ErrorMessage(STR_TABINSERT_ERROR);
2677 				return;
2678 			}
2679             //break;
2680 			case 2:
2681 				ErrorMessage(STR_ABSREFLOST);
2682 			break;
2683 			case 3:
2684 				ErrorMessage(STR_NAMECONFLICT);
2685 			break;
2686 			case 4:
2687 			{
2688 				ErrorMessage(STR_ABSREFLOST);
2689 				ErrorMessage(STR_NAMECONFLICT);
2690 			}
2691 			break;
2692 			default:
2693 			break;
2694 		}
2695 		//pDestShell->GetUndoManager()->Clear();		//! Undo implementieren !!!
2696 /*
2697 		String sName;
2698 		pDestDoc->GetName(nDestTab, sName);
2699 		pDestShell->GetUndoManager()->AddUndoAction(
2700 						new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) );
2701 */
2702 		if (!bCopy)
2703 		{
2704 			if(nTabCount!=nTabSelCount)
2705 				DeleteTables(TheTabs);// incl. Paint & Undo
2706 			else
2707 				ErrorMessage(STR_TABREMOVE_ERROR);
2708 		}
2709 
2710 		if (bNewDoc)
2711 		{
2712 			//	ChartListenerCollection must be updated before DeleteTab
2713 			if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
2714 				pDestDoc->UpdateChartListenerCollection();
2715 
2716 			pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size()));   // first old table
2717 //?			pDestDoc->SelectTable(0, sal_True);		// neue erste Tabelle selektieren
2718 			if (pDestViewSh)
2719 				pDestViewSh->TabChanged();		// Pages auf dem Drawing-Layer
2720 			pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2721 									PAINT_GRID | PAINT_TOP | PAINT_LEFT |
2722 									PAINT_EXTRAS | PAINT_SIZE );
2723 			//	PAINT_SIZE fuer Gliederung
2724 		}
2725 		else
2726 		{
2727 			pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
2728 			pDestShell->PostPaintExtras();
2729 			pDestShell->PostPaintGridAll();
2730 		}
2731 
2732 		TheTabs.clear();
2733 
2734 		pDestShell->SetDocumentModified();
2735 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2736 	}
2737 	else					// within the documents
2738 	{
2739 
2740 		ScMarkData& rMark		= GetViewData()->GetMarkData();
2741 		SCTAB		nTabCount	= pDoc->GetTableCount();
2742 
2743 		SvShorts	TheTabs;
2744 		SvShorts	TheDestTabs;
2745 		SvStrings	TheTabNames;
2746 		String		aDestName;
2747 		String		*pString;
2748 
2749 		for(SCTAB i=0;i<nTabCount;i++)
2750 		{
2751 			if(rMark.GetTableSelect(i))
2752 			{
2753 				String aTabName;
2754 				pDoc->GetName( i, aTabName);
2755 				TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2756 
2757 				for(SCTAB j=i+1;j<nTabCount;j++)
2758 				{
2759 					if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2760 					{
2761 						pDoc->GetName( j, aTabName);
2762 						TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2763 						i=j;
2764 					}
2765 					else break;
2766 				}
2767 
2768 			}
2769 		}
2770 
2771 		if (bCopy && bUndo)
2772 			pDoc->BeginDrawUndo();			// drawing layer must do its own undo actions
2773 
2774 		pDoc->GetName( nDestTab, aDestName);
2775 		SCTAB nDestTab1=nDestTab;
2776 		SCTAB nMovTab=0;
2777 		for(int j=0;j<TheTabNames.Count();j++)
2778 		{
2779 			nTabCount	= pDoc->GetTableCount();
2780             pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)];
2781 			if(!pDoc->GetTable(*pString,nMovTab))
2782 			{
2783 				nMovTab=nTabCount;
2784 			}
2785 			if(!pDoc->GetTable(aDestName,nDestTab1))
2786 			{
2787 				nDestTab1=nTabCount;
2788 			}
2789 			pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False );	// Undo ist hier
2790 
2791 			if(bCopy && pDoc->IsScenario(nMovTab))
2792 			{
2793 				String aComment;
2794 				Color  aColor;
2795 				sal_uInt16 nFlags;
2796 
2797 				pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
2798 				pDoc->SetScenario(nDestTab1,sal_True);
2799 				pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2800 				sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2801 				pDoc->SetActiveScenario( nDestTab1, bActive );
2802 				sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2803 				pDoc->SetVisible(nDestTab1,bVisible );
2804 			}
2805 
2806 			TheTabs.push_back(nMovTab);
2807 
2808 			if(!bCopy)
2809 			{
2810 				if(!pDoc->GetTable(*pString,nDestTab1))
2811 				{
2812 					nDestTab1=nTabCount;
2813 				}
2814 			}
2815 
2816 			TheDestTabs.push_back(nDestTab1);
2817 			delete pString;
2818 		}
2819 
2820 		nTab = GetViewData()->GetTabNo();
2821 
2822 		if (bUndo)
2823 		{
2824 			if (bCopy)
2825 			{
2826 				pDocShell->GetUndoManager()->AddUndoAction(
2827 						new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
2828 			}
2829 			else
2830 			{
2831 				pDocShell->GetUndoManager()->AddUndoAction(
2832 						new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
2833 			}
2834 		}
2835 
2836 		SCTAB nNewTab = nDestTab;
2837 		if (nNewTab == SC_TAB_APPEND)
2838 			nNewTab = pDoc->GetTableCount()-1;
2839 		else if (!bCopy && nTab<nDestTab)
2840 			nNewTab--;
2841 
2842 		SetTabNo( nNewTab, sal_True );
2843 
2844         //#i29848# adjust references to data on the copied sheet
2845         if( bCopy )
2846             ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
2847 	}
2848 }
2849 
2850 
2851 //----------------------------------------------------------------------------
2852 
2853 void ScViewFunc::ShowTable( const String& rName )
2854 {
2855 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
2856 	ScDocument* pDoc = pDocSh->GetDocument();
2857 	sal_Bool bUndo(pDoc->IsUndoEnabled());
2858 	sal_Bool bFound = sal_False;
2859 	SCTAB nPos = 0;
2860 	String aTabName;
2861 	SCTAB nCount = pDoc->GetTableCount();
2862 	for (SCTAB i=0; i<nCount; i++)
2863 	{
2864 		pDoc->GetName( i, aTabName );
2865 		if ( aTabName == rName )
2866 		{
2867 			nPos = i;
2868 			bFound = sal_True;
2869 		}
2870 	}
2871 
2872 	if (bFound)
2873 	{
2874 		pDoc->SetVisible( nPos, sal_True );
2875 		if (bUndo)
2876 		{
2877 			pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
2878 		}
2879 		SetTabNo( nPos, sal_True );
2880 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2881 		pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2882 		pDocSh->SetDocumentModified();
2883 	}
2884 	else
2885 		Sound::Beep();
2886 }
2887 
2888 
2889 //----------------------------------------------------------------------------
2890 
2891 void ScViewFunc::HideTable( SCTAB nTab )
2892 {
2893 	ScDocShell* pDocSh = GetViewData()->GetDocShell();
2894 	ScDocument* pDoc = pDocSh->GetDocument();
2895 	sal_Bool bUndo(pDoc->IsUndoEnabled());
2896 	SCTAB nVisible = 0;
2897 	SCTAB nCount = pDoc->GetTableCount();
2898 	for (SCTAB i=0; i<nCount; i++)
2899 	{
2900 		if (pDoc->IsVisible(i))
2901 			++nVisible;
2902 	}
2903 
2904 	if (nVisible > 1)
2905 	{
2906 		pDoc->SetVisible( nTab, sal_False );
2907 		if (bUndo)
2908 		{
2909 			pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) );
2910 		}
2911 
2912 		//	Views updaten:
2913 		pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
2914 
2915 		SetTabNo( nTab, sal_True );
2916 		SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2917 		pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2918 		pDocSh->SetDocumentModified();
2919 	}
2920 	else
2921 		Sound::Beep();
2922 }
2923 
2924 
2925 //----------------------------------------------------------------------------
2926 
2927 void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
2928 {
2929 	ScEditableTester aTester( this );
2930 	if (!aTester.IsEditable())
2931 	{
2932 		ErrorMessage(aTester.GetMessageId());
2933 		return;
2934 	}
2935 
2936 	const sal_Unicode* pChar	= rStr.GetBuffer();
2937 	ScTabViewShell* pViewShell	= GetViewData()->GetViewShell();
2938 	SvxFontItem		aFontItem( rFont.GetFamily(),
2939 							   rFont.GetName(),
2940 							   rFont.GetStyleName(),
2941 							   rFont.GetPitch(),
2942 							   rFont.GetCharSet(),
2943 							   ATTR_FONT );
2944 
2945 	//	if string contains WEAK characters, set all fonts
2946 	sal_uInt8 nScript;
2947 	ScDocument* pDoc = GetViewData()->GetDocument();
2948 	if ( pDoc->HasStringWeakCharacters( rStr ) )
2949 		nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
2950 	else
2951 		nScript = pDoc->GetStringScriptType( rStr );
2952 
2953 	SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
2954 	aSetItem.PutItemForScriptType( nScript, aFontItem );
2955 	ApplyUserItemSet( aSetItem.GetItemSet() );
2956 
2957 	while ( *pChar )
2958 		pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
2959 }
2960 
2961 
2962 //----------------------------------------------------------------------------
2963 
2964 void ScViewFunc::UpdateLineAttrs( SvxBorderLine&	   rLine,
2965 								  const SvxBorderLine* pDestLine,
2966 								  const SvxBorderLine* pSrcLine,
2967 								  sal_Bool 				   bColor )
2968 {
2969 	if ( pSrcLine && pDestLine )
2970 	{
2971 		if ( bColor )
2972 		{
2973 			rLine.SetColor		( pSrcLine->GetColor() );
2974 			rLine.SetOutWidth	( pDestLine->GetOutWidth() );
2975 			rLine.SetInWidth	( pDestLine->GetInWidth() );
2976 			rLine.SetDistance	( pDestLine->GetDistance() );
2977 		}
2978 		else
2979 		{
2980 			rLine.SetColor		( pDestLine->GetColor() );
2981 			rLine.SetOutWidth	( pSrcLine->GetOutWidth() );
2982 			rLine.SetInWidth	( pSrcLine->GetInWidth() );
2983 			rLine.SetDistance	( pSrcLine->GetDistance() );
2984 		}
2985 	}
2986 }
2987 
2988 
2989 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
2990 	pBoxLine = aBoxItem.Get##LINE();								\
2991 	if ( pBoxLine )													\
2992 	{																\
2993 		if ( pLine )												\
2994 		{															\
2995 			UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly );	\
2996 			aBoxItem.SetLine( &aLine, BOXLINE );					\
2997 		}															\
2998 		else														\
2999 			aBoxItem.SetLine( NULL, BOXLINE );						\
3000 	}
3001 
3002 
3003 //----------------------------------------------------------------------------
3004 
3005 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
3006 										 sal_Bool bColorOnly )
3007 {
3008 	// nur wegen Matrix nicht editierbar? Attribute trotzdem ok
3009 	sal_Bool bOnlyNotBecauseOfMatrix;
3010 	if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
3011 	{
3012 		ErrorMessage(STR_PROTECTIONERR);
3013 		return;
3014 	}
3015 
3016 	ScDocument*				pDoc = GetViewData()->GetDocument();
3017     ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
3018     ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
3019 	ScDocShell*				pDocSh = GetViewData()->GetDocShell();
3020 	const ScPatternAttr*	pSelAttrs = GetSelectionPattern();
3021     const SfxItemSet&       rSelItemSet = pSelAttrs->GetItemSet();
3022 
3023 	const SfxPoolItem*		pBorderAttr	= NULL;
3024     SfxItemState            eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
3025 
3026     const SfxPoolItem*      pTLBRItem = 0;
3027     SfxItemState            eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
3028 
3029     const SfxPoolItem*      pBLTRItem = 0;
3030     SfxItemState            eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
3031 
3032     // any of the lines visible?
3033     if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
3034 	{
3035         // none of the lines don't care?
3036         if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
3037 		{
3038 			SfxItemSet*		pOldSet	= new SfxItemSet(
3039 											*(pDoc->GetPool()),
3040 											ATTR_PATTERN_START,
3041 											ATTR_PATTERN_END );
3042 			SfxItemSet*		pNewSet	= new SfxItemSet(
3043 											*(pDoc->GetPool()),
3044 											ATTR_PATTERN_START,
3045 											ATTR_PATTERN_END );
3046 
3047 			//------------------------------------------------------------
3048 			const SvxBorderLine*	pBoxLine = NULL;
3049 			SvxBorderLine			aLine;
3050 
3051 			// hier wird die pBoxLine benutzt:
3052 
3053             if( pBorderAttr )
3054             {
3055                 SvxBoxItem      aBoxItem( *(const SvxBoxItem*)pBorderAttr );
3056                 SvxBoxInfoItem  aBoxInfoItem( ATTR_BORDER_INNER );
3057 
3058                 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
3059                 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
3060                 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
3061                 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
3062 
3063                 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
3064                 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
3065                 aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
3066 
3067                 pOldSet->Put( *pBorderAttr );
3068                 pNewSet->Put( aBoxItem );
3069                 pNewSet->Put( aBoxInfoItem );
3070             }
3071 
3072             if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
3073             {
3074                 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
3075                 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
3076                 aTLBRItem.SetLine( &aLine );
3077                 pOldSet->Put( *pTLBRItem );
3078                 pNewSet->Put( aTLBRItem );
3079             }
3080 
3081             if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
3082             {
3083                 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
3084                 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
3085                 aBLTRItem.SetLine( &aLine );
3086                 pOldSet->Put( *pBLTRItem );
3087                 pNewSet->Put( aBLTRItem );
3088             }
3089 
3090 			ApplyAttributes( pNewSet, pOldSet );
3091 
3092 			delete pOldSet;
3093 			delete pNewSet;
3094 		}
3095 		else // if ( eItemState == SFX_ITEM_DONTCARE )
3096 		{
3097 			aFuncMark.MarkToMulti();
3098 			pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
3099 		}
3100 
3101 		ScRange aMarkRange;
3102 		aFuncMark.GetMultiMarkArea( aMarkRange );
3103 		SCCOL nStartCol = aMarkRange.aStart.Col();
3104 		SCROW nStartRow = aMarkRange.aStart.Row();
3105 		SCTAB nStartTab = aMarkRange.aStart.Tab();
3106 		SCCOL nEndCol = aMarkRange.aEnd.Col();
3107 		SCROW nEndRow = aMarkRange.aEnd.Row();
3108 		SCTAB nEndTab = aMarkRange.aEnd.Tab();
3109 		pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
3110 						   nEndCol, nEndRow, nEndTab,
3111 						   PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3112 
3113 		pDocSh->UpdateOle( GetViewData() );
3114 		pDocSh->SetDocumentModified();
3115 	}
3116 }
3117 
3118 #undef SET_LINE_ATTRIBUTES
3119 
3120 
3121 //----------------------------------------------------------------------------
3122 
3123 void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
3124 {
3125 	ScDocument* pDoc = GetViewData()->GetDocument();
3126 	sal_uLong nIndex = pDoc->AddCondFormat(rNew);			// dafuer gibt's kein Undo
3127 	SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
3128 
3129 	ApplyAttr( aItem );			// mit Paint und Undo...
3130 }
3131 
3132 
3133 //----------------------------------------------------------------------------
3134 
3135 void ScViewFunc::SetValidation( const ScValidationData& rNew )
3136 {
3137 	ScDocument* pDoc = GetViewData()->GetDocument();
3138 	sal_uLong nIndex = pDoc->AddValidationEntry(rNew);		// dafuer gibt's kein Undo
3139 	SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
3140 
3141 	ApplyAttr( aItem );			// mit Paint und Undo...
3142 }
3143 
3144 
3145