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 <svtools/PasswordHelper.hxx>
44 #include <vcl/svapp.hxx>
45 #include "document.hxx"
49 #include "rangenam.hxx"
50 #include "dbcolect.hxx"
52 #include "docpool.hxx"
53 #include "poolhelp.hxx"
54 #include "autoform.hxx"
55 #include "rangelst.hxx"
56 #include "chartarr.hxx"
57 #include "chartlock.hxx"
58 #include "compiler.hxx"
59 #include "refupdat.hxx"
60 #include "docoptio.hxx"
61 #include "viewopti.hxx"
62 #include "scextopt.hxx"
64 #include "bcaslot.hxx"
65 #include "tablink.hxx"
66 #include "externalrefmgr.hxx"
67 #include "markdata.hxx"
68 #include "validat.hxx"
69 #include "dociter.hxx"
70 #include "detdata.hxx"
71 #include "detfunc.hxx"
72 #include "scmod.hxx" // SC_MOD
73 #include "inputopt.hxx" // GetExpandRefs
74 #include "chartlis.hxx"
75 #include "sc.hrc" // SID_LINK
77 #include "dpobject.hxx"
78 #include "unoguard.hxx"
79 #include "drwlayer.hxx"
80 #include "unoreflist.hxx"
81 #include "listenercalls.hxx"
82 #include "tabprotection.hxx"
83 #include "formulaparserpool.hxx"
84 #include "clipparam.hxx"
88 using namespace com::sun::star
;
89 using ::std::auto_ptr
;
91 //------------------------------------------------------------------------
93 ScRangeName
* ScDocument::GetRangeName()
98 void ScDocument::SetRangeName( ScRangeName
* pNewRangeName
)
102 pRangeName
= pNewRangeName
;
105 //UNUSED2008-05 ScRangeData* ScDocument::GetRangeAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab,
106 //UNUSED2008-05 BOOL bStartOnly) const
108 //UNUSED2008-05 if ( pRangeName )
109 //UNUSED2008-05 return pRangeName->GetRangeAtCursor( ScAddress( nCol, nRow, nTab ), bStartOnly );
111 //UNUSED2008-05 return NULL;
114 ScRangeData
* ScDocument::GetRangeAtBlock( const ScRange
& rBlock
, String
* pName
) const
116 ScRangeData
* pData
= NULL
;
119 pData
= pRangeName
->GetRangeAtBlock( rBlock
);
121 *pName
= pData
->GetName();
126 ScDBCollection
* ScDocument::GetDBCollection() const
128 return pDBCollection
;
131 void ScDocument::SetDBCollection( ScDBCollection
* pNewDBCollection
, BOOL bRemoveAutoFilter
)
133 if ( bRemoveAutoFilter
)
135 // remove auto filter attribute if new db data don't contain auto filter flag
136 // start position is also compared, so bRemoveAutoFilter must not be set from ref-undo!
140 USHORT nOldCount
= pDBCollection
->GetCount();
141 for (USHORT nOld
=0; nOld
<nOldCount
; nOld
++)
143 ScDBData
* pOldData
= (*pDBCollection
)[nOld
];
144 if ( pOldData
->HasAutoFilter() )
147 pOldData
->GetArea( aOldRange
);
150 USHORT nNewIndex
= 0;
151 if ( pNewDBCollection
&&
152 pNewDBCollection
->SearchName( pOldData
->GetName(), nNewIndex
) )
154 ScDBData
* pNewData
= (*pNewDBCollection
)[nNewIndex
];
155 if ( pNewData
->HasAutoFilter() )
158 pNewData
->GetArea( aNewRange
);
159 if ( aOldRange
.aStart
== aNewRange
.aStart
)
166 aOldRange
.aEnd
.SetRow( aOldRange
.aStart
.Row() );
167 RemoveFlagsTab( aOldRange
.aStart
.Col(), aOldRange
.aStart
.Row(),
168 aOldRange
.aEnd
.Col(), aOldRange
.aEnd
.Row(),
169 aOldRange
.aStart
.Tab(), SC_MF_AUTO
);
171 pShell
->Broadcast( ScPaintHint( aOldRange
, PAINT_GRID
) );
179 delete pDBCollection
;
180 pDBCollection
= pNewDBCollection
;
183 ScDBData
* ScDocument::GetDBAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, BOOL bStartOnly
) const
186 return pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, bStartOnly
);
191 ScDBData
* ScDocument::GetDBAtArea(SCTAB nTab
, SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
) const
194 return pDBCollection
->GetDBAtArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
199 ScDPCollection
* ScDocument::GetDPCollection()
202 pDPCollection
= new ScDPCollection(this);
203 return pDPCollection
;
206 ScDPObject
* ScDocument::GetDPAtCursor(SCCOL nCol
, SCROW nRow
, SCTAB nTab
) const
211 USHORT nCount
= pDPCollection
->GetCount();
212 ScAddress
aPos( nCol
, nRow
, nTab
);
213 for (USHORT i
=0; i
<nCount
; i
++)
214 if ( (*pDPCollection
)[i
]->GetOutRange().In( aPos
) )
215 return (*pDPCollection
)[i
];
220 ScDPObject
* ScDocument::GetDPAtBlock( const ScRange
& rBlock
) const
225 /* Walk the collection in reverse order to get something of an
226 * approximation of MS Excels 'most recent' effect. */
227 USHORT i
= pDPCollection
->GetCount();
229 if ( (*pDPCollection
)[i
]->GetOutRange().In( rBlock
) )
230 return (*pDPCollection
)[i
];
235 ScChartCollection
* ScDocument::GetChartCollection() const
237 return pChartCollection
;
240 void ScDocument::StopTemporaryChartLock()
242 if( apTemporaryChartLock
.get() )
243 apTemporaryChartLock
->StopLocking();
246 void ScDocument::SetChartListenerCollection(
247 ScChartListenerCollection
* pNewChartListenerCollection
,
248 BOOL bSetChartRangeLists
)
250 ScChartListenerCollection
* pOld
= pChartListenerCollection
;
251 pChartListenerCollection
= pNewChartListenerCollection
;
252 if ( pChartListenerCollection
)
255 pChartListenerCollection
->SetDiffDirty( *pOld
, bSetChartRangeLists
);
256 pChartListenerCollection
->StartAllListeners();
261 void ScDocument::SetScenario( SCTAB nTab
, BOOL bFlag
)
263 if (ValidTab(nTab
) && pTab
[nTab
])
264 pTab
[nTab
]->SetScenario(bFlag
);
267 BOOL
ScDocument::IsScenario( SCTAB nTab
) const
269 return ValidTab(nTab
) && pTab
[nTab
] &&pTab
[nTab
]->IsScenario();
270 //if (ValidTab(nTab) && pTab[nTab])
271 // return pTab[nTab]->IsScenario();
276 void ScDocument::SetScenarioData( SCTAB nTab
, const String
& rComment
,
277 const Color
& rColor
, USHORT nFlags
)
279 if (ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
281 pTab
[nTab
]->SetScenarioComment( rComment
);
282 pTab
[nTab
]->SetScenarioColor( rColor
);
283 pTab
[nTab
]->SetScenarioFlags( nFlags
);
287 void ScDocument::GetScenarioData( SCTAB nTab
, String
& rComment
,
288 Color
& rColor
, USHORT
& rFlags
) const
290 if (ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
292 pTab
[nTab
]->GetScenarioComment( rComment
);
293 rColor
= pTab
[nTab
]->GetScenarioColor();
294 rFlags
= pTab
[nTab
]->GetScenarioFlags();
298 void ScDocument::GetScenarioFlags( SCTAB nTab
, USHORT
& rFlags
) const
300 if (VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsScenario())
301 rFlags
= pTab
[nTab
]->GetScenarioFlags();
304 BOOL
ScDocument::IsLinked( SCTAB nTab
) const
306 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsLinked();
308 //if (ValidTab(nTab) && pTab[nTab])
309 // return pTab[nTab]->IsLinked();
313 formula::FormulaGrammar::AddressConvention
ScDocument::GetAddressConvention() const
315 return formula::FormulaGrammar::extractRefConvention(eGrammar
);
318 formula::FormulaGrammar::Grammar
ScDocument::GetGrammar() const
323 void ScDocument::SetGrammar( formula::FormulaGrammar::Grammar eGram
)
328 BOOL
ScDocument::GetLinkMode( SCTAB nTab
) const
330 if (ValidTab(nTab
) && pTab
[nTab
])
331 return pTab
[nTab
]->GetLinkMode();
335 const String
& ScDocument::GetLinkDoc( SCTAB nTab
) const
337 if (ValidTab(nTab
) && pTab
[nTab
])
338 return pTab
[nTab
]->GetLinkDoc();
342 const String
& ScDocument::GetLinkFlt( SCTAB nTab
) const
344 if (ValidTab(nTab
) && pTab
[nTab
])
345 return pTab
[nTab
]->GetLinkFlt();
349 const String
& ScDocument::GetLinkOpt( SCTAB nTab
) const
351 if (ValidTab(nTab
) && pTab
[nTab
])
352 return pTab
[nTab
]->GetLinkOpt();
356 const String
& ScDocument::GetLinkTab( SCTAB nTab
) const
358 if (ValidTab(nTab
) && pTab
[nTab
])
359 return pTab
[nTab
]->GetLinkTab();
363 ULONG
ScDocument::GetLinkRefreshDelay( SCTAB nTab
) const
365 if (ValidTab(nTab
) && pTab
[nTab
])
366 return pTab
[nTab
]->GetLinkRefreshDelay();
370 void ScDocument::SetLink( SCTAB nTab
, BYTE nMode
, const String
& rDoc
,
371 const String
& rFilter
, const String
& rOptions
,
372 const String
& rTabName
, ULONG nRefreshDelay
)
374 if (ValidTab(nTab
) && pTab
[nTab
])
375 pTab
[nTab
]->SetLink( nMode
, rDoc
, rFilter
, rOptions
, rTabName
, nRefreshDelay
);
378 BOOL
ScDocument::HasLink( const String
& rDoc
,
379 const String
& rFilter
, const String
& rOptions
) const
381 SCTAB nCount
= GetTableCount();
382 for (SCTAB i
=0; i
<nCount
; i
++)
383 if (pTab
[i
]->IsLinked()
384 && pTab
[i
]->GetLinkDoc() == rDoc
385 && pTab
[i
]->GetLinkFlt() == rFilter
386 && pTab
[i
]->GetLinkOpt() == rOptions
)
392 BOOL
ScDocument::LinkExternalTab( SCTAB
& rTab
, const String
& aDocTab
,
393 const String
& aFileName
, const String
& aTabName
)
397 DBG_ERRORFILE( "LinkExternalTab in Clipboard" );
401 String aFilterName
; // wird vom Loader gefuellt
402 String aOptions
; // Filter-Optionen
403 sal_uInt32 nLinkCnt
= pExtDocOptions
? pExtDocOptions
->GetDocSettings().mnLinkCnt
: 0;
404 ScDocumentLoader
aLoader( aFileName
, aFilterName
, aOptions
, nLinkCnt
+ 1 );
405 if ( aLoader
.IsError() )
407 ScDocument
* pSrcDoc
= aLoader
.GetDocument();
411 if ( pSrcDoc
->GetTable( aTabName
, nSrcTab
) )
413 if ( !InsertTab( SC_TAB_APPEND
, aDocTab
, TRUE
) )
415 DBG_ERRORFILE("can't insert external document table");
418 rTab
= GetTableCount() - 1;
419 // nicht neu einfuegen, nur Ergebnisse
420 TransferTab( pSrcDoc
, nSrcTab
, rTab
, FALSE
, TRUE
);
425 ULONG nRefreshDelay
= 0;
427 BOOL bWasThere
= HasLink( aFileName
, aFilterName
, aOptions
);
428 SetLink( rTab
, SC_LINK_VALUE
, aFileName
, aFilterName
, aOptions
, aTabName
, nRefreshDelay
);
429 if ( !bWasThere
) // Link pro Quelldokument nur einmal eintragen
431 ScTableLink
* pLink
= new ScTableLink( pShell
, aFileName
, aFilterName
, aOptions
, nRefreshDelay
);
432 pLink
->SetInCreate( TRUE
);
433 GetLinkManager()->InsertFileLink( *pLink
, OBJECT_CLIENT_FILE
, aFileName
,
436 pLink
->SetInCreate( FALSE
);
437 SfxBindings
* pBindings
= GetViewBindings();
439 pBindings
->Invalidate( SID_LINKS
);
444 ScExternalRefManager
* ScDocument::GetExternalRefManager()
446 if (!pExternalRefMgr
.get())
447 pExternalRefMgr
.reset(new ScExternalRefManager(this));
449 return pExternalRefMgr
.get();
452 bool ScDocument::IsInExternalReferenceMarking() const
454 return pExternalRefMgr
.get() && pExternalRefMgr
->isInReferenceMarking();
457 void ScDocument::MarkUsedExternalReferences()
459 if (!pExternalRefMgr
.get())
461 if (!pExternalRefMgr
->hasExternalData())
464 bool bAllMarked
= pExternalRefMgr
->markUsedByLinkListeners();
466 for (SCTAB nTab
= 0; !bAllMarked
&& nTab
< nMaxTableNumber
; ++nTab
)
469 bAllMarked
= pTab
[nTab
]->MarkUsedExternalReferences();
471 /* NOTE: Conditional formats and validation objects are marked when
472 * collecting them during export. */
475 ScFormulaParserPool
& ScDocument::GetFormulaParserPool() const
477 if( !mxFormulaParserPool
.get() )
478 mxFormulaParserPool
.reset( new ScFormulaParserPool( *this ) );
479 return *mxFormulaParserPool
;
482 ScOutlineTable
* ScDocument::GetOutlineTable( SCTAB nTab
, BOOL bCreate
)
484 ScOutlineTable
* pVal
= NULL
;
489 pVal
= pTab
[nTab
]->GetOutlineTable();
493 pTab
[nTab
]->StartOutlineTable();
494 pVal
= pTab
[nTab
]->GetOutlineTable();
501 BOOL
ScDocument::SetOutlineTable( SCTAB nTab
, const ScOutlineTable
* pNewOutline
)
503 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->SetOutlineTable(pNewOutline
);
504 //if (VALIDTAB(nTab))
506 // return pTab[nTab]->SetOutlineTable(pNewOutline);
511 void ScDocument::DoAutoOutline( SCCOL nStartCol
, SCROW nStartRow
,
512 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
514 if (VALIDTAB(nTab
) && pTab
[nTab
])
515 pTab
[nTab
]->DoAutoOutline( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
518 BOOL
ScDocument::TestRemoveSubTotals( SCTAB nTab
, const ScSubTotalParam
& rParam
)
520 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->TestRemoveSubTotals( rParam
);
521 //if (VALIDTAB(nTab) && pTab[nTab] )
522 // return pTab[nTab]->TestRemoveSubTotals( rParam );
527 void ScDocument::RemoveSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
529 if ( VALIDTAB(nTab
) && pTab
[nTab
] )
530 pTab
[nTab
]->RemoveSubTotals( rParam
);
533 BOOL
ScDocument::DoSubTotals( SCTAB nTab
, ScSubTotalParam
& rParam
)
535 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->DoSubTotals( rParam
);
536 //if (VALIDTAB(nTab))
538 // return pTab[nTab]->DoSubTotals( rParam );
543 BOOL
ScDocument::HasSubTotalCells( const ScRange
& rRange
)
545 ScCellIterator
aIter( this, rRange
);
546 ScBaseCell
* pCell
= aIter
.GetFirst();
549 if ( pCell
->GetCellType() == CELLTYPE_FORMULA
&& ((ScFormulaCell
*)pCell
)->IsSubTotal() )
552 pCell
= aIter
.GetNext();
554 return FALSE
; // none found
557 // kopiert aus diesem Dokument die Zellen von Positionen, an denen in pPosDoc
558 // auch Zellen stehen, nach pDestDoc
560 void ScDocument::CopyUpdated( ScDocument
* pPosDoc
, ScDocument
* pDestDoc
)
562 SCTAB nCount
= GetTableCount();
563 for (SCTAB nTab
=0; nTab
<nCount
; nTab
++)
564 if (pTab
[nTab
] && pPosDoc
->pTab
[nTab
] && pDestDoc
->pTab
[nTab
])
565 pTab
[nTab
]->CopyUpdated( pPosDoc
->pTab
[nTab
], pDestDoc
->pTab
[nTab
] );
568 void ScDocument::CopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
, BOOL bNewScenario
)
570 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
) && pTab
[nSrcTab
] && pTab
[nDestTab
])
572 // Flags fuer aktive Szenarios richtig setzen
573 // und aktuelle Werte in bisher aktive Szenarios zurueckschreiben
575 ScRangeList aRanges
= *pTab
[nSrcTab
]->GetScenarioRanges();
576 const ULONG nRangeCount
= aRanges
.Count();
578 // nDestTab ist die Zieltabelle
579 for ( SCTAB nTab
= nDestTab
+1;
580 nTab
<=MAXTAB
&& pTab
[nTab
] && pTab
[nTab
]->IsScenario();
583 if ( pTab
[nTab
]->IsActiveScenario() ) // auch wenn's dasselbe Szenario ist
585 BOOL bTouched
= FALSE
;
586 for ( ULONG nR
=0; nR
<nRangeCount
&& !bTouched
; nR
++)
588 const ScRange
* pRange
= aRanges
.GetObject(nR
);
589 if ( pTab
[nTab
]->HasScenarioRange( *pRange
) )
594 pTab
[nTab
]->SetActiveScenario(FALSE
);
595 if ( pTab
[nTab
]->GetScenarioFlags() & SC_SCENARIO_TWOWAY
)
596 pTab
[nTab
]->CopyScenarioFrom( pTab
[nDestTab
] );
601 pTab
[nSrcTab
]->SetActiveScenario(TRUE
); // da kommt's her...
602 if (!bNewScenario
) // Daten aus dem ausgewaehlten Szenario kopieren
604 BOOL bOldAutoCalc
= GetAutoCalc();
605 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
606 pTab
[nSrcTab
]->CopyScenarioTo( pTab
[nDestTab
] );
608 SetAutoCalc( bOldAutoCalc
);
613 void ScDocument::MarkScenario( SCTAB nSrcTab
, SCTAB nDestTab
, ScMarkData
& rDestMark
,
614 BOOL bResetMark
, USHORT nNeededBits
) const
617 rDestMark
.ResetMark();
619 if (ValidTab(nSrcTab
) && pTab
[nSrcTab
])
620 pTab
[nSrcTab
]->MarkScenarioIn( rDestMark
, nNeededBits
);
622 rDestMark
.SetAreaTab( nDestTab
);
625 BOOL
ScDocument::HasScenarioRange( SCTAB nTab
, const ScRange
& rRange
) const
627 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasScenarioRange( rRange
);
628 //if (ValidTab(nTab) && pTab[nTab])
629 // return pTab[nTab]->HasScenarioRange( rRange );
634 const ScRangeList
* ScDocument::GetScenarioRanges( SCTAB nTab
) const
636 if (ValidTab(nTab
) && pTab
[nTab
])
637 return pTab
[nTab
]->GetScenarioRanges();
642 BOOL
ScDocument::IsActiveScenario( SCTAB nTab
) const
644 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->IsActiveScenario( );
645 //if (ValidTab(nTab) && pTab[nTab])
646 // return pTab[nTab]->IsActiveScenario();
651 void ScDocument::SetActiveScenario( SCTAB nTab
, BOOL bActive
)
653 if (ValidTab(nTab
) && pTab
[nTab
])
654 pTab
[nTab
]->SetActiveScenario( bActive
);
657 BOOL
ScDocument::TestCopyScenario( SCTAB nSrcTab
, SCTAB nDestTab
) const
659 if (ValidTab(nSrcTab
) && ValidTab(nDestTab
))
660 return pTab
[nSrcTab
]->TestCopyScenarioTo( pTab
[nDestTab
] );
662 DBG_ERROR("falsche Tabelle bei TestCopyScenario");
666 void ScDocument::AddUnoObject( SfxListener
& rObject
)
668 if (!pUnoBroadcaster
)
669 pUnoBroadcaster
= new SfxBroadcaster
;
671 rObject
.StartListening( *pUnoBroadcaster
);
674 void ScDocument::RemoveUnoObject( SfxListener
& rObject
)
678 rObject
.EndListening( *pUnoBroadcaster
);
680 if ( bInUnoBroadcast
)
682 // #107294# Broadcasts from ScDocument::BroadcastUno are the only way that
683 // uno object methods are called without holding a reference.
685 // If RemoveUnoObject is called from an object dtor in the finalizer thread
686 // while the main thread is calling BroadcastUno, the dtor thread must wait
687 // (or the object's Notify might try to access a deleted object).
688 // The SolarMutex can't be locked here because if a component is called from
689 // a VCL event, the main thread has the SolarMutex locked all the time.
691 // This check is done after calling EndListening, so a later BroadcastUno call
692 // won't touch this object.
694 vos::IMutex
& rSolarMutex
= Application::GetSolarMutex();
695 if ( rSolarMutex
.tryToAcquire() )
697 // BroadcastUno is always called with the SolarMutex locked, so if it
698 // can be acquired, this is within the same thread (should not happen)
699 DBG_ERRORFILE( "RemoveUnoObject called from BroadcastUno" );
700 rSolarMutex
.release();
704 // let the thread that called BroadcastUno continue
705 while ( bInUnoBroadcast
)
707 vos::OThread::yield();
714 DBG_ERROR("No Uno broadcaster");
718 void ScDocument::BroadcastUno( const SfxHint
&rHint
)
722 bInUnoBroadcast
= TRUE
;
723 pUnoBroadcaster
->Broadcast( rHint
);
724 bInUnoBroadcast
= FALSE
;
726 // During Broadcast notification, Uno objects can add to pUnoListenerCalls.
727 // The listener calls must be processed after completing the broadcast,
728 // because they can add or remove objects from pUnoBroadcaster.
730 if ( pUnoListenerCalls
&& rHint
.ISA( SfxSimpleHint
) &&
731 ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DATACHANGED
&&
732 !bInUnoListenerCall
)
734 // Listener calls may lead to BroadcastUno calls again. The listener calls
735 // are not nested, instead the calls are collected in the list, and the
736 // outermost call executes them all.
738 ScChartLockGuard
aChartLockGuard(this);
739 bInUnoListenerCall
= TRUE
;
740 pUnoListenerCalls
->ExecuteAndClear();
741 bInUnoListenerCall
= FALSE
;
746 void ScDocument::AddUnoListenerCall( const uno::Reference
<util::XModifyListener
>& rListener
,
747 const lang::EventObject
& rEvent
)
749 DBG_ASSERT( bInUnoBroadcast
, "AddUnoListenerCall is supposed to be called from BroadcastUno only" );
751 if ( !pUnoListenerCalls
)
752 pUnoListenerCalls
= new ScUnoListenerCalls
;
753 pUnoListenerCalls
->Add( rListener
, rEvent
);
756 void ScDocument::BeginUnoRefUndo()
758 DBG_ASSERT( !pUnoRefUndoList
, "BeginUnoRefUndo twice" );
759 delete pUnoRefUndoList
;
761 pUnoRefUndoList
= new ScUnoRefList
;
764 ScUnoRefList
* ScDocument::EndUnoRefUndo()
766 ScUnoRefList
* pRet
= pUnoRefUndoList
;
767 pUnoRefUndoList
= NULL
;
768 return pRet
; // must be deleted by caller!
771 void ScDocument::AddUnoRefChange( sal_Int64 nId
, const ScRangeList
& rOldRanges
)
773 if ( pUnoRefUndoList
)
774 pUnoRefUndoList
->Add( nId
, rOldRanges
);
777 sal_Int64
ScDocument::GetNewUnoId()
779 return ++nUnoObjectId
;
782 void ScDocument::UpdateReference( UpdateRefMode eUpdateRefMode
,
783 SCCOL nCol1
, SCROW nRow1
, SCTAB nTab1
,
784 SCCOL nCol2
, SCROW nRow2
, SCTAB nTab2
,
785 SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
,
786 ScDocument
* pUndoDoc
, BOOL bIncludeDraw
)
788 PutInOrder( nCol1
, nCol2
);
789 PutInOrder( nRow1
, nRow2
);
790 PutInOrder( nTab1
, nTab2
);
791 if (VALIDTAB(nTab1
) && VALIDTAB(nTab2
))
793 BOOL bExpandRefsOld
= IsExpandRefs();
794 if ( eUpdateRefMode
== URM_INSDEL
&& (nDx
> 0 || nDy
> 0 || nDz
> 0) )
795 SetExpandRefs( SC_MOD()->GetInputOptions().GetExpandRefs() );
798 if ( eUpdateRefMode
== URM_COPY
)
805 ScRange
aRange( nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
);
806 xColNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
807 xRowNameRanges
->UpdateReference( eUpdateRefMode
, this, aRange
, nDx
, nDy
, nDz
);
808 pDBCollection
->UpdateReference( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
809 pRangeName
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
811 pDPCollection
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
812 UpdateChartRef( eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
, nDx
, nDy
, nDz
);
813 UpdateRefAreaLinks( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
815 pCondFormList
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
816 if ( pValidationList
)
817 pValidationList
->UpdateReference( eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
819 pDetOpList
->UpdateReference( this, eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
);
820 if ( pUnoBroadcaster
)
821 pUnoBroadcaster
->Broadcast( ScUpdateRefHint(
822 eUpdateRefMode
, aRange
, nDx
, nDy
, nDz
) );
826 for ( ; i
<=iMax
; i
++)
828 pTab
[i
]->UpdateReference(
829 eUpdateRefMode
, nCol1
, nRow1
, nTab1
, nCol2
, nRow2
, nTab2
,
830 nDx
, nDy
, nDz
, pUndoDoc
, bIncludeDraw
);
840 theCol1
= aEmbedRange
.aStart
.Col();
841 theRow1
= aEmbedRange
.aStart
.Row();
842 theTab1
= aEmbedRange
.aStart
.Tab();
843 theCol2
= aEmbedRange
.aEnd
.Col();
844 theRow2
= aEmbedRange
.aEnd
.Row();
845 theTab2
= aEmbedRange
.aEnd
.Tab();
846 if ( ScRefUpdate::Update( this, eUpdateRefMode
, nCol1
,nRow1
,nTab1
, nCol2
,nRow2
,nTab2
,
847 nDx
,nDy
,nDz
, theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
) )
849 aEmbedRange
= ScRange( theCol1
,theRow1
,theTab1
, theCol2
,theRow2
,theTab2
);
852 SetExpandRefs( bExpandRefsOld
);
854 // #30428# after moving, no clipboard move ref-updates are possible
855 if ( eUpdateRefMode
!= URM_COPY
&& IsClipboardSource() )
857 ScDocument
* pClipDoc
= SC_MOD()->GetClipDoc();
859 pClipDoc
->GetClipParam().mbCutMode
= false;
864 void ScDocument::UpdateTranspose( const ScAddress
& rDestPos
, ScDocument
* pClipDoc
,
865 const ScMarkData
& rMark
, ScDocument
* pUndoDoc
)
867 DBG_ASSERT(pClipDoc
->bIsClip
, "UpdateTranspose: kein Clip");
870 ScClipParam
& rClipParam
= GetClipParam();
871 if (rClipParam
.maRanges
.Count())
872 aSource
= *rClipParam
.maRanges
.First();
873 ScAddress aDest
= rDestPos
;
876 for (SCTAB nDestTab
=0; nDestTab
<=MAXTAB
&& pTab
[nDestTab
]; nDestTab
++)
877 if (rMark
.GetTableSelect(nDestTab
))
879 while (!pClipDoc
->pTab
[nClipTab
]) nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
880 aSource
.aStart
.SetTab( nClipTab
);
881 aSource
.aEnd
.SetTab( nClipTab
);
882 aDest
.SetTab( nDestTab
);
884 // wie UpdateReference
886 pRangeName
->UpdateTranspose( aSource
, aDest
); // vor den Zellen!
887 for (SCTAB i
=0; i
<=MAXTAB
; i
++)
889 pTab
[i
]->UpdateTranspose( aSource
, aDest
, pUndoDoc
);
891 nClipTab
= (nClipTab
+1) % (MAXTAB
+1);
895 void ScDocument::UpdateGrow( const ScRange
& rArea
, SCCOL nGrowX
, SCROW nGrowY
)
901 pRangeName
->UpdateGrow( rArea
, nGrowX
, nGrowY
);
903 for (SCTAB i
=0; i
<=MAXTAB
&& pTab
[i
]; i
++)
904 pTab
[i
]->UpdateGrow( rArea
, nGrowX
, nGrowY
);
907 void ScDocument::Fill(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, const ScMarkData
& rMark
,
908 ULONG nFillCount
, FillDir eFillDir
, FillCmd eFillCmd
, FillDateCmd eFillDateCmd
,
909 double nStepValue
, double nMaxValue
)
911 PutInOrder( nCol1
, nCol2
);
912 PutInOrder( nRow1
, nRow2
);
913 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
915 if (rMark
.GetTableSelect(i
))
916 pTab
[i
]->Fill(nCol1
, nRow1
, nCol2
, nRow2
,
917 nFillCount
, eFillDir
, eFillCmd
, eFillDateCmd
,
918 nStepValue
, nMaxValue
);
921 String
ScDocument::GetAutoFillPreview( const ScRange
& rSource
, SCCOL nEndX
, SCROW nEndY
)
923 SCTAB nTab
= rSource
.aStart
.Tab();
925 return pTab
[nTab
]->GetAutoFillPreview( rSource
, nEndX
, nEndY
);
930 void ScDocument::AutoFormat( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
931 USHORT nFormatNo
, const ScMarkData
& rMark
)
933 PutInOrder( nStartCol
, nEndCol
);
934 PutInOrder( nStartRow
, nEndRow
);
935 for (SCTAB i
=0; i
<= MAXTAB
; i
++)
937 if (rMark
.GetTableSelect(i
))
938 pTab
[i
]->AutoFormat( nStartCol
, nStartRow
, nEndCol
, nEndRow
, nFormatNo
);
941 void ScDocument::GetAutoFormatData(SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
942 ScAutoFormatData
& rData
)
948 PutInOrder(nStartCol
, nEndCol
);
949 PutInOrder(nStartRow
, nEndRow
);
950 pTab
[nTab
]->GetAutoFormatData(nStartCol
, nStartRow
, nEndCol
, nEndRow
, rData
);
956 void ScDocument::GetSearchAndReplaceStart( const SvxSearchItem
& rSearchItem
,
957 SCCOL
& rCol
, SCROW
& rRow
)
959 USHORT nCommand
= rSearchItem
.GetCommand();
960 BOOL bReplace
= ( nCommand
== SVX_SEARCHCMD_REPLACE
||
961 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
);
962 if ( rSearchItem
.GetBackward() )
964 if ( rSearchItem
.GetRowDirection() )
966 if ( rSearchItem
.GetPattern() )
984 if ( rSearchItem
.GetPattern() )
1003 if ( rSearchItem
.GetRowDirection() )
1005 if ( rSearchItem
.GetPattern() )
1010 else if ( bReplace
)
1023 if ( rSearchItem
.GetPattern() )
1028 else if ( bReplace
)
1042 BOOL
ScDocument::SearchAndReplace(const SvxSearchItem
& rSearchItem
,
1043 SCCOL
& rCol
, SCROW
& rRow
, SCTAB
& rTab
,
1045 String
& rUndoStr
, ScDocument
* pUndoDoc
)
1047 //! getrennte Markierungen pro Tabelle verwalten !!!!!!!!!!!!!
1049 rMark
.MarkToMulti();
1051 BOOL bFound
= FALSE
;
1057 USHORT nCommand
= rSearchItem
.GetCommand();
1058 if ( nCommand
== SVX_SEARCHCMD_FIND_ALL
||
1059 nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
1061 for (nTab
= 0; nTab
<= MAXTAB
; nTab
++)
1064 if (rMark
.GetTableSelect(nTab
))
1068 bFound
|= pTab
[nTab
]->SearchAndReplace(
1069 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1073 // Markierung wird innen schon komplett gesetzt
1079 if (rSearchItem
.GetBackward())
1081 for (nTab
= rTab
; ((SCsTAB
)nTab
>= 0) && !bFound
; nTab
--)
1084 if (rMark
.GetTableSelect(nTab
))
1086 bFound
= pTab
[nTab
]->SearchAndReplace(
1087 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1095 ScDocument::GetSearchAndReplaceStart(
1096 rSearchItem
, nCol
, nRow
);
1102 for (nTab
= rTab
; (nTab
<= MAXTAB
) && !bFound
; nTab
++)
1105 if (rMark
.GetTableSelect(nTab
))
1107 bFound
= pTab
[nTab
]->SearchAndReplace(
1108 rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
1116 ScDocument::GetSearchAndReplaceStart(
1117 rSearchItem
, nCol
, nRow
);
1128 BOOL
ScDocument::UpdateOutlineCol( SCCOL nStartCol
, SCCOL nEndCol
, SCTAB nTab
, BOOL bShow
)
1130 if ( ValidTab(nTab
) && pTab
[nTab
] )
1131 return pTab
[nTab
]->UpdateOutlineCol( nStartCol
, nEndCol
, bShow
);
1133 DBG_ERROR("missing tab");
1137 BOOL
ScDocument::UpdateOutlineRow( SCROW nStartRow
, SCROW nEndRow
, SCTAB nTab
, BOOL bShow
)
1139 if ( ValidTab(nTab
) && pTab
[nTab
] )
1140 return pTab
[nTab
]->UpdateOutlineRow( nStartRow
, nEndRow
, bShow
);
1142 DBG_ERROR("missing tab");
1146 void ScDocument::Sort(SCTAB nTab
, const ScSortParam
& rSortParam
, BOOL bKeepQuery
)
1148 if ( ValidTab(nTab
) && pTab
[nTab
] )
1150 BOOL bOldDisableIdle
= IsIdleDisabled();
1151 DisableIdle( TRUE
);
1152 pTab
[nTab
]->Sort(rSortParam
, bKeepQuery
);
1153 DisableIdle( bOldDisableIdle
);
1157 SCSIZE
ScDocument::Query(SCTAB nTab
, const ScQueryParam
& rQueryParam
, BOOL bKeepSub
)
1159 if ( ValidTab(nTab
) && pTab
[nTab
] )
1160 return pTab
[nTab
]->Query((ScQueryParam
&)rQueryParam
, bKeepSub
);
1162 DBG_ERROR("missing tab");
1167 BOOL
ScDocument::ValidQuery( SCROW nRow
, SCTAB nTab
, const ScQueryParam
& rQueryParam
, BOOL
* pSpecial
)
1169 if ( ValidTab(nTab
) && pTab
[nTab
] )
1170 return pTab
[nTab
]->ValidQuery( nRow
, rQueryParam
, pSpecial
);
1172 DBG_ERROR("missing tab");
1177 void ScDocument::GetUpperCellString(SCCOL nCol
, SCROW nRow
, SCTAB nTab
, String
& rStr
)
1179 if ( ValidTab(nTab
) && pTab
[nTab
] )
1180 pTab
[nTab
]->GetUpperCellString( nCol
, nRow
, rStr
);
1185 BOOL
ScDocument::CreateQueryParam(SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
, SCTAB nTab
, ScQueryParam
& rQueryParam
)
1187 if ( ValidTab(nTab
) && pTab
[nTab
] )
1188 return pTab
[nTab
]->CreateQueryParam(nCol1
, nRow1
, nCol2
, nRow2
, rQueryParam
);
1190 DBG_ERROR("missing tab");
1194 BOOL
ScDocument::HasAutoFilter( SCCOL nCurCol
, SCROW nCurRow
, SCTAB nCurTab
)
1196 ScDBData
* pDBData
= GetDBAtCursor( nCurCol
, nCurRow
, nCurTab
);
1197 BOOL bHasAutoFilter
= ( pDBData
!= NULL
);
1201 if ( pDBData
->HasHeader() )
1207 ScQueryParam aParam
;
1208 pDBData
->GetQueryParam( aParam
);
1209 nRow
= aParam
.nRow1
;
1211 for ( nCol
=aParam
.nCol1
; nCol
<=aParam
.nCol2
&& bHasAutoFilter
; nCol
++ )
1213 nFlag
= ((ScMergeFlagAttr
*)
1214 GetAttr( nCol
, nRow
, nCurTab
, ATTR_MERGE_FLAG
))->
1217 if ( (nFlag
& SC_MF_AUTO
) == 0 )
1218 bHasAutoFilter
= FALSE
;
1222 bHasAutoFilter
= FALSE
;
1225 return bHasAutoFilter
;
1228 BOOL
ScDocument::HasColHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1231 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasColHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1232 //if (VALIDTAB(nTab))
1234 // return pTab[nTab]->HasColHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1239 BOOL
ScDocument::HasRowHeader( SCCOL nStartCol
, SCROW nStartRow
, SCCOL nEndCol
, SCROW nEndRow
,
1242 return VALIDTAB(nTab
) && pTab
[nTab
] && pTab
[nTab
]->HasRowHeader( nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1243 //if (VALIDTAB(nTab))
1245 // return pTab[nTab]->HasRowHeader( nStartCol, nStartRow, nEndCol, nEndRow );
1250 void ScDocument::UpdateDynamicEndRow(ScDBData
& rDBData
) const
1255 rDBData
.GetArea(nTab
, nCol1
, nRow1
, nCol2
, nRow2
);
1256 SCCOL nCol1a
= nCol1
, nCol2a
= nCol2
;
1257 SCROW nRow1a
= nRow1
, nRow2a
= nRow2
;
1258 GetDataArea(nTab
, nCol1a
, nRow1a
, nCol2a
, nRow2a
, false);
1259 rDBData
.SetDynamicEndRow(nRow2a
);
1263 // GetFilterEntries - Eintraege fuer AutoFilter-Listbox
1266 BOOL
ScDocument::GetFilterEntries(
1267 SCCOL nCol
, SCROW nRow
, SCTAB nTab
, bool bFilter
, TypedScStrCollection
& rStrings
, bool& rHasDates
)
1269 if ( ValidTab(nTab
) && pTab
[nTab
] && pDBCollection
)
1271 ScDBData
* pDBData
= pDBCollection
->GetDBAtCursor(nCol
, nRow
, nTab
, FALSE
); //!??
1274 UpdateDynamicEndRow(*pDBData
);
1280 pDBData
->GetArea( nAreaTab
, nStartCol
, nStartRow
, nEndCol
, nEndRow
);
1281 if (pDBData
->HasHeader())
1284 ScQueryParam aParam
;
1285 pDBData
->GetQueryParam( aParam
);
1286 nEndRow
= aParam
.nDynamicEndRow
;
1287 rStrings
.SetCaseSensitive( aParam
.bCaseSens
);
1289 // return all filter entries, if a filter condition is connected with a boolean OR
1292 SCSIZE nEntryCount
= aParam
.GetEntryCount();
1293 for ( SCSIZE i
= 0; i
< nEntryCount
&& aParam
.GetEntry(i
).bDoQuery
; ++i
)
1295 ScQueryEntry
& rEntry
= aParam
.GetEntry(i
);
1296 if ( rEntry
.eConnect
!= SC_AND
)
1306 pTab
[nTab
]->GetFilteredFilterEntries( nCol
, nStartRow
, nEndRow
, aParam
, rStrings
, rHasDates
);
1310 pTab
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1321 // GetFilterEntriesArea - Eintraege fuer Filter-Dialog
1324 BOOL
ScDocument::GetFilterEntriesArea( SCCOL nCol
, SCROW nStartRow
, SCROW nEndRow
,
1325 SCTAB nTab
, TypedScStrCollection
& rStrings
, bool& rHasDates
)
1327 if ( ValidTab(nTab
) && pTab
[nTab
] )
1329 pTab
[nTab
]->GetFilterEntries( nCol
, nStartRow
, nEndRow
, rStrings
, rHasDates
);
1337 // GetDataEntries - Eintraege fuer Auswahlliste-Listbox (keine Zahlen / Formeln)
1340 BOOL
ScDocument::GetDataEntries( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
1341 TypedScStrCollection
& rStrings
, BOOL bLimit
)
1345 /* Try to generate the list from list validation. This part is skipped,
1346 if bLimit==TRUE, because in that case this function is called to get
1347 cell values for auto completion on input. */
1348 sal_uInt32 nValidation
= static_cast< const SfxUInt32Item
* >( GetAttr( nCol
, nRow
, nTab
, ATTR_VALIDDATA
) )->GetValue();
1351 const ScValidationData
* pData
= GetValidationEntry( nValidation
);
1352 if( pData
&& pData
->FillSelectionList( rStrings
, ScAddress( nCol
, nRow
, nTab
) ) )
1357 return ValidTab(nTab
) && pTab
[nTab
] && pTab
[nTab
]->GetDataEntries( nCol
, nRow
, rStrings
, bLimit
);
1358 //if (ValidTab(nTab) && pTab[nTab])
1359 // return pTab[nTab]->GetDataEntries( nCol, nRow, rStrings, bLimit );
1365 // GetFormulaEntries - Eintraege fuer Formel-AutoEingabe
1368 // Funktionen werden als 1 schon vom InputHandler eingefuegt
1369 #define SC_STRTYPE_NAMES 2
1370 #define SC_STRTYPE_DBNAMES 3
1371 #define SC_STRTYPE_HEADERS 4
1373 BOOL
ScDocument::GetFormulaEntries( TypedScStrCollection
& rStrings
)
1383 USHORT nRangeCount
= pRangeName
->GetCount();
1384 for ( i
=0; i
<nRangeCount
; i
++ )
1386 ScRangeData
* pData
= (*pRangeName
)[i
];
1389 TypedStrData
* pNew
= new TypedStrData( pData
->GetName(), 0.0, SC_STRTYPE_NAMES
);
1390 if ( !rStrings
.Insert(pNew
) )
1397 // Datenbank-Bereiche
1400 if ( pDBCollection
)
1402 USHORT nDBCount
= pDBCollection
->GetCount();
1403 for ( i
=0; i
<nDBCount
; i
++ )
1405 ScDBData
* pData
= (*pDBCollection
)[i
];
1408 TypedStrData
* pNew
= new TypedStrData( pData
->GetName(), 0.0, SC_STRTYPE_DBNAMES
);
1409 if ( !rStrings
.Insert(pNew
) )
1416 // Inhalte von Beschriftungsbereichen
1419 ScRangePairList
* pLists
[2];
1420 pLists
[0] = GetColNameRanges();
1421 pLists
[1] = GetRowNameRanges();
1422 for (USHORT nListNo
=0; nListNo
<2; nListNo
++)
1424 ScRangePairList
* pList
= pLists
[nListNo
];
1426 for ( ScRangePair
* pPair
= pList
->First(); pPair
; pPair
= pList
->Next() )
1428 ScRange aRange
= pPair
->GetRange(0);
1429 ScCellIterator
aIter( this, aRange
);
1430 for ( ScBaseCell
* pCell
= aIter
.GetFirst(); pCell
; pCell
= aIter
.GetNext() )
1431 if ( pCell
->HasStringData() )
1433 String aStr
= pCell
->GetStringData();
1434 TypedStrData
* pNew
= new TypedStrData( aStr
, 0.0, SC_STRTYPE_HEADERS
);
1435 if ( !rStrings
.Insert(pNew
) )
1445 BOOL
ScDocument::IsEmbedded() const
1450 void ScDocument::GetEmbedded( ScRange
& rRange
) const
1452 rRange
= aEmbedRange
;
1455 Rectangle
ScDocument::GetEmbeddedRect() const // 1/100 mm
1458 ScTable
* pTable
= pTab
[aEmbedRange
.aStart
.Tab()];
1461 DBG_ERROR("GetEmbeddedRect ohne Tabelle");
1467 for (i
=0; i
<aEmbedRange
.aStart
.Col(); i
++)
1468 aRect
.Left() += pTable
->GetColWidth(i
);
1469 aRect
.Top() += pTable
->GetRowHeight( 0, aEmbedRange
.aStart
.Row() - 1);
1470 aRect
.Right() = aRect
.Left();
1471 for (i
=aEmbedRange
.aStart
.Col(); i
<=aEmbedRange
.aEnd
.Col(); i
++)
1472 aRect
.Right() += pTable
->GetColWidth(i
);
1473 aRect
.Bottom() = aRect
.Top();
1474 aRect
.Bottom() += pTable
->GetRowHeight( aEmbedRange
.aStart
.Row(), aEmbedRange
.aEnd
.Row());
1476 aRect
.Left() = (long) ( aRect
.Left() * HMM_PER_TWIPS
);
1477 aRect
.Right() = (long) ( aRect
.Right() * HMM_PER_TWIPS
);
1478 aRect
.Top() = (long) ( aRect
.Top() * HMM_PER_TWIPS
);
1479 aRect
.Bottom() = (long) ( aRect
.Bottom() * HMM_PER_TWIPS
);
1484 void ScDocument::SetEmbedded( const ScRange
& rRange
)
1487 aEmbedRange
= rRange
;
1490 void ScDocument::ResetEmbedded()
1492 bIsEmbedded
= FALSE
;
1493 aEmbedRange
= ScRange();
1496 ScRange
ScDocument::GetRange( SCTAB nTab
, const Rectangle
& rMMRect
)
1498 ScTable
* pTable
= pTab
[nTab
];
1501 DBG_ERROR("GetRange ohne Tabelle");
1505 Rectangle aPosRect
= rMMRect
;
1506 if ( IsNegativePage( nTab
) )
1507 ScDrawLayer::MirrorRectRTL( aPosRect
); // always with positive (LTR) values
1515 nTwips
= (long) (aPosRect
.Left() / HMM_PER_TWIPS
);
1521 nAdd
= (long) pTable
->GetColWidth(nX1
);
1522 if (nSize
+nAdd
<= nTwips
+1 && nX1
<MAXCOL
)
1531 nTwips
= (long) (aPosRect
.Right() / HMM_PER_TWIPS
);
1537 nAdd
= (long) pTable
->GetColWidth(nX2
);
1538 if (nSize
+nAdd
< nTwips
&& nX2
<MAXCOL
)
1549 nTwips
= (long) (aPosRect
.Top() / HMM_PER_TWIPS
);
1553 for (SCROW i
= nY1
; i
<= MAXROW
&& !bEnd
; ++i
)
1555 if (pTable
->RowHidden(i
))
1559 nAdd
= static_cast<long>(pTable
->GetRowHeight(i
));
1560 if (nSize
+nAdd
<= nTwips
+1 && nY1
<MAXROW
)
1569 nY1
= MAXROW
; // all hidden down to the bottom
1571 nTwips
= (long) (aPosRect
.Bottom() / HMM_PER_TWIPS
);
1575 for (SCROW i
= nY2
; i
<= MAXROW
&& !bEnd
; ++i
)
1578 nAdd
= static_cast<long>(pTable
->GetRowHeight(i
));
1579 if (nSize
+nAdd
< nTwips
&& nY2
<MAXROW
)
1588 nY2
= MAXROW
; // all hidden down to the bottom
1590 return ScRange( nX1
,nY1
,nTab
, nX2
,nY2
,nTab
);
1593 void ScDocument::SetEmbedded( const Rectangle
& rRect
) // aus VisArea (1/100 mm)
1596 aEmbedRange
= GetRange( nVisibleTab
, rRect
);
1599 // VisArea auf Zellgrenzen anpassen
1601 void lcl_SnapHor( ScTable
* pTable
, long& rVal
, SCCOL
& rStartCol
)
1604 long nTwips
= (long) (rVal
/ HMM_PER_TWIPS
);
1606 while ( nCol
<MAXCOL
)
1608 long nAdd
= pTable
->GetColWidth(nCol
);
1609 if ( nSnap
+ nAdd
/2 < nTwips
|| nCol
< rStartCol
)
1617 rVal
= (long) ( nSnap
* HMM_PER_TWIPS
);
1621 void lcl_SnapVer( ScTable
* pTable
, long& rVal
, SCROW
& rStartRow
)
1624 long nTwips
= (long) (rVal
/ HMM_PER_TWIPS
);
1627 bool bFound
= false;
1628 for (SCROW i
= nRow
; i
<= MAXROW
; ++i
)
1631 if (pTable
->RowHidden(i
, NULL
, &nLastRow
))
1638 long nAdd
= pTable
->GetRowHeight(i
);
1639 if ( nSnap
+ nAdd
/2 < nTwips
|| nRow
< rStartRow
)
1651 nRow
= MAXROW
; // all hidden down to the bottom
1653 rVal
= (long) ( nSnap
* HMM_PER_TWIPS
);
1657 void ScDocument::SnapVisArea( Rectangle
& rRect
) const
1659 ScTable
* pTable
= pTab
[nVisibleTab
];
1662 DBG_ERROR("SetEmbedded ohne Tabelle");
1666 BOOL bNegativePage
= IsNegativePage( nVisibleTab
);
1667 if ( bNegativePage
)
1668 ScDrawLayer::MirrorRectRTL( rRect
); // calculate with positive (LTR) values
1671 lcl_SnapHor( pTable
, rRect
.Left(), nCol
);
1672 ++nCol
; // mindestens eine Spalte
1673 lcl_SnapHor( pTable
, rRect
.Right(), nCol
);
1676 lcl_SnapVer( pTable
, rRect
.Top(), nRow
);
1677 ++nRow
; // mindestens eine Zeile
1678 lcl_SnapVer( pTable
, rRect
.Bottom(), nRow
);
1680 if ( bNegativePage
)
1681 ScDrawLayer::MirrorRectRTL( rRect
); // back to real rectangle
1684 ScDocProtection
* ScDocument::GetDocProtection() const
1686 return pDocProtection
.get();
1689 void ScDocument::SetDocProtection(const ScDocProtection
* pProtect
)
1692 pDocProtection
.reset(new ScDocProtection(*pProtect
));
1694 pDocProtection
.reset(NULL
);
1697 BOOL
ScDocument::IsDocProtected() const
1699 return pDocProtection
.get() && pDocProtection
->isProtected();
1702 BOOL
ScDocument::IsDocEditable() const
1704 // import into read-only document is possible
1705 return !IsDocProtected() && ( bImportingXML
|| mbChangeReadOnlyEnabled
|| !pShell
|| !pShell
->IsReadOnly() );
1708 BOOL
ScDocument::IsTabProtected( SCTAB nTab
) const
1710 if (VALIDTAB(nTab
) && pTab
[nTab
])
1711 return pTab
[nTab
]->IsProtected();
1713 DBG_ERROR("Falsche Tabellennummer");
1717 ScTableProtection
* ScDocument::GetTabProtection( SCTAB nTab
) const
1719 if (VALIDTAB(nTab
) && pTab
[nTab
])
1720 return pTab
[nTab
]->GetProtection();
1725 void ScDocument::SetTabProtection(SCTAB nTab
, const ScTableProtection
* pProtect
)
1727 if (!ValidTab(nTab
))
1730 pTab
[nTab
]->SetProtection(pProtect
);
1733 void ScDocument::CopyTabProtection(SCTAB nTabSrc
, SCTAB nTabDest
)
1735 if (!ValidTab(nTabSrc
) || !ValidTab(nTabDest
))
1738 pTab
[nTabDest
]->SetProtection( pTab
[nTabSrc
]->GetProtection() );
1741 const ScDocOptions
& ScDocument::GetDocOptions() const
1743 DBG_ASSERT( pDocOptions
, "No DocOptions! :-(" );
1744 return *pDocOptions
;
1747 void ScDocument::SetDocOptions( const ScDocOptions
& rOpt
)
1751 DBG_ASSERT( pDocOptions
, "No DocOptions! :-(" );
1752 *pDocOptions
= rOpt
;
1753 rOpt
.GetDate( d
,m
,y
);
1755 xPoolHelper
->SetFormTableOpt(rOpt
);
1757 SetGrammar( rOpt
.GetFormulaSyntax() );
1759 // Update the separators.
1760 ScCompiler::UpdateSeparatorsNative(
1761 rOpt
.GetFormulaSepArg(), rOpt
.GetFormulaSepArrayCol(), rOpt
.GetFormulaSepArrayRow());
1764 const ScViewOptions
& ScDocument::GetViewOptions() const
1766 DBG_ASSERT( pViewOptions
, "No ViewOptions! :-(" );
1767 return *pViewOptions
;
1770 void ScDocument::SetViewOptions( const ScViewOptions
& rOpt
)
1772 DBG_ASSERT( pViewOptions
, "No ViewOptions! :-(" );
1773 *pViewOptions
= rOpt
;
1776 void ScDocument::GetLanguage( LanguageType
& rLatin
, LanguageType
& rCjk
, LanguageType
& rCtl
) const
1779 rCjk
= eCjkLanguage
;
1780 rCtl
= eCtlLanguage
;
1783 void ScDocument::SetLanguage( LanguageType eLatin
, LanguageType eCjk
, LanguageType eCtl
)
1786 eCjkLanguage
= eCjk
;
1787 eCtlLanguage
= eCtl
;
1788 if ( xPoolHelper
.isValid() )
1790 ScDocumentPool
* pPool
= xPoolHelper
->GetDocPool();
1791 pPool
->SetPoolDefaultItem( SvxLanguageItem( eLanguage
, ATTR_FONT_LANGUAGE
) );
1792 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCjkLanguage
, ATTR_CJK_FONT_LANGUAGE
) );
1793 pPool
->SetPoolDefaultItem( SvxLanguageItem( eCtlLanguage
, ATTR_CTL_FONT_LANGUAGE
) );
1796 UpdateDrawLanguages(); // set edit engine defaults in drawing layer pool
1799 void ScDocument::SetDrawDefaults()
1801 bSetDrawDefaults
= TRUE
;
1802 UpdateDrawDefaults();
1805 Rectangle
ScDocument::GetMMRect( SCCOL nStartCol
, SCROW nStartRow
,
1806 SCCOL nEndCol
, SCROW nEndRow
, SCTAB nTab
)
1808 if (!ValidTab(nTab
) || !pTab
[nTab
])
1810 DBG_ERROR("GetMMRect: falsche Tabelle");
1811 return Rectangle(0,0,0,0);
1817 for (i
=0; i
<nStartCol
; i
++)
1818 aRect
.Left() += GetColWidth(i
,nTab
);
1819 aRect
.Top() += FastGetRowHeight( 0, nStartRow
-1, nTab
);
1821 aRect
.Right() = aRect
.Left();
1822 aRect
.Bottom() = aRect
.Top();
1824 for (i
=nStartCol
; i
<=nEndCol
; i
++)
1825 aRect
.Right() += GetColWidth(i
,nTab
);
1826 aRect
.Bottom() += FastGetRowHeight( nStartRow
, nEndRow
, nTab
);
1828 aRect
.Left() = (long)(aRect
.Left() * HMM_PER_TWIPS
);
1829 aRect
.Right() = (long)(aRect
.Right() * HMM_PER_TWIPS
);
1830 aRect
.Top() = (long)(aRect
.Top() * HMM_PER_TWIPS
);
1831 aRect
.Bottom() = (long)(aRect
.Bottom() * HMM_PER_TWIPS
);
1833 if ( IsNegativePage( nTab
) )
1834 ScDrawLayer::MirrorRectRTL( aRect
);
1839 void ScDocument::SetExtDocOptions( ScExtDocOptions
* pNewOptions
)
1841 delete pExtDocOptions
;
1842 pExtDocOptions
= pNewOptions
;
1845 void ScDocument::DoMergeContents( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1846 SCCOL nEndCol
, SCROW nEndRow
)
1853 for (nRow
=nStartRow
; nRow
<=nEndRow
; nRow
++)
1854 for (nCol
=nStartCol
; nCol
<=nEndCol
; nCol
++)
1856 GetString(nCol
,nRow
,nTab
,aCellStr
);
1863 if (nCol
!= nStartCol
|| nRow
!= nStartRow
)
1864 SetString(nCol
,nRow
,nTab
,aEmpty
);
1867 SetString(nStartCol
,nStartRow
,nTab
,aTotal
);
1870 void ScDocument::DoMerge( SCTAB nTab
, SCCOL nStartCol
, SCROW nStartRow
,
1871 SCCOL nEndCol
, SCROW nEndRow
, bool bDeleteCaptions
)
1873 ScMergeAttr
aAttr( nEndCol
-nStartCol
+1, nEndRow
-nStartRow
+1 );
1874 ApplyAttr( nStartCol
, nStartRow
, nTab
, aAttr
);
1876 if ( nEndCol
> nStartCol
)
1877 ApplyFlagsTab( nStartCol
+1, nStartRow
, nEndCol
, nStartRow
, nTab
, SC_MF_HOR
);
1878 if ( nEndRow
> nStartRow
)
1879 ApplyFlagsTab( nStartCol
, nStartRow
+1, nStartCol
, nEndRow
, nTab
, SC_MF_VER
);
1880 if ( nEndCol
> nStartCol
&& nEndRow
> nStartRow
)
1881 ApplyFlagsTab( nStartCol
+1, nStartRow
+1, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1883 // remove all covered notes (removed captions are collected by drawing undo if active)
1884 USHORT nDelFlag
= IDF_NOTE
| (bDeleteCaptions
? 0 : IDF_NOCAPTIONS
);
1885 if( nStartCol
< nEndCol
)
1886 DeleteAreaTab( nStartCol
+ 1, nStartRow
, nEndCol
, nStartRow
, nTab
, nDelFlag
);
1887 if( nStartRow
< nEndRow
)
1888 DeleteAreaTab( nStartCol
, nStartRow
+ 1, nEndCol
, nEndRow
, nTab
, nDelFlag
);
1891 void ScDocument::RemoveMerge( SCCOL nCol
, SCROW nRow
, SCTAB nTab
)
1893 const ScMergeAttr
* pAttr
= (const ScMergeAttr
*)
1894 GetAttr( nCol
, nRow
, nTab
, ATTR_MERGE
);
1896 if ( pAttr
->GetColMerge() <= 1 && pAttr
->GetRowMerge() <= 1 )
1899 SCCOL nEndCol
= nCol
+ pAttr
->GetColMerge() - 1;
1900 SCROW nEndRow
= nRow
+ pAttr
->GetRowMerge() - 1;
1902 RemoveFlagsTab( nCol
, nRow
, nEndCol
, nEndRow
, nTab
, SC_MF_HOR
| SC_MF_VER
);
1904 const ScMergeAttr
* pDefAttr
= (const ScMergeAttr
*)
1905 &xPoolHelper
->GetDocPool()->GetDefaultItem( ATTR_MERGE
);
1906 ApplyAttr( nCol
, nRow
, nTab
, *pDefAttr
);
1909 void ScDocument::ExtendPrintArea( OutputDevice
* pDev
, SCTAB nTab
,
1910 SCCOL nStartCol
, SCROW nStartRow
, SCCOL
& rEndCol
, SCROW nEndRow
)
1912 if ( ValidTab(nTab
) && pTab
[nTab
] )
1913 pTab
[nTab
]->ExtendPrintArea( pDev
, nStartCol
, nStartRow
, rEndCol
, nEndRow
);
1916 void ScDocument::IncSizeRecalcLevel( SCTAB nTab
)
1918 if ( ValidTab(nTab
) && pTab
[nTab
] )
1919 pTab
[nTab
]->IncRecalcLevel();
1922 void ScDocument::DecSizeRecalcLevel( SCTAB nTab
)
1924 if ( ValidTab(nTab
) && pTab
[nTab
] )
1925 pTab
[nTab
]->DecRecalcLevel();