GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / sc / source / ui / view / viewfun2.cxx
blob2ee7075b5c6f56b7b9ef85295732dd0f849b5159
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "scitems.hxx"
21 #include <comphelper/string.hxx>
22 #include <editeng/eeitem.hxx>
24 #include <sfx2/app.hxx>
25 #include <editeng/boxitem.hxx>
26 #include <editeng/fontitem.hxx>
27 #include <editeng/scripttypeitem.hxx>
28 #include <svl/srchitem.hxx>
29 #include <sfx2/linkmgr.hxx>
30 #include <sfx2/dispatch.hxx>
31 #include <sfx2/docfilt.hxx>
32 #include <sfx2/docfile.hxx>
33 #include <sfx2/objitem.hxx>
34 #include <sfx2/viewfrm.hxx>
35 #include <svl/stritem.hxx>
36 #include <svl/zforlist.hxx>
37 #include <svx/svdview.hxx>
38 #include <vcl/msgbox.hxx>
39 #include <vcl/waitobj.hxx>
41 #include <basic/sbstar.hxx>
42 #include <com/sun/star/container/XNameContainer.hpp>
43 #include <com/sun/star/script/XLibraryContainer.hpp>
45 #include "viewfunc.hxx"
47 #include "sc.hrc"
48 #include "globstr.hrc"
50 #include "attrib.hxx"
51 #include "autoform.hxx"
52 #include "formulacell.hxx"
53 #include "cellmergeoption.hxx"
54 #include "compiler.hxx"
55 #include "docfunc.hxx"
56 #include "docpool.hxx"
57 #include "docsh.hxx"
58 #include "global.hxx"
59 #include "patattr.hxx"
60 #include "printfun.hxx"
61 #include "rangenam.hxx"
62 #include "rangeutl.hxx"
63 #include "refundo.hxx"
64 #include "table.hxx"
65 #include "tablink.hxx"
66 #include "tabvwsh.hxx"
67 #include "uiitems.hxx"
68 #include "undoblk.hxx"
69 #include "undocell.hxx"
70 #include "undotab.hxx"
71 #include "sizedev.hxx"
72 #include "editable.hxx"
73 #include "scmod.hxx"
74 #include "inputhdl.hxx"
75 #include "inputwin.hxx"
76 #include "funcdesc.hxx"
77 #include "docuno.hxx"
78 #include "charthelper.hxx"
79 #include "tabbgcolor.hxx"
80 #include "clipparam.hxx"
81 #include "prnsave.hxx"
82 #include "searchresults.hxx"
83 #include "tokenarray.hxx"
85 #include <boost/scoped_ptr.hpp>
86 #include <vector>
87 #include <memory>
89 using namespace com::sun::star;
90 using ::editeng::SvxBorderLine;
92 using ::std::vector;
93 using ::std::auto_ptr;
95 // helper func defined in docfunc.cxx
96 void VBA_DeleteModule( ScDocShell& rDocSh, const OUString& sModuleName );
98 // STATIC DATA ---------------------------------------------------------------
101 //----------------------------------------------------------------------------
103 sal_Bool ScViewFunc::AdjustBlockHeight( sal_Bool bPaint, ScMarkData* pMarkData )
105 ScDocShell* pDocSh = GetViewData()->GetDocShell();
106 if (!pMarkData)
107 pMarkData = &GetViewData()->GetMarkData();
109 ScDocument* pDoc = pDocSh->GetDocument();
110 SCCOLROW* pRanges = new SCCOLROW[MAXCOLROWCOUNT];
111 SCCOLROW nRangeCnt = pMarkData->GetMarkRowRanges( pRanges );
112 if (nRangeCnt == 0)
114 pRanges[0] = pRanges[1] = GetViewData()->GetCurY();
115 nRangeCnt = 1;
118 double nPPTX = GetViewData()->GetPPTX();
119 double nPPTY = GetViewData()->GetPPTY();
120 Fraction aZoomX = GetViewData()->GetZoomX();
121 Fraction aZoomY = GetViewData()->GetZoomY();
123 ScSizeDeviceProvider aProv(pDocSh);
124 if (aProv.IsPrinter())
126 nPPTX = aProv.GetPPTX();
127 nPPTY = aProv.GetPPTY();
128 aZoomX = aZoomY = Fraction( 1, 1 );
131 sal_Bool bAnyChanged = false;
132 ScMarkData::iterator itr = pMarkData->begin(), itrEnd = pMarkData->end();
133 for (; itr != itrEnd; ++itr)
135 SCTAB nTab = *itr;
136 SCCOLROW* pOneRange = pRanges;
137 sal_Bool bChanged = false;
138 SCROW nPaintY = 0;
139 for (SCROW nRangeNo=0; nRangeNo<nRangeCnt; nRangeNo++)
141 SCROW nStartNo = *(pOneRange++);
142 SCROW nEndNo = *(pOneRange++);
143 if (pDoc->SetOptimalHeight( nStartNo, nEndNo, nTab, 0, aProv.GetDevice(),
144 nPPTX, nPPTY, aZoomX, aZoomY, false ))
146 if (!bChanged)
147 nPaintY = nStartNo;
148 bAnyChanged = bChanged = sal_True;
151 if ( bPaint && bChanged )
152 pDocSh->PostPaint( 0, nPaintY, nTab, MAXCOL, MAXROW, nTab,
153 PAINT_GRID | PAINT_LEFT );
155 delete[] pRanges;
157 if ( bPaint && bAnyChanged )
158 pDocSh->UpdateOle(GetViewData());
160 return bAnyChanged;
164 //----------------------------------------------------------------------------
166 sal_Bool ScViewFunc::AdjustRowHeight( SCROW nStartRow, SCROW nEndRow, sal_Bool bPaint )
168 ScDocShell* pDocSh = GetViewData()->GetDocShell();
169 ScDocument* pDoc = pDocSh->GetDocument();
170 SCTAB nTab = GetViewData()->GetTabNo();
171 double nPPTX = GetViewData()->GetPPTX();
172 double nPPTY = GetViewData()->GetPPTY();
173 Fraction aZoomX = GetViewData()->GetZoomX();
174 Fraction aZoomY = GetViewData()->GetZoomY();
175 sal_uInt16 nOldPixel = 0;
176 if (nStartRow == nEndRow)
177 nOldPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
179 ScSizeDeviceProvider aProv(pDocSh);
180 if (aProv.IsPrinter())
182 nPPTX = aProv.GetPPTX();
183 nPPTY = aProv.GetPPTY();
184 aZoomX = aZoomY = Fraction( 1, 1 );
186 sal_Bool bChanged = pDoc->SetOptimalHeight( nStartRow, nEndRow, nTab, 0, aProv.GetDevice(),
187 nPPTX, nPPTY, aZoomX, aZoomY, false );
189 if (bChanged && ( nStartRow == nEndRow ))
191 sal_uInt16 nNewPixel = (sal_uInt16) (pDoc->GetRowHeight(nStartRow,nTab) * nPPTY);
192 if ( nNewPixel == nOldPixel )
193 bChanged = false;
196 if ( bPaint && bChanged )
197 pDocSh->PostPaint( 0, nStartRow, nTab, MAXCOL, MAXROW, nTab,
198 PAINT_GRID | PAINT_LEFT );
200 return bChanged;
204 //----------------------------------------------------------------------------
206 enum ScAutoSum
208 ScAutoSumNone = 0,
209 ScAutoSumData,
210 ScAutoSumSum
214 static ScAutoSum lcl_IsAutoSumData( ScDocument* pDoc, SCCOL nCol, SCROW nRow,
215 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
217 ScRefCellValue aCell;
218 aCell.assign(*pDoc, ScAddress(nCol, nRow, nTab));
219 if (aCell.hasNumeric())
221 if (aCell.meType == CELLTYPE_FORMULA)
223 ScTokenArray* pCode = aCell.mpFormula->GetCode();
224 if ( pCode && pCode->GetOuterFuncOpCode() == ocSum )
226 if ( pCode->GetAdjacentExtendOfOuterFuncRefs( nExtend,
227 ScAddress( nCol, nRow, nTab ), eDir ) )
228 return ScAutoSumSum;
231 return ScAutoSumData;
233 return ScAutoSumNone;
237 //----------------------------------------------------------------------------
239 #define SC_AUTOSUM_MAXCOUNT 20
241 static ScAutoSum lcl_SeekAutoSumData( ScDocument* pDoc, SCCOL& nCol, SCROW& nRow,
242 SCTAB nTab, ScDirection eDir, SCCOLROW& nExtend )
244 sal_uInt16 nCount = 0;
245 while (nCount < SC_AUTOSUM_MAXCOUNT)
247 if ( eDir == DIR_TOP )
249 if (nRow > 0)
250 --nRow;
251 else
252 return ScAutoSumNone;
254 else
256 if (nCol > 0)
257 --nCol;
258 else
259 return ScAutoSumNone;
261 ScAutoSum eSum;
262 if ( (eSum = lcl_IsAutoSumData(
263 pDoc, nCol, nRow, nTab, eDir, nExtend )) != ScAutoSumNone )
264 return eSum;
265 ++nCount;
267 return ScAutoSumNone;
270 #undef SC_AUTOSUM_MAXCOUNT
272 //----------------------------------------------------------------------------
274 static bool lcl_FindNextSumEntryInColumn( ScDocument* pDoc, SCCOL nCol, SCROW& nRow,
275 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinRow )
277 const SCROW nTmp = nRow;
278 ScAutoSum eSkip = ScAutoSumNone;
279 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) ) == ScAutoSumData &&
280 nRow > nMinRow )
282 --nRow;
284 if ( eSkip == ScAutoSumSum && nRow < nTmp )
286 return true;
288 return false;
291 //----------------------------------------------------------------------------
293 static bool lcl_FindNextSumEntryInRow( ScDocument* pDoc, SCCOL& nCol, SCROW nRow,
294 SCTAB nTab, SCCOLROW& nExtend, SCROW nMinCol )
296 const SCCOL nTmp = nCol;
297 ScAutoSum eSkip = ScAutoSumNone;
298 while ( ( eSkip = lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) ) == ScAutoSumData &&
299 nCol > nMinCol )
301 --nCol;
303 if ( eSkip == ScAutoSumSum && nCol < nTmp )
305 return true;
307 return false;
310 //----------------------------------------------------------------------------
312 static bool lcl_GetAutoSumForColumnRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
314 const ScAddress aStart = rRange.aStart;
315 const ScAddress aEnd = rRange.aEnd;
316 if ( aStart.Col() != aEnd.Col() )
318 return false;
321 const SCTAB nTab = aEnd.Tab();
322 const SCCOL nCol = aEnd.Col();
323 SCROW nEndRow = aEnd.Row();
324 SCROW nStartRow = nEndRow;
325 SCCOLROW nExtend = 0;
326 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nCol, nEndRow, nTab, DIR_TOP, nExtend /*out*/ );
328 if ( eSum == ScAutoSumSum )
330 bool bContinue = false;
333 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
334 nEndRow = static_cast< SCROW >( nExtend );
335 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, aStart.Row() ) ) == true )
337 nStartRow = nEndRow;
339 } while ( bContinue );
341 else
343 while ( nStartRow > aStart.Row() &&
344 lcl_IsAutoSumData( pDoc, nCol, nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) != ScAutoSumSum )
346 --nStartRow;
348 rRangeList.Append( ScRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab ) );
351 return true;
354 //----------------------------------------------------------------------------
356 static bool lcl_GetAutoSumForRowRange( ScDocument* pDoc, ScRangeList& rRangeList, const ScRange& rRange )
358 const ScAddress aStart = rRange.aStart;
359 const ScAddress aEnd = rRange.aEnd;
360 if ( aStart.Row() != aEnd.Row() )
362 return false;
365 const SCTAB nTab = aEnd.Tab();
366 const SCROW nRow = aEnd.Row();
367 SCCOL nEndCol = aEnd.Col();
368 SCCOL nStartCol = nEndCol;
369 SCCOLROW nExtend = 0;
370 const ScAutoSum eSum = lcl_IsAutoSumData( pDoc, nEndCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ );
372 if ( eSum == ScAutoSumSum )
374 bool bContinue = false;
377 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
378 nEndCol = static_cast< SCCOL >( nExtend );
379 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, aStart.Col() ) ) == true )
381 nStartCol = nEndCol;
383 } while ( bContinue );
385 else
387 while ( nStartCol > aStart.Col() &&
388 lcl_IsAutoSumData( pDoc, nStartCol-1, nRow, nTab, DIR_LEFT, nExtend /*out*/ ) != ScAutoSumSum )
390 --nStartCol;
392 rRangeList.Append( ScRange( nStartCol, nRow, nTab, nEndCol, nRow, nTab ) );
395 return true;
398 //----------------------------------------------------------------------------
400 sal_Bool ScViewFunc::GetAutoSumArea( ScRangeList& rRangeList )
402 ScDocument* pDoc = GetViewData()->GetDocument();
403 SCTAB nTab = GetViewData()->GetTabNo();
405 SCCOL nCol = GetViewData()->GetCurX();
406 SCROW nRow = GetViewData()->GetCurY();
408 SCCOL nStartCol = nCol;
409 SCROW nStartRow = nRow;
410 SCCOL nEndCol = nCol;
411 SCROW nEndRow = nRow;
412 SCCOL nSeekCol = nCol;
413 SCROW nSeekRow = nRow;
414 SCCOLROW nExtend; // will become valid via reference for ScAutoSumSum
416 sal_Bool bCol = false;
417 sal_Bool bRow = false;
419 ScAutoSum eSum;
420 if ( nRow != 0
421 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
422 DIR_TOP, nExtend /*out*/ )) == ScAutoSumData )
423 && ((eSum = lcl_IsAutoSumData( pDoc, nCol, nRow-1, nTab,
424 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
427 bRow = sal_True;
428 nSeekRow = nRow - 1;
430 else if ( nCol != 0 && (eSum = lcl_IsAutoSumData( pDoc, nCol-1, nRow, nTab,
431 DIR_LEFT, nExtend /*out*/ )) == ScAutoSumData )
433 bCol = sal_True;
434 nSeekCol = nCol - 1;
436 else if ( (eSum = lcl_SeekAutoSumData( pDoc, nCol, nSeekRow, nTab, DIR_TOP, nExtend /*out*/ )) != ScAutoSumNone )
437 bRow = sal_True;
438 else if (( eSum = lcl_SeekAutoSumData( pDoc, nSeekCol, nRow, nTab, DIR_LEFT, nExtend /*out*/ )) != ScAutoSumNone )
439 bCol = sal_True;
441 if ( bCol || bRow )
443 if ( bRow )
445 nStartRow = nSeekRow; // nSeekRow might be adjusted via reference
446 if ( eSum == ScAutoSumSum )
447 nEndRow = nStartRow; // only sum sums
448 else
449 nEndRow = nRow - 1; // maybe extend data area at bottom
451 else
453 nStartCol = nSeekCol; // nSeekCol might be adjusted vie reference
454 if ( eSum == ScAutoSumSum )
455 nEndCol = nStartCol; // only sum sums
456 else
457 nEndCol = nCol - 1; // maybe extend data area to the right
459 sal_Bool bContinue = false;
462 if ( eSum == ScAutoSumData )
464 if ( bRow )
466 while ( nStartRow != 0 && lcl_IsAutoSumData( pDoc, nCol,
467 nStartRow-1, nTab, DIR_TOP, nExtend /*out*/ ) == eSum )
468 --nStartRow;
470 else
472 while ( nStartCol != 0 && lcl_IsAutoSumData( pDoc, nStartCol-1,
473 nRow, nTab, DIR_LEFT, nExtend /*out*/ ) == eSum )
474 --nStartCol;
477 rRangeList.Append(
478 ScRange( nStartCol, nStartRow, nTab, nEndCol, nEndRow, nTab ) );
479 if ( eSum == ScAutoSumSum )
481 if ( bRow )
483 nEndRow = static_cast< SCROW >( nExtend );
484 if ( ( bContinue = lcl_FindNextSumEntryInColumn( pDoc, nCol, nEndRow /*inout*/, nTab, nExtend /*out*/, 0 ) ) == true )
486 nStartRow = nEndRow;
489 else
491 nEndCol = static_cast< SCCOL >( nExtend );
492 if ( ( bContinue = lcl_FindNextSumEntryInRow( pDoc, nEndCol /*inout*/, nRow, nTab, nExtend /*out*/, 0 ) ) == true )
494 nStartCol = nEndCol;
498 } while ( bContinue );
499 return sal_True;
501 return false;
504 //----------------------------------------------------------------------------
506 void ScViewFunc::EnterAutoSum(const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr)
508 OUString aFormula = GetAutoSumFormula( rRangeList, bSubTotal, rAddr );
509 EnterBlock( aFormula, NULL );
512 //----------------------------------------------------------------------------
514 bool ScViewFunc::AutoSum( const ScRange& rRange, bool bSubTotal, bool bSetCursor, bool bContinue )
516 ScDocument* pDoc = GetViewData()->GetDocument();
517 const SCTAB nTab = rRange.aStart.Tab();
518 SCCOL nStartCol = rRange.aStart.Col();
519 SCROW nStartRow = rRange.aStart.Row();
520 const SCCOL nEndCol = rRange.aEnd.Col();
521 const SCROW nEndRow = rRange.aEnd.Row();
522 SCCOLROW nExtend = 0; // out parameter for lcl_IsAutoSumData
524 // ignore rows at the top of the given range which don't contain autosum data
525 bool bRowData = false;
526 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
528 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
530 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_TOP, nExtend ) != ScAutoSumNone )
532 bRowData = true;
533 break;
536 if ( bRowData )
538 nStartRow = nRow;
539 break;
542 if ( !bRowData )
544 return false;
547 // ignore columns at the left of the given range which don't contain autosum data
548 bool bColData = false;
549 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
551 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
553 if ( lcl_IsAutoSumData( pDoc, nCol, nRow, nTab, DIR_LEFT, nExtend ) != ScAutoSumNone )
555 bColData = true;
556 break;
559 if ( bColData )
561 nStartCol = nCol;
562 break;
565 if ( !bColData )
567 return false;
570 const bool bEndRowEmpty = pDoc->IsBlockEmpty( nTab, nStartCol, nEndRow, nEndCol, nEndRow );
571 const bool bEndColEmpty = pDoc->IsBlockEmpty( nTab, nEndCol, nStartRow, nEndCol, nEndRow );
572 bool bRow = ( ( nStartRow != nEndRow ) && ( bEndRowEmpty || ( !bEndRowEmpty && !bEndColEmpty ) ) );
573 bool bCol = ( ( nStartCol != nEndCol ) && ( bEndColEmpty || nStartRow == nEndRow ) );
575 // find an empty row for entering the result
576 SCROW nInsRow = nEndRow;
577 if ( bRow && !bEndRowEmpty )
579 if ( nInsRow < MAXROW )
581 ++nInsRow;
582 while ( !pDoc->IsBlockEmpty( nTab, nStartCol, nInsRow, nEndCol, nInsRow ) )
584 if ( nInsRow < MAXROW )
586 ++nInsRow;
588 else
590 bRow = false;
591 break;
595 else
597 bRow = false;
601 // find an empty column for entering the result
602 SCCOL nInsCol = nEndCol;
603 if ( bCol && !bEndColEmpty )
605 if ( nInsCol < MAXCOL )
607 ++nInsCol;
608 while ( !pDoc->IsBlockEmpty( nTab, nInsCol, nStartRow, nInsCol, nEndRow ) )
610 if ( nInsCol < MAXCOL )
612 ++nInsCol;
614 else
616 bCol = false;
617 break;
621 else
623 bCol = false;
627 if ( !bRow && !bCol )
629 return false;
632 SCCOL nMarkEndCol = nEndCol;
633 SCROW nMarkEndRow = nEndRow;
635 if ( bRow )
637 // calculate the row sums for all columns of the given range
639 SCROW nSumEndRow = nEndRow;
641 if ( bEndRowEmpty )
643 // the last row of the given range is empty;
644 // don't take into account for calculating the autosum
645 --nSumEndRow;
647 else
649 // increase mark range
650 ++nMarkEndRow;
653 for ( SCCOL nCol = nStartCol; nCol <= nEndCol; ++nCol )
655 if ( !pDoc->IsBlockEmpty( nTab, nCol, nStartRow, nCol, nSumEndRow ) )
657 ScRangeList aRangeList;
658 const ScRange aRange( nCol, nStartRow, nTab, nCol, nSumEndRow, nTab );
659 if ( lcl_GetAutoSumForColumnRange( pDoc, aRangeList, aRange ) )
661 const OUString aFormula = GetAutoSumFormula(
662 aRangeList, bSubTotal, ScAddress(nCol, nInsRow, nTab));
663 EnterData( nCol, nInsRow, nTab, aFormula );
669 if ( bCol )
671 // calculate the column sums for all rows of the given range
673 SCCOL nSumEndCol = nEndCol;
675 if ( bEndColEmpty )
677 // the last column of the given range is empty;
678 // don't take into account for calculating the autosum
679 --nSumEndCol;
681 else
683 // increase mark range
684 ++nMarkEndCol;
687 for ( SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow )
689 if ( !pDoc->IsBlockEmpty( nTab, nStartCol, nRow, nSumEndCol, nRow ) )
691 ScRangeList aRangeList;
692 const ScRange aRange( nStartCol, nRow, nTab, nSumEndCol, nRow, nTab );
693 if ( lcl_GetAutoSumForRowRange( pDoc, aRangeList, aRange ) )
695 const OUString aFormula = GetAutoSumFormula( aRangeList, bSubTotal, ScAddress(nInsCol, nRow, nTab) );
696 EnterData( nInsCol, nRow, nTab, aFormula );
702 // set new mark range and cursor position
703 const ScRange aMarkRange( nStartCol, nStartRow, nTab, nMarkEndCol, nMarkEndRow, nTab );
704 MarkRange( aMarkRange, false, bContinue );
705 if ( bSetCursor )
707 SetCursor( nMarkEndCol, nMarkEndRow );
710 return true;
713 //----------------------------------------------------------------------------
715 OUString ScViewFunc::GetAutoSumFormula( const ScRangeList& rRangeList, bool bSubTotal, const ScAddress& rAddr )
717 ScViewData* pViewData = GetViewData();
718 ScDocument* pDoc = pViewData->GetDocument();
719 ::boost::scoped_ptr<ScTokenArray> pArray(new ScTokenArray);
721 pArray->AddOpCode(bSubTotal ? ocSubTotal : ocSum);
722 pArray->AddOpCode(ocOpen);
724 if (bSubTotal)
726 pArray->AddDouble(9);
727 pArray->AddOpCode(ocSep);
730 if(!rRangeList.empty())
732 ScRangeList aRangeList = rRangeList;
733 const ScRange* pFirst = aRangeList.front();
734 size_t ListSize = aRangeList.size();
735 for ( size_t i = 0; i < ListSize; ++i )
737 const ScRange* p = aRangeList[i];
738 if (p != pFirst)
739 pArray->AddOpCode(ocSep);
740 ScComplexRefData aRef;
741 aRef.InitRangeRel(*p, rAddr);
742 pArray->AddDoubleReference(aRef);
746 pArray->AddOpCode(ocClose);
748 ScCompiler aComp(pDoc, rAddr, *pArray);
749 aComp.SetGrammar(pDoc->GetGrammar());
750 OUStringBuffer aBuf;
751 aComp.CreateStringFromTokenArray(aBuf);
752 OUString aFormula = aBuf.makeStringAndClear();
753 aBuf.append('=');
754 aBuf.append(aFormula);
755 return aBuf.makeStringAndClear();
758 //----------------------------------------------------------------------------
760 void ScViewFunc::EnterBlock( const OUString& rString, const EditTextObject* pData )
762 // test for multi selection
764 SCCOL nCol = GetViewData()->GetCurX();
765 SCROW nRow = GetViewData()->GetCurY();
766 SCTAB nTab = GetViewData()->GetTabNo();
767 ScMarkData& rMark = GetViewData()->GetMarkData();
768 if ( rMark.IsMultiMarked() )
770 rMark.MarkToSimple();
771 if ( rMark.IsMultiMarked() )
772 { // "Insert into multi selection not possible"
773 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0);
775 // insert into single cell
776 if ( pData )
777 EnterData(nCol, nRow, nTab, *pData);
778 else
779 EnterData( nCol, nRow, nTab, rString );
780 return;
784 ScDocument* pDoc = GetViewData()->GetDocument();
785 OUString aNewStr = rString;
786 if ( pData )
788 const ScPatternAttr* pOldPattern = pDoc->GetPattern( nCol, nRow, nTab );
789 ScTabEditEngine aEngine( *pOldPattern, pDoc->GetEnginePool() );
790 aEngine.SetText(*pData);
792 ScEditAttrTester aTester( &aEngine );
793 if (!aTester.NeedsObject())
795 aNewStr = aEngine.GetText();
796 pData = NULL;
800 // Insert via PasteFromClip
802 WaitObject aWait( GetFrameWin() );
804 ScAddress aPos( nCol, nRow, nTab );
806 ScDocument* pInsDoc = new ScDocument( SCDOCMODE_CLIP );
807 pInsDoc->ResetClip( pDoc, nTab );
809 if (aNewStr[0] == '=') // Formula ?
811 // SetString not possible, because in Clipboard-Documents nothing will be compiled!
812 pInsDoc->SetFormulaCell(aPos, new ScFormulaCell(pDoc, aPos, aNewStr));
814 else if ( pData )
816 // A copy of pData will be stored.
817 pInsDoc->SetEditText(aPos, *pData, pDoc->GetEditPool());
819 else
820 pInsDoc->SetString( nCol, nRow, nTab, aNewStr );
822 pInsDoc->SetClipArea( ScRange(aPos) );
823 // insert Block, with Undo etc.
824 if ( PasteFromClip( IDF_CONTENTS, pInsDoc, PASTE_NOFUNC, false, false,
825 false, INS_NONE, IDF_ATTRIB ) )
827 const SfxUInt32Item* pItem = (SfxUInt32Item*) pInsDoc->GetAttr(
828 nCol, nRow, nTab, ATTR_VALUE_FORMAT );
829 if ( pItem )
830 { // set number format if incompatible
831 // MarkData was already MarkToSimple'ed in PasteFromClip
832 ScRange aRange;
833 rMark.GetMarkArea( aRange );
834 ScPatternAttr* pPattern = new ScPatternAttr( pDoc->GetPool() );
835 pPattern->GetItemSet().Put( *pItem );
836 short nNewType = pDoc->GetFormatTable()->GetType( pItem->GetValue() );
837 pDoc->ApplyPatternIfNumberformatIncompatible( aRange, rMark,
838 *pPattern, nNewType );
839 delete pPattern;
843 delete pInsDoc;
847 //----------------------------------------------------------------------------
848 // manual page break
850 void ScViewFunc::InsertPageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
851 sal_Bool bSetModified )
853 SCTAB nTab = GetViewData()->GetTabNo();
854 ScAddress aCursor;
855 if (pPos)
856 aCursor = *pPos;
857 else
858 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
860 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
861 InsertPageBreak( bColumn, aCursor, bRecord, bSetModified, false );
863 if ( bSuccess && bSetModified )
864 UpdatePageBreakData( true ); // for PageBreak-Mode
868 //----------------------------------------------------------------------------
870 void ScViewFunc::DeletePageBreak( sal_Bool bColumn, sal_Bool bRecord, const ScAddress* pPos,
871 sal_Bool bSetModified )
873 SCTAB nTab = GetViewData()->GetTabNo();
874 ScAddress aCursor;
875 if (pPos)
876 aCursor = *pPos;
877 else
878 aCursor = ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
880 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
881 RemovePageBreak( bColumn, aCursor, bRecord, bSetModified, false );
883 if ( bSuccess && bSetModified )
884 UpdatePageBreakData( true ); // for PageBreak-Mode
887 //----------------------------------------------------------------------------
889 void ScViewFunc::RemoveManualBreaks()
891 ScDocShell* pDocSh = GetViewData()->GetDocShell();
892 ScDocument* pDoc = pDocSh->GetDocument();
893 SCTAB nTab = GetViewData()->GetTabNo();
894 sal_Bool bUndo(pDoc->IsUndoEnabled());
896 if (bUndo)
898 ScDocument* pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
899 pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True );
900 pDoc->CopyToDocument( 0,0,nTab, MAXCOL,MAXROW,nTab, IDF_NONE, false, pUndoDoc );
901 pDocSh->GetUndoManager()->AddUndoAction(
902 new ScUndoRemoveBreaks( pDocSh, nTab, pUndoDoc ) );
905 pDoc->RemoveManualBreaks(nTab);
906 pDoc->UpdatePageBreaks(nTab);
908 UpdatePageBreakData( sal_True );
909 pDocSh->SetDocumentModified();
910 pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, PAINT_GRID );
913 //----------------------------------------------------------------------------
915 void ScViewFunc::SetPrintZoom(sal_uInt16 nScale, sal_uInt16 nPages)
917 ScDocShell* pDocSh = GetViewData()->GetDocShell();
918 SCTAB nTab = GetViewData()->GetTabNo();
919 pDocSh->SetPrintZoom( nTab, nScale, nPages );
922 void ScViewFunc::AdjustPrintZoom()
924 ScRange aRange;
925 if ( GetViewData()->GetSimpleArea( aRange ) != SC_MARK_SIMPLE )
926 GetViewData()->GetMarkData().GetMultiMarkArea( aRange );
927 GetViewData()->GetDocShell()->AdjustPrintZoom( aRange );
930 //----------------------------------------------------------------------------
932 void ScViewFunc::SetPrintRanges( sal_Bool bEntireSheet, const OUString* pPrint,
933 const OUString* pRepCol, const OUString* pRepRow,
934 sal_Bool bAddPrint )
936 // on all selected tables
938 ScDocShell* pDocSh = GetViewData()->GetDocShell();
939 ScDocument* pDoc = pDocSh->GetDocument();
940 ScMarkData& rMark = GetViewData()->GetMarkData();
941 SCTAB nTab;
942 sal_Bool bUndo (pDoc->IsUndoEnabled());
944 ScPrintRangeSaver* pOldRanges = pDoc->CreatePrintRangeSaver();
946 ScAddress::Details aDetails(pDoc->GetAddressConvention(), 0, 0);
948 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
949 for (; itr != itrEnd; ++itr)
951 nTab = *itr;
952 ScRange aRange( 0,0,nTab );
954 // print ranges
956 if( !bAddPrint )
957 pDoc->ClearPrintRanges( nTab );
959 if( bEntireSheet )
961 pDoc->SetPrintEntireSheet( nTab );
963 else if ( pPrint )
965 if ( !pPrint->isEmpty() )
967 const sal_Unicode sep = ScCompiler::GetNativeSymbolChar(ocSep);
968 sal_uInt16 nTCount = comphelper::string::getTokenCount(*pPrint, sep);
969 for (sal_uInt16 i=0; i<nTCount; i++)
971 OUString aToken = pPrint->getToken(i, sep);
972 if ( aRange.ParseAny( aToken, pDoc, aDetails ) & SCA_VALID )
973 pDoc->AddPrintRange( nTab, aRange );
977 else // NULL = use selection (print range is always set), use empty string to delete all ranges
979 if ( GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE )
981 pDoc->AddPrintRange( nTab, aRange );
983 else if ( rMark.IsMultiMarked() )
985 rMark.MarkToMulti();
986 ScRangeListRef pList( new ScRangeList );
987 rMark.FillRangeListWithMarks( pList, false );
988 for (size_t i = 0, n = pList->size(); i < n; ++i)
990 ScRange* pR = (*pList)[i];
991 pDoc->AddPrintRange(nTab, *pR);
996 // repeat columns
998 if ( pRepCol )
1000 if ( pRepCol->isEmpty() )
1001 pDoc->SetRepeatColRange( nTab, NULL );
1002 else
1003 if ( aRange.ParseAny( *pRepCol, pDoc, aDetails ) & SCA_VALID )
1004 pDoc->SetRepeatColRange( nTab, &aRange );
1007 // repeat rows
1009 if ( pRepRow )
1011 if ( pRepRow->isEmpty() )
1012 pDoc->SetRepeatRowRange( nTab, NULL );
1013 else
1014 if ( aRange.ParseAny( *pRepRow, pDoc, aDetails ) & SCA_VALID )
1015 pDoc->SetRepeatRowRange( nTab, &aRange );
1019 // undo (for all tables)
1020 if (bUndo)
1022 SCTAB nCurTab = GetViewData()->GetTabNo();
1023 ScPrintRangeSaver* pNewRanges = pDoc->CreatePrintRangeSaver();
1024 pDocSh->GetUndoManager()->AddUndoAction(
1025 new ScUndoPrintRange( pDocSh, nCurTab, pOldRanges, pNewRanges ) );
1027 else
1028 delete pOldRanges;
1030 // update page breaks
1032 itr = rMark.begin();
1033 for (; itr != itrEnd; ++itr)
1034 ScPrintFunc( pDocSh, pDocSh->GetPrinter(), *itr ).UpdatePages();
1036 SfxBindings& rBindings = GetViewData()->GetBindings();
1037 rBindings.Invalidate( SID_DELETE_PRINTAREA );
1039 pDocSh->SetDocumentModified();
1042 //----------------------------------------------------------------------------
1043 // Merge cells
1045 sal_Bool ScViewFunc::TestMergeCells() // pre-test (for menu)
1047 // simple test: sal_True if there's a selection but no multi selection and not filtered
1049 const ScMarkData& rMark = GetViewData()->GetMarkData();
1050 if ( rMark.IsMarked() || rMark.IsMultiMarked() )
1052 ScRange aDummy;
1053 return GetViewData()->GetSimpleArea( aDummy) == SC_MARK_SIMPLE;
1055 else
1056 return false;
1060 //----------------------------------------------------------------------------
1062 sal_Bool ScViewFunc::MergeCells( sal_Bool bApi, sal_Bool& rDoContents, sal_Bool bRecord, sal_Bool bCenter )
1064 // Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
1065 // so that the Contents-QueryBox won't appear
1066 ScEditableTester aTester( this );
1067 if (!aTester.IsEditable())
1069 ErrorMessage(aTester.GetMessageId());
1070 return false;
1073 ScMarkData& rMark = GetViewData()->GetMarkData();
1074 rMark.MarkToSimple();
1075 if (!rMark.IsMarked())
1077 ErrorMessage(STR_NOMULTISELECT);
1078 return false;
1081 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1082 ScDocument* pDoc = pDocSh->GetDocument();
1084 ScRange aMarkRange;
1085 rMark.GetMarkArea( aMarkRange );
1086 SCCOL nStartCol = aMarkRange.aStart.Col();
1087 SCROW nStartRow = aMarkRange.aStart.Row();
1088 SCTAB nStartTab = aMarkRange.aStart.Tab();
1089 SCCOL nEndCol = aMarkRange.aEnd.Col();
1090 SCROW nEndRow = aMarkRange.aEnd.Row();
1091 SCTAB nEndTab = aMarkRange.aEnd.Tab();
1092 if ( nStartCol == nEndCol && nStartRow == nEndRow )
1094 // nothing to do
1095 return true;
1098 if ( pDoc->HasAttrib( nStartCol, nStartRow, nStartTab, nEndCol, nEndRow, nEndTab,
1099 HASATTR_MERGED | HASATTR_OVERLAPPED ) )
1100 { // "Don't nest merging !"
1101 ErrorMessage(STR_MSSG_MERGECELLS_0);
1102 return false;
1105 // Check for the contents of all selected tables.
1106 bool bAskDialog = false;
1107 ScCellMergeOption aMergeOption(nStartCol, nStartRow, nEndCol, nEndRow, bCenter);
1108 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
1109 for (; itr != itrEnd; ++itr)
1111 SCTAB i = *itr;
1112 aMergeOption.maTabs.insert(i);
1114 if (!pDoc->IsBlockEmpty(i, nStartCol, nStartRow+1, nStartCol, nEndRow) ||
1115 !pDoc->IsBlockEmpty(i, nStartCol+1, nStartRow, nEndCol, nEndRow))
1116 bAskDialog = true;
1119 sal_Bool bOk = true;
1121 if (bAskDialog)
1123 if (!bApi)
1125 MessBox aBox( GetViewData()->GetDialogParent(),
1126 WinBits(WB_YES_NO_CANCEL | WB_DEF_NO),
1127 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ),
1128 ScGlobal::GetRscString( STR_MERGE_NOTEMPTY ) );
1129 sal_uInt16 nRetVal = aBox.Execute();
1131 if ( nRetVal == RET_YES )
1132 rDoContents = sal_True;
1133 else if ( nRetVal == RET_CANCEL )
1134 bOk = false;
1138 if (bOk)
1140 bOk = pDocSh->GetDocFunc().MergeCells( aMergeOption, rDoContents, bRecord, bApi );
1142 if (bOk)
1144 SetCursor( nStartCol, nStartRow );
1145 //DoneBlockMode( sal_False);
1146 Unmark();
1148 pDocSh->UpdateOle(GetViewData());
1149 UpdateInputLine();
1153 return bOk;
1157 //----------------------------------------------------------------------------
1159 sal_Bool ScViewFunc::TestRemoveMerge()
1161 sal_Bool bMerged = false;
1162 ScRange aRange;
1163 if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1165 ScDocument* pDoc = GetViewData()->GetDocument();
1166 if ( pDoc->HasAttrib( aRange, HASATTR_MERGED ) )
1167 bMerged = sal_True;
1169 return bMerged;
1173 //----------------------------------------------------------------------------
1175 static bool lcl_extendMergeRange(ScCellMergeOption& rOption, const ScRange& rRange)
1177 bool bExtended = false;
1178 if (rOption.mnStartCol > rRange.aStart.Col())
1180 rOption.mnStartCol = rRange.aStart.Col();
1181 bExtended = true;
1183 if (rOption.mnStartRow > rRange.aStart.Row())
1185 rOption.mnStartRow = rRange.aStart.Row();
1186 bExtended = true;
1188 if (rOption.mnEndCol < rRange.aEnd.Col())
1190 rOption.mnEndCol = rRange.aEnd.Col();
1191 bExtended = true;
1193 if (rOption.mnEndRow < rRange.aEnd.Row())
1195 rOption.mnEndRow = rRange.aEnd.Row();
1196 bExtended = true;
1198 return bExtended;
1201 sal_Bool ScViewFunc::RemoveMerge( sal_Bool bRecord )
1203 ScRange aRange;
1204 ScEditableTester aTester( this );
1205 if (!aTester.IsEditable())
1207 ErrorMessage(aTester.GetMessageId());
1208 return false;
1210 else if (GetViewData()->GetSimpleArea( aRange ) == SC_MARK_SIMPLE)
1212 ScDocument* pDoc = GetViewData()->GetDocument();
1213 ScRange aExtended( aRange );
1214 pDoc->ExtendMerge( aExtended );
1215 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1216 const ScMarkData& rMark = GetViewData()->GetMarkData();
1217 ScCellMergeOption aOption(aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row());
1218 bool bExtended = false;
1221 bExtended = false;
1222 ScMarkData::const_iterator itr = rMark.begin(), itrEnd = rMark.end();
1223 for (; itr != itrEnd; ++itr)
1225 SCTAB i = *itr;
1226 aOption.maTabs.insert(i);
1227 aExtended.aStart.SetTab(i);
1228 aExtended.aEnd.SetTab(i);
1229 pDoc->ExtendMerge(aExtended);
1230 pDoc->ExtendOverlapped(aExtended);
1232 // Expand the current range to be inclusive of all merged
1233 // areas on all sheets.
1234 bExtended = lcl_extendMergeRange(aOption, aExtended);
1237 while (bExtended);
1239 sal_Bool bOk = pDocSh->GetDocFunc().UnmergeCells(aOption, bRecord );
1240 aExtended = aOption.getFirstSingleRange();
1241 MarkRange( aExtended );
1243 if (bOk)
1244 pDocSh->UpdateOle(GetViewData());
1246 return sal_True; //! bOk ??
1249 //----------------------------------------------------------------------------
1251 void ScViewFunc::FillSimple( FillDir eDir, bool bRecord )
1253 ScRange aRange;
1254 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1256 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1257 const ScMarkData& rMark = GetViewData()->GetMarkData();
1258 bool bSuccess = pDocSh->GetDocFunc().FillSimple( aRange, &rMark, eDir, bRecord, false );
1259 if (bSuccess)
1261 pDocSh->UpdateOle(GetViewData());
1262 UpdateScrollBars();
1265 else
1266 ErrorMessage(STR_NOMULTISELECT);
1269 //----------------------------------------------------------------------------
1271 void ScViewFunc::FillSeries( FillDir eDir, FillCmd eCmd, FillDateCmd eDateCmd,
1272 double fStart, double fStep, double fMax, sal_Bool bRecord )
1274 ScRange aRange;
1275 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1277 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1278 const ScMarkData& rMark = GetViewData()->GetMarkData();
1279 sal_Bool bSuccess = pDocSh->GetDocFunc().
1280 FillSeries( aRange, &rMark, eDir, eCmd, eDateCmd,
1281 fStart, fStep, fMax, bRecord, false );
1282 if (bSuccess)
1284 pDocSh->UpdateOle(GetViewData());
1285 UpdateScrollBars();
1287 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh, aRange);
1290 else
1291 ErrorMessage(STR_NOMULTISELECT);
1294 //----------------------------------------------------------------------------
1296 void ScViewFunc::FillAuto( FillDir eDir, SCCOL nStartCol, SCROW nStartRow,
1297 SCCOL nEndCol, SCROW nEndRow, sal_uLong nCount, sal_Bool bRecord )
1299 SCTAB nTab = GetViewData()->GetTabNo();
1300 ScRange aRange( nStartCol,nStartRow,nTab, nEndCol,nEndRow,nTab );
1301 ScRange aSourceRange( aRange );
1302 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1303 const ScMarkData& rMark = GetViewData()->GetMarkData();
1304 sal_Bool bSuccess = pDocSh->GetDocFunc().
1305 FillAuto( aRange, &rMark, eDir, nCount, bRecord, false );
1306 if (bSuccess)
1308 MarkRange( aRange, false ); // aRange was modified in FillAuto
1309 pDocSh->UpdateOle(GetViewData());
1310 UpdateScrollBars();
1312 if (ScModelObj* pModelObj = HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh))
1314 ScRangeList aChangeRanges;
1315 ScRange aChangeRange( aRange );
1316 switch (eDir)
1318 case FILL_TO_BOTTOM:
1319 aChangeRange.aStart.SetRow( aSourceRange.aEnd.Row() + 1 );
1320 break;
1321 case FILL_TO_TOP:
1322 aChangeRange.aEnd.SetRow( aSourceRange.aStart.Row() - 1 );
1323 break;
1324 case FILL_TO_RIGHT:
1325 aChangeRange.aStart.SetCol( aSourceRange.aEnd.Col() + 1 );
1326 break;
1327 case FILL_TO_LEFT:
1328 aChangeRange.aEnd.SetCol( aSourceRange.aStart.Col() - 1 );
1329 break;
1330 default:
1331 break;
1333 aChangeRanges.Append( aChangeRange );
1334 HelperNotifyChanges::Notify(*pModelObj, aChangeRanges);
1339 //----------------------------------------------------------------------------
1341 void ScViewFunc::FillTab( sal_uInt16 nFlags, sal_uInt16 nFunction, sal_Bool bSkipEmpty, sal_Bool bAsLink )
1343 //! allow source sheet to be protected
1344 ScEditableTester aTester( this );
1345 if (!aTester.IsEditable())
1347 ErrorMessage(aTester.GetMessageId());
1348 return;
1351 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1352 ScDocument* pDoc = pDocSh->GetDocument();
1353 ScMarkData& rMark = GetViewData()->GetMarkData();
1354 SCTAB nTab = GetViewData()->GetTabNo();
1355 sal_Bool bUndo(pDoc->IsUndoEnabled());
1357 ScRange aMarkRange;
1358 rMark.MarkToSimple();
1359 sal_Bool bMulti = rMark.IsMultiMarked();
1360 if (bMulti)
1361 rMark.GetMultiMarkArea( aMarkRange );
1362 else if (rMark.IsMarked())
1363 rMark.GetMarkArea( aMarkRange );
1364 else
1365 aMarkRange = ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab );
1367 ScDocument* pUndoDoc = NULL;
1369 if (bUndo)
1371 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
1372 pUndoDoc->InitUndo( pDoc, nTab, nTab );
1374 ScMarkData::iterator itr = rMark.begin(), itrEnd = rMark.end();
1375 for (; itr != itrEnd; ++itr)
1376 if (*itr != nTab )
1378 SCTAB i = *itr;
1379 pUndoDoc->AddUndoTab( i, i );
1380 aMarkRange.aStart.SetTab( i );
1381 aMarkRange.aEnd.SetTab( i );
1382 pDoc->CopyToDocument( aMarkRange, IDF_ALL, bMulti, pUndoDoc );
1386 if (bMulti)
1387 pDoc->FillTabMarked( nTab, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1388 else
1390 aMarkRange.aStart.SetTab( nTab );
1391 aMarkRange.aEnd.SetTab( nTab );
1392 pDoc->FillTab( aMarkRange, rMark, nFlags, nFunction, bSkipEmpty, bAsLink );
1395 if (bUndo)
1396 { //! for ChangeTrack not until the end
1397 pDocSh->GetUndoManager()->AddUndoAction(
1398 new ScUndoFillTable( pDocSh, rMark,
1399 aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nTab,
1400 aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab,
1401 pUndoDoc, bMulti, nTab, nFlags, nFunction, bSkipEmpty, bAsLink ) );
1404 pDocSh->PostPaintGridAll();
1405 pDocSh->PostDataChanged();
1408 //----------------------------------------------------------------------------
1410 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1412 Extends a current selection down to the last non-empty cell of an adjacent
1413 column when the lower-right corner of the selection is double-clicked. It
1414 uses a left-adjoining non-empty column as a guide if such is available,
1415 otherwise a right-adjoining non-empty column is used.
1417 @author Kohei Yoshida (kohei@openoffice.org)
1419 @return No return value
1421 @see #i12313#
1423 void ScViewFunc::FillCrossDblClick()
1425 ScRange aRange;
1426 GetViewData()->GetSimpleArea( aRange );
1427 aRange.Justify();
1429 SCTAB nTab = GetViewData()->GetCurPos().Tab();
1430 SCCOL nStartX = aRange.aStart.Col();
1431 SCROW nStartY = aRange.aStart.Row();
1432 SCCOL nEndX = aRange.aEnd.Col();
1433 SCROW nEndY = aRange.aEnd.Row();
1435 ScDocument* pDoc = GetViewData()->GetDocument();
1437 // Make sure the selection is not empty
1438 if ( pDoc->IsBlockEmpty( nTab, nStartX, nStartY, nEndX, nEndY ) )
1439 return;
1441 if ( nEndY < MAXROW )
1443 if ( nStartX > 0 )
1445 SCCOL nMovX = nStartX - 1;
1446 SCROW nMovY = nStartY;
1448 if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1449 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1451 pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
1453 if ( nMovY > nEndY )
1455 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1456 nMovY - nEndY );
1457 return;
1462 if ( nEndX < MAXCOL )
1464 SCCOL nMovX = nEndX + 1;
1465 SCROW nMovY = nStartY;
1467 if ( pDoc->HasData( nMovX, nStartY, nTab ) &&
1468 pDoc->HasData( nMovX, nStartY + 1, nTab ) )
1470 pDoc->FindAreaPos( nMovX, nMovY, nTab, SC_MOVE_DOWN );
1472 if ( nMovY > nEndY )
1474 FillAuto( FILL_TO_BOTTOM, nStartX, nStartY, nEndX, nEndY,
1475 nMovY - nEndY );
1476 return;
1483 //----------------------------------------------------------------------------
1485 void ScViewFunc::TransliterateText( sal_Int32 nType )
1487 ScMarkData aFuncMark = GetViewData()->GetMarkData();
1488 if ( !aFuncMark.IsMarked() && !aFuncMark.IsMultiMarked() )
1490 // no selection -> use cursor position
1492 ScAddress aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
1493 aFuncMark.SetMarkArea( ScRange( aCursor ) );
1496 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1497 TransliterateText( aFuncMark, nType, sal_True, false );
1498 if (bSuccess)
1500 GetViewData()->GetViewShell()->UpdateInputHandler();
1504 //----------------------------------------------------------------------------
1505 // AutoFormat
1507 ScAutoFormatData* ScViewFunc::CreateAutoFormatData()
1509 ScAutoFormatData* pData = NULL;
1510 SCCOL nStartCol;
1511 SCROW nStartRow;
1512 SCTAB nStartTab;
1513 SCCOL nEndCol;
1514 SCROW nEndRow;
1515 SCTAB nEndTab;
1516 if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE)
1518 if ( nEndCol-nStartCol >= 3 && nEndRow-nStartRow >= 3 )
1520 ScDocument* pDoc = GetViewData()->GetDocument();
1521 pData = new ScAutoFormatData;
1522 pDoc->GetAutoFormatData( nStartTab, nStartCol,nStartRow,nEndCol,nEndRow, *pData );
1525 return pData;
1529 //----------------------------------------------------------------------------
1531 void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo, sal_Bool bRecord )
1533 ScRange aRange;
1534 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1536 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1537 ScMarkData& rMark = GetViewData()->GetMarkData();
1539 sal_Bool bSuccess = pDocSh->GetDocFunc().AutoFormat( aRange, &rMark, nFormatNo, bRecord, false );
1540 if (bSuccess)
1541 pDocSh->UpdateOle(GetViewData());
1543 else
1544 ErrorMessage(STR_NOMULTISELECT);
1548 //----------------------------------------------------------------------------
1549 // Suchen & Ersetzen
1551 void ScViewFunc::SearchAndReplace( const SvxSearchItem* pSearchItem,
1552 sal_Bool bAddUndo, sal_Bool bIsApi )
1554 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1555 ScDocument* pDoc = pDocSh->GetDocument();
1556 ScMarkData& rMark = GetViewData()->GetMarkData();
1557 if (bAddUndo && !pDoc->IsUndoEnabled())
1558 bAddUndo = false;
1560 SCCOL nCol, nOldCol;
1561 SCROW nRow, nOldRow;
1562 SCTAB nTab, nOldTab;
1563 nCol = nOldCol = GetViewData()->GetCurX();
1564 nRow = nOldRow = GetViewData()->GetCurY();
1565 nTab = nOldTab = GetViewData()->GetTabNo();
1567 sal_uInt16 nCommand = pSearchItem->GetCommand();
1568 bool bAllTables = pSearchItem->IsAllTables();
1569 std::set<SCTAB> aOldSelectedTables;
1570 SCTAB nLastTab = pDoc->GetTableCount() - 1;
1571 SCTAB nStartTab, nEndTab;
1572 if ( bAllTables )
1574 nStartTab = 0;
1575 nEndTab = nLastTab;
1576 std::set<SCTAB> aTmp(rMark.begin(), rMark.end());
1577 aOldSelectedTables.swap(aTmp);
1579 else
1580 { //! at least one is always selected
1581 nStartTab = rMark.GetFirstSelected();
1582 nEndTab = rMark.GetLastSelected();
1585 if ( nCommand == SVX_SEARCHCMD_FIND
1586 || nCommand == SVX_SEARCHCMD_FIND_ALL)
1587 bAddUndo = false;
1589 //! account for bAttrib during Undo !!!
1591 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1592 std::auto_ptr<ScDocument> pUndoDoc;
1593 std::auto_ptr<ScMarkData> pUndoMark;
1594 SAL_WNODEPRECATED_DECLARATIONS_POP
1595 OUString aUndoStr;
1596 if (bAddUndo)
1598 pUndoMark.reset(new ScMarkData(rMark)); // Mark is being modified
1599 if ( nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1601 pUndoDoc.reset(new ScDocument(SCDOCMODE_UNDO));
1602 pUndoDoc->InitUndo( pDoc, nStartTab, nEndTab );
1606 if ( bAllTables )
1607 { //! select all, after pUndoMark has been created
1608 for ( SCTAB j = nStartTab; j <= nEndTab; j++ )
1610 rMark.SelectTable( j, true );
1614 DoneBlockMode(true); // don't delete mark
1615 InitOwnBlockMode();
1617 // If search starts at the beginning don't ask again whether it shall start at the beginning
1618 bool bFirst = true;
1619 if ( nCol == 0 && nRow == 0 && nTab == nStartTab && !pSearchItem->GetBackward() )
1620 bFirst = false;
1622 bool bFound = false;
1623 while (true)
1625 GetFrameWin()->EnterWait();
1626 ScRangeList aMatchedRanges;
1627 if (pDoc->SearchAndReplace(*pSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, pUndoDoc.get()))
1629 bFound = true;
1630 bFirst = true;
1631 if (bAddUndo)
1633 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1634 new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark,
1635 nCol, nRow, nTab,
1636 aUndoStr, pUndoDoc.release(), pSearchItem ) );
1639 if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
1641 static SearchResults *aSearchResults = new SearchResults(pDoc);
1642 aSearchResults->Show(aMatchedRanges);
1644 rMark.ResetMark();
1645 for (size_t i = 0, n = aMatchedRanges.size(); i < n; ++i)
1647 const ScRange& r = *aMatchedRanges[i];
1648 if (r.aStart.Tab() == nTab)
1649 rMark.SetMultiMarkArea(r);
1653 break; // break 'while (TRUE)'
1655 else if ( bFirst && (nCommand == SVX_SEARCHCMD_FIND ||
1656 nCommand == SVX_SEARCHCMD_REPLACE) )
1658 bFirst = false;
1659 sal_uInt16 nRetVal;
1660 GetFrameWin()->LeaveWait();
1661 if ( bIsApi )
1662 nRetVal = RET_NO;
1663 else
1665 // search dialog as parent (if available)
1666 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1667 sal_uInt16 nStrId;
1668 if ( pSearchItem->GetBackward() )
1670 if ( nStartTab == nEndTab )
1671 nStrId = STR_MSSG_SEARCHANDREPLACE_1;
1672 else
1673 nStrId = STR_MSSG_SEARCHANDREPLACE_4;
1675 else
1677 if ( nStartTab == nEndTab )
1678 nStrId = STR_MSSG_SEARCHANDREPLACE_2;
1679 else
1680 nStrId = STR_MSSG_SEARCHANDREPLACE_5;
1682 MessBox aBox( pParent, WinBits(WB_YES_NO | WB_DEF_YES),
1683 ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_3 ),
1684 ScGlobal::GetRscString( nStrId ) );
1685 nRetVal = aBox.Execute();
1688 if ( nRetVal == RET_YES )
1690 ScDocument::GetSearchAndReplaceStart( *pSearchItem, nCol, nRow );
1691 if (pSearchItem->GetBackward())
1692 nTab = nEndTab;
1693 else
1694 nTab = nStartTab;
1696 else
1698 break; // break 'while (TRUE)'
1701 else // nothing found
1703 if ( nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1705 pDocSh->PostPaintGridAll(); // Mark
1708 GetFrameWin()->LeaveWait();
1709 if (!bIsApi)
1711 // search dialog as parent if available
1712 Window* pParent = GetParentOrChild(SID_SEARCH_DLG);
1713 // "nothing found"
1714 InfoBox aBox( pParent, ScGlobal::GetRscString( STR_MSSG_SEARCHANDREPLACE_0 ) );
1715 aBox.Execute();
1718 break; // break 'while (TRUE)'
1720 } // of while true
1722 if (!aOldSelectedTables.empty())
1724 // restore originally selected table
1725 for (SCTAB i = 0; i <= nEndTab; ++i)
1726 rMark.SelectTable(i, false);
1728 std::set<SCTAB>::const_iterator itr = aOldSelectedTables.begin(), itrEnd = aOldSelectedTables.end();
1729 for (; itr != itrEnd; ++itr)
1730 rMark.SelectTable(*itr, true);
1732 if ( bFound )
1733 { // if a table is selected as a "match" it remains selected.
1734 rMark.SelectTable( nTab, true );
1735 // It's a swap if only one table was selected before
1736 //! otherwise now one table more might be selected
1737 if ( aOldSelectedTables.size() == 1 && nTab != nOldTab )
1738 rMark.SelectTable( nOldTab, false );
1742 MarkDataChanged();
1744 if ( bFound )
1746 if ( nTab != GetViewData()->GetTabNo() )
1747 SetTabNo( nTab );
1749 // if nothing is marked, DoneBlockMode, then marking can start
1750 // directly from this place via Shift-Cursor
1751 if (!rMark.IsMarked() && !rMark.IsMultiMarked())
1752 DoneBlockMode(true);
1754 AlignToCursor( nCol, nRow, SC_FOLLOW_JUMP );
1755 SetCursor( nCol, nRow, true );
1757 if ( nCommand == SVX_SEARCHCMD_REPLACE
1758 || nCommand == SVX_SEARCHCMD_REPLACE_ALL )
1760 if ( nCommand == SVX_SEARCHCMD_REPLACE )
1762 pDocSh->PostPaint( nCol,nRow,nTab, nCol,nRow,nTab, PAINT_GRID );
1764 // jump to next cell if we replaced everything in the cell
1765 // where the cursor was positioned (but avoid switching tabs)
1766 if ( nCol == nOldCol && nRow == nOldRow && nTab == nOldTab )
1768 SvxSearchItem aSearchItem = ScGlobal::GetSearchItem();
1769 aSearchItem.SetCommand(SVX_SEARCHCMD_FIND);
1770 aSearchItem.SetWhich(SID_SEARCH_ITEM);
1772 ScRangeList aMatchedRanges;
1773 ScTable::UpdateSearchItemAddressForReplace( aSearchItem, nCol, nRow );
1774 if ( pDoc->SearchAndReplace( aSearchItem, nCol, nRow, nTab, rMark, aMatchedRanges, aUndoStr, NULL ) &&
1775 ( nTab == nOldTab ) &&
1776 ( nCol != nOldCol || nRow != nOldRow ) )
1778 SetCursor( nCol, nRow, true );
1782 else
1783 pDocSh->PostPaintGridAll();
1784 pDocSh->SetDocumentModified();
1786 else if ( nCommand == SVX_SEARCHCMD_FIND_ALL )
1787 pDocSh->PostPaintGridAll(); // mark
1788 GetFrameWin()->LeaveWait();
1793 //----------------------------------------------------------------------------
1794 // Zielwertsuche
1796 void ScViewFunc::Solve( const ScSolveParam& rParam )
1798 ScDocument* pDoc = GetViewData()->GetDocument();
1800 SCCOL nDestCol = rParam.aRefVariableCell.Col();
1801 SCROW nDestRow = rParam.aRefVariableCell.Row();
1802 SCTAB nDestTab = rParam.aRefVariableCell.Tab();
1804 ScEditableTester aTester( pDoc, nDestTab, nDestCol,nDestRow, nDestCol,nDestRow );
1805 if (!aTester.IsEditable())
1807 ErrorMessage(aTester.GetMessageId());
1808 return;
1811 if ( pDoc )
1813 OUString aTargetValStr;
1814 if ( rParam.pStrTargetVal != NULL )
1815 aTargetValStr = *(rParam.pStrTargetVal);
1817 OUString aMsgStr;
1818 OUString aResStr;
1819 double nSolveResult;
1821 GetFrameWin()->EnterWait();
1823 sal_Bool bExact =
1824 pDoc->Solver(
1825 rParam.aRefFormulaCell.Col(),
1826 rParam.aRefFormulaCell.Row(),
1827 rParam.aRefFormulaCell.Tab(),
1828 nDestCol, nDestRow, nDestTab,
1829 aTargetValStr,
1830 nSolveResult );
1832 GetFrameWin()->LeaveWait();
1834 SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1835 sal_uLong nFormat = 0;
1836 const ScPatternAttr* pPattern = pDoc->GetPattern( nDestCol, nDestRow, nDestTab );
1837 if ( pPattern )
1838 nFormat = pPattern->GetNumberFormat( pFormatter );
1839 Color* p;
1840 pFormatter->GetOutputString( nSolveResult, nFormat, aResStr, &p );
1842 if ( bExact )
1844 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_0 );
1845 aMsgStr += aResStr;
1846 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_1 );
1848 else
1850 aMsgStr = ScGlobal::GetRscString( STR_MSSG_SOLVE_2 );
1851 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_3 );
1852 aMsgStr += aResStr ;
1853 aMsgStr += ScGlobal::GetRscString( STR_MSSG_SOLVE_4 );
1856 MessBox aBox( GetViewData()->GetDialogParent(),
1857 WinBits(WB_YES_NO | WB_DEF_NO),
1858 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), aMsgStr );
1859 sal_uInt16 nRetVal = aBox.Execute();
1861 if ( RET_YES == nRetVal )
1862 EnterValue( nDestCol, nDestRow, nDestTab, nSolveResult );
1864 GetViewData()->GetViewShell()->UpdateInputHandler( sal_True );
1869 //----------------------------------------------------------------------------
1870 // multi operation
1872 void ScViewFunc::TabOp( const ScTabOpParam& rParam, sal_Bool bRecord )
1874 ScRange aRange;
1875 if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE)
1877 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1878 ScMarkData& rMark = GetViewData()->GetMarkData();
1879 pDocSh->GetDocFunc().TabOp( aRange, &rMark, rParam, bRecord, false );
1881 else
1882 ErrorMessage(STR_NOMULTISELECT);
1886 //----------------------------------------------------------------------------
1888 void ScViewFunc::MakeScenario( const OUString& rName, const OUString& rComment,
1889 const Color& rColor, sal_uInt16 nFlags )
1891 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1892 ScMarkData& rMark = GetViewData()->GetMarkData();
1893 SCTAB nTab = GetViewData()->GetTabNo();
1895 SCTAB nNewTab = pDocSh->MakeScenario( nTab, rName, rComment, rColor, nFlags, rMark );
1896 if (nFlags & SC_SCENARIO_COPYALL)
1897 SetTabNo( nNewTab, true ); // SC_SCENARIO_COPYALL -> visible
1898 else
1900 SfxBindings& rBindings = GetViewData()->GetBindings();
1901 rBindings.Invalidate( SID_STATUS_DOCPOS ); // Statusbar
1902 rBindings.Invalidate( SID_TABLES_COUNT );
1903 rBindings.Invalidate( SID_SELECT_SCENARIO );
1904 rBindings.Invalidate( FID_TABLE_SHOW );
1909 //----------------------------------------------------------------------------
1911 void ScViewFunc::ExtendScenario()
1913 ScEditableTester aTester( this );
1914 if (!aTester.IsEditable())
1916 ErrorMessage(aTester.GetMessageId());
1917 return;
1920 // Undo: apply attributes
1922 ScDocument* pDoc = GetViewData()->GetDocument();
1923 ScPatternAttr aPattern( pDoc->GetPool() );
1924 aPattern.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO ) );
1925 aPattern.GetItemSet().Put( ScProtectionAttr( sal_True ) );
1926 ApplySelectionPattern(aPattern);
1930 //----------------------------------------------------------------------------
1932 void ScViewFunc::UseScenario( const OUString& rName )
1934 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1935 SCTAB nTab = GetViewData()->GetTabNo();
1937 DoneBlockMode();
1938 InitOwnBlockMode();
1939 pDocSh->UseScenario( nTab, rName );
1943 //----------------------------------------------------------------------------
1944 // Insert table
1946 sal_Bool ScViewFunc::InsertTable( const OUString& rName, SCTAB nTab, sal_Bool bRecord )
1948 // Order Tabl/Name is inverted for DocFunc
1949 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
1950 InsertTable( nTab, rName, bRecord, false );
1951 if (bSuccess)
1952 SetTabNo( nTab, sal_True );
1954 return bSuccess;
1957 //----------------------------------------------------------------------------
1958 // Insert tables
1960 sal_Bool ScViewFunc::InsertTables(std::vector<OUString>& aNames, SCTAB nTab,
1961 SCTAB nCount, sal_Bool bRecord )
1963 ScDocShell* pDocSh = GetViewData()->GetDocShell();
1964 ScDocument* pDoc = pDocSh->GetDocument();
1965 if (bRecord && !pDoc->IsUndoEnabled())
1966 bRecord = false;
1968 WaitObject aWait( GetFrameWin() );
1970 if (bRecord)
1972 pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
1975 bool bFlag=false;
1977 if(aNames.empty())
1979 pDoc->CreateValidTabNames(aNames, nCount);
1981 if (pDoc->InsertTabs(nTab, aNames, false))
1983 pDocSh->Broadcast( ScTablesHint( SC_TABS_INSERTED, nTab, nCount ) );
1984 bFlag = true;
1987 if (bFlag)
1989 if (bRecord)
1990 pDocSh->GetUndoManager()->AddUndoAction(
1991 new ScUndoInsertTables( pDocSh, nTab, aNames));
1993 // Update views
1995 SetTabNo( nTab, true );
1996 pDocSh->PostPaintExtras();
1997 pDocSh->SetDocumentModified();
1998 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
1999 return true;
2001 else
2003 return false;
2008 //----------------------------------------------------------------------------
2010 sal_Bool ScViewFunc::AppendTable( const OUString& rName, sal_Bool bRecord )
2012 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2013 ScDocument* pDoc = pDocSh->GetDocument();
2014 if (bRecord && !pDoc->IsUndoEnabled())
2015 bRecord = false;
2017 WaitObject aWait( GetFrameWin() );
2019 if (bRecord)
2020 pDoc->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2022 if (pDoc->InsertTab( SC_TAB_APPEND, rName ))
2024 SCTAB nTab = pDoc->GetTableCount()-1;
2025 if (bRecord)
2026 pDocSh->GetUndoManager()->AddUndoAction(
2027 new ScUndoInsertTab( pDocSh, nTab, sal_True, rName));
2028 GetViewData()->InsertTab( nTab );
2029 SetTabNo( nTab, sal_True );
2030 pDocSh->PostPaintExtras();
2031 pDocSh->SetDocumentModified();
2032 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2033 return sal_True;
2035 else
2037 return false;
2042 //----------------------------------------------------------------------------
2044 sal_Bool ScViewFunc::DeleteTable( SCTAB nTab, sal_Bool bRecord )
2046 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2047 ScDocument* pDoc = pDocSh->GetDocument();
2049 sal_Bool bSuccess = pDocSh->GetDocFunc().DeleteTable( nTab, bRecord, false );
2050 if (bSuccess)
2052 SCTAB nNewTab = nTab;
2053 if ( nNewTab >= pDoc->GetTableCount() )
2054 --nNewTab;
2055 SetTabNo( nNewTab, sal_True );
2057 return bSuccess;
2060 //only use this method for undo for now, all sheets must be connected
2061 //this method doesn't support undo for now, merge it when it with the other method later
2062 bool ScViewFunc::DeleteTables( const SCTAB nTab, SCTAB nSheets )
2064 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2065 ScDocument* pDoc = pDocSh->GetDocument();
2066 bool bVbaEnabled = pDoc->IsInVBAMode();
2067 SCTAB nNewTab = nTab;
2068 WaitObject aWait( GetFrameWin() );
2070 while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2071 --nNewTab;
2073 if (pDoc->DeleteTabs(nTab, nSheets))
2075 if( bVbaEnabled )
2077 for (SCTAB aTab = 0; aTab < nSheets; ++aTab)
2079 OUString sCodeName;
2080 bool bHasCodeName = pDoc->GetCodeName( nTab + aTab, sCodeName );
2081 if ( bHasCodeName )
2082 VBA_DeleteModule( *pDocSh, sCodeName );
2086 pDocSh->Broadcast( ScTablesHint( SC_TABS_DELETED, nTab, nSheets ) );
2087 if ( nNewTab >= pDoc->GetTableCount() )
2088 nNewTab = pDoc->GetTableCount() - 1;
2089 SetTabNo( nNewTab, sal_True );
2091 pDocSh->PostPaintExtras();
2092 pDocSh->SetDocumentModified();
2094 SfxApplication* pSfxApp = SFX_APP(); // Navigator
2095 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2096 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2097 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2098 return true;
2100 return false;
2103 sal_Bool ScViewFunc::DeleteTables(const vector<SCTAB> &TheTabs, sal_Bool bRecord )
2105 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2106 ScDocument* pDoc = pDocSh->GetDocument();
2107 sal_Bool bVbaEnabled = pDoc->IsInVBAMode();
2108 SCTAB nNewTab = TheTabs.front();
2109 WaitObject aWait( GetFrameWin() );
2110 if (bRecord && !pDoc->IsUndoEnabled())
2111 bRecord = false;
2112 if ( bVbaEnabled )
2113 bRecord = false;
2115 while ( nNewTab > 0 && !pDoc->IsVisible( nNewTab ) )
2116 --nNewTab;
2118 sal_Bool bWasLinked = false;
2119 ScDocument* pUndoDoc = NULL;
2120 ScRefUndoData* pUndoData = NULL;
2121 if (bRecord)
2123 pUndoDoc = new ScDocument( SCDOCMODE_UNDO );
2124 SCTAB nCount = pDoc->GetTableCount();
2126 OUString aOldName;
2127 for(unsigned int i=0; i<TheTabs.size(); ++i)
2129 SCTAB nTab = TheTabs[i];
2130 if (i==0)
2131 pUndoDoc->InitUndo( pDoc, nTab,nTab, true,true ); // incl. column/fow flags
2132 else
2133 pUndoDoc->AddUndoTab( nTab,nTab, true,true ); // incl. column/fow flags
2135 pDoc->CopyToDocument(0,0,nTab, MAXCOL,MAXROW,nTab, IDF_ALL,false, pUndoDoc );
2136 pDoc->GetName( nTab, aOldName );
2137 pUndoDoc->RenameTab( nTab, aOldName, false );
2138 if (pDoc->IsLinked(nTab))
2140 bWasLinked = sal_True;
2141 pUndoDoc->SetLink( nTab, pDoc->GetLinkMode(nTab), pDoc->GetLinkDoc(nTab),
2142 pDoc->GetLinkFlt(nTab), pDoc->GetLinkOpt(nTab),
2143 pDoc->GetLinkTab(nTab),
2144 pDoc->GetLinkRefreshDelay(nTab) );
2146 if ( pDoc->IsScenario(nTab) )
2148 pUndoDoc->SetScenario( nTab, sal_True );
2149 OUString aComment;
2150 Color aColor;
2151 sal_uInt16 nScenFlags;
2152 pDoc->GetScenarioData( nTab, aComment, aColor, nScenFlags );
2153 pUndoDoc->SetScenarioData( nTab, aComment, aColor, nScenFlags );
2154 sal_Bool bActive = pDoc->IsActiveScenario( nTab );
2155 pUndoDoc->SetActiveScenario( nTab, bActive );
2157 pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) );
2158 pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) );
2159 pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) );
2160 pUndoDoc->SetLayoutRTL( nTab, pDoc->IsLayoutRTL( nTab ) );
2162 if ( pDoc->IsTabProtected( nTab ) )
2163 pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab));
2165 // Drawing-Layer is responsible for its Undo !!!
2166 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2169 pUndoDoc->AddUndoTab( 0, nCount-1 ); // all Tabs for references
2171 pDoc->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2173 pUndoData = new ScRefUndoData( pDoc );
2176 sal_Bool bDelDone = false;
2178 for(int i=TheTabs.size()-1; i>=0; --i)
2180 OUString sCodeName;
2181 sal_Bool bHasCodeName = pDoc->GetCodeName( TheTabs[i], sCodeName );
2182 if (pDoc->DeleteTab(TheTabs[i]))
2184 bDelDone = sal_True;
2185 if( bVbaEnabled )
2187 if( bHasCodeName )
2189 VBA_DeleteModule( *pDocSh, sCodeName );
2192 pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[i] ) );
2195 if (bRecord)
2197 pDocSh->GetUndoManager()->AddUndoAction(
2198 new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs,
2199 pUndoDoc, pUndoData ));
2203 if (bDelDone)
2205 if ( nNewTab >= pDoc->GetTableCount() )
2206 nNewTab = pDoc->GetTableCount() - 1;
2208 SetTabNo( nNewTab, sal_True );
2210 if (bWasLinked)
2212 pDocSh->UpdateLinks(); // update Link-Manager
2213 GetViewData()->GetBindings().Invalidate(SID_LINKS);
2216 pDocSh->PostPaintExtras();
2217 pDocSh->SetDocumentModified();
2220 SfxApplication* pSfxApp = SFX_APP(); // Navigator
2221 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2222 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED ) );
2223 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED ) );
2225 else
2227 delete pUndoDoc;
2228 delete pUndoData;
2230 return bDelDone;
2234 //----------------------------------------------------------------------------
2236 sal_Bool ScViewFunc::RenameTable( const OUString& rName, SCTAB nTab )
2238 // order Table/Name is inverted for DocFunc
2239 sal_Bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().
2240 RenameTable( nTab, rName, true, false );
2241 if (bSuccess)
2243 // the table name might be part of a formula
2244 GetViewData()->GetViewShell()->UpdateInputHandler();
2246 return bSuccess;
2250 //----------------------------------------------------------------------------
2252 bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab )
2254 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, sal_True, false );
2255 if (bSuccess)
2257 GetViewData()->GetViewShell()->UpdateInputHandler();
2259 return bSuccess;
2262 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList )
2264 bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, sal_True, false );
2265 if (bSuccess)
2267 GetViewData()->GetViewShell()->UpdateInputHandler();
2269 return bSuccess;
2272 //----------------------------------------------------------------------------
2274 void ScViewFunc::InsertAreaLink( const OUString& rFile,
2275 const OUString& rFilter, const OUString& rOptions,
2276 const OUString& rSource, sal_uLong nRefresh )
2278 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2279 SCCOL nPosX = GetViewData()->GetCurX();
2280 SCROW nPosY = GetViewData()->GetCurY();
2281 SCTAB nTab = GetViewData()->GetTabNo();
2282 ScAddress aPos( nPosX, nPosY, nTab );
2284 pDocSh->GetDocFunc().InsertAreaLink( rFile, rFilter, rOptions, rSource, aPos, nRefresh, false, false );
2288 //----------------------------------------------------------------------------
2290 void ScViewFunc::InsertTableLink( const OUString& rFile,
2291 const OUString& rFilter, const OUString& rOptions,
2292 const OUString& rTabName )
2294 OUString aFilterName = rFilter;
2295 OUString aOpt = rOptions;
2296 OUString aURL = rFile;
2297 ScDocumentLoader aLoader( aURL, aFilterName, aOpt );
2298 if (!aLoader.IsError())
2300 ScDocShell* pSrcSh = aLoader.GetDocShell();
2301 ScDocument* pSrcDoc = pSrcSh->GetDocument();
2302 SCTAB nTab = MAXTAB+1;
2303 if (rTabName.isEmpty()) // no name given -> first table
2304 nTab = 0;
2305 else
2307 OUString aTemp;
2308 SCTAB nCount = pSrcDoc->GetTableCount();
2309 for (SCTAB i=0; i<nCount; i++)
2311 pSrcDoc->GetName( i, aTemp );
2312 if ( aTemp.equals(rTabName) )
2313 nTab = i;
2317 if ( nTab <= MAXTAB )
2318 ImportTables( pSrcSh, 1, &nTab, sal_True,
2319 GetViewData()->GetTabNo() );
2324 //----------------------------------------------------------------------------
2325 // Copy/link tables from another document
2327 void ScViewFunc::ImportTables( ScDocShell* pSrcShell,
2328 SCTAB nCount, const SCTAB* pSrcTabs, sal_Bool bLink,SCTAB nTab )
2330 ScDocument* pSrcDoc = pSrcShell->GetDocument();
2332 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2333 ScDocument* pDoc = pDocSh->GetDocument();
2334 sal_Bool bUndo(pDoc->IsUndoEnabled());
2336 sal_Bool bError = false;
2337 sal_Bool bRefs = false;
2338 sal_Bool bName = false;
2340 if (pSrcDoc->GetDrawLayer())
2341 pDocSh->MakeDrawLayer();
2343 if (bUndo)
2344 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2346 SCTAB nInsCount = 0;
2347 SCTAB i;
2348 for( i=0; i<nCount; i++ )
2349 { // insert sheets first and update all references
2350 OUString aName;
2351 pSrcDoc->GetName( pSrcTabs[i], aName );
2352 pDoc->CreateValidTabName( aName );
2353 if ( !pDoc->InsertTab( nTab+i, aName ) )
2355 bError = sal_True; // total error
2356 break; // for
2358 ++nInsCount;
2360 for (i=0; i<nCount && !bError; i++)
2362 SCTAB nSrcTab = pSrcTabs[i];
2363 SCTAB nDestTab1=nTab+i;
2364 sal_uLong nErrVal = pDocSh->TransferTab( *pSrcShell, nSrcTab, nDestTab1,
2365 false, false ); // no insert
2367 switch (nErrVal)
2369 case 0: // internal error or full of errors
2370 bError = true;
2371 break;
2372 case 2:
2373 bRefs = sal_True;
2374 break;
2375 case 3:
2376 bName = sal_True;
2377 break;
2378 case 4:
2379 bRefs = bName = sal_True;
2380 break;
2385 if (bLink)
2387 sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
2389 SfxMedium* pMed = pSrcShell->GetMedium();
2390 OUString aFileName = pMed->GetName();
2391 OUString aFilterName;
2392 if (pMed->GetFilter())
2393 aFilterName = pMed->GetFilter()->GetFilterName();
2394 OUString aOptions = ScDocumentLoader::GetOptions(*pMed);
2396 sal_Bool bWasThere = pDoc->HasLink( aFileName, aFilterName, aOptions );
2398 sal_uLong nRefresh = 0;
2399 OUString aTabStr;
2400 for (i=0; i<nInsCount; i++)
2402 pSrcDoc->GetName( pSrcTabs[i], aTabStr );
2403 pDoc->SetLink( nTab+i, SC_LINK_NORMAL,
2404 aFileName, aFilterName, aOptions, aTabStr, nRefresh );
2407 if (!bWasThere) // Insert link only once per source document
2409 ScTableLink* pLink = new ScTableLink( pDocSh, aFileName, aFilterName, aOptions, nRefresh );
2410 pLink->SetInCreate( sal_True );
2411 pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, aFileName, &aFilterName );
2412 pLink->Update();
2413 pLink->SetInCreate( false );
2415 SfxBindings& rBindings = GetViewData()->GetBindings();
2416 rBindings.Invalidate( SID_LINKS );
2421 if (bUndo)
2423 pDocSh->GetUndoManager()->AddUndoAction(
2424 new ScUndoImportTab( pDocSh, nTab, nCount ) );
2427 for (i=0; i<nInsCount; i++)
2428 GetViewData()->InsertTab(nTab);
2429 SetTabNo(nTab,sal_True);
2430 pDocSh->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2431 PAINT_GRID | PAINT_TOP | PAINT_LEFT | PAINT_EXTRAS );
2433 SfxApplication* pSfxApp = SFX_APP();
2434 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2435 pSfxApp->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED ) );
2437 pDocSh->PostPaintExtras();
2438 pDocSh->PostPaintGridAll();
2439 pDocSh->SetDocumentModified();
2441 if (bRefs)
2442 ErrorMessage(STR_ABSREFLOST);
2443 if (bName)
2444 ErrorMessage(STR_NAMECONFLICT);
2448 //----------------------------------------------------------------------------
2449 // Move/Copy table to another document
2451 void ScViewFunc::MoveTable(
2452 sal_uInt16 nDestDocNo, SCTAB nDestTab, bool bCopy, const OUString* pNewTabName )
2454 ScDocument* pDoc = GetViewData()->GetDocument();
2455 ScDocShell* pDocShell = GetViewData()->GetDocShell();
2456 ScDocument* pDestDoc = NULL;
2457 ScDocShell* pDestShell = NULL;
2458 ScTabViewShell* pDestViewSh = NULL;
2459 sal_Bool bUndo (pDoc->IsUndoEnabled());
2460 bool bRename = pNewTabName && !pNewTabName->isEmpty();
2462 bool bNewDoc = (nDestDocNo == SC_DOC_NEW);
2463 if ( bNewDoc )
2465 nDestTab = 0; // firstly insert
2467 // execute without SFX_CALLMODE_RECORD, because already contained in move command
2469 OUString aUrl("private:factory/" STRING_SCAPP);
2470 SfxStringItem aItem( SID_FILE_NAME, aUrl );
2471 SfxStringItem aTarget( SID_TARGETNAME, OUString("_blank") );
2473 const SfxPoolItem* pRetItem = GetViewData()->GetDispatcher().Execute(
2474 SID_OPENDOC, SFX_CALLMODE_API|SFX_CALLMODE_SYNCHRON, &aItem, &aTarget, 0L );
2475 if ( pRetItem )
2477 if ( pRetItem->ISA( SfxObjectItem ) )
2478 pDestShell = PTR_CAST( ScDocShell, ((const SfxObjectItem*)pRetItem)->GetShell() );
2479 else if ( pRetItem->ISA( SfxViewFrameItem ) )
2481 SfxViewFrame* pFrm = ((const SfxViewFrameItem*)pRetItem)->GetFrame();
2482 if (pFrm)
2483 pDestShell = PTR_CAST( ScDocShell, pFrm->GetObjectShell() );
2485 if (pDestShell)
2486 pDestViewSh = pDestShell->GetBestViewShell();
2489 else
2490 pDestShell = ScDocShell::GetShellByNum( nDestDocNo );
2492 if (!pDestShell)
2494 OSL_FAIL("Dest-Doc nicht gefunden !!!");
2495 return;
2498 ScMarkData& rMark = GetViewData()->GetMarkData();
2499 if (bRename && rMark.GetSelectCount() != 1)
2501 // Custom sheet name is provided, but more than one sheet is selected.
2502 // We don't support this scenario at the moment.
2503 return;
2506 pDestDoc = pDestShell->GetDocument();
2508 SCTAB nTab = GetViewData()->GetTabNo();
2510 if (pDestDoc != pDoc)
2512 if (bNewDoc)
2514 while (pDestDoc->GetTableCount() > 1)
2515 pDestDoc->DeleteTab(0);
2516 pDestDoc->RenameTab( 0, OUString("______42_____"),
2517 false );
2520 SCTAB nTabCount = pDoc->GetTableCount();
2521 SCTAB nTabSelCount = rMark.GetSelectCount();
2523 vector<SCTAB> TheTabs;
2525 for(SCTAB i=0; i<nTabCount; ++i)
2527 if(rMark.GetTableSelect(i))
2529 OUString aTabName;
2530 pDoc->GetName( i, aTabName);
2531 TheTabs.push_back(i);
2532 for(SCTAB j=i+1;j<nTabCount;j++)
2534 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2536 pDoc->GetName( j, aTabName);
2537 TheTabs.push_back(j);
2538 i=j;
2540 else break;
2545 GetFrameWin()->EnterWait();
2547 if (pDoc->GetDrawLayer())
2548 pDestShell->MakeDrawLayer();
2550 if (!bNewDoc && bUndo)
2551 pDestDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2553 sal_uLong nErrVal =1;
2554 if(nDestTab==SC_TAB_APPEND)
2555 nDestTab=pDestDoc->GetTableCount();
2556 SCTAB nDestTab1=nDestTab;
2557 ScClipParam aParam;
2558 for( sal_uInt16 j=0; j<TheTabs.size(); ++j, ++nDestTab1 )
2559 { // insert sheets first and update all references
2560 OUString aName;
2561 if (bRename)
2562 aName = *pNewTabName;
2563 else
2564 pDoc->GetName( TheTabs[j], aName );
2566 pDestDoc->CreateValidTabName( aName );
2567 if ( !pDestDoc->InsertTab( nDestTab1, aName ) )
2569 nErrVal = 0; // total error
2570 break; // for
2572 ScRange aRange( 0, 0, TheTabs[j], MAXCOL, MAXROW, TheTabs[j] );
2573 aParam.maRanges.Append(aRange);
2575 pDoc->SetClipParam(aParam);
2576 if ( nErrVal > 0 )
2578 nDestTab1 = nDestTab;
2579 for(sal_uInt16 i=0; i<TheTabs.size();++i)
2581 nErrVal = pDestShell->TransferTab( *pDocShell, TheTabs[i], static_cast<SCTAB>(nDestTab1), false, false );
2582 nDestTab1++;
2585 OUString sName;
2586 if (!bNewDoc && bUndo)
2588 pDestDoc->GetName(nDestTab, sName);
2589 pDestShell->GetUndoManager()->AddUndoAction(
2590 new ScUndoImportTab( pDestShell, nDestTab,
2591 static_cast<SCTAB>(TheTabs.size())));
2594 else
2596 pDestShell->GetUndoManager()->Clear();
2599 GetFrameWin()->LeaveWait();
2600 switch (nErrVal)
2602 case 0: // internal error or full of errors
2604 ErrorMessage(STR_TABINSERT_ERROR);
2605 return;
2607 //break;
2608 case 2:
2609 ErrorMessage(STR_ABSREFLOST);
2610 break;
2611 case 3:
2612 ErrorMessage(STR_NAMECONFLICT);
2613 break;
2614 case 4:
2616 ErrorMessage(STR_ABSREFLOST);
2617 ErrorMessage(STR_NAMECONFLICT);
2619 break;
2620 default:
2621 break;
2624 if (!bCopy)
2626 if(nTabCount!=nTabSelCount)
2627 DeleteTables(TheTabs); // incl. Paint & Undo
2628 else
2629 ErrorMessage(STR_TABREMOVE_ERROR);
2632 if (bNewDoc)
2634 // ChartListenerCollection must be updated before DeleteTab
2635 if ( pDestDoc->IsChartListenerCollectionNeedsUpdate() )
2636 pDestDoc->UpdateChartListenerCollection();
2638 pDestDoc->DeleteTab(static_cast<SCTAB>(TheTabs.size())); // old first table
2639 if (pDestViewSh)
2641 // Make sure to clear the cached page view after sheet
2642 // deletion, which still points to the sdr page belonging to
2643 // the deleted sheet.
2644 SdrView* pSdrView = pDestViewSh->GetSdrView();
2645 if (pSdrView)
2646 pSdrView->ClearPageView();
2648 pDestViewSh->TabChanged(); // Pages auf dem Drawing-Layer
2650 pDestShell->PostPaint( 0,0,0, MAXCOL,MAXROW,MAXTAB,
2651 PAINT_GRID | PAINT_TOP | PAINT_LEFT |
2652 PAINT_EXTRAS | PAINT_SIZE );
2653 // PAINT_SIZE for outline
2655 else
2657 pDestShell->Broadcast( ScTablesHint( SC_TAB_INSERTED, nDestTab ) );
2658 pDestShell->PostPaintExtras();
2659 pDestShell->PostPaintGridAll();
2662 TheTabs.clear();
2664 pDestShell->SetDocumentModified();
2665 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2667 else
2669 // Move or copy within the same document.
2670 SCTAB nTabCount = pDoc->GetTableCount();
2672 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2673 auto_ptr< vector<SCTAB> > pSrcTabs(new vector<SCTAB>);
2674 auto_ptr< vector<SCTAB> > pDestTabs(new vector<SCTAB>);
2675 auto_ptr< vector<OUString> > pTabNames(new vector<OUString>);
2676 auto_ptr< vector<OUString> > pDestNames(NULL);
2677 SAL_WNODEPRECATED_DECLARATIONS_POP
2678 pSrcTabs->reserve(nTabCount);
2679 pDestTabs->reserve(nTabCount);
2680 pTabNames->reserve(nTabCount);
2681 OUString aDestName;
2683 for(SCTAB i=0;i<nTabCount;i++)
2685 if(rMark.GetTableSelect(i))
2687 OUString aTabName;
2688 pDoc->GetName( i, aTabName);
2689 pTabNames->push_back(aTabName);
2691 for(SCTAB j=i+1;j<nTabCount;j++)
2693 if((!pDoc->IsVisible(j))&&(pDoc->IsScenario(j)))
2695 pDoc->GetName( j, aTabName);
2696 pTabNames->push_back(aTabName);
2697 i=j;
2699 else break;
2704 if (bCopy && bUndo)
2705 pDoc->BeginDrawUndo(); // drawing layer must do its own undo actions
2707 pDoc->GetName( nDestTab, aDestName);
2708 SCTAB nDestTab1=nDestTab;
2709 SCTAB nMovTab=0;
2710 for (size_t j = 0, n = pTabNames->size(); j < n; ++j)
2712 nTabCount = pDoc->GetTableCount();
2713 const OUString& rStr = (*pTabNames)[j];
2714 if(!pDoc->GetTable(rStr,nMovTab))
2716 nMovTab=nTabCount;
2718 if(!pDoc->GetTable(aDestName,nDestTab1))
2720 nDestTab1=nTabCount;
2722 pDocShell->MoveTable( nMovTab, nDestTab1, bCopy, false ); // Undo is here
2724 if(bCopy && pDoc->IsScenario(nMovTab))
2726 OUString aComment;
2727 Color aColor;
2728 sal_uInt16 nFlags;
2730 pDoc->GetScenarioData(nMovTab, aComment,aColor, nFlags);
2731 pDoc->SetScenario(nDestTab1,sal_True);
2732 pDoc->SetScenarioData(nDestTab1,aComment,aColor,nFlags);
2733 sal_Bool bActive = pDoc->IsActiveScenario(nMovTab );
2734 pDoc->SetActiveScenario( nDestTab1, bActive );
2735 sal_Bool bVisible=pDoc->IsVisible(nMovTab);
2736 pDoc->SetVisible(nDestTab1,bVisible );
2739 pSrcTabs->push_back(nMovTab);
2741 if(!bCopy)
2743 if(!pDoc->GetTable(rStr,nDestTab1))
2745 nDestTab1=nTabCount;
2749 pDestTabs->push_back(nDestTab1);
2752 // Rename must be done after all sheets have been moved.
2753 if (bRename)
2755 pDestNames.reset(new vector<OUString>);
2756 size_t n = pDestTabs->size();
2757 pDestNames->reserve(n);
2758 for (size_t j = 0; j < n; ++j)
2760 SCTAB nRenameTab = (*pDestTabs)[j];
2761 OUString aTabName = *pNewTabName;
2762 pDoc->CreateValidTabName( aTabName );
2763 pDestNames->push_back(aTabName);
2764 pDoc->RenameTab(nRenameTab, aTabName);
2767 else
2768 // No need to keep this around when we are not renaming.
2769 pTabNames.reset();
2771 nTab = GetViewData()->GetTabNo();
2773 if (bUndo)
2775 if (bCopy)
2777 pDocShell->GetUndoManager()->AddUndoAction(
2778 new ScUndoCopyTab(
2779 pDocShell, pSrcTabs.release(), pDestTabs.release(), pDestNames.release()));
2781 else
2783 pDocShell->GetUndoManager()->AddUndoAction(
2784 new ScUndoMoveTab(
2785 pDocShell, pSrcTabs.release(), pDestTabs.release(), pTabNames.release(), pDestNames.release()));
2789 SCTAB nNewTab = nDestTab;
2790 if (nNewTab == SC_TAB_APPEND)
2791 nNewTab = pDoc->GetTableCount()-1;
2792 else if (!bCopy && nTab<nDestTab)
2793 nNewTab--;
2795 SetTabNo( nNewTab, sal_True );
2797 //#i29848# adjust references to data on the copied sheet
2798 if( bCopy )
2799 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab );
2804 //----------------------------------------------------------------------------
2806 void ScViewFunc::ShowTable( const std::vector<OUString>& rNames )
2808 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2809 ScDocument* pDoc = pDocSh->GetDocument();
2810 sal_Bool bUndo(pDoc->IsUndoEnabled());
2812 std::vector<SCTAB> undoTabs;
2813 OUString aName;
2814 SCTAB nPos = 0;
2816 bool bFound(false);
2818 for (std::vector<OUString>::const_iterator itr=rNames.begin(), itrEnd = rNames.end(); itr!=itrEnd; ++itr)
2820 aName = *itr;
2821 if (pDoc->GetTable(aName, nPos))
2823 pDoc->SetVisible( nPos, sal_True );
2824 SetTabNo( nPos, sal_True );
2825 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2826 if (!bFound)
2827 bFound = true;
2828 if (bUndo)
2829 undoTabs.push_back(nPos);
2832 if (bFound)
2834 if (bUndo)
2836 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, true ) );
2838 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2839 pDocSh->SetDocumentModified();
2844 //----------------------------------------------------------------------------
2846 void ScViewFunc::HideTable( const ScMarkData& rMark )
2848 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2849 ScDocument* pDoc = pDocSh->GetDocument();
2850 sal_Bool bUndo(pDoc->IsUndoEnabled());
2851 SCTAB nVisible = 0;
2852 SCTAB nTabCount = pDoc->GetTableCount();
2854 SCTAB nTabSelCount = rMark.GetSelectCount();
2856 // check to make sure we won't hide all sheets. we need at least one visible at all times.
2857 for ( SCTAB i=0; i < nTabCount && nVisible <= nTabSelCount ; i++ )
2858 if (pDoc->IsVisible(i))
2859 ++nVisible;
2861 if (nVisible > nTabSelCount)
2863 SCTAB nTab;
2864 ScMarkData::MarkedTabsType::const_iterator it;
2865 std::vector<SCTAB> undoTabs;
2867 ScMarkData::MarkedTabsType selectedTabs = rMark.GetSelectedTabs();
2868 for (it=selectedTabs.begin(); it!=selectedTabs.end(); ++it)
2870 nTab = *it;
2871 if (pDoc->IsVisible( nTab ))
2873 pDoc->SetVisible( nTab, false );
2874 // Update views
2875 pDocSh->Broadcast( ScTablesHint( SC_TAB_HIDDEN, nTab ) );
2876 SetTabNo( nTab, true );
2877 // Store for undo
2878 if (bUndo)
2879 undoTabs.push_back(nTab);
2882 if (bUndo)
2884 pDocSh->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh, undoTabs, false ) );
2887 // Update views
2888 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) );
2889 pDocSh->PostPaint(0,0,0,MAXCOL,MAXROW,MAXTAB, PAINT_EXTRAS);
2890 pDocSh->SetDocumentModified();
2895 //----------------------------------------------------------------------------
2897 void ScViewFunc::InsertSpecialChar( const OUString& rStr, const Font& rFont )
2899 ScEditableTester aTester( this );
2900 if (!aTester.IsEditable())
2902 ErrorMessage(aTester.GetMessageId());
2903 return;
2906 const sal_Unicode* pChar = rStr.getStr();
2907 ScTabViewShell* pViewShell = GetViewData()->GetViewShell();
2908 SvxFontItem aFontItem( rFont.GetFamily(),
2909 rFont.GetName(),
2910 rFont.GetStyleName(),
2911 rFont.GetPitch(),
2912 rFont.GetCharSet(),
2913 ATTR_FONT );
2915 // if string contains WEAK characters, set all fonts
2916 sal_uInt8 nScript;
2917 ScDocument* pDoc = GetViewData()->GetDocument();
2918 if ( pDoc->HasStringWeakCharacters( rStr ) )
2919 nScript = SCRIPTTYPE_LATIN | SCRIPTTYPE_ASIAN | SCRIPTTYPE_COMPLEX;
2920 else
2921 nScript = pDoc->GetStringScriptType( rStr );
2923 SvxScriptSetItem aSetItem( SID_ATTR_CHAR_FONT, pViewShell->GetPool() );
2924 aSetItem.PutItemForScriptType( nScript, aFontItem );
2925 ApplyUserItemSet( aSetItem.GetItemSet() );
2927 while ( *pChar )
2928 pViewShell->TabKeyInput( KeyEvent( *(pChar++), KeyCode() ) );
2932 //----------------------------------------------------------------------------
2934 void ScViewFunc::UpdateLineAttrs( SvxBorderLine& rLine,
2935 const SvxBorderLine* pDestLine,
2936 const SvxBorderLine* pSrcLine,
2937 sal_Bool bColor )
2939 if ( pSrcLine && pDestLine )
2941 if ( bColor )
2943 rLine.SetColor ( pSrcLine->GetColor() );
2944 rLine.SetBorderLineStyle(pDestLine->GetBorderLineStyle());
2945 rLine.SetWidth ( pDestLine->GetWidth() );
2947 else
2949 rLine.SetColor ( pDestLine->GetColor() );
2950 rLine.SetBorderLineStyle(pSrcLine->GetBorderLineStyle());
2951 rLine.SetWidth ( pSrcLine->GetWidth() );
2957 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
2958 pBoxLine = aBoxItem.Get##LINE(); \
2959 if ( pBoxLine ) \
2961 if ( pLine ) \
2963 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
2964 aBoxItem.SetLine( &aLine, BOXLINE ); \
2966 else \
2967 aBoxItem.SetLine( NULL, BOXLINE ); \
2971 //----------------------------------------------------------------------------
2973 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine* pLine,
2974 sal_Bool bColorOnly )
2976 // Not editable only due to a matrix? Attribute is ok anyhow.
2977 bool bOnlyNotBecauseOfMatrix;
2978 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix ) && !bOnlyNotBecauseOfMatrix )
2980 ErrorMessage(STR_PROTECTIONERR);
2981 return;
2984 ScDocument* pDoc = GetViewData()->GetDocument();
2985 ScMarkData aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
2986 ScViewUtil::UnmarkFiltered( aFuncMark, pDoc );
2987 ScDocShell* pDocSh = GetViewData()->GetDocShell();
2988 const ScPatternAttr* pSelAttrs = GetSelectionPattern();
2989 const SfxItemSet& rSelItemSet = pSelAttrs->GetItemSet();
2991 const SfxPoolItem* pBorderAttr = NULL;
2992 SfxItemState eItemState = rSelItemSet.GetItemState( ATTR_BORDER, sal_True, &pBorderAttr );
2994 const SfxPoolItem* pTLBRItem = 0;
2995 SfxItemState eTLBRState = rSelItemSet.GetItemState( ATTR_BORDER_TLBR, sal_True, &pTLBRItem );
2997 const SfxPoolItem* pBLTRItem = 0;
2998 SfxItemState eBLTRState = rSelItemSet.GetItemState( ATTR_BORDER_BLTR, sal_True, &pBLTRItem );
3000 // any of the lines visible?
3001 if( (eItemState != SFX_ITEM_DEFAULT) || (eTLBRState != SFX_ITEM_DEFAULT) || (eBLTRState != SFX_ITEM_DEFAULT) )
3003 // none of the lines don't care?
3004 if( (eItemState != SFX_ITEM_DONTCARE) && (eTLBRState != SFX_ITEM_DONTCARE) && (eBLTRState != SFX_ITEM_DONTCARE) )
3006 SfxItemSet* pOldSet = new SfxItemSet(
3007 *(pDoc->GetPool()),
3008 ATTR_PATTERN_START,
3009 ATTR_PATTERN_END );
3010 SfxItemSet* pNewSet = new SfxItemSet(
3011 *(pDoc->GetPool()),
3012 ATTR_PATTERN_START,
3013 ATTR_PATTERN_END );
3015 //------------------------------------------------------------
3016 const SvxBorderLine* pBoxLine = NULL;
3017 SvxBorderLine aLine;
3019 // here pBoxLine is used
3021 if( pBorderAttr )
3023 SvxBoxItem aBoxItem( *(const SvxBoxItem*)pBorderAttr );
3024 SvxBoxInfoItem aBoxInfoItem( ATTR_BORDER_INNER );
3026 SET_LINE_ATTRIBUTES(Top,BOX_LINE_TOP)
3027 SET_LINE_ATTRIBUTES(Bottom,BOX_LINE_BOTTOM)
3028 SET_LINE_ATTRIBUTES(Left,BOX_LINE_LEFT)
3029 SET_LINE_ATTRIBUTES(Right,BOX_LINE_RIGHT)
3031 aBoxInfoItem.SetLine( aBoxItem.GetTop(), BOXINFO_LINE_HORI );
3032 aBoxInfoItem.SetLine( aBoxItem.GetLeft(), BOXINFO_LINE_VERT );
3033 aBoxInfoItem.ResetFlags(); // set Lines to Valid
3035 pOldSet->Put( *pBorderAttr );
3036 pNewSet->Put( aBoxItem );
3037 pNewSet->Put( aBoxInfoItem );
3040 if( pTLBRItem && ((const SvxLineItem*)pTLBRItem)->GetLine() )
3042 SvxLineItem aTLBRItem( *(const SvxLineItem*)pTLBRItem );
3043 UpdateLineAttrs( aLine, aTLBRItem.GetLine(), pLine, bColorOnly );
3044 aTLBRItem.SetLine( &aLine );
3045 pOldSet->Put( *pTLBRItem );
3046 pNewSet->Put( aTLBRItem );
3049 if( pBLTRItem && ((const SvxLineItem*)pBLTRItem)->GetLine() )
3051 SvxLineItem aBLTRItem( *(const SvxLineItem*)pBLTRItem );
3052 UpdateLineAttrs( aLine, aBLTRItem.GetLine(), pLine, bColorOnly );
3053 aBLTRItem.SetLine( &aLine );
3054 pOldSet->Put( *pBLTRItem );
3055 pNewSet->Put( aBLTRItem );
3058 ApplyAttributes( pNewSet, pOldSet );
3060 delete pOldSet;
3061 delete pNewSet;
3063 else // if ( eItemState == SFX_ITEM_DONTCARE )
3065 aFuncMark.MarkToMulti();
3066 pDoc->ApplySelectionLineStyle( aFuncMark, pLine, bColorOnly );
3069 ScRange aMarkRange;
3070 aFuncMark.GetMultiMarkArea( aMarkRange );
3071 SCCOL nStartCol = aMarkRange.aStart.Col();
3072 SCROW nStartRow = aMarkRange.aStart.Row();
3073 SCTAB nStartTab = aMarkRange.aStart.Tab();
3074 SCCOL nEndCol = aMarkRange.aEnd.Col();
3075 SCROW nEndRow = aMarkRange.aEnd.Row();
3076 SCTAB nEndTab = aMarkRange.aEnd.Tab();
3077 pDocSh->PostPaint( nStartCol, nStartRow, nStartTab,
3078 nEndCol, nEndRow, nEndTab,
3079 PAINT_GRID, SC_PF_LINES | SC_PF_TESTMERGE );
3081 pDocSh->UpdateOle( GetViewData() );
3082 pDocSh->SetDocumentModified();
3086 #undef SET_LINE_ATTRIBUTES
3088 //----------------------------------------------------------------------------
3090 void ScViewFunc::SetValidation( const ScValidationData& rNew )
3092 ScDocument* pDoc = GetViewData()->GetDocument();
3093 sal_uLong nIndex = pDoc->AddValidationEntry(rNew); // for it there is no Undo
3094 SfxUInt32Item aItem( ATTR_VALIDDATA, nIndex );
3096 ApplyAttr( aItem ); // with Paint and Undo...
3100 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */