xref: /AOO41X/main/sc/source/ui/view/viewfun2.cxx (revision 3ea0c3d5cfef7203d1d18b0d5fde9ed31f4a4181)
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 
AdjustBlockHeight(sal_Bool bPaint,ScMarkData * pMarkData)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 
AdjustRowHeight(SCROW nStartRow,SCROW nEndRow,sal_Bool bPaint)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 
lcl_IsAutoSumData(ScDocument * pDoc,SCCOL nCol,SCROW nRow,SCTAB nTab,ScDirection eDir,SCCOLROW & nExtend)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 
lcl_SeekAutoSumData(ScDocument * pDoc,SCCOL & nCol,SCROW & nRow,SCTAB nTab,ScDirection eDir,SCCOLROW & nExtend)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 
lcl_FindNextSumEntryInColumn(ScDocument * pDoc,SCCOL nCol,SCROW & nRow,SCTAB nTab,SCCOLROW & nExtend,SCROW nMinRow)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 
lcl_FindNextSumEntryInRow(ScDocument * pDoc,SCCOL & nCol,SCROW nRow,SCTAB nTab,SCCOLROW & nExtend,SCROW nMinCol)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 
lcl_GetAutoSumForColumnRange(ScDocument * pDoc,ScRangeList & rRangeList,const ScRange & rRange)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 
lcl_GetAutoSumForRowRange(ScDocument * pDoc,ScRangeList & rRangeList,const ScRange & rRange)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 
GetAutoSumArea(ScRangeList & rRangeList)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 
EnterAutoSum(const ScRangeList & rRangeList,sal_Bool bSubTotal)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 
AutoSum(const ScRange & rRange,bool bSubTotal,bool bSetCursor,bool bContinue)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 
GetAutoSumFormula(const ScRangeList & rRangeList,bool bSubTotal)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 
EnterBlock(const String & rString,const EditTextObject * pData)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 
InsertPageBreak(sal_Bool bColumn,sal_Bool bRecord,const ScAddress * pPos,sal_Bool bSetModified)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 
DeletePageBreak(sal_Bool bColumn,sal_Bool bRecord,const ScAddress * pPos,sal_Bool bSetModified)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 
RemoveManualBreaks()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 
SetPrintZoom(sal_uInt16 nScale,sal_uInt16 nPages)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 
AdjustPrintZoom()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 
SetPrintRanges(sal_Bool bEntireSheet,const String * pPrint,const String * pRepCol,const String * pRepRow,sal_Bool bAddPrint)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 
TestMergeCells()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 
MergeCells(sal_Bool bApi,sal_Bool & rDoContents,sal_Bool bRecord)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 
TestRemoveMerge()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 
RemoveMerge(sal_Bool bRecord)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 
FillSimple(FillDir eDir,sal_Bool bRecord)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 
FillSeries(FillDir eDir,FillCmd eCmd,FillDateCmd eDateCmd,double fStart,double fStep,double fMax,sal_Bool bRecord)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 
FillAuto(FillDir eDir,SCCOL nStartCol,SCROW nStartRow,SCCOL nEndCol,SCROW nEndRow,sal_uLong nCount,sal_Bool bRecord)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 
FillTab(sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty,sal_Bool bAsLink)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 */
FillCrossDblClick()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 
TransliterateText(sal_Int32 nType)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 
CreateAutoFormatData()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 
AutoFormat(sal_uInt16 nFormatNo,sal_Bool bRecord)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 
SearchAndReplace(const SvxSearchItem * pSearchItem,sal_Bool bAddUndo,sal_Bool bIsApi)1619 sal_Bool ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
1620                                         sal_Bool bAddUndo, sal_Bool bIsApi )
1621 {
1622     ScDocShell* pDocSh = GetViewData()->GetDocShell();
1623     ScDocument* pDoc = pDocSh->GetDocument();
1624     ScMarkData& rMark = GetViewData()->GetMarkData();
1625     if (bAddUndo && !pDoc->IsUndoEnabled())
1626         bAddUndo = sal_False;
1627 
1628     SCCOL nCol = GetViewData()->GetCurX();
1629     SCROW nRow = GetViewData()->GetCurY();
1630     SCTAB nTab = GetViewData()->GetTabNo();
1631 //    sal_Bool bAttrib = pSearchItem->GetPattern();
1632     sal_uInt16 nCommand = pSearchItem->GetCommand();
1633     sal_Bool bAllTables = pSearchItem->IsAllTables();
1634     sal_Bool* pOldSelectedTables = NULL;
1635     sal_uInt16 nOldSelectedCount = 0;
1636     SCTAB nOldTab = nTab;
1637     SCTAB nLastTab = pDoc->GetTableCount() - 1;
1638     SCTAB nStartTab, nEndTab;
1639     if ( bAllTables )
1640     {
1641         nStartTab = 0;
1642         nEndTab = nLastTab;
1643         pOldSelectedTables = new sal_Bool [ nEndTab + 1 ];
1644         for ( SCTAB j = 0; j <= nEndTab; j++ )
1645         {
1646             pOldSelectedTables[j] = rMark.GetTableSelect( j );
1647             if ( pOldSelectedTables[j] )
1648                 ++nOldSelectedCount;
1649         }
1650     }
1651     else
1652     {   //! mindestens eine ist immer selektiert
1653         nStartTab = nEndTab = rMark.GetFirstSelected();
1654         for ( SCTAB j = nStartTab + 1; j <= nLastTab; j++ )
1655         {
1656             if ( rMark.GetTableSelect( j ) )
1657                 nEndTab = j;
1658         }
1659     }
1660 
1661     if (   nCommand == SVX_SEARCHCMD_REPLACE
1662         || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1663     {
1664         for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1665         {
1666             if ( (bAllTables || rMark.GetTableSelect( j )) &&
1667                     pDoc->IsTabProtected( j ) )
1668             {
1669                 if ( pOldSelectedTables )
1670                     delete [] pOldSelectedTables;
1671                 ErrorMessage(STR_PROTECTIONERR);
1672                 return sal_False;
1673             }
1674         }
1675     }
1676 
1677     if (   nCommand == SVX_SEARCHCMD_FIND
1678         || nCommand == SVX_SEARCHCMD_FIND_ALL)
1679         bAddUndo = sal_False;
1680 
1681     //!     bAttrib bei Undo beruecksichtigen !!!
1682 
1683     ScDocument* pUndoDoc = NULL;
1684     ScMarkData* pUndoMark = NULL;
1685     String aUndoStr;
1686     if (bAddUndo)
1687     {
1688         pUndoMark = new ScMarkData( rMark );                // Markierung wird veraendert
1689         if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1690         {
1691             pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1692             pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
1693         }
1694     }
1695 
1696     if ( bAllTables )
1697     {   //! alles selektieren, erst nachdem pUndoMark erzeugt wurde
1698         for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1699         {
1700             rMark.SelectTable( j, sal_True );
1701         }
1702     }
1703 
1704     DoneBlockMode(sal_True);                // Markierung nicht loeschen!
1705     InitOwnBlockMode();
1706 
1707     //  wenn vom Anfang an gesucht wird, nicht nochmal fragen ob vom Anfang gesucht werden soll
1708     sal_Bool bFirst = sal_True;
1709     if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward()  )
1710         bFirst = sal_False;
1711 
1712     sal_Bool bFound = sal_False;
1713     while (sal_True)
1714     {
1715         GetFrameWin()->EnterWait();
1716         if (pDoc->SearchAndReplace( *pSearchItem, nCol, nRow, nTab, rMark, aUndoStr, pUndoDoc ) )
1717         {
1718             bFound = sal_True;
1719             bFirst = sal_True;
1720             if (bAddUndo)
1721             {
1722                 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1723                     new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
1724                                         nCol, nRow, nTab,
1725                                         aUndoStr, pUndoDoc, pSearchItem ) );
1726                 pUndoDoc = NULL;
1727             }
1728 
1729             break;                  // Abbruch while True
1730         }
1731         else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
1732                 nCommand == SVX_SEARCHCMD_REPLACE) )
1733         {
1734             bFirst = sal_False;
1735             sal_uInt16 nRetVal;
1736             GetFrameWin()->LeaveWait();
1737             if ( bIsApi )
1738                 nRetVal = RET_NO;
1739             else
1740             {
1741                 //  Suchen-Dialog als Parent, wenn vorhanden
1742                 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1743                 sal_uInt16 nStrId;
1744                 if ( pSearchItem->GetBackward() )
1745                 {
1746                     if ( nStartTab == nEndTab )
1747                         nStrId = STR_MSSG_SEARCHANDREPLACE_1;
1748                     else
1749                         nStrId = STR_MSSG_SEARCHANDREPLACE_4;
1750                 }
1751                 else
1752                 {
1753                     if ( nStartTab == nEndTab )
1754                         nStrId = STR_MSSG_SEARCHANDREPLACE_2;
1755                     else
1756                         nStrId = STR_MSSG_SEARCHANDREPLACE_5;
1757                 }
1758                 MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
1759                                 ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
1760                                 ScGlobal::GetRscString( nStrId ) );
1761                 nRetVal = aBox.Execute();
1762             }
1763 
1764             if ( nRetVal == RET_YES )
1765             {
1766                 ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
1767                 if (pSearchItem->GetBackward())
1768                     nTab = nEndTab;
1769                 else
1770                     nTab = nStartTab;
1771             }
1772             else
1773             {
1774                 break;                  // Abbruch while True
1775             }
1776         }
1777         else                            // nichts gefunden
1778         {
1779             if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1780             {
1781                 pDocSh->PostPaintGridAll();                             // Markierung
1782             }
1783 
1784             GetFrameWin()->LeaveWait();
1785             if (!bIsApi)
1786             {
1787                 //  Suchen-Dialog als Parent, wenn vorhanden
1788                 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1789                 // "nichts gefunden"
1790                 InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
1791                 aBox.Execute();
1792             }
1793 
1794             break;                      // Abbruch while True
1795         }
1796     }                               // of while sal_True
1797 
1798     if ( pOldSelectedTables )
1799     {   // urspruenglich selektierte Tabellen wiederherstellen
1800         for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1801         {
1802             rMark.SelectTable( j, pOldSelectedTables[j] );
1803         }
1804         if ( bFound )
1805         {   // durch Fundstelle neu selektierte Tabelle bleibt
1806             rMark.SelectTable( nTab, sal_True );
1807             // wenn vorher nur eine selektiert war, ist es ein Tausch
1808             //! wenn nicht, ist jetzt evtl. eine mehr selektiert
1809             if ( nOldSelectedCount == 1 && nTab != nOldTab )
1810                 rMark.SelectTable( nOldTab, sal_False );
1811         }
1812         delete [] pOldSelectedTables;
1813     }
1814 
1815     MarkDataChanged();
1816 
1817     if ( bFound )
1818     {
1819         if ( nTab != GetViewData()->GetTabNo() )
1820             SetTabNo( nTab );
1821 
1822         //  wenn nichts markiert ist, DoneBlockMode, damit von hier aus
1823         //  direkt per Shift-Cursor markiert werden kann:
1824         if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1825             DoneBlockMode(sal_True);
1826 
1827         AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
1828         SetCursor( nCol, nRow, sal_True );
1829 
1830         if (   nCommand == SVX_SEARCHCMD_REPLACE
1831             || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1832         {
1833             if ( nCommand == SVX_SEARCHCMD_REPLACE )
1834                 pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
1835             else
1836                 pDocSh->PostPaintGridAll();
1837             pDocSh->SetDocumentModified();
1838         }
1839         else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
1840             pDocSh->PostPaintGridAll();                             // Markierung
1841         GetFrameWin()->LeaveWait();
1842     }
1843 
1844     delete pUndoDoc;            // loeschen wenn nicht benutzt
1845     delete pUndoMark;           // kann immer geloescht werden
1846     return bFound;
1847 }
1848 
1849 
1850 //----------------------------------------------------------------------------
1851 //  Zielwertsuche
1852 
Solve(const ScSolveParam & rParam)1853 void ScViewFunc::Solve( const ScSolveParam& rParam )
1854 {
1855     ScDocument* pDoc = GetViewData()->GetDocument();
1856 
1857     SCCOL nDestCol = rParam.aRefVariableCell.Col();
1858     SCROW nDestRow = rParam.aRefVariableCell.Row();
1859     SCTAB nDestTab = rParam.aRefVariableCell.Tab();
1860 
1861     ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
1862     if (!aTester.IsEditable())
1863     {
1864         ErrorMessage(aTester.GetMessageId());
1865         return;
1866     }
1867 
1868     if ( pDoc )
1869     {
1870         String  aTargetValStr;
1871         if ( rParam.pStrTargetVal != NULL )
1872             aTargetValStr = *(rParam.pStrTargetVal);
1873 
1874         String  aMsgStr;
1875         String  aResStr;
1876         double  nSolveResult;
1877 
1878         GetFrameWin()->EnterWait();
1879 
1880         sal_Bool    bExact =
1881                     pDoc->Solver(
1882                         rParam.aRefFormulaCell.Col(),
1883                         rParam.aRefFormulaCell.Row(),
1884                         rParam.aRefFormulaCell.Tab(),
1885                         nDestCol, nDestRow, nDestTab,
1886                         aTargetValStr,
1887                         nSolveResult );
1888 
1889         GetFrameWin()->LeaveWait();
1890 
1891         SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1892         sal_uLong nFormat = 0;
1893         const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
1894         if ( pPattern )
1895             nFormat = pPattern->GetNumberFormat( pFormatter );
1896         Color* p;
1897         pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
1898 
1899         if ( bExact )
1900         {
1901             aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
1902             aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
1903             aMsgStr += String( aResStr );
1904             aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
1905         }
1906         else
1907         {
1908             aMsgStr  = ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
1909             aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
1910             aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_5 );
1911             aMsgStr += String( aResStr );
1912             aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_6 );
1913         }
1914 
1915         MessBox aBox( GetViewData()->GetDialogParent(),
1916                         WinBits(WB_YES_NO | WB_DEF_NO),
1917                         ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
1918         sal_uInt16 nRetVal = aBox.Execute();
1919 
1920         if ( RET_YES == nRetVal )
1921             EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
1922 
1923         GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
1924     }
1925 }
1926 
1927 
1928 //----------------------------------------------------------------------------
1929 //  Mehrfachoperation
1930 
TabOp(const ScTabOpParam & rParam,sal_Bool bRecord)1931 void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
1932 {
1933     ScRange aRange;
1934     if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1935     {
1936         ScDocShell* pDocSh = GetViewData()->GetDocShell();
1937         ScMarkData& rMark = GetViewData()->GetMarkData();
1938         pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, sal_False );
1939     }
1940     else
1941         ErrorMessage(STR_NOMULTISELECT);
1942 }
1943 
1944 
1945 //----------------------------------------------------------------------------
1946 
MakeScenario(const String & rName,const String & rComment,const Color & rColor,sal_uInt16 nFlags)1947 void ScViewFunc::MakeScenario( const String& rName, const String& rComment,
1948                                     const Color& rColor, sal_uInt16 nFlags )
1949 {
1950     ScDocShell* pDocSh  = GetViewData()->GetDocShell();
1951     ScMarkData& rMark   = GetViewData()->GetMarkData();
1952     SCTAB       nTab    = GetViewData()->GetTabNo();
1953 
1954     SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
1955     if (nFlags & SC_SCENARIO_COPYALL)
1956         SetTabNo( nNewTab, sal_True );          // SC_SCENARIO_COPYALL -> sichtbar
1957     else
1958     {
1959         SfxBindings& rBindings = GetViewData()->GetBindings();
1960         rBindings.Invalidate( SID_STATUS_DOCPOS );      // Statusbar
1961         rBindings.Invalidate( SID_TABLES_COUNT );
1962         rBindings.Invalidate( SID_SELECT_SCENARIO );
1963         rBindings.Invalidate( FID_TABLE_SHOW );
1964     }
1965 }
1966 
1967 
1968 //----------------------------------------------------------------------------
1969 
ExtendScenario()1970 void ScViewFunc::ExtendScenario()
1971 {
1972     ScEditableTester aTester( this );
1973     if (!aTester.IsEditable())
1974     {
1975         ErrorMessage(aTester.GetMessageId());
1976         return;
1977     }
1978 
1979         //  Undo: Attribute anwenden
1980 
1981     ScDocument* pDoc = GetViewData()->GetDocument();
1982     ScPatternAttr aPattern( pDoc->GetPool() );
1983     aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
1984     aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
1985     ApplySelectionPattern(aPattern);
1986 }
1987 
1988 
1989 //----------------------------------------------------------------------------
1990 
UseScenario(const String & rName)1991 void ScViewFunc::UseScenario( const String& rName )
1992 {
1993     ScDocShell* pDocSh  = GetViewData()->GetDocShell();
1994     SCTAB       nTab    = GetViewData()->GetTabNo();
1995 
1996     DoneBlockMode();
1997     InitOwnBlockMode();
1998     pDocSh->UseScenario( nTab, rName );
1999 }
2000 
2001 
2002 //----------------------------------------------------------------------------
2003 //  Tabelle einfuegen
2004 
InsertTable(const String & rName,SCTAB nTab,sal_Bool bRecord)2005 sal_Bool ScViewFunc::InsertTable( const String& rName, SCTAB nTab, sal_Bool bRecord )
2006 {
2007     //  Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2008     sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2009                         InsertTable( nTab, rName, bRecord, sal_False );
2010     if (bSuccess)
2011         SetTabNo( nTab, sal_True );
2012 
2013     return bSuccess;
2014 }
2015 
2016 //----------------------------------------------------------------------------
2017 //  Tabellen einfuegen
2018 
InsertTables(SvStrings * pNames,SCTAB nTab,SCTAB nCount,sal_Bool bRecord)2019 sal_Bool ScViewFunc::InsertTables(SvStrings *pNames, SCTAB nTab,
2020                                             SCTAB nCount, sal_Bool bRecord )
2021 {
2022     ScDocShell* pDocSh  = GetViewData()->GetDocShell();
2023     ScDocument* pDoc    = pDocSh->GetDocument();
2024     if (bRecord && !pDoc->IsUndoEnabled())
2025         bRecord = sal_False;
2026 
2027     SvStrings *pNameList= NULL;
2028 
2029     WaitObject aWait( GetFrameWin() );
2030 
2031     if (bRecord)
2032     {
2033         pNameList= new SvStrings;
2034         pDoc->BeginDrawUndo();                          //  InsertTab erzeugt ein SdrUndoNewPage
2035     }
2036 
2037     sal_Bool bFlag=sal_False;
2038 
2039     String aValTabName;
2040     String *pStr;
2041 
2042     for(SCTAB i=0;i<nCount;i++)
2043     {
2044         if(pNames!=NULL)
2045         {
2046             pStr=pNames->GetObject(static_cast<sal_uInt16>(i));
2047         }
2048         else
2049         {
2050             aValTabName.Erase();
2051             pDoc->CreateValidTabName( aValTabName);
2052             pStr=&aValTabName;
2053         }
2054 
2055         if(pDoc->InsertTab( nTab+i,*pStr))
2056         {
2057             bFlag=sal_True;
2058             pDocSh->Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab+i ) );
2059         }
2060         else
2061         {
2062             break;
2063         }
2064 
2065         if(pNameList!=NULL)
2066             pNameList->Insert(new String(*pStr),pNameList->Count());
2067 
2068     }
2069 
2070     if (bFlag)
2071     {
2072         if (bRecord)
2073             pDocSh->GetUndoManager()->AddUndoAction(
2074                         new ScUndoInsertTables( pDocSh, nTab, sal_False, pNameList));
2075 
2076         //  Views updaten:
2077 
2078         SetTabNo( nTab, sal_True );
2079         pDocSh->PostPaintExtras();
2080         pDocSh->SetDocumentModified();
2081         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2082         return sal_True;
2083     }
2084     else
2085     {
2086         return sal_False;
2087     }
2088 }
2089 
2090 
2091 //----------------------------------------------------------------------------
2092 
AppendTable(const String & rName,sal_Bool bRecord)2093 sal_Bool ScViewFunc::AppendTable( const String& rName, sal_Bool bRecord )
2094 {
2095     ScDocShell* pDocSh = GetViewData()->GetDocShell();
2096     ScDocument* pDoc   = pDocSh->GetDocument();
2097     if (bRecord && !pDoc->IsUndoEnabled())
2098         bRecord = sal_False;
2099 
2100     WaitObject aWait( GetFrameWin() );
2101 
2102     if (bRecord)
2103         pDoc->BeginDrawUndo();                          //  InsertTab erzeugt ein SdrUndoNewPage
2104 
2105     if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
2106     {
2107         SCTAB nTab = pDoc->GetTableCount()-1;
2108         if (bRecord)
2109             pDocSh->GetUndoManager()->AddUndoAction(
2110                         new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2111         GetViewData()->InsertTab( nTab );
2112         SetTabNo( nTab, sal_True );
2113         pDocSh->PostPaintExtras();
2114         pDocSh->SetDocumentModified();
2115         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2116         return sal_True;
2117     }
2118     else
2119     {
2120         return sal_False;
2121     }
2122 }
2123 
2124 
2125 //----------------------------------------------------------------------------
2126 
DeleteTable(SCTAB nTab,sal_Bool bRecord)2127 sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2128 {
2129     ScDocShell* pDocSh  = GetViewData()->GetDocShell();
2130     ScDocument* pDoc    = pDocSh->GetDocument();
2131 
2132     sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, sal_False );
2133     if (bSuccess)
2134     {
2135         SCTAB nNewTab = nTab;
2136         if ( nNewTab >= pDoc->GetTableCount() )
2137             --nNewTab;
2138         SetTabNo( nNewTab, sal_True );
2139     }
2140     return bSuccess;
2141 }
2142 
DeleteTables(const SvShorts & TheTabs,sal_Bool bRecord)2143 sal_Bool ScViewFunc::DeleteTables(const SvShorts &TheTabs, sal_Bool bRecord )
2144 {
2145     ScDocShell* pDocSh  = GetViewData()->GetDocShell();
2146     ScDocument* pDoc    = pDocSh->GetDocument();
2147     sal_Bool bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : sal_False;
2148     SCTAB       nNewTab = TheTabs.front();
2149     WaitObject aWait( GetFrameWin() );
2150     if (bRecord && !pDoc->IsUndoEnabled())
2151         bRecord = sal_False;
2152 
2153     while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2154         --nNewTab;
2155 
2156     sal_Bool bWasLinked = sal_False;
2157     ScDocument* pUndoDoc = NULL;
2158     ScRefUndoData* pUndoData = NULL;
2159     if (bRecord)
2160     {
2161         pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2162 //      pUndoDoc->InitDrawLayer( pDocSh );
2163         SCTAB nCount = pDoc->GetTableCount();
2164 
2165 //      pUndoDoc->InitUndo( pDoc, 0, nCount-1 );        // incl. Ref.
2166 
2167         String aOldName;
2168         for (size_t i = 0; i < TheTabs.size(); i++)
2169         {
2170             SCTAB nTab = TheTabs[i];
2171             if (i==0)
2172                 pUndoDoc->InitUndo( pDoc, nTab,nTab, sal_True,sal_True );   // incl. Spalten/Zeilenflags
2173             else
2174                 pUndoDoc->AddUndoTab( nTab,nTab, sal_True,sal_True );       // incl. Spalten/Zeilenflags
2175 
2176             pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,sal_False, pUndoDoc );
2177             pDoc->GetName( nTab, aOldName );
2178             pUndoDoc->RenameTab( nTab, aOldName, sal_False );
2179             if (pDoc->IsLinked(nTab))
2180             {
2181                 bWasLinked = sal_True;
2182                 pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2183                                     pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2184                                     pDoc->GetLinkTab(nTab),
2185                                     pDoc->GetLinkRefreshDelay(nTab) );
2186             }
2187             if ( pDoc->IsScenario(nTab) )
2188             {
2189                 pUndoDoc->SetScenario( nTab, sal_True );
2190                 String aComment;
2191                 Color  aColor;
2192                 sal_uInt16 nScenFlags;
2193                 pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2194                 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2195                 sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2196                 pUndoDoc->SetActiveScenario( nTab, bActive );
2197             }
2198             pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2199             pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
2200             pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2201 
2202             if ( pDoc->IsTabProtected( nTab ) )
2203                 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
2204 
2205             //  Drawing-Layer muss sein Undo selbst in der Hand behalten !!!
2206             //      pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2207         }
2208 
2209         pUndoDoc->AddUndoTab( 0, nCount-1 );            //  alle Tabs fuer Referenzen
2210 
2211         pDoc->BeginDrawUndo();                          //  DeleteTab erzeugt ein SdrUndoDelPage
2212 
2213         pUndoData = new ScRefUndoData( pDoc );
2214     }
2215 
2216     sal_Bool bDelDone = sal_False;
2217 
2218     for (size_t i = TheTabs.size(); i > 0; i--)
2219     {
2220         String sCodeName;
2221         sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i-1], sCodeName );
2222         if (pDoc->DeleteTab( TheTabs[i-1], pUndoDoc ))
2223         {
2224             bDelDone = sal_True;
2225             if( bVbaEnabled )
2226             {
2227                 if( bHasCodeName )
2228                 {
2229                     VBA_DeleteModule( *pDocSh, sCodeName );
2230                 }
2231             }
2232             pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i-1] ) );
2233         }
2234     }
2235     if (bRecord)
2236     {
2237         pDocSh->GetUndoManager()->AddUndoAction(
2238                     new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
2239                                             pUndoDoc, pUndoData ));
2240     }
2241 
2242 
2243     if (bDelDone)
2244     {
2245         if ( nNewTab >= pDoc->GetTableCount() )
2246             nNewTab = pDoc->GetTableCount() - 1;
2247 
2248         SetTabNo( nNewTab, sal_True );
2249 
2250         if (bWasLinked)
2251         {
2252             pDocSh->UpdateLinks();              // Link-Manager updaten
2253             GetViewData()->GetBindings().Invalidate(SID_LINKS);
2254         }
2255 
2256         pDocSh->PostPaintExtras();
2257         pDocSh->SetDocumentModified();
2258 
2259         SfxApplication* pSfxApp = SFX_APP();                                // Navigator
2260         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2261         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2262         pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2263     }
2264     else
2265     {
2266         delete pUndoDoc;
2267         delete pUndoData;
2268     }
2269     return bDelDone;
2270 }
2271 
2272 
2273 //----------------------------------------------------------------------------
2274 
RenameTable(const String & rName,SCTAB nTab)2275 sal_Bool ScViewFunc::RenameTable( const String& rName, SCTAB nTab )
2276 {
2277     //  Reihenfolge Tabelle/Name ist bei DocFunc umgekehrt
2278     sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2279                         RenameTable( nTab, rName, sal_True, sal_False );
2280     if (bSuccess)
2281     {
2282         //  Der Tabellenname koennte in einer Formel vorkommen...
2283         GetViewData()->GetViewShell()->UpdateInputHandler();
2284     }
2285     return bSuccess;
2286 }
2287 
2288 
2289 //----------------------------------------------------------------------------
2290 
SetTabBgColor(const Color & rColor,SCTAB nTab)2291 bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
2292 {
2293     bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, sal_False );
2294     if (bSuccess)
2295     {
2296         GetViewData()->GetViewShell()->UpdateInputHandler();
2297     }
2298     return bSuccess;
2299 }
2300 
SetTabBgColor(ScUndoTabColorInfo::List & rUndoSetTabBgColorInfoList)2301 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
2302 {
2303     bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, sal_False );
2304     if (bSuccess)
2305     {
2306         GetViewData()->GetViewShell()->UpdateInputHandler();
2307     }
2308     return bSuccess;
2309 }
2310 
2311 //----------------------------------------------------------------------------
2312 
InsertAreaLink(const String & rFile,const String & rFilter,const String & rOptions,const String & rSource,sal_uLong nRefresh)2313 void ScViewFunc::InsertAreaLink( const String& rFile,
2314                                     const String& rFilter, const String& rOptions,
2315                                     const String& rSource, sal_uLong nRefresh )
2316 {
2317     ScDocShell* pDocSh = GetViewData()->GetDocShell();
2318     SCCOL nPosX = GetViewData()->GetCurX();
2319     SCROW nPosY = GetViewData()->GetCurY();
2320     SCTAB nTab = GetViewData()->GetTabNo();
2321     ScAddress aPos( nPosX, nPosY, nTab );
2322 
2323     pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, sal_False, sal_False );
2324 }
2325 
2326 
2327 //----------------------------------------------------------------------------
2328 
InsertTableLink(const String & rFile,const String & rFilter,const String & rOptions,const String & rTabName)2329 void ScViewFunc::InsertTableLink( const String& rFile,
2330                                     const String& rFilter, const String& rOptions,
2331                                     const String& rTabName )
2332 {
2333     String aFilterName = rFilter;
2334     String aOpt = rOptions;
2335     ScDocumentLoader aLoader( rFile, aFilterName, aOpt );
2336     if (!aLoader.IsError())
2337     {
2338         ScDocShell* pSrcSh = aLoader.GetDocShell();
2339         ScDocument* pSrcDoc = pSrcSh->GetDocument();
2340         SCTAB nTab = MAXTAB+1;
2341         if (!rTabName.Len())                // kein Name angegeben -> erste Tabelle
2342             nTab = 0;
2343         else
2344         {
2345             String aTemp;
2346             SCTAB nCount = pSrcDoc->GetTableCount();
2347             for (SCTAB i=0; i<nCount; i++)
2348             {
2349                 pSrcDoc->GetName( i, aTemp );
2350                 if ( aTemp == rTabName )
2351                     nTab = i;
2352             }
2353         }
2354 
2355         if ( nTab <= MAXTAB )
2356             ImportTables( pSrcSh, 1, &nTab, sal_True,
2357                         GetViewData()->GetTabNo() );
2358     }
2359 }
2360 
2361 
2362 //----------------------------------------------------------------------------
2363 //  Tabellen aus anderem Dokument kopieren / linken
2364 
ImportTables(ScDocShell * pSrcShell,SCTAB nCount,const SCTAB * pSrcTabs,sal_Bool bLink,SCTAB nTab)2365 void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
2366                                 SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2367 {
2368     ScDocument* pSrcDoc = pSrcShell->GetDocument();
2369 
2370     ScDocShell* pDocSh = GetViewData()->GetDocShell();
2371     ScDocument* pDoc = pDocSh->GetDocument();
2372     sal_Bool bUndo(pDoc->IsUndoEnabled());
2373     //SCTAB nTab = GetViewData()->GetTabNo();
2374 
2375     sal_Bool bError = sal_False;
2376     sal_Bool bRefs = sal_False;
2377     sal_Bool bName = sal_False;
2378 
2379     if (pSrcDoc->GetDrawLayer())
2380         pDocSh->MakeDrawLayer();
2381 
2382     if (bUndo)
2383         pDoc->BeginDrawUndo();          // drawing layer must do its own undo actions
2384 
2385     SCTAB nInsCount = 0;
2386     SCTAB i;
2387     for( i=0; i<nCount; i++ )
2388     {   // #63304# insert sheets first and update all references
2389         String aName;
2390         pSrcDoc->GetName( pSrcTabs[i], aName );
2391         pDoc->CreateValidTabName( aName );
2392         if ( !pDoc->InsertTab( nTab+i, aName ) )
2393         {
2394             bError = sal_True;      // total error
2395             break;  // for
2396         }
2397         ++nInsCount;
2398     }
2399     for (i=0; i<nCount && !bError; i++)
2400     {
2401         SCTAB nSrcTab = pSrcTabs[i];
2402         SCTAB nDestTab1=nTab+i;
2403         sal_uLong nErrVal = pDoc->TransferTab( pSrcDoc, nSrcTab, nDestTab1,
2404             sal_False );        // no insert
2405 
2406         switch (nErrVal)
2407         {
2408             case 0:                     // interner Fehler oder voll Fehler
2409                 bError = sal_True;
2410                 break;
2411             case 2:
2412                 bRefs = sal_True;
2413                 break;
2414             case 3:
2415                 bName = sal_True;
2416                 break;
2417             case 4:
2418                 bRefs = bName = sal_True;
2419                 break;
2420         }
2421 
2422         // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2423         if ( !bError )
2424             pDoc->TransferDrawPage( pSrcDoc, nSrcTab, nDestTab1 );
2425 
2426         if(!bError &&pSrcDoc->IsScenario(nSrcTab))
2427         {
2428             String aComment;
2429             Color  aColor;
2430             sal_uInt16 nFlags;
2431 
2432             pSrcDoc->GetScenarioData(nSrcTab, aComment,aColor, nFlags);
2433             pDoc->SetScenario( nDestTab1,sal_True);
2434             pDoc->SetScenarioData( nTab+i,aComment,aColor,nFlags);
2435             sal_Bool bActive = pSrcDoc->IsActiveScenario(nSrcTab );
2436             pDoc->SetActiveScenario( nDestTab1, bActive );
2437             sal_Bool bVisible=pSrcDoc->IsVisible(nSrcTab);
2438             pDoc->SetVisible(nDestTab1,bVisible );
2439 
2440         }
2441     }
2442 
2443     if (bLink)
2444     {
2445         sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2446 
2447         SfxMedium* pMed = pSrcShell->GetMedium();
2448         String aFileName = pMed->GetName();
2449         String aFilterName;
2450         if (pMed->GetFilter())
2451             aFilterName = pMed->GetFilter()->GetFilterName();
2452         String aOptions = ScDocumentLoader::GetOptions(*pMed);
2453 
2454         sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2455 
2456         sal_uLong nRefresh = 0;
2457         String aTabStr;
2458         for (i=0; i<nInsCount; i++)
2459         {
2460             pSrcDoc->GetName( pSrcTabs[i], aTabStr );
2461             pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2462                         aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2463         }
2464 
2465         if (!bWasThere)         // Link pro Quelldokument nur einmal eintragen
2466         {
2467             ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2468             pLink->SetInCreate( sal_True );
2469             pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
2470             pLink->Update();
2471             pLink->SetInCreate( sal_False );
2472 
2473             SfxBindings& rBindings = GetViewData()->GetBindings();
2474             rBindings.Invalidate( SID_LINKS );
2475         }
2476     }
2477 
2478 
2479     if (bUndo)
2480     {
2481         pDocSh->GetUndoManager()->AddUndoAction(
2482                 new ScUndoImportTab( pDocSh, nTab, nCount, bLink ) );
2483     }
2484 
2485     for (i=0; i<nInsCount; i++)
2486         GetViewData()->InsertTab(nTab);
2487     SetTabNo(nTab,sal_True);
2488     pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2489                                 PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
2490 
2491     SfxApplication* pSfxApp = SFX_APP();
2492     pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2493     pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
2494 
2495     pDocSh->PostPaintExtras();
2496     pDocSh->PostPaintGridAll();
2497     pDocSh->SetDocumentModified();
2498 
2499     if (bRefs)
2500         ErrorMessage(STR_ABSREFLOST);
2501     if (bName)
2502         ErrorMessage(STR_NAMECONFLICT);
2503 }
2504 
2505 
2506 //----------------------------------------------------------------------------
2507 //  Tabelle in anderes Dokument verschieben / kopieren
2508 
MoveTable(sal_uInt16 nDestDocNo,SCTAB nDestTab,sal_Bool bCopy)2509 void ScViewFunc::MoveTable( sal_uInt16 nDestDocNo, SCTAB nDestTab, sal_Bool bCopy )
2510 {
2511     ScDocument* pDoc       = GetViewData()->GetDocument();
2512     ScDocShell* pDocShell  = GetViewData()->GetDocShell();
2513     ScDocument* pDestDoc   = NULL;
2514     ScDocShell* pDestShell = NULL;
2515     ScTabViewShell* pDestViewSh = NULL;
2516     sal_Bool bUndo (pDoc->IsUndoEnabled());
2517 
2518     sal_Bool bNewDoc = ( nDestDocNo == SC_DOC_NEW );
2519     if ( bNewDoc )
2520     {
2521         nDestTab = 0;           // als erstes einfuegen
2522 
2523         //  ohne SFX_CALLMODE_RECORD ausfuehren, weil schon im Move-Befehl enthalten:
2524 
2525         String aUrl = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("private:factory/"));
2526         aUrl.AppendAscii(RTL_CONSTASCII_STRINGPARAM( STRING_SCAPP ));               // "scalc"
2527         SfxStringItem aItem( SID_FILE_NAME, aUrl );
2528         SfxStringItem aTarget( SID_TARGETNAME, String::CreateFromAscii("_blank") );
2529 
2530         const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
2531                     SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
2532         if ( pRetItem )
2533         {
2534             if ( pRetItem->ISA( SfxObjectItem ) )
2535                 pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
2536             else if ( pRetItem->ISA( SfxViewFrameItem ) )
2537             {
2538                 SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
2539                 if (pFrm)
2540                     pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2541             }
2542             if (pDestShell)
2543                 pDestViewSh = pDestShell->GetBestViewShell();
2544         }
2545     }
2546     else
2547         pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
2548 
2549     if (!pDestShell)
2550     {
2551         DBG_ERROR("Dest-Doc nicht gefunden !!!");
2552         return;
2553     }
2554 
2555     pDestDoc = pDestShell->GetDocument();
2556 
2557     SCTAB nTab = GetViewData()->GetTabNo();
2558 
2559     if (pDestDoc != pDoc)
2560     {
2561         if (bNewDoc)
2562         {
2563             while (pDestDoc->GetTableCount() > 1)
2564                 pDestDoc->DeleteTab(0);
2565             pDestDoc->RenameTab( 0,
2566                         String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("______42_____")),
2567                         sal_False );
2568         }
2569 
2570         ScMarkData& rMark       = GetViewData()->GetMarkData();
2571         SCTAB       nTabCount   = pDoc->GetTableCount();
2572         SCTAB       nTabSelCount = rMark.GetSelectCount();
2573 
2574         SvShorts    TheTabs;
2575 
2576         for(SCTAB i=0;i<nTabCount;i++)
2577         {
2578             if(rMark.GetTableSelect(i))
2579             {
2580                 String aTabName;
2581                 pDoc->GetName( i, aTabName);
2582                 TheTabs.push_back(i);
2583                 for(SCTAB j=i+1;j<nTabCount;j++)
2584                 {
2585                     if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2586                     {
2587                         pDoc->GetName( j, aTabName);
2588                         TheTabs.push_back(j);
2589                         i=j;
2590                     }
2591                     else break;
2592                 }
2593             }
2594         }
2595 
2596         GetFrameWin()->EnterWait();
2597 
2598         if (pDoc->GetDrawLayer())
2599             pDestShell->MakeDrawLayer();
2600 
2601         if (!bNewDoc && bUndo)
2602             pDestDoc->BeginDrawUndo();      // drawing layer must do its own undo actions
2603 
2604         sal_uLong nErrVal =1;
2605         if(nDestTab==SC_TAB_APPEND)
2606             nDestTab=pDestDoc->GetTableCount();
2607         SCTAB nDestTab1=nDestTab;
2608         for( size_t j=0; j<TheTabs.size(); j++, nDestTab1++ )
2609         {   // #63304# insert sheets first and update all references
2610             String aName;
2611             pDoc->GetName( TheTabs[j], aName );
2612             pDestDoc->CreateValidTabName( aName );
2613             if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
2614             {
2615                 nErrVal = 0;        // total error
2616                 break;  // for
2617             }
2618         }
2619         if ( nErrVal > 0 )
2620         {
2621             nDestTab1 = nDestTab;
2622             for(size_t i=0;i<TheTabs.size();i++)
2623             {
2624                 nErrVal = pDestDoc->TransferTab( pDoc, TheTabs[i], nDestTab1,
2625                     sal_False );        // no insert
2626 
2627                 // TransferTab doesn't copy drawing objects with bInsertNew=FALSE
2628                 if ( nErrVal > 0 )
2629                     pDestDoc->TransferDrawPage( pDoc, TheTabs[i], nDestTab1 );
2630 
2631                 if(nErrVal>0 && pDoc->IsScenario(TheTabs[i]))
2632                 {
2633                     String aComment;
2634                     Color  aColor;
2635                     sal_uInt16 nFlags;
2636 
2637                     pDoc->GetScenarioData(TheTabs[i], aComment,aColor, nFlags);
2638                     pDestDoc->SetScenario(nDestTab1,sal_True);
2639                     pDestDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2640                     sal_Bool bActive = pDoc->IsActiveScenario(TheTabs[i]);
2641                     pDestDoc->SetActiveScenario(nDestTab1, bActive );
2642 
2643                     sal_Bool bVisible=pDoc->IsVisible(TheTabs[i]);
2644                     pDestDoc->SetVisible(nDestTab1,bVisible );
2645 
2646                 }
2647 
2648                 if ( nErrVal > 0 && pDoc->IsTabProtected( TheTabs[i] ) )
2649                     pDestDoc->SetTabProtection(nDestTab1, pDoc->GetTabProtection(TheTabs[i]));
2650 
2651                 nDestTab1++;
2652             }
2653         }
2654         String sName;
2655         if (!bNewDoc && bUndo)
2656         {
2657             pDestDoc->GetName(nDestTab, sName);
2658             pDestShell->GetUndoManager()->AddUndoAction(
2659                             new ScUndoImportTab( pDestShell, nDestTab,
2660                                 static_cast<SCTAB>(TheTabs.size()), sal_False));
2661 
2662         }
2663         else
2664         {
2665             pDestShell->GetUndoManager()->Clear();
2666         }
2667 
2668         GetFrameWin()->LeaveWait();
2669         switch (nErrVal)
2670         {
2671             case 0:                     // interner Fehler oder voll Fehler
2672             {
2673                 ErrorMessage(STR_TABINSERT_ERROR);
2674                 return;
2675             }
2676             //break;
2677             case 2:
2678                 ErrorMessage(STR_ABSREFLOST);
2679             break;
2680             case 3:
2681                 ErrorMessage(STR_NAMECONFLICT);
2682             break;
2683             case 4:
2684             {
2685                 ErrorMessage(STR_ABSREFLOST);
2686                 ErrorMessage(STR_NAMECONFLICT);
2687             }
2688             break;
2689             default:
2690             break;
2691         }
2692         //pDestShell->GetUndoManager()->Clear();        //! Undo implementieren !!!
2693 /*
2694         String sName;
2695         pDestDoc->GetName(nDestTab, sName);
2696         pDestShell->GetUndoManager()->AddUndoAction(
2697                         new ScUndoInsertTab( pDestShell, nDestTab, sal_True, sName ) );
2698 */
2699         if (!bCopy)
2700         {
2701             if(nTabCount!=nTabSelCount)
2702                 DeleteTables(TheTabs);// incl. Paint & Undo
2703             else
2704                 ErrorMessage(STR_TABREMOVE_ERROR);
2705         }
2706 
2707         if (bNewDoc)
2708         {
2709             //  ChartListenerCollection must be updated before DeleteTab
2710             if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
2711                 pDestDoc->UpdateChartListenerCollection();
2712 
2713             pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size()));   // first old table
2714 //?         pDestDoc->SelectTable(0, sal_True);     // neue erste Tabelle selektieren
2715             if (pDestViewSh)
2716                 pDestViewSh->TabChanged();      // Pages auf dem Drawing-Layer
2717             pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2718                                     PAINT_GRID | PAINT_TOP | PAINT_LEFT |
2719                                     PAINT_EXTRAS | PAINT_SIZE );
2720             //  PAINT_SIZE fuer Gliederung
2721         }
2722         else
2723         {
2724             pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
2725             pDestShell->PostPaintExtras();
2726             pDestShell->PostPaintGridAll();
2727         }
2728 
2729         TheTabs.clear();
2730 
2731         pDestShell->SetDocumentModified();
2732         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2733     }
2734     else                    // within the documents
2735     {
2736 
2737         ScMarkData& rMark       = GetViewData()->GetMarkData();
2738         SCTAB       nTabCount   = pDoc->GetTableCount();
2739 
2740         SvShorts    TheTabs;
2741         SvShorts    TheDestTabs;
2742         SvStrings   TheTabNames;
2743         String      aDestName;
2744         String      *pString;
2745 
2746         for(SCTAB i=0;i<nTabCount;i++)
2747         {
2748             if(rMark.GetTableSelect(i))
2749             {
2750                 String aTabName;
2751                 pDoc->GetName( i, aTabName);
2752                 TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2753 
2754                 for(SCTAB j=i+1;j<nTabCount;j++)
2755                 {
2756                     if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2757                     {
2758                         pDoc->GetName( j, aTabName);
2759                         TheTabNames.Insert(new String(aTabName),TheTabNames.Count());
2760                         i=j;
2761                     }
2762                     else break;
2763                 }
2764 
2765             }
2766         }
2767 
2768         if (bCopy && bUndo)
2769             pDoc->BeginDrawUndo();          // drawing layer must do its own undo actions
2770 
2771         pDoc->GetName( nDestTab, aDestName);
2772         SCTAB nDestTab1=nDestTab;
2773         SCTAB nMovTab=0;
2774         for(int j=0;j<TheTabNames.Count();j++)
2775         {
2776             nTabCount   = pDoc->GetTableCount();
2777             pString=TheTabNames[sal::static_int_cast<sal_uInt16>(j)];
2778             if(!pDoc->GetTable(*pString,nMovTab))
2779             {
2780                 nMovTab=nTabCount;
2781             }
2782             if(!pDoc->GetTable(aDestName,nDestTab1))
2783             {
2784                 nDestTab1=nTabCount;
2785             }
2786             pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, sal_False );   // Undo ist hier
2787 
2788             if(bCopy && pDoc->IsScenario(nMovTab))
2789             {
2790                 String aComment;
2791                 Color  aColor;
2792                 sal_uInt16 nFlags;
2793 
2794                 pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
2795                 pDoc->SetScenario(nDestTab1,sal_True);
2796                 pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2797                 sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2798                 pDoc->SetActiveScenario( nDestTab1, bActive );
2799                 sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2800                 pDoc->SetVisible(nDestTab1,bVisible );
2801             }
2802 
2803             TheTabs.push_back(nMovTab);
2804 
2805             if(!bCopy)
2806             {
2807                 if(!pDoc->GetTable(*pString,nDestTab1))
2808                 {
2809                     nDestTab1=nTabCount;
2810                 }
2811             }
2812 
2813             TheDestTabs.push_back(nDestTab1);
2814             delete pString;
2815         }
2816 
2817         nTab = GetViewData()->GetTabNo();
2818 
2819         if (bUndo)
2820         {
2821             if (bCopy)
2822             {
2823                 pDocShell->GetUndoManager()->AddUndoAction(
2824                         new ScUndoCopyTab( pDocShell, TheTabs, TheDestTabs));
2825             }
2826             else
2827             {
2828                 pDocShell->GetUndoManager()->AddUndoAction(
2829                         new ScUndoMoveTab( pDocShell, TheTabs, TheDestTabs));
2830             }
2831         }
2832 
2833         SCTAB nNewTab = nDestTab;
2834         if (nNewTab == SC_TAB_APPEND)
2835             nNewTab = pDoc->GetTableCount()-1;
2836         else if (!bCopy && nTab<nDestTab)
2837             nNewTab--;
2838 
2839         SetTabNo( nNewTab, sal_True );
2840 
2841         //#i29848# adjust references to data on the copied sheet
2842         if( bCopy )
2843             ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
2844     }
2845 }
2846 
2847 
2848 //----------------------------------------------------------------------------
2849 
ShowTable(const String & rName)2850 void ScViewFunc::ShowTable( const String& rName )
2851 {
2852     ScDocShell* pDocSh = GetViewData()->GetDocShell();
2853     ScDocument* pDoc = pDocSh->GetDocument();
2854     sal_Bool bUndo(pDoc->IsUndoEnabled());
2855     sal_Bool bFound = sal_False;
2856     SCTAB nPos = 0;
2857     String aTabName;
2858     SCTAB nCount = pDoc->GetTableCount();
2859     for (SCTAB i=0; i<nCount; i++)
2860     {
2861         pDoc->GetName( i, aTabName );
2862         if ( aTabName == rName )
2863         {
2864             nPos = i;
2865             bFound = sal_True;
2866         }
2867     }
2868 
2869     if (bFound)
2870     {
2871         pDoc->SetVisible( nPos, sal_True );
2872         if (bUndo)
2873         {
2874             pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nPos, sal_True ) );
2875         }
2876         SetTabNo( nPos, sal_True );
2877         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2878         pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2879         pDocSh->SetDocumentModified();
2880     }
2881     else
2882         Sound::Beep();
2883 }
2884 
2885 
2886 //----------------------------------------------------------------------------
2887 
HideTable(SCTAB nTab)2888 void ScViewFunc::HideTable( SCTAB nTab )
2889 {
2890     ScDocShell* pDocSh = GetViewData()->GetDocShell();
2891     ScDocument* pDoc = pDocSh->GetDocument();
2892     sal_Bool bUndo(pDoc->IsUndoEnabled());
2893     SCTAB nVisible = 0;
2894     SCTAB nCount = pDoc->GetTableCount();
2895     for (SCTAB i=0; i<nCount; i++)
2896     {
2897         if (pDoc->IsVisible(i))
2898             ++nVisible;
2899     }
2900 
2901     if (nVisible > 1)
2902     {
2903         pDoc->SetVisible( nTab, sal_False );
2904         if (bUndo)
2905         {
2906             pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, nTab, sal_False ) );
2907         }
2908 
2909         //  Views updaten:
2910         pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
2911 
2912         SetTabNo( nTab, sal_True );
2913         SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2914         pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2915         pDocSh->SetDocumentModified();
2916     }
2917     else
2918         Sound::Beep();
2919 }
2920 
2921 
2922 //----------------------------------------------------------------------------
2923 
InsertSpecialChar(const String & rStr,const Font & rFont)2924 void ScViewFunc::InsertSpecialChar( const String& rStr, const Font& rFont )
2925 {
2926     ScEditableTester aTester( this );
2927     if (!aTester.IsEditable())
2928     {
2929         ErrorMessage(aTester.GetMessageId());
2930         return;
2931     }
2932 
2933     const sal_Unicode* pChar    = rStr.GetBuffer();
2934     ScTabViewShell* pViewShell  = GetViewData()->GetViewShell();
2935     SvxFontItem     aFontItem( rFont.GetFamily(),
2936                                rFont.GetName(),
2937                                rFont.GetStyleName(),
2938                                rFont.GetPitch(),
2939                                rFont.GetCharSet(),
2940                                ATTR_FONT );
2941 
2942     //  if string contains WEAK characters, set all fonts
2943     sal_uInt8 nScript;
2944     ScDocument* pDoc = GetViewData()->GetDocument();
2945     if ( pDoc->HasStringWeakCharacters( rStr ) )
2946         nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
2947     else
2948         nScript = pDoc->GetStringScriptType( rStr );
2949 
2950     SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
2951     aSetItem.PutItemForScriptType( nScript, aFontItem );
2952     ApplyUserItemSet( aSetItem.GetItemSet() );
2953 
2954     while ( *pChar )
2955         pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
2956 }
2957 
2958 
2959 //----------------------------------------------------------------------------
2960 
UpdateLineAttrs(SvxBorderLine & rLine,const SvxBorderLine * pDestLine,const SvxBorderLine * pSrcLine,sal_Bool bColor)2961 void ScViewFunc::UpdateLineAttrs( SvxBorderLine&       rLine,
2962                                   const SvxBorderLine* pDestLine,
2963                                   const SvxBorderLine* pSrcLine,
2964                                   sal_Bool                 bColor )
2965 {
2966     if ( pSrcLine && pDestLine )
2967     {
2968         if ( bColor )
2969         {
2970             rLine.SetColor      ( pSrcLine->GetColor() );
2971             rLine.SetOutWidth   ( pDestLine->GetOutWidth() );
2972             rLine.SetInWidth    ( pDestLine->GetInWidth() );
2973             rLine.SetDistance   ( pDestLine->GetDistance() );
2974         }
2975         else
2976         {
2977             rLine.SetColor      ( pDestLine->GetColor() );
2978             rLine.SetOutWidth   ( pSrcLine->GetOutWidth() );
2979             rLine.SetInWidth    ( pSrcLine->GetInWidth() );
2980             rLine.SetDistance   ( pSrcLine->GetDistance() );
2981         }
2982     }
2983 }
2984 
2985 
2986 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
2987     pBoxLine = aBoxItem.Get##LINE();                                \
2988     if ( pBoxLine )                                                 \
2989     {                                                               \
2990         if ( pLine )                                                \
2991         {                                                           \
2992             UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly );  \
2993             aBoxItem.SetLine( &aLine, BOXLINE );                    \
2994         }                                                           \
2995         else                                                        \
2996             aBoxItem.SetLine( NULL, BOXLINE );                      \
2997     }
2998 
2999 
3000 //----------------------------------------------------------------------------
3001 
SetSelectionFrameLines(const SvxBorderLine * pLine,sal_Bool bColorOnly)3002 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
3003                                          sal_Bool bColorOnly )
3004 {
3005     // nur wegen Matrix nicht editierbar? Attribute trotzdem ok
3006     sal_Bool bOnlyNotBecauseOfMatrix;
3007     if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
3008     {
3009         ErrorMessage(STR_PROTECTIONERR);
3010         return;
3011     }
3012 
3013     ScDocument*             pDoc = GetViewData()->GetDocument();
3014     ScMarkData aFuncMark( GetViewData()->GetMarkData() );       // local copy for UnmarkFiltered
3015     ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
3016     ScDocShell*             pDocSh = GetViewData()->GetDocShell();
3017     const ScPatternAttr*    pSelAttrs = GetSelectionPattern();
3018     const SfxItemSet&       rSelItemSet = pSelAttrs->GetItemSet();
3019 
3020     const SfxPoolItem*      pBorderAttr = NULL;
3021     SfxItemState            eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
3022 
3023     const SfxPoolItem*      pTLBRItem = 0;
3024     SfxItemState            eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
3025 
3026     const SfxPoolItem*      pBLTRItem = 0;
3027     SfxItemState            eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
3028 
3029     // any of the lines visible?
3030     if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
3031     {
3032         // none of the lines don't care?
3033         if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
3034         {
3035             SfxItemSet*     pOldSet = new SfxItemSet(
3036                                             *(pDoc->GetPool()),
3037                                             ATTR_PATTERN_START,
3038                                             ATTR_PATTERN_END );
3039             SfxItemSet*     pNewSet = new SfxItemSet(
3040                                             *(pDoc->GetPool()),
3041                                             ATTR_PATTERN_START,
3042                                             ATTR_PATTERN_END );
3043 
3044             //------------------------------------------------------------
3045             const SvxBorderLine*    pBoxLine = NULL;
3046             SvxBorderLine           aLine;
3047 
3048             // hier wird die pBoxLine benutzt:
3049 
3050             if( pBorderAttr )
3051             {
3052                 SvxBoxItem      aBoxItem( *(const SvxBoxItem*)pBorderAttr );
3053                 SvxBoxInfoItem  aBoxInfoItem( ATTR_BORDER_INNER );
3054 
3055                 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
3056                 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
3057                 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
3058                 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
3059 
3060                 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
3061                 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
3062                 aBoxInfoItem.ResetFlags(); // Lines auf Valid setzen
3063 
3064                 pOldSet->Put( *pBorderAttr );
3065                 pNewSet->Put( aBoxItem );
3066                 pNewSet->Put( aBoxInfoItem );
3067             }
3068 
3069             if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
3070             {
3071                 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
3072                 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
3073                 aTLBRItem.SetLine( &aLine );
3074                 pOldSet->Put( *pTLBRItem );
3075                 pNewSet->Put( aTLBRItem );
3076             }
3077 
3078             if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
3079             {
3080                 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
3081                 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
3082                 aBLTRItem.SetLine( &aLine );
3083                 pOldSet->Put( *pBLTRItem );
3084                 pNewSet->Put( aBLTRItem );
3085             }
3086 
3087             ApplyAttributes( pNewSet, pOldSet );
3088 
3089             delete pOldSet;
3090             delete pNewSet;
3091         }
3092         else // if ( eItemState == SFX_ITEM_DONTCARE )
3093         {
3094             aFuncMark.MarkToMulti();
3095             pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
3096         }
3097 
3098         ScRange aMarkRange;
3099         aFuncMark.GetMultiMarkArea( aMarkRange );
3100         SCCOL nStartCol = aMarkRange.aStart.Col();
3101         SCROW nStartRow = aMarkRange.aStart.Row();
3102         SCTAB nStartTab = aMarkRange.aStart.Tab();
3103         SCCOL nEndCol = aMarkRange.aEnd.Col();
3104         SCROW nEndRow = aMarkRange.aEnd.Row();
3105         SCTAB nEndTab = aMarkRange.aEnd.Tab();
3106         pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
3107                            nEndCol, nEndRow, nEndTab,
3108                            PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3109 
3110         pDocSh->UpdateOle( GetViewData() );
3111         pDocSh->SetDocumentModified();
3112     }
3113 }
3114 
3115 #undef SET_LINE_ATTRIBUTES
3116 
3117 
3118 //----------------------------------------------------------------------------
3119 
SetConditionalFormat(const ScConditionalFormat & rNew)3120 void ScViewFunc::SetConditionalFormat( const ScConditionalFormat& rNew )
3121 {
3122     ScDocument* pDoc = GetViewData()->GetDocument();
3123     sal_uLong nIndex = pDoc->AddCondFormat(rNew);           // dafuer gibt's kein Undo
3124     SfxUInt32Item aItem( ATTR_CONDITIONAL, nIndex );
3125 
3126     ApplyAttr( aItem );         // mit Paint und Undo...
3127 }
3128 
3129 
3130 //----------------------------------------------------------------------------
3131 
SetValidation(const ScValidationData & rNew)3132 void ScViewFunc::SetValidation( const ScValidationData& rNew )
3133 {
3134     ScDocument* pDoc = GetViewData()->GetDocument();
3135     sal_uLong nIndex = pDoc->AddValidationEntry(rNew);      // dafuer gibt's kein Undo
3136     SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
3137 
3138     ApplyAttr( aItem );         // mit Paint und Undo...
3139 }
3140 
3141 
3142