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 <com/sun/star/script/vba/XVBAEventProcessor.hpp>
21 #include "scitems.hxx"
22 #include <editeng/langitem.hxx>
23 #include <svl/srchitem.hxx>
24 #include <sfx2/linkmgr.hxx>
25 #include <sfx2/bindings.hxx>
26 #include <sfx2/objsh.hxx>
27 #include <svl/zforlist.hxx>
28 #include <svl/PasswordHelper.hxx>
29 #include <vcl/svapp.hxx>
30 #include "document.hxx"
33 #include "rangenam.hxx"
36 #include "docpool.hxx"
37 #include "poolhelp.hxx"
38 #include "autoform.hxx"
39 #include "rangelst.hxx"
40 #include "chartarr.hxx"
41 #include "chartlock.hxx"
42 #include "refupdat.hxx"
43 #include "docoptio.hxx"
44 #include "viewopti.hxx"
45 #include "scextopt.hxx"
47 #include "bcaslot.hxx"
48 #include "tablink.hxx"
49 #include "externalrefmgr.hxx"
50 #include "markdata.hxx"
51 #include "validat.hxx"
52 #include "dociter.hxx"
53 #include "detdata.hxx"
54 #include "detfunc.hxx"
55 #include "inputopt.hxx"
56 #include "chartlis.hxx"
59 #include "dpobject.hxx"
60 #include "drwlayer.hxx"
61 #include "unoreflist.hxx"
62 #include "listenercalls.hxx"
63 #include "dpshttab.hxx"
64 #include "dpcache.hxx"
65 #include "tabprotection.hxx"
66 #include "formulaparserpool.hxx"
67 #include "clipparam.hxx"
68 #include "sheetevents.hxx"
69 #include "colorscale.hxx"
70 #include "queryentry.hxx"
71 #include "formulacell.hxx"
72 #include "refupdatecontext.hxx"
73 #include "scopetools.hxx"
75 #include "globalnames.hxx"
76 #include <boost/scoped_ptr.hpp>
77 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
79 using namespace com::sun::star
;
83 void sortAndRemoveDuplicates(std::vector
<ScTypedStrData
>& rStrings
, bool bCaseSens
)
87 std::sort(rStrings
.begin(), rStrings
.end(), ScTypedStrData::LessCaseSensitive());
88 std::vector
<ScTypedStrData
>::iterator it
=
89 std::unique(rStrings
.begin(), rStrings
.end(), ScTypedStrData::EqualCaseSensitive());
90 rStrings
.erase(it
, rStrings
.end());
94 std::sort(rStrings
.begin(), rStrings
.end(), ScTypedStrData::LessCaseInsensitive());
95 std::vector
<ScTypedStrData
>::iterator it
=
96 std::unique(rStrings
.begin(), rStrings
.end(), ScTypedStrData::EqualCaseInsensitive());
97 rStrings
.erase(it
, rStrings
.end());
103 void ScDocument::GetAllTabRangeNames(ScRangeName::TabNameCopyMap
& rNames
) const
105 ScRangeName::TabNameCopyMap aNames
;
106 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); ++i
)
109 // no more tables to iterate through.
112 const ScRangeName
* p
= maTabs
[i
]->mpRangeName
;
113 if (!p
|| p
->empty())
114 // ignore empty ones.
117 aNames
.insert(ScRangeName::TabNameCopyMap::value_type(i
, p
));
122 void ScDocument::SetAllRangeNames( const boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
124 OUString
aGlobalStr(STR_GLOBAL_RANGE_NAME
);
125 boost::ptr_map
<OUString
,ScRangeName
>::const_iterator itr
= rRangeMap
.begin(), itrEnd
= rRangeMap
.end();
126 for (; itr
!=itrEnd
; ++itr
)
128 if (itr
->first
== aGlobalStr
)
131 const ScRangeName
* pName
= itr
->second
;
135 pRangeName
= new ScRangeName( *pName
);
139 const ScRangeName
* pName
= itr
->second
;
141 bool bFound
= GetTable(itr
->first
, nTab
);
142 assert(bFound
); (void)bFound
; // fouled up?
144 SetRangeName( nTab
, NULL
);
146 SetRangeName( nTab
, new ScRangeName( *pName
) );
151 void ScDocument::GetTabRangeNameMap(std::map
<OUString
, ScRangeName
*>& aRangeNameMap
)
153 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); ++i
)
157 ScRangeName
* p
= maTabs
[i
]->GetRangeName();
160 p
= new ScRangeName();
164 maTabs
[i
]->GetName(aTableName
);
165 aRangeNameMap
.insert(std::pair
<OUString
, ScRangeName
*>(aTableName
,p
));
169 void ScDocument::GetRangeNameMap(std::map
<OUString
, ScRangeName
*>& aRangeNameMap
)
171 GetTabRangeNameMap(aRangeNameMap
);
174 pRangeName
= new ScRangeName();
176 OUString
aGlobal(STR_GLOBAL_RANGE_NAME
);
177 aRangeNameMap
.insert(std::pair
<OUString
, ScRangeName
*>(aGlobal
, pRangeName
));
180 ScRangeName
* ScDocument::GetRangeName(SCTAB nTab
) const
182 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
185 return maTabs
[nTab
]->GetRangeName();
188 ScRangeName
* ScDocument::GetRangeName() const
191 pRangeName
= new ScRangeName
;
195 void ScDocument::SetRangeName(SCTAB nTab
, ScRangeName
* pNew
)
197 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
200 return maTabs
[nTab
]->SetRangeName(pNew
);
203 void ScDocument::SetRangeName( ScRangeName
* pNewRangeName
)
205 if (pRangeName
== pNewRangeName
)
209 pRangeName
= pNewRangeName
;
212 bool ScDocument::InsertNewRangeName( const OUString
& rName
, const ScAddress
& rPos
, const OUString
& rExpr
)
214 ScRangeName
* pGlobalNames
= GetRangeName();
218 ScRangeData
* pName
= new ScRangeData(this, rName
, rExpr
, rPos
, RT_NAME
, GetGrammar());
219 return pGlobalNames
->insert(pName
);
222 const ScRangeData
* ScDocument::GetRangeAtBlock( const ScRange
& rBlock
, OUString
* pName
) const
224 const ScRangeData
* pData
= NULL
;
227 pData
= pRangeName
->findByRange( rBlock
);
229 *pName
= pData
->GetName();
234 void ScDocument::SetDBCollection( ScDBCollection
* pNewDBCollection
, bool bRemoveAutoFilter
)
236 if (pDBCollection
&& bRemoveAutoFilter
)
238 // remove auto filter attribute if new db data don't contain auto filter flag
239 // start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
241 ScDBCollection::NamedDBs
& rNamedDBs
= pDBCollection
->getNamedDBs();
242 ScDBCollection::NamedDBs::const_iterator itr
= rNamedDBs
.begin(), itrEnd
= rNamedDBs
.end();
243 for (; itr
!= itrEnd
; ++itr
)
245 const ScDBData
& rOldData
= *itr
;
246 if (!rOldData
.HasAutoFilter())
250 rOldData
.GetArea(aOldRange
);
253 if (pNewDBCollection
)
255 ScDBData
* pNewData
= pNewDBCollection
->getNamedDBs().findByUpperName(rOldData
.GetUpperName());
258 if (pNewData
->HasAutoFilter())
261 pNewData
->GetArea(aNewRange
);
262 if (aOldRange
.aStart
== aNewRange
.aStart
)
270 aOldRange
.aEnd
.SetRow(aOldRange
.aStart
.Row());
271 RemoveFlagsTab( aOldRange
.aStart
.Col(), aOldRange
.aStart
.Row(),
272 aOldRange
.aEnd
.Col(), aOldRange
.aEnd
.Row(),
273 aOldRange
.aStart
.Tab(), SC_MF_AUTO
);
274 RepaintRange( aOldRange
);
279 delete pDBCollection
;
281 pDBCollection
= pNewDBCollection
;
284 const ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
) const
287 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
292 ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
)
295 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
300 const ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
303 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
308 ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
311 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
316 bool ScDocument::HasPivotTable() const
318 return pDPCollection
&& pDPCollection
->GetCount();
321 ScDPCollection
* ScDocument::GetDPCollection()
324 pDPCollection
= new ScDPCollection(this);
325 return pDPCollection
;
328 const ScDPCollection
* ScDocument::GetDPCollection() const
330 return pDPCollection
;
333 ScDPObject
* ScDocument::GetDPAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
338 sal_uInt16 nCount
= pDPCollection
->GetCount();
339 ScAddress
aPos( nCol
, nRow
, nTab
);
340 for (sal_uInt16 i
=0; i
<nCount
; i
++)
341 if ( (*pDPCollection
)[i
]->GetOutRange().In( aPos
) )
342 return (*pDPCollection
)[i
];
347 ScDPObject
* ScDocument::GetDPAtBlock( const ScRange
& rBlock
) const
352 /* Walk the collection in reverse order to get something of an
353 * approximation of MS Excels 'most recent' effect. */
354 sal_uInt16 i
= pDPCollection
->GetCount();
356 if ( (*pDPCollection
)[i
]->GetOutRange().In( rBlock
) )
357 return (*pDPCollection
)[i
];
362 void ScDocument::StopTemporaryChartLock()
364 if( apTemporaryChartLock
.get() )
365 apTemporaryChartLock
->StopLocking();
368 void ScDocument::SetChartListenerCollection(
369 ScChartListenerCollection
* pNewChartListenerCollection
,
370 bool bSetChartRangeLists
)
372 ScChartListenerCollection
* pOld
= pChartListenerCollection
;
373 pChartListenerCollection
= pNewChartListenerCollection
;
374 if ( pChartListenerCollection
)
377 pChartListenerCollection
->SetDiffDirty( *pOld
, bSetChartRangeLists
);
378 pChartListenerCollection
->StartAllListeners();
383 void ScDocument::SetScenario( SCTAB nTab
, bool bFlag
)
385 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
386 maTabs
[nTab
]->SetScenario(bFlag
);
389 bool ScDocument::IsScenario( SCTAB nTab
) const
391 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] &&maTabs
[nTab
]->IsScenario();
394 void ScDocument::SetScenarioData( SCTAB nTab
, const OUString
& rComment
,
395 const Color
& rColor
, sal_uInt16 nFlags
)
397 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsScenario())
399 maTabs
[nTab
]->SetScenarioComment( rComment
);
400 maTabs
[nTab
]->SetScenarioColor( rColor
);
401 maTabs
[nTab
]->SetScenarioFlags( nFlags
);
405 Color
ScDocument::GetTabBgColor( SCTAB nTab
) const
407 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
408 return maTabs
[nTab
]->GetTabBgColor();
409 return Color(COL_AUTO
);
412 void ScDocument::SetTabBgColor( SCTAB nTab
, const Color
& rColor
)
414 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
415 maTabs
[nTab
]->SetTabBgColor(rColor
);
418 bool ScDocument::IsDefaultTabBgColor( SCTAB nTab
) const
420 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
421 return maTabs
[nTab
]->GetTabBgColor() == COL_AUTO
;
425 void ScDocument::GetScenarioData( SCTAB nTab
, OUString
& rComment
,
426 Color
& rColor
, sal_uInt16
& rFlags
) const
428 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsScenario())
430 maTabs
[nTab
]->GetScenarioComment( rComment
);
431 rColor
= maTabs
[nTab
]->GetScenarioColor();
432 rFlags
= maTabs
[nTab
]->GetScenarioFlags();
436 void ScDocument::GetScenarioFlags( SCTAB nTab
, sal_uInt16
& rFlags
) const
438 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsScenario())
439 rFlags
= maTabs
[nTab
]->GetScenarioFlags();
442 bool ScDocument::IsLinked( SCTAB nTab
) const
444 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsLinked();
446 //if (ValidTab(nTab) && pTab[nTab])
447 // return pTab[nTab]->IsLinked();
451 formula::FormulaGrammar::AddressConvention
ScDocument::GetAddressConvention() const
453 return formula::FormulaGrammar::extractRefConvention(eGrammar
);
456 void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram
)
461 sal_uInt8
ScDocument::GetLinkMode( SCTAB nTab
) const
463 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
464 return maTabs
[nTab
]->GetLinkMode();
468 const OUString
ScDocument::GetLinkDoc( SCTAB nTab
) const
470 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
471 return maTabs
[nTab
]->GetLinkDoc();
475 const OUString
ScDocument::GetLinkFlt( SCTAB nTab
) const
477 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
478 return maTabs
[nTab
]->GetLinkFlt();
482 const OUString
ScDocument::GetLinkOpt( SCTAB nTab
) const
484 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
485 return maTabs
[nTab
]->GetLinkOpt();
489 const OUString
ScDocument::GetLinkTab( SCTAB nTab
) const
491 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
492 return maTabs
[nTab
]->GetLinkTab();
496 sal_uLong
ScDocument::GetLinkRefreshDelay( SCTAB nTab
) const
498 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
499 return maTabs
[nTab
]->GetLinkRefreshDelay();
503 void ScDocument::SetLink( SCTAB nTab
, sal_uInt8 nMode
, const OUString
& rDoc
,
504 const OUString
& rFilter
, const OUString
& rOptions
,
505 const OUString
& rTabName
, sal_uLong nRefreshDelay
)
507 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
508 maTabs
[nTab
]->SetLink( nMode
, rDoc
, rFilter
, rOptions
, rTabName
, nRefreshDelay
);
511 bool ScDocument::HasLink( const OUString
& rDoc
,
512 const OUString
& rFilter
, const OUString
& rOptions
) const
514 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
515 for (SCTAB i
=0; i
<nCount
; i
++)
516 if (maTabs
[i
]->IsLinked()
517 && maTabs
[i
]->GetLinkDoc() == rDoc
518 && maTabs
[i
]->GetLinkFlt() == rFilter
519 && maTabs
[i
]->GetLinkOpt() == rOptions
)
525 bool ScDocument::LinkExternalTab( SCTAB
& rTab
, const OUString
& aDocTab
,
526 const OUString
& aFileName
, const OUString
& aTabName
)
530 OSL_FAIL( "LinkExternalTab in Clipboard" );
534 OUString aFilterName
; // Is filled by the Loader
535 OUString aOptions
; // Filter options
536 sal_uInt32 nLinkCnt
= pExtDocOptions
? pExtDocOptions
->GetDocSettings().mnLinkCnt
: 0;
537 ScDocumentLoader
aLoader( aFileName
, aFilterName
, aOptions
, nLinkCnt
+ 1 );
538 if ( aLoader
.IsError() )
540 ScDocument
* pSrcDoc
= aLoader
.GetDocument();
544 if ( pSrcDoc
->GetTable( aTabName
, nSrcTab
) )
546 if ( !InsertTab( SC_TAB_APPEND
, aDocTab
, true ) )
548 OSL_FAIL("can't insert external document table");
551 rTab
= GetTableCount() - 1;
552 // Don't insert anew, just the results
553 TransferTab( pSrcDoc
, nSrcTab
, rTab
, false, true );
558 sal_uLong nRefreshDelay
= 0;
560 bool bWasThere
= HasLink( aFileName
, aFilterName
, aOptions
);
561 SetLink( rTab
, SC_LINK_VALUE
, aFileName
, aFilterName
, aOptions
, aTabName
, nRefreshDelay
);
562 if ( !bWasThere
) // Add link only once per source document
564 ScTableLink
* pLink
= new ScTableLink( pShell
, aFileName
, aFilterName
, aOptions
, nRefreshDelay
);
565 pLink
->SetInCreate( true );
566 OUString aFilName
= aFilterName
;
567 GetLinkManager()->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, OUString(aFileName
),
570 pLink
->SetInCreate( false );
571 SfxBindings
* pBindings
= GetViewBindings();
573 pBindings
->Invalidate( SID_LINKS
);
578 ScExternalRefManager
* ScDocument::GetExternalRefManager() const
580 ScDocument
* pThis
= const_cast<ScDocument
*>(this);
581 if (!pExternalRefMgr
.get())
582 pThis
->pExternalRefMgr
.reset( new ScExternalRefManager( pThis
));
584 return pExternalRefMgr
.get();
587 bool ScDocument::IsInExternalReferenceMarking() const
589 return pExternalRefMgr
.get() && pExternalRefMgr
->isInReferenceMarking();
592 void ScDocument::MarkUsedExternalReferences()
594 if (!pExternalRefMgr
.get())
596 if (!pExternalRefMgr
->hasExternalData())
599 pExternalRefMgr
->markUsedByLinkListeners();
601 pExternalRefMgr
->markUsedExternalRefCells();
603 /* NOTE: Conditional formats and validation objects are marked when
604 * collecting them during export. */
607 ScFormulaParserPool
& ScDocument::GetFormulaParserPool() const
609 if( !mxFormulaParserPool
.get() )
610 mxFormulaParserPool
.reset( new ScFormulaParserPool( *this ) );
611 return *mxFormulaParserPool
;
614 const ScSheetEvents
* ScDocument::GetSheetEvents( SCTAB nTab
) const
616 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
617 return maTabs
[nTab
]->GetSheetEvents();
621 void ScDocument::SetSheetEvents( SCTAB nTab
, const ScSheetEvents
* pNew
)
623 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
624 maTabs
[nTab
]->SetSheetEvents( pNew
);
627 bool ScDocument::HasSheetEventScript( SCTAB nTab
, sal_Int32 nEvent
, bool bWithVbaEvents
) const
629 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
631 // check if any event handler script has been configured
632 const ScSheetEvents
* pEvents
= maTabs
[nTab
]->GetSheetEvents();
633 if ( pEvents
&& pEvents
->GetScript( nEvent
) )
635 // check if VBA event handlers exist
636 if (bWithVbaEvents
&& mxVbaEvents
.is()) try
638 uno::Sequence
< uno::Any
> aArgs( 1 );
640 if (mxVbaEvents
->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent
), aArgs
) ||
641 mxVbaEvents
->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent
), uno::Sequence
< uno::Any
>() ))
644 catch( uno::Exception
& )
651 bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent
, bool bWithVbaEvents
) const
653 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
654 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
655 if (HasSheetEventScript( nTab
, nEvent
, bWithVbaEvents
))
660 bool ScDocument::HasAnyCalcNotification() const
662 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
663 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
664 if (maTabs
[nTab
] && maTabs
[nTab
]->GetCalcNotification())
669 bool ScDocument::HasCalcNotification( SCTAB nTab
) const
671 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
672 return maTabs
[nTab
]->GetCalcNotification();
676 void ScDocument::SetCalcNotification( SCTAB nTab
)
678 // set only if not set before
679 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && !maTabs
[nTab
]->GetCalcNotification())
680 maTabs
[nTab
]->SetCalcNotification(true);
683 void ScDocument::ResetCalcNotifications()
685 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
686 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
687 if (maTabs
[nTab
] && maTabs
[nTab
]->GetCalcNotification())
688 maTabs
[nTab
]->SetCalcNotification(false);
691 ScOutlineTable
* ScDocument::GetOutlineTable( SCTAB nTab
, bool bCreate
)
693 ScOutlineTable
* pVal
= NULL
;
695 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
698 pVal
= maTabs
[nTab
]->GetOutlineTable();
702 maTabs
[nTab
]->StartOutlineTable();
703 pVal
= maTabs
[nTab
]->GetOutlineTable();
710 bool ScDocument::SetOutlineTable( SCTAB nTab
, const ScOutlineTable
* pNewOutline
)
712 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->SetOutlineTable(pNewOutline
);
715 void ScDocument::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
,
716 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
718 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
719 maTabs
[nTab
]->DoAutoOutline( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
722 bool ScDocument::TestRemoveSubTotals( SCTAB nTab
, const ScSubTotalParam
& rParam
)
724 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->TestRemoveSubTotals( rParam
);
727 void ScDocument::RemoveSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
729 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
730 maTabs
[nTab
]->RemoveSubTotals( rParam
);
733 bool ScDocument::DoSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
735 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->DoSubTotals( rParam
);
738 bool ScDocument::HasSubTotalCells( const ScRange
& rRange
)
740 ScCellIterator
aIter( this, rRange
);
741 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
743 if (aIter
.getType() != CELLTYPE_FORMULA
)
746 if (aIter
.getFormulaCell()->IsSubTotal())
749 return false; // none found
753 * From this document this method copies the cells of positions at which
754 * there are also cells in pPosDoc to pDestDoc
756 void ScDocument::CopyUpdated( ScDocument
* pPosDoc
, ScDocument
* pDestDoc
)
758 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
759 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
760 if (maTabs
[nTab
] && pPosDoc
->maTabs
[nTab
] && pDestDoc
->maTabs
[nTab
])
761 maTabs
[nTab
]->CopyUpdated( pPosDoc
->maTabs
[nTab
], pDestDoc
->maTabs
[nTab
] );
764 void ScDocument::CopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
, bool bNewScenario
)
766 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size())
767 && nDestTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
] && maTabs
[nDestTab
])
769 // Set flags correctly for active scenarios
770 // and write current values back to recently active scenarios
771 ScRangeList aRanges
= *maTabs
[nSrcTab
]->GetScenarioRanges();
773 // nDestTab is the target table
774 for ( SCTAB nTab
= nDestTab
+1;
775 nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsScenario();
778 if ( maTabs
[nTab
]->IsActiveScenario() ) // Even if it's the same scenario
780 bool bTouched
= false;
781 for ( size_t nR
=0, nRangeCount
= aRanges
.size(); nR
< nRangeCount
&& !bTouched
; nR
++ )
783 const ScRange
* pRange
= aRanges
[ nR
];
784 if ( maTabs
[nTab
]->HasScenarioRange( *pRange
) )
789 maTabs
[nTab
]->SetActiveScenario(false);
790 if ( maTabs
[nTab
]->GetScenarioFlags() & SC_SCENARIO_TWOWAY
)
791 maTabs
[nTab
]->CopyScenarioFrom( maTabs
[nDestTab
] );
796 maTabs
[nSrcTab
]->SetActiveScenario(true); // This is where it's from ...
797 if (!bNewScenario
) // Copy data from the selected scenario
799 sc::AutoCalcSwitch
aACSwitch(*this, false);
800 maTabs
[nSrcTab
]->CopyScenarioTo( maTabs
[nDestTab
] );
802 sc::SetFormulaDirtyContext aCxt
;
803 SetAllFormulasDirty(aCxt
);
808 void ScDocument::MarkScenario( SCTAB nSrcTab
, SCTAB nDestTab
, ScMarkData
& rDestMark
,
809 bool bResetMark
, sal_uInt16 nNeededBits
) const
812 rDestMark
.ResetMark();
814 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
815 maTabs
[nSrcTab
]->MarkScenarioIn( rDestMark
, nNeededBits
);
817 rDestMark
.SetAreaTab( nDestTab
);
820 bool ScDocument::HasScenarioRange( SCTAB nTab
, const ScRange
& rRange
) const
822 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->HasScenarioRange( rRange
);
825 const ScRangeList
* ScDocument::GetScenarioRanges( SCTAB nTab
) const
827 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
828 return maTabs
[nTab
]->GetScenarioRanges();
833 bool ScDocument::IsActiveScenario( SCTAB nTab
) const
835 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsActiveScenario( );
838 void ScDocument::SetActiveScenario( SCTAB nTab
, bool bActive
)
840 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
841 maTabs
[nTab
]->SetActiveScenario( bActive
);
844 bool ScDocument::TestCopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
) const
846 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size())
847 && nDestTab
< static_cast<SCTAB
>(maTabs
.size())&& ValidTab(nDestTab
))
848 return maTabs
[nSrcTab
]->TestCopyScenarioTo( maTabs
[nDestTab
] );
850 OSL_FAIL("wrong table at TestCopyScenario");
854 void ScDocument::AddUnoObject( SfxListener
& rObject
)
856 if (!pUnoBroadcaster
)
857 pUnoBroadcaster
= new SfxBroadcaster
;
859 rObject
.StartListening( *pUnoBroadcaster
);
862 void ScDocument::RemoveUnoObject( SfxListener
& rObject
)
866 rObject
.EndListening( *pUnoBroadcaster
);
868 if ( bInUnoBroadcast
)
870 // Broadcasts from ScDocument::BroadcastUno are the only way that
871 // uno object methods are called without holding a reference.
873 // If RemoveUnoObject is called from an object dtor in the finalizer thread
874 // while the main thread is calling BroadcastUno, the dtor thread must wait
875 // (or the object's Notify might try to access a deleted object).
876 // The SolarMutex can't be locked here because if a component is called from
877 // a VCL event, the main thread has the SolarMutex locked all the time.
879 // This check is done after calling EndListening, so a later BroadcastUno call
880 // won't touch this object.
882 vcl::SolarMutexTryAndBuyGuard g
;
885 // BroadcastUno is always called with the SolarMutex locked, so if it
886 // can be acquired, this is within the same thread (should not happen)
887 OSL_FAIL( "RemoveUnoObject called from BroadcastUno" );
891 // Let the thread that called BroadcastUno continue
892 while ( bInUnoBroadcast
)
894 osl::Thread::yield();
901 OSL_FAIL("No Uno broadcaster");
905 void ScDocument::BroadcastUno( const SfxHint
&rHint
)
909 bInUnoBroadcast
= true;
910 pUnoBroadcaster
->Broadcast( rHint
);
911 bInUnoBroadcast
= false;
913 // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
914 // The listener calls must be processed after completing the broadcast,
915 // because they can add or remove objects from pUnoBroadcaster.
917 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
918 if ( pUnoListenerCalls
&& pSimpleHint
&&
919 pSimpleHint
->GetId() == SFX_HINT_DATACHANGED
&&
920 !bInUnoListenerCall
)
922 // Listener calls may lead to BroadcastUno calls again. The listener calls
923 // are not nested, instead the calls are collected in the list, and the
924 // outermost call executes them all.
926 ScChartLockGuard
aChartLockGuard(this);
927 bInUnoListenerCall
= true;
928 pUnoListenerCalls
->ExecuteAndClear();
929 bInUnoListenerCall
= false;
934 void ScDocument::AddUnoListenerCall( const uno::Reference
<util::XModifyListener
>& rListener
,
935 const lang::EventObject
& rEvent
)
937 OSL_ENSURE( bInUnoBroadcast
, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
939 if ( !pUnoListenerCalls
)
940 pUnoListenerCalls
= new ScUnoListenerCalls
;
941 pUnoListenerCalls
->Add( rListener
, rEvent
);
944 void ScDocument::BeginUnoRefUndo()
946 OSL_ENSURE( !pUnoRefUndoList
, "BeginUnoRefUndo twice" );
947 delete pUnoRefUndoList
;
949 pUnoRefUndoList
= new ScUnoRefList
;
952 ScUnoRefList
* ScDocument::EndUnoRefUndo()
954 ScUnoRefList
* pRet
= pUnoRefUndoList
;
955 pUnoRefUndoList
= NULL
;
956 return pRet
; // Must be deleted by caller!
959 void ScDocument::AddUnoRefChange( sal_Int64 nId
, const ScRangeList
& rOldRanges
)
961 if ( pUnoRefUndoList
)
962 pUnoRefUndoList
->Add( nId
, rOldRanges
);
965 void ScDocument::UpdateReference(
966 sc::RefUpdateContext
& rCxt
, ScDocument
* pUndoDoc
, bool bIncludeDraw
, bool bUpdateNoteCaptionPos
)
968 if (!ValidRange(rCxt
.maRange
))
971 boost::scoped_ptr
<sc::ExpandRefsSwitch
> pExpandRefsSwitch
;
972 if (rCxt
.isInserted())
973 pExpandRefsSwitch
.reset(new sc::ExpandRefsSwitch(*this, SC_MOD()->GetInputOptions().GetExpandRefs()));
975 size_t nFirstTab
, nLastTab
;
976 if (rCxt
.meMode
== URM_COPY
)
978 nFirstTab
= rCxt
.maRange
.aStart
.Tab();
979 nLastTab
= rCxt
.maRange
.aEnd
.Tab();
983 // TODO: Have these methods use the context object directly.
984 ScRange aRange
= rCxt
.maRange
;
985 UpdateRefMode eUpdateRefMode
= rCxt
.meMode
;
986 SCCOL nDx
= rCxt
.mnColDelta
;
987 SCROW nDy
= rCxt
.mnRowDelta
;
988 SCTAB nDz
= rCxt
.mnTabDelta
;
989 SCCOL nCol1
= rCxt
.maRange
.aStart
.Col(), nCol2
= rCxt
.maRange
.aEnd
.Col();
990 SCROW nRow1
= rCxt
.maRange
.aStart
.Row(), nRow2
= rCxt
.maRange
.aEnd
.Row();
991 SCTAB nTab1
= rCxt
.maRange
.aStart
.Tab(), nTab2
= rCxt
.maRange
.aEnd
.Tab();
993 xColNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
994 xRowNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
995 pDBCollection
->UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
997 pRangeName
->UpdateReference(rCxt
, -1);
999 pDPCollection
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1000 UpdateChartRef( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
1001 UpdateRefAreaLinks( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1002 if ( pValidationList
)
1003 pValidationList
->UpdateReference(rCxt
);
1005 pDetOpList
->UpdateReference( this, eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1006 if ( pUnoBroadcaster
)
1007 pUnoBroadcaster
->Broadcast( ScUpdateRefHint(
1008 eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
) );
1011 nLastTab
= maTabs
.size()-1;
1014 for (size_t i
= nFirstTab
, n
= maTabs
.size() ; i
<= nLastTab
&& i
< n
; ++i
)
1019 maTabs
[i
]->UpdateReference(rCxt
, pUndoDoc
, bIncludeDraw
, bUpdateNoteCaptionPos
);
1030 theCol1
= aEmbedRange
.aStart
.Col();
1031 theRow1
= aEmbedRange
.aStart
.Row();
1032 theTab1
= aEmbedRange
.aStart
.Tab();
1033 theCol2
= aEmbedRange
.aEnd
.Col();
1034 theRow2
= aEmbedRange
.aEnd
.Row();
1035 theTab2
= aEmbedRange
.aEnd
.Tab();
1037 // TODO: Have ScRefUpdate::Update() use the context object directly.
1038 UpdateRefMode eUpdateRefMode
= rCxt
.meMode
;
1039 SCCOL nDx
= rCxt
.mnColDelta
;
1040 SCROW nDy
= rCxt
.mnRowDelta
;
1041 SCTAB nDz
= rCxt
.mnTabDelta
;
1042 SCCOL nCol1
= rCxt
.maRange
.aStart
.Col(), nCol2
= rCxt
.maRange
.aEnd
.Col();
1043 SCROW nRow1
= rCxt
.maRange
.aStart
.Row(), nRow2
= rCxt
.maRange
.aEnd
.Row();
1044 SCTAB nTab1
= rCxt
.maRange
.aStart
.Tab(), nTab2
= rCxt
.maRange
.aEnd
.Tab();
1046 if ( ScRefUpdate::Update( this, eUpdateRefMode
, nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
1047 nDx
,nDy
,nDz
, theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) )
1049 aEmbedRange
= ScRange( theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
);
1053 // After moving, no clipboard move ref-updates are possible
1054 if (rCxt
.meMode
!= URM_COPY
&& IsClipboardSource())
1056 ScDocument
* pClipDoc
= ScModule::GetClipDoc();
1058 pClipDoc
->GetClipParam().mbCutMode
= false;
1062 void ScDocument::UpdateTranspose( const ScAddress
& rDestPos
, ScDocument
* pClipDoc
,
1063 const ScMarkData
& rMark
, ScDocument
* pUndoDoc
)
1065 OSL_ENSURE(pClipDoc
->bIsClip
, "UpdateTranspose: No Clip");
1068 ScClipParam
& rClipParam
= GetClipParam();
1069 if (!rClipParam
.maRanges
.empty())
1070 aSource
= *rClipParam
.maRanges
.front();
1071 ScAddress aDest
= rDestPos
;
1074 for (SCTAB nDestTab
=0; nDestTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nDestTab
]; nDestTab
++)
1075 if (rMark
.GetTableSelect(nDestTab
))
1077 while (!pClipDoc
->maTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1078 aSource
.aStart
.SetTab( nClipTab
);
1079 aSource
.aEnd
.SetTab( nClipTab
);
1080 aDest
.SetTab( nDestTab
);
1082 // Like UpdateReference
1084 pRangeName
->UpdateTranspose( aSource
, aDest
); // Before the cells!
1085 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1087 maTabs
[i
]->UpdateTranspose( aSource
, aDest
, pUndoDoc
);
1089 nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1093 void ScDocument::UpdateGrow( const ScRange
& rArea
, SCCOL nGrowX
, SCROW nGrowY
)
1095 //TODO: pDBCollection
1096 //TODO: pPivotCollection
1097 //TODO: UpdateChartRef
1100 pRangeName
->UpdateGrow( rArea
, nGrowX
, nGrowY
);
1102 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[i
]; i
++)
1103 maTabs
[i
]->UpdateGrow( rArea
, nGrowX
, nGrowY
);
1106 void ScDocument::Fill(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, ScProgress
* pProgress
, const ScMarkData
& rMark
,
1107 sal_uLong nFillCount
, FillDir eFillDir
, FillCmd eFillCmd
, FillDateCmd eFillDateCmd
,
1108 double nStepValue
, double nMaxValue
)
1110 PutInOrder( nCol1
, nCol2
);
1111 PutInOrder( nRow1
, nRow2
);
1112 SCTAB nMax
= maTabs
.size();
1113 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1114 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1116 maTabs
[*itr
]->Fill(nCol1
, nRow1
, nCol2
, nRow2
,
1117 nFillCount
, eFillDir
, eFillCmd
, eFillDateCmd
,
1118 nStepValue
, nMaxValue
, pProgress
);
1121 OUString
ScDocument::GetAutoFillPreview( const ScRange
& rSource
, SCCOL nEndX
, SCROW nEndY
)
1123 SCTAB nTab
= rSource
.aStart
.Tab();
1124 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1125 return maTabs
[nTab
]->GetAutoFillPreview( rSource
, nEndX
, nEndY
);
1130 void ScDocument::AutoFormat( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1131 sal_uInt16 nFormatNo
, const ScMarkData
& rMark
)
1133 PutInOrder( nStartCol
, nEndCol
);
1134 PutInOrder( nStartRow
, nEndRow
);
1135 SCTAB nMax
= maTabs
.size();
1136 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1137 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1139 maTabs
[*itr
]->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
);
1142 void ScDocument::GetAutoFormatData(SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1143 ScAutoFormatData
& rData
)
1145 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
1149 PutInOrder(nStartCol
, nEndCol
);
1150 PutInOrder(nStartRow
, nEndRow
);
1151 maTabs
[nTab
]->GetAutoFormatData(nStartCol
, nStartRow
, nEndCol
, nEndRow
, rData
);
1156 void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem
& rSearchItem
,
1157 SCCOL
& rCol
, SCROW
& rRow
)
1159 SvxSearchCmd nCommand
= rSearchItem
.GetCommand();
1160 bool bReplace
= ( nCommand
== SvxSearchCmd::REPLACE
||
1161 nCommand
== SvxSearchCmd::REPLACE_ALL
);
1162 if ( rSearchItem
.GetBackward() )
1164 if ( rSearchItem
.GetRowDirection() )
1166 if ( rSearchItem
.GetPattern() )
1171 else if ( bReplace
)
1184 if ( rSearchItem
.GetPattern() )
1189 else if ( bReplace
)
1203 if ( rSearchItem
.GetRowDirection() )
1205 if ( rSearchItem
.GetPattern() )
1210 else if ( bReplace
)
1223 if ( rSearchItem
.GetPattern() )
1228 else if ( bReplace
)
1242 bool ScDocument::SearchAndReplace(
1243 const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
,
1244 const ScMarkData
& rMark
, ScRangeList
& rMatchedRanges
,
1245 OUString
& rUndoStr
, ScDocument
* pUndoDoc
)
1247 // FIXME: Manage separated marks per table!
1248 bool bFound
= false;
1249 if (rTab
>= static_cast<SCTAB
>(maTabs
.size()))
1250 OSL_FAIL("table out of range");
1256 SvxSearchCmd nCommand
= rSearchItem
.GetCommand();
1257 if ( nCommand
== SvxSearchCmd::FIND_ALL
||
1258 nCommand
== SvxSearchCmd::REPLACE_ALL
)
1260 SCTAB nMax
= maTabs
.size();
1261 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1262 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1267 bFound
|= maTabs
[*itr
]->SearchAndReplace(
1268 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1271 // Mark is set completely inside already
1277 if (rSearchItem
.GetBackward())
1279 for (nTab
= rTab
; ((SCsTAB
)nTab
>= 0) && !bFound
; nTab
--)
1282 if (rMark
.GetTableSelect(nTab
))
1284 bFound
= maTabs
[nTab
]->SearchAndReplace(
1285 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1294 ScDocument::GetSearchAndReplaceStart(
1295 rSearchItem
, nCol
, nRow
);
1297 // notify LibreOfficeKit about changed page
1298 if ( GetDrawLayer() && GetDrawLayer()->isTiledRendering() )
1300 OString aPayload
= OString::number(nTab
);
1301 GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART
, aPayload
.getStr());
1309 for (nTab
= rTab
; (nTab
< static_cast<SCTAB
>(maTabs
.size())) && !bFound
; nTab
++)
1312 if (rMark
.GetTableSelect(nTab
))
1314 bFound
= maTabs
[nTab
]->SearchAndReplace(
1315 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1324 ScDocument::GetSearchAndReplaceStart(
1325 rSearchItem
, nCol
, nRow
);
1327 // notify LibreOfficeKit about changed page
1328 if ( GetDrawLayer() && GetDrawLayer()->isTiledRendering() )
1330 OString aPayload
= OString::number(nTab
);
1331 GetDrawLayer()->libreOfficeKitCallback(LOK_CALLBACK_SET_PART
, aPayload
.getStr());
1345 bool ScDocument::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bShow
)
1347 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1348 return maTabs
[nTab
]->UpdateOutlineCol( nStartCol
, nEndCol
, bShow
);
1350 OSL_FAIL("missing tab");
1354 bool ScDocument::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bShow
)
1356 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1357 return maTabs
[nTab
]->UpdateOutlineRow( nStartRow
, nEndRow
, bShow
);
1359 OSL_FAIL("missing tab");
1363 void ScDocument::Sort(
1364 SCTAB nTab
, const ScSortParam
& rSortParam
, bool bKeepQuery
, bool bUpdateRefs
,
1365 ScProgress
* pProgress
, sc::ReorderParam
* pUndo
)
1367 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1369 bool bOldEnableIdle
= IsIdleEnabled();
1371 maTabs
[nTab
]->Sort(rSortParam
, bKeepQuery
, bUpdateRefs
, pProgress
, pUndo
);
1372 EnableIdle(bOldEnableIdle
);
1376 void ScDocument::Reorder( const sc::ReorderParam
& rParam
, ScProgress
* pProgress
)
1378 ScTable
* pTab
= FetchTable(rParam
.maSortRange
.aStart
.Tab());
1382 bool bOldEnableIdle
= IsIdleEnabled();
1384 pTab
->Reorder(rParam
, pProgress
);
1385 EnableIdle(bOldEnableIdle
);
1388 SCSIZE
ScDocument::Query(SCTAB nTab
, const ScQueryParam
& rQueryParam
, bool bKeepSub
)
1390 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1391 return maTabs
[nTab
]->Query((ScQueryParam
&)rQueryParam
, bKeepSub
);
1393 OSL_FAIL("missing tab");
1397 void ScDocument::GetUpperCellString(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rStr
)
1399 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1400 maTabs
[nTab
]->GetUpperCellString( nCol
, nRow
, rStr
);
1405 bool ScDocument::CreateQueryParam(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab
, ScQueryParam
& rQueryParam
)
1407 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1408 return maTabs
[nTab
]->CreateQueryParam(nCol1
, nRow1
, nCol2
, nRow2
, rQueryParam
);
1410 OSL_FAIL("missing tab");
1414 bool ScDocument::HasAutoFilter( SCCOL nCurCol
, SCROW nCurRow
, SCTAB nCurTab
)
1416 const ScDBData
* pDBData
= GetDBAtCursor( nCurCol
, nCurRow
, nCurTab
);
1417 bool bHasAutoFilter
= (pDBData
!= NULL
);
1421 if ( pDBData
->HasHeader() )
1427 ScQueryParam aParam
;
1428 pDBData
->GetQueryParam( aParam
);
1429 nRow
= aParam
.nRow1
;
1431 for ( nCol
=aParam
.nCol1
; nCol
<=aParam
.nCol2
&& bHasAutoFilter
; nCol
++ )
1433 nFlag
= static_cast<const ScMergeFlagAttr
*>(
1434 GetAttr( nCol
, nRow
, nCurTab
, ATTR_MERGE_FLAG
))->
1437 if ( (nFlag
& SC_MF_AUTO
) == 0 )
1438 bHasAutoFilter
= false;
1442 bHasAutoFilter
= false;
1445 return bHasAutoFilter
;
1448 bool ScDocument::HasColHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1451 return ValidTab(nTab
) && maTabs
[nTab
] && maTabs
[nTab
]->HasColHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1454 bool ScDocument::HasRowHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1457 return ValidTab(nTab
) && maTabs
[nTab
] && maTabs
[nTab
]->HasRowHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1461 * Entries for AutoFilter listbox
1463 bool ScDocument::GetFilterEntries(
1464 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bFilter
, std::vector
<ScTypedStrData
>& rStrings
, bool& rHasDates
)
1466 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && pDBCollection
)
1468 ScDBData
* pDBData
= pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, false); //!??
1471 pDBData
->ExtendDataArea(this);
1477 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1479 if (pDBData
->HasHeader())
1482 ScQueryParam aParam
;
1483 pDBData
->GetQueryParam( aParam
);
1485 // Return all filter entries, if a filter condition is connected with a boolean OR
1488 SCSIZE nEntryCount
= aParam
.GetEntryCount();
1489 for ( SCSIZE i
= 0; i
< nEntryCount
&& aParam
.GetEntry(i
).bDoQuery
; ++i
)
1491 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1492 if ( rEntry
.eConnect
!= SC_AND
)
1502 maTabs
[nTab
]->GetFilteredFilterEntries( nCol
, nStartRow
, nEndRow
, aParam
, rStrings
, rHasDates
);
1506 maTabs
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1509 sortAndRemoveDuplicates(rStrings
, aParam
.bCaseSens
);
1518 * Entries for Filter dialog
1520 bool ScDocument::GetFilterEntriesArea(
1521 SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bCaseSens
,
1522 std::vector
<ScTypedStrData
>& rStrings
, bool& rHasDates
)
1524 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1526 maTabs
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1527 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1535 * Entries for selection list listbox (no numbers/formulas)
1537 bool ScDocument::GetDataEntries(
1538 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bCaseSens
,
1539 std::vector
<ScTypedStrData
>& rStrings
, bool bLimit
)
1543 /* Try to generate the list from list validation. This part is skipped,
1544 if bLimit==true, because in that case this function is called to get
1545 cell values for auto completion on input. */
1546 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
1549 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
1550 if( pData
&& pData
->FillSelectionList( rStrings
, ScAddress( nCol
, nRow
, nTab
) ) )
1552 if (pData
->GetListType() == css::sheet::TableValidationVisibility::SORTEDASCENDING
)
1553 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1560 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()))
1566 std::set
<ScTypedStrData
> aStrings
;
1567 bool bRet
= maTabs
[nTab
]->GetDataEntries(nCol
, nRow
, aStrings
, bLimit
);
1568 rStrings
.insert(rStrings
.end(), aStrings
.begin(), aStrings
.end());
1569 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1575 * Entries for Formula auto input
1577 bool ScDocument::GetFormulaEntries( ScTypedCaseStrSet
& rStrings
)
1583 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
1584 for (; itr
!= itrEnd
; ++itr
)
1585 rStrings
.insert(ScTypedStrData(itr
->second
->GetName(), 0.0, ScTypedStrData::Name
));
1588 // Database collection
1589 if ( pDBCollection
)
1591 const ScDBCollection::NamedDBs
& rDBs
= pDBCollection
->getNamedDBs();
1592 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
1593 for (; itr
!= itrEnd
; ++itr
)
1594 rStrings
.insert(ScTypedStrData(itr
->GetName(), 0.0, ScTypedStrData::DbName
));
1597 // Content of name ranges
1598 ScRangePairList
* pLists
[2];
1599 pLists
[0] = GetColNameRanges();
1600 pLists
[1] = GetRowNameRanges();
1601 for (sal_uInt16 nListNo
=0; nListNo
<2; nListNo
++)
1603 ScRangePairList
* pList
= pLists
[ nListNo
];
1607 for ( size_t i
= 0, nPairs
= pList
->size(); i
< nPairs
; ++i
)
1609 ScRangePair
* pPair
= (*pList
)[i
];
1610 ScRange aRange
= pPair
->GetRange(0);
1611 ScCellIterator
aIter( this, aRange
);
1612 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
1614 if (!aIter
.hasString())
1617 OUString aStr
= aIter
.getString();
1618 rStrings
.insert(ScTypedStrData(aStr
, 0.0, ScTypedStrData::Header
));
1626 void ScDocument::GetEmbedded( ScRange
& rRange
) const
1628 rRange
= aEmbedRange
;
1631 Rectangle
ScDocument::GetEmbeddedRect() const // 1/100 mm
1634 ScTable
* pTable
= NULL
;
1635 if ( aEmbedRange
.aStart
.Tab() < static_cast<SCTAB
>(maTabs
.size()) )
1636 pTable
= maTabs
[aEmbedRange
.aStart
.Tab()];
1638 OSL_FAIL("table out of range");
1641 OSL_FAIL("GetEmbeddedRect without a table");
1647 for (i
=0; i
<aEmbedRange
.aStart
.Col(); i
++)
1648 aRect
.Left() += pTable
->GetColWidth(i
);
1649 aRect
.Top() += pTable
->GetRowHeight( 0, aEmbedRange
.aStart
.Row() - 1);
1650 aRect
.Right() = aRect
.Left();
1651 for (i
=aEmbedRange
.aStart
.Col(); i
<=aEmbedRange
.aEnd
.Col(); i
++)
1652 aRect
.Right() += pTable
->GetColWidth(i
);
1653 aRect
.Bottom() = aRect
.Top();
1654 aRect
.Bottom() += pTable
->GetRowHeight( aEmbedRange
.aStart
.Row(), aEmbedRange
.aEnd
.Row());
1656 aRect
.Left() = (long) ( aRect
.Left() * HMM_PER_TWIPS
);
1657 aRect
.Right() = (long) ( aRect
.Right() * HMM_PER_TWIPS
);
1658 aRect
.Top() = (long) ( aRect
.Top() * HMM_PER_TWIPS
);
1659 aRect
.Bottom() = (long) ( aRect
.Bottom() * HMM_PER_TWIPS
);
1664 void ScDocument::SetEmbedded( const ScRange
& rRange
)
1667 aEmbedRange
= rRange
;
1670 void ScDocument::ResetEmbedded()
1672 bIsEmbedded
= false;
1673 aEmbedRange
= ScRange();
1676 /** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
1677 while result is less than nStopTwips.
1678 @return true if advanced at least one row.
1680 static bool lcl_AddTwipsWhile( long & rTwips
, long nStopTwips
, SCROW
& rPosY
, SCROW nEndRow
, const ScTable
* pTable
, bool bHiddenAsZero
= true )
1683 bool bAdded
= false;
1685 while (rTwips
< nStopTwips
&& nRow
<= nEndRow
&& !bStop
)
1687 SCROW nHeightEndRow
;
1688 sal_uInt16 nHeight
= pTable
->GetRowHeight( nRow
, NULL
, &nHeightEndRow
, bHiddenAsZero
);
1689 if (nHeightEndRow
> nEndRow
)
1690 nHeightEndRow
= nEndRow
;
1692 nRow
= nHeightEndRow
+ 1;
1695 SCROW nRows
= nHeightEndRow
- nRow
+ 1;
1696 sal_Int64 nAdd
= static_cast<sal_Int64
>(nHeight
) * nRows
;
1697 if (nAdd
+ rTwips
>= nStopTwips
)
1699 sal_Int64 nDiff
= nAdd
+ rTwips
- nStopTwips
;
1700 nRows
-= static_cast<SCROW
>(nDiff
/ nHeight
);
1701 nAdd
= static_cast<sal_Int64
>(nHeight
) * nRows
;
1702 // We're looking for a value that satisfies loop condition.
1703 if (nAdd
+ rTwips
>= nStopTwips
)
1710 rTwips
+= static_cast<long>(nAdd
);
1723 ScRange
ScDocument::GetRange( SCTAB nTab
, const Rectangle
& rMMRect
, bool bHiddenAsZero
) const
1725 ScTable
* pTable
= NULL
;
1726 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1727 pTable
= maTabs
[nTab
];
1729 OSL_FAIL("table out of range");
1732 OSL_FAIL("GetRange without a table");
1736 Rectangle aPosRect
= rMMRect
;
1737 if ( IsNegativePage( nTab
) )
1738 ScDrawLayer::MirrorRectRTL( aPosRect
); // Always with positive (LTR) values
1746 nTwips
= (long) (aPosRect
.Left() / HMM_PER_TWIPS
);
1752 nAdd
= (long) pTable
->GetColWidth(nX1
, bHiddenAsZero
);
1753 if (nSize
+nAdd
<= nTwips
+1 && nX1
<MAXCOL
)
1762 nTwips
= (long) (aPosRect
.Right() / HMM_PER_TWIPS
);
1768 nAdd
= (long) pTable
->GetColWidth(nX2
, bHiddenAsZero
);
1769 if (nSize
+nAdd
< nTwips
&& nX2
<MAXCOL
)
1779 nTwips
= (long) (aPosRect
.Top() / HMM_PER_TWIPS
);
1782 // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
1783 if (lcl_AddTwipsWhile( nSize
, nTwips
+2, nY1
, MAXROW
, pTable
, bHiddenAsZero
) && nY1
< MAXROW
)
1784 ++nY1
; // original loop ended on last matched +1 unless that was MAXROW
1786 nTwips
= (long) (aPosRect
.Bottom() / HMM_PER_TWIPS
);
1789 // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
1790 if (lcl_AddTwipsWhile( nSize
, nTwips
, nY2
, MAXROW
, pTable
, bHiddenAsZero
) && nY2
< MAXROW
)
1791 ++nY2
; // original loop ended on last matched +1 unless that was MAXROW
1793 return ScRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
1796 void ScDocument::SetEmbedded( SCTAB nTab
, const Rectangle
& rRect
) // From VisArea (1/100 mm)
1799 aEmbedRange
= GetRange( nTab
, rRect
);
1802 ScDocProtection
* ScDocument::GetDocProtection() const
1804 return pDocProtection
.get();
1807 void ScDocument::SetDocProtection(const ScDocProtection
* pProtect
)
1810 pDocProtection
.reset(new ScDocProtection(*pProtect
));
1812 pDocProtection
.reset();
1815 bool ScDocument::IsDocProtected() const
1817 return pDocProtection
.get() && pDocProtection
->isProtected();
1820 bool ScDocument::IsDocEditable() const
1822 // Import into read-only document is possible
1823 return !IsDocProtected() && ( bImportingXML
|| mbChangeReadOnlyEnabled
|| !pShell
|| !pShell
->IsReadOnly() );
1826 bool ScDocument::IsTabProtected( SCTAB nTab
) const
1828 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1829 return maTabs
[nTab
]->IsProtected();
1831 OSL_FAIL("Wrong table number");
1835 ScTableProtection
* ScDocument::GetTabProtection( SCTAB nTab
) const
1837 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1838 return maTabs
[nTab
]->GetProtection();
1843 void ScDocument::SetTabProtection(SCTAB nTab
, const ScTableProtection
* pProtect
)
1845 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()))
1848 maTabs
[nTab
]->SetProtection(pProtect
);
1851 void ScDocument::CopyTabProtection(SCTAB nTabSrc
, SCTAB nTabDest
)
1853 if (!ValidTab(nTabSrc
) || nTabSrc
>= static_cast<SCTAB
>(maTabs
.size()) || nTabDest
>= static_cast<SCTAB
>(maTabs
.size()) || !ValidTab(nTabDest
))
1856 maTabs
[nTabDest
]->SetProtection( maTabs
[nTabSrc
]->GetProtection() );
1859 const ScDocOptions
& ScDocument::GetDocOptions() const
1861 assert(pDocOptions
&& "No DocOptions! :-(");
1862 return *pDocOptions
;
1865 void ScDocument::SetDocOptions( const ScDocOptions
& rOpt
)
1867 assert(pDocOptions
&& "No DocOptions! :-(");
1869 *pDocOptions
= rOpt
;
1870 xPoolHelper
->SetFormTableOpt(rOpt
);
1873 const ScViewOptions
& ScDocument::GetViewOptions() const
1875 assert(pViewOptions
&& "No ViewOptions! :-(");
1876 return *pViewOptions
;
1879 void ScDocument::SetViewOptions( const ScViewOptions
& rOpt
)
1881 assert(pViewOptions
&& "No ViewOptions! :-(");
1882 *pViewOptions
= rOpt
;
1885 void ScDocument::GetLanguage( LanguageType
& rLatin
, LanguageType
& rCjk
, LanguageType
& rCtl
) const
1888 rCjk
= eCjkLanguage
;
1889 rCtl
= eCtlLanguage
;
1892 void ScDocument::SetLanguage( LanguageType eLatin
, LanguageType eCjk
, LanguageType eCtl
)
1895 eCjkLanguage
= eCjk
;
1896 eCtlLanguage
= eCtl
;
1897 if ( xPoolHelper
.is() )
1899 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
1900 pPool
->SetPoolDefaultItem( SvxLanguageItem( eLanguage
, ATTR_FONT_LANGUAGE
) );
1901 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage
, ATTR_CJK_FONT_LANGUAGE
) );
1902 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage
, ATTR_CTL_FONT_LANGUAGE
) );
1905 UpdateDrawLanguages(); // Set edit engine defaults in drawing layer pool
1908 Rectangle
ScDocument::GetMMRect( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, bool bHiddenAsZero
) const
1910 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
1912 OSL_FAIL("GetMMRect: wrong table");
1913 return Rectangle(0,0,0,0);
1919 for (i
=0; i
<nStartCol
; i
++)
1920 aRect
.Left() += GetColWidth(i
,nTab
, bHiddenAsZero
);
1921 aRect
.Top() += GetRowHeight( 0, nStartRow
-1, nTab
, bHiddenAsZero
);
1923 aRect
.Right() = aRect
.Left();
1924 aRect
.Bottom() = aRect
.Top();
1926 for (i
=nStartCol
; i
<=nEndCol
; i
++)
1927 aRect
.Right() += GetColWidth(i
,nTab
, bHiddenAsZero
);
1928 aRect
.Bottom() += GetRowHeight( nStartRow
, nEndRow
, nTab
, bHiddenAsZero
);
1930 aRect
.Left() = (long)(aRect
.Left() * HMM_PER_TWIPS
);
1931 aRect
.Right() = (long)(aRect
.Right() * HMM_PER_TWIPS
);
1932 aRect
.Top() = (long)(aRect
.Top() * HMM_PER_TWIPS
);
1933 aRect
.Bottom() = (long)(aRect
.Bottom() * HMM_PER_TWIPS
);
1935 if ( IsNegativePage( nTab
) )
1936 ScDrawLayer::MirrorRectRTL( aRect
);
1941 void ScDocument::SetExtDocOptions( ScExtDocOptions
* pNewOptions
)
1943 delete pExtDocOptions
;
1944 pExtDocOptions
= pNewOptions
;
1947 void ScDocument::DoMergeContents( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1948 SCCOL nEndCol
, SCROW nEndRow
)
1951 OUStringBuffer aTotal
;
1955 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
1956 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1958 aCellStr
= GetString(nCol
, nRow
, nTab
);
1959 if (!aCellStr
.isEmpty())
1961 if (!aTotal
.isEmpty())
1963 aTotal
.append(aCellStr
);
1965 if (nCol
!= nStartCol
|| nRow
!= nStartRow
)
1966 SetString(nCol
,nRow
,nTab
,aEmpty
);
1969 SetString(nStartCol
,nStartRow
,nTab
,aTotal
.makeStringAndClear());
1972 void ScDocument::DoMerge( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1973 SCCOL nEndCol
, SCROW nEndRow
, bool bDeleteCaptions
)
1975 ScMergeAttr
aAttr( nEndCol
-nStartCol
+1, nEndRow
-nStartRow
+1 );
1976 ApplyAttr( nStartCol
, nStartRow
, nTab
, aAttr
);
1978 if ( nEndCol
> nStartCol
)
1979 ApplyFlagsTab( nStartCol
+1, nStartRow
, nEndCol
, nStartRow
, nTab
, SC_MF_HOR
);
1980 if ( nEndRow
> nStartRow
)
1981 ApplyFlagsTab( nStartCol
, nStartRow
+1, nStartCol
, nEndRow
, nTab
, SC_MF_VER
);
1982 if ( nEndCol
> nStartCol
&& nEndRow
> nStartRow
)
1983 ApplyFlagsTab( nStartCol
+1, nStartRow
+1, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1985 // Remove all covered notes (removed captions are collected by drawing undo if active)
1986 InsertDeleteFlags nDelFlag
= IDF_NOTE
| (bDeleteCaptions
? IDF_NONE
: IDF_NOCAPTIONS
);
1987 if( nStartCol
< nEndCol
)
1988 DeleteAreaTab( nStartCol
+ 1, nStartRow
, nEndCol
, nStartRow
, nTab
, nDelFlag
);
1989 if( nStartRow
< nEndRow
)
1990 DeleteAreaTab( nStartCol
, nStartRow
+ 1, nEndCol
, nEndRow
, nTab
, nDelFlag
);
1993 void ScDocument::RemoveMerge( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1995 const ScMergeAttr
* pAttr
= static_cast<const ScMergeAttr
*>(
1996 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE
));
1998 if ( pAttr
->GetColMerge() <= 1 && pAttr
->GetRowMerge() <= 1 )
2001 SCCOL nEndCol
= nCol
+ pAttr
->GetColMerge() - 1;
2002 SCROW nEndRow
= nRow
+ pAttr
->GetRowMerge() - 1;
2004 RemoveFlagsTab( nCol
, nRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
2006 const ScMergeAttr
* pDefAttr
= static_cast<const ScMergeAttr
*>(
2007 &xPoolHelper
->GetDocPool()->GetDefaultItem( ATTR_MERGE
));
2008 ApplyAttr( nCol
, nRow
, nTab
, *pDefAttr
);
2011 void ScDocument::ExtendPrintArea( OutputDevice
* pDev
, SCTAB nTab
,
2012 SCCOL nStartCol
, SCROW nStartRow
, SCCOL
& rEndCol
, SCROW nEndRow
) const
2014 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
2015 maTabs
[nTab
]->ExtendPrintArea( pDev
, nStartCol
, nStartRow
, rEndCol
, nEndRow
);
2018 SCSIZE
ScDocument::GetPatternCount( SCTAB nTab
, SCCOL nCol
) const
2020 if( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
2021 return maTabs
[nTab
]->GetPatternCount( nCol
);
2026 SCSIZE
ScDocument::GetPatternCount( SCTAB nTab
, SCCOL nCol
, SCROW nRow1
, SCROW nRow2
) const
2028 if( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
2029 return maTabs
[nTab
]->GetPatternCount( nCol
, nRow1
, nRow2
);
2034 bool ScDocument::ReservePatternCount( SCTAB nTab
, SCCOL nCol
, SCSIZE nReserve
)
2036 if( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
2037 return maTabs
[nTab
]->ReservePatternCount( nCol
, nReserve
);
2042 void ScDocument::GetSortParam( ScSortParam
& rParam
, SCTAB nTab
)
2044 rParam
= mSheetSortParams
[ nTab
];
2047 void ScDocument::SetSortParam( ScSortParam
& rParam
, SCTAB nTab
)
2049 mSheetSortParams
[ nTab
] = rParam
;
2052 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */