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