1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: documen3.cxx,v $
10 * $Revision: 1.42.100.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include "scitems.hxx"
37 #include <svx/langitem.hxx>
38 #include <svx/srchitem.hxx>
39 #include <svx/linkmgr.hxx>
40 #include <sfx2/bindings.hxx>
41 #include <sfx2/objsh.hxx>
42 #include <svtools/zforlist.hxx>
43 #include <vcl/svapp.hxx>
44 #include "document.hxx"
48 #include "rangenam.hxx"
49 #include "dbcolect.hxx"
51 #include "docpool.hxx"
52 #include "poolhelp.hxx"
53 #include "autoform.hxx"
54 #include "rangelst.hxx"
55 #include "chartarr.hxx"
56 #include "chartlock.hxx"
57 #include "compiler.hxx"
58 #include "refupdat.hxx"
59 #include "docoptio.hxx"
60 #include "viewopti.hxx"
61 #include "scextopt.hxx"
63 #include "bcaslot.hxx"
64 #include "tablink.hxx"
65 #include "externalrefmgr.hxx"
66 #include "markdata.hxx"
67 #include "validat.hxx"
68 #include "dociter.hxx"
69 #include "detdata.hxx"
70 #include "detfunc.hxx"
71 #include "scmod.hxx" // SC_MOD
72 #include "inputopt.hxx" // GetExpandRefs
73 #include "chartlis.hxx"
74 #include "sc.hrc" // SID_LINK
76 #include "dpobject.hxx"
77 #include "unoguard.hxx"
78 #include "drwlayer.hxx"
79 #include "unoreflist.hxx"
80 #include "listenercalls.hxx"
81 #include "svtools/PasswordHelper.hxx"
82 #include "tabprotection.hxx"
83 #include "clipparam.hxx"
87 using namespace com::sun::star
;
88 using ::std::auto_ptr
;
90 //------------------------------------------------------------------------
92 ScRangeName
* ScDocument::GetRangeName()
97 void ScDocument::SetRangeName( ScRangeName
* pNewRangeName
)
101 pRangeName
= pNewRangeName
;
104 //UNUSED2008-05 ScRangeData* ScDocument::GetRangeAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab,
105 //UNUSED2008-05 BOOL bStartOnly) const
107 //UNUSED2008-05 if ( pRangeName )
108 //UNUSED2008-05 return pRangeName->GetRangeAtCursor( ScAddress( nCol, nRow, nTab ), bStartOnly );
110 //UNUSED2008-05 return NULL;
113 ScRangeData
* ScDocument::GetRangeAtBlock( const ScRange
& rBlock
, String
* pName
) const
115 ScRangeData
* pData
= NULL
;
118 pData
= pRangeName
->GetRangeAtBlock( rBlock
);
120 *pName
= pData
->GetName();
125 ScDBCollection
* ScDocument::GetDBCollection() const
127 return pDBCollection
;
130 void ScDocument::SetDBCollection( ScDBCollection
* pNewDBCollection
, BOOL bRemoveAutoFilter
)
132 if ( bRemoveAutoFilter
)
134 // remove auto filter attribute if new db data don't contain auto filter flag
135 // start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
139 USHORT nOldCount
= pDBCollection
->GetCount();
140 for (USHORT nOld
=0; nOld
<nOldCount
; nOld
++)
142 ScDBData
* pOldData
= (*pDBCollection
)[nOld
];
143 if ( pOldData
->HasAutoFilter() )
146 pOldData
->GetArea( aOldRange
);
149 USHORT nNewIndex
= 0;
150 if ( pNewDBCollection
&&
151 pNewDBCollection
->SearchName( pOldData
->GetName(), nNewIndex
) )
153 ScDBData
* pNewData
= (*pNewDBCollection
)[nNewIndex
];
154 if ( pNewData
->HasAutoFilter() )
157 pNewData
->GetArea( aNewRange
);
158 if ( aOldRange
.aStart
== aNewRange
.aStart
)
165 aOldRange
.aEnd
.SetRow( aOldRange
.aStart
.Row() );
166 RemoveFlagsTab( aOldRange
.aStart
.Col(), aOldRange
.aStart
.Row(),
167 aOldRange
.aEnd
.Col(), aOldRange
.aEnd
.Row(),
168 aOldRange
.aStart
.Tab(), SC_MF_AUTO
);
170 pShell
->Broadcast( ScPaintHint( aOldRange
, PAINT_GRID
) );
178 delete pDBCollection
;
179 pDBCollection
= pNewDBCollection
;
182 ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, BOOL bStartOnly
) const
185 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
190 ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
193 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
198 ScDPCollection
* ScDocument::GetDPCollection()
201 pDPCollection
= new ScDPCollection(this);
202 return pDPCollection
;
205 ScDPObject
* ScDocument::GetDPAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
210 USHORT nCount
= pDPCollection
->GetCount();
211 ScAddress
aPos( nCol
, nRow
, nTab
);
212 for (USHORT i
=0; i
<nCount
; i
++)
213 if ( (*pDPCollection
)[i
]->GetOutRange().In( aPos
) )
214 return (*pDPCollection
)[i
];
219 ScDPObject
* ScDocument::GetDPAtBlock( const ScRange
& rBlock
) const
224 /* Walk the collection in reverse order to get something of an
225 * approximation of MS Excels 'most recent' effect. */
226 USHORT i
= pDPCollection
->GetCount();
228 if ( (*pDPCollection
)[i
]->GetOutRange().In( rBlock
) )
229 return (*pDPCollection
)[i
];
234 #if OLD_PIVOT_IMPLEMENTATION
235 ScPivotCollection
* ScDocument::GetPivotCollection() const
237 return pPivotCollection
;
240 void ScDocument::SetPivotCollection(ScPivotCollection
* pNewPivotCollection
)
242 if ( pPivotCollection
&& pNewPivotCollection
&&
243 *pPivotCollection
== *pNewPivotCollection
)
245 delete pNewPivotCollection
;
249 if (pPivotCollection
)
250 delete pPivotCollection
;
251 pPivotCollection
= pNewPivotCollection
;
253 if (pPivotCollection
)
255 USHORT nCount
= pPivotCollection
->GetCount();
256 for (USHORT i
=0; i
<nCount
; i
++)
258 ScPivot
* pPivot
= (*pPivotCollection
)[i
];
259 if (pPivot
->CreateData())
260 pPivot
->ReleaseData();
265 ScPivot
* ScDocument::GetPivotAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
267 if (pPivotCollection
)
268 return pPivotCollection
->GetPivotAtCursor(nCol
, nRow
, nTab
);
274 ScChartCollection
* ScDocument::GetChartCollection() const
276 return pChartCollection
;
279 void ScDocument::StopTemporaryChartLock()
281 if( apTemporaryChartLock
.get() )
282 apTemporaryChartLock
->StopLocking();
285 void ScDocument::SetChartListenerCollection(
286 ScChartListenerCollection
* pNewChartListenerCollection
,
287 BOOL bSetChartRangeLists
)
289 ScChartListenerCollection
* pOld
= pChartListenerCollection
;
290 pChartListenerCollection
= pNewChartListenerCollection
;
291 if ( pChartListenerCollection
)
294 pChartListenerCollection
->SetDiffDirty( *pOld
, bSetChartRangeLists
);
295 pChartListenerCollection
->StartAllListeners();
300 void ScDocument::SetScenario( SCTAB nTab
, BOOL bFlag
)
302 if (ValidTab(nTab
) && pTab
[nTab
])
303 pTab
[nTab
]->SetScenario(bFlag
);
306 BOOL
ScDocument::IsScenario( SCTAB nTab
) const
308 return ValidTab(nTab
) && pTab
[nTab
] &&pTab
[nTab
]->IsScenario();
309 //if (ValidTab(nTab) && pTab[nTab])
310 // return pTab[nTab]->IsScenario();
315 void ScDocument::SetScenarioData( SCTAB nTab
, const String
& rComment
,
316 const Color
& rColor
, USHORT nFlags
)
318 if (ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
320 pTab
[nTab
]->SetScenarioComment( rComment
);
321 pTab
[nTab
]->SetScenarioColor( rColor
);
322 pTab
[nTab
]->SetScenarioFlags( nFlags
);
326 void ScDocument::GetScenarioData( SCTAB nTab
, String
& rComment
,
327 Color
& rColor
, USHORT
& rFlags
) const
329 if (ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
331 pTab
[nTab
]->GetScenarioComment( rComment
);
332 rColor
= pTab
[nTab
]->GetScenarioColor();
333 rFlags
= pTab
[nTab
]->GetScenarioFlags();
337 void ScDocument::GetScenarioFlags( SCTAB nTab
, USHORT
& rFlags
) const
339 if (VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
340 rFlags
= pTab
[nTab
]->GetScenarioFlags();
343 BOOL
ScDocument::IsLinked( SCTAB nTab
) const
345 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsLinked();
347 //if (ValidTab(nTab) && pTab[nTab])
348 // return pTab[nTab]->IsLinked();
352 formula::FormulaGrammar::AddressConvention
ScDocument::GetAddressConvention() const
354 return formula::FormulaGrammar::extractRefConvention(eGrammar
);
357 formula::FormulaGrammar::Grammar
ScDocument::GetGrammar() const
362 void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram
)
367 BOOL
ScDocument::GetLinkMode( SCTAB nTab
) const
369 if (ValidTab(nTab
) && pTab
[nTab
])
370 return pTab
[nTab
]->GetLinkMode();
374 const String
& ScDocument::GetLinkDoc( SCTAB nTab
) const
376 if (ValidTab(nTab
) && pTab
[nTab
])
377 return pTab
[nTab
]->GetLinkDoc();
381 const String
& ScDocument::GetLinkFlt( SCTAB nTab
) const
383 if (ValidTab(nTab
) && pTab
[nTab
])
384 return pTab
[nTab
]->GetLinkFlt();
388 const String
& ScDocument::GetLinkOpt( SCTAB nTab
) const
390 if (ValidTab(nTab
) && pTab
[nTab
])
391 return pTab
[nTab
]->GetLinkOpt();
395 const String
& ScDocument::GetLinkTab( SCTAB nTab
) const
397 if (ValidTab(nTab
) && pTab
[nTab
])
398 return pTab
[nTab
]->GetLinkTab();
402 ULONG
ScDocument::GetLinkRefreshDelay( SCTAB nTab
) const
404 if (ValidTab(nTab
) && pTab
[nTab
])
405 return pTab
[nTab
]->GetLinkRefreshDelay();
409 void ScDocument::SetLink( SCTAB nTab
, BYTE nMode
, const String
& rDoc
,
410 const String
& rFilter
, const String
& rOptions
,
411 const String
& rTabName
, ULONG nRefreshDelay
)
413 if (ValidTab(nTab
) && pTab
[nTab
])
414 pTab
[nTab
]->SetLink( nMode
, rDoc
, rFilter
, rOptions
, rTabName
, nRefreshDelay
);
417 BOOL
ScDocument::HasLink( const String
& rDoc
,
418 const String
& rFilter
, const String
& rOptions
) const
420 SCTAB nCount
= GetTableCount();
421 for (SCTAB i
=0; i
<nCount
; i
++)
422 if (pTab
[i
]->IsLinked()
423 && pTab
[i
]->GetLinkDoc() == rDoc
424 && pTab
[i
]->GetLinkFlt() == rFilter
425 && pTab
[i
]->GetLinkOpt() == rOptions
)
431 BOOL
ScDocument::LinkExternalTab( SCTAB
& rTab
, const String
& aDocTab
,
432 const String
& aFileName
, const String
& aTabName
)
436 DBG_ERRORFILE( "LinkExternalTab in Clipboard" );
440 String aFilterName
; // wird vom Loader gefuellt
441 String aOptions
; // Filter-Optionen
442 sal_uInt32 nLinkCnt
= pExtDocOptions
? pExtDocOptions
->GetDocSettings().mnLinkCnt
: 0;
443 ScDocumentLoader
aLoader( aFileName
, aFilterName
, aOptions
, nLinkCnt
+ 1 );
444 if ( aLoader
.IsError() )
446 ScDocument
* pSrcDoc
= aLoader
.GetDocument();
450 if ( pSrcDoc
->GetTable( aTabName
, nSrcTab
) )
452 if ( !InsertTab( SC_TAB_APPEND
, aDocTab
, TRUE
) )
454 DBG_ERRORFILE("can't insert external document table");
457 rTab
= GetTableCount() - 1;
458 // nicht neu einfuegen, nur Ergebnisse
459 TransferTab( pSrcDoc
, nSrcTab
, rTab
, FALSE
, TRUE
);
464 ULONG nRefreshDelay
= 0;
466 BOOL bWasThere
= HasLink( aFileName
, aFilterName
, aOptions
);
467 SetLink( rTab
, SC_LINK_VALUE
, aFileName
, aFilterName
, aOptions
, aTabName
, nRefreshDelay
);
468 if ( !bWasThere
) // Link pro Quelldokument nur einmal eintragen
470 ScTableLink
* pLink
= new ScTableLink( pShell
, aFileName
, aFilterName
, aOptions
, nRefreshDelay
);
471 pLink
->SetInCreate( TRUE
);
472 pLinkManager
->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, aFileName
,
475 pLink
->SetInCreate( FALSE
);
476 SfxBindings
* pBindings
= GetViewBindings();
478 pBindings
->Invalidate( SID_LINKS
);
483 ScExternalRefManager
* ScDocument::GetExternalRefManager()
485 if (!pExternalRefMgr
.get())
486 pExternalRefMgr
.reset(new ScExternalRefManager(this));
488 return pExternalRefMgr
.get();
491 bool ScDocument::IsInExternalReferenceMarking() const
493 return pExternalRefMgr
.get() && pExternalRefMgr
->isInReferenceMarking();
496 void ScDocument::MarkUsedExternalReferences()
498 if (!pExternalRefMgr
.get())
500 if (!pExternalRefMgr
->hasExternalData())
503 bool bAllMarked
= pExternalRefMgr
->markUsedByLinkListeners();
505 for (SCTAB nTab
= 0; !bAllMarked
&& nTab
< nMaxTableNumber
; ++nTab
)
508 bAllMarked
= pTab
[nTab
]->MarkUsedExternalReferences();
510 /* NOTE: Conditional formats and validation objects are marked when
511 * collecting them during export. */
514 ScOutlineTable
* ScDocument::GetOutlineTable( SCTAB nTab
, BOOL bCreate
)
516 ScOutlineTable
* pVal
= NULL
;
521 pVal
= pTab
[nTab
]->GetOutlineTable();
525 pTab
[nTab
]->StartOutlineTable();
526 pVal
= pTab
[nTab
]->GetOutlineTable();
533 BOOL
ScDocument::SetOutlineTable( SCTAB nTab
, const ScOutlineTable
* pNewOutline
)
535 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->SetOutlineTable(pNewOutline
);
536 //if (VALIDTAB(nTab))
538 // return pTab[nTab]->SetOutlineTable(pNewOutline);
543 void ScDocument::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
,
544 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
546 if (VALIDTAB(nTab
) && pTab
[nTab
])
547 pTab
[nTab
]->DoAutoOutline( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
550 BOOL
ScDocument::TestRemoveSubTotals( SCTAB nTab
, const ScSubTotalParam
& rParam
)
552 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->TestRemoveSubTotals( rParam
);
553 //if (VALIDTAB(nTab) && pTab[nTab] )
554 // return pTab[nTab]->TestRemoveSubTotals( rParam );
559 void ScDocument::RemoveSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
561 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
562 pTab
[nTab
]->RemoveSubTotals( rParam
);
565 BOOL
ScDocument::DoSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
567 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->DoSubTotals( rParam
);
568 //if (VALIDTAB(nTab))
570 // return pTab[nTab]->DoSubTotals( rParam );
575 BOOL
ScDocument::HasSubTotalCells( const ScRange
& rRange
)
577 ScCellIterator
aIter( this, rRange
);
578 ScBaseCell
* pCell
= aIter
.GetFirst();
581 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
&& ((ScFormulaCell
*)pCell
)->IsSubTotal() )
584 pCell
= aIter
.GetNext();
586 return FALSE
; // none found
589 // kopiert aus diesem Dokument die Zellen von Positionen, an denen in pPosDoc
590 // auch Zellen stehen, nach pDestDoc
592 void ScDocument::CopyUpdated( ScDocument
* pPosDoc
, ScDocument
* pDestDoc
)
594 SCTAB nCount
= GetTableCount();
595 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
596 if (pTab
[nTab
] && pPosDoc
->pTab
[nTab
] && pDestDoc
->pTab
[nTab
])
597 pTab
[nTab
]->CopyUpdated( pPosDoc
->pTab
[nTab
], pDestDoc
->pTab
[nTab
] );
600 void ScDocument::CopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
, BOOL bNewScenario
)
602 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
) && pTab
[nSrcTab
] && pTab
[nDestTab
])
604 // Flags fuer aktive Szenarios richtig setzen
605 // und aktuelle Werte in bisher aktive Szenarios zurueckschreiben
607 ScRangeList aRanges
= *pTab
[nSrcTab
]->GetScenarioRanges();
608 const ULONG nRangeCount
= aRanges
.Count();
610 // nDestTab ist die Zieltabelle
611 for ( SCTAB nTab
= nDestTab
+1;
612 nTab
<=MAXTAB
&& pTab
[nTab
] && pTab
[nTab
]->IsScenario();
615 if ( pTab
[nTab
]->IsActiveScenario() ) // auch wenn's dasselbe Szenario ist
617 BOOL bTouched
= FALSE
;
618 for ( ULONG nR
=0; nR
<nRangeCount
&& !bTouched
; nR
++)
620 const ScRange
* pRange
= aRanges
.GetObject(nR
);
621 if ( pTab
[nTab
]->HasScenarioRange( *pRange
) )
626 pTab
[nTab
]->SetActiveScenario(FALSE
);
627 if ( pTab
[nTab
]->GetScenarioFlags() & SC_SCENARIO_TWOWAY
)
628 pTab
[nTab
]->CopyScenarioFrom( pTab
[nDestTab
] );
633 pTab
[nSrcTab
]->SetActiveScenario(TRUE
); // da kommt's her...
634 if (!bNewScenario
) // Daten aus dem ausgewaehlten Szenario kopieren
636 BOOL bOldAutoCalc
= GetAutoCalc();
637 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
638 pTab
[nSrcTab
]->CopyScenarioTo( pTab
[nDestTab
] );
640 SetAutoCalc( bOldAutoCalc
);
645 void ScDocument::MarkScenario( SCTAB nSrcTab
, SCTAB nDestTab
, ScMarkData
& rDestMark
,
646 BOOL bResetMark
, USHORT nNeededBits
) const
649 rDestMark
.ResetMark();
651 if (ValidTab(nSrcTab
) && pTab
[nSrcTab
])
652 pTab
[nSrcTab
]->MarkScenarioIn( rDestMark
, nNeededBits
);
654 rDestMark
.SetAreaTab( nDestTab
);
657 BOOL
ScDocument::HasScenarioRange( SCTAB nTab
, const ScRange
& rRange
) const
659 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasScenarioRange( rRange
);
660 //if (ValidTab(nTab) && pTab[nTab])
661 // return pTab[nTab]->HasScenarioRange( rRange );
666 const ScRangeList
* ScDocument::GetScenarioRanges( SCTAB nTab
) const
668 if (ValidTab(nTab
) && pTab
[nTab
])
669 return pTab
[nTab
]->GetScenarioRanges();
674 BOOL
ScDocument::IsActiveScenario( SCTAB nTab
) const
676 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsActiveScenario( );
677 //if (ValidTab(nTab) && pTab[nTab])
678 // return pTab[nTab]->IsActiveScenario();
683 void ScDocument::SetActiveScenario( SCTAB nTab
, BOOL bActive
)
685 if (ValidTab(nTab
) && pTab
[nTab
])
686 pTab
[nTab
]->SetActiveScenario( bActive
);
689 BOOL
ScDocument::TestCopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
) const
691 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
))
692 return pTab
[nSrcTab
]->TestCopyScenarioTo( pTab
[nDestTab
] );
694 DBG_ERROR("falsche Tabelle bei TestCopyScenario");
698 void ScDocument::AddUnoObject( SfxListener
& rObject
)
700 if (!pUnoBroadcaster
)
701 pUnoBroadcaster
= new SfxBroadcaster
;
703 rObject
.StartListening( *pUnoBroadcaster
);
706 void ScDocument::RemoveUnoObject( SfxListener
& rObject
)
710 rObject
.EndListening( *pUnoBroadcaster
);
712 if ( bInUnoBroadcast
)
714 // #107294# Broadcasts from ScDocument::BroadcastUno are the only way that
715 // uno object methods are called without holding a reference.
717 // If RemoveUnoObject is called from an object dtor in the finalizer thread
718 // while the main thread is calling BroadcastUno, the dtor thread must wait
719 // (or the object's Notify might try to access a deleted object).
720 // The SolarMutex can't be locked here because if a component is called from
721 // a VCL event, the main thread has the SolarMutex locked all the time.
723 // This check is done after calling EndListening, so a later BroadcastUno call
724 // won't touch this object.
726 vos::IMutex
& rSolarMutex
= Application::GetSolarMutex();
727 if ( rSolarMutex
.tryToAcquire() )
729 // BroadcastUno is always called with the SolarMutex locked, so if it
730 // can be acquired, this is within the same thread (should not happen)
731 DBG_ERRORFILE( "RemoveUnoObject called from BroadcastUno" );
732 rSolarMutex
.release();
736 // let the thread that called BroadcastUno continue
737 while ( bInUnoBroadcast
)
739 vos::OThread::yield();
746 DBG_ERROR("No Uno broadcaster");
750 void ScDocument::BroadcastUno( const SfxHint
&rHint
)
754 bInUnoBroadcast
= TRUE
;
755 pUnoBroadcaster
->Broadcast( rHint
);
756 bInUnoBroadcast
= FALSE
;
758 // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
759 // The listener calls must be processed after completing the broadcast,
760 // because they can add or remove objects from pUnoBroadcaster.
762 if ( pUnoListenerCalls
&& rHint
.ISA( SfxSimpleHint
) &&
763 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DATACHANGED
&&
764 !bInUnoListenerCall
)
766 // Listener calls may lead to BroadcastUno calls again. The listener calls
767 // are not nested, instead the calls are collected in the list, and the
768 // outermost call executes them all.
770 ScChartLockGuard
aChartLockGuard(this);
771 bInUnoListenerCall
= TRUE
;
772 pUnoListenerCalls
->ExecuteAndClear();
773 bInUnoListenerCall
= FALSE
;
778 void ScDocument::AddUnoListenerCall( const uno::Reference
<util::XModifyListener
>& rListener
,
779 const lang::EventObject
& rEvent
)
781 DBG_ASSERT( bInUnoBroadcast
, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
783 if ( !pUnoListenerCalls
)
784 pUnoListenerCalls
= new ScUnoListenerCalls
;
785 pUnoListenerCalls
->Add( rListener
, rEvent
);
788 void ScDocument::BeginUnoRefUndo()
790 DBG_ASSERT( !pUnoRefUndoList
, "BeginUnoRefUndo twice" );
791 delete pUnoRefUndoList
;
793 pUnoRefUndoList
= new ScUnoRefList
;
796 ScUnoRefList
* ScDocument::EndUnoRefUndo()
798 ScUnoRefList
* pRet
= pUnoRefUndoList
;
799 pUnoRefUndoList
= NULL
;
800 return pRet
; // must be deleted by caller!
803 void ScDocument::AddUnoRefChange( sal_Int64 nId
, const ScRangeList
& rOldRanges
)
805 if ( pUnoRefUndoList
)
806 pUnoRefUndoList
->Add( nId
, rOldRanges
);
809 sal_Int64
ScDocument::GetNewUnoId()
811 return ++nUnoObjectId
;
814 void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode
,
815 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
816 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
817 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
818 ScDocument
* pUndoDoc
, BOOL bIncludeDraw
)
820 PutInOrder( nCol1
, nCol2
);
821 PutInOrder( nRow1
, nRow2
);
822 PutInOrder( nTab1
, nTab2
);
823 if (VALIDTAB(nTab1
) && VALIDTAB(nTab2
))
825 BOOL bExpandRefsOld
= IsExpandRefs();
826 if ( eUpdateRefMode
== URM_INSDEL
&& (nDx
> 0 || nDy
> 0 || nDz
> 0) )
827 SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
830 if ( eUpdateRefMode
== URM_COPY
)
837 ScRange
aRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
838 xColNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
839 xRowNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
840 pDBCollection
->UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
841 pRangeName
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
842 #if OLD_PIVOT_IMPLEMENTATION
843 if (pPivotCollection
)
844 pPivotCollection
->UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
847 pDPCollection
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
848 UpdateChartRef( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
849 UpdateRefAreaLinks( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
851 pCondFormList
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
852 if ( pValidationList
)
853 pValidationList
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
855 pDetOpList
->UpdateReference( this, eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
856 if ( pUnoBroadcaster
)
857 pUnoBroadcaster
->Broadcast( ScUpdateRefHint(
858 eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
) );
862 for ( ; i
<=iMax
; i
++)
864 pTab
[i
]->UpdateReference(
865 eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
,
866 nDx
, nDy
, nDz
, pUndoDoc
, bIncludeDraw
);
876 theCol1
= aEmbedRange
.aStart
.Col();
877 theRow1
= aEmbedRange
.aStart
.Row();
878 theTab1
= aEmbedRange
.aStart
.Tab();
879 theCol2
= aEmbedRange
.aEnd
.Col();
880 theRow2
= aEmbedRange
.aEnd
.Row();
881 theTab2
= aEmbedRange
.aEnd
.Tab();
882 if ( ScRefUpdate::Update( this, eUpdateRefMode
, nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
883 nDx
,nDy
,nDz
, theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) )
885 aEmbedRange
= ScRange( theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
);
888 SetExpandRefs( bExpandRefsOld
);
890 // #30428# after moving, no clipboard move ref-updates are possible
891 if ( eUpdateRefMode
!= URM_COPY
&& IsClipboardSource() )
893 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
895 pClipDoc
->GetClipParam().mbCutMode
= false;
900 void ScDocument::UpdateTranspose( const ScAddress
& rDestPos
, ScDocument
* pClipDoc
,
901 const ScMarkData
& rMark
, ScDocument
* pUndoDoc
)
903 DBG_ASSERT(pClipDoc
->bIsClip
, "UpdateTranspose: kein Clip");
906 ScClipParam
& rClipParam
= GetClipParam();
907 if (rClipParam
.maRanges
.Count())
908 aSource
= *rClipParam
.maRanges
.First();
909 ScAddress aDest
= rDestPos
;
912 for (SCTAB nDestTab
=0; nDestTab
<=MAXTAB
&& pTab
[nDestTab
]; nDestTab
++)
913 if (rMark
.GetTableSelect(nDestTab
))
915 while (!pClipDoc
->pTab
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
916 aSource
.aStart
.SetTab( nClipTab
);
917 aSource
.aEnd
.SetTab( nClipTab
);
918 aDest
.SetTab( nDestTab
);
920 // wie UpdateReference
922 pRangeName
->UpdateTranspose( aSource
, aDest
); // vor den Zellen!
923 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
925 pTab
[i
]->UpdateTranspose( aSource
, aDest
, pUndoDoc
);
927 nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
931 void ScDocument::UpdateGrow( const ScRange
& rArea
, SCCOL nGrowX
, SCROW nGrowY
)
937 pRangeName
->UpdateGrow( rArea
, nGrowX
, nGrowY
);
938 #if OLD_PIVOT_IMPLEMENTATION
939 pPivotCollection
->UpdateGrow( rArea
, nGrowX
, nGrowY
);
942 for (SCTAB i
=0; i
<=MAXTAB
&& pTab
[i
]; i
++)
943 pTab
[i
]->UpdateGrow( rArea
, nGrowX
, nGrowY
);
946 void ScDocument::Fill(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, const ScMarkData
& rMark
,
947 ULONG nFillCount
, FillDir eFillDir
, FillCmd eFillCmd
, FillDateCmd eFillDateCmd
,
948 double nStepValue
, double nMaxValue
)
950 PutInOrder( nCol1
, nCol2
);
951 PutInOrder( nRow1
, nRow2
);
952 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
954 if (rMark
.GetTableSelect(i
))
955 pTab
[i
]->Fill(nCol1
, nRow1
, nCol2
, nRow2
,
956 nFillCount
, eFillDir
, eFillCmd
, eFillDateCmd
,
957 nStepValue
, nMaxValue
);
960 String
ScDocument::GetAutoFillPreview( const ScRange
& rSource
, SCCOL nEndX
, SCROW nEndY
)
962 SCTAB nTab
= rSource
.aStart
.Tab();
964 return pTab
[nTab
]->GetAutoFillPreview( rSource
, nEndX
, nEndY
);
969 void ScDocument::AutoFormat( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
970 USHORT nFormatNo
, const ScMarkData
& rMark
)
972 PutInOrder( nStartCol
, nEndCol
);
973 PutInOrder( nStartRow
, nEndRow
);
974 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
976 if (rMark
.GetTableSelect(i
))
977 pTab
[i
]->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
);
980 void ScDocument::GetAutoFormatData(SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
981 ScAutoFormatData
& rData
)
987 PutInOrder(nStartCol
, nEndCol
);
988 PutInOrder(nStartRow
, nEndRow
);
989 pTab
[nTab
]->GetAutoFormatData(nStartCol
, nStartRow
, nEndCol
, nEndRow
, rData
);
995 void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem
& rSearchItem
,
996 SCCOL
& rCol
, SCROW
& rRow
)
998 USHORT nCommand
= rSearchItem
.GetCommand();
999 BOOL bReplace
= ( nCommand
== SVX_SEARCHCMD_REPLACE
||
1000 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
);
1001 if ( rSearchItem
.GetBackward() )
1003 if ( rSearchItem
.GetRowDirection() )
1005 if ( rSearchItem
.GetPattern() )
1010 else if ( bReplace
)
1023 if ( rSearchItem
.GetPattern() )
1028 else if ( bReplace
)
1042 if ( rSearchItem
.GetRowDirection() )
1044 if ( rSearchItem
.GetPattern() )
1049 else if ( bReplace
)
1062 if ( rSearchItem
.GetPattern() )
1067 else if ( bReplace
)
1081 BOOL
ScDocument::SearchAndReplace(const SvxSearchItem
& rSearchItem
,
1082 SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
,
1084 String
& rUndoStr
, ScDocument
* pUndoDoc
)
1086 //! getrennte Markierungen pro Tabelle verwalten !!!!!!!!!!!!!
1088 rMark
.MarkToMulti();
1090 BOOL bFound
= FALSE
;
1096 USHORT nCommand
= rSearchItem
.GetCommand();
1097 if ( nCommand
== SVX_SEARCHCMD_FIND_ALL
||
1098 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1100 for (nTab
= 0; nTab
<= MAXTAB
; nTab
++)
1103 if (rMark
.GetTableSelect(nTab
))
1107 bFound
|= pTab
[nTab
]->SearchAndReplace(
1108 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1112 // Markierung wird innen schon komplett gesetzt
1118 if (rSearchItem
.GetBackward())
1120 for (nTab
= rTab
; ((SCsTAB
)nTab
>= 0) && !bFound
; nTab
--)
1123 if (rMark
.GetTableSelect(nTab
))
1125 bFound
= pTab
[nTab
]->SearchAndReplace(
1126 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1134 ScDocument::GetSearchAndReplaceStart(
1135 rSearchItem
, nCol
, nRow
);
1141 for (nTab
= rTab
; (nTab
<= MAXTAB
) && !bFound
; nTab
++)
1144 if (rMark
.GetTableSelect(nTab
))
1146 bFound
= pTab
[nTab
]->SearchAndReplace(
1147 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1155 ScDocument::GetSearchAndReplaceStart(
1156 rSearchItem
, nCol
, nRow
);
1167 BOOL
ScDocument::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, BOOL bShow
)
1169 if ( ValidTab(nTab
) && pTab
[nTab
] )
1170 return pTab
[nTab
]->UpdateOutlineCol( nStartCol
, nEndCol
, bShow
);
1172 DBG_ERROR("missing tab");
1176 BOOL
ScDocument::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, BOOL bShow
)
1178 if ( ValidTab(nTab
) && pTab
[nTab
] )
1179 return pTab
[nTab
]->UpdateOutlineRow( nStartRow
, nEndRow
, bShow
);
1181 DBG_ERROR("missing tab");
1185 void ScDocument::Sort(SCTAB nTab
, const ScSortParam
& rSortParam
, BOOL bKeepQuery
)
1187 if ( ValidTab(nTab
) && pTab
[nTab
] )
1189 BOOL bOldDisableIdle
= IsIdleDisabled();
1190 DisableIdle( TRUE
);
1191 pTab
[nTab
]->Sort(rSortParam
, bKeepQuery
);
1192 DisableIdle( bOldDisableIdle
);
1196 SCSIZE
ScDocument::Query(SCTAB nTab
, const ScQueryParam
& rQueryParam
, BOOL bKeepSub
)
1198 if ( ValidTab(nTab
) && pTab
[nTab
] )
1199 return pTab
[nTab
]->Query((ScQueryParam
&)rQueryParam
, bKeepSub
);
1201 DBG_ERROR("missing tab");
1206 BOOL
ScDocument::ValidQuery( SCROW nRow
, SCTAB nTab
, const ScQueryParam
& rQueryParam
, BOOL
* pSpecial
)
1208 if ( ValidTab(nTab
) && pTab
[nTab
] )
1209 return pTab
[nTab
]->ValidQuery( nRow
, rQueryParam
, pSpecial
);
1211 DBG_ERROR("missing tab");
1216 void ScDocument::GetUpperCellString(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rStr
)
1218 if ( ValidTab(nTab
) && pTab
[nTab
] )
1219 pTab
[nTab
]->GetUpperCellString( nCol
, nRow
, rStr
);
1224 BOOL
ScDocument::CreateQueryParam(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab
, ScQueryParam
& rQueryParam
)
1226 if ( ValidTab(nTab
) && pTab
[nTab
] )
1227 return pTab
[nTab
]->CreateQueryParam(nCol1
, nRow1
, nCol2
, nRow2
, rQueryParam
);
1229 DBG_ERROR("missing tab");
1233 BOOL
ScDocument::HasAutoFilter( SCCOL nCurCol
, SCROW nCurRow
, SCTAB nCurTab
)
1235 ScDBData
* pDBData
= GetDBAtCursor( nCurCol
, nCurRow
, nCurTab
);
1236 BOOL bHasAutoFilter
= ( pDBData
!= NULL
);
1240 if ( pDBData
->HasHeader() )
1246 ScQueryParam aParam
;
1247 pDBData
->GetQueryParam( aParam
);
1248 nRow
= aParam
.nRow1
;
1250 for ( nCol
=aParam
.nCol1
; nCol
<=aParam
.nCol2
&& bHasAutoFilter
; nCol
++ )
1252 nFlag
= ((ScMergeFlagAttr
*)
1253 GetAttr( nCol
, nRow
, nCurTab
, ATTR_MERGE_FLAG
))->
1256 if ( (nFlag
& SC_MF_AUTO
) == 0 )
1257 bHasAutoFilter
= FALSE
;
1261 bHasAutoFilter
= FALSE
;
1264 return bHasAutoFilter
;
1267 BOOL
ScDocument::HasColHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1270 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasColHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1271 //if (VALIDTAB(nTab))
1273 // return pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1278 BOOL
ScDocument::HasRowHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1281 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasRowHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1282 //if (VALIDTAB(nTab))
1284 // return pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1289 void ScDocument::UpdateDynamicEndRow(ScDBData
& rDBData
) const
1294 rDBData
.GetArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
1295 SCCOL nCol1a
= nCol1
, nCol2a
= nCol2
;
1296 SCROW nRow1a
= nRow1
, nRow2a
= nRow2
;
1297 GetDataArea(nTab
, nCol1a
, nRow1a
, nCol2a
, nRow2a
, false);
1298 rDBData
.SetDynamicEndRow(nRow2a
);
1302 // GetFilterEntries - Eintraege fuer AutoFilter-Listbox
1305 BOOL
ScDocument::GetFilterEntries( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, TypedScStrCollection
& rStrings
, bool bFilter
)
1307 if ( ValidTab(nTab
) && pTab
[nTab
] && pDBCollection
)
1309 ScDBData
* pDBData
= pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, FALSE
); //!??
1312 UpdateDynamicEndRow(*pDBData
);
1318 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1319 if (pDBData
->HasHeader())
1322 ScQueryParam aParam
;
1323 pDBData
->GetQueryParam( aParam
);
1324 nEndRow
= aParam
.nDynamicEndRow
;
1325 rStrings
.SetCaseSensitive( aParam
.bCaseSens
);
1327 // return all filter entries, if a filter condition is connected with a boolean OR
1330 SCSIZE nEntryCount
= aParam
.GetEntryCount();
1331 for ( SCSIZE i
= 0; i
< nEntryCount
&& aParam
.GetEntry(i
).bDoQuery
; ++i
)
1333 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1334 if ( rEntry
.eConnect
!= SC_AND
)
1344 pTab
[nTab
]->GetFilteredFilterEntries( nCol
, nStartRow
, nEndRow
, aParam
, rStrings
);
1348 pTab
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
);
1359 // GetFilterEntriesArea - Eintraege fuer Filter-Dialog
1362 BOOL
ScDocument::GetFilterEntriesArea( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
,
1363 SCTAB nTab
, TypedScStrCollection
& rStrings
)
1365 if ( ValidTab(nTab
) && pTab
[nTab
] )
1367 pTab
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
);
1375 // GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln)
1378 BOOL
ScDocument::GetDataEntries( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
1379 TypedScStrCollection
& rStrings
, BOOL bLimit
)
1383 /* Try to generate the list from list validation. This part is skipped,
1384 if bLimit==TRUE, because in that case this function is called to get
1385 cell values for auto completion on input. */
1386 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
1389 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
1390 if( pData
&& pData
->FillSelectionList( rStrings
, ScAddress( nCol
, nRow
, nTab
) ) )
1395 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->GetDataEntries( nCol
, nRow
, rStrings
, bLimit
);
1396 //if (ValidTab(nTab) && pTab[nTab])
1397 // return pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
1403 // GetFormulaEntries - Eintraege fuer Formel-AutoEingabe
1406 // Funktionen werden als 1 schon vom InputHandler eingefuegt
1407 #define SC_STRTYPE_NAMES 2
1408 #define SC_STRTYPE_DBNAMES 3
1409 #define SC_STRTYPE_HEADERS 4
1411 BOOL
ScDocument::GetFormulaEntries( TypedScStrCollection
& rStrings
)
1421 USHORT nRangeCount
= pRangeName
->GetCount();
1422 for ( i
=0; i
<nRangeCount
; i
++ )
1424 ScRangeData
* pData
= (*pRangeName
)[i
];
1427 TypedStrData
* pNew
= new TypedStrData( pData
->GetName(), 0.0, SC_STRTYPE_NAMES
);
1428 if ( !rStrings
.Insert(pNew
) )
1435 // Datenbank-Bereiche
1438 if ( pDBCollection
)
1440 USHORT nDBCount
= pDBCollection
->GetCount();
1441 for ( i
=0; i
<nDBCount
; i
++ )
1443 ScDBData
* pData
= (*pDBCollection
)[i
];
1446 TypedStrData
* pNew
= new TypedStrData( pData
->GetName(), 0.0, SC_STRTYPE_DBNAMES
);
1447 if ( !rStrings
.Insert(pNew
) )
1454 // Inhalte von Beschriftungsbereichen
1457 ScRangePairList
* pLists
[2];
1458 pLists
[0] = GetColNameRanges();
1459 pLists
[1] = GetRowNameRanges();
1460 for (USHORT nListNo
=0; nListNo
<2; nListNo
++)
1462 ScRangePairList
* pList
= pLists
[nListNo
];
1464 for ( ScRangePair
* pPair
= pList
->First(); pPair
; pPair
= pList
->Next() )
1466 ScRange aRange
= pPair
->GetRange(0);
1467 ScCellIterator
aIter( this, aRange
);
1468 for ( ScBaseCell
* pCell
= aIter
.GetFirst(); pCell
; pCell
= aIter
.GetNext() )
1469 if ( pCell
->HasStringData() )
1471 String aStr
= pCell
->GetStringData();
1472 TypedStrData
* pNew
= new TypedStrData( aStr
, 0.0, SC_STRTYPE_HEADERS
);
1473 if ( !rStrings
.Insert(pNew
) )
1483 BOOL
ScDocument::IsEmbedded() const
1488 void ScDocument::GetEmbedded( ScRange
& rRange
) const
1490 rRange
= aEmbedRange
;
1493 Rectangle
ScDocument::GetEmbeddedRect() const // 1/100 mm
1496 ScTable
* pTable
= pTab
[aEmbedRange
.aStart
.Tab()];
1499 DBG_ERROR("GetEmbeddedRect ohne Tabelle");
1505 for (i
=0; i
<aEmbedRange
.aStart
.Col(); i
++)
1506 aRect
.Left() += pTable
->GetColWidth(i
);
1507 aRect
.Top() += pTable
->GetRowHeight( 0, aEmbedRange
.aStart
.Row() - 1);
1508 aRect
.Right() = aRect
.Left();
1509 for (i
=aEmbedRange
.aStart
.Col(); i
<=aEmbedRange
.aEnd
.Col(); i
++)
1510 aRect
.Right() += pTable
->GetColWidth(i
);
1511 aRect
.Bottom() = aRect
.Top();
1512 aRect
.Bottom() += pTable
->GetRowHeight( aEmbedRange
.aStart
.Row(), aEmbedRange
.aEnd
.Row());
1514 aRect
.Left() = (long) ( aRect
.Left() * HMM_PER_TWIPS
);
1515 aRect
.Right() = (long) ( aRect
.Right() * HMM_PER_TWIPS
);
1516 aRect
.Top() = (long) ( aRect
.Top() * HMM_PER_TWIPS
);
1517 aRect
.Bottom() = (long) ( aRect
.Bottom() * HMM_PER_TWIPS
);
1522 void ScDocument::SetEmbedded( const ScRange
& rRange
)
1525 aEmbedRange
= rRange
;
1528 void ScDocument::ResetEmbedded()
1530 bIsEmbedded
= FALSE
;
1531 aEmbedRange
= ScRange();
1534 ScRange
ScDocument::GetRange( SCTAB nTab
, const Rectangle
& rMMRect
)
1536 ScTable
* pTable
= pTab
[nTab
];
1539 DBG_ERROR("GetRange ohne Tabelle");
1543 Rectangle aPosRect
= rMMRect
;
1544 if ( IsNegativePage( nTab
) )
1545 ScDrawLayer::MirrorRectRTL( aPosRect
); // always with positive (LTR) values
1553 nTwips
= (long) (aPosRect
.Left() / HMM_PER_TWIPS
);
1559 nAdd
= (long) pTable
->GetColWidth(nX1
);
1560 if (nSize
+nAdd
<= nTwips
+1 && nX1
<MAXCOL
)
1569 nTwips
= (long) (aPosRect
.Right() / HMM_PER_TWIPS
);
1575 nAdd
= (long) pTable
->GetColWidth(nX2
);
1576 if (nSize
+nAdd
< nTwips
&& nX2
<MAXCOL
)
1587 nTwips
= (long) (aPosRect
.Top() / HMM_PER_TWIPS
);
1591 for (SCROW i
= nY1
; i
<= MAXROW
&& !bEnd
; ++i
)
1593 if (pTable
->RowHidden(i
))
1597 nAdd
= static_cast<long>(pTable
->GetRowHeight(i
));
1598 if (nSize
+nAdd
<= nTwips
+1 && nY1
<MAXROW
)
1607 nY1
= MAXROW
; // all hidden down to the bottom
1609 nTwips
= (long) (aPosRect
.Bottom() / HMM_PER_TWIPS
);
1613 for (SCROW i
= nY2
; i
<= MAXROW
&& !bEnd
; ++i
)
1616 nAdd
= static_cast<long>(pTable
->GetRowHeight(i
));
1617 if (nSize
+nAdd
< nTwips
&& nY2
<MAXROW
)
1626 nY2
= MAXROW
; // all hidden down to the bottom
1628 return ScRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
1631 void ScDocument::SetEmbedded( const Rectangle
& rRect
) // aus VisArea (1/100 mm)
1634 aEmbedRange
= GetRange( nVisibleTab
, rRect
);
1637 // VisArea auf Zellgrenzen anpassen
1639 void lcl_SnapHor( ScTable
* pTable
, long& rVal
, SCCOL
& rStartCol
)
1642 long nTwips
= (long) (rVal
/ HMM_PER_TWIPS
);
1644 while ( nCol
<MAXCOL
)
1646 long nAdd
= pTable
->GetColWidth(nCol
);
1647 if ( nSnap
+ nAdd
/2 < nTwips
|| nCol
< rStartCol
)
1655 rVal
= (long) ( nSnap
* HMM_PER_TWIPS
);
1659 void lcl_SnapVer( ScTable
* pTable
, long& rVal
, SCROW
& rStartRow
)
1662 long nTwips
= (long) (rVal
/ HMM_PER_TWIPS
);
1665 bool bFound
= false;
1666 for (SCROW i
= nRow
; i
<= MAXROW
; ++i
)
1669 if (pTable
->RowHidden(i
, NULL
, &nLastRow
))
1676 long nAdd
= pTable
->GetRowHeight(i
);
1677 if ( nSnap
+ nAdd
/2 < nTwips
|| nRow
< rStartRow
)
1689 nRow
= MAXROW
; // all hidden down to the bottom
1691 rVal
= (long) ( nSnap
* HMM_PER_TWIPS
);
1695 void ScDocument::SnapVisArea( Rectangle
& rRect
) const
1697 ScTable
* pTable
= pTab
[nVisibleTab
];
1700 DBG_ERROR("SetEmbedded ohne Tabelle");
1704 BOOL bNegativePage
= IsNegativePage( nVisibleTab
);
1705 if ( bNegativePage
)
1706 ScDrawLayer::MirrorRectRTL( rRect
); // calculate with positive (LTR) values
1709 lcl_SnapHor( pTable
, rRect
.Left(), nCol
);
1710 ++nCol
; // mindestens eine Spalte
1711 lcl_SnapHor( pTable
, rRect
.Right(), nCol
);
1714 lcl_SnapVer( pTable
, rRect
.Top(), nRow
);
1715 ++nRow
; // mindestens eine Zeile
1716 lcl_SnapVer( pTable
, rRect
.Bottom(), nRow
);
1718 if ( bNegativePage
)
1719 ScDrawLayer::MirrorRectRTL( rRect
); // back to real rectangle
1722 ScDocProtection
* ScDocument::GetDocProtection() const
1724 return pDocProtection
.get();
1727 void ScDocument::SetDocProtection(const ScDocProtection
* pProtect
)
1730 pDocProtection
.reset(new ScDocProtection(*pProtect
));
1732 pDocProtection
.reset(NULL
);
1735 BOOL
ScDocument::IsDocProtected() const
1737 return pDocProtection
.get() && pDocProtection
->isProtected();
1740 BOOL
ScDocument::IsDocEditable() const
1742 // import into read-only document is possible
1743 return !IsDocProtected() && ( bImportingXML
|| mbChangeReadOnlyEnabled
|| !pShell
|| !pShell
->IsReadOnly() );
1746 BOOL
ScDocument::IsTabProtected( SCTAB nTab
) const
1748 if (VALIDTAB(nTab
) && pTab
[nTab
])
1749 return pTab
[nTab
]->IsProtected();
1751 DBG_ERROR("Falsche Tabellennummer");
1755 ScTableProtection
* ScDocument::GetTabProtection( SCTAB nTab
) const
1757 if (VALIDTAB(nTab
) && pTab
[nTab
])
1758 return pTab
[nTab
]->GetProtection();
1763 void ScDocument::SetTabProtection(SCTAB nTab
, const ScTableProtection
* pProtect
)
1765 if (!ValidTab(nTab
))
1768 pTab
[nTab
]->SetProtection(pProtect
);
1771 void ScDocument::CopyTabProtection(SCTAB nTabSrc
, SCTAB nTabDest
)
1773 if (!ValidTab(nTabSrc
) || !ValidTab(nTabDest
))
1776 pTab
[nTabDest
]->SetProtection( pTab
[nTabSrc
]->GetProtection() );
1779 const ScDocOptions
& ScDocument::GetDocOptions() const
1781 DBG_ASSERT( pDocOptions
, "No DocOptions! :-(" );
1782 return *pDocOptions
;
1785 void ScDocument::SetDocOptions( const ScDocOptions
& rOpt
)
1789 DBG_ASSERT( pDocOptions
, "No DocOptions! :-(" );
1790 *pDocOptions
= rOpt
;
1791 rOpt
.GetDate( d
,m
,y
);
1793 SvNumberFormatter
* pFormatter
= xPoolHelper
->GetFormTable();
1794 pFormatter
->ChangeNullDate( d
,m
,y
);
1795 pFormatter
->ChangeStandardPrec( (USHORT
)rOpt
.GetStdPrecision() );
1796 pFormatter
->SetYear2000( rOpt
.GetYear2000() );
1797 SetGrammar( rOpt
.GetFormulaSyntax() );
1799 // Update the separators.
1800 ScCompiler::UpdateSeparatorsNative(
1801 rOpt
.GetFormulaSepArg(), rOpt
.GetFormulaSepArrayCol(), rOpt
.GetFormulaSepArrayRow());
1804 const ScViewOptions
& ScDocument::GetViewOptions() const
1806 DBG_ASSERT( pViewOptions
, "No ViewOptions! :-(" );
1807 return *pViewOptions
;
1810 void ScDocument::SetViewOptions( const ScViewOptions
& rOpt
)
1812 DBG_ASSERT( pViewOptions
, "No ViewOptions! :-(" );
1813 *pViewOptions
= rOpt
;
1816 void ScDocument::GetLanguage( LanguageType
& rLatin
, LanguageType
& rCjk
, LanguageType
& rCtl
) const
1819 rCjk
= eCjkLanguage
;
1820 rCtl
= eCtlLanguage
;
1823 void ScDocument::SetLanguage( LanguageType eLatin
, LanguageType eCjk
, LanguageType eCtl
)
1826 eCjkLanguage
= eCjk
;
1827 eCtlLanguage
= eCtl
;
1828 if ( xPoolHelper
.isValid() )
1830 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
1831 pPool
->SetPoolDefaultItem( SvxLanguageItem( eLanguage
, ATTR_FONT_LANGUAGE
) );
1832 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage
, ATTR_CJK_FONT_LANGUAGE
) );
1833 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage
, ATTR_CTL_FONT_LANGUAGE
) );
1836 UpdateDrawLanguages(); // set edit engine defaults in drawing layer pool
1839 void ScDocument::SetDrawDefaults()
1841 bSetDrawDefaults
= TRUE
;
1842 UpdateDrawDefaults();
1845 Rectangle
ScDocument::GetMMRect( SCCOL nStartCol
, SCROW nStartRow
,
1846 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
1848 if (!ValidTab(nTab
) || !pTab
[nTab
])
1850 DBG_ERROR("GetMMRect: falsche Tabelle");
1851 return Rectangle(0,0,0,0);
1857 for (i
=0; i
<nStartCol
; i
++)
1858 aRect
.Left() += GetColWidth(i
,nTab
);
1859 aRect
.Top() += FastGetRowHeight( 0, nStartRow
-1, nTab
);
1861 aRect
.Right() = aRect
.Left();
1862 aRect
.Bottom() = aRect
.Top();
1864 for (i
=nStartCol
; i
<=nEndCol
; i
++)
1865 aRect
.Right() += GetColWidth(i
,nTab
);
1866 aRect
.Bottom() += FastGetRowHeight( nStartRow
, nEndRow
, nTab
);
1868 aRect
.Left() = (long)(aRect
.Left() * HMM_PER_TWIPS
);
1869 aRect
.Right() = (long)(aRect
.Right() * HMM_PER_TWIPS
);
1870 aRect
.Top() = (long)(aRect
.Top() * HMM_PER_TWIPS
);
1871 aRect
.Bottom() = (long)(aRect
.Bottom() * HMM_PER_TWIPS
);
1873 if ( IsNegativePage( nTab
) )
1874 ScDrawLayer::MirrorRectRTL( aRect
);
1879 void ScDocument::SetExtDocOptions( ScExtDocOptions
* pNewOptions
)
1881 delete pExtDocOptions
;
1882 pExtDocOptions
= pNewOptions
;
1885 void ScDocument::DoMergeContents( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1886 SCCOL nEndCol
, SCROW nEndRow
)
1893 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
1894 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1896 GetString(nCol
,nRow
,nTab
,aCellStr
);
1903 if (nCol
!= nStartCol
|| nRow
!= nStartRow
)
1904 SetString(nCol
,nRow
,nTab
,aEmpty
);
1907 SetString(nStartCol
,nStartRow
,nTab
,aTotal
);
1910 void ScDocument::DoMerge( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1911 SCCOL nEndCol
, SCROW nEndRow
, bool bDeleteCaptions
)
1913 ScMergeAttr
aAttr( nEndCol
-nStartCol
+1, nEndRow
-nStartRow
+1 );
1914 ApplyAttr( nStartCol
, nStartRow
, nTab
, aAttr
);
1916 if ( nEndCol
> nStartCol
)
1917 ApplyFlagsTab( nStartCol
+1, nStartRow
, nEndCol
, nStartRow
, nTab
, SC_MF_HOR
);
1918 if ( nEndRow
> nStartRow
)
1919 ApplyFlagsTab( nStartCol
, nStartRow
+1, nStartCol
, nEndRow
, nTab
, SC_MF_VER
);
1920 if ( nEndCol
> nStartCol
&& nEndRow
> nStartRow
)
1921 ApplyFlagsTab( nStartCol
+1, nStartRow
+1, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1923 // remove all covered notes (removed captions are collected by drawing undo if active)
1924 USHORT nDelFlag
= IDF_NOTE
| (bDeleteCaptions
? 0 : IDF_NOCAPTIONS
);
1925 if( nStartCol
< nEndCol
)
1926 DeleteAreaTab( nStartCol
+ 1, nStartRow
, nEndCol
, nStartRow
, nTab
, nDelFlag
);
1927 if( nStartRow
< nEndRow
)
1928 DeleteAreaTab( nStartCol
, nStartRow
+ 1, nEndCol
, nEndRow
, nTab
, nDelFlag
);
1931 void ScDocument::RemoveMerge( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1933 const ScMergeAttr
* pAttr
= (const ScMergeAttr
*)
1934 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE
);
1936 if ( pAttr
->GetColMerge() <= 1 && pAttr
->GetRowMerge() <= 1 )
1939 SCCOL nEndCol
= nCol
+ pAttr
->GetColMerge() - 1;
1940 SCROW nEndRow
= nRow
+ pAttr
->GetRowMerge() - 1;
1942 RemoveFlagsTab( nCol
, nRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1944 const ScMergeAttr
* pDefAttr
= (const ScMergeAttr
*)
1945 &xPoolHelper
->GetDocPool()->GetDefaultItem( ATTR_MERGE
);
1946 ApplyAttr( nCol
, nRow
, nTab
, *pDefAttr
);
1949 void ScDocument::ExtendPrintArea( OutputDevice
* pDev
, SCTAB nTab
,
1950 SCCOL nStartCol
, SCROW nStartRow
, SCCOL
& rEndCol
, SCROW nEndRow
)
1952 if ( ValidTab(nTab
) && pTab
[nTab
] )
1953 pTab
[nTab
]->ExtendPrintArea( pDev
, nStartCol
, nStartRow
, rEndCol
, nEndRow
);
1956 void ScDocument::IncSizeRecalcLevel( SCTAB nTab
)
1958 if ( ValidTab(nTab
) && pTab
[nTab
] )
1959 pTab
[nTab
]->IncRecalcLevel();
1962 void ScDocument::DecSizeRecalcLevel( SCTAB nTab
)
1964 if ( ValidTab(nTab
) && pTab
[nTab
] )
1965 pTab
[nTab
]->DecRecalcLevel();