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"
60 #include "patattr.hxx"
61 #include "printfun.hxx"
62 #include "rangenam.hxx"
63 #include "rangeutl.hxx"
64 #include "refundo.hxx"
66 #include "tablink.hxx"
67 #include "tabvwsh.hxx"
68 #include "uiitems.hxx"
69 #include "undoblk.hxx"
70 #include "undocell.hxx"
71 #include "undotab.hxx"
72 #include "sizedev.hxx"
73 #include "editable.hxx"
75 #include "inputhdl.hxx"
76 #include "inputwin.hxx"
77 #include "funcdesc.hxx"
79 #include "charthelper.hxx"
80 #include "tabbgcolor.hxx"
81 #include "clipparam.hxx"
82 #include "prnsave.hxx"
83 #include "searchresults.hxx"
84 #include "tokenarray.hxx"
85 #include <columnspanset.hxx>
86 #include <rowheightcontext.hxx>
88 #include <boost/scoped_ptr.hpp>
92 using namespace com::sun::star
;
93 using ::editeng::SvxBorderLine
;
96 using ::std::auto_ptr
;
98 // helper func defined in docfunc.cxx
99 void VBA_DeleteModule( ScDocShell
& rDocSh
, const OUString
& sModuleName
);
101 // STATIC DATA ---------------------------------------------------------------
104 bool ScViewFunc::AdjustBlockHeight( bool bPaint
, ScMarkData
* pMarkData
)
106 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
108 pMarkData
= &GetViewData()->GetMarkData();
110 ScDocument
* pDoc
= pDocSh
->GetDocument();
111 std::vector
<sc::ColRowSpan
> aMarkedRows
= pMarkData
->GetMarkedRowSpans();
113 if (aMarkedRows
.empty())
115 SCROW nCurRow
= GetViewData()->GetCurY();
116 aMarkedRows
.push_back(sc::ColRowSpan(nCurRow
, nCurRow
));
119 double nPPTX
= GetViewData()->GetPPTX();
120 double nPPTY
= GetViewData()->GetPPTY();
121 Fraction aZoomX
= GetViewData()->GetZoomX();
122 Fraction aZoomY
= GetViewData()->GetZoomY();
124 ScSizeDeviceProvider
aProv(pDocSh
);
125 if (aProv
.IsPrinter())
127 nPPTX
= aProv
.GetPPTX();
128 nPPTY
= aProv
.GetPPTY();
129 aZoomX
= aZoomY
= Fraction( 1, 1 );
132 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, aZoomX
, aZoomY
, aProv
.GetDevice());
133 bool bAnyChanged
= false;
134 ScMarkData::iterator itr
= pMarkData
->begin(), itrEnd
= pMarkData
->end();
135 for (; itr
!= itrEnd
; ++itr
)
138 bool bChanged
= false;
140 std::vector
<sc::ColRowSpan
>::const_iterator itRows
= aMarkedRows
.begin(), itRowsEnd
= aMarkedRows
.end();
141 for (; itRows
!= itRowsEnd
; ++itRows
)
143 SCROW nStartNo
= itRows
->mnStart
;
144 SCROW nEndNo
= itRows
->mnEnd
;
145 if (pDoc
->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());
164 bool ScViewFunc::AdjustRowHeight( SCROW nStartRow
, SCROW nEndRow
, bool bPaint
)
166 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
167 ScDocument
* pDoc
= pDocSh
->GetDocument();
168 SCTAB nTab
= GetViewData()->GetTabNo();
169 double nPPTX
= GetViewData()->GetPPTX();
170 double nPPTY
= GetViewData()->GetPPTY();
171 Fraction aZoomX
= GetViewData()->GetZoomX();
172 Fraction aZoomY
= GetViewData()->GetZoomY();
173 sal_uInt16 nOldPixel
= 0;
174 if (nStartRow
== nEndRow
)
175 nOldPixel
= (sal_uInt16
) (pDoc
->GetRowHeight(nStartRow
,nTab
) * nPPTY
);
177 ScSizeDeviceProvider
aProv(pDocSh
);
178 if (aProv
.IsPrinter())
180 nPPTX
= aProv
.GetPPTX();
181 nPPTY
= aProv
.GetPPTY();
182 aZoomX
= aZoomY
= Fraction( 1, 1 );
184 sc::RowHeightContext
aCxt(nPPTX
, nPPTY
, aZoomX
, aZoomY
, aProv
.GetDevice());
185 bool bChanged
= pDoc
->SetOptimalHeight(aCxt
, nStartRow
, nEndRow
, nTab
);
187 if (bChanged
&& ( nStartRow
== nEndRow
))
189 sal_uInt16 nNewPixel
= (sal_uInt16
) (pDoc
->GetRowHeight(nStartRow
,nTab
) * nPPTY
);
190 if ( nNewPixel
== nOldPixel
)
194 if ( bPaint
&& bChanged
)
195 pDocSh
->PostPaint( 0, nStartRow
, nTab
, MAXCOL
, MAXROW
, nTab
,
196 PAINT_GRID
| PAINT_LEFT
);
210 static ScAutoSum
lcl_IsAutoSumData( ScDocument
* pDoc
, SCCOL nCol
, SCROW nRow
,
211 SCTAB nTab
, ScDirection eDir
, SCCOLROW
& nExtend
)
213 ScRefCellValue aCell
;
214 aCell
.assign(*pDoc
, ScAddress(nCol
, nRow
, nTab
));
215 if (aCell
.hasNumeric())
217 if (aCell
.meType
== CELLTYPE_FORMULA
)
219 ScTokenArray
* pCode
= aCell
.mpFormula
->GetCode();
220 if ( pCode
&& pCode
->GetOuterFuncOpCode() == ocSum
)
222 if ( pCode
->GetAdjacentExtendOfOuterFuncRefs( nExtend
,
223 ScAddress( nCol
, nRow
, nTab
), eDir
) )
227 return ScAutoSumData
;
229 return ScAutoSumNone
;
233 #define SC_AUTOSUM_MAXCOUNT 20
235 static ScAutoSum
lcl_SeekAutoSumData( ScDocument
* pDoc
, SCCOL
& nCol
, SCROW
& nRow
,
236 SCTAB nTab
, ScDirection eDir
, SCCOLROW
& nExtend
)
238 sal_uInt16 nCount
= 0;
239 while (nCount
< SC_AUTOSUM_MAXCOUNT
)
241 if ( eDir
== DIR_TOP
)
246 return ScAutoSumNone
;
253 return ScAutoSumNone
;
256 if ( (eSum
= lcl_IsAutoSumData(
257 pDoc
, nCol
, nRow
, nTab
, eDir
, nExtend
)) != ScAutoSumNone
)
261 return ScAutoSumNone
;
264 #undef SC_AUTOSUM_MAXCOUNT
266 static bool lcl_FindNextSumEntryInColumn( ScDocument
* pDoc
, SCCOL nCol
, SCROW
& nRow
,
267 SCTAB nTab
, SCCOLROW
& nExtend
, SCROW nMinRow
)
269 const SCROW nTmp
= nRow
;
270 ScAutoSum eSkip
= ScAutoSumNone
;
271 while ( ( eSkip
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_TOP
, nExtend
) ) == ScAutoSumData
&&
276 if ( eSkip
== ScAutoSumSum
&& nRow
< nTmp
)
283 static bool lcl_FindNextSumEntryInRow( ScDocument
* pDoc
, SCCOL
& nCol
, SCROW nRow
,
284 SCTAB nTab
, SCCOLROW
& nExtend
, SCROW nMinCol
)
286 const SCCOL nTmp
= nCol
;
287 ScAutoSum eSkip
= ScAutoSumNone
;
288 while ( ( eSkip
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_LEFT
, nExtend
) ) == ScAutoSumData
&&
293 if ( eSkip
== ScAutoSumSum
&& nCol
< nTmp
)
300 static bool lcl_GetAutoSumForColumnRange( ScDocument
* pDoc
, ScRangeList
& rRangeList
, const ScRange
& rRange
)
302 const ScAddress aStart
= rRange
.aStart
;
303 const ScAddress aEnd
= rRange
.aEnd
;
304 if ( aStart
.Col() != aEnd
.Col() )
309 const SCTAB nTab
= aEnd
.Tab();
310 const SCCOL nCol
= aEnd
.Col();
311 SCROW nEndRow
= aEnd
.Row();
312 SCROW nStartRow
= nEndRow
;
313 SCCOLROW nExtend
= 0;
314 const ScAutoSum eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nEndRow
, nTab
, DIR_TOP
, nExtend
/*out*/ );
316 if ( eSum
== ScAutoSumSum
)
318 bool bContinue
= false;
321 rRangeList
.Append( ScRange( nCol
, nStartRow
, nTab
, nCol
, nEndRow
, nTab
) );
322 nEndRow
= static_cast< SCROW
>( nExtend
);
323 if ( ( bContinue
= lcl_FindNextSumEntryInColumn( pDoc
, nCol
, nEndRow
/*inout*/, nTab
, nExtend
/*out*/, aStart
.Row() ) ) == true )
327 } while ( bContinue
);
331 while ( nStartRow
> aStart
.Row() &&
332 lcl_IsAutoSumData( pDoc
, nCol
, nStartRow
-1, nTab
, DIR_TOP
, nExtend
/*out*/ ) != ScAutoSumSum
)
336 rRangeList
.Append( ScRange( nCol
, nStartRow
, nTab
, nCol
, nEndRow
, nTab
) );
342 static bool lcl_GetAutoSumForRowRange( ScDocument
* pDoc
, ScRangeList
& rRangeList
, const ScRange
& rRange
)
344 const ScAddress aStart
= rRange
.aStart
;
345 const ScAddress aEnd
= rRange
.aEnd
;
346 if ( aStart
.Row() != aEnd
.Row() )
351 const SCTAB nTab
= aEnd
.Tab();
352 const SCROW nRow
= aEnd
.Row();
353 SCCOL nEndCol
= aEnd
.Col();
354 SCCOL nStartCol
= nEndCol
;
355 SCCOLROW nExtend
= 0;
356 const ScAutoSum eSum
= lcl_IsAutoSumData( pDoc
, nEndCol
, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ );
358 if ( eSum
== ScAutoSumSum
)
360 bool bContinue
= false;
363 rRangeList
.Append( ScRange( nStartCol
, nRow
, nTab
, nEndCol
, nRow
, nTab
) );
364 nEndCol
= static_cast< SCCOL
>( nExtend
);
365 if ( ( bContinue
= lcl_FindNextSumEntryInRow( pDoc
, nEndCol
/*inout*/, nRow
, nTab
, nExtend
/*out*/, aStart
.Col() ) ) == true )
369 } while ( bContinue
);
373 while ( nStartCol
> aStart
.Col() &&
374 lcl_IsAutoSumData( pDoc
, nStartCol
-1, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ ) != ScAutoSumSum
)
378 rRangeList
.Append( ScRange( nStartCol
, nRow
, nTab
, nEndCol
, nRow
, nTab
) );
384 bool ScViewFunc::GetAutoSumArea( ScRangeList
& rRangeList
)
386 ScDocument
* pDoc
= GetViewData()->GetDocument();
387 SCTAB nTab
= GetViewData()->GetTabNo();
389 SCCOL nCol
= GetViewData()->GetCurX();
390 SCROW nRow
= GetViewData()->GetCurY();
392 SCCOL nStartCol
= nCol
;
393 SCROW nStartRow
= nRow
;
394 SCCOL nEndCol
= nCol
;
395 SCROW nEndRow
= nRow
;
396 SCCOL nSeekCol
= nCol
;
397 SCROW nSeekRow
= nRow
;
398 SCCOLROW nExtend
; // will become valid via reference for ScAutoSumSum
405 && ((eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
-1, nTab
,
406 DIR_TOP
, nExtend
/*out*/ )) == ScAutoSumData
)
407 && ((eSum
= lcl_IsAutoSumData( pDoc
, nCol
, nRow
-1, nTab
,
408 DIR_LEFT
, nExtend
/*out*/ )) == ScAutoSumData
)
414 else if ( nCol
!= 0 && (eSum
= lcl_IsAutoSumData( pDoc
, nCol
-1, nRow
, nTab
,
415 DIR_LEFT
, nExtend
/*out*/ )) == ScAutoSumData
)
420 else if ( (eSum
= lcl_SeekAutoSumData( pDoc
, nCol
, nSeekRow
, nTab
, DIR_TOP
, nExtend
/*out*/ )) != ScAutoSumNone
)
422 else if (( eSum
= lcl_SeekAutoSumData( pDoc
, nSeekCol
, nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ )) != ScAutoSumNone
)
429 nStartRow
= nSeekRow
; // nSeekRow might be adjusted via reference
430 if ( eSum
== ScAutoSumSum
)
431 nEndRow
= nStartRow
; // only sum sums
433 nEndRow
= nRow
- 1; // maybe extend data area at bottom
437 nStartCol
= nSeekCol
; // nSeekCol might be adjusted vie reference
438 if ( eSum
== ScAutoSumSum
)
439 nEndCol
= nStartCol
; // only sum sums
441 nEndCol
= nCol
- 1; // maybe extend data area to the right
443 bool bContinue
= false;
446 if ( eSum
== ScAutoSumData
)
450 while ( nStartRow
!= 0 && lcl_IsAutoSumData( pDoc
, nCol
,
451 nStartRow
-1, nTab
, DIR_TOP
, nExtend
/*out*/ ) == eSum
)
456 while ( nStartCol
!= 0 && lcl_IsAutoSumData( pDoc
, nStartCol
-1,
457 nRow
, nTab
, DIR_LEFT
, nExtend
/*out*/ ) == eSum
)
462 ScRange( nStartCol
, nStartRow
, nTab
, nEndCol
, nEndRow
, nTab
) );
463 if ( eSum
== ScAutoSumSum
)
467 nEndRow
= static_cast< SCROW
>( nExtend
);
468 if ( ( bContinue
= lcl_FindNextSumEntryInColumn( pDoc
, nCol
, nEndRow
/*inout*/, nTab
, nExtend
/*out*/, 0 ) ) )
475 nEndCol
= static_cast< SCCOL
>( nExtend
);
476 if ( ( bContinue
= lcl_FindNextSumEntryInRow( pDoc
, nEndCol
/*inout*/, nRow
, nTab
, nExtend
/*out*/, 0 ) ) )
482 } while ( bContinue
);
488 void ScViewFunc::EnterAutoSum(const ScRangeList
& rRangeList
, bool bSubTotal
, const ScAddress
& rAddr
)
490 OUString aFormula
= GetAutoSumFormula( rRangeList
, bSubTotal
, rAddr
);
491 EnterBlock( aFormula
, NULL
);
494 bool ScViewFunc::AutoSum( const ScRange
& rRange
, bool bSubTotal
, bool bSetCursor
, bool bContinue
)
496 ScDocument
* pDoc
= GetViewData()->GetDocument();
497 const SCTAB nTab
= rRange
.aStart
.Tab();
498 SCCOL nStartCol
= rRange
.aStart
.Col();
499 SCROW nStartRow
= rRange
.aStart
.Row();
500 const SCCOL nEndCol
= rRange
.aEnd
.Col();
501 const SCROW nEndRow
= rRange
.aEnd
.Row();
502 SCCOLROW nExtend
= 0; // out parameter for lcl_IsAutoSumData
504 // ignore rows at the top of the given range which don't contain autosum data
505 bool bRowData
= false;
506 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
508 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
510 if ( lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_TOP
, nExtend
) != ScAutoSumNone
)
527 // ignore columns at the left of the given range which don't contain autosum data
528 bool bColData
= false;
529 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
531 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
533 if ( lcl_IsAutoSumData( pDoc
, nCol
, nRow
, nTab
, DIR_LEFT
, nExtend
) != ScAutoSumNone
)
550 const bool bEndRowEmpty
= pDoc
->IsBlockEmpty( nTab
, nStartCol
, nEndRow
, nEndCol
, nEndRow
);
551 const bool bEndColEmpty
= pDoc
->IsBlockEmpty( nTab
, nEndCol
, nStartRow
, nEndCol
, nEndRow
);
552 bool bRow
= ( ( nStartRow
!= nEndRow
) && ( bEndRowEmpty
|| ( !bEndRowEmpty
&& !bEndColEmpty
) ) );
553 bool bCol
= ( ( nStartCol
!= nEndCol
) && ( bEndColEmpty
|| nStartRow
== nEndRow
) );
555 // find an empty row for entering the result
556 SCROW nInsRow
= nEndRow
;
557 if ( bRow
&& !bEndRowEmpty
)
559 if ( nInsRow
< MAXROW
)
562 while ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
, nInsRow
, nEndCol
, nInsRow
) )
564 if ( nInsRow
< MAXROW
)
581 // find an empty column for entering the result
582 SCCOL nInsCol
= nEndCol
;
583 if ( bCol
&& !bEndColEmpty
)
585 if ( nInsCol
< MAXCOL
)
588 while ( !pDoc
->IsBlockEmpty( nTab
, nInsCol
, nStartRow
, nInsCol
, nEndRow
) )
590 if ( nInsCol
< MAXCOL
)
607 if ( !bRow
&& !bCol
)
612 SCCOL nMarkEndCol
= nEndCol
;
613 SCROW nMarkEndRow
= nEndRow
;
617 // calculate the row sums for all columns of the given range
619 SCROW nSumEndRow
= nEndRow
;
623 // the last row of the given range is empty;
624 // don't take into account for calculating the autosum
629 // increase mark range
633 for ( SCCOL nCol
= nStartCol
; nCol
<= nEndCol
; ++nCol
)
635 if ( !pDoc
->IsBlockEmpty( nTab
, nCol
, nStartRow
, nCol
, nSumEndRow
) )
637 ScRangeList aRangeList
;
638 const ScRange
aRange( nCol
, nStartRow
, nTab
, nCol
, nSumEndRow
, nTab
);
639 if ( lcl_GetAutoSumForColumnRange( pDoc
, aRangeList
, aRange
) )
641 const OUString aFormula
= GetAutoSumFormula(
642 aRangeList
, bSubTotal
, ScAddress(nCol
, nInsRow
, nTab
));
643 EnterData( nCol
, nInsRow
, nTab
, aFormula
);
651 // calculate the column sums for all rows of the given range
653 SCCOL nSumEndCol
= nEndCol
;
657 // the last column of the given range is empty;
658 // don't take into account for calculating the autosum
663 // increase mark range
667 for ( SCROW nRow
= nStartRow
; nRow
<= nEndRow
; ++nRow
)
669 if ( !pDoc
->IsBlockEmpty( nTab
, nStartCol
, nRow
, nSumEndCol
, nRow
) )
671 ScRangeList aRangeList
;
672 const ScRange
aRange( nStartCol
, nRow
, nTab
, nSumEndCol
, nRow
, nTab
);
673 if ( lcl_GetAutoSumForRowRange( pDoc
, aRangeList
, aRange
) )
675 const OUString aFormula
= GetAutoSumFormula( aRangeList
, bSubTotal
, ScAddress(nInsCol
, nRow
, nTab
) );
676 EnterData( nInsCol
, nRow
, nTab
, aFormula
);
682 // set new mark range and cursor position
683 const ScRange
aMarkRange( nStartCol
, nStartRow
, nTab
, nMarkEndCol
, nMarkEndRow
, nTab
);
684 MarkRange( aMarkRange
, false, bContinue
);
687 SetCursor( nMarkEndCol
, nMarkEndRow
);
693 OUString
ScViewFunc::GetAutoSumFormula( const ScRangeList
& rRangeList
, bool bSubTotal
, const ScAddress
& rAddr
)
695 ScViewData
* pViewData
= GetViewData();
696 ScDocument
* pDoc
= pViewData
->GetDocument();
697 ::boost::scoped_ptr
<ScTokenArray
> pArray(new ScTokenArray
);
699 pArray
->AddOpCode(bSubTotal
? ocSubTotal
: ocSum
);
700 pArray
->AddOpCode(ocOpen
);
704 pArray
->AddDouble(9);
705 pArray
->AddOpCode(ocSep
);
708 if(!rRangeList
.empty())
710 ScRangeList aRangeList
= rRangeList
;
711 const ScRange
* pFirst
= aRangeList
.front();
712 size_t ListSize
= aRangeList
.size();
713 for ( size_t i
= 0; i
< ListSize
; ++i
)
715 const ScRange
* p
= aRangeList
[i
];
717 pArray
->AddOpCode(ocSep
);
718 ScComplexRefData aRef
;
719 aRef
.InitRangeRel(*p
, rAddr
);
720 pArray
->AddDoubleReference(aRef
);
724 pArray
->AddOpCode(ocClose
);
726 ScCompiler
aComp(pDoc
, rAddr
, *pArray
);
727 aComp
.SetGrammar(pDoc
->GetGrammar());
729 aComp
.CreateStringFromTokenArray(aBuf
);
730 OUString aFormula
= aBuf
.makeStringAndClear();
732 aBuf
.append(aFormula
);
733 return aBuf
.makeStringAndClear();
736 void ScViewFunc::EnterBlock( const OUString
& rString
, const EditTextObject
* pData
)
738 // test for multi selection
740 SCCOL nCol
= GetViewData()->GetCurX();
741 SCROW nRow
= GetViewData()->GetCurY();
742 SCTAB nTab
= GetViewData()->GetTabNo();
743 ScMarkData
& rMark
= GetViewData()->GetMarkData();
744 if ( rMark
.IsMultiMarked() )
746 rMark
.MarkToSimple();
747 if ( rMark
.IsMultiMarked() )
748 { // "Insert into multi selection not possible"
749 ErrorMessage(STR_MSSG_PASTEFROMCLIP_0
);
751 // insert into single cell
753 EnterData(nCol
, nRow
, nTab
, *pData
);
755 EnterData( nCol
, nRow
, nTab
, rString
);
760 ScDocument
* pDoc
= GetViewData()->GetDocument();
761 OUString aNewStr
= rString
;
764 const ScPatternAttr
* pOldPattern
= pDoc
->GetPattern( nCol
, nRow
, nTab
);
765 ScTabEditEngine
aEngine( *pOldPattern
, pDoc
->GetEnginePool() );
766 aEngine
.SetText(*pData
);
768 ScEditAttrTester
aTester( &aEngine
);
769 if (!aTester
.NeedsObject())
771 aNewStr
= aEngine
.GetText();
776 // Insert via PasteFromClip
778 WaitObject
aWait( GetFrameWin() );
780 ScAddress
aPos( nCol
, nRow
, nTab
);
782 boost::scoped_ptr
<ScDocument
> pInsDoc(new ScDocument( SCDOCMODE_CLIP
));
783 pInsDoc
->ResetClip( pDoc
, nTab
);
785 if (aNewStr
[0] == '=') // Formula ?
787 // SetString not possible, because in Clipboard-Documents nothing will be compiled!
788 pInsDoc
->SetFormulaCell(aPos
, new ScFormulaCell(pDoc
, aPos
, aNewStr
));
792 // A copy of pData will be stored.
793 pInsDoc
->SetEditText(aPos
, *pData
, pDoc
->GetEditPool());
796 pInsDoc
->SetString( nCol
, nRow
, nTab
, aNewStr
);
798 pInsDoc
->SetClipArea( ScRange(aPos
) );
799 // insert Block, with Undo etc.
800 if ( PasteFromClip( IDF_CONTENTS
, pInsDoc
.get(), PASTE_NOFUNC
, false, false,
801 false, INS_NONE
, IDF_ATTRIB
) )
803 const SfxUInt32Item
* pItem
= (SfxUInt32Item
*) pInsDoc
->GetAttr(
804 nCol
, nRow
, nTab
, ATTR_VALUE_FORMAT
);
806 { // set number format if incompatible
807 // MarkData was already MarkToSimple'ed in PasteFromClip
809 rMark
.GetMarkArea( aRange
);
810 boost::scoped_ptr
<ScPatternAttr
> pPattern(new ScPatternAttr( pDoc
->GetPool() ));
811 pPattern
->GetItemSet().Put( *pItem
);
812 short nNewType
= pDoc
->GetFormatTable()->GetType( pItem
->GetValue() );
813 pDoc
->ApplyPatternIfNumberformatIncompatible( aRange
, rMark
,
814 *pPattern
, nNewType
);
821 void ScViewFunc::InsertPageBreak( bool bColumn
, bool bRecord
, const ScAddress
* pPos
,
824 SCTAB nTab
= GetViewData()->GetTabNo();
829 aCursor
= ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab
);
831 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().
832 InsertPageBreak( bColumn
, aCursor
, bRecord
, bSetModified
, false );
834 if ( bSuccess
&& bSetModified
)
835 UpdatePageBreakData( true ); // for PageBreak-Mode
839 void ScViewFunc::DeletePageBreak( bool bColumn
, bool bRecord
, const ScAddress
* pPos
,
842 SCTAB nTab
= GetViewData()->GetTabNo();
847 aCursor
= ScAddress( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab
);
849 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().
850 RemovePageBreak( bColumn
, aCursor
, bRecord
, bSetModified
, false );
852 if ( bSuccess
&& bSetModified
)
853 UpdatePageBreakData( true ); // for PageBreak-Mode
856 void ScViewFunc::RemoveManualBreaks()
858 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
859 ScDocument
* pDoc
= pDocSh
->GetDocument();
860 SCTAB nTab
= GetViewData()->GetTabNo();
861 bool bUndo(pDoc
->IsUndoEnabled());
865 ScDocument
* pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
866 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
, true, true );
867 pDoc
->CopyToDocument( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_NONE
, false, pUndoDoc
);
868 pDocSh
->GetUndoManager()->AddUndoAction(
869 new ScUndoRemoveBreaks( pDocSh
, nTab
, pUndoDoc
) );
872 pDoc
->RemoveManualBreaks(nTab
);
873 pDoc
->UpdatePageBreaks(nTab
);
875 UpdatePageBreakData( true );
876 pDocSh
->SetDocumentModified();
877 pDocSh
->PostPaint( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
, PAINT_GRID
);
880 void ScViewFunc::SetPrintZoom(sal_uInt16 nScale
, sal_uInt16 nPages
)
882 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
883 SCTAB nTab
= GetViewData()->GetTabNo();
884 pDocSh
->SetPrintZoom( nTab
, nScale
, nPages
);
887 void ScViewFunc::AdjustPrintZoom()
890 if ( GetViewData()->GetSimpleArea( aRange
) != SC_MARK_SIMPLE
)
891 GetViewData()->GetMarkData().GetMultiMarkArea( aRange
);
892 GetViewData()->GetDocShell()->AdjustPrintZoom( aRange
);
895 void ScViewFunc::SetPrintRanges( bool bEntireSheet
, const OUString
* pPrint
,
896 const OUString
* pRepCol
, const OUString
* pRepRow
,
899 // on all selected tables
901 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
902 ScDocument
* pDoc
= pDocSh
->GetDocument();
903 ScMarkData
& rMark
= GetViewData()->GetMarkData();
905 bool bUndo (pDoc
->IsUndoEnabled());
907 ScPrintRangeSaver
* pOldRanges
= pDoc
->CreatePrintRangeSaver();
909 ScAddress::Details
aDetails(pDoc
->GetAddressConvention(), 0, 0);
911 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
912 for (; itr
!= itrEnd
; ++itr
)
915 ScRange
aRange( 0,0,nTab
);
920 pDoc
->ClearPrintRanges( nTab
);
924 pDoc
->SetPrintEntireSheet( nTab
);
928 if ( !pPrint
->isEmpty() )
930 const sal_Unicode sep
= ScCompiler::GetNativeSymbolChar(ocSep
);
931 sal_uInt16 nTCount
= comphelper::string::getTokenCount(*pPrint
, sep
);
932 for (sal_uInt16 i
=0; i
<nTCount
; i
++)
934 OUString aToken
= pPrint
->getToken(i
, sep
);
935 if ( aRange
.ParseAny( aToken
, pDoc
, aDetails
) & SCA_VALID
)
936 pDoc
->AddPrintRange( nTab
, aRange
);
940 else // NULL = use selection (print range is always set), use empty string to delete all ranges
942 if ( GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
944 pDoc
->AddPrintRange( nTab
, aRange
);
946 else if ( rMark
.IsMultiMarked() )
949 ScRangeListRef
pList( new ScRangeList
);
950 rMark
.FillRangeListWithMarks( pList
, false );
951 for (size_t i
= 0, n
= pList
->size(); i
< n
; ++i
)
953 ScRange
* pR
= (*pList
)[i
];
954 pDoc
->AddPrintRange(nTab
, *pR
);
963 if ( pRepCol
->isEmpty() )
964 pDoc
->SetRepeatColRange( nTab
, NULL
);
966 if ( aRange
.ParseAny( *pRepCol
, pDoc
, aDetails
) & SCA_VALID
)
967 pDoc
->SetRepeatColRange( nTab
, &aRange
);
974 if ( pRepRow
->isEmpty() )
975 pDoc
->SetRepeatRowRange( nTab
, NULL
);
977 if ( aRange
.ParseAny( *pRepRow
, pDoc
, aDetails
) & SCA_VALID
)
978 pDoc
->SetRepeatRowRange( nTab
, &aRange
);
982 // undo (for all tables)
985 SCTAB nCurTab
= GetViewData()->GetTabNo();
986 ScPrintRangeSaver
* pNewRanges
= pDoc
->CreatePrintRangeSaver();
987 pDocSh
->GetUndoManager()->AddUndoAction(
988 new ScUndoPrintRange( pDocSh
, nCurTab
, pOldRanges
, pNewRanges
) );
993 // update page breaks
996 for (; itr
!= itrEnd
; ++itr
)
997 ScPrintFunc( pDocSh
, pDocSh
->GetPrinter(), *itr
).UpdatePages();
999 SfxBindings
& rBindings
= GetViewData()->GetBindings();
1000 rBindings
.Invalidate( SID_DELETE_PRINTAREA
);
1002 pDocSh
->SetDocumentModified();
1008 bool ScViewFunc::TestMergeCells() // pre-test (for menu)
1010 // simple test: true if there's a selection but no multi selection and not filtered
1012 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1013 if ( rMark
.IsMarked() || rMark
.IsMultiMarked() )
1016 return GetViewData()->GetSimpleArea( aDummy
) == SC_MARK_SIMPLE
;
1023 bool ScViewFunc::MergeCells( bool bApi
, bool& rDoContents
, bool bRecord
, bool bCenter
)
1025 // Editable- and Being-Nested- test must be at the beginning (in DocFunc too),
1026 // so that the Contents-QueryBox won't appear
1027 ScEditableTester
aTester( this );
1028 if (!aTester
.IsEditable())
1030 ErrorMessage(aTester
.GetMessageId());
1034 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1035 rMark
.MarkToSimple();
1036 if (!rMark
.IsMarked())
1038 ErrorMessage(STR_NOMULTISELECT
);
1042 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1043 ScDocument
* pDoc
= pDocSh
->GetDocument();
1046 rMark
.GetMarkArea( aMarkRange
);
1047 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
1048 SCROW nStartRow
= aMarkRange
.aStart
.Row();
1049 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
1050 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
1051 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
1052 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
1053 if ( nStartCol
== nEndCol
&& nStartRow
== nEndRow
)
1059 if ( pDoc
->HasAttrib( nStartCol
, nStartRow
, nStartTab
, nEndCol
, nEndRow
, nEndTab
,
1060 HASATTR_MERGED
| HASATTR_OVERLAPPED
) )
1061 { // "Don't nest merging !"
1062 ErrorMessage(STR_MSSG_MERGECELLS_0
);
1066 // Check for the contents of all selected tables.
1067 bool bAskDialog
= false;
1068 ScCellMergeOption
aMergeOption(nStartCol
, nStartRow
, nEndCol
, nEndRow
, bCenter
);
1069 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1070 for (; itr
!= itrEnd
; ++itr
)
1073 aMergeOption
.maTabs
.insert(i
);
1075 if (!pDoc
->IsBlockEmpty(i
, nStartCol
, nStartRow
+1, nStartCol
, nEndRow
) ||
1076 !pDoc
->IsBlockEmpty(i
, nStartCol
+1, nStartRow
, nEndCol
, nEndRow
))
1086 MessBox
aBox( GetViewData()->GetDialogParent(),
1087 WinBits(WB_YES_NO_CANCEL
| WB_DEF_NO
),
1088 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0
),
1089 ScGlobal::GetRscString( STR_MERGE_NOTEMPTY
) );
1090 sal_uInt16 nRetVal
= aBox
.Execute();
1092 if ( nRetVal
== RET_YES
)
1094 else if ( nRetVal
== RET_CANCEL
)
1101 bOk
= pDocSh
->GetDocFunc().MergeCells( aMergeOption
, rDoContents
, bRecord
, bApi
);
1105 SetCursor( nStartCol
, nStartRow
);
1106 //DoneBlockMode( sal_False);
1109 pDocSh
->UpdateOle(GetViewData());
1118 bool ScViewFunc::TestRemoveMerge()
1120 bool bMerged
= false;
1122 if (GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1124 ScDocument
* pDoc
= GetViewData()->GetDocument();
1125 if ( pDoc
->HasAttrib( aRange
, HASATTR_MERGED
) )
1132 static bool lcl_extendMergeRange(ScCellMergeOption
& rOption
, const ScRange
& rRange
)
1134 bool bExtended
= false;
1135 if (rOption
.mnStartCol
> rRange
.aStart
.Col())
1137 rOption
.mnStartCol
= rRange
.aStart
.Col();
1140 if (rOption
.mnStartRow
> rRange
.aStart
.Row())
1142 rOption
.mnStartRow
= rRange
.aStart
.Row();
1145 if (rOption
.mnEndCol
< rRange
.aEnd
.Col())
1147 rOption
.mnEndCol
= rRange
.aEnd
.Col();
1150 if (rOption
.mnEndRow
< rRange
.aEnd
.Row())
1152 rOption
.mnEndRow
= rRange
.aEnd
.Row();
1158 bool ScViewFunc::RemoveMerge( bool bRecord
)
1161 ScEditableTester
aTester( this );
1162 if (!aTester
.IsEditable())
1164 ErrorMessage(aTester
.GetMessageId());
1167 else if (GetViewData()->GetSimpleArea( aRange
) == SC_MARK_SIMPLE
)
1169 ScDocument
* pDoc
= GetViewData()->GetDocument();
1170 ScRange
aExtended( aRange
);
1171 pDoc
->ExtendMerge( aExtended
);
1172 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1173 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1174 ScCellMergeOption
aOption(aRange
.aStart
.Col(), aRange
.aStart
.Row(), aRange
.aEnd
.Col(), aRange
.aEnd
.Row());
1175 bool bExtended
= false;
1179 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1180 for (; itr
!= itrEnd
; ++itr
)
1183 aOption
.maTabs
.insert(i
);
1184 aExtended
.aStart
.SetTab(i
);
1185 aExtended
.aEnd
.SetTab(i
);
1186 pDoc
->ExtendMerge(aExtended
);
1187 pDoc
->ExtendOverlapped(aExtended
);
1189 // Expand the current range to be inclusive of all merged
1190 // areas on all sheets.
1191 bExtended
= lcl_extendMergeRange(aOption
, aExtended
);
1196 bool bOk
= pDocSh
->GetDocFunc().UnmergeCells(aOption
, bRecord
);
1197 aExtended
= aOption
.getFirstSingleRange();
1198 MarkRange( aExtended
);
1201 pDocSh
->UpdateOle(GetViewData());
1203 return true; //! bOk ??
1206 void ScViewFunc::FillSimple( FillDir eDir
, bool bRecord
)
1209 if (GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1211 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1212 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1213 bool bSuccess
= pDocSh
->GetDocFunc().FillSimple( aRange
, &rMark
, eDir
, bRecord
, false );
1216 pDocSh
->UpdateOle(GetViewData());
1221 ErrorMessage(STR_NOMULTISELECT
);
1224 void ScViewFunc::FillSeries( FillDir eDir
, FillCmd eCmd
, FillDateCmd eDateCmd
,
1225 double fStart
, double fStep
, double fMax
, bool bRecord
)
1228 if (GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1230 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1231 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1232 bool bSuccess
= pDocSh
->GetDocFunc().
1233 FillSeries( aRange
, &rMark
, eDir
, eCmd
, eDateCmd
,
1234 fStart
, fStep
, fMax
, bRecord
, false );
1237 pDocSh
->UpdateOle(GetViewData());
1240 HelperNotifyChanges::NotifyIfChangesListeners(*pDocSh
, aRange
);
1244 ErrorMessage(STR_NOMULTISELECT
);
1247 void ScViewFunc::FillAuto( FillDir eDir
, SCCOL nStartCol
, SCROW nStartRow
,
1248 SCCOL nEndCol
, SCROW nEndRow
, sal_uLong nCount
, bool bRecord
)
1250 SCTAB nTab
= GetViewData()->GetTabNo();
1251 ScRange
aRange( nStartCol
,nStartRow
,nTab
, nEndCol
,nEndRow
,nTab
);
1252 ScRange
aSourceRange( aRange
);
1253 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1254 const ScMarkData
& rMark
= GetViewData()->GetMarkData();
1255 bool bSuccess
= pDocSh
->GetDocFunc().
1256 FillAuto( aRange
, &rMark
, eDir
, nCount
, bRecord
, false );
1259 MarkRange( aRange
, false ); // aRange was modified in FillAuto
1260 pDocSh
->UpdateOle(GetViewData());
1263 if (ScModelObj
* pModelObj
= HelperNotifyChanges::getMustPropagateChangesModel(*pDocSh
))
1265 ScRangeList aChangeRanges
;
1266 ScRange
aChangeRange( aRange
);
1269 case FILL_TO_BOTTOM
:
1270 aChangeRange
.aStart
.SetRow( aSourceRange
.aEnd
.Row() + 1 );
1273 aChangeRange
.aEnd
.SetRow( aSourceRange
.aStart
.Row() - 1 );
1276 aChangeRange
.aStart
.SetCol( aSourceRange
.aEnd
.Col() + 1 );
1279 aChangeRange
.aEnd
.SetCol( aSourceRange
.aStart
.Col() - 1 );
1284 aChangeRanges
.Append( aChangeRange
);
1285 HelperNotifyChanges::Notify(*pModelObj
, aChangeRanges
);
1290 void ScViewFunc::FillTab( sal_uInt16 nFlags
, sal_uInt16 nFunction
, bool bSkipEmpty
, bool bAsLink
)
1292 //! allow source sheet to be protected
1293 ScEditableTester
aTester( this );
1294 if (!aTester
.IsEditable())
1296 ErrorMessage(aTester
.GetMessageId());
1300 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1301 ScDocument
* pDoc
= pDocSh
->GetDocument();
1302 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1303 SCTAB nTab
= GetViewData()->GetTabNo();
1304 bool bUndo(pDoc
->IsUndoEnabled());
1307 rMark
.MarkToSimple();
1308 bool bMulti
= rMark
.IsMultiMarked();
1310 rMark
.GetMultiMarkArea( aMarkRange
);
1311 else if (rMark
.IsMarked())
1312 rMark
.GetMarkArea( aMarkRange
);
1314 aMarkRange
= ScRange( GetViewData()->GetCurX(), GetViewData()->GetCurY(), nTab
);
1316 ScDocument
* pUndoDoc
= NULL
;
1320 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
1321 pUndoDoc
->InitUndo( pDoc
, nTab
, nTab
);
1323 ScMarkData::iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1324 for (; itr
!= itrEnd
; ++itr
)
1328 pUndoDoc
->AddUndoTab( i
, i
);
1329 aMarkRange
.aStart
.SetTab( i
);
1330 aMarkRange
.aEnd
.SetTab( i
);
1331 pDoc
->CopyToDocument( aMarkRange
, IDF_ALL
, bMulti
, pUndoDoc
);
1336 pDoc
->FillTabMarked( nTab
, rMark
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
1339 aMarkRange
.aStart
.SetTab( nTab
);
1340 aMarkRange
.aEnd
.SetTab( nTab
);
1341 pDoc
->FillTab( aMarkRange
, rMark
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
);
1345 { //! for ChangeTrack not until the end
1346 pDocSh
->GetUndoManager()->AddUndoAction(
1347 new ScUndoFillTable( pDocSh
, rMark
,
1348 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(), nTab
,
1349 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(), nTab
,
1350 pUndoDoc
, bMulti
, nTab
, nFlags
, nFunction
, bSkipEmpty
, bAsLink
) );
1353 pDocSh
->PostPaintGridAll();
1354 pDocSh
->PostDataChanged();
1357 /** Downward fill of selected cell(s) by double-clicking cross-hair cursor
1359 Extends a current selection down to the last non-empty cell of an adjacent
1360 column when the lower-right corner of the selection is double-clicked. It
1361 uses a left-adjoining non-empty column as a guide if such is available,
1362 otherwise a right-adjoining non-empty column is used.
1364 @author Kohei Yoshida (kohei@openoffice.org)
1366 @return No return value
1370 void ScViewFunc::FillCrossDblClick()
1373 GetViewData()->GetSimpleArea( aRange
);
1376 SCTAB nTab
= GetViewData()->GetCurPos().Tab();
1377 SCCOL nStartX
= aRange
.aStart
.Col();
1378 SCROW nStartY
= aRange
.aStart
.Row();
1379 SCCOL nEndX
= aRange
.aEnd
.Col();
1380 SCROW nEndY
= aRange
.aEnd
.Row();
1382 ScDocument
* pDoc
= GetViewData()->GetDocument();
1384 // Make sure the selection is not empty
1385 if ( pDoc
->IsBlockEmpty( nTab
, nStartX
, nStartY
, nEndX
, nEndY
) )
1388 if ( nEndY
< MAXROW
)
1392 SCCOL nMovX
= nStartX
- 1;
1393 SCROW nMovY
= nStartY
;
1395 if ( pDoc
->HasData( nMovX
, nStartY
, nTab
) &&
1396 pDoc
->HasData( nMovX
, nStartY
+ 1, nTab
) )
1398 pDoc
->FindAreaPos( nMovX
, nMovY
, nTab
, SC_MOVE_DOWN
);
1400 if ( nMovY
> nEndY
)
1402 FillAuto( FILL_TO_BOTTOM
, nStartX
, nStartY
, nEndX
, nEndY
,
1409 if ( nEndX
< MAXCOL
)
1411 SCCOL nMovX
= nEndX
+ 1;
1412 SCROW nMovY
= nStartY
;
1414 if ( pDoc
->HasData( nMovX
, nStartY
, nTab
) &&
1415 pDoc
->HasData( nMovX
, nStartY
+ 1, nTab
) )
1417 pDoc
->FindAreaPos( nMovX
, nMovY
, nTab
, SC_MOVE_DOWN
);
1419 if ( nMovY
> nEndY
)
1421 FillAuto( FILL_TO_BOTTOM
, nStartX
, nStartY
, nEndX
, nEndY
,
1430 void ScViewFunc::TransliterateText( sal_Int32 nType
)
1432 ScMarkData aFuncMark
= GetViewData()->GetMarkData();
1433 if ( !aFuncMark
.IsMarked() && !aFuncMark
.IsMultiMarked() )
1435 // no selection -> use cursor position
1437 ScAddress
aCursor( GetViewData()->GetCurX(), GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
1438 aFuncMark
.SetMarkArea( ScRange( aCursor
) );
1441 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().
1442 TransliterateText( aFuncMark
, nType
, true, false );
1445 GetViewData()->GetViewShell()->UpdateInputHandler();
1452 ScAutoFormatData
* ScViewFunc::CreateAutoFormatData()
1454 ScAutoFormatData
* pData
= NULL
;
1461 if (GetViewData()->GetSimpleArea(nStartCol
,nStartRow
,nStartTab
,nEndCol
,nEndRow
,nEndTab
) == SC_MARK_SIMPLE
)
1463 if ( nEndCol
-nStartCol
>= 3 && nEndRow
-nStartRow
>= 3 )
1465 ScDocument
* pDoc
= GetViewData()->GetDocument();
1466 pData
= new ScAutoFormatData
;
1467 pDoc
->GetAutoFormatData( nStartTab
, nStartCol
,nStartRow
,nEndCol
,nEndRow
, *pData
);
1474 void ScViewFunc::AutoFormat( sal_uInt16 nFormatNo
, bool bRecord
)
1477 if (GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1479 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1480 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1482 bool bSuccess
= pDocSh
->GetDocFunc().AutoFormat( aRange
, &rMark
, nFormatNo
, bRecord
, false );
1484 pDocSh
->UpdateOle(GetViewData());
1487 ErrorMessage(STR_NOMULTISELECT
);
1490 // Suchen & Ersetzen
1492 bool ScViewFunc::SearchAndReplace( const SvxSearchItem
* pSearchItem
,
1493 bool bAddUndo
, bool bIsApi
)
1495 SvxSearchDialogWrapper::SetSearchLabel(SL_Empty
);
1496 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1497 ScDocument
* pDoc
= pDocSh
->GetDocument();
1498 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1499 if (bAddUndo
&& !pDoc
->IsUndoEnabled())
1502 SCCOL nCol
, nOldCol
;
1503 SCROW nRow
, nOldRow
;
1504 SCTAB nTab
, nOldTab
;
1505 nCol
= nOldCol
= GetViewData()->GetCurX();
1506 nRow
= nOldRow
= GetViewData()->GetCurY();
1507 nTab
= nOldTab
= GetViewData()->GetTabNo();
1509 sal_uInt16 nCommand
= pSearchItem
->GetCommand();
1510 bool bAllTables
= pSearchItem
->IsAllTables();
1511 std::set
<SCTAB
> aOldSelectedTables
;
1512 SCTAB nLastTab
= pDoc
->GetTableCount() - 1;
1513 SCTAB nStartTab
, nEndTab
;
1518 std::set
<SCTAB
> aTmp(rMark
.begin(), rMark
.end());
1519 aOldSelectedTables
.swap(aTmp
);
1522 { //! at least one is always selected
1523 nStartTab
= rMark
.GetFirstSelected();
1524 nEndTab
= rMark
.GetLastSelected();
1527 if ( nCommand
== SVX_SEARCHCMD_FIND
1528 || nCommand
== SVX_SEARCHCMD_FIND_ALL
)
1531 //! account for bAttrib during Undo !!!
1533 SAL_WNODEPRECATED_DECLARATIONS_PUSH
1534 std::auto_ptr
<ScDocument
> pUndoDoc
;
1535 std::auto_ptr
<ScMarkData
> pUndoMark
;
1536 SAL_WNODEPRECATED_DECLARATIONS_POP
1540 pUndoMark
.reset(new ScMarkData(rMark
)); // Mark is being modified
1541 if ( nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1543 pUndoDoc
.reset(new ScDocument(SCDOCMODE_UNDO
));
1544 pUndoDoc
->InitUndo( pDoc
, nStartTab
, nEndTab
);
1549 { //! select all, after pUndoMark has been created
1550 for ( SCTAB j
= nStartTab
; j
<= nEndTab
; j
++ )
1552 rMark
.SelectTable( j
, true );
1556 DoneBlockMode(true); // don't delete mark
1559 // If search starts at the beginning don't ask again whether it shall start at the beginning
1561 if ( nCol
== 0 && nRow
== 0 && nTab
== nStartTab
&& !pSearchItem
->GetBackward() )
1564 bool bFound
= false;
1567 GetFrameWin()->EnterWait();
1568 ScRangeList aMatchedRanges
;
1569 if (pDoc
->SearchAndReplace(*pSearchItem
, nCol
, nRow
, nTab
, rMark
, aMatchedRanges
, aUndoStr
, pUndoDoc
.get()))
1575 GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction(
1576 new ScUndoReplace( GetViewData()->GetDocShell(), *pUndoMark
,
1578 aUndoStr
, pUndoDoc
.release(), pSearchItem
) );
1581 if (nCommand
== SVX_SEARCHCMD_FIND_ALL
|| nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1583 SfxViewFrame
* pViewFrm
= SfxViewFrame::Current();
1586 pViewFrm
->ShowChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId(), true);
1587 SfxChildWindow
* pWnd
= pViewFrm
->GetChildWindow(sc::SearchResultsDlgWrapper::GetChildWindowId());
1590 sc::SearchResultsDlg
* pDlg
= static_cast<sc::SearchResultsDlg
*>(pWnd
->GetWindow());
1592 pDlg
->FillResults(pDoc
, aMatchedRanges
);
1597 for (size_t i
= 0, n
= aMatchedRanges
.size(); i
< n
; ++i
)
1599 const ScRange
& r
= *aMatchedRanges
[i
];
1600 if (r
.aStart
.Tab() == nTab
)
1601 rMark
.SetMultiMarkArea(r
);
1605 break; // break 'while (TRUE)'
1607 else if ( bFirst
&& (nCommand
== SVX_SEARCHCMD_FIND
||
1608 nCommand
== SVX_SEARCHCMD_REPLACE
) )
1611 GetFrameWin()->LeaveWait();
1614 if ( nStartTab
== nEndTab
)
1615 SvxSearchDialogWrapper::SetSearchLabel(SL_EndSheet
);
1617 SvxSearchDialogWrapper::SetSearchLabel(SL_End
);
1619 ScDocument::GetSearchAndReplaceStart( *pSearchItem
, nCol
, nRow
);
1620 if (pSearchItem
->GetBackward())
1627 break; // break 'while (TRUE)'
1630 else // nothing found
1632 if ( nCommand
== SVX_SEARCHCMD_FIND_ALL
|| nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1634 pDocSh
->PostPaintGridAll(); // Mark
1637 GetFrameWin()->LeaveWait();
1639 SvxSearchDialogWrapper::SetSearchLabel(SL_NotFound
);
1641 break; // break 'while (TRUE)'
1645 if (!aOldSelectedTables
.empty())
1647 // restore originally selected table
1648 for (SCTAB i
= 0; i
<= nEndTab
; ++i
)
1649 rMark
.SelectTable(i
, false);
1651 std::set
<SCTAB
>::const_iterator itr
= aOldSelectedTables
.begin(), itrEnd
= aOldSelectedTables
.end();
1652 for (; itr
!= itrEnd
; ++itr
)
1653 rMark
.SelectTable(*itr
, true);
1656 { // if a table is selected as a "match" it remains selected.
1657 rMark
.SelectTable( nTab
, true );
1658 // It's a swap if only one table was selected before
1659 //! otherwise now one table more might be selected
1660 if ( aOldSelectedTables
.size() == 1 && nTab
!= nOldTab
)
1661 rMark
.SelectTable( nOldTab
, false );
1669 if ( nTab
!= GetViewData()->GetTabNo() )
1672 // if nothing is marked, DoneBlockMode, then marking can start
1673 // directly from this place via Shift-Cursor
1674 if (!rMark
.IsMarked() && !rMark
.IsMultiMarked())
1675 DoneBlockMode(true);
1677 AlignToCursor( nCol
, nRow
, SC_FOLLOW_JUMP
);
1678 SetCursor( nCol
, nRow
, true );
1680 if ( nCommand
== SVX_SEARCHCMD_REPLACE
1681 || nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1683 if ( nCommand
== SVX_SEARCHCMD_REPLACE
)
1685 pDocSh
->PostPaint( nCol
,nRow
,nTab
, nCol
,nRow
,nTab
, PAINT_GRID
);
1687 // jump to next cell if we replaced everything in the cell
1688 // where the cursor was positioned (but avoid switching tabs)
1689 if ( nCol
== nOldCol
&& nRow
== nOldRow
&& nTab
== nOldTab
)
1691 SvxSearchItem aSearchItem
= ScGlobal::GetSearchItem();
1692 aSearchItem
.SetCommand(SVX_SEARCHCMD_FIND
);
1693 aSearchItem
.SetWhich(SID_SEARCH_ITEM
);
1695 ScRangeList aMatchedRanges
;
1696 ScTable::UpdateSearchItemAddressForReplace( aSearchItem
, nCol
, nRow
);
1697 if ( pDoc
->SearchAndReplace( aSearchItem
, nCol
, nRow
, nTab
, rMark
, aMatchedRanges
, aUndoStr
, NULL
) &&
1698 ( nTab
== nOldTab
) &&
1699 ( nCol
!= nOldCol
|| nRow
!= nOldRow
) )
1701 SetCursor( nCol
, nRow
, true );
1706 pDocSh
->PostPaintGridAll();
1707 pDocSh
->SetDocumentModified();
1709 else if ( nCommand
== SVX_SEARCHCMD_FIND_ALL
)
1710 pDocSh
->PostPaintGridAll(); // mark
1711 GetFrameWin()->LeaveWait();
1718 void ScViewFunc::Solve( const ScSolveParam
& rParam
)
1720 ScDocument
* pDoc
= GetViewData()->GetDocument();
1722 SCCOL nDestCol
= rParam
.aRefVariableCell
.Col();
1723 SCROW nDestRow
= rParam
.aRefVariableCell
.Row();
1724 SCTAB nDestTab
= rParam
.aRefVariableCell
.Tab();
1726 ScEditableTester
aTester( pDoc
, nDestTab
, nDestCol
,nDestRow
, nDestCol
,nDestRow
);
1727 if (!aTester
.IsEditable())
1729 ErrorMessage(aTester
.GetMessageId());
1735 OUString aTargetValStr
;
1736 if ( rParam
.pStrTargetVal
!= NULL
)
1737 aTargetValStr
= *(rParam
.pStrTargetVal
);
1741 double nSolveResult
;
1743 GetFrameWin()->EnterWait();
1747 rParam
.aRefFormulaCell
.Col(),
1748 rParam
.aRefFormulaCell
.Row(),
1749 rParam
.aRefFormulaCell
.Tab(),
1750 nDestCol
, nDestRow
, nDestTab
,
1754 GetFrameWin()->LeaveWait();
1756 SvNumberFormatter
* pFormatter
= pDoc
->GetFormatTable();
1757 sal_uLong nFormat
= 0;
1758 const ScPatternAttr
* pPattern
= pDoc
->GetPattern( nDestCol
, nDestRow
, nDestTab
);
1760 nFormat
= pPattern
->GetNumberFormat( pFormatter
);
1762 pFormatter
->GetOutputString( nSolveResult
, nFormat
, aResStr
, &p
);
1766 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_0
);
1768 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_1
);
1772 aMsgStr
= ScGlobal::GetRscString( STR_MSSG_SOLVE_2
);
1773 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_3
);
1774 aMsgStr
+= aResStr
;
1775 aMsgStr
+= ScGlobal::GetRscString( STR_MSSG_SOLVE_4
);
1778 MessBox
aBox( GetViewData()->GetDialogParent(),
1779 WinBits(WB_YES_NO
| WB_DEF_NO
),
1780 ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0
), aMsgStr
);
1781 sal_uInt16 nRetVal
= aBox
.Execute();
1783 if ( RET_YES
== nRetVal
)
1784 EnterValue( nDestCol
, nDestRow
, nDestTab
, nSolveResult
);
1786 GetViewData()->GetViewShell()->UpdateInputHandler( true );
1792 void ScViewFunc::TabOp( const ScTabOpParam
& rParam
, bool bRecord
)
1795 if (GetViewData()->GetSimpleArea(aRange
) == SC_MARK_SIMPLE
)
1797 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1798 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1799 pDocSh
->GetDocFunc().TabOp( aRange
, &rMark
, rParam
, bRecord
, false );
1802 ErrorMessage(STR_NOMULTISELECT
);
1806 void ScViewFunc::MakeScenario( const OUString
& rName
, const OUString
& rComment
,
1807 const Color
& rColor
, sal_uInt16 nFlags
)
1809 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1810 ScMarkData
& rMark
= GetViewData()->GetMarkData();
1811 SCTAB nTab
= GetViewData()->GetTabNo();
1813 SCTAB nNewTab
= pDocSh
->MakeScenario( nTab
, rName
, rComment
, rColor
, nFlags
, rMark
);
1814 if (nFlags
& SC_SCENARIO_COPYALL
)
1815 SetTabNo( nNewTab
, true ); // SC_SCENARIO_COPYALL -> visible
1818 SfxBindings
& rBindings
= GetViewData()->GetBindings();
1819 rBindings
.Invalidate( SID_STATUS_DOCPOS
); // Statusbar
1820 rBindings
.Invalidate( SID_ROWCOL_SELCOUNT
); // Statusbar
1821 rBindings
.Invalidate( SID_TABLES_COUNT
);
1822 rBindings
.Invalidate( SID_SELECT_SCENARIO
);
1823 rBindings
.Invalidate( FID_TABLE_SHOW
);
1828 void ScViewFunc::ExtendScenario()
1830 ScEditableTester
aTester( this );
1831 if (!aTester
.IsEditable())
1833 ErrorMessage(aTester
.GetMessageId());
1837 // Undo: apply attributes
1839 ScDocument
* pDoc
= GetViewData()->GetDocument();
1840 ScPatternAttr
aPattern( pDoc
->GetPool() );
1841 aPattern
.GetItemSet().Put( ScMergeFlagAttr( SC_MF_SCENARIO
) );
1842 aPattern
.GetItemSet().Put( ScProtectionAttr( true ) );
1843 ApplySelectionPattern(aPattern
);
1847 void ScViewFunc::UseScenario( const OUString
& rName
)
1849 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1850 SCTAB nTab
= GetViewData()->GetTabNo();
1854 pDocSh
->UseScenario( nTab
, rName
);
1859 bool ScViewFunc::InsertTable( const OUString
& rName
, SCTAB nTab
, bool bRecord
)
1861 // Order Tabl/Name is inverted for DocFunc
1862 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().
1863 InsertTable( nTab
, rName
, bRecord
, false );
1865 SetTabNo( nTab
, true );
1873 bool ScViewFunc::InsertTables(std::vector
<OUString
>& aNames
, SCTAB nTab
,
1874 SCTAB nCount
, bool bRecord
)
1876 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1877 ScDocument
* pDoc
= pDocSh
->GetDocument();
1878 if (bRecord
&& !pDoc
->IsUndoEnabled())
1881 WaitObject
aWait( GetFrameWin() );
1885 pDoc
->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
1892 pDoc
->CreateValidTabNames(aNames
, nCount
);
1894 if (pDoc
->InsertTabs(nTab
, aNames
, false))
1896 pDocSh
->Broadcast( ScTablesHint( SC_TABS_INSERTED
, nTab
, nCount
) );
1903 pDocSh
->GetUndoManager()->AddUndoAction(
1904 new ScUndoInsertTables( pDocSh
, nTab
, aNames
));
1908 SetTabNo( nTab
, true );
1909 pDocSh
->PostPaintExtras();
1910 pDocSh
->SetDocumentModified();
1911 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
1921 bool ScViewFunc::AppendTable( const OUString
& rName
, bool bRecord
)
1923 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1924 ScDocument
* pDoc
= pDocSh
->GetDocument();
1925 if (bRecord
&& !pDoc
->IsUndoEnabled())
1928 WaitObject
aWait( GetFrameWin() );
1931 pDoc
->BeginDrawUndo(); // InsertTab creates a SdrUndoNewPage
1933 if (pDoc
->InsertTab( SC_TAB_APPEND
, rName
))
1935 SCTAB nTab
= pDoc
->GetTableCount()-1;
1937 pDocSh
->GetUndoManager()->AddUndoAction(
1938 new ScUndoInsertTab( pDocSh
, nTab
, true, rName
));
1939 GetViewData()->InsertTab( nTab
);
1940 SetTabNo( nTab
, true );
1941 pDocSh
->PostPaintExtras();
1942 pDocSh
->SetDocumentModified();
1943 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
1953 bool ScViewFunc::DeleteTable( SCTAB nTab
, bool bRecord
)
1955 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1956 ScDocument
* pDoc
= pDocSh
->GetDocument();
1958 bool bSuccess
= pDocSh
->GetDocFunc().DeleteTable( nTab
, bRecord
, false );
1961 SCTAB nNewTab
= nTab
;
1962 if ( nNewTab
>= pDoc
->GetTableCount() )
1964 SetTabNo( nNewTab
, true );
1969 //only use this method for undo for now, all sheets must be connected
1970 //this method doesn't support undo for now, merge it when it with the other method later
1971 bool ScViewFunc::DeleteTables( const SCTAB nTab
, SCTAB nSheets
)
1973 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
1974 ScDocument
* pDoc
= pDocSh
->GetDocument();
1975 bool bVbaEnabled
= pDoc
->IsInVBAMode();
1976 SCTAB nNewTab
= nTab
;
1977 WaitObject
aWait( GetFrameWin() );
1979 while ( nNewTab
> 0 && !pDoc
->IsVisible( nNewTab
) )
1982 if (pDoc
->DeleteTabs(nTab
, nSheets
))
1986 for (SCTAB aTab
= 0; aTab
< nSheets
; ++aTab
)
1989 bool bHasCodeName
= pDoc
->GetCodeName( nTab
+ aTab
, sCodeName
);
1991 VBA_DeleteModule( *pDocSh
, sCodeName
);
1995 pDocSh
->Broadcast( ScTablesHint( SC_TABS_DELETED
, nTab
, nSheets
) );
1996 if ( nNewTab
>= pDoc
->GetTableCount() )
1997 nNewTab
= pDoc
->GetTableCount() - 1;
1998 SetTabNo( nNewTab
, true );
2000 pDocSh
->PostPaintExtras();
2001 pDocSh
->SetDocumentModified();
2003 SfxApplication
* pSfxApp
= SFX_APP(); // Navigator
2004 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2005 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
2006 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2012 bool ScViewFunc::DeleteTables(const vector
<SCTAB
> &TheTabs
, bool bRecord
)
2014 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2015 ScDocument
* pDoc
= pDocSh
->GetDocument();
2016 bool bVbaEnabled
= pDoc
->IsInVBAMode();
2017 SCTAB nNewTab
= TheTabs
.front();
2018 WaitObject
aWait( GetFrameWin() );
2019 if (bRecord
&& !pDoc
->IsUndoEnabled())
2024 while ( nNewTab
> 0 && !pDoc
->IsVisible( nNewTab
) )
2027 bool bWasLinked
= false;
2028 ScDocument
* pUndoDoc
= NULL
;
2029 ScRefUndoData
* pUndoData
= NULL
;
2032 pUndoDoc
= new ScDocument( SCDOCMODE_UNDO
);
2033 SCTAB nCount
= pDoc
->GetTableCount();
2036 for(unsigned int i
=0; i
<TheTabs
.size(); ++i
)
2038 SCTAB nTab
= TheTabs
[i
];
2040 pUndoDoc
->InitUndo( pDoc
, nTab
,nTab
, true,true ); // incl. column/fow flags
2042 pUndoDoc
->AddUndoTab( nTab
,nTab
, true,true ); // incl. column/fow flags
2044 pDoc
->CopyToDocument(0,0,nTab
, MAXCOL
,MAXROW
,nTab
, IDF_ALL
,false, pUndoDoc
);
2045 pDoc
->GetName( nTab
, aOldName
);
2046 pUndoDoc
->RenameTab( nTab
, aOldName
, false );
2047 if (pDoc
->IsLinked(nTab
))
2050 pUndoDoc
->SetLink( nTab
, pDoc
->GetLinkMode(nTab
), pDoc
->GetLinkDoc(nTab
),
2051 pDoc
->GetLinkFlt(nTab
), pDoc
->GetLinkOpt(nTab
),
2052 pDoc
->GetLinkTab(nTab
),
2053 pDoc
->GetLinkRefreshDelay(nTab
) );
2055 if ( pDoc
->IsScenario(nTab
) )
2057 pUndoDoc
->SetScenario( nTab
, true );
2060 sal_uInt16 nScenFlags
;
2061 pDoc
->GetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2062 pUndoDoc
->SetScenarioData( nTab
, aComment
, aColor
, nScenFlags
);
2063 bool bActive
= pDoc
->IsActiveScenario( nTab
);
2064 pUndoDoc
->SetActiveScenario( nTab
, bActive
);
2066 pUndoDoc
->SetVisible( nTab
, pDoc
->IsVisible( nTab
) );
2067 pUndoDoc
->SetTabBgColor( nTab
, pDoc
->GetTabBgColor(nTab
) );
2068 pUndoDoc
->SetSheetEvents( nTab
, pDoc
->GetSheetEvents( nTab
) );
2069 pUndoDoc
->SetLayoutRTL( nTab
, pDoc
->IsLayoutRTL( nTab
) );
2071 if ( pDoc
->IsTabProtected( nTab
) )
2072 pUndoDoc
->SetTabProtection(nTab
, pDoc
->GetTabProtection(nTab
));
2074 // Drawing-Layer is responsible for its Undo !!!
2075 // pUndoDoc->TransferDrawPage(pDoc, nTab,nTab);
2078 pUndoDoc
->AddUndoTab( 0, nCount
-1 ); // all Tabs for references
2080 pDoc
->BeginDrawUndo(); // DeleteTab creates a SdrUndoDelPage
2082 pUndoData
= new ScRefUndoData( pDoc
);
2085 bool bDelDone
= false;
2087 for(int i
=TheTabs
.size()-1; i
>=0; --i
)
2090 bool bHasCodeName
= pDoc
->GetCodeName( TheTabs
[i
], sCodeName
);
2091 if (pDoc
->DeleteTab(TheTabs
[i
]))
2098 VBA_DeleteModule( *pDocSh
, sCodeName
);
2101 pDocSh
->Broadcast( ScTablesHint( SC_TAB_DELETED
, TheTabs
[i
] ) );
2106 pDocSh
->GetUndoManager()->AddUndoAction(
2107 new ScUndoDeleteTab( GetViewData()->GetDocShell(), TheTabs
,
2108 pUndoDoc
, pUndoData
));
2114 if ( nNewTab
>= pDoc
->GetTableCount() )
2115 nNewTab
= pDoc
->GetTableCount() - 1;
2117 SetTabNo( nNewTab
, true );
2121 pDocSh
->UpdateLinks(); // update Link-Manager
2122 GetViewData()->GetBindings().Invalidate(SID_LINKS
);
2125 pDocSh
->PostPaintExtras();
2126 pDocSh
->SetDocumentModified();
2129 SfxApplication
* pSfxApp
= SFX_APP(); // Navigator
2130 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2131 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_DBAREAS_CHANGED
) );
2132 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREALINKS_CHANGED
) );
2143 bool ScViewFunc::RenameTable( const OUString
& rName
, SCTAB nTab
)
2145 // order Table/Name is inverted for DocFunc
2146 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().
2147 RenameTable( nTab
, rName
, true, false );
2150 // the table name might be part of a formula
2151 GetViewData()->GetViewShell()->UpdateInputHandler();
2157 bool ScViewFunc::SetTabBgColor( const Color
& rColor
, SCTAB nTab
)
2159 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab
, rColor
, true, false );
2162 GetViewData()->GetViewShell()->UpdateInputHandler();
2167 bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List
& rUndoSetTabBgColorInfoList
)
2169 bool bSuccess
= GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList
, true, false );
2172 GetViewData()->GetViewShell()->UpdateInputHandler();
2177 void ScViewFunc::InsertAreaLink( const OUString
& rFile
,
2178 const OUString
& rFilter
, const OUString
& rOptions
,
2179 const OUString
& rSource
, sal_uLong nRefresh
)
2181 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2182 SCCOL nPosX
= GetViewData()->GetCurX();
2183 SCROW nPosY
= GetViewData()->GetCurY();
2184 SCTAB nTab
= GetViewData()->GetTabNo();
2185 ScAddress
aPos( nPosX
, nPosY
, nTab
);
2187 pDocSh
->GetDocFunc().InsertAreaLink( rFile
, rFilter
, rOptions
, rSource
, aPos
, nRefresh
, false, false );
2191 void ScViewFunc::InsertTableLink( const OUString
& rFile
,
2192 const OUString
& rFilter
, const OUString
& rOptions
,
2193 const OUString
& rTabName
)
2195 OUString aFilterName
= rFilter
;
2196 OUString aOpt
= rOptions
;
2197 OUString aURL
= rFile
;
2198 ScDocumentLoader
aLoader( aURL
, aFilterName
, aOpt
);
2199 if (!aLoader
.IsError())
2201 ScDocShell
* pSrcSh
= aLoader
.GetDocShell();
2202 ScDocument
* pSrcDoc
= pSrcSh
->GetDocument();
2203 SCTAB nTab
= MAXTAB
+1;
2204 if (rTabName
.isEmpty()) // no name given -> first table
2209 SCTAB nCount
= pSrcDoc
->GetTableCount();
2210 for (SCTAB i
=0; i
<nCount
; i
++)
2212 pSrcDoc
->GetName( i
, aTemp
);
2213 if ( aTemp
.equals(rTabName
) )
2218 if ( nTab
<= MAXTAB
)
2219 ImportTables( pSrcSh
, 1, &nTab
, true,
2220 GetViewData()->GetTabNo() );
2224 // Copy/link tables from another document
2226 void ScViewFunc::ImportTables( ScDocShell
* pSrcShell
,
2227 SCTAB nCount
, const SCTAB
* pSrcTabs
, bool bLink
,SCTAB nTab
)
2229 ScDocument
* pSrcDoc
= pSrcShell
->GetDocument();
2231 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2232 ScDocument
* pDoc
= pDocSh
->GetDocument();
2233 bool bUndo(pDoc
->IsUndoEnabled());
2235 bool bError
= false;
2239 if (pSrcDoc
->GetDrawLayer())
2240 pDocSh
->MakeDrawLayer();
2243 pDoc
->BeginDrawUndo(); // drawing layer must do its own undo actions
2245 SCTAB nInsCount
= 0;
2247 for( i
=0; i
<nCount
; i
++ )
2248 { // insert sheets first and update all references
2250 pSrcDoc
->GetName( pSrcTabs
[i
], aName
);
2251 pDoc
->CreateValidTabName( aName
);
2252 if ( !pDoc
->InsertTab( nTab
+i
, aName
) )
2254 bError
= true; // total error
2259 for (i
=0; i
<nCount
&& !bError
; i
++)
2261 SCTAB nSrcTab
= pSrcTabs
[i
];
2262 SCTAB nDestTab1
=nTab
+i
;
2263 sal_uLong nErrVal
= pDocSh
->TransferTab( *pSrcShell
, nSrcTab
, nDestTab1
,
2264 false, false ); // no insert
2268 case 0: // internal error or full of errors
2278 bRefs
= bName
= true;
2286 sfx2::LinkManager
* pLinkManager
= pDoc
->GetLinkManager();
2288 SfxMedium
* pMed
= pSrcShell
->GetMedium();
2289 OUString aFileName
= pMed
->GetName();
2290 OUString aFilterName
;
2291 if (pMed
->GetFilter())
2292 aFilterName
= pMed
->GetFilter()->GetFilterName();
2293 OUString aOptions
= ScDocumentLoader::GetOptions(*pMed
);
2295 bool bWasThere
= pDoc
->HasLink( aFileName
, aFilterName
, aOptions
);
2297 sal_uLong nRefresh
= 0;
2299 for (i
=0; i
<nInsCount
; i
++)
2301 pSrcDoc
->GetName( pSrcTabs
[i
], aTabStr
);
2302 pDoc
->SetLink( nTab
+i
, SC_LINK_NORMAL
,
2303 aFileName
, aFilterName
, aOptions
, aTabStr
, nRefresh
);
2306 if (!bWasThere
) // Insert link only once per source document
2308 ScTableLink
* pLink
= new ScTableLink( pDocSh
, aFileName
, aFilterName
, aOptions
, nRefresh
);
2309 pLink
->SetInCreate( true );
2310 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, aFileName
, &aFilterName
);
2312 pLink
->SetInCreate( false );
2314 SfxBindings
& rBindings
= GetViewData()->GetBindings();
2315 rBindings
.Invalidate( SID_LINKS
);
2322 pDocSh
->GetUndoManager()->AddUndoAction(
2323 new ScUndoImportTab( pDocSh
, nTab
, nCount
) );
2326 for (i
=0; i
<nInsCount
; i
++)
2327 GetViewData()->InsertTab(nTab
);
2328 SetTabNo(nTab
,true);
2329 pDocSh
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
,
2330 PAINT_GRID
| PAINT_TOP
| PAINT_LEFT
| PAINT_EXTRAS
);
2332 SfxApplication
* pSfxApp
= SFX_APP();
2333 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2334 pSfxApp
->Broadcast( SfxSimpleHint( SC_HINT_AREAS_CHANGED
) );
2336 pDocSh
->PostPaintExtras();
2337 pDocSh
->PostPaintGridAll();
2338 pDocSh
->SetDocumentModified();
2341 ErrorMessage(STR_ABSREFLOST
);
2343 ErrorMessage(STR_NAMECONFLICT
);
2346 // Move/Copy table to another document
2348 void ScViewFunc::MoveTable(
2349 sal_uInt16 nDestDocNo
, SCTAB nDestTab
, bool bCopy
, const OUString
* pNewTabName
)
2351 ScDocument
* pDoc
= GetViewData()->GetDocument();
2352 ScDocShell
* pDocShell
= GetViewData()->GetDocShell();
2353 ScDocument
* pDestDoc
= NULL
;
2354 ScDocShell
* pDestShell
= NULL
;
2355 ScTabViewShell
* pDestViewSh
= NULL
;
2356 bool bUndo (pDoc
->IsUndoEnabled());
2357 bool bRename
= pNewTabName
&& !pNewTabName
->isEmpty();
2359 bool bNewDoc
= (nDestDocNo
== SC_DOC_NEW
);
2362 nDestTab
= 0; // firstly insert
2364 // execute without SFX_CALLMODE_RECORD, because already contained in move command
2366 OUString
aUrl("private:factory/" STRING_SCAPP
);
2367 SfxStringItem
aItem( SID_FILE_NAME
, aUrl
);
2368 SfxStringItem
aTarget( SID_TARGETNAME
, OUString("_blank") );
2370 const SfxPoolItem
* pRetItem
= GetViewData()->GetDispatcher().Execute(
2371 SID_OPENDOC
, SFX_CALLMODE_API
|SFX_CALLMODE_SYNCHRON
, &aItem
, &aTarget
, 0L );
2374 if ( pRetItem
->ISA( SfxObjectItem
) )
2375 pDestShell
= PTR_CAST( ScDocShell
, ((const SfxObjectItem
*)pRetItem
)->GetShell() );
2376 else if ( pRetItem
->ISA( SfxViewFrameItem
) )
2378 SfxViewFrame
* pFrm
= ((const SfxViewFrameItem
*)pRetItem
)->GetFrame();
2380 pDestShell
= PTR_CAST( ScDocShell
, pFrm
->GetObjectShell() );
2383 pDestViewSh
= pDestShell
->GetBestViewShell();
2387 pDestShell
= ScDocShell::GetShellByNum( nDestDocNo
);
2391 OSL_FAIL("Dest-Doc nicht gefunden !!!");
2395 ScMarkData
& rMark
= GetViewData()->GetMarkData();
2396 if (bRename
&& rMark
.GetSelectCount() != 1)
2398 // Custom sheet name is provided, but more than one sheet is selected.
2399 // We don't support this scenario at the moment.
2403 pDestDoc
= pDestShell
->GetDocument();
2405 SCTAB nTab
= GetViewData()->GetTabNo();
2407 if (pDestDoc
!= pDoc
)
2411 while (pDestDoc
->GetTableCount() > 1)
2412 pDestDoc
->DeleteTab(0);
2413 pDestDoc
->RenameTab( 0, OUString("______42_____"),
2417 SCTAB nTabCount
= pDoc
->GetTableCount();
2418 SCTAB nTabSelCount
= rMark
.GetSelectCount();
2420 vector
<SCTAB
> TheTabs
;
2422 for(SCTAB i
=0; i
<nTabCount
; ++i
)
2424 if(rMark
.GetTableSelect(i
))
2427 pDoc
->GetName( i
, aTabName
);
2428 TheTabs
.push_back(i
);
2429 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
2431 if((!pDoc
->IsVisible(j
))&&(pDoc
->IsScenario(j
)))
2433 pDoc
->GetName( j
, aTabName
);
2434 TheTabs
.push_back(j
);
2442 GetFrameWin()->EnterWait();
2444 if (pDoc
->GetDrawLayer())
2445 pDestShell
->MakeDrawLayer();
2447 if (!bNewDoc
&& bUndo
)
2448 pDestDoc
->BeginDrawUndo(); // drawing layer must do its own undo actions
2450 sal_uLong nErrVal
=1;
2451 if(nDestTab
==SC_TAB_APPEND
)
2452 nDestTab
=pDestDoc
->GetTableCount();
2453 SCTAB nDestTab1
=nDestTab
;
2455 for( sal_uInt16 j
=0; j
<TheTabs
.size(); ++j
, ++nDestTab1
)
2456 { // insert sheets first and update all references
2459 aName
= *pNewTabName
;
2461 pDoc
->GetName( TheTabs
[j
], aName
);
2463 pDestDoc
->CreateValidTabName( aName
);
2464 if ( !pDestDoc
->InsertTab( nDestTab1
, aName
) )
2466 nErrVal
= 0; // total error
2469 ScRange
aRange( 0, 0, TheTabs
[j
], MAXCOL
, MAXROW
, TheTabs
[j
] );
2470 aParam
.maRanges
.Append(aRange
);
2472 pDoc
->SetClipParam(aParam
);
2475 nDestTab1
= nDestTab
;
2476 for(sal_uInt16 i
=0; i
<TheTabs
.size();++i
)
2478 nErrVal
= pDestShell
->TransferTab( *pDocShell
, TheTabs
[i
], static_cast<SCTAB
>(nDestTab1
), false, false );
2483 if (!bNewDoc
&& bUndo
)
2485 pDestDoc
->GetName(nDestTab
, sName
);
2486 pDestShell
->GetUndoManager()->AddUndoAction(
2487 new ScUndoImportTab( pDestShell
, nDestTab
,
2488 static_cast<SCTAB
>(TheTabs
.size())));
2493 pDestShell
->GetUndoManager()->Clear();
2496 GetFrameWin()->LeaveWait();
2499 case 0: // internal error or full of errors
2501 ErrorMessage(STR_TABINSERT_ERROR
);
2506 ErrorMessage(STR_ABSREFLOST
);
2509 ErrorMessage(STR_NAMECONFLICT
);
2513 ErrorMessage(STR_ABSREFLOST
);
2514 ErrorMessage(STR_NAMECONFLICT
);
2523 if(nTabCount
!=nTabSelCount
)
2524 DeleteTables(TheTabs
); // incl. Paint & Undo
2526 ErrorMessage(STR_TABREMOVE_ERROR
);
2531 // ChartListenerCollection must be updated before DeleteTab
2532 if ( pDestDoc
->IsChartListenerCollectionNeedsUpdate() )
2533 pDestDoc
->UpdateChartListenerCollection();
2535 pDestDoc
->DeleteTab(static_cast<SCTAB
>(TheTabs
.size())); // old first table
2538 // Make sure to clear the cached page view after sheet
2539 // deletion, which still points to the sdr page belonging to
2540 // the deleted sheet.
2541 SdrView
* pSdrView
= pDestViewSh
->GetSdrView();
2543 pSdrView
->ClearPageView();
2545 pDestViewSh
->TabChanged(); // Pages auf dem Drawing-Layer
2547 pDestShell
->PostPaint( 0,0,0, MAXCOL
,MAXROW
,MAXTAB
,
2548 PAINT_GRID
| PAINT_TOP
| PAINT_LEFT
|
2549 PAINT_EXTRAS
| PAINT_SIZE
);
2550 // PAINT_SIZE for outline
2554 pDestShell
->Broadcast( ScTablesHint( SC_TAB_INSERTED
, nDestTab
) );
2555 pDestShell
->PostPaintExtras();
2556 pDestShell
->PostPaintGridAll();
2561 pDestShell
->SetDocumentModified();
2562 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2566 // Move or copy within the same document.
2567 SCTAB nTabCount
= pDoc
->GetTableCount();
2569 SAL_WNODEPRECATED_DECLARATIONS_PUSH
2570 auto_ptr
< vector
<SCTAB
> > pSrcTabs(new vector
<SCTAB
>);
2571 auto_ptr
< vector
<SCTAB
> > pDestTabs(new vector
<SCTAB
>);
2572 auto_ptr
< vector
<OUString
> > pTabNames(new vector
<OUString
>);
2573 auto_ptr
< vector
<OUString
> > pDestNames(NULL
);
2574 SAL_WNODEPRECATED_DECLARATIONS_POP
2575 pSrcTabs
->reserve(nTabCount
);
2576 pDestTabs
->reserve(nTabCount
);
2577 pTabNames
->reserve(nTabCount
);
2580 for(SCTAB i
=0;i
<nTabCount
;i
++)
2582 if(rMark
.GetTableSelect(i
))
2585 pDoc
->GetName( i
, aTabName
);
2586 pTabNames
->push_back(aTabName
);
2588 for(SCTAB j
=i
+1;j
<nTabCount
;j
++)
2590 if((!pDoc
->IsVisible(j
))&&(pDoc
->IsScenario(j
)))
2592 pDoc
->GetName( j
, aTabName
);
2593 pTabNames
->push_back(aTabName
);
2602 pDoc
->BeginDrawUndo(); // drawing layer must do its own undo actions
2604 pDoc
->GetName( nDestTab
, aDestName
);
2605 SCTAB nDestTab1
=nDestTab
;
2607 for (size_t j
= 0, n
= pTabNames
->size(); j
< n
; ++j
)
2609 nTabCount
= pDoc
->GetTableCount();
2610 const OUString
& rStr
= (*pTabNames
)[j
];
2611 if(!pDoc
->GetTable(rStr
,nMovTab
))
2615 if(!pDoc
->GetTable(aDestName
,nDestTab1
))
2617 nDestTab1
=nTabCount
;
2619 pDocShell
->MoveTable( nMovTab
, nDestTab1
, bCopy
, false ); // Undo is here
2621 if(bCopy
&& pDoc
->IsScenario(nMovTab
))
2627 pDoc
->GetScenarioData(nMovTab
, aComment
,aColor
, nFlags
);
2628 pDoc
->SetScenario(nDestTab1
,true);
2629 pDoc
->SetScenarioData(nDestTab1
,aComment
,aColor
,nFlags
);
2630 bool bActive
= pDoc
->IsActiveScenario(nMovTab
);
2631 pDoc
->SetActiveScenario( nDestTab1
, bActive
);
2632 bool bVisible
=pDoc
->IsVisible(nMovTab
);
2633 pDoc
->SetVisible(nDestTab1
,bVisible
);
2636 pSrcTabs
->push_back(nMovTab
);
2640 if(!pDoc
->GetTable(rStr
,nDestTab1
))
2642 nDestTab1
=nTabCount
;
2646 pDestTabs
->push_back(nDestTab1
);
2649 // Rename must be done after all sheets have been moved.
2652 pDestNames
.reset(new vector
<OUString
>);
2653 size_t n
= pDestTabs
->size();
2654 pDestNames
->reserve(n
);
2655 for (size_t j
= 0; j
< n
; ++j
)
2657 SCTAB nRenameTab
= (*pDestTabs
)[j
];
2658 OUString aTabName
= *pNewTabName
;
2659 pDoc
->CreateValidTabName( aTabName
);
2660 pDestNames
->push_back(aTabName
);
2661 pDoc
->RenameTab(nRenameTab
, aTabName
);
2665 // No need to keep this around when we are not renaming.
2668 nTab
= GetViewData()->GetTabNo();
2674 pDocShell
->GetUndoManager()->AddUndoAction(
2676 pDocShell
, pSrcTabs
.release(), pDestTabs
.release(), pDestNames
.release()));
2680 pDocShell
->GetUndoManager()->AddUndoAction(
2682 pDocShell
, pSrcTabs
.release(), pDestTabs
.release(), pTabNames
.release(), pDestNames
.release()));
2686 SCTAB nNewTab
= nDestTab
;
2687 if (nNewTab
== SC_TAB_APPEND
)
2688 nNewTab
= pDoc
->GetTableCount()-1;
2689 else if (!bCopy
&& nTab
<nDestTab
)
2692 SetTabNo( nNewTab
, true );
2694 //#i29848# adjust references to data on the copied sheet
2696 ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc
, pDestDoc
, nTab
, nNewTab
);
2701 void ScViewFunc::ShowTable( const std::vector
<OUString
>& rNames
)
2703 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2704 ScDocument
* pDoc
= pDocSh
->GetDocument();
2705 bool bUndo(pDoc
->IsUndoEnabled());
2707 std::vector
<SCTAB
> undoTabs
;
2713 for (std::vector
<OUString
>::const_iterator itr
=rNames
.begin(), itrEnd
= rNames
.end(); itr
!=itrEnd
; ++itr
)
2716 if (pDoc
->GetTable(aName
, nPos
))
2718 pDoc
->SetVisible( nPos
, true );
2719 SetTabNo( nPos
, true );
2720 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2724 undoTabs
.push_back(nPos
);
2731 pDocSh
->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh
, undoTabs
, true ) );
2733 pDocSh
->PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
2734 pDocSh
->SetDocumentModified();
2739 void ScViewFunc::HideTable( const ScMarkData
& rMark
)
2741 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2742 ScDocument
* pDoc
= pDocSh
->GetDocument();
2743 bool bUndo(pDoc
->IsUndoEnabled());
2745 SCTAB nTabCount
= pDoc
->GetTableCount();
2747 SCTAB nTabSelCount
= rMark
.GetSelectCount();
2749 // check to make sure we won't hide all sheets. we need at least one visible at all times.
2750 for ( SCTAB i
=0; i
< nTabCount
&& nVisible
<= nTabSelCount
; i
++ )
2751 if (pDoc
->IsVisible(i
))
2754 if (nVisible
> nTabSelCount
)
2757 ScMarkData::MarkedTabsType::const_iterator it
;
2758 std::vector
<SCTAB
> undoTabs
;
2760 ScMarkData::MarkedTabsType selectedTabs
= rMark
.GetSelectedTabs();
2761 for (it
=selectedTabs
.begin(); it
!=selectedTabs
.end(); ++it
)
2764 if (pDoc
->IsVisible( nTab
))
2766 pDoc
->SetVisible( nTab
, false );
2768 pDocSh
->Broadcast( ScTablesHint( SC_TAB_HIDDEN
, nTab
) );
2769 SetTabNo( nTab
, true );
2772 undoTabs
.push_back(nTab
);
2777 pDocSh
->GetUndoManager()->AddUndoAction( new ScUndoShowHideTab( pDocSh
, undoTabs
, false ) );
2781 SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED
) );
2782 pDocSh
->PostPaint(0,0,0,MAXCOL
,MAXROW
,MAXTAB
, PAINT_EXTRAS
);
2783 pDocSh
->SetDocumentModified();
2788 void ScViewFunc::InsertSpecialChar( const OUString
& rStr
, const Font
& rFont
)
2790 ScEditableTester
aTester( this );
2791 if (!aTester
.IsEditable())
2793 ErrorMessage(aTester
.GetMessageId());
2797 const sal_Unicode
* pChar
= rStr
.getStr();
2798 ScTabViewShell
* pViewShell
= GetViewData()->GetViewShell();
2799 SvxFontItem
aFontItem( rFont
.GetFamily(),
2801 rFont
.GetStyleName(),
2806 // if string contains WEAK characters, set all fonts
2808 ScDocument
* pDoc
= GetViewData()->GetDocument();
2809 if ( pDoc
->HasStringWeakCharacters( rStr
) )
2810 nScript
= SCRIPTTYPE_LATIN
| SCRIPTTYPE_ASIAN
| SCRIPTTYPE_COMPLEX
;
2812 nScript
= pDoc
->GetStringScriptType( rStr
);
2814 SvxScriptSetItem
aSetItem( SID_ATTR_CHAR_FONT
, pViewShell
->GetPool() );
2815 aSetItem
.PutItemForScriptType( nScript
, aFontItem
);
2816 ApplyUserItemSet( aSetItem
.GetItemSet() );
2819 pViewShell
->TabKeyInput( KeyEvent( *(pChar
++), KeyCode() ) );
2823 void ScViewFunc::UpdateLineAttrs( SvxBorderLine
& rLine
,
2824 const SvxBorderLine
* pDestLine
,
2825 const SvxBorderLine
* pSrcLine
,
2828 if ( pSrcLine
&& pDestLine
)
2832 rLine
.SetColor ( pSrcLine
->GetColor() );
2833 rLine
.SetBorderLineStyle(pDestLine
->GetBorderLineStyle());
2834 rLine
.SetWidth ( pDestLine
->GetWidth() );
2838 rLine
.SetColor ( pDestLine
->GetColor() );
2839 rLine
.SetBorderLineStyle(pSrcLine
->GetBorderLineStyle());
2840 rLine
.SetWidth ( pSrcLine
->GetWidth() );
2846 #define SET_LINE_ATTRIBUTES(LINE,BOXLINE) \
2847 pBoxLine = aBoxItem.Get##LINE(); \
2852 UpdateLineAttrs( aLine, pBoxLine, pLine, bColorOnly ); \
2853 aBoxItem.SetLine( &aLine, BOXLINE ); \
2856 aBoxItem.SetLine( NULL, BOXLINE ); \
2860 void ScViewFunc::SetSelectionFrameLines( const SvxBorderLine
* pLine
,
2863 // Not editable only due to a matrix? Attribute is ok anyhow.
2864 bool bOnlyNotBecauseOfMatrix
;
2865 if ( !SelectionEditable( &bOnlyNotBecauseOfMatrix
) && !bOnlyNotBecauseOfMatrix
)
2867 ErrorMessage(STR_PROTECTIONERR
);
2871 ScDocument
* pDoc
= GetViewData()->GetDocument();
2872 ScMarkData
aFuncMark( GetViewData()->GetMarkData() ); // local copy for UnmarkFiltered
2873 ScViewUtil::UnmarkFiltered( aFuncMark
, pDoc
);
2874 ScDocShell
* pDocSh
= GetViewData()->GetDocShell();
2875 const ScPatternAttr
* pSelAttrs
= GetSelectionPattern();
2876 const SfxItemSet
& rSelItemSet
= pSelAttrs
->GetItemSet();
2878 const SfxPoolItem
* pBorderAttr
= NULL
;
2879 SfxItemState eItemState
= rSelItemSet
.GetItemState( ATTR_BORDER
, true, &pBorderAttr
);
2881 const SfxPoolItem
* pTLBRItem
= 0;
2882 SfxItemState eTLBRState
= rSelItemSet
.GetItemState( ATTR_BORDER_TLBR
, true, &pTLBRItem
);
2884 const SfxPoolItem
* pBLTRItem
= 0;
2885 SfxItemState eBLTRState
= rSelItemSet
.GetItemState( ATTR_BORDER_BLTR
, true, &pBLTRItem
);
2887 // any of the lines visible?
2888 if( (eItemState
!= SFX_ITEM_DEFAULT
) || (eTLBRState
!= SFX_ITEM_DEFAULT
) || (eBLTRState
!= SFX_ITEM_DEFAULT
) )
2890 // none of the lines don't care?
2891 if( (eItemState
!= SFX_ITEM_DONTCARE
) && (eTLBRState
!= SFX_ITEM_DONTCARE
) && (eBLTRState
!= SFX_ITEM_DONTCARE
) )
2893 boost::scoped_ptr
<SfxItemSet
> pOldSet(new SfxItemSet(
2896 ATTR_PATTERN_END
));
2897 boost::scoped_ptr
<SfxItemSet
> pNewSet(new SfxItemSet(
2900 ATTR_PATTERN_END
));
2903 const SvxBorderLine
* pBoxLine
= NULL
;
2904 SvxBorderLine aLine
;
2906 // here pBoxLine is used
2910 SvxBoxItem
aBoxItem( *(const SvxBoxItem
*)pBorderAttr
);
2911 SvxBoxInfoItem
aBoxInfoItem( ATTR_BORDER_INNER
);
2913 SET_LINE_ATTRIBUTES(Top
,BOX_LINE_TOP
)
2914 SET_LINE_ATTRIBUTES(Bottom
,BOX_LINE_BOTTOM
)
2915 SET_LINE_ATTRIBUTES(Left
,BOX_LINE_LEFT
)
2916 SET_LINE_ATTRIBUTES(Right
,BOX_LINE_RIGHT
)
2918 aBoxInfoItem
.SetLine( aBoxItem
.GetTop(), BOXINFO_LINE_HORI
);
2919 aBoxInfoItem
.SetLine( aBoxItem
.GetLeft(), BOXINFO_LINE_VERT
);
2920 aBoxInfoItem
.ResetFlags(); // set Lines to Valid
2922 pOldSet
->Put( *pBorderAttr
);
2923 pNewSet
->Put( aBoxItem
);
2924 pNewSet
->Put( aBoxInfoItem
);
2927 if( pTLBRItem
&& ((const SvxLineItem
*)pTLBRItem
)->GetLine() )
2929 SvxLineItem
aTLBRItem( *(const SvxLineItem
*)pTLBRItem
);
2930 UpdateLineAttrs( aLine
, aTLBRItem
.GetLine(), pLine
, bColorOnly
);
2931 aTLBRItem
.SetLine( &aLine
);
2932 pOldSet
->Put( *pTLBRItem
);
2933 pNewSet
->Put( aTLBRItem
);
2936 if( pBLTRItem
&& ((const SvxLineItem
*)pBLTRItem
)->GetLine() )
2938 SvxLineItem
aBLTRItem( *(const SvxLineItem
*)pBLTRItem
);
2939 UpdateLineAttrs( aLine
, aBLTRItem
.GetLine(), pLine
, bColorOnly
);
2940 aBLTRItem
.SetLine( &aLine
);
2941 pOldSet
->Put( *pBLTRItem
);
2942 pNewSet
->Put( aBLTRItem
);
2945 ApplyAttributes( pNewSet
.get(), pOldSet
.get() );
2947 else // if ( eItemState == SFX_ITEM_DONTCARE )
2949 aFuncMark
.MarkToMulti();
2950 pDoc
->ApplySelectionLineStyle( aFuncMark
, pLine
, bColorOnly
);
2954 aFuncMark
.GetMultiMarkArea( aMarkRange
);
2955 SCCOL nStartCol
= aMarkRange
.aStart
.Col();
2956 SCROW nStartRow
= aMarkRange
.aStart
.Row();
2957 SCTAB nStartTab
= aMarkRange
.aStart
.Tab();
2958 SCCOL nEndCol
= aMarkRange
.aEnd
.Col();
2959 SCROW nEndRow
= aMarkRange
.aEnd
.Row();
2960 SCTAB nEndTab
= aMarkRange
.aEnd
.Tab();
2961 pDocSh
->PostPaint( nStartCol
, nStartRow
, nStartTab
,
2962 nEndCol
, nEndRow
, nEndTab
,
2963 PAINT_GRID
, SC_PF_LINES
| SC_PF_TESTMERGE
);
2965 pDocSh
->UpdateOle( GetViewData() );
2966 pDocSh
->SetDocumentModified();
2970 #undef SET_LINE_ATTRIBUTES
2972 void ScViewFunc::SetValidation( const ScValidationData
& rNew
)
2974 ScDocument
* pDoc
= GetViewData()->GetDocument();
2975 sal_uLong nIndex
= pDoc
->AddValidationEntry(rNew
); // for it there is no Undo
2976 SfxUInt32Item
aItem( ATTR_VALIDDATA
, nIndex
);
2978 ApplyAttr( aItem
); // with Paint and Undo...
2982 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */