1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/srchdlg.hxx>
38 #include <svx/svdview.hxx>
39 #include <vcl/msgbox.hxx>
40 #include <vcl/waitobj.hxx>
42 #include <basic/sbstar.hxx>
43 #include <com/sun/star/container/XNameContainer.hpp>
44 #include <com/sun/star/script/XLibraryContainer.hpp>
46 #include "viewfunc.hxx"
49 #include "globstr.hrc"
52 #include "autoform.hxx"
53 #include "formulacell.hxx"
54 #include "cellmergeoption.hxx"
55 #include "compiler.hxx"
56 #include "docfunc.hxx"
57 #include "docpool.hxx"
59 #include "docoptio.hxx"
61 #include "patattr.hxx"
62 #include "printfun.hxx"
63 #include "rangenam.hxx"
64 #include "rangeutl.hxx"
65 #include "refundo.hxx"
67 #include "tablink.hxx"
68 #include "tabvwsh.hxx"
69 #include "uiitems.hxx"
70 #include "undoblk.hxx"
71 #include "undocell.hxx"
72 #include "undotab.hxx"
73 #include "sizedev.hxx"
74 #include "editable.hxx"
76 #include "inputhdl.hxx"
77 #include "inputwin.hxx"
78 #include "funcdesc.hxx"
80 #include "charthelper.hxx"
81 #include "tabbgcolor.hxx"
82 #include "clipparam.hxx"
83 #include "prnsave.hxx"
84 #include "searchresults.hxx"
85 #include "tokenarray.hxx"
86 #include <columnspanset.hxx>
87 #include <rowheightcontext.hxx>
88 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
90 #include <boost/scoped_ptr.hpp>
94 using namespace com::sun::star
;
95 using ::editeng::SvxBorderLine
;
98 using ::std::unique_ptr
;
100 // STATIC DATA ---------------------------------------------------------------
102 bool ScViewFunc::AdjustBlockHeight( bool bPaint
, ScMarkData
* pMarkData
)
104 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
106 pMarkData
= &GetViewData().GetMarkData();
108 ScDocument
& rDoc
= pDocSh
->GetDocument();
109 std::vector
<sc::ColRowSpan
> aMarkedRows
= pMarkData
->GetMarkedRowSpans();
111 if (aMarkedRows
.empty())
113 SCROW nCurRow
= GetViewData().GetCurY();
114 aMarkedRows
.push_back(sc::ColRowSpan(nCurRow
, nCurRow
));
117 double nPPTX
= GetViewData().GetPPTX();
118 double nPPTY
= GetViewData().GetPPTY();
119 Fraction aZoomX
= GetViewData().GetZoomX();
120 Fraction aZoomY
= GetViewData().GetZoomY();
122 ScSizeDeviceProvider
aProv(pDocSh
);
123 if (aProv
.IsPrinter())
125 nPPTX
= aProv
.GetPPTX();
126 nPPTY
= aProv
.GetPPTY();
127 aZoomX
= aZoomY
= Fraction( 1, 1 );
130 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, aZoomX
, aZoomY
, aProv
.GetDevice());
131 bool bAnyChanged
= false;
132 ScMarkData::iterator itr
= pMarkData
->begin(), itrEnd
= pMarkData
->end();
133 for (; itr
!= itrEnd
; ++itr
)
136 bool bChanged
= false;
138 std::vector
<sc::ColRowSpan
>::const_iterator itRows
= aMarkedRows
.begin(), itRowsEnd
= aMarkedRows
.end();
139 for (; itRows
!= itRowsEnd
; ++itRows
)
141 SCROW nStartNo
= itRows
->mnStart
;
142 SCROW nEndNo
= itRows
->mnEnd
;
143 ScAddress
aTopLeft(0, nStartNo
, nTab
);
144 rDoc
.UpdateScriptTypes(aTopLeft
, MAXCOLCOUNT
, nEndNo
-nStartNo
+1);
145 if (rDoc
.SetOptimalHeight(aCxt
, nStartNo
, nEndNo
, nTab
))
149 bAnyChanged
= bChanged
= true;
152 if ( bPaint
&& bChanged
)
153 pDocSh
->PostPaint( 0, nPaintY
, nTab
, MAXCOL
, MAXROW
, nTab
,
154 PAINT_GRID
| PAINT_LEFT
);
157 if ( bPaint
&& bAnyChanged
)
158 pDocSh
->UpdateOle(&GetViewData());
163 bool ScViewFunc::AdjustRowHeight( SCROW nStartRow
, SCROW nEndRow
, bool bPaint
)
165 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
166 ScDocument
& rDoc
= 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
) (rDoc
.GetRowHeight(nStartRow
,nTab
) * nPPTY
);
176 ScSizeDeviceProvider
aProv(pDocSh
);
177 if (aProv
.IsPrinter())
179 nPPTX
= aProv
.GetPPTX();
180 nPPTY
= aProv
.GetPPTY();
181 aZoomX
= aZoomY
= Fraction( 1, 1 );
183 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, aZoomX
, aZoomY
, aProv
.GetDevice());
184 bool bChanged
= rDoc
.SetOptimalHeight(aCxt
, nStartRow
, nEndRow
, nTab
);
186 if (bChanged
&& ( nStartRow
== nEndRow
))
188 sal_uInt16 nNewPixel
= (sal_uInt16
) (rDoc
.GetRowHeight(nStartRow
,nTab
) * nPPTY
);
189 if ( nNewPixel
== nOldPixel
)
193 if ( bPaint
&& bChanged
)
194 pDocSh
->PostPaint( 0, nStartRow
, nTab
, MAXCOL
, MAXROW
, nTab
,
195 PAINT_GRID
| PAINT_LEFT
);
207 static ScAutoSum
lcl_IsAutoSumData( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
,
208 SCTAB nTab
, ScDirection eDir
, SCCOLROW
& nExtend
)
210 ScRefCellValue aCell
;
211 aCell
.assign(*pDoc
, ScAddress(nCol
, nRow
, nTab
));
212 if (aCell
.hasNumeric())
214 if (aCell
.meType
== CELLTYPE_FORMULA
)
216 ScTokenArray
* pCode
= aCell
.mpFormula
->GetCode();
217 if ( pCode
&& pCode
->GetOuterFuncOpCode() == ocSum
)
219 if ( pCode
->GetAdjacentExtendOfOuterFuncRefs( nExtend
,
220 ScAddress( nCol
, nRow
, nTab
), eDir
) )
224 return ScAutoSumData
;
226 return ScAutoSumNone
;
229 #define SC_AUTOSUM_MAXCOUNT 20
231 static ScAutoSum
lcl_SeekAutoSumData( ScDocument
* pDoc
, SCCOL
& nCol
, SCROW
& nRow
,
232 SCTAB nTab
, ScDirection eDir
, SCCOLROW
& nExtend
)
234 sal_uInt16 nCount
= 0;
235 while (nCount
< SC_AUTOSUM_MAXCOUNT
)
237 if ( eDir
== DIR_TOP
)
242 return ScAutoSumNone
;
249 return ScAutoSumNone
;
252 if ( (eSum
= lcl_IsAutoSumData(
253 pDoc
, nCol
, nRow
, nTab
, eDir
, nExtend
)) != ScAutoSumNone
)
257 return ScAutoSumNone
;
260 #undef SC_AUTOSUM_MAXCOUNT
262 static bool lcl_FindNextSumEntryInColumn( ScDocument
* pDoc
, SCCOL nCol
, SCROW
& nRow
,
263 SCTAB nTab
, SCCOLROW
& nExtend
, SCROW nMinRow
)
265 const SCROW nTmp
= nRow
;
266 ScAutoSum eSkip
= ScAutoSumNone
;
267 while ( ( eSkip
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_TOP
, nExtend
) ) == ScAutoSumData
&&
272 if ( eSkip
== ScAutoSumSum
&& nRow
< nTmp
)
279 static bool lcl_FindNextSumEntryInRow( ScDocument
* pDoc
, SCCOL
& nCol
, SCROW nRow
,
280 SCTAB nTab
, SCCOLROW
& nExtend
, SCROW nMinCol
)
282 const SCCOL nTmp
= nCol
;
283 ScAutoSum eSkip
= ScAutoSumNone
;
284 while ( ( eSkip
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_LEFT
, nExtend
) ) == ScAutoSumData
&&
289 if ( eSkip
== ScAutoSumSum
&& nCol
< nTmp
)
296 static bool lcl_GetAutoSumForColumnRange( ScDocument
* pDoc
, ScRangeList
& rRangeList
, const ScRange
& rRange
)
298 const ScAddress aStart
= rRange
.aStart
;
299 const ScAddress aEnd
= rRange
.aEnd
;
300 if ( aStart
.Col() != aEnd
.Col() )
305 const SCTAB nTab
= aEnd
.Tab();
306 const SCCOL nCol
= aEnd
.Col();
307 SCROW nEndRow
= aEnd
.Row();
308 SCROW nStartRow
= nEndRow
;
309 SCCOLROW nExtend
= 0;
310 const ScAutoSum eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nEndRow
, nTab
, DIR_TOP
, nExtend
/*out*/ );
312 if ( eSum
== ScAutoSumSum
)
314 bool bContinue
= false;
317 rRangeList
.Append( ScRange( nCol
, nStartRow
, nTab
, nCol
, nEndRow
, nTab
) );
318 nEndRow
= static_cast< SCROW
>( nExtend
);
319 if ( ( bContinue
= lcl_FindNextSumEntryInColumn( pDoc
, nCol
, nEndRow
/*inout*/, nTab
, nExtend
/*out*/, aStart
.Row() ) ) )
323 } while ( bContinue
);
327 while ( nStartRow
> aStart
.Row() &&
328 lcl_IsAutoSumData( pDoc
, nCol
, nStartRow
-1, nTab
, DIR_TOP
, nExtend
/*out*/ ) != ScAutoSumSum
)
332 rRangeList
.Append( ScRange( nCol
, nStartRow
, nTab
, nCol
, nEndRow
, nTab
) );
338 static bool lcl_GetAutoSumForRowRange( ScDocument
* pDoc
, ScRangeList
& rRangeList
, const ScRange
& rRange
)
340 const ScAddress aStart
= rRange
.aStart
;
341 const ScAddress aEnd
= rRange
.aEnd
;
342 if ( aStart
.Row() != aEnd
.Row() )
347 const SCTAB nTab
= aEnd
.Tab();
348 const SCROW nRow
= aEnd
.Row();
349 SCCOL nEndCol
= aEnd
.Col();
350 SCCOL nStartCol
= nEndCol
;
351 SCCOLROW nExtend
= 0;
352 const ScAutoSum eSum
= lcl_IsAutoSumData( pDoc
, nEndCol
, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ );
354 if ( eSum
== ScAutoSumSum
)
356 bool bContinue
= false;
359 rRangeList
.Append( ScRange( nStartCol
, nRow
, nTab
, nEndCol
, nRow
, nTab
) );
360 nEndCol
= static_cast< SCCOL
>( nExtend
);
361 if ( ( bContinue
= lcl_FindNextSumEntryInRow( pDoc
, nEndCol
/*inout*/, nRow
, nTab
, nExtend
/*out*/, aStart
.Col() ) ) )
365 } while ( bContinue
);
369 while ( nStartCol
> aStart
.Col() &&
370 lcl_IsAutoSumData( pDoc
, nStartCol
-1, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ ) != ScAutoSumSum
)
374 rRangeList
.Append( ScRange( nStartCol
, nRow
, nTab
, nEndCol
, nRow
, nTab
) );
380 bool ScViewFunc::GetAutoSumArea( ScRangeList
& rRangeList
)
382 ScDocument
* pDoc
= GetViewData().GetDocument();
383 SCTAB nTab
= GetViewData().GetTabNo();
385 SCCOL nCol
= GetViewData().GetCurX();
386 SCROW nRow
= GetViewData().GetCurY();
388 SCCOL nStartCol
= nCol
;
389 SCROW nStartRow
= nRow
;
390 SCCOL nEndCol
= nCol
;
391 SCROW nEndRow
= nRow
;
392 SCCOL nSeekCol
= nCol
;
393 SCROW nSeekRow
= nRow
;
394 SCCOLROW nExtend
; // will become valid via reference for ScAutoSumSum
401 && ((eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
-1, nTab
,
402 DIR_TOP
, nExtend
/*out*/ )) == ScAutoSumData
)
403 && ((eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
-1, nTab
,
404 DIR_LEFT
, nExtend
/*out*/ )) == ScAutoSumData
)
410 else if ( nCol
!= 0 && (eSum
= lcl_IsAutoSumData( pDoc
, nCol
-1, nRow
, nTab
,
411 DIR_LEFT
, nExtend
/*out*/ )) == ScAutoSumData
)
416 else if ( (eSum
= lcl_SeekAutoSumData( pDoc
, nCol
, nSeekRow
, nTab
, DIR_TOP
, nExtend
/*out*/ )) != ScAutoSumNone
)
418 else if (( eSum
= lcl_SeekAutoSumData( pDoc
, nSeekCol
, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ )) != ScAutoSumNone
)
425 nStartRow
= nSeekRow
; // nSeekRow might be adjusted via reference
426 if ( eSum
== ScAutoSumSum
)
427 nEndRow
= nStartRow
; // only sum sums
429 nEndRow
= nRow
- 1; // maybe extend data area at bottom
433 nStartCol
= nSeekCol
; // nSeekCol might be adjusted vie reference
434 if ( eSum
== ScAutoSumSum
)
435 nEndCol
= nStartCol
; // only sum sums
437 nEndCol
= nCol
- 1; // maybe extend data area to the right
439 bool bContinue
= false;
442 if ( eSum
== ScAutoSumData
)
446 while ( nStartRow
!= 0 && lcl_IsAutoSumData( pDoc
, nCol
,
447 nStartRow
-1, nTab
, DIR_TOP
, nExtend
/*out*/ ) == eSum
)
452 while ( nStartCol
!= 0 && lcl_IsAutoSumData( pDoc
, nStartCol
-1,
453 nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ ) == eSum
)
458 ScRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
) );
459 if ( eSum
== ScAutoSumSum
)
463 nEndRow
= static_cast< SCROW
>( nExtend
);
464 if ( ( bContinue
= lcl_FindNextSumEntryInColumn( pDoc
, nCol
, nEndRow
/*inout*/, nTab
, nExtend
/*out*/, 0 ) ) )
471 nEndCol
= static_cast< SCCOL
>( nExtend
);
472 if ( ( bContinue
= lcl_FindNextSumEntryInRow( pDoc
, nEndCol
/*inout*/, nRow
, nTab
, nExtend
/*out*/, 0 ) ) )
478 } while ( bContinue
);
484 void ScViewFunc::EnterAutoSum(const ScRangeList
& rRangeList
, bool bSubTotal
, const ScAddress
& rAddr
)
486 OUString aFormula
= GetAutoSumFormula( rRangeList
, bSubTotal
, rAddr
);
487 EnterBlock( aFormula
, NULL
);
490 bool ScViewFunc::AutoSum( const ScRange
& rRange
, bool bSubTotal
, bool bSetCursor
, bool bContinue
)
492 ScDocument
* pDoc
= GetViewData().GetDocument();
493 const SCTAB nTab
= rRange
.aStart
.Tab();
494 SCCOL nStartCol
= rRange
.aStart
.Col();
495 SCROW nStartRow
= rRange
.aStart
.Row();
496 const SCCOL nEndCol
= rRange
.aEnd
.Col();
497 const SCROW nEndRow
= rRange
.aEnd
.Row();
498 SCCOLROW nExtend
= 0; // out parameter for lcl_IsAutoSumData
500 // ignore rows at the top of the given range which don't contain autosum data
501 bool bRowData
= false;
502 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
504 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
506 if ( lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_TOP
, nExtend
) != ScAutoSumNone
)
523 // ignore columns at the left of the given range which don't contain autosum data
524 bool bColData
= false;
525 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
527 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
529 if ( lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_LEFT
, nExtend
) != ScAutoSumNone
)
546 const bool bEndRowEmpty
= pDoc
->IsBlockEmpty( nTab
, nStartCol
, nEndRow
, nEndCol
, nEndRow
);
547 const bool bEndColEmpty
= pDoc
->IsBlockEmpty( nTab
, nEndCol
, nStartRow
, nEndCol
, nEndRow
);
548 bool bRow
= ( ( nStartRow
!= nEndRow
) && ( bEndRowEmpty
|| ( !bEndRowEmpty
&& !bEndColEmpty
) ) );
549 bool bCol
= ( ( nStartCol
!= nEndCol
) && ( bEndColEmpty
|| nStartRow
== nEndRow
) );
551 // find an empty row for entering the result
552 SCROW nInsRow
= nEndRow
;
553 if ( bRow
&& !bEndRowEmpty
)
555 if ( nInsRow
< MAXROW
)
558 while ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
, nInsRow
, nEndCol
, nInsRow
) )
560 if ( nInsRow
< MAXROW
)
577 // find an empty column for entering the result
578 SCCOL nInsCol
= nEndCol
;
579 if ( bCol
&& !bEndColEmpty
)
581 if ( nInsCol
< MAXCOL
)
584 while ( !pDoc
->IsBlockEmpty( nTab
, nInsCol
, nStartRow
, nInsCol
, nEndRow
) )
586 if ( nInsCol
< MAXCOL
)
603 if ( !bRow
&& !bCol
)
608 SCCOL nMarkEndCol
= nEndCol
;
609 SCROW nMarkEndRow
= nEndRow
;
613 // calculate the row sums for all columns of the given range
615 SCROW nSumEndRow
= nEndRow
;
619 // the last row of the given range is empty;
620 // don't take into account for calculating the autosum
625 // increase mark range
629 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
631 if ( !pDoc
->IsBlockEmpty( nTab
, nCol
, nStartRow
, nCol
, nSumEndRow
) )
633 ScRangeList aRangeList
;
634 const ScRange
aRange( nCol
, nStartRow
, nTab
, nCol
, nSumEndRow
, nTab
);
635 if ( lcl_GetAutoSumForColumnRange( pDoc
, aRangeList
, aRange
) )
637 const OUString aFormula
= GetAutoSumFormula(
638 aRangeList
, bSubTotal
, ScAddress(nCol
, nInsRow
, nTab
));
639 EnterData( nCol
, nInsRow
, nTab
, aFormula
);
647 // calculate the column sums for all rows of the given range
649 SCCOL nSumEndCol
= nEndCol
;
653 // the last column of the given range is empty;
654 // don't take into account for calculating the autosum
659 // increase mark range
663 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
665 if ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
, nRow
, nSumEndCol
, nRow
) )
667 ScRangeList aRangeList
;
668 const ScRange
aRange( nStartCol
, nRow
, nTab
, nSumEndCol
, nRow
, nTab
);
669 if ( lcl_GetAutoSumForRowRange( pDoc
, aRangeList
, aRange
) )
671 const OUString aFormula
= GetAutoSumFormula( aRangeList
, bSubTotal
, ScAddress(nInsCol
, nRow
, nTab
) );
672 EnterData( nInsCol
, nRow
, nTab
, aFormula
);
678 // set new mark range and cursor position
679 const ScRange
aMarkRange( nStartCol
, nStartRow
, nTab
, nMarkEndCol
, nMarkEndRow
, nTab
);
680 MarkRange( aMarkRange
, false, bContinue
);
683 SetCursor( nMarkEndCol
, nMarkEndRow
);
689 OUString
ScViewFunc::GetAutoSumFormula( const ScRangeList
& rRangeList
, bool bSubTotal
, const ScAddress
& rAddr
)
691 ScViewData
& rViewData
= GetViewData();
692 ScDocument
* pDoc
= rViewData
.GetDocument();
693 ::boost::scoped_ptr
<ScTokenArray
> pArray(new ScTokenArray
);
695 pArray
->AddOpCode(bSubTotal
? ocSubTotal
: ocSum
);
696 pArray
->AddOpCode(ocOpen
);
700 pArray
->AddDouble(9);
701 pArray
->AddOpCode(ocSep
);
704 if(!rRangeList
.empty())
706 ScRangeList aRangeList
= rRangeList
;
707 const ScRange
* pFirst
= aRangeList
.front();
708 size_t ListSize
= aRangeList
.size();
709 for ( size_t i
= 0; i
< ListSize
; ++i
)
711 const ScRange
* p
= aRangeList
[i
];
713 pArray
->AddOpCode(ocSep
);
714 ScComplexRefData aRef
;
715 aRef
.InitRangeRel(*p
, rAddr
);
716 pArray
->AddDoubleReference(aRef
);
720 pArray
->AddOpCode(ocClose
);
722 ScCompiler
aComp(pDoc
, rAddr
, *pArray
);
723 aComp
.SetGrammar(pDoc
->GetGrammar());
725 aComp
.CreateStringFromTokenArray(aBuf
);
726 OUString aFormula
= aBuf
.makeStringAndClear();
728 aBuf
.append(aFormula
);
729 return aBuf
.makeStringAndClear();
732 void ScViewFunc::EnterBlock( const OUString
& rString
, const EditTextObject
* pData
)
734 // test for multi selection
736 SCCOL nCol
= GetViewData().GetCurX();
737 SCROW nRow
= GetViewData().GetCurY();
738 SCTAB nTab
= GetViewData().GetTabNo();
739 ScMarkData
& rMark
= GetViewData().GetMarkData();
740 if ( rMark
.IsMultiMarked() )
742 rMark
.MarkToSimple();
743 if ( rMark
.IsMultiMarked() )
744 { // "Insert into multi selection not possible"
745 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
747 // insert into single cell
749 EnterData(nCol
, nRow
, nTab
, *pData
);
751 EnterData( nCol
, nRow
, nTab
, rString
);
756 ScDocument
* pDoc
= GetViewData().GetDocument();
757 OUString aNewStr
= rString
;
760 const ScPatternAttr
* pOldPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
761 ScTabEditEngine
aEngine( *pOldPattern
, pDoc
->GetEnginePool() );
762 aEngine
.SetText(*pData
);
764 ScEditAttrTester
aTester( &aEngine
);
765 if (!aTester
.NeedsObject())
767 aNewStr
= aEngine
.GetText();
772 // Insert via PasteFromClip
774 WaitObject
aWait( GetFrameWin() );
776 ScAddress
aPos( nCol
, nRow
, nTab
);
778 boost::scoped_ptr
<ScDocument
> pInsDoc(new ScDocument( SCDOCMODE_CLIP
));
779 pInsDoc
->ResetClip( pDoc
, nTab
);
781 if (aNewStr
[0] == '=') // Formula ?
783 // SetString not possible, because in Clipboard-Documents nothing will be compiled!
784 pInsDoc
->SetFormulaCell(aPos
, new ScFormulaCell(pDoc
, aPos
, aNewStr
));
788 // A copy of pData will be stored.
789 pInsDoc
->SetEditText(aPos
, *pData
, pDoc
->GetEditPool());
792 pInsDoc
->SetString( nCol
, nRow
, nTab
, aNewStr
);
794 pInsDoc
->SetClipArea( ScRange(aPos
) );
795 // insert Block, with Undo etc.
796 if ( PasteFromClip( IDF_CONTENTS
, pInsDoc
.get(), PASTE_NOFUNC
, false, false,
797 false, INS_NONE
, IDF_ATTRIB
) )
799 const SfxUInt32Item
* pItem
= static_cast<const SfxUInt32Item
*>( pInsDoc
->GetAttr(
800 nCol
, nRow
, nTab
, ATTR_VALUE_FORMAT
) );
802 { // set number format if incompatible
803 // MarkData was already MarkToSimple'ed in PasteFromClip
805 rMark
.GetMarkArea( aRange
);
806 boost::scoped_ptr
<ScPatternAttr
> pPattern(new ScPatternAttr( pDoc
->GetPool() ));
807 pPattern
->GetItemSet().Put( *pItem
);
808 short nNewType
= pDoc
->GetFormatTable()->GetType( pItem
->GetValue() );
809 pDoc
->ApplyPatternIfNumberformatIncompatible( aRange
, rMark
,
810 *pPattern
, nNewType
);
817 void ScViewFunc::InsertPageBreak( bool bColumn
, bool bRecord
, const ScAddress
* pPos
,
820 SCTAB nTab
= GetViewData().GetTabNo();
825 aCursor
= ScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), nTab
);
827 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().
828 InsertPageBreak( bColumn
, aCursor
, bRecord
, bSetModified
, false );
830 if ( bSuccess
&& bSetModified
)
831 UpdatePageBreakData( true ); // for PageBreak-Mode
834 void ScViewFunc::DeletePageBreak( bool bColumn
, bool bRecord
, const ScAddress
* pPos
,
837 SCTAB nTab
= GetViewData().GetTabNo();
842 aCursor
= ScAddress( GetViewData().GetCurX(), GetViewData().GetCurY(), nTab
);
844 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().
845 RemovePageBreak( bColumn
, aCursor
, bRecord
, bSetModified
, false );
847 if ( bSuccess
&& bSetModified
)
848 UpdatePageBreakData( true ); // for PageBreak-Mode
851 void ScViewFunc::RemoveManualBreaks()
853 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
854 ScDocument
& rDoc
= pDocSh
->GetDocument();
855 SCTAB nTab
= GetViewData().GetTabNo();
856 bool bUndo(rDoc
.IsUndoEnabled());
860 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
861 pUndoDoc
->InitUndo( &rDoc
, nTab
, nTab
, true, true );
862 rDoc
.CopyToDocument( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_NONE
, false, pUndoDoc
);
863 pDocSh
->GetUndoManager()->AddUndoAction(
864 new ScUndoRemoveBreaks( pDocSh
, nTab
, pUndoDoc
) );
867 rDoc
.RemoveManualBreaks(nTab
);
868 rDoc
.UpdatePageBreaks(nTab
);
870 UpdatePageBreakData( true );
871 pDocSh
->SetDocumentModified();
872 pDocSh
->PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
875 void ScViewFunc::SetPrintZoom(sal_uInt16 nScale
, sal_uInt16 nPages
)
877 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
878 SCTAB nTab
= GetViewData().GetTabNo();
879 pDocSh
->SetPrintZoom( nTab
, nScale
, nPages
);
882 void ScViewFunc::AdjustPrintZoom()
885 if ( GetViewData().GetSimpleArea( aRange
) != SC_MARK_SIMPLE
)
886 GetViewData().GetMarkData().GetMultiMarkArea( aRange
);
887 GetViewData().GetDocShell()->AdjustPrintZoom( aRange
);
890 void ScViewFunc::SetPrintRanges( bool bEntireSheet
, const OUString
* pPrint
,
891 const OUString
* pRepCol
, const OUString
* pRepRow
,
894 // on all selected tables
896 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
897 ScDocument
& rDoc
= pDocSh
->GetDocument();
898 ScMarkData
& rMark
= GetViewData().GetMarkData();
900 bool bUndo (rDoc
.IsUndoEnabled());
902 ScPrintRangeSaver
* pOldRanges
= rDoc
.CreatePrintRangeSaver();
904 ScAddress::Details
aDetails(rDoc
.GetAddressConvention(), 0, 0);
906 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
907 for (; itr
!= itrEnd
; ++itr
)
910 ScRange
aRange( 0,0,nTab
);
915 rDoc
.ClearPrintRanges( nTab
);
919 rDoc
.SetPrintEntireSheet( nTab
);
923 if ( !pPrint
->isEmpty() )
925 const sal_Unicode sep
= ScCompiler::GetNativeSymbolChar(ocSep
);
926 sal_uInt16 nTCount
= comphelper::string::getTokenCount(*pPrint
, sep
);
927 for (sal_uInt16 i
=0; i
<nTCount
; i
++)
929 OUString aToken
= pPrint
->getToken(i
, sep
);
930 if ( aRange
.ParseAny( aToken
, &rDoc
, aDetails
) & SCA_VALID
)
931 rDoc
.AddPrintRange( nTab
, aRange
);
935 else // NULL = use selection (print range is always set), use empty string to delete all ranges
937 if ( GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
939 rDoc
.AddPrintRange( nTab
, aRange
);
941 else if ( rMark
.IsMultiMarked() )
944 ScRangeListRef
pList( new ScRangeList
);
945 rMark
.FillRangeListWithMarks( pList
, false );
946 for (size_t i
= 0, n
= pList
->size(); i
< n
; ++i
)
948 ScRange
* pR
= (*pList
)[i
];
949 rDoc
.AddPrintRange(nTab
, *pR
);
958 if ( pRepCol
->isEmpty() )
959 rDoc
.SetRepeatColRange( nTab
, NULL
);
961 if ( aRange
.ParseAny( *pRepCol
, &rDoc
, aDetails
) & SCA_VALID
)
962 rDoc
.SetRepeatColRange( nTab
, &aRange
);
969 if ( pRepRow
->isEmpty() )
970 rDoc
.SetRepeatRowRange( nTab
, NULL
);
972 if ( aRange
.ParseAny( *pRepRow
, &rDoc
, aDetails
) & SCA_VALID
)
973 rDoc
.SetRepeatRowRange( nTab
, &aRange
);
977 // undo (for all tables)
980 SCTAB nCurTab
= GetViewData().GetTabNo();
981 ScPrintRangeSaver
* pNewRanges
= rDoc
.CreatePrintRangeSaver();
982 pDocSh
->GetUndoManager()->AddUndoAction(
983 new ScUndoPrintRange( pDocSh
, nCurTab
, pOldRanges
, pNewRanges
) );
988 // update page breaks
991 for (; itr
!= itrEnd
; ++itr
)
992 ScPrintFunc( pDocSh
, pDocSh
->GetPrinter(), *itr
).UpdatePages();
994 SfxBindings
& rBindings
= GetViewData().GetBindings();
995 rBindings
.Invalidate( SID_DELETE_PRINTAREA
);
997 pDocSh
->SetDocumentModified();
1002 bool ScViewFunc::TestMergeCells() // pre-test (for menu)
1004 // simple test: true if there's a selection but no multi selection and not filtered
1006 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1007 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
1010 return GetViewData().GetSimpleArea( aDummy
) == SC_MARK_SIMPLE
;
1016 bool ScViewFunc::MergeCells( bool bApi
, bool& rDoContents
, bool bRecord
, bool bCenter
)
1018 // Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
1019 // so that the Contents-QueryBox won't appear
1020 ScEditableTester
aTester( this );
1021 if (!aTester
.IsEditable())
1023 ErrorMessage(aTester
.GetMessageId());
1027 ScMarkData
& rMark
= GetViewData().GetMarkData();
1028 rMark
.MarkToSimple();
1029 if (!rMark
.IsMarked())
1031 ErrorMessage(STR_NOMULTISELECT
);
1035 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1036 ScDocument
& rDoc
= pDocSh
->GetDocument();
1039 rMark
.GetMarkArea( aMarkRange
);
1040 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
1041 SCROW nStartRow
= aMarkRange
.aStart
.Row();
1042 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
1043 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
1044 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
1045 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
1046 if ( nStartCol
== nEndCol
&& nStartRow
== nEndRow
)
1052 if ( rDoc
.HasAttrib( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
1053 HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
1054 { // "Don't nest merging !"
1055 ErrorMessage(STR_MSSG_MERGECELLS_0
);
1059 // Check for the contents of all selected tables.
1060 bool bAskDialog
= false;
1061 ScCellMergeOption
aMergeOption(nStartCol
, nStartRow
, nEndCol
, nEndRow
, bCenter
);
1062 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1063 for (; itr
!= itrEnd
; ++itr
)
1066 aMergeOption
.maTabs
.insert(i
);
1068 if (!rDoc
.IsBlockEmpty(i
, nStartCol
, nStartRow
+1, nStartCol
, nEndRow
) ||
1069 !rDoc
.IsBlockEmpty(i
, nStartCol
+1, nStartRow
, nEndCol
, nEndRow
))
1079 ScopedVclPtrInstance
<MessBox
> aBox( GetViewData().GetDialogParent(),
1080 WinBits(WB_YES_NO_CANCEL
| WB_DEF_NO
),
1081 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0
),
1082 ScGlobal::GetRscString( STR_MERGE_NOTEMPTY
) );
1083 sal_uInt16 nRetVal
= aBox
->Execute();
1085 if ( nRetVal
== RET_YES
)
1087 else if ( nRetVal
== RET_CANCEL
)
1094 bOk
= pDocSh
->GetDocFunc().MergeCells( aMergeOption
, rDoContents
, bRecord
, bApi
);
1098 SetCursor( nStartCol
, nStartRow
);
1099 //DoneBlockMode( sal_False);
1102 pDocSh
->UpdateOle(&GetViewData());
1110 bool ScViewFunc::TestRemoveMerge()
1112 bool bMerged
= false;
1114 if (GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1116 ScDocument
* pDoc
= GetViewData().GetDocument();
1117 if ( pDoc
->HasAttrib( aRange
, HASATTR_MERGED
) )
1123 static bool lcl_extendMergeRange(ScCellMergeOption
& rOption
, const ScRange
& rRange
)
1125 bool bExtended
= false;
1126 if (rOption
.mnStartCol
> rRange
.aStart
.Col())
1128 rOption
.mnStartCol
= rRange
.aStart
.Col();
1131 if (rOption
.mnStartRow
> rRange
.aStart
.Row())
1133 rOption
.mnStartRow
= rRange
.aStart
.Row();
1136 if (rOption
.mnEndCol
< rRange
.aEnd
.Col())
1138 rOption
.mnEndCol
= rRange
.aEnd
.Col();
1141 if (rOption
.mnEndRow
< rRange
.aEnd
.Row())
1143 rOption
.mnEndRow
= rRange
.aEnd
.Row();
1149 bool ScViewFunc::RemoveMerge( bool bRecord
)
1152 ScEditableTester
aTester( this );
1153 if (!aTester
.IsEditable())
1155 ErrorMessage(aTester
.GetMessageId());
1158 else if (GetViewData().GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1160 ScDocument
* pDoc
= GetViewData().GetDocument();
1161 ScRange
aExtended( aRange
);
1162 pDoc
->ExtendMerge( aExtended
);
1163 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1164 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1165 ScCellMergeOption
aOption(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row());
1166 bool bExtended
= false;
1170 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1171 for (; itr
!= itrEnd
; ++itr
)
1174 aOption
.maTabs
.insert(i
);
1175 aExtended
.aStart
.SetTab(i
);
1176 aExtended
.aEnd
.SetTab(i
);
1177 pDoc
->ExtendMerge(aExtended
);
1178 pDoc
->ExtendOverlapped(aExtended
);
1180 // Expand the current range to be inclusive of all merged
1181 // areas on all sheets.
1182 bExtended
= lcl_extendMergeRange(aOption
, aExtended
);
1187 bool bOk
= pDocSh
->GetDocFunc().UnmergeCells(aOption
, bRecord
);
1188 aExtended
= aOption
.getFirstSingleRange();
1189 MarkRange( aExtended
);
1192 pDocSh
->UpdateOle(&GetViewData());
1194 return true; //! bOk ??
1197 void ScViewFunc::FillSimple( FillDir eDir
, bool bRecord
)
1200 if (GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1202 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1203 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1204 bool bSuccess
= pDocSh
->GetDocFunc().FillSimple( aRange
, &rMark
, eDir
, bRecord
, false );
1207 pDocSh
->UpdateOle(&GetViewData());
1209 bool bDoAutoSpell
= pDocSh
->GetDocument().GetDocOptions().IsAutoSpell();
1211 CopyAutoSpellData(eDir
, aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row(),
1212 ::std::numeric_limits
<sal_uLong
>::max());
1216 ErrorMessage(STR_NOMULTISELECT
);
1219 void ScViewFunc::FillSeries( FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
,
1220 double fStart
, double fStep
, double fMax
, bool bRecord
)
1223 if (GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1225 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1226 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1227 bool bSuccess
= pDocSh
->GetDocFunc().
1228 FillSeries( aRange
, &rMark
, eDir
, eCmd
, eDateCmd
,
1229 fStart
, fStep
, fMax
, bRecord
, false );
1232 pDocSh
->UpdateOle(&GetViewData());
1235 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, aRange
);
1239 ErrorMessage(STR_NOMULTISELECT
);
1242 void ScViewFunc::FillAuto( FillDir eDir
, SCCOL nStartCol
, SCROW nStartRow
,
1243 SCCOL nEndCol
, SCROW nEndRow
, sal_uLong nCount
, bool bRecord
)
1245 SCTAB nTab
= GetViewData().GetTabNo();
1246 ScRange
aRange( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
);
1247 ScRange
aSourceRange( aRange
);
1248 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1249 const ScMarkData
& rMark
= GetViewData().GetMarkData();
1250 bool bSuccess
= pDocSh
->GetDocFunc().
1251 FillAuto( aRange
, &rMark
, eDir
, nCount
, bRecord
, false );
1254 MarkRange( aRange
, false ); // aRange was modified in FillAuto
1255 pDocSh
->UpdateOle(&GetViewData());
1258 bool bDoAutoSpell
= pDocSh
->GetDocument().GetDocOptions().IsAutoSpell();
1260 CopyAutoSpellData(eDir
, nStartCol
, nStartRow
, nEndCol
, nEndRow
, nCount
);
1262 if (ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
))
1264 ScRangeList aChangeRanges
;
1265 ScRange
aChangeRange( aRange
);
1268 case FILL_TO_BOTTOM
:
1269 aChangeRange
.aStart
.SetRow( aSourceRange
.aEnd
.Row() + 1 );
1272 aChangeRange
.aEnd
.SetRow( aSourceRange
.aStart
.Row() - 1 );
1275 aChangeRange
.aStart
.SetCol( aSourceRange
.aEnd
.Col() + 1 );
1278 aChangeRange
.aEnd
.SetCol( aSourceRange
.aStart
.Col() - 1 );
1283 aChangeRanges
.Append( aChangeRange
);
1284 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
);
1289 void ScViewFunc::CopyAutoSpellData( FillDir eDir
, SCCOL nStartCol
, SCROW nStartRow
,
1290 SCCOL nEndCol
, SCROW nEndRow
, sal_uLong nCount
)
1292 ScGridWindow
* pWin
= this->GetActiveWin();
1293 if ( pWin
->InsideVisibleRange(nStartCol
, nStartRow
) && pWin
->InsideVisibleRange(nEndCol
, nEndRow
) )
1295 if ( nCount
== ::std::numeric_limits
<sal_uLong
>::max() )
1299 case FILL_TO_BOTTOM
:
1300 for ( SCCOL nColItr
= nStartCol
; nColItr
<= nEndCol
; ++nColItr
)
1302 const std::vector
<editeng::MisspellRanges
>* pRanges
= pWin
->GetAutoSpellData(nColItr
, nStartRow
);
1305 for ( SCROW nRowItr
= nStartRow
+ 1; nRowItr
<= nEndRow
; ++nRowItr
)
1306 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1310 for ( SCCOL nColItr
= nStartCol
; nColItr
<= nEndCol
; ++nColItr
)
1312 const std::vector
<editeng::MisspellRanges
>* pRanges
= pWin
->GetAutoSpellData(nColItr
, nEndRow
);
1315 for ( SCROW nRowItr
= nEndRow
- 1; nRowItr
>= nStartRow
; --nRowItr
)
1316 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1320 for ( SCROW nRowItr
= nStartRow
; nRowItr
<= nEndRow
; ++nRowItr
)
1322 const std::vector
<editeng::MisspellRanges
>* pRanges
= pWin
->GetAutoSpellData(nStartCol
, nRowItr
);
1325 for ( SCCOL nColItr
= nStartCol
+ 1; nColItr
<= nEndCol
; ++nColItr
)
1326 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1330 for ( SCROW nRowItr
= nStartRow
; nRowItr
<= nEndRow
; ++nRowItr
)
1332 const std::vector
<editeng::MisspellRanges
>* pRanges
= pWin
->GetAutoSpellData(nEndCol
, nRowItr
);
1335 for ( SCCOL nColItr
= nEndCol
- 1; nColItr
>= nStartCol
; --nColItr
)
1336 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1343 typedef const std::vector
<editeng::MisspellRanges
>* MisspellRangesType
;
1344 SCROW nRowRepeatSize
= (nEndRow
- nStartRow
+ 1);
1345 SCCOL nColRepeatSize
= (nEndCol
- nStartCol
+ 1);
1348 std::vector
<std::vector
<MisspellRangesType
>> aSourceSpellRanges(nRowRepeatSize
, std::vector
<MisspellRangesType
>(nColRepeatSize
));
1350 for ( SCROW nRowIdx
= 0; nRowIdx
< nRowRepeatSize
; ++nRowIdx
)
1351 for ( SCROW nColIdx
= 0; nColIdx
< nColRepeatSize
; ++nColIdx
)
1352 aSourceSpellRanges
[nRowIdx
][nColIdx
] = pWin
->GetAutoSpellData( nStartCol
+ nColIdx
, nStartRow
+ nRowIdx
);
1356 case FILL_TO_BOTTOM
:
1357 nTillRow
= nEndRow
+ nCount
;
1358 for ( SCCOL nColItr
= nStartCol
; nColItr
<= nEndCol
; ++nColItr
)
1360 for ( SCROW nRowItr
= nEndRow
+ 1; nRowItr
<= nTillRow
; ++nRowItr
)
1362 size_t nSourceRowIdx
= ( ( nRowItr
- nEndRow
- 1 ) % nRowRepeatSize
);
1363 MisspellRangesType pRanges
= aSourceSpellRanges
[nSourceRowIdx
][nColItr
- nStartCol
];
1366 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1372 nTillRow
= nStartRow
- nCount
;
1373 for ( SCCOL nColItr
= nStartCol
; nColItr
<= nEndCol
; ++nColItr
)
1375 for ( SCROW nRowItr
= nStartRow
- 1; nRowItr
>= nTillRow
; --nRowItr
)
1377 size_t nSourceRowIdx
= nRowRepeatSize
- 1 - ( ( nStartRow
- 1 - nRowItr
) % nRowRepeatSize
);
1378 MisspellRangesType pRanges
= aSourceSpellRanges
[nSourceRowIdx
][nColItr
- nStartCol
];
1381 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1387 nTillCol
= nEndCol
+ nCount
;
1388 for ( SCCOL nColItr
= nEndCol
+ 1; nColItr
<= nTillCol
; ++nColItr
)
1390 size_t nSourceColIdx
= ( ( nColItr
- nEndCol
- 1 ) % nColRepeatSize
);
1391 for ( SCROW nRowItr
= nStartRow
; nRowItr
<= nEndRow
; ++nRowItr
)
1393 MisspellRangesType pRanges
= aSourceSpellRanges
[nRowItr
- nStartRow
][nSourceColIdx
];
1396 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1402 nTillCol
= nStartCol
- nCount
;
1403 for ( SCCOL nColItr
= nStartCol
- 1; nColItr
>= nTillCol
; --nColItr
)
1405 size_t nSourceColIdx
= nColRepeatSize
- 1 - ( ( nStartCol
- 1 - nColItr
) % nColRepeatSize
);
1406 for ( SCROW nRowItr
= nStartRow
; nRowItr
<= nEndRow
; ++nRowItr
)
1408 MisspellRangesType pRanges
= aSourceSpellRanges
[nRowItr
- nStartRow
][nSourceColIdx
];
1411 pWin
->SetAutoSpellData(nColItr
, nRowItr
, pRanges
);
1418 pWin
->ResetAutoSpell();
1422 void ScViewFunc::FillTab( InsertDeleteFlags nFlags
, sal_uInt16 nFunction
, bool bSkipEmpty
, bool bAsLink
)
1424 //! allow source sheet to be protected
1425 ScEditableTester
aTester( this );
1426 if (!aTester
.IsEditable())
1428 ErrorMessage(aTester
.GetMessageId());
1432 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1433 ScDocument
& rDoc
= pDocSh
->GetDocument();
1434 ScMarkData
& rMark
= GetViewData().GetMarkData();
1435 SCTAB nTab
= GetViewData().GetTabNo();
1436 bool bUndo(rDoc
.IsUndoEnabled());
1439 rMark
.MarkToSimple();
1440 bool bMulti
= rMark
.IsMultiMarked();
1442 rMark
.GetMultiMarkArea( aMarkRange
);
1443 else if (rMark
.IsMarked())
1444 rMark
.GetMarkArea( aMarkRange
);
1446 aMarkRange
= ScRange( GetViewData().GetCurX(), GetViewData().GetCurY(), nTab
);
1448 ScDocument
* pUndoDoc
= NULL
;
1452 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1453 pUndoDoc
->InitUndo( &rDoc
, nTab
, nTab
);
1455 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1456 for (; itr
!= itrEnd
; ++itr
)
1460 pUndoDoc
->AddUndoTab( i
, i
);
1461 aMarkRange
.aStart
.SetTab( i
);
1462 aMarkRange
.aEnd
.SetTab( i
);
1463 rDoc
.CopyToDocument( aMarkRange
, IDF_ALL
, bMulti
, pUndoDoc
);
1468 rDoc
.FillTabMarked( nTab
, rMark
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
1471 aMarkRange
.aStart
.SetTab( nTab
);
1472 aMarkRange
.aEnd
.SetTab( nTab
);
1473 rDoc
.FillTab( aMarkRange
, rMark
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
1477 { //! for ChangeTrack not until the end
1478 pDocSh
->GetUndoManager()->AddUndoAction(
1479 new ScUndoFillTable( pDocSh
, rMark
,
1480 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nTab
,
1481 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(), nTab
,
1482 pUndoDoc
, bMulti
, nTab
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
) );
1485 pDocSh
->PostPaintGridAll();
1486 pDocSh
->PostDataChanged();
1489 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1491 Extends a current selection down to the last non-empty cell of an adjacent
1492 column when the lower-right corner of the selection is double-clicked. It
1493 uses a left-adjoining non-empty column as a guide if such is available,
1494 otherwise a right-adjoining non-empty column is used.
1496 @author Kohei Yoshida (kohei@openoffice.org)
1498 @return No return value
1502 void ScViewFunc::FillCrossDblClick()
1505 GetViewData().GetSimpleArea( aRange
);
1508 SCTAB nTab
= GetViewData().GetCurPos().Tab();
1509 SCCOL nStartX
= aRange
.aStart
.Col();
1510 SCROW nStartY
= aRange
.aStart
.Row();
1511 SCCOL nEndX
= aRange
.aEnd
.Col();
1512 SCROW nEndY
= aRange
.aEnd
.Row();
1514 ScDocument
* pDoc
= GetViewData().GetDocument();
1516 // Make sure the selection is not empty
1517 if ( pDoc
->IsBlockEmpty( nTab
, nStartX
, nStartY
, nEndX
, nEndY
) )
1520 if ( nEndY
< MAXROW
)
1524 SCCOL nMovX
= nStartX
- 1;
1525 SCROW nMovY
= nStartY
;
1527 if ( pDoc
->HasData( nMovX
, nStartY
, nTab
) &&
1528 pDoc
->HasData( nMovX
, nStartY
+ 1, nTab
) )
1530 pDoc
->FindAreaPos( nMovX
, nMovY
, nTab
, SC_MOVE_DOWN
);
1532 if ( nMovY
> nEndY
)
1534 FillAuto( FILL_TO_BOTTOM
, nStartX
, nStartY
, nEndX
, nEndY
,
1541 if ( nEndX
< MAXCOL
)
1543 SCCOL nMovX
= nEndX
+ 1;
1544 SCROW nMovY
= nStartY
;
1546 if ( pDoc
->HasData( nMovX
, nStartY
, nTab
) &&
1547 pDoc
->HasData( nMovX
, nStartY
+ 1, nTab
) )
1549 pDoc
->FindAreaPos( nMovX
, nMovY
, nTab
, SC_MOVE_DOWN
);
1551 if ( nMovY
> nEndY
)
1553 FillAuto( FILL_TO_BOTTOM
, nStartX
, nStartY
, nEndX
, nEndY
,
1562 void ScViewFunc::ConvertFormulaToValue()
1565 GetViewData().GetSimpleArea(aRange
);
1568 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1569 pDocSh
->GetDocFunc().ConvertFormulaToValue(aRange
, true, true);
1570 pDocSh
->PostPaint(aRange
, PAINT_GRID
);
1573 void ScViewFunc::TransliterateText( sal_Int32 nType
)
1575 ScMarkData aFuncMark
= GetViewData().GetMarkData();
1576 if ( !aFuncMark
.IsMarked() && !aFuncMark
.IsMultiMarked() )
1578 // no selection -> use cursor position
1580 ScAddress
aCursor( GetViewData().GetCurX(), GetViewData().GetCurY(), GetViewData().GetTabNo() );
1581 aFuncMark
.SetMarkArea( ScRange( aCursor
) );
1584 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().
1585 TransliterateText( aFuncMark
, nType
, true, false );
1588 GetViewData().GetViewShell()->UpdateInputHandler();
1594 ScAutoFormatData
* ScViewFunc::CreateAutoFormatData()
1596 ScAutoFormatData
* pData
= NULL
;
1603 if (GetViewData().GetSimpleArea(nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
) == SC_MARK_SIMPLE
)
1605 if ( nEndCol
-nStartCol
>= 3 && nEndRow
-nStartRow
>= 3 )
1607 ScDocument
* pDoc
= GetViewData().GetDocument();
1608 pData
= new ScAutoFormatData
;
1609 pDoc
->GetAutoFormatData( nStartTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
, *pData
);
1615 void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo
, bool bRecord
)
1618 if (GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1620 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1621 ScMarkData
& rMark
= GetViewData().GetMarkData();
1623 bool bSuccess
= pDocSh
->GetDocFunc().AutoFormat( aRange
, &rMark
, nFormatNo
, bRecord
, false );
1625 pDocSh
->UpdateOle(&GetViewData());
1628 ErrorMessage(STR_NOMULTISELECT
);
1631 // Suchen & Ersetzen
1633 bool ScViewFunc::SearchAndReplace( const SvxSearchItem
* pSearchItem
,
1634 bool bAddUndo
, bool bIsApi
)
1636 SvxSearchDialogWrapper::SetSearchLabel(SL_Empty
);
1637 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1638 ScDocument
& rDoc
= pDocSh
->GetDocument();
1639 ScMarkData
& rMark
= GetViewData().GetMarkData();
1640 if (bAddUndo
&& !rDoc
.IsUndoEnabled())
1643 if ( !rMark
.IsMarked() && !rMark
.IsMultiMarked() && (pSearchItem
->HasStartPoint()) )
1645 // No selection -> but we have a start point (top left corner of the
1646 // current view), start searching from there, not from the current
1651 int nPixelX
= pSearchItem
->GetStartPointX() * GetViewData().GetPPTX();
1652 int nPixelY
= pSearchItem
->GetStartPointY() * GetViewData().GetPPTY();
1654 GetViewData().GetPosFromPixel(nPixelX
, nPixelY
, GetViewData().GetActivePart(), nPosX
, nPosY
);
1656 AlignToCursor( nPosX
, nPosY
, SC_FOLLOW_JUMP
);
1657 SetCursor( nPosX
, nPosY
, true );
1660 SCCOL nCol
, nOldCol
;
1661 SCROW nRow
, nOldRow
;
1662 SCTAB nTab
, nOldTab
;
1663 nCol
= nOldCol
= GetViewData().GetCurX();
1664 nRow
= nOldRow
= GetViewData().GetCurY();
1665 nTab
= nOldTab
= GetViewData().GetTabNo();
1667 SvxSearchCmd nCommand
= pSearchItem
->GetCommand();
1668 bool bAllTables
= pSearchItem
->IsAllTables();
1669 std::set
<SCTAB
> aOldSelectedTables
;
1670 SCTAB nLastTab
= rDoc
.GetTableCount() - 1;
1671 SCTAB nStartTab
, nEndTab
;
1676 std::set
<SCTAB
> aTmp(rMark
.begin(), rMark
.end());
1677 aOldSelectedTables
.swap(aTmp
);
1680 { //! at least one is always selected
1681 nStartTab
= rMark
.GetFirstSelected();
1682 nEndTab
= rMark
.GetLastSelected();
1685 if ( nCommand
== SvxSearchCmd::FIND
1686 || nCommand
== SvxSearchCmd::FIND_ALL
)
1689 //! account for bAttrib during Undo !!!
1691 std::unique_ptr
<ScDocument
> pUndoDoc
;
1692 std::unique_ptr
<ScMarkData
> pUndoMark
;
1696 pUndoMark
.reset(new ScMarkData(rMark
)); // Mark is being modified
1697 if ( nCommand
== SvxSearchCmd::REPLACE_ALL
)
1699 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1700 pUndoDoc
->InitUndo( &rDoc
, nStartTab
, nEndTab
);
1705 { //! select all, after pUndoMark has been created
1706 for ( SCTAB j
= nStartTab
; j
<= nEndTab
; j
++ )
1708 rMark
.SelectTable( j
, true );
1712 DoneBlockMode(true); // don't delete mark
1715 // If search starts at the beginning don't ask again whether it shall start at the beginning
1717 if ( nCol
== 0 && nRow
== 0 && nTab
== nStartTab
&& !pSearchItem
->GetBackward() )
1720 bool bFound
= false;
1723 GetFrameWin()->EnterWait();
1724 ScRangeList aMatchedRanges
;
1725 if (rDoc
.SearchAndReplace(*pSearchItem
, nCol
, nRow
, nTab
, rMark
, aMatchedRanges
, aUndoStr
, pUndoDoc
.get()))
1731 GetViewData().GetDocShell()->GetUndoManager()->AddUndoAction(
1732 new ScUndoReplace( GetViewData().GetDocShell(), *pUndoMark
,
1734 aUndoStr
, pUndoDoc
.release(), pSearchItem
) );
1737 if (nCommand
== SvxSearchCmd::FIND_ALL
|| nCommand
== SvxSearchCmd::REPLACE_ALL
)
1739 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1742 pViewFrm
->ShowChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId(), true);
1743 SfxChildWindow
* pWnd
= pViewFrm
->GetChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId());
1746 sc::SearchResultsDlg
* pDlg
= static_cast<sc::SearchResultsDlg
*>(pWnd
->GetWindow());
1748 pDlg
->FillResults(&rDoc
, aMatchedRanges
);
1753 for (size_t i
= 0, n
= aMatchedRanges
.size(); i
< n
; ++i
)
1755 const ScRange
& r
= *aMatchedRanges
[i
];
1756 if (r
.aStart
.Tab() == nTab
)
1757 rMark
.SetMultiMarkArea(r
);
1761 break; // break 'while (TRUE)'
1763 else if ( bFirst
&& (nCommand
== SvxSearchCmd::FIND
||
1764 nCommand
== SvxSearchCmd::REPLACE
) )
1767 GetFrameWin()->LeaveWait();
1770 if ( nStartTab
== nEndTab
)
1771 SvxSearchDialogWrapper::SetSearchLabel(SL_EndSheet
);
1773 SvxSearchDialogWrapper::SetSearchLabel(SL_End
);
1775 ScDocument::GetSearchAndReplaceStart( *pSearchItem
, nCol
, nRow
);
1776 if (pSearchItem
->GetBackward())
1783 break; // break 'while (TRUE)'
1786 else // nothing found
1788 if ( nCommand
== SvxSearchCmd::FIND_ALL
|| nCommand
== SvxSearchCmd::REPLACE_ALL
)
1790 pDocSh
->PostPaintGridAll(); // Mark
1793 GetFrameWin()->LeaveWait();
1796 rDoc
.GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SEARCH_NOT_FOUND
,
1797 pSearchItem
->GetSearchString().toUtf8().getStr());
1798 SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound
);
1801 break; // break 'while (TRUE)'
1805 if (!aOldSelectedTables
.empty())
1807 // restore originally selected table
1808 for (SCTAB i
= 0; i
<= nEndTab
; ++i
)
1809 rMark
.SelectTable(i
, false);
1811 std::set
<SCTAB
>::const_iterator itr
= aOldSelectedTables
.begin(), itrEnd
= aOldSelectedTables
.end();
1812 for (; itr
!= itrEnd
; ++itr
)
1813 rMark
.SelectTable(*itr
, true);
1816 { // if a table is selected as a "match" it remains selected.
1817 rMark
.SelectTable( nTab
, true );
1818 // It's a swap if only one table was selected before
1819 //! otherwise now one table more might be selected
1820 if ( aOldSelectedTables
.size() == 1 && nTab
!= nOldTab
)
1821 rMark
.SelectTable( nOldTab
, false );
1829 if ( nTab
!= GetViewData().GetTabNo() )
1832 // if nothing is marked, DoneBlockMode, then marking can start
1833 // directly from this place via Shift-Cursor
1834 if (!rMark
.IsMarked() && !rMark
.IsMultiMarked())
1835 DoneBlockMode(true);
1837 AlignToCursor( nCol
, nRow
, SC_FOLLOW_JUMP
);
1838 SetCursor( nCol
, nRow
, true );
1840 if (rDoc
.GetDrawLayer()->isTiledRendering())
1842 Point aCurPos
= GetViewData().GetScrPos(nCol
, nRow
, GetViewData().GetActivePart());
1844 // just update the cell selection
1845 ScGridWindow
* pGridWindow
= GetViewData().GetActiveWin();
1848 // move the cell selection handles
1849 pGridWindow
->SetCellSelectionPixel(LOK_SETTEXTSELECTION_RESET
, aCurPos
.X(), aCurPos
.Y());
1850 pGridWindow
->SetCellSelectionPixel(LOK_SETTEXTSELECTION_START
, aCurPos
.X(), aCurPos
.Y());
1851 pGridWindow
->SetCellSelectionPixel(LOK_SETTEXTSELECTION_END
, aCurPos
.X(), aCurPos
.Y());
1855 if ( nCommand
== SvxSearchCmd::REPLACE
1856 || nCommand
== SvxSearchCmd::REPLACE_ALL
)
1858 if ( nCommand
== SvxSearchCmd::REPLACE
)
1860 pDocSh
->PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PAINT_GRID
);
1862 // jump to next cell if we replaced everything in the cell
1863 // where the cursor was positioned (but avoid switching tabs)
1864 if ( nCol
== nOldCol
&& nRow
== nOldRow
&& nTab
== nOldTab
)
1866 SvxSearchItem aSearchItem
= ScGlobal::GetSearchItem();
1867 aSearchItem
.SetCommand(SvxSearchCmd::FIND
);
1868 aSearchItem
.SetWhich(SID_SEARCH_ITEM
);
1870 ScRangeList aMatchedRanges
;
1871 ScTable::UpdateSearchItemAddressForReplace( aSearchItem
, nCol
, nRow
);
1872 if ( rDoc
.SearchAndReplace( aSearchItem
, nCol
, nRow
, nTab
, rMark
, aMatchedRanges
, aUndoStr
, NULL
) &&
1873 ( nTab
== nOldTab
) &&
1874 ( nCol
!= nOldCol
|| nRow
!= nOldRow
) )
1876 SetCursor( nCol
, nRow
, true );
1881 pDocSh
->PostPaintGridAll();
1882 pDocSh
->SetDocumentModified();
1884 else if ( nCommand
== SvxSearchCmd::FIND_ALL
)
1885 pDocSh
->PostPaintGridAll(); // mark
1886 GetFrameWin()->LeaveWait();
1893 void ScViewFunc::Solve( const ScSolveParam
& rParam
)
1895 ScDocument
* pDoc
= GetViewData().GetDocument();
1899 SCCOL nDestCol
= rParam
.aRefVariableCell
.Col();
1900 SCROW nDestRow
= rParam
.aRefVariableCell
.Row();
1901 SCTAB nDestTab
= rParam
.aRefVariableCell
.Tab();
1903 ScEditableTester
aTester( pDoc
, nDestTab
, nDestCol
,nDestRow
, nDestCol
,nDestRow
);
1904 if (!aTester
.IsEditable())
1906 ErrorMessage(aTester
.GetMessageId());
1910 OUString aTargetValStr
;
1911 if ( rParam
.pStrTargetVal
!= NULL
)
1912 aTargetValStr
= *(rParam
.pStrTargetVal
);
1916 double nSolveResult
;
1918 GetFrameWin()->EnterWait();
1922 rParam
.aRefFormulaCell
.Col(),
1923 rParam
.aRefFormulaCell
.Row(),
1924 rParam
.aRefFormulaCell
.Tab(),
1925 nDestCol
, nDestRow
, nDestTab
,
1929 GetFrameWin()->LeaveWait();
1931 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
1932 sal_uLong nFormat
= 0;
1933 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nDestCol
, nDestRow
, nDestTab
);
1935 nFormat
= pPattern
->GetNumberFormat( pFormatter
);
1937 pFormatter
->GetOutputString( nSolveResult
, nFormat
, aResStr
, &p
);
1941 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_0
);
1943 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_1
);
1947 aMsgStr
= ScGlobal::GetRscString( STR_MSSG_SOLVE_2
);
1948 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_3
);
1949 aMsgStr
+= aResStr
;
1950 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_4
);
1953 ScopedVclPtrInstance
<MessBox
> aBox( GetViewData().GetDialogParent(),
1954 WinBits(WB_YES_NO
| WB_DEF_NO
),
1955 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0
), aMsgStr
);
1956 sal_uInt16 nRetVal
= aBox
->Execute();
1958 if ( RET_YES
== nRetVal
)
1959 EnterValue( nDestCol
, nDestRow
, nDestTab
, nSolveResult
);
1961 GetViewData().GetViewShell()->UpdateInputHandler( true );
1967 void ScViewFunc::TabOp( const ScTabOpParam
& rParam
, bool bRecord
)
1970 if (GetViewData().GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1972 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1973 ScMarkData
& rMark
= GetViewData().GetMarkData();
1974 pDocSh
->GetDocFunc().TabOp( aRange
, &rMark
, rParam
, bRecord
, false );
1977 ErrorMessage(STR_NOMULTISELECT
);
1980 void ScViewFunc::MakeScenario( const OUString
& rName
, const OUString
& rComment
,
1981 const Color
& rColor
, sal_uInt16 nFlags
)
1983 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
1984 ScMarkData
& rMark
= GetViewData().GetMarkData();
1985 SCTAB nTab
= GetViewData().GetTabNo();
1987 SCTAB nNewTab
= pDocSh
->MakeScenario( nTab
, rName
, rComment
, rColor
, nFlags
, rMark
);
1988 if (nFlags
& SC_SCENARIO_COPYALL
)
1989 SetTabNo( nNewTab
, true ); // SC_SCENARIO_COPYALL -> visible
1992 SfxBindings
& rBindings
= GetViewData().GetBindings();
1993 rBindings
.Invalidate( SID_STATUS_DOCPOS
); // Statusbar
1994 rBindings
.Invalidate( SID_ROWCOL_SELCOUNT
); // Statusbar
1995 rBindings
.Invalidate( SID_TABLES_COUNT
);
1996 rBindings
.Invalidate( SID_SELECT_SCENARIO
);
1997 rBindings
.Invalidate( FID_TABLE_SHOW
);
2001 void ScViewFunc::ExtendScenario()
2003 ScEditableTester
aTester( this );
2004 if (!aTester
.IsEditable())
2006 ErrorMessage(aTester
.GetMessageId());
2010 // Undo: apply attributes
2012 ScDocument
* pDoc
= GetViewData().GetDocument();
2013 ScPatternAttr
aPattern( pDoc
->GetPool() );
2014 aPattern
.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO
) );
2015 aPattern
.GetItemSet().Put( ScProtectionAttr( true ) );
2016 ApplySelectionPattern(aPattern
);
2019 void ScViewFunc::UseScenario( const OUString
& rName
)
2021 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2022 SCTAB nTab
= GetViewData().GetTabNo();
2026 pDocSh
->UseScenario( nTab
, rName
);
2031 bool ScViewFunc::InsertTable( const OUString
& rName
, SCTAB nTab
, bool bRecord
)
2033 // Order Tabl/Name is inverted for DocFunc
2034 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().
2035 InsertTable( nTab
, rName
, bRecord
, false );
2037 SetTabNo( nTab
, true );
2044 bool ScViewFunc::InsertTables(std::vector
<OUString
>& aNames
, SCTAB nTab
,
2045 SCTAB nCount
, bool bRecord
)
2047 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2048 ScDocument
& rDoc
= pDocSh
->GetDocument();
2049 if (bRecord
&& !rDoc
.IsUndoEnabled())
2052 WaitObject
aWait( GetFrameWin() );
2056 rDoc
.BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2063 rDoc
.CreateValidTabNames(aNames
, nCount
);
2065 if (rDoc
.InsertTabs(nTab
, aNames
, false))
2067 pDocSh
->Broadcast( ScTablesHint( SC_TABS_INSERTED
, nTab
, nCount
) );
2074 pDocSh
->GetUndoManager()->AddUndoAction(
2075 new ScUndoInsertTables( pDocSh
, nTab
, aNames
));
2079 SetTabNo( nTab
, true );
2080 pDocSh
->PostPaintExtras();
2081 pDocSh
->SetDocumentModified();
2082 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2091 bool ScViewFunc::AppendTable( const OUString
& rName
, bool bRecord
)
2093 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2094 ScDocument
& rDoc
= pDocSh
->GetDocument();
2095 if (bRecord
&& !rDoc
.IsUndoEnabled())
2098 WaitObject
aWait( GetFrameWin() );
2101 rDoc
.BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
2103 if (rDoc
.InsertTab( SC_TAB_APPEND
, rName
))
2105 SCTAB nTab
= rDoc
.GetTableCount()-1;
2107 pDocSh
->GetUndoManager()->AddUndoAction(
2108 new ScUndoInsertTab( pDocSh
, nTab
, true, rName
));
2109 GetViewData().InsertTab( nTab
);
2110 SetTabNo( nTab
, true );
2111 pDocSh
->PostPaintExtras();
2112 pDocSh
->SetDocumentModified();
2113 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2122 bool ScViewFunc::DeleteTable( SCTAB nTab
, bool bRecord
)
2124 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2125 ScDocument
& rDoc
= pDocSh
->GetDocument();
2127 bool bSuccess
= pDocSh
->GetDocFunc().DeleteTable( nTab
, bRecord
, false );
2130 SCTAB nNewTab
= nTab
;
2131 if ( nNewTab
>= rDoc
.GetTableCount() )
2133 SetTabNo( nNewTab
, true );
2138 //only use this method for undo for now, all sheets must be connected
2139 //this method doesn't support undo for now, merge it when it with the other method later
2140 bool ScViewFunc::DeleteTables( const SCTAB nTab
, SCTAB nSheets
)
2142 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2143 ScDocument
& rDoc
= pDocSh
->GetDocument();
2144 bool bVbaEnabled
= rDoc
.IsInVBAMode();
2145 SCTAB nNewTab
= nTab
;
2146 WaitObject
aWait( GetFrameWin() );
2148 while ( nNewTab
> 0 && !rDoc
.IsVisible( nNewTab
) )
2151 if (rDoc
.DeleteTabs(nTab
, nSheets
))
2155 for (SCTAB aTab
= 0; aTab
< nSheets
; ++aTab
)
2158 bool bHasCodeName
= rDoc
.GetCodeName( nTab
+ aTab
, sCodeName
);
2160 VBA_DeleteModule( *pDocSh
, sCodeName
);
2164 pDocSh
->Broadcast( ScTablesHint( SC_TABS_DELETED
, nTab
, nSheets
) );
2165 if ( nNewTab
>= rDoc
.GetTableCount() )
2166 nNewTab
= rDoc
.GetTableCount() - 1;
2167 SetTabNo( nNewTab
, true );
2169 pDocSh
->PostPaintExtras();
2170 pDocSh
->SetDocumentModified();
2172 SfxApplication
* pSfxApp
= SfxGetpApp(); // Navigator
2173 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2174 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
2175 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2181 bool ScViewFunc::DeleteTables(const vector
<SCTAB
> &TheTabs
, bool bRecord
)
2183 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2184 ScDocument
& rDoc
= pDocSh
->GetDocument();
2185 bool bVbaEnabled
= rDoc
.IsInVBAMode();
2186 SCTAB nNewTab
= TheTabs
.front();
2187 WaitObject
aWait( GetFrameWin() );
2188 if (bRecord
&& !rDoc
.IsUndoEnabled())
2193 while ( nNewTab
> 0 && !rDoc
.IsVisible( nNewTab
) )
2196 bool bWasLinked
= false;
2197 ScDocument
* pUndoDoc
= NULL
;
2198 ScRefUndoData
* pUndoData
= NULL
;
2201 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2202 SCTAB nCount
= rDoc
.GetTableCount();
2205 for(unsigned int i
=0; i
<TheTabs
.size(); ++i
)
2207 SCTAB nTab
= TheTabs
[i
];
2209 pUndoDoc
->InitUndo( &rDoc
, nTab
,nTab
, true,true ); // incl. column/fow flags
2211 pUndoDoc
->AddUndoTab( nTab
,nTab
, true,true ); // incl. column/fow flags
2213 rDoc
.CopyToDocument(0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_ALL
,false, pUndoDoc
);
2214 rDoc
.GetName( nTab
, aOldName
);
2215 pUndoDoc
->RenameTab( nTab
, aOldName
, false );
2216 if (rDoc
.IsLinked(nTab
))
2219 pUndoDoc
->SetLink( nTab
, rDoc
.GetLinkMode(nTab
), rDoc
.GetLinkDoc(nTab
),
2220 rDoc
.GetLinkFlt(nTab
), rDoc
.GetLinkOpt(nTab
),
2221 rDoc
.GetLinkTab(nTab
),
2222 rDoc
.GetLinkRefreshDelay(nTab
) );
2224 if ( rDoc
.IsScenario(nTab
) )
2226 pUndoDoc
->SetScenario( nTab
, true );
2229 sal_uInt16 nScenFlags
;
2230 rDoc
.GetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2231 pUndoDoc
->SetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2232 bool bActive
= rDoc
.IsActiveScenario( nTab
);
2233 pUndoDoc
->SetActiveScenario( nTab
, bActive
);
2235 pUndoDoc
->SetVisible( nTab
, rDoc
.IsVisible( nTab
) );
2236 pUndoDoc
->SetTabBgColor( nTab
, rDoc
.GetTabBgColor(nTab
) );
2237 pUndoDoc
->SetSheetEvents( nTab
, rDoc
.GetSheetEvents( nTab
) );
2238 pUndoDoc
->SetLayoutRTL( nTab
, rDoc
.IsLayoutRTL( nTab
) );
2240 if ( rDoc
.IsTabProtected( nTab
) )
2241 pUndoDoc
->SetTabProtection(nTab
, rDoc
.GetTabProtection(nTab
));
2243 // Drawing-Layer is responsible for its Undo !!!
2244 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2247 pUndoDoc
->AddUndoTab( 0, nCount
-1 ); // all Tabs for references
2249 rDoc
.BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2251 pUndoData
= new ScRefUndoData( &rDoc
);
2254 bool bDelDone
= false;
2256 for(int i
=TheTabs
.size()-1; i
>=0; --i
)
2259 bool bHasCodeName
= rDoc
.GetCodeName( TheTabs
[i
], sCodeName
);
2260 if (rDoc
.DeleteTab(TheTabs
[i
]))
2267 VBA_DeleteModule( *pDocSh
, sCodeName
);
2270 pDocSh
->Broadcast( ScTablesHint( SC_TAB_DELETED
, TheTabs
[i
] ) );
2275 pDocSh
->GetUndoManager()->AddUndoAction(
2276 new ScUndoDeleteTab( GetViewData().GetDocShell(), TheTabs
,
2277 pUndoDoc
, pUndoData
));
2282 if ( nNewTab
>= rDoc
.GetTableCount() )
2283 nNewTab
= rDoc
.GetTableCount() - 1;
2285 SetTabNo( nNewTab
, true );
2289 pDocSh
->UpdateLinks(); // update Link-Manager
2290 GetViewData().GetBindings().Invalidate(SID_LINKS
);
2293 pDocSh
->PostPaintExtras();
2294 pDocSh
->SetDocumentModified();
2296 SfxApplication
* pSfxApp
= SfxGetpApp(); // Navigator
2297 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2298 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
2299 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2309 bool ScViewFunc::RenameTable( const OUString
& rName
, SCTAB nTab
)
2311 // order Table/Name is inverted for DocFunc
2312 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().
2313 RenameTable( nTab
, rName
, true, false );
2316 // the table name might be part of a formula
2317 GetViewData().GetViewShell()->UpdateInputHandler();
2322 bool ScViewFunc::SetTabBgColor( const Color
& rColor
, SCTAB nTab
)
2324 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().SetTabBgColor( nTab
, rColor
, true, false );
2327 GetViewData().GetViewShell()->UpdateInputHandler();
2332 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List
& rUndoSetTabBgColorInfoList
)
2334 bool bSuccess
= GetViewData().GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList
, true, false );
2337 GetViewData().GetViewShell()->UpdateInputHandler();
2342 void ScViewFunc::InsertAreaLink( const OUString
& rFile
,
2343 const OUString
& rFilter
, const OUString
& rOptions
,
2344 const OUString
& rSource
, sal_uLong nRefresh
)
2346 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2347 SCCOL nPosX
= GetViewData().GetCurX();
2348 SCROW nPosY
= GetViewData().GetCurY();
2349 SCTAB nTab
= GetViewData().GetTabNo();
2350 ScAddress
aPos( nPosX
, nPosY
, nTab
);
2352 pDocSh
->GetDocFunc().InsertAreaLink( rFile
, rFilter
, rOptions
, rSource
, aPos
, nRefresh
, false, false );
2355 void ScViewFunc::InsertTableLink( const OUString
& rFile
,
2356 const OUString
& rFilter
, const OUString
& rOptions
,
2357 const OUString
& rTabName
)
2359 OUString aFilterName
= rFilter
;
2360 OUString aOpt
= rOptions
;
2361 OUString aURL
= rFile
;
2362 ScDocumentLoader
aLoader( aURL
, aFilterName
, aOpt
);
2363 if (!aLoader
.IsError())
2365 ScDocShell
* pSrcSh
= aLoader
.GetDocShell();
2366 ScDocument
& rSrcDoc
= pSrcSh
->GetDocument();
2367 SCTAB nTab
= MAXTAB
+1;
2368 if (rTabName
.isEmpty()) // no name given -> first table
2373 SCTAB nCount
= rSrcDoc
.GetTableCount();
2374 for (SCTAB i
=0; i
<nCount
; i
++)
2376 rSrcDoc
.GetName( i
, aTemp
);
2377 if ( aTemp
.equals(rTabName
) )
2382 if ( nTab
<= MAXTAB
)
2383 ImportTables( pSrcSh
, 1, &nTab
, true,
2384 GetViewData().GetTabNo() );
2388 // Copy/link tables from another document
2390 void ScViewFunc::ImportTables( ScDocShell
* pSrcShell
,
2391 SCTAB nCount
, const SCTAB
* pSrcTabs
, bool bLink
,SCTAB nTab
)
2393 ScDocument
& rSrcDoc
= pSrcShell
->GetDocument();
2395 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2396 ScDocument
& rDoc
= pDocSh
->GetDocument();
2397 bool bUndo(rDoc
.IsUndoEnabled());
2399 bool bError
= false;
2403 if (rSrcDoc
.GetDrawLayer())
2404 pDocSh
->MakeDrawLayer();
2407 rDoc
.BeginDrawUndo(); // drawing layer must do its own undo actions
2409 SCTAB nInsCount
= 0;
2411 for( i
=0; i
<nCount
; i
++ )
2412 { // insert sheets first and update all references
2414 rSrcDoc
.GetName( pSrcTabs
[i
], aName
);
2415 rDoc
.CreateValidTabName( aName
);
2416 if ( !rDoc
.InsertTab( nTab
+i
, aName
) )
2418 bError
= true; // total error
2423 for (i
=0; i
<nCount
&& !bError
; i
++)
2425 SCTAB nSrcTab
= pSrcTabs
[i
];
2426 SCTAB nDestTab1
=nTab
+i
;
2427 sal_uLong nErrVal
= pDocSh
->TransferTab( *pSrcShell
, nSrcTab
, nDestTab1
,
2428 false, false ); // no insert
2432 case 0: // internal error or full of errors
2442 bRefs
= bName
= true;
2450 sfx2::LinkManager
* pLinkManager
= rDoc
.GetLinkManager();
2452 SfxMedium
* pMed
= pSrcShell
->GetMedium();
2453 OUString aFileName
= pMed
->GetName();
2454 OUString aFilterName
;
2455 if (pMed
->GetFilter())
2456 aFilterName
= pMed
->GetFilter()->GetFilterName();
2457 OUString aOptions
= ScDocumentLoader::GetOptions(*pMed
);
2459 bool bWasThere
= rDoc
.HasLink( aFileName
, aFilterName
, aOptions
);
2461 sal_uLong nRefresh
= 0;
2463 for (i
=0; i
<nInsCount
; i
++)
2465 rSrcDoc
.GetName( pSrcTabs
[i
], aTabStr
);
2466 rDoc
.SetLink( nTab
+i
, SC_LINK_NORMAL
,
2467 aFileName
, aFilterName
, aOptions
, aTabStr
, nRefresh
);
2470 if (!bWasThere
) // Insert link only once per source document
2472 ScTableLink
* pLink
= new ScTableLink( pDocSh
, aFileName
, aFilterName
, aOptions
, nRefresh
);
2473 pLink
->SetInCreate( true );
2474 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, aFileName
, &aFilterName
);
2476 pLink
->SetInCreate( false );
2478 SfxBindings
& rBindings
= GetViewData().GetBindings();
2479 rBindings
.Invalidate( SID_LINKS
);
2485 pDocSh
->GetUndoManager()->AddUndoAction(
2486 new ScUndoImportTab( pDocSh
, nTab
, nCount
) );
2489 for (i
=0; i
<nInsCount
; i
++)
2490 GetViewData().InsertTab(nTab
);
2491 SetTabNo(nTab
,true);
2492 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
,
2493 PAINT_GRID
| PAINT_TOP
| PAINT_LEFT
| PAINT_EXTRAS
);
2495 SfxApplication
* pSfxApp
= SfxGetpApp();
2496 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2497 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
2499 pDocSh
->PostPaintExtras();
2500 pDocSh
->PostPaintGridAll();
2501 pDocSh
->SetDocumentModified();
2504 ErrorMessage(STR_ABSREFLOST
);
2506 ErrorMessage(STR_NAMECONFLICT
);
2509 // Move/Copy table to another document
2511 void ScViewFunc::MoveTable(
2512 sal_uInt16 nDestDocNo
, SCTAB nDestTab
, bool bCopy
, const OUString
* pNewTabName
)
2514 ScDocument
* pDoc
= GetViewData().GetDocument();
2515 ScDocShell
* pDocShell
= GetViewData().GetDocShell();
2516 ScDocument
* pDestDoc
= NULL
;
2517 ScDocShell
* pDestShell
= NULL
;
2518 ScTabViewShell
* pDestViewSh
= NULL
;
2519 bool bUndo (pDoc
->IsUndoEnabled());
2520 bool bRename
= pNewTabName
&& !pNewTabName
->isEmpty();
2522 bool bNewDoc
= (nDestDocNo
== SC_DOC_NEW
);
2525 nDestTab
= 0; // firstly insert
2527 // execute without SfxCallMode::RECORD, because already contained in move command
2529 OUString
aUrl("private:factory/" STRING_SCAPP
);
2530 SfxStringItem
aItem( SID_FILE_NAME
, aUrl
);
2531 SfxStringItem
aTarget( SID_TARGETNAME
, OUString("_blank") );
2533 const SfxPoolItem
* pRetItem
= GetViewData().GetDispatcher().Execute(
2534 SID_OPENDOC
, SfxCallMode::API
|SfxCallMode::SYNCHRON
, &aItem
, &aTarget
, 0L );
2537 if ( pRetItem
->ISA( SfxObjectItem
) )
2538 pDestShell
= PTR_CAST( ScDocShell
, static_cast<const SfxObjectItem
*>(pRetItem
)->GetShell() );
2539 else if ( pRetItem
->ISA( SfxViewFrameItem
) )
2541 SfxViewFrame
* pFrm
= static_cast<const SfxViewFrameItem
*>(pRetItem
)->GetFrame();
2543 pDestShell
= PTR_CAST( ScDocShell
, pFrm
->GetObjectShell() );
2546 pDestViewSh
= pDestShell
->GetBestViewShell();
2550 pDestShell
= ScDocShell::GetShellByNum( nDestDocNo
);
2554 OSL_FAIL("Dest-Doc nicht gefunden !!!");
2558 ScMarkData
& rMark
= GetViewData().GetMarkData();
2559 if (bRename
&& rMark
.GetSelectCount() != 1)
2561 // Custom sheet name is provided, but more than one sheet is selected.
2562 // We don't support this scenario at the moment.
2566 pDestDoc
= &pDestShell
->GetDocument();
2568 SCTAB nTab
= GetViewData().GetTabNo();
2570 if (pDestDoc
!= pDoc
)
2574 while (pDestDoc
->GetTableCount() > 1)
2575 pDestDoc
->DeleteTab(0);
2576 pDestDoc
->RenameTab( 0, OUString("______42_____"),
2580 SCTAB nTabCount
= pDoc
->GetTableCount();
2581 SCTAB nTabSelCount
= rMark
.GetSelectCount();
2583 vector
<SCTAB
> TheTabs
;
2585 for(SCTAB i
=0; i
<nTabCount
; ++i
)
2587 if(rMark
.GetTableSelect(i
))
2590 pDoc
->GetName( i
, aTabName
);
2591 TheTabs
.push_back(i
);
2592 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
2594 if((!pDoc
->IsVisible(j
)) && pDoc
->IsScenario(j
))
2596 pDoc
->GetName( j
, aTabName
);
2597 TheTabs
.push_back(j
);
2605 GetFrameWin()->EnterWait();
2607 if (pDoc
->GetDrawLayer())
2608 pDestShell
->MakeDrawLayer();
2610 if (!bNewDoc
&& bUndo
)
2611 pDestDoc
->BeginDrawUndo(); // drawing layer must do its own undo actions
2613 sal_uLong nErrVal
=1;
2614 if(nDestTab
==SC_TAB_APPEND
)
2615 nDestTab
=pDestDoc
->GetTableCount();
2616 SCTAB nDestTab1
=nDestTab
;
2618 for( sal_uInt16 j
=0; j
<TheTabs
.size(); ++j
, ++nDestTab1
)
2619 { // insert sheets first and update all references
2622 aName
= *pNewTabName
;
2624 pDoc
->GetName( TheTabs
[j
], aName
);
2626 pDestDoc
->CreateValidTabName( aName
);
2627 if ( !pDestDoc
->InsertTab( nDestTab1
, aName
) )
2629 nErrVal
= 0; // total error
2632 ScRange
aRange( 0, 0, TheTabs
[j
], MAXCOL
, MAXROW
, TheTabs
[j
] );
2633 aParam
.maRanges
.Append(aRange
);
2635 pDoc
->SetClipParam(aParam
);
2638 nDestTab1
= nDestTab
;
2639 for(sal_uInt16 i
=0; i
<TheTabs
.size();++i
)
2641 nErrVal
= pDestShell
->TransferTab( *pDocShell
, TheTabs
[i
], static_cast<SCTAB
>(nDestTab1
), false, false );
2646 if (!bNewDoc
&& bUndo
)
2648 pDestDoc
->GetName(nDestTab
, sName
);
2649 pDestShell
->GetUndoManager()->AddUndoAction(
2650 new ScUndoImportTab( pDestShell
, nDestTab
,
2651 static_cast<SCTAB
>(TheTabs
.size())));
2656 pDestShell
->GetUndoManager()->Clear();
2659 GetFrameWin()->LeaveWait();
2662 case 0: // internal error or full of errors
2664 ErrorMessage(STR_TABINSERT_ERROR
);
2668 ErrorMessage(STR_ABSREFLOST
);
2671 ErrorMessage(STR_NAMECONFLICT
);
2675 ErrorMessage(STR_ABSREFLOST
);
2676 ErrorMessage(STR_NAMECONFLICT
);
2685 if(nTabCount
!=nTabSelCount
)
2686 DeleteTables(TheTabs
); // incl. Paint & Undo
2688 ErrorMessage(STR_TABREMOVE_ERROR
);
2693 // ChartListenerCollection must be updated before DeleteTab
2694 if ( pDestDoc
->IsChartListenerCollectionNeedsUpdate() )
2695 pDestDoc
->UpdateChartListenerCollection();
2697 pDestDoc
->DeleteTab(static_cast<SCTAB
>(TheTabs
.size())); // old first table
2700 // Make sure to clear the cached page view after sheet
2701 // deletion, which still points to the sdr page belonging to
2702 // the deleted sheet.
2703 SdrView
* pSdrView
= pDestViewSh
->GetSdrView();
2705 pSdrView
->ClearPageView();
2707 pDestViewSh
->TabChanged(); // Pages auf dem Drawing-Layer
2709 pDestShell
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
,
2710 PAINT_GRID
| PAINT_TOP
| PAINT_LEFT
|
2711 PAINT_EXTRAS
| PAINT_SIZE
);
2712 // PAINT_SIZE for outline
2716 pDestShell
->Broadcast( ScTablesHint( SC_TAB_INSERTED
, nDestTab
) );
2717 pDestShell
->PostPaintExtras();
2718 pDestShell
->PostPaintGridAll();
2723 pDestShell
->SetDocumentModified();
2724 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2728 // Move or copy within the same document.
2729 SCTAB nTabCount
= pDoc
->GetTableCount();
2731 unique_ptr
< vector
<SCTAB
> > pSrcTabs(new vector
<SCTAB
>);
2732 unique_ptr
< vector
<SCTAB
> > pDestTabs(new vector
<SCTAB
>);
2733 unique_ptr
< vector
<OUString
> > pTabNames(new vector
<OUString
>);
2734 unique_ptr
< vector
<OUString
> > pDestNames
;
2735 pSrcTabs
->reserve(nTabCount
);
2736 pDestTabs
->reserve(nTabCount
);
2737 pTabNames
->reserve(nTabCount
);
2740 for(SCTAB i
=0;i
<nTabCount
;i
++)
2742 if(rMark
.GetTableSelect(i
))
2745 pDoc
->GetName( i
, aTabName
);
2746 pTabNames
->push_back(aTabName
);
2748 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
2750 if((!pDoc
->IsVisible(j
)) && pDoc
->IsScenario(j
))
2752 pDoc
->GetName( j
, aTabName
);
2753 pTabNames
->push_back(aTabName
);
2762 pDoc
->BeginDrawUndo(); // drawing layer must do its own undo actions
2764 pDoc
->GetName( nDestTab
, aDestName
);
2765 SCTAB nDestTab1
=nDestTab
;
2767 for (size_t j
= 0, n
= pTabNames
->size(); j
< n
; ++j
)
2769 nTabCount
= pDoc
->GetTableCount();
2770 const OUString
& rStr
= (*pTabNames
)[j
];
2771 if(!pDoc
->GetTable(rStr
,nMovTab
))
2775 if(!pDoc
->GetTable(aDestName
,nDestTab1
))
2777 nDestTab1
=nTabCount
;
2779 pDocShell
->MoveTable( nMovTab
, nDestTab1
, bCopy
, false ); // Undo is here
2781 if(bCopy
&& pDoc
->IsScenario(nMovTab
))
2787 pDoc
->GetScenarioData(nMovTab
, aComment
,aColor
, nFlags
);
2788 pDoc
->SetScenario(nDestTab1
,true);
2789 pDoc
->SetScenarioData(nDestTab1
,aComment
,aColor
,nFlags
);
2790 bool bActive
= pDoc
->IsActiveScenario(nMovTab
);
2791 pDoc
->SetActiveScenario( nDestTab1
, bActive
);
2792 bool bVisible
=pDoc
->IsVisible(nMovTab
);
2793 pDoc
->SetVisible(nDestTab1
,bVisible
);
2796 pSrcTabs
->push_back(nMovTab
);
2800 if(!pDoc
->GetTable(rStr
,nDestTab1
))
2802 nDestTab1
=nTabCount
;
2806 pDestTabs
->push_back(nDestTab1
);
2809 // Rename must be done after all sheets have been moved.
2812 pDestNames
.reset(new vector
<OUString
>);
2813 size_t n
= pDestTabs
->size();
2814 pDestNames
->reserve(n
);
2815 for (size_t j
= 0; j
< n
; ++j
)
2817 SCTAB nRenameTab
= (*pDestTabs
)[j
];
2818 OUString aTabName
= *pNewTabName
;
2819 pDoc
->CreateValidTabName( aTabName
);
2820 pDestNames
->push_back(aTabName
);
2821 pDoc
->RenameTab(nRenameTab
, aTabName
);
2825 // No need to keep this around when we are not renaming.
2828 nTab
= GetViewData().GetTabNo();
2834 pDocShell
->GetUndoManager()->AddUndoAction(
2836 pDocShell
, pSrcTabs
.release(), pDestTabs
.release(), pDestNames
.release()));
2840 pDocShell
->GetUndoManager()->AddUndoAction(
2842 pDocShell
, pSrcTabs
.release(), pDestTabs
.release(), pTabNames
.release(), pDestNames
.release()));
2846 SCTAB nNewTab
= nDestTab
;
2847 if (nNewTab
== SC_TAB_APPEND
)
2848 nNewTab
= pDoc
->GetTableCount()-1;
2849 else if (!bCopy
&& nTab
<nDestTab
)
2852 SetTabNo( nNewTab
, true );
2854 //#i29848# adjust references to data on the copied sheet
2856 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc
, pDestDoc
, nTab
, nNewTab
);
2860 void ScViewFunc::ShowTable( const std::vector
<OUString
>& rNames
)
2862 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2863 ScDocument
& rDoc
= pDocSh
->GetDocument();
2864 bool bUndo(rDoc
.IsUndoEnabled());
2866 std::vector
<SCTAB
> undoTabs
;
2872 for (std::vector
<OUString
>::const_iterator itr
=rNames
.begin(), itrEnd
= rNames
.end(); itr
!=itrEnd
; ++itr
)
2875 if (rDoc
.GetTable(aName
, nPos
))
2877 rDoc
.SetVisible( nPos
, true );
2878 SetTabNo( nPos
, true );
2879 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2883 undoTabs
.push_back(nPos
);
2890 pDocSh
->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh
, undoTabs
, true ) );
2892 pDocSh
->PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
2893 pDocSh
->SetDocumentModified();
2897 void ScViewFunc::HideTable( const ScMarkData
& rMark
)
2899 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
2900 ScDocument
& rDoc
= pDocSh
->GetDocument();
2901 bool bUndo(rDoc
.IsUndoEnabled());
2903 SCTAB nTabCount
= rDoc
.GetTableCount();
2905 SCTAB nTabSelCount
= rMark
.GetSelectCount();
2907 // check to make sure we won't hide all sheets. we need at least one visible at all times.
2908 for ( SCTAB i
=0; i
< nTabCount
&& nVisible
<= nTabSelCount
; i
++ )
2909 if (rDoc
.IsVisible(i
))
2912 if (nVisible
> nTabSelCount
)
2915 ScMarkData::MarkedTabsType::const_iterator it
;
2916 std::vector
<SCTAB
> undoTabs
;
2918 ScMarkData::MarkedTabsType selectedTabs
= rMark
.GetSelectedTabs();
2919 for (it
=selectedTabs
.begin(); it
!=selectedTabs
.end(); ++it
)
2922 if (rDoc
.IsVisible( nTab
))
2924 rDoc
.SetVisible( nTab
, false );
2926 pDocSh
->Broadcast( ScTablesHint( SC_TAB_HIDDEN
, nTab
) );
2927 SetTabNo( nTab
, true );
2930 undoTabs
.push_back(nTab
);
2935 pDocSh
->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh
, undoTabs
, false ) );
2939 SfxGetpApp()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2940 pDocSh
->PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
2941 pDocSh
->SetDocumentModified();
2945 void ScViewFunc::InsertSpecialChar( const OUString
& rStr
, const vcl::Font
& rFont
)
2947 ScEditableTester
aTester( this );
2948 if (!aTester
.IsEditable())
2950 ErrorMessage(aTester
.GetMessageId());
2954 const sal_Unicode
* pChar
= rStr
.getStr();
2955 ScTabViewShell
* pViewShell
= GetViewData().GetViewShell();
2956 SvxFontItem
aFontItem( rFont
.GetFamily(),
2958 rFont
.GetStyleName(),
2963 // if string contains WEAK characters, set all fonts
2964 SvtScriptType nScript
;
2965 ScDocument
* pDoc
= GetViewData().GetDocument();
2966 if ( pDoc
->HasStringWeakCharacters( rStr
) )
2967 nScript
= SvtScriptType::LATIN
| SvtScriptType::ASIAN
| SvtScriptType::COMPLEX
;
2969 nScript
= pDoc
->GetStringScriptType( rStr
);
2971 SvxScriptSetItem
aSetItem( SID_ATTR_CHAR_FONT
, pViewShell
->GetPool() );
2972 aSetItem
.PutItemForScriptType( nScript
, aFontItem
);
2973 ApplyUserItemSet( aSetItem
.GetItemSet() );
2976 pViewShell
->TabKeyInput( KeyEvent( *(pChar
++), vcl::KeyCode() ) );
2979 void ScViewFunc::UpdateLineAttrs( SvxBorderLine
& rLine
,
2980 const SvxBorderLine
* pDestLine
,
2981 const SvxBorderLine
* pSrcLine
,
2984 if ( pSrcLine
&& pDestLine
)
2988 rLine
.SetColor ( pSrcLine
->GetColor() );
2989 rLine
.SetBorderLineStyle(pDestLine
->GetBorderLineStyle());
2990 rLine
.SetWidth ( pDestLine
->GetWidth() );
2994 rLine
.SetColor ( pDestLine
->GetColor() );
2995 rLine
.SetBorderLineStyle(pSrcLine
->GetBorderLineStyle());
2996 rLine
.SetWidth ( pSrcLine
->GetWidth() );
3001 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
3002 pBoxLine = aBoxItem.Get##LINE(); \
3007 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
3008 aBoxItem.SetLine( &aLine, BOXLINE ); \
3011 aBoxItem.SetLine( NULL, BOXLINE ); \
3014 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine
* pLine
,
3017 // Not editable only due to a matrix? Attribute is ok anyhow.
3018 bool bOnlyNotBecauseOfMatrix
;
3019 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
3021 ErrorMessage(STR_PROTECTIONERR
);
3025 ScDocument
* pDoc
= GetViewData().GetDocument();
3026 ScMarkData
aFuncMark( GetViewData().GetMarkData() ); // local copy for UnmarkFiltered
3027 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
3028 ScDocShell
* pDocSh
= GetViewData().GetDocShell();
3029 const ScPatternAttr
* pSelAttrs
= GetSelectionPattern();
3030 const SfxItemSet
& rSelItemSet
= pSelAttrs
->GetItemSet();
3032 const SfxPoolItem
* pBorderAttr
= NULL
;
3033 SfxItemState eItemState
= rSelItemSet
.GetItemState( ATTR_BORDER
, true, &pBorderAttr
);
3035 const SfxPoolItem
* pTLBRItem
= 0;
3036 SfxItemState eTLBRState
= rSelItemSet
.GetItemState( ATTR_BORDER_TLBR
, true, &pTLBRItem
);
3038 const SfxPoolItem
* pBLTRItem
= 0;
3039 SfxItemState eBLTRState
= rSelItemSet
.GetItemState( ATTR_BORDER_BLTR
, true, &pBLTRItem
);
3041 // any of the lines visible?
3042 if( (eItemState
!= SfxItemState::DEFAULT
) || (eTLBRState
!= SfxItemState::DEFAULT
) || (eBLTRState
!= SfxItemState::DEFAULT
) )
3044 // none of the lines don't care?
3045 if( (eItemState
!= SfxItemState::DONTCARE
) && (eTLBRState
!= SfxItemState::DONTCARE
) && (eBLTRState
!= SfxItemState::DONTCARE
) )
3047 boost::scoped_ptr
<SfxItemSet
> pOldSet(new SfxItemSet(
3050 ATTR_PATTERN_END
));
3051 boost::scoped_ptr
<SfxItemSet
> pNewSet(new SfxItemSet(
3054 ATTR_PATTERN_END
));
3056 const SvxBorderLine
* pBoxLine
= NULL
;
3057 SvxBorderLine aLine
;
3059 // here pBoxLine is used
3063 SvxBoxItem
aBoxItem( *static_cast<const SvxBoxItem
*>(pBorderAttr
) );
3064 SvxBoxInfoItem
aBoxInfoItem( ATTR_BORDER_INNER
);
3066 SET_LINE_ATTRIBUTES(Top
,SvxBoxItemLine::TOP
)
3067 SET_LINE_ATTRIBUTES(Bottom
,SvxBoxItemLine::BOTTOM
)
3068 SET_LINE_ATTRIBUTES(Left
,SvxBoxItemLine::LEFT
)
3069 SET_LINE_ATTRIBUTES(Right
,SvxBoxItemLine::RIGHT
)
3071 aBoxInfoItem
.SetLine( aBoxItem
.GetTop(), SvxBoxInfoItemLine::HORI
);
3072 aBoxInfoItem
.SetLine( aBoxItem
.GetLeft(), SvxBoxInfoItemLine::VERT
);
3073 aBoxInfoItem
.ResetFlags(); // set Lines to Valid
3075 pOldSet
->Put( *pBorderAttr
);
3076 pNewSet
->Put( aBoxItem
);
3077 pNewSet
->Put( aBoxInfoItem
);
3080 if( pTLBRItem
&& static_cast<const SvxLineItem
*>(pTLBRItem
)->GetLine() )
3082 SvxLineItem
aTLBRItem( *static_cast<const SvxLineItem
*>(pTLBRItem
) );
3083 UpdateLineAttrs( aLine
, aTLBRItem
.GetLine(), pLine
, bColorOnly
);
3084 aTLBRItem
.SetLine( &aLine
);
3085 pOldSet
->Put( *pTLBRItem
);
3086 pNewSet
->Put( aTLBRItem
);
3089 if( pBLTRItem
&& static_cast<const SvxLineItem
*>(pBLTRItem
)->GetLine() )
3091 SvxLineItem
aBLTRItem( *static_cast<const SvxLineItem
*>(pBLTRItem
) );
3092 UpdateLineAttrs( aLine
, aBLTRItem
.GetLine(), pLine
, bColorOnly
);
3093 aBLTRItem
.SetLine( &aLine
);
3094 pOldSet
->Put( *pBLTRItem
);
3095 pNewSet
->Put( aBLTRItem
);
3098 ApplyAttributes( pNewSet
.get(), pOldSet
.get() );
3100 else // if ( eItemState == SfxItemState::DONTCARE )
3102 aFuncMark
.MarkToMulti();
3103 pDoc
->ApplySelectionLineStyle( aFuncMark
, pLine
, bColorOnly
);
3107 aFuncMark
.GetMultiMarkArea( aMarkRange
);
3108 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
3109 SCROW nStartRow
= aMarkRange
.aStart
.Row();
3110 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
3111 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
3112 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
3113 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
3114 pDocSh
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
3115 nEndCol
, nEndRow
, nEndTab
,
3116 PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
3118 pDocSh
->UpdateOle( &GetViewData() );
3119 pDocSh
->SetDocumentModified();
3123 #undef SET_LINE_ATTRIBUTES
3125 void ScViewFunc::SetValidation( const ScValidationData
& rNew
)
3127 ScDocument
* pDoc
= GetViewData().GetDocument();
3128 sal_uLong nIndex
= pDoc
->AddValidationEntry(rNew
); // for it there is no Undo
3129 SfxUInt32Item
aItem( ATTR_VALIDDATA
, nIndex
);
3131 ApplyAttr( aItem
); // with Paint and Undo...
3134 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */