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"
34 #include "rangenam.hxx"
37 #include "docpool.hxx"
38 #include "poolhelp.hxx"
39 #include "autoform.hxx"
40 #include "rangelst.hxx"
41 #include "chartarr.hxx"
42 #include "chartlock.hxx"
43 #include "refupdat.hxx"
44 #include "docoptio.hxx"
45 #include "viewopti.hxx"
46 #include "scextopt.hxx"
48 #include "bcaslot.hxx"
49 #include "tablink.hxx"
50 #include "externalrefmgr.hxx"
51 #include "markdata.hxx"
52 #include "validat.hxx"
53 #include "dociter.hxx"
54 #include "detdata.hxx"
55 #include "detfunc.hxx"
56 #include "inputopt.hxx" // GetExpandRefs
57 #include "chartlis.hxx"
58 #include "sc.hrc" // SID_LINK
60 #include "dpobject.hxx"
61 #include "drwlayer.hxx"
62 #include "unoreflist.hxx"
63 #include "listenercalls.hxx"
64 #include "dpshttab.hxx"
65 #include "dpcache.hxx"
66 #include "tabprotection.hxx"
67 #include "formulaparserpool.hxx"
68 #include "clipparam.hxx"
69 #include "sheetevents.hxx"
70 #include "colorscale.hxx"
71 #include "queryentry.hxx"
72 #include "formulacell.hxx"
74 #include "globalnames.hxx"
77 using namespace com::sun::star
;
81 void sortAndRemoveDuplicates(std::vector
<ScTypedStrData
>& rStrings
, bool bCaseSens
)
85 std::sort(rStrings
.begin(), rStrings
.end(), ScTypedStrData::LessCaseSensitive());
86 std::vector
<ScTypedStrData
>::iterator it
=
87 std::unique(rStrings
.begin(), rStrings
.end(), ScTypedStrData::EqualCaseSensitive());
88 rStrings
.erase(it
, rStrings
.end());
92 std::sort(rStrings
.begin(), rStrings
.end(), ScTypedStrData::LessCaseInsensitive());
93 std::vector
<ScTypedStrData
>::iterator it
=
94 std::unique(rStrings
.begin(), rStrings
.end(), ScTypedStrData::EqualCaseInsensitive());
95 rStrings
.erase(it
, rStrings
.end());
101 void ScDocument::GetAllTabRangeNames(ScRangeName::TabNameCopyMap
& rNames
) const
103 ScRangeName::TabNameCopyMap aNames
;
104 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); ++i
)
107 // no more tables to iterate through.
110 const ScRangeName
* p
= maTabs
[i
]->GetRangeName();
111 if (!p
|| p
->empty())
112 // ignore empty ones.
115 aNames
.insert(ScRangeName::TabNameCopyMap::value_type(i
, p
));
120 void ScDocument::SetAllRangeNames( const boost::ptr_map
<OUString
, ScRangeName
>& rRangeMap
)
122 OUString
aGlobalStr(STR_GLOBAL_RANGE_NAME
);
123 boost::ptr_map
<OUString
,ScRangeName
>::const_iterator itr
= rRangeMap
.begin(), itrEnd
= rRangeMap
.end();
124 for (; itr
!=itrEnd
; ++itr
)
126 if (itr
->first
== aGlobalStr
)
129 const ScRangeName
* pName
= itr
->second
;
133 pRangeName
= new ScRangeName( *pName
);
137 const ScRangeName
* pName
= itr
->second
;
139 GetTable(itr
->first
, nTab
);
141 SetRangeName( nTab
, NULL
);
143 SetRangeName( nTab
, new ScRangeName( *pName
) );
148 void ScDocument::GetTabRangeNameMap(std::map
<OUString
, ScRangeName
*>& aRangeNameMap
)
150 for (SCTAB i
= 0; i
< static_cast<SCTAB
>(maTabs
.size()); ++i
)
154 ScRangeName
* p
= maTabs
[i
]->GetRangeName();
157 p
= new ScRangeName();
161 maTabs
[i
]->GetName(aTableName
);
162 aRangeNameMap
.insert(std::pair
<OUString
, ScRangeName
*>(aTableName
,p
));
166 void ScDocument::GetRangeNameMap(std::map
<OUString
, ScRangeName
*>& aRangeNameMap
)
168 GetTabRangeNameMap(aRangeNameMap
);
171 pRangeName
= new ScRangeName();
173 OUString
aGlobal(STR_GLOBAL_RANGE_NAME
);
174 aRangeNameMap
.insert(std::pair
<OUString
, ScRangeName
*>(aGlobal
, pRangeName
));
177 ScRangeName
* ScDocument::GetRangeName(SCTAB nTab
) const
179 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
182 return maTabs
[nTab
]->GetRangeName();
185 ScRangeName
* ScDocument::GetRangeName() const
188 pRangeName
= new ScRangeName
;
192 void ScDocument::SetRangeName(SCTAB nTab
, ScRangeName
* pNew
)
194 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
197 return maTabs
[nTab
]->SetRangeName(pNew
);
200 void ScDocument::SetRangeName( ScRangeName
* pNewRangeName
)
203 pRangeName
= pNewRangeName
;
207 const ScRangeData
* ScDocument::GetRangeAtBlock( const ScRange
& rBlock
, OUString
* pName
) const
209 const ScRangeData
* pData
= NULL
;
212 pData
= pRangeName
->findByRange( rBlock
);
214 *pName
= pData
->GetName();
219 ScDBCollection
* ScDocument::GetDBCollection() const
221 return pDBCollection
;
224 void ScDocument::SetDBCollection( ScDBCollection
* pNewDBCollection
, bool bRemoveAutoFilter
)
226 if (pDBCollection
&& bRemoveAutoFilter
)
228 // remove auto filter attribute if new db data don't contain auto filter flag
229 // start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
231 ScDBCollection::NamedDBs
& rNamedDBs
= pDBCollection
->getNamedDBs();
232 ScDBCollection::NamedDBs::const_iterator itr
= rNamedDBs
.begin(), itrEnd
= rNamedDBs
.end();
233 for (; itr
!= itrEnd
; ++itr
)
235 const ScDBData
& rOldData
= *itr
;
236 if (!rOldData
.HasAutoFilter())
240 rOldData
.GetArea(aOldRange
);
243 if (pNewDBCollection
)
245 ScDBData
* pNewData
= pNewDBCollection
->getNamedDBs().findByUpperName(rOldData
.GetUpperName());
248 if (pNewData
->HasAutoFilter())
251 pNewData
->GetArea(aNewRange
);
252 if (aOldRange
.aStart
== aNewRange
.aStart
)
260 aOldRange
.aEnd
.SetRow(aOldRange
.aStart
.Row());
261 RemoveFlagsTab( aOldRange
.aStart
.Col(), aOldRange
.aStart
.Row(),
262 aOldRange
.aEnd
.Col(), aOldRange
.aEnd
.Row(),
263 aOldRange
.aStart
.Tab(), SC_MF_AUTO
);
264 RepaintRange( aOldRange
);
269 delete pDBCollection
;
271 pDBCollection
= pNewDBCollection
;
274 const ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
) const
277 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
282 ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bStartOnly
)
285 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
290 const ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
293 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
298 ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
)
301 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
306 bool ScDocument::HasPivotTable() const
308 return pDPCollection
&& pDPCollection
->GetCount();
311 ScDPCollection
* ScDocument::GetDPCollection()
314 pDPCollection
= new ScDPCollection(this);
315 return pDPCollection
;
318 const ScDPCollection
* ScDocument::GetDPCollection() const
320 return pDPCollection
;
323 ScDPObject
* ScDocument::GetDPAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
328 sal_uInt16 nCount
= pDPCollection
->GetCount();
329 ScAddress
aPos( nCol
, nRow
, nTab
);
330 for (sal_uInt16 i
=0; i
<nCount
; i
++)
331 if ( (*pDPCollection
)[i
]->GetOutRange().In( aPos
) )
332 return (*pDPCollection
)[i
];
337 ScDPObject
* ScDocument::GetDPAtBlock( const ScRange
& rBlock
) const
342 /* Walk the collection in reverse order to get something of an
343 * approximation of MS Excels 'most recent' effect. */
344 sal_uInt16 i
= pDPCollection
->GetCount();
346 if ( (*pDPCollection
)[i
]->GetOutRange().In( rBlock
) )
347 return (*pDPCollection
)[i
];
352 ScChartCollection
* ScDocument::GetChartCollection() const
354 return pChartCollection
;
357 void ScDocument::StopTemporaryChartLock()
359 if( apTemporaryChartLock
.get() )
360 apTemporaryChartLock
->StopLocking();
363 ScChartListenerCollection
* ScDocument::GetChartListenerCollection() const
365 return pChartListenerCollection
;
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 formula::FormulaGrammar::Grammar
ScDocument::GetGrammar() const
461 void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram
)
466 sal_uInt8
ScDocument::GetLinkMode( SCTAB nTab
) const
468 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
469 return maTabs
[nTab
]->GetLinkMode();
473 const OUString
ScDocument::GetLinkDoc( SCTAB nTab
) const
475 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
476 return maTabs
[nTab
]->GetLinkDoc();
480 const OUString
ScDocument::GetLinkFlt( SCTAB nTab
) const
482 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
483 return maTabs
[nTab
]->GetLinkFlt();
487 const OUString
ScDocument::GetLinkOpt( SCTAB nTab
) const
489 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
490 return maTabs
[nTab
]->GetLinkOpt();
494 const OUString
ScDocument::GetLinkTab( SCTAB nTab
) const
496 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
497 return maTabs
[nTab
]->GetLinkTab();
501 sal_uLong
ScDocument::GetLinkRefreshDelay( SCTAB nTab
) const
503 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
504 return maTabs
[nTab
]->GetLinkRefreshDelay();
508 void ScDocument::SetLink( SCTAB nTab
, sal_uInt8 nMode
, const OUString
& rDoc
,
509 const OUString
& rFilter
, const OUString
& rOptions
,
510 const OUString
& rTabName
, sal_uLong nRefreshDelay
)
512 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
513 maTabs
[nTab
]->SetLink( nMode
, rDoc
, rFilter
, rOptions
, rTabName
, nRefreshDelay
);
516 bool ScDocument::HasLink( const OUString
& rDoc
,
517 const OUString
& rFilter
, const OUString
& rOptions
) const
519 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
520 for (SCTAB i
=0; i
<nCount
; i
++)
521 if (maTabs
[i
]->IsLinked()
522 && maTabs
[i
]->GetLinkDoc() == rDoc
523 && maTabs
[i
]->GetLinkFlt() == rFilter
524 && maTabs
[i
]->GetLinkOpt() == rOptions
)
530 bool ScDocument::LinkExternalTab( SCTAB
& rTab
, const OUString
& aDocTab
,
531 const OUString
& aFileName
, const OUString
& aTabName
)
535 OSL_FAIL( "LinkExternalTab in Clipboard" );
539 OUString aFilterName
; // wird vom Loader gefuellt
540 OUString aOptions
; // Filter-Optionen
541 sal_uInt32 nLinkCnt
= pExtDocOptions
? pExtDocOptions
->GetDocSettings().mnLinkCnt
: 0;
542 ScDocumentLoader
aLoader( aFileName
, aFilterName
, aOptions
, nLinkCnt
+ 1 );
543 if ( aLoader
.IsError() )
545 ScDocument
* pSrcDoc
= aLoader
.GetDocument();
549 if ( pSrcDoc
->GetTable( aTabName
, nSrcTab
) )
551 if ( !InsertTab( SC_TAB_APPEND
, aDocTab
, true ) )
553 OSL_FAIL("can't insert external document table");
556 rTab
= GetTableCount() - 1;
557 // nicht neu einfuegen, nur Ergebnisse
558 TransferTab( pSrcDoc
, nSrcTab
, rTab
, false, true );
563 sal_uLong nRefreshDelay
= 0;
565 bool bWasThere
= HasLink( aFileName
, aFilterName
, aOptions
);
566 SetLink( rTab
, SC_LINK_VALUE
, aFileName
, aFilterName
, aOptions
, aTabName
, nRefreshDelay
);
567 if ( !bWasThere
) // Link pro Quelldokument nur einmal eintragen
569 ScTableLink
* pLink
= new ScTableLink( pShell
, aFileName
, aFilterName
, aOptions
, nRefreshDelay
);
570 pLink
->SetInCreate( true );
571 String aFilName
= aFilterName
;
572 GetLinkManager()->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, OUString(aFileName
),
575 pLink
->SetInCreate( false );
576 SfxBindings
* pBindings
= GetViewBindings();
578 pBindings
->Invalidate( SID_LINKS
);
583 ScExternalRefManager
* ScDocument::GetExternalRefManager() const
585 ScDocument
* pThis
= const_cast<ScDocument
*>(this);
586 if (!pExternalRefMgr
.get())
587 pThis
->pExternalRefMgr
.reset( new ScExternalRefManager( pThis
));
589 return pExternalRefMgr
.get();
592 bool ScDocument::IsInExternalReferenceMarking() const
594 return pExternalRefMgr
.get() && pExternalRefMgr
->isInReferenceMarking();
597 void ScDocument::MarkUsedExternalReferences()
599 if (!pExternalRefMgr
.get())
601 if (!pExternalRefMgr
->hasExternalData())
604 pExternalRefMgr
->markUsedByLinkListeners();
606 pExternalRefMgr
->markUsedExternalRefCells();
608 /* NOTE: Conditional formats and validation objects are marked when
609 * collecting them during export. */
612 ScFormulaParserPool
& ScDocument::GetFormulaParserPool() const
614 if( !mxFormulaParserPool
.get() )
615 mxFormulaParserPool
.reset( new ScFormulaParserPool( *this ) );
616 return *mxFormulaParserPool
;
619 const ScSheetEvents
* ScDocument::GetSheetEvents( SCTAB nTab
) const
621 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
622 return maTabs
[nTab
]->GetSheetEvents();
626 void ScDocument::SetSheetEvents( SCTAB nTab
, const ScSheetEvents
* pNew
)
628 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
629 maTabs
[nTab
]->SetSheetEvents( pNew
);
632 bool ScDocument::HasSheetEventScript( SCTAB nTab
, sal_Int32 nEvent
, bool bWithVbaEvents
) const
634 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
636 // check if any event handler script has been configured
637 const ScSheetEvents
* pEvents
= maTabs
[nTab
]->GetSheetEvents();
638 if ( pEvents
&& pEvents
->GetScript( nEvent
) )
640 // check if VBA event handlers exist
641 if (bWithVbaEvents
&& mxVbaEvents
.is()) try
643 uno::Sequence
< uno::Any
> aArgs( 1 );
645 if (mxVbaEvents
->hasVbaEventHandler( ScSheetEvents::GetVbaSheetEventId( nEvent
), aArgs
) ||
646 mxVbaEvents
->hasVbaEventHandler( ScSheetEvents::GetVbaDocumentEventId( nEvent
), uno::Sequence
< uno::Any
>() ))
649 catch( uno::Exception
& )
656 bool ScDocument::HasAnySheetEventScript( sal_Int32 nEvent
, bool bWithVbaEvents
) const
658 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
659 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
660 if (HasSheetEventScript( nTab
, nEvent
, bWithVbaEvents
))
665 bool ScDocument::HasAnyCalcNotification() const
667 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
668 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
669 if (maTabs
[nTab
] && maTabs
[nTab
]->GetCalcNotification())
674 bool ScDocument::HasCalcNotification( SCTAB nTab
) const
676 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
677 return maTabs
[nTab
]->GetCalcNotification();
681 void ScDocument::SetCalcNotification( SCTAB nTab
)
683 // set only if not set before
684 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && !maTabs
[nTab
]->GetCalcNotification())
685 maTabs
[nTab
]->SetCalcNotification(true);
688 void ScDocument::ResetCalcNotifications()
690 SCTAB nSize
= static_cast<SCTAB
>(maTabs
.size());
691 for (SCTAB nTab
= 0; nTab
< nSize
; nTab
++)
692 if (maTabs
[nTab
] && maTabs
[nTab
]->GetCalcNotification())
693 maTabs
[nTab
]->SetCalcNotification(false);
696 ScOutlineTable
* ScDocument::GetOutlineTable( SCTAB nTab
, bool bCreate
)
698 ScOutlineTable
* pVal
= NULL
;
700 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
703 pVal
= maTabs
[nTab
]->GetOutlineTable();
707 maTabs
[nTab
]->StartOutlineTable();
708 pVal
= maTabs
[nTab
]->GetOutlineTable();
715 bool ScDocument::SetOutlineTable( SCTAB nTab
, const ScOutlineTable
* pNewOutline
)
717 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->SetOutlineTable(pNewOutline
);
720 void ScDocument::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
,
721 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
723 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
724 maTabs
[nTab
]->DoAutoOutline( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
727 bool ScDocument::TestRemoveSubTotals( SCTAB nTab
, const ScSubTotalParam
& rParam
)
729 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->TestRemoveSubTotals( rParam
);
732 void ScDocument::RemoveSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
734 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
735 maTabs
[nTab
]->RemoveSubTotals( rParam
);
738 bool ScDocument::DoSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
740 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->DoSubTotals( rParam
);
743 bool ScDocument::HasSubTotalCells( const ScRange
& rRange
)
745 ScCellIterator
aIter( this, rRange
);
746 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
748 if (aIter
.getType() != CELLTYPE_FORMULA
)
751 if (aIter
.getFormulaCell()->IsSubTotal())
754 return false; // none found
757 // kopiert aus diesem Dokument die Zellen von Positionen, an denen in pPosDoc
758 // auch Zellen stehen, nach pDestDoc
760 void ScDocument::CopyUpdated( ScDocument
* pPosDoc
, ScDocument
* pDestDoc
)
762 SCTAB nCount
= static_cast<SCTAB
>(maTabs
.size());
763 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
764 if (maTabs
[nTab
] && pPosDoc
->maTabs
[nTab
] && pDestDoc
->maTabs
[nTab
])
765 maTabs
[nTab
]->CopyUpdated( pPosDoc
->maTabs
[nTab
], pDestDoc
->maTabs
[nTab
] );
768 void ScDocument::CopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
, bool bNewScenario
)
770 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size())
771 && nDestTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
] && maTabs
[nDestTab
])
773 // Flags fuer aktive Szenarios richtig setzen
774 // und aktuelle Werte in bisher aktive Szenarios zurueckschreiben
776 ScRangeList aRanges
= *maTabs
[nSrcTab
]->GetScenarioRanges();
778 // nDestTab ist die Zieltabelle
779 for ( SCTAB nTab
= nDestTab
+1;
780 nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsScenario();
783 if ( maTabs
[nTab
]->IsActiveScenario() ) // auch wenn's dasselbe Szenario ist
785 bool bTouched
= false;
786 for ( size_t nR
=0, nRangeCount
= aRanges
.size(); nR
< nRangeCount
&& !bTouched
; nR
++ )
788 const ScRange
* pRange
= aRanges
[ nR
];
789 if ( maTabs
[nTab
]->HasScenarioRange( *pRange
) )
794 maTabs
[nTab
]->SetActiveScenario(false);
795 if ( maTabs
[nTab
]->GetScenarioFlags() & SC_SCENARIO_TWOWAY
)
796 maTabs
[nTab
]->CopyScenarioFrom( maTabs
[nDestTab
] );
801 maTabs
[nSrcTab
]->SetActiveScenario(true); // da kommt's her...
802 if (!bNewScenario
) // Daten aus dem ausgewaehlten Szenario kopieren
804 bool bOldAutoCalc
= GetAutoCalc();
805 SetAutoCalc( false ); // Mehrfachberechnungen vermeiden
806 maTabs
[nSrcTab
]->CopyScenarioTo( maTabs
[nDestTab
] );
808 SetAutoCalc( bOldAutoCalc
);
813 void ScDocument::MarkScenario( SCTAB nSrcTab
, SCTAB nDestTab
, ScMarkData
& rDestMark
,
814 bool bResetMark
, sal_uInt16 nNeededBits
) const
817 rDestMark
.ResetMark();
819 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nSrcTab
])
820 maTabs
[nSrcTab
]->MarkScenarioIn( rDestMark
, nNeededBits
);
822 rDestMark
.SetAreaTab( nDestTab
);
825 bool ScDocument::HasScenarioRange( SCTAB nTab
, const ScRange
& rRange
) const
827 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->HasScenarioRange( rRange
);
830 const ScRangeList
* ScDocument::GetScenarioRanges( SCTAB nTab
) const
832 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
833 return maTabs
[nTab
]->GetScenarioRanges();
838 bool ScDocument::IsActiveScenario( SCTAB nTab
) const
840 return ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && maTabs
[nTab
]->IsActiveScenario( );
843 void ScDocument::SetActiveScenario( SCTAB nTab
, bool bActive
)
845 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
846 maTabs
[nTab
]->SetActiveScenario( bActive
);
849 bool ScDocument::TestCopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
) const
851 if (ValidTab(nSrcTab
) && nSrcTab
< static_cast<SCTAB
>(maTabs
.size())
852 && nDestTab
< static_cast<SCTAB
>(maTabs
.size())&& ValidTab(nDestTab
))
853 return maTabs
[nSrcTab
]->TestCopyScenarioTo( maTabs
[nDestTab
] );
855 OSL_FAIL("wrong table at TestCopyScenario");
859 void ScDocument::AddUnoObject( SfxListener
& rObject
)
861 if (!pUnoBroadcaster
)
862 pUnoBroadcaster
= new SfxBroadcaster
;
864 rObject
.StartListening( *pUnoBroadcaster
);
867 void ScDocument::RemoveUnoObject( SfxListener
& rObject
)
871 rObject
.EndListening( *pUnoBroadcaster
);
873 if ( bInUnoBroadcast
)
875 // Broadcasts from ScDocument::BroadcastUno are the only way that
876 // uno object methods are called without holding a reference.
878 // If RemoveUnoObject is called from an object dtor in the finalizer thread
879 // while the main thread is calling BroadcastUno, the dtor thread must wait
880 // (or the object's Notify might try to access a deleted object).
881 // The SolarMutex can't be locked here because if a component is called from
882 // a VCL event, the main thread has the SolarMutex locked all the time.
884 // This check is done after calling EndListening, so a later BroadcastUno call
885 // won't touch this object.
887 comphelper::SolarMutex
& rSolarMutex
= Application::GetSolarMutex();
888 if ( rSolarMutex
.tryToAcquire() )
890 // BroadcastUno is always called with the SolarMutex locked, so if it
891 // can be acquired, this is within the same thread (should not happen)
892 OSL_FAIL( "RemoveUnoObject called from BroadcastUno" );
893 rSolarMutex
.release();
897 // let the thread that called BroadcastUno continue
898 while ( bInUnoBroadcast
)
900 osl::Thread::yield();
907 OSL_FAIL("No Uno broadcaster");
911 void ScDocument::BroadcastUno( const SfxHint
&rHint
)
915 bInUnoBroadcast
= true;
916 pUnoBroadcaster
->Broadcast( rHint
);
917 bInUnoBroadcast
= false;
919 // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
920 // The listener calls must be processed after completing the broadcast,
921 // because they can add or remove objects from pUnoBroadcaster.
923 if ( pUnoListenerCalls
&& rHint
.ISA( SfxSimpleHint
) &&
924 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DATACHANGED
&&
925 !bInUnoListenerCall
)
927 // Listener calls may lead to BroadcastUno calls again. The listener calls
928 // are not nested, instead the calls are collected in the list, and the
929 // outermost call executes them all.
931 ScChartLockGuard
aChartLockGuard(this);
932 bInUnoListenerCall
= true;
933 pUnoListenerCalls
->ExecuteAndClear();
934 bInUnoListenerCall
= false;
939 void ScDocument::AddUnoListenerCall( const uno::Reference
<util::XModifyListener
>& rListener
,
940 const lang::EventObject
& rEvent
)
942 OSL_ENSURE( bInUnoBroadcast
, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
944 if ( !pUnoListenerCalls
)
945 pUnoListenerCalls
= new ScUnoListenerCalls
;
946 pUnoListenerCalls
->Add( rListener
, rEvent
);
949 void ScDocument::BeginUnoRefUndo()
951 OSL_ENSURE( !pUnoRefUndoList
, "BeginUnoRefUndo twice" );
952 delete pUnoRefUndoList
;
954 pUnoRefUndoList
= new ScUnoRefList
;
957 ScUnoRefList
* ScDocument::EndUnoRefUndo()
959 ScUnoRefList
* pRet
= pUnoRefUndoList
;
960 pUnoRefUndoList
= NULL
;
961 return pRet
; // must be deleted by caller!
964 void ScDocument::AddUnoRefChange( sal_Int64 nId
, const ScRangeList
& rOldRanges
)
966 if ( pUnoRefUndoList
)
967 pUnoRefUndoList
->Add( nId
, rOldRanges
);
970 sal_Int64
ScDocument::GetNewUnoId()
972 return ++nUnoObjectId
;
975 void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode
,
976 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
977 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
978 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
979 ScDocument
* pUndoDoc
, bool bIncludeDraw
,
980 bool bUpdateNoteCaptionPos
)
982 PutInOrder( nCol1
, nCol2
);
983 PutInOrder( nRow1
, nRow2
);
984 PutInOrder( nTab1
, nTab2
);
985 if (ValidTab(nTab1
) && ValidTab(nTab2
))
987 bool bExpandRefsOld
= IsExpandRefs();
988 if ( eUpdateRefMode
== URM_INSDEL
&& (nDx
> 0 || nDy
> 0 || nDz
> 0) )
989 SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
992 if ( eUpdateRefMode
== URM_COPY
)
999 ScRange
aRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
1000 xColNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
1001 xRowNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
1002 pDBCollection
->UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
1004 pRangeName
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1005 if ( pDPCollection
)
1006 pDPCollection
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1007 UpdateChartRef( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
1008 UpdateRefAreaLinks( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1009 if ( pValidationList
)
1010 pValidationList
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1012 pDetOpList
->UpdateReference( this, eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
1013 if ( pUnoBroadcaster
)
1014 pUnoBroadcaster
->Broadcast( ScUpdateRefHint(
1015 eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
) );
1017 iMax
= static_cast<SCTAB
>(maTabs
.size())-1;
1019 for ( ; i
<=iMax
&& i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1021 maTabs
[i
]->UpdateReference(
1022 eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
,
1023 nDx
, nDy
, nDz
, pUndoDoc
, bIncludeDraw
, bUpdateNoteCaptionPos
);
1033 theCol1
= aEmbedRange
.aStart
.Col();
1034 theRow1
= aEmbedRange
.aStart
.Row();
1035 theTab1
= aEmbedRange
.aStart
.Tab();
1036 theCol2
= aEmbedRange
.aEnd
.Col();
1037 theRow2
= aEmbedRange
.aEnd
.Row();
1038 theTab2
= aEmbedRange
.aEnd
.Tab();
1039 if ( ScRefUpdate::Update( this, eUpdateRefMode
, nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
1040 nDx
,nDy
,nDz
, theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) )
1042 aEmbedRange
= ScRange( theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
);
1045 SetExpandRefs( bExpandRefsOld
);
1047 // after moving, no clipboard move ref-updates are possible
1048 if ( eUpdateRefMode
!= URM_COPY
&& IsClipboardSource() )
1050 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
1052 pClipDoc
->GetClipParam().mbCutMode
= false;
1057 void ScDocument::UpdateTranspose( const ScAddress
& rDestPos
, ScDocument
* pClipDoc
,
1058 const ScMarkData
& rMark
, ScDocument
* pUndoDoc
)
1060 OSL_ENSURE(pClipDoc
->bIsClip
, "UpdateTranspose: No Clip");
1063 ScClipParam
& rClipParam
= GetClipParam();
1064 if (!rClipParam
.maRanges
.empty())
1065 aSource
= *rClipParam
.maRanges
.front();
1066 ScAddress aDest
= rDestPos
;
1069 for (SCTAB nDestTab
=0; nDestTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nDestTab
]; nDestTab
++)
1070 if (rMark
.GetTableSelect(nDestTab
))
1072 while (!pClipDoc
->maTabs
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1073 aSource
.aStart
.SetTab( nClipTab
);
1074 aSource
.aEnd
.SetTab( nClipTab
);
1075 aDest
.SetTab( nDestTab
);
1077 // wie UpdateReference
1079 pRangeName
->UpdateTranspose( aSource
, aDest
); // vor den Zellen!
1080 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()); i
++)
1082 maTabs
[i
]->UpdateTranspose( aSource
, aDest
, pUndoDoc
);
1084 nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
1088 void ScDocument::UpdateGrow( const ScRange
& rArea
, SCCOL nGrowX
, SCROW nGrowY
)
1091 //! pPivotCollection
1095 pRangeName
->UpdateGrow( rArea
, nGrowX
, nGrowY
);
1097 for (SCTAB i
=0; i
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[i
]; i
++)
1098 maTabs
[i
]->UpdateGrow( rArea
, nGrowX
, nGrowY
);
1101 void ScDocument::Fill(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, ScProgress
* pProgress
, const ScMarkData
& rMark
,
1102 sal_uLong nFillCount
, FillDir eFillDir
, FillCmd eFillCmd
, FillDateCmd eFillDateCmd
,
1103 double nStepValue
, double nMaxValue
)
1105 PutInOrder( nCol1
, nCol2
);
1106 PutInOrder( nRow1
, nRow2
);
1107 SCTAB nMax
= maTabs
.size();
1108 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1109 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1111 maTabs
[*itr
]->Fill(nCol1
, nRow1
, nCol2
, nRow2
,
1112 nFillCount
, eFillDir
, eFillCmd
, eFillDateCmd
,
1113 nStepValue
, nMaxValue
, pProgress
);
1116 OUString
ScDocument::GetAutoFillPreview( const ScRange
& rSource
, SCCOL nEndX
, SCROW nEndY
)
1118 SCTAB nTab
= rSource
.aStart
.Tab();
1119 if (nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1120 return maTabs
[nTab
]->GetAutoFillPreview( rSource
, nEndX
, nEndY
);
1125 void ScDocument::AutoFormat( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1126 sal_uInt16 nFormatNo
, const ScMarkData
& rMark
)
1128 PutInOrder( nStartCol
, nEndCol
);
1129 PutInOrder( nStartRow
, nEndRow
);
1130 SCTAB nMax
= maTabs
.size();
1131 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1132 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1134 maTabs
[*itr
]->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
);
1137 void ScDocument::GetAutoFormatData(SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1138 ScAutoFormatData
& rData
)
1140 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()))
1144 PutInOrder(nStartCol
, nEndCol
);
1145 PutInOrder(nStartRow
, nEndRow
);
1146 maTabs
[nTab
]->GetAutoFormatData(nStartCol
, nStartRow
, nEndCol
, nEndRow
, rData
);
1151 void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem
& rSearchItem
,
1152 SCCOL
& rCol
, SCROW
& rRow
)
1154 sal_uInt16 nCommand
= rSearchItem
.GetCommand();
1155 bool bReplace
= ( nCommand
== SVX_SEARCHCMD_REPLACE
||
1156 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
);
1157 if ( rSearchItem
.GetBackward() )
1159 if ( rSearchItem
.GetRowDirection() )
1161 if ( rSearchItem
.GetPattern() )
1166 else if ( bReplace
)
1179 if ( rSearchItem
.GetPattern() )
1184 else if ( bReplace
)
1198 if ( rSearchItem
.GetRowDirection() )
1200 if ( rSearchItem
.GetPattern() )
1205 else if ( bReplace
)
1218 if ( rSearchItem
.GetPattern() )
1223 else if ( bReplace
)
1237 bool ScDocument::SearchAndReplace(
1238 const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
,
1239 const ScMarkData
& rMark
, ScRangeList
& rMatchedRanges
,
1240 OUString
& rUndoStr
, ScDocument
* pUndoDoc
)
1242 //! getrennte Markierungen pro Tabelle verwalten !!!!!!!!!!!!!
1244 bool bFound
= false;
1245 if (rTab
>= static_cast<SCTAB
>(maTabs
.size()))
1246 OSL_FAIL("table out of range");
1252 sal_uInt16 nCommand
= rSearchItem
.GetCommand();
1253 if ( nCommand
== SVX_SEARCHCMD_FIND_ALL
||
1254 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1256 SCTAB nMax
= maTabs
.size();
1257 ScMarkData::const_iterator itr
= rMark
.begin(), itrEnd
= rMark
.end();
1258 for (; itr
!= itrEnd
&& *itr
< nMax
; ++itr
)
1263 bFound
|= maTabs
[*itr
]->SearchAndReplace(
1264 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1267 // Markierung wird innen schon komplett gesetzt
1273 if (rSearchItem
.GetBackward())
1275 for (nTab
= rTab
; ((SCsTAB
)nTab
>= 0) && !bFound
; nTab
--)
1278 if (rMark
.GetTableSelect(nTab
))
1280 bFound
= maTabs
[nTab
]->SearchAndReplace(
1281 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1289 ScDocument::GetSearchAndReplaceStart(
1290 rSearchItem
, nCol
, nRow
);
1296 for (nTab
= rTab
; (nTab
< static_cast<SCTAB
>(maTabs
.size())) && !bFound
; nTab
++)
1299 if (rMark
.GetTableSelect(nTab
))
1301 bFound
= maTabs
[nTab
]->SearchAndReplace(
1302 rSearchItem
, nCol
, nRow
, rMark
, rMatchedRanges
, rUndoStr
, pUndoDoc
);
1310 ScDocument::GetSearchAndReplaceStart(
1311 rSearchItem
, nCol
, nRow
);
1322 bool ScDocument::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, bool bShow
)
1324 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1325 return maTabs
[nTab
]->UpdateOutlineCol( nStartCol
, nEndCol
, bShow
);
1327 OSL_FAIL("missing tab");
1331 bool ScDocument::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bShow
)
1333 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1334 return maTabs
[nTab
]->UpdateOutlineRow( nStartRow
, nEndRow
, bShow
);
1336 OSL_FAIL("missing tab");
1340 void ScDocument::Sort(SCTAB nTab
, const ScSortParam
& rSortParam
, bool bKeepQuery
, ScProgress
* pProgress
)
1342 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1344 bool bOldEnableIdle
= IsIdleEnabled();
1346 maTabs
[nTab
]->Sort(rSortParam
, bKeepQuery
, pProgress
);
1347 EnableIdle(bOldEnableIdle
);
1351 SCSIZE
ScDocument::Query(SCTAB nTab
, const ScQueryParam
& rQueryParam
, bool bKeepSub
)
1353 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1354 return maTabs
[nTab
]->Query((ScQueryParam
&)rQueryParam
, bKeepSub
);
1356 OSL_FAIL("missing tab");
1361 void ScDocument::GetUpperCellString(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, OUString
& rStr
)
1363 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1364 maTabs
[nTab
]->GetUpperCellString( nCol
, nRow
, rStr
);
1369 bool ScDocument::CreateQueryParam(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab
, ScQueryParam
& rQueryParam
)
1371 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1372 return maTabs
[nTab
]->CreateQueryParam(nCol1
, nRow1
, nCol2
, nRow2
, rQueryParam
);
1374 OSL_FAIL("missing tab");
1378 bool ScDocument::HasAutoFilter( SCCOL nCurCol
, SCROW nCurRow
, SCTAB nCurTab
)
1380 const ScDBData
* pDBData
= GetDBAtCursor( nCurCol
, nCurRow
, nCurTab
);
1381 bool bHasAutoFilter
= (pDBData
!= NULL
);
1385 if ( pDBData
->HasHeader() )
1391 ScQueryParam aParam
;
1392 pDBData
->GetQueryParam( aParam
);
1393 nRow
= aParam
.nRow1
;
1395 for ( nCol
=aParam
.nCol1
; nCol
<=aParam
.nCol2
&& bHasAutoFilter
; nCol
++ )
1397 nFlag
= ((ScMergeFlagAttr
*)
1398 GetAttr( nCol
, nRow
, nCurTab
, ATTR_MERGE_FLAG
))->
1401 if ( (nFlag
& SC_MF_AUTO
) == 0 )
1402 bHasAutoFilter
= false;
1406 bHasAutoFilter
= false;
1409 return bHasAutoFilter
;
1412 bool ScDocument::HasColHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1415 return ValidTab(nTab
) && maTabs
[nTab
] && maTabs
[nTab
]->HasColHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1418 bool ScDocument::HasRowHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1421 return ValidTab(nTab
) && maTabs
[nTab
] && maTabs
[nTab
]->HasRowHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1425 // GetFilterEntries - Eintraege fuer AutoFilter-Listbox
1428 bool ScDocument::GetFilterEntries(
1429 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bFilter
, std::vector
<ScTypedStrData
>& rStrings
, bool& rHasDates
)
1431 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] && pDBCollection
)
1433 ScDBData
* pDBData
= pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, false); //!??
1436 pDBData
->ExtendDataArea(this);
1442 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1444 if (pDBData
->HasHeader())
1447 ScQueryParam aParam
;
1448 pDBData
->GetQueryParam( aParam
);
1450 // return all filter entries, if a filter condition is connected with a boolean OR
1453 SCSIZE nEntryCount
= aParam
.GetEntryCount();
1454 for ( SCSIZE i
= 0; i
< nEntryCount
&& aParam
.GetEntry(i
).bDoQuery
; ++i
)
1456 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1457 if ( rEntry
.eConnect
!= SC_AND
)
1467 maTabs
[nTab
]->GetFilteredFilterEntries( nCol
, nStartRow
, nEndRow
, aParam
, rStrings
, rHasDates
);
1471 maTabs
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1474 sortAndRemoveDuplicates(rStrings
, aParam
.bCaseSens
);
1483 // GetFilterEntriesArea - Eintraege fuer Filter-Dialog
1486 bool ScDocument::GetFilterEntriesArea(
1487 SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, bool bCaseSens
,
1488 std::vector
<ScTypedStrData
>& rStrings
, bool& rHasDates
)
1490 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
1492 maTabs
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1493 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1501 // GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln)
1504 bool ScDocument::GetDataEntries(
1505 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bCaseSens
,
1506 std::vector
<ScTypedStrData
>& rStrings
, bool bLimit
)
1510 /* Try to generate the list from list validation. This part is skipped,
1511 if bLimit==true, because in that case this function is called to get
1512 cell values for auto completion on input. */
1513 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
1516 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
1517 if( pData
&& pData
->FillSelectionList( rStrings
, ScAddress( nCol
, nRow
, nTab
) ) )
1519 if (pData
->GetListType() == ValidListType::SORTEDASCENDING
)
1520 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1527 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()))
1533 std::set
<ScTypedStrData
> aStrings
;
1534 bool bRet
= maTabs
[nTab
]->GetDataEntries(nCol
, nRow
, aStrings
, bLimit
);
1535 rStrings
.insert(rStrings
.end(), aStrings
.begin(), aStrings
.end());
1536 sortAndRemoveDuplicates(rStrings
, bCaseSens
);
1542 // GetFormulaEntries - Eintraege fuer Formel-AutoEingabe
1545 bool ScDocument::GetFormulaEntries( ScTypedCaseStrSet
& rStrings
)
1553 ScRangeName::const_iterator itr
= pRangeName
->begin(), itrEnd
= pRangeName
->end();
1554 for (; itr
!= itrEnd
; ++itr
)
1555 rStrings
.insert(ScTypedStrData(itr
->second
->GetName(), 0.0, ScTypedStrData::Name
));
1559 // Datenbank-Bereiche
1562 if ( pDBCollection
)
1564 const ScDBCollection::NamedDBs
& rDBs
= pDBCollection
->getNamedDBs();
1565 ScDBCollection::NamedDBs::const_iterator itr
= rDBs
.begin(), itrEnd
= rDBs
.end();
1566 for (; itr
!= itrEnd
; ++itr
)
1567 rStrings
.insert(ScTypedStrData(itr
->GetName(), 0.0, ScTypedStrData::DbName
));
1571 // Inhalte von Beschriftungsbereichen
1574 ScRangePairList
* pLists
[2];
1575 pLists
[0] = GetColNameRanges();
1576 pLists
[1] = GetRowNameRanges();
1577 for (sal_uInt16 nListNo
=0; nListNo
<2; nListNo
++)
1579 ScRangePairList
* pList
= pLists
[ nListNo
];
1583 for ( size_t i
= 0, nPairs
= pList
->size(); i
< nPairs
; ++i
)
1585 ScRangePair
* pPair
= (*pList
)[i
];
1586 ScRange aRange
= pPair
->GetRange(0);
1587 ScCellIterator
aIter( this, aRange
);
1588 for (bool bHas
= aIter
.first(); bHas
; bHas
= aIter
.next())
1590 if (!aIter
.hasString())
1593 OUString aStr
= aIter
.getString();
1594 rStrings
.insert(ScTypedStrData(aStr
, 0.0, ScTypedStrData::Header
));
1603 bool ScDocument::IsEmbedded() const
1608 void ScDocument::GetEmbedded( ScRange
& rRange
) const
1610 rRange
= aEmbedRange
;
1613 Rectangle
ScDocument::GetEmbeddedRect() const // 1/100 mm
1616 ScTable
* pTable
= NULL
;
1617 if ( aEmbedRange
.aStart
.Tab() < static_cast<SCTAB
>(maTabs
.size()) )
1618 pTable
= maTabs
[aEmbedRange
.aStart
.Tab()];
1620 OSL_FAIL("table out of range");
1623 OSL_FAIL("GetEmbeddedRect without a table");
1629 for (i
=0; i
<aEmbedRange
.aStart
.Col(); i
++)
1630 aRect
.Left() += pTable
->GetColWidth(i
);
1631 aRect
.Top() += pTable
->GetRowHeight( 0, aEmbedRange
.aStart
.Row() - 1);
1632 aRect
.Right() = aRect
.Left();
1633 for (i
=aEmbedRange
.aStart
.Col(); i
<=aEmbedRange
.aEnd
.Col(); i
++)
1634 aRect
.Right() += pTable
->GetColWidth(i
);
1635 aRect
.Bottom() = aRect
.Top();
1636 aRect
.Bottom() += pTable
->GetRowHeight( aEmbedRange
.aStart
.Row(), aEmbedRange
.aEnd
.Row());
1638 aRect
.Left() = (long) ( aRect
.Left() * HMM_PER_TWIPS
);
1639 aRect
.Right() = (long) ( aRect
.Right() * HMM_PER_TWIPS
);
1640 aRect
.Top() = (long) ( aRect
.Top() * HMM_PER_TWIPS
);
1641 aRect
.Bottom() = (long) ( aRect
.Bottom() * HMM_PER_TWIPS
);
1646 void ScDocument::SetEmbedded( const ScRange
& rRange
)
1649 aEmbedRange
= rRange
;
1652 void ScDocument::ResetEmbedded()
1654 bIsEmbedded
= false;
1655 aEmbedRange
= ScRange();
1659 /** Similar to ScViewData::AddPixelsWhile(), but add height twips and only
1660 while result is less than nStopTwips.
1661 @return true if advanced at least one row.
1663 static bool lcl_AddTwipsWhile( long & rTwips
, long nStopTwips
, SCROW
& rPosY
, SCROW nEndRow
, const ScTable
* pTable
, bool bHiddenAsZero
= true )
1666 bool bAdded
= false;
1668 while (rTwips
< nStopTwips
&& nRow
<= nEndRow
&& !bStop
)
1670 SCROW nHeightEndRow
;
1671 sal_uInt16 nHeight
= pTable
->GetRowHeight( nRow
, NULL
, &nHeightEndRow
, bHiddenAsZero
);
1672 if (nHeightEndRow
> nEndRow
)
1673 nHeightEndRow
= nEndRow
;
1675 nRow
= nHeightEndRow
+ 1;
1678 SCROW nRows
= nHeightEndRow
- nRow
+ 1;
1679 sal_Int64 nAdd
= static_cast<sal_Int64
>(nHeight
) * nRows
;
1680 if (nAdd
+ rTwips
>= nStopTwips
)
1682 sal_Int64 nDiff
= nAdd
+ rTwips
- nStopTwips
;
1683 nRows
-= static_cast<SCROW
>(nDiff
/ nHeight
);
1684 nAdd
= static_cast<sal_Int64
>(nHeight
) * nRows
;
1685 // We're looking for a value that satisfies loop condition.
1686 if (nAdd
+ rTwips
>= nStopTwips
)
1693 rTwips
+= static_cast<long>(nAdd
);
1706 ScRange
ScDocument::GetRange( SCTAB nTab
, const Rectangle
& rMMRect
, bool bHiddenAsZero
) const
1708 ScTable
* pTable
= NULL
;
1709 if (nTab
< static_cast<SCTAB
>(maTabs
.size()))
1710 pTable
= maTabs
[nTab
];
1712 OSL_FAIL("table out of range");
1715 OSL_FAIL("GetRange without a table");
1719 Rectangle aPosRect
= rMMRect
;
1720 if ( IsNegativePage( nTab
) )
1721 ScDrawLayer::MirrorRectRTL( aPosRect
); // always with positive (LTR) values
1729 nTwips
= (long) (aPosRect
.Left() / HMM_PER_TWIPS
);
1735 nAdd
= (long) pTable
->GetColWidth(nX1
, bHiddenAsZero
);
1736 if (nSize
+nAdd
<= nTwips
+1 && nX1
<MAXCOL
)
1745 nTwips
= (long) (aPosRect
.Right() / HMM_PER_TWIPS
);
1751 nAdd
= (long) pTable
->GetColWidth(nX2
, bHiddenAsZero
);
1752 if (nSize
+nAdd
< nTwips
&& nX2
<MAXCOL
)
1763 nTwips
= (long) (aPosRect
.Top() / HMM_PER_TWIPS
);
1766 // Was if(nSize+nAdd<=nTwips+1) inside loop => if(nSize+nAdd<nTwips+2)
1767 if (lcl_AddTwipsWhile( nSize
, nTwips
+2, nY1
, MAXROW
, pTable
, bHiddenAsZero
) && nY1
< MAXROW
)
1768 ++nY1
; // original loop ended on last matched +1 unless that was MAXROW
1770 nTwips
= (long) (aPosRect
.Bottom() / HMM_PER_TWIPS
);
1773 // Was if(nSize+nAdd<nTwips) inside loop => if(nSize+nAdd<nTwips)
1774 if (lcl_AddTwipsWhile( nSize
, nTwips
, nY2
, MAXROW
, pTable
, bHiddenAsZero
) && nY2
< MAXROW
)
1775 ++nY2
; // original loop ended on last matched +1 unless that was MAXROW
1777 return ScRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
1780 void ScDocument::SetEmbedded( SCTAB nTab
, const Rectangle
& rRect
) // aus VisArea (1/100 mm)
1783 aEmbedRange
= GetRange( nTab
, rRect
);
1786 ScDocProtection
* ScDocument::GetDocProtection() const
1788 return pDocProtection
.get();
1791 void ScDocument::SetDocProtection(const ScDocProtection
* pProtect
)
1794 pDocProtection
.reset(new ScDocProtection(*pProtect
));
1796 pDocProtection
.reset(NULL
);
1799 bool ScDocument::IsDocProtected() const
1801 return pDocProtection
.get() && pDocProtection
->isProtected();
1804 bool ScDocument::IsDocEditable() const
1806 // import into read-only document is possible
1807 return !IsDocProtected() && ( bImportingXML
|| mbChangeReadOnlyEnabled
|| !pShell
|| !pShell
->IsReadOnly() );
1810 bool ScDocument::IsTabProtected( SCTAB nTab
) const
1812 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1813 return maTabs
[nTab
]->IsProtected();
1815 OSL_FAIL("Wrong table number");
1819 ScTableProtection
* ScDocument::GetTabProtection( SCTAB nTab
) const
1821 if (ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
])
1822 return maTabs
[nTab
]->GetProtection();
1827 void ScDocument::SetTabProtection(SCTAB nTab
, const ScTableProtection
* pProtect
)
1829 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()))
1832 maTabs
[nTab
]->SetProtection(pProtect
);
1835 void ScDocument::CopyTabProtection(SCTAB nTabSrc
, SCTAB nTabDest
)
1837 if (!ValidTab(nTabSrc
) || nTabSrc
>= static_cast<SCTAB
>(maTabs
.size()) || nTabDest
>= static_cast<SCTAB
>(maTabs
.size()) || !ValidTab(nTabDest
))
1840 maTabs
[nTabDest
]->SetProtection( maTabs
[nTabSrc
]->GetProtection() );
1843 const ScDocOptions
& ScDocument::GetDocOptions() const
1845 OSL_ENSURE( pDocOptions
, "No DocOptions! :-(" );
1846 return *pDocOptions
;
1849 void ScDocument::SetDocOptions( const ScDocOptions
& rOpt
)
1851 OSL_ENSURE( pDocOptions
, "No DocOptions! :-(" );
1853 *pDocOptions
= rOpt
;
1854 xPoolHelper
->SetFormTableOpt(rOpt
);
1857 const ScViewOptions
& ScDocument::GetViewOptions() const
1859 OSL_ENSURE( pViewOptions
, "No ViewOptions! :-(" );
1860 return *pViewOptions
;
1863 void ScDocument::SetViewOptions( const ScViewOptions
& rOpt
)
1865 OSL_ENSURE( pViewOptions
, "No ViewOptions! :-(" );
1866 *pViewOptions
= rOpt
;
1869 void ScDocument::GetLanguage( LanguageType
& rLatin
, LanguageType
& rCjk
, LanguageType
& rCtl
) const
1872 rCjk
= eCjkLanguage
;
1873 rCtl
= eCtlLanguage
;
1876 void ScDocument::SetLanguage( LanguageType eLatin
, LanguageType eCjk
, LanguageType eCtl
)
1879 eCjkLanguage
= eCjk
;
1880 eCtlLanguage
= eCtl
;
1881 if ( xPoolHelper
.is() )
1883 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
1884 pPool
->SetPoolDefaultItem( SvxLanguageItem( eLanguage
, ATTR_FONT_LANGUAGE
) );
1885 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage
, ATTR_CJK_FONT_LANGUAGE
) );
1886 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage
, ATTR_CTL_FONT_LANGUAGE
) );
1889 UpdateDrawLanguages(); // set edit engine defaults in drawing layer pool
1892 void ScDocument::SetDrawDefaults()
1894 bSetDrawDefaults
= true;
1895 UpdateDrawDefaults();
1898 Rectangle
ScDocument::GetMMRect( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
, bool bHiddenAsZero
) const
1900 if (!ValidTab(nTab
) || nTab
>= static_cast<SCTAB
>(maTabs
.size()) || !maTabs
[nTab
])
1902 OSL_FAIL("GetMMRect: wrong table");
1903 return Rectangle(0,0,0,0);
1909 for (i
=0; i
<nStartCol
; i
++)
1910 aRect
.Left() += GetColWidth(i
,nTab
, bHiddenAsZero
);
1911 aRect
.Top() += GetRowHeight( 0, nStartRow
-1, nTab
, bHiddenAsZero
);
1913 aRect
.Right() = aRect
.Left();
1914 aRect
.Bottom() = aRect
.Top();
1916 for (i
=nStartCol
; i
<=nEndCol
; i
++)
1917 aRect
.Right() += GetColWidth(i
,nTab
, bHiddenAsZero
);
1918 aRect
.Bottom() += GetRowHeight( nStartRow
, nEndRow
, nTab
, bHiddenAsZero
);
1920 aRect
.Left() = (long)(aRect
.Left() * HMM_PER_TWIPS
);
1921 aRect
.Right() = (long)(aRect
.Right() * HMM_PER_TWIPS
);
1922 aRect
.Top() = (long)(aRect
.Top() * HMM_PER_TWIPS
);
1923 aRect
.Bottom() = (long)(aRect
.Bottom() * HMM_PER_TWIPS
);
1925 if ( IsNegativePage( nTab
) )
1926 ScDrawLayer::MirrorRectRTL( aRect
);
1931 void ScDocument::SetExtDocOptions( ScExtDocOptions
* pNewOptions
)
1933 delete pExtDocOptions
;
1934 pExtDocOptions
= pNewOptions
;
1937 void ScDocument::DoMergeContents( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1938 SCCOL nEndCol
, SCROW nEndRow
)
1941 OUStringBuffer aTotal
;
1945 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
1946 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1948 aCellStr
= GetString(nCol
, nRow
, nTab
);
1949 if (!aCellStr
.isEmpty())
1951 if (aTotal
.getLength())
1953 aTotal
.append(aCellStr
);
1955 if (nCol
!= nStartCol
|| nRow
!= nStartRow
)
1956 SetString(nCol
,nRow
,nTab
,aEmpty
);
1959 SetString(nStartCol
,nStartRow
,nTab
,aTotal
.makeStringAndClear());
1962 void ScDocument::DoMerge( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1963 SCCOL nEndCol
, SCROW nEndRow
, bool bDeleteCaptions
)
1965 ScMergeAttr
aAttr( nEndCol
-nStartCol
+1, nEndRow
-nStartRow
+1 );
1966 ApplyAttr( nStartCol
, nStartRow
, nTab
, aAttr
);
1968 if ( nEndCol
> nStartCol
)
1969 ApplyFlagsTab( nStartCol
+1, nStartRow
, nEndCol
, nStartRow
, nTab
, SC_MF_HOR
);
1970 if ( nEndRow
> nStartRow
)
1971 ApplyFlagsTab( nStartCol
, nStartRow
+1, nStartCol
, nEndRow
, nTab
, SC_MF_VER
);
1972 if ( nEndCol
> nStartCol
&& nEndRow
> nStartRow
)
1973 ApplyFlagsTab( nStartCol
+1, nStartRow
+1, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1975 // remove all covered notes (removed captions are collected by drawing undo if active)
1976 sal_uInt16 nDelFlag
= IDF_NOTE
| (bDeleteCaptions
? 0 : IDF_NOCAPTIONS
);
1977 if( nStartCol
< nEndCol
)
1978 DeleteAreaTab( nStartCol
+ 1, nStartRow
, nEndCol
, nStartRow
, nTab
, nDelFlag
);
1979 if( nStartRow
< nEndRow
)
1980 DeleteAreaTab( nStartCol
, nStartRow
+ 1, nEndCol
, nEndRow
, nTab
, nDelFlag
);
1983 void ScDocument::RemoveMerge( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1985 const ScMergeAttr
* pAttr
= (const ScMergeAttr
*)
1986 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE
);
1988 if ( pAttr
->GetColMerge() <= 1 && pAttr
->GetRowMerge() <= 1 )
1991 SCCOL nEndCol
= nCol
+ pAttr
->GetColMerge() - 1;
1992 SCROW nEndRow
= nRow
+ pAttr
->GetRowMerge() - 1;
1994 RemoveFlagsTab( nCol
, nRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1996 const ScMergeAttr
* pDefAttr
= (const ScMergeAttr
*)
1997 &xPoolHelper
->GetDocPool()->GetDefaultItem( ATTR_MERGE
);
1998 ApplyAttr( nCol
, nRow
, nTab
, *pDefAttr
);
2001 void ScDocument::ExtendPrintArea( OutputDevice
* pDev
, SCTAB nTab
,
2002 SCCOL nStartCol
, SCROW nStartRow
, SCCOL
& rEndCol
, SCROW nEndRow
) const
2004 if ( ValidTab(nTab
) && nTab
< static_cast<SCTAB
>(maTabs
.size()) && maTabs
[nTab
] )
2005 maTabs
[nTab
]->ExtendPrintArea( pDev
, nStartCol
, nStartRow
, rEndCol
, nEndRow
);
2008 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */