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: documen2.cxx,v $
10 * $Revision: 1.75.18.1 $
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 #define _ZFORLIST_DECLARE_TABLE
37 #include "scitems.hxx"
38 #include <svx/eeitem.hxx>
40 #include <svx/editeng.hxx>
41 #include <svx/forbiddencharacterstable.hxx>
42 #include <svx/linkmgr.hxx>
43 #include <svx/svdpool.hxx>
44 #include <svx/svdobj.hxx>
45 #include <sfx2/bindings.hxx>
46 #include <sfx2/objsh.hxx>
47 #include <sfx2/printer.hxx>
48 #include <svtools/zforlist.hxx>
49 #include <svtools/zformat.hxx>
50 #include <vcl/virdev.hxx>
51 #include <comphelper/processfactory.hxx>
52 #include <svtools/PasswordHelper.hxx>
53 #include <tools/tenccvt.hxx>
54 #include <tools/list.hxx>
57 #include "document.hxx"
60 #include "patattr.hxx"
61 #include "rangenam.hxx"
62 #include "dbcolect.hxx"
64 #include "docpool.hxx"
65 #include "stlpool.hxx"
66 #include "stlsheet.hxx"
67 #include "globstr.hrc"
68 #include "chartarr.hxx"
69 #include "chartlock.hxx"
70 #include "rechead.hxx"
73 #include "bcaslot.hxx"
74 #include "adiasync.hxx"
75 #include "addinlis.hxx"
76 #include "chartlis.hxx"
77 #include "markdata.hxx"
78 #include "conditio.hxx"
79 #include "validat.hxx"
80 #include "progress.hxx"
81 #include "detdata.hxx"
82 #include "sc.hrc" // FID_DATACHANGED
83 #include "ddelink.hxx"
84 #include "chgtrack.hxx"
85 #include "chgviset.hxx"
86 #include "editutil.hxx"
88 #include "dpobject.hxx"
89 #include "scrdata.hxx"
90 #include "poolhelp.hxx"
91 #include "unoreflist.hxx"
92 #include "listenercalls.hxx"
93 #include "recursionhelper.hxx"
94 #include "lookupcache.hxx"
95 #include "externalrefmgr.hxx"
96 #include "tabprotection.hxx"
97 #include "formulaparserpool.hxx"
98 #include "clipparam.hxx"
99 #include "macromgr.hxx"
100 #include <com/sun/star/document/XVbaEventsHelper.hpp>
102 // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and
103 // dtor plus helpers are convenient.
104 struct ScLookupCacheMapImpl
106 ScLookupCacheMap aCacheMap
;
107 ~ScLookupCacheMapImpl()
115 ScLookupCacheMap aTmp
;
116 aCacheMap
.swap( aTmp
);
121 for (ScLookupCacheMap::iterator
it( aCacheMap
.begin()); it
!= aCacheMap
.end(); ++it
)
126 // STATIC DATA -----------------------------------------------------------
128 ScDocument::ScDocument( ScDocumentMode eMode
,
129 SfxObjectShell
* pDocShell
) :
130 xServiceManager( ::comphelper::getProcessServiceFactory() ),
131 mpUndoManager( NULL
),
134 pNoteItemPool( NULL
),
137 pVirtualDevice_100th_mm( NULL
),
140 pCondFormList( NULL
),
141 pValidationList( NULL
),
142 pFormatExchangeList( NULL
),
143 pDPCollection( NULL
),
144 pLinkManager( NULL
),
145 pFormulaTree( NULL
),
146 pEOFormulaTree( NULL
),
147 pFormulaTrack( NULL
),
148 pEOFormulaTrack( NULL
),
149 pOtherObjects( NULL
),
152 pChangeTrack( NULL
),
153 pUnoBroadcaster( NULL
),
154 pUnoListenerCalls( NULL
),
155 pUnoRefUndoList( NULL
),
156 pChangeViewSettings( NULL
),
157 pScriptTypeData( NULL
),
158 pCacheFieldEditEngine( NULL
),
159 pDocProtection( NULL
),
162 pExternalRefMgr( NULL
),
163 pViewOptions( NULL
),
165 pExtDocOptions( NULL
),
166 pConsolidateDlgData( NULL
),
167 pRecursionHelper( NULL
),
168 pAutoNameCache( NULL
),
169 pLookupCacheMapImpl( NULL
),
171 nRangeOverflowType( 0 ),
172 aCurTextWidthCalcPos(MAXCOL
,0,0),
173 nFormulaCodeInTree(0),
174 nXMLImportedFormulaCount( 0 ),
176 nMacroInterpretLevel(0),
177 nInterpreterTableOpLevel(0),
178 nMaxTableNumber( 0 ),
179 nSrcVer( SC_CURRENT_VERSION
),
180 nSrcMaxRow( MAXROW
),
181 nFormulaTrackCount(0),
184 eLinkMode(LM_UNKNOWN
),
185 bAutoCalc( eMode
== SCDOCMODE_DOCUMENT
),
186 bAutoCalcShellDisabled( FALSE
),
187 bForcedFormulaPending( FALSE
),
188 bCalculatingFormulaTree( FALSE
),
189 bIsClip( eMode
== SCDOCMODE_CLIP
),
190 bIsUndo( eMode
== SCDOCMODE_UNDO
),
192 bIsEmbedded( FALSE
),
193 // bNoSetDirty( TRUE ),
194 bNoSetDirty( FALSE
),
195 bInsertingFromOtherDoc( FALSE
),
196 bLoadingMedium(false),
197 bImportingXML( FALSE
),
198 bXMLFromWrapper( FALSE
),
199 bCalcingAfterLoad( FALSE
),
200 bNoListening( FALSE
),
201 bLoadingDone( TRUE
),
202 bIdleDisabled( FALSE
),
203 bInLinkUpdate( FALSE
),
204 bChartListenerCollectionNeedsUpdate( FALSE
),
205 bHasForcedFormulas( FALSE
),
206 bInDtorClear( FALSE
),
207 bExpandRefs( FALSE
),
208 bDetectiveDirty( FALSE
),
209 nMacroCallMode( SC_MACROCALL_ALLOWED
),
210 bHasMacroFunc( FALSE
),
212 nAsianCompression(SC_ASIANCOMPRESSION_INVALID
),
213 nAsianKerning(SC_ASIANKERNING_INVALID
),
214 bSetDrawDefaults( FALSE
),
215 bPastingDrawFromOtherDoc( FALSE
),
216 nInDdeLinkUpdate( 0 ),
217 bInUnoBroadcast( FALSE
),
218 bInUnoListenerCall( FALSE
),
219 eGrammar( formula::FormulaGrammar::GRAM_NATIVE
),
220 bStyleSheetUsageInvalid( TRUE
),
221 mbUndoEnabled( true ),
222 mbAdjustHeightEnabled( true ),
223 mbExecuteLinkEnabled( true ),
224 mbChangeReadOnlyEnabled( false ),
225 mbStreamValidLocked( false ),
226 mnNamedRangesLockCount( 0 )
228 SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT
);
230 eSrcSet
= gsl_getSystemTextEncoding();
232 if ( eMode
== SCDOCMODE_DOCUMENT
)
235 pLinkManager
= new SvxLinkManager( pDocShell
);
237 xPoolHelper
= new ScPoolHelper( this );
240 pBASM
= new ScBroadcastAreaSlotMachine( this );
241 pChartListenerCollection
= new ScChartListenerCollection( this );
242 pRefreshTimerControl
= new ScRefreshTimerControl
;
248 pChartListenerCollection
= NULL
;
249 pRefreshTimerControl
= NULL
;
252 for (SCTAB i
=1; i
<=MAXTAB
; i
++)
255 pRangeName
= new ScRangeName( 4, 4, FALSE
, this );
256 pDBCollection
= new ScDBCollection( 4, 4, FALSE
, this );
257 pSelectionAttr
= NULL
;
258 pChartCollection
= new ScChartCollection
;
259 apTemporaryChartLock
= std::auto_ptr
< ScTemporaryChartLock
>( new ScTemporaryChartLock(this) );
260 xColNameRanges
= new ScRangePairList
;
261 xRowNameRanges
= new ScRangePairList
;
263 // languages for a visible document are set by docshell later (from options)
264 SetLanguage( ScGlobal::eLnge
, ScGlobal::eLnge
, ScGlobal::eLnge
);
266 aTrackTimer
.SetTimeoutHdl( LINK( this, ScDocument
, TrackTimeHdl
) );
267 aTrackTimer
.SetTimeout( 100 );
270 SvxLinkManager
* ScDocument::GetLinkManager() const
272 if ( bAutoCalc
&& !pLinkManager
&& pShell
)
274 pLinkManager
= new SvxLinkManager( pShell
);
280 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram
)
283 eGram
== formula::FormulaGrammar::GRAM_ODFF
||
284 eGram
== formula::FormulaGrammar::GRAM_PODF
,
285 "ScDocument::SetStorageGrammar: wrong storage grammar");
287 eStorageGrammar
= eGram
;
289 // FIXME: the XML import shouldn't strip brackets, the compiler should
290 // digest them instead, which could also speedup reference recognition
293 eXmlImportGrammar
= formula::FormulaGrammar::mergeToGrammar( eGram
,
294 formula::FormulaGrammar::CONV_OOO
);
298 void ScDocument::SetDocVisible( BOOL bSet
)
300 // called from view ctor - only for a visible document,
301 // each new sheet's RTL flag is initialized from the locale
306 sal_uInt32
ScDocument::GetDocumentID() const
308 const ScDocument
* pThis
= this;
309 sal_uInt32 nCrc
= rtl_crc32( 0, &pThis
, sizeof(ScDocument
*) );
310 // the this pointer only might not be sufficient
311 nCrc
= rtl_crc32( nCrc
, &pShell
, sizeof(SfxObjectShell
*) );
316 void ScDocument::StartChangeTracking()
319 pChangeTrack
= new ScChangeTrack( this );
322 void ScDocument::EndChangeTracking()
328 void ScDocument::SetChangeTrack( ScChangeTrack
* pTrack
)
330 DBG_ASSERT( pTrack
->GetDocument() == this, "SetChangeTrack: different documents" );
331 if ( !pTrack
|| pTrack
== pChangeTrack
|| pTrack
->GetDocument() != this )
334 pChangeTrack
= pTrack
;
338 IMPL_LINK( ScDocument
, TrackTimeHdl
, Timer
*, EMPTYARG
)
340 if ( ScDdeLink::IsInUpdate() ) // nicht verschachteln
342 aTrackTimer
.Start(); // spaeter nochmal versuchen
344 else if (pShell
) // ausfuehren
347 pShell
->Broadcast( SfxSimpleHint( FID_DATACHANGED
) );
348 ResetChanged( ScRange(0,0,0,MAXCOL
,MAXROW
,MAXTAB
) );
352 if (!pShell
->IsModified())
354 pShell
->SetModified( TRUE
);
355 SfxBindings
* pBindings
= GetViewBindings();
358 pBindings
->Invalidate( SID_SAVEDOC
);
359 pBindings
->Invalidate( SID_DOC_MODIFIED
);
367 void ScDocument::StartTrackTimer()
369 if (!aTrackTimer
.IsActive()) // nicht ewig aufschieben
373 ScDocument::~ScDocument()
375 DBG_ASSERT( !bInLinkUpdate
, "bInLinkUpdate in dtor" );
379 // first of all disable all refresh timers by deleting the control
380 if ( pRefreshTimerControl
)
381 { // To be sure there isn't anything running do it with a protector,
382 // this ensures also that nothing needs the control anymore.
383 ScRefreshTimerProtector
aProt( GetRefreshTimerControlAddress() );
384 delete pRefreshTimerControl
, pRefreshTimerControl
= NULL
;
389 if ( GetLinkManager() )
391 // BaseLinks freigeben
392 for ( USHORT n
= pLinkManager
->GetServers().Count(); n
; )
393 pLinkManager
->GetServers()[ --n
]->Closed();
395 if ( pLinkManager
->GetLinks().Count() )
396 pLinkManager
->Remove( 0, pLinkManager
->GetLinks().Count() );
399 mxFormulaParserPool
.reset();
400 // Destroy the external ref mgr instance here because it has a timer
401 // which needs to be stopped before the app closes.
402 pExternalRefMgr
.reset();
404 ScAddInAsync::RemoveDocument( this );
405 ScAddInListener::RemoveDocument( this );
406 DELETEZ( pChartListenerCollection
); // vor pBASM wg. evtl. Listener!
407 DELETEZ( pLookupCacheMapImpl
); // before pBASM because of listeners
408 // BroadcastAreas vor allen Zellen zerstoeren um unnoetige
409 // Einzel-EndListenings der Formelzellen zu vermeiden
410 delete pBASM
; // BroadcastAreaSlotMachine
415 delete pUnoBroadcaster
; // broadcasted nochmal SFX_HINT_DYING
416 pUnoBroadcaster
= NULL
;
419 delete pUnoRefUndoList
;
420 delete pUnoListenerCalls
;
422 Clear( sal_True
); // TRUE = from destructor (needed for SdrModel::ClearModel)
426 pCondFormList
->DeleteAndDestroy( 0, pCondFormList
->Count() );
427 DELETEZ(pCondFormList
);
431 pValidationList
->DeleteAndDestroy( 0, pValidationList
->Count() );
432 DELETEZ(pValidationList
);
435 delete pDBCollection
;
436 delete pSelectionAttr
;
437 apTemporaryChartLock
.reset();
438 delete pChartCollection
;
440 delete pFormatExchangeList
;
443 delete pConsolidateDlgData
;
446 delete pDetOpList
; // loescht auch die Eintraege
450 SfxItemPool::Free(pNoteItemPool
);
451 delete pChangeViewSettings
; // und weg damit
452 delete pVirtualDevice_100th_mm
;
454 delete pDPCollection
;
456 // delete the EditEngine before destroying the xPoolHelper
457 delete pCacheFieldEditEngine
;
459 if ( xPoolHelper
.isValid() && !bIsClip
)
460 xPoolHelper
->SourceDocumentGone();
461 xPoolHelper
.unbind();
464 delete pScriptTypeData
;
465 delete pOtherObjects
;
466 delete pRecursionHelper
;
468 DBG_ASSERT( !pAutoNameCache
, "AutoNameCache still set in dtor" );
471 void ScDocument::InitClipPtrs( ScDocument
* pSourceDoc
)
473 DBG_ASSERT(bIsClip
, "InitClipPtrs und nicht bIsClip");
477 pCondFormList
->DeleteAndDestroy( 0, pCondFormList
->Count() );
478 DELETEZ(pCondFormList
);
482 pValidationList
->DeleteAndDestroy( 0, pValidationList
->Count() );
483 DELETEZ(pValidationList
);
488 xPoolHelper
= pSourceDoc
->xPoolHelper
;
490 // bedingte Formate / Gueltigkeiten
491 //! Vorlagen kopieren?
492 const ScConditionalFormatList
* pSourceCond
= pSourceDoc
->pCondFormList
;
494 pCondFormList
= new ScConditionalFormatList(this, *pSourceCond
);
495 const ScValidationDataList
* pSourceValid
= pSourceDoc
->pValidationList
;
497 pValidationList
= new ScValidationDataList(this, *pSourceValid
);
499 // Links in Stream speichern
501 if (pSourceDoc
->HasDdeLinks())
503 pClipData
= new SvMemoryStream
;
504 pSourceDoc
->SaveDdeLinks(*pClipData
);
509 // Options pointers exist (ImplCreateOptions) for any document.
510 // Must be copied for correct results in OLE objects (#i42666#).
511 SetDocOptions( pSourceDoc
->GetDocOptions() );
512 SetViewOptions( pSourceDoc
->GetViewOptions() );
515 SvNumberFormatter
* ScDocument::GetFormatTable() const
517 return xPoolHelper
->GetFormTable();
520 SfxItemPool
* ScDocument::GetEditPool() const
522 return xPoolHelper
->GetEditPool();
525 SfxItemPool
* ScDocument::GetEnginePool() const
527 return xPoolHelper
->GetEnginePool();
530 ScFieldEditEngine
& ScDocument::GetEditEngine()
534 pEditEngine
= new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
535 pEditEngine
->SetUpdateMode( FALSE
);
536 pEditEngine
->EnableUndo( FALSE
);
537 pEditEngine
->SetRefMapMode( MAP_100TH_MM
);
538 pEditEngine
->SetForbiddenCharsTable( xForbiddenCharacters
);
543 ScNoteEditEngine
& ScDocument::GetNoteEngine()
547 pNoteEngine
= new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
548 pNoteEngine
->SetUpdateMode( FALSE
);
549 pNoteEngine
->EnableUndo( FALSE
);
550 pNoteEngine
->SetRefMapMode( MAP_100TH_MM
);
551 pNoteEngine
->SetForbiddenCharsTable( xForbiddenCharacters
);
552 const SfxItemSet
& rItemSet
= GetDefPattern()->GetItemSet();
553 SfxItemSet
* pEEItemSet
= new SfxItemSet( pNoteEngine
->GetEmptyItemSet() );
554 ScPatternAttr::FillToEditItemSet( *pEEItemSet
, rItemSet
);
555 pNoteEngine
->SetDefaults( pEEItemSet
); // edit engine takes ownership
560 //UNUSED2009-05 SfxItemPool& ScDocument::GetNoteItemPool()
562 //UNUSED2009-05 if ( !pNoteItemPool )
563 //UNUSED2009-05 pNoteItemPool = new SfxItemPool(SdrObject::GetGlobalDrawObjectItemPool());
564 //UNUSED2009-05 return *pNoteItemPool;
567 void ScDocument::ResetClip( ScDocument
* pSourceDoc
, const ScMarkData
* pMarks
)
571 InitClipPtrs(pSourceDoc
);
573 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
574 if (pSourceDoc
->pTab
[i
])
575 if (!pMarks
|| pMarks
->GetTableSelect(i
))
578 pSourceDoc
->pTab
[i
]->GetName(aString
);
579 pTab
[i
] = new ScTable(this, i
, aString
);
580 pTab
[i
]->SetLayoutRTL( pSourceDoc
->pTab
[i
]->IsLayoutRTL() );
581 nMaxTableNumber
= i
+1;
586 DBG_ERROR("ResetClip");
590 void ScDocument::ResetClip( ScDocument
* pSourceDoc
, SCTAB nTab
)
594 InitClipPtrs(pSourceDoc
);
596 pTab
[nTab
] = new ScTable(this, nTab
,
597 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
598 if (pSourceDoc
->pTab
[nTab
])
599 pTab
[nTab
]->SetLayoutRTL( pSourceDoc
->pTab
[nTab
]->IsLayoutRTL() );
600 nMaxTableNumber
= nTab
+1;
604 DBG_ERROR("ResetClip");
608 void ScDocument::DeleteNumberFormat( const sal_uInt32
* /* pDelKeys */, sal_uInt32
/* nCount */ )
611 for (ULONG i = 0; i < nCount; i++)
612 xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
616 void ScDocument::PutCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
617 ScBaseCell
* pCell
, ULONG nFormatIndex
, BOOL bForceTab
)
621 if ( bForceTab
&& !pTab
[nTab
] )
623 BOOL bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
625 pTab
[nTab
] = new ScTable(this, nTab
,
626 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
631 pTab
[nTab
]->PutCell( nCol
, nRow
, nFormatIndex
, pCell
);
635 //UNUSED2009-05 void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell,
636 //UNUSED2009-05 ULONG nFormatIndex, BOOL bForceTab )
638 //UNUSED2009-05 SCTAB nTab = rPos.Tab();
639 //UNUSED2009-05 if ( bForceTab && !pTab[nTab] )
641 //UNUSED2009-05 BOOL bExtras = !bIsUndo; // Spaltenbreiten, Zeilenhoehen, Flags
643 //UNUSED2009-05 pTab[nTab] = new ScTable(this, nTab,
644 //UNUSED2009-05 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
645 //UNUSED2009-05 bExtras, bExtras);
648 //UNUSED2009-05 if (pTab[nTab])
649 //UNUSED2009-05 pTab[nTab]->PutCell( rPos, nFormatIndex, pCell );
652 BOOL
ScDocument::GetPrintArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
,
655 if (ValidTab(nTab
) && pTab
[nTab
])
657 BOOL bAny
= pTab
[nTab
]->GetPrintArea( rEndCol
, rEndRow
, bNotes
);
660 ScRange
aDrawRange(0,0,nTab
, MAXCOL
,MAXROW
,nTab
);
661 if (DrawGetPrintArea( aDrawRange
, TRUE
, TRUE
))
663 if (aDrawRange
.aEnd
.Col()>rEndCol
) rEndCol
=aDrawRange
.aEnd
.Col();
664 if (aDrawRange
.aEnd
.Row()>rEndRow
) rEndRow
=aDrawRange
.aEnd
.Row();
676 BOOL
ScDocument::GetPrintAreaHor( SCTAB nTab
, SCROW nStartRow
, SCROW nEndRow
,
677 SCCOL
& rEndCol
, BOOL bNotes
) const
679 if (ValidTab(nTab
) && pTab
[nTab
])
681 BOOL bAny
= pTab
[nTab
]->GetPrintAreaHor( nStartRow
, nEndRow
, rEndCol
, bNotes
);
684 ScRange
aDrawRange(0,nStartRow
,nTab
, MAXCOL
,nEndRow
,nTab
);
685 if (DrawGetPrintArea( aDrawRange
, TRUE
, FALSE
))
687 if (aDrawRange
.aEnd
.Col()>rEndCol
) rEndCol
=aDrawRange
.aEnd
.Col();
698 BOOL
ScDocument::GetPrintAreaVer( SCTAB nTab
, SCCOL nStartCol
, SCCOL nEndCol
,
699 SCROW
& rEndRow
, BOOL bNotes
) const
701 if (ValidTab(nTab
) && pTab
[nTab
])
703 BOOL bAny
= pTab
[nTab
]->GetPrintAreaVer( nStartCol
, nEndCol
, rEndRow
, bNotes
);
706 ScRange
aDrawRange(nStartCol
,0,nTab
, nEndCol
,MAXROW
,nTab
);
707 if (DrawGetPrintArea( aDrawRange
, FALSE
, TRUE
))
709 if (aDrawRange
.aEnd
.Row()>rEndRow
) rEndRow
=aDrawRange
.aEnd
.Row();
720 BOOL
ScDocument::GetDataStart( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
) const
722 if (ValidTab(nTab
) && pTab
[nTab
])
724 BOOL bAny
= pTab
[nTab
]->GetDataStart( rStartCol
, rStartRow
);
727 ScRange
aDrawRange(0,0,nTab
, MAXCOL
,MAXROW
,nTab
);
728 if (DrawGetPrintArea( aDrawRange
, TRUE
, TRUE
))
730 if (aDrawRange
.aStart
.Col()<rStartCol
) rStartCol
=aDrawRange
.aStart
.Col();
731 if (aDrawRange
.aStart
.Row()<rStartRow
) rStartRow
=aDrawRange
.aStart
.Row();
743 BOOL
ScDocument::MoveTab( SCTAB nOldPos
, SCTAB nNewPos
)
745 if (nOldPos
== nNewPos
) return FALSE
;
747 if (VALIDTAB(nOldPos
))
751 SCTAB nTabCount
= GetTableCount();
754 BOOL bOldAutoCalc
= GetAutoCalc();
755 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
756 SetNoListening( TRUE
);
757 ScProgress
* pProgress
= new ScProgress( GetDocumentShell(),
758 ScGlobal::GetRscString(STR_UNDO_MOVE_TAB
), GetCodeCount() );
759 if (nNewPos
== SC_TAB_APPEND
)
760 nNewPos
= nTabCount
-1;
762 // Referenz-Updaterei
763 //! mit UpdateReference zusammenfassen!
765 SCsTAB nDz
= ((SCsTAB
)nNewPos
) - (SCsTAB
)nOldPos
;
766 ScRange
aSourceRange( 0,0,nOldPos
, MAXCOL
,MAXROW
,nOldPos
);
767 pRangeName
->UpdateTabRef(nOldPos
, 3, nNewPos
);
768 pDBCollection
->UpdateMoveTab( nOldPos
, nNewPos
);
769 xColNameRanges
->UpdateReference( URM_REORDER
, this, aSourceRange
, 0,0,nDz
);
770 xRowNameRanges
->UpdateReference( URM_REORDER
, this, aSourceRange
, 0,0,nDz
);
772 pDPCollection
->UpdateReference( URM_REORDER
, aSourceRange
, 0,0,nDz
);
774 pDetOpList
->UpdateReference( this, URM_REORDER
, aSourceRange
, 0,0,nDz
);
775 UpdateChartRef( URM_REORDER
,
776 0,0,nOldPos
, MAXCOL
,MAXROW
,nOldPos
, 0,0,nDz
);
777 UpdateRefAreaLinks( URM_REORDER
, aSourceRange
, 0,0,nDz
);
779 pCondFormList
->UpdateMoveTab( nOldPos
, nNewPos
);
780 if ( pValidationList
)
781 pValidationList
->UpdateMoveTab( nOldPos
, nNewPos
);
782 if ( pUnoBroadcaster
)
783 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_REORDER
,
784 aSourceRange
, 0,0,nDz
) );
786 ScTable
* pSaveTab
= pTab
[nOldPos
];
788 for (i
= nOldPos
+ 1; i
< nTabCount
; i
++)
789 pTab
[i
- 1] = pTab
[i
];
791 for (i
= nTabCount
- 1; i
> nNewPos
; i
--)
792 pTab
[i
] = pTab
[i
- 1];
793 pTab
[nNewPos
] = pSaveTab
;
794 for (i
= 0; i
<= MAXTAB
; i
++)
796 pTab
[i
]->UpdateMoveTab( nOldPos
, nNewPos
, i
, *pProgress
);
797 delete pProgress
; // freimachen fuer evtl. andere
798 for (i
= 0; i
<= MAXTAB
; i
++)
800 pTab
[i
]->UpdateCompile();
801 SetNoListening( FALSE
);
802 for (i
= 0; i
<= MAXTAB
; i
++)
804 pTab
[i
]->StartAllListeners();
805 // #81844# sheet names of references may not be valid until sheet is moved
806 pChartListenerCollection
->UpdateScheduledSeriesRanges();
808 SetAutoCalc( bOldAutoCalc
);
811 DrawMovePage( static_cast<sal_uInt16
>(nOldPos
), static_cast<sal_uInt16
>(nNewPos
) );
813 // Update cells containing external references.
814 if (pExternalRefMgr
.get())
815 pExternalRefMgr
->updateRefMoveTable(nOldPos
, nNewPos
, false);
824 BOOL
ScDocument::CopyTab( SCTAB nOldPos
, SCTAB nNewPos
, const ScMarkData
* pOnlyMarked
)
826 if (SC_TAB_APPEND
== nNewPos
) nNewPos
= nMaxTableNumber
;
828 GetName(nOldPos
, aName
);
830 // vorneweg testen, ob der Prefix als gueltig erkannt wird
831 // wenn nicht, nur doppelte vermeiden
832 BOOL bPrefix
= ValidTabName( aName
);
833 DBG_ASSERT(bPrefix
, "ungueltiger Tabellenname");
836 CreateValidTabName(aName
);
840 bValid
= ( ValidNewTabName(aName
) && (nMaxTableNumber
<= MAXTAB
) );
842 bValid
= ( !GetTable( aName
, nDummy
) && (nMaxTableNumber
<= MAXTAB
) );
844 BOOL bOldAutoCalc
= GetAutoCalc();
845 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
848 if (nNewPos
== nMaxTableNumber
)
850 pTab
[nMaxTableNumber
] = new ScTable(this, nMaxTableNumber
, aName
);
855 if (VALIDTAB(nNewPos
) && (nNewPos
< nMaxTableNumber
))
857 SetNoListening( TRUE
);
859 ScRange
aRange( 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
);
860 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
861 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
862 pRangeName
->UpdateTabRef(nNewPos
, 1);
863 pDBCollection
->UpdateReference(
864 URM_INSDEL
, 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
866 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
868 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,1 );
869 UpdateChartRef( URM_INSDEL
, 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
870 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,1 );
871 if ( pUnoBroadcaster
)
872 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,1 ) );
875 for (i
= 0; i
<= MAXTAB
; i
++)
876 if (pTab
[i
] && i
!= nOldPos
)
877 pTab
[i
]->UpdateInsertTab(nNewPos
);
878 for (i
= nMaxTableNumber
; i
> nNewPos
; i
--)
879 pTab
[i
] = pTab
[i
- 1];
880 if (nNewPos
<= nOldPos
)
882 pTab
[nNewPos
] = new ScTable(this, nNewPos
, aName
);
885 for (i
= 0; i
<= MAXTAB
; i
++)
886 if (pTab
[i
] && i
!= nOldPos
&& i
!= nNewPos
)
887 pTab
[i
]->UpdateCompile();
888 SetNoListening( FALSE
);
889 for (i
= 0; i
<= MAXTAB
; i
++)
890 if (pTab
[i
] && i
!= nOldPos
&& i
!= nNewPos
)
891 pTab
[i
]->StartAllListeners();
893 // update conditional formats after table is inserted
895 pCondFormList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
896 if ( pValidationList
)
897 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
898 // #81844# sheet names of references may not be valid until sheet is copied
899 pChartListenerCollection
->UpdateScheduledSeriesRanges();
907 SetNoListening( TRUE
); // noch nicht bei CopyToTable/Insert
908 pTab
[nOldPos
]->CopyToTable(0, 0, MAXCOL
, MAXROW
, IDF_ALL
, (pOnlyMarked
!= NULL
),
909 pTab
[nNewPos
], pOnlyMarked
);
911 /* if (nNewPos < nOldPos)
912 nDz = ((short)nNewPos) - (short)nOldPos + 1;
914 */ nDz
= ((short)nNewPos
) - (short)nOldPos
;
915 pTab
[nNewPos
]->UpdateReference(URM_COPY
, 0, 0, nNewPos
, MAXCOL
, MAXROW
,
916 nNewPos
, 0, 0, nDz
, NULL
);
918 pTab
[nNewPos
]->UpdateInsertTabAbs(nNewPos
); // alle abs. um eins hoch!!
919 pTab
[nOldPos
]->UpdateInsertTab(nNewPos
);
921 pTab
[nOldPos
]->UpdateCompile();
922 pTab
[nNewPos
]->UpdateCompile( TRUE
); // #67996# maybe already compiled in Clone, but used names need recompilation
923 SetNoListening( FALSE
);
924 pTab
[nOldPos
]->StartAllListeners();
925 pTab
[nNewPos
]->StartAllListeners();
927 SetAutoCalc( bOldAutoCalc
);
930 DrawCopyPage( static_cast<sal_uInt16
>(nOldPos
), static_cast<sal_uInt16
>(nNewPos
) );
932 pTab
[nNewPos
]->SetPageStyle( pTab
[nOldPos
]->GetPageStyle() );
933 pTab
[nNewPos
]->SetPendingRowHeights( pTab
[nOldPos
]->IsPendingRowHeights() );
935 // Update cells containing external references.
936 if (pExternalRefMgr
.get())
937 pExternalRefMgr
->updateRefMoveTable(nOldPos
, nNewPos
, true);
940 SetAutoCalc( bOldAutoCalc
);
944 ULONG
ScDocument::TransferTab( ScDocument
* pSrcDoc
, SCTAB nSrcPos
,
945 SCTAB nDestPos
, BOOL bInsertNew
,
948 ULONG nRetVal
= 1; // 0 => Fehler 1 = ok
949 // 2 => RefBox, 3 => NameBox
952 if (bInsertNew
) // neu einfuegen
955 pSrcDoc
->GetName(nSrcPos
, aName
);
956 CreateValidTabName(aName
);
957 bValid
= InsertTab(nDestPos
, aName
);
959 else // bestehende Tabelle ersetzen
961 if (VALIDTAB(nDestPos
) && pTab
[nDestPos
])
963 pTab
[nDestPos
]->DeleteArea( 0,0, MAXCOL
,MAXROW
, IDF_ALL
);
971 BOOL bOldAutoCalcSrc
= FALSE
;
972 BOOL bOldAutoCalc
= GetAutoCalc();
973 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
974 SetNoListening( TRUE
);
977 bOldAutoCalcSrc
= pSrcDoc
->GetAutoCalc();
978 pSrcDoc
->SetAutoCalc( TRUE
); // falls was berechnet werden muss
982 NumFmtMergeHandler
aNumFmtMergeHdl(this, pSrcDoc
);
984 nDestPos
= Min(nDestPos
, (SCTAB
)(GetTableCount() - 1));
985 { // scope for bulk broadcast
986 ScBulkBroadcast
aBulkBroadcast( pBASM
);
987 pSrcDoc
->pTab
[nSrcPos
]->CopyToTable(0, 0, MAXCOL
, MAXROW
,
988 ( bResultsOnly
? IDF_ALL
& ~IDF_FORMULA
: IDF_ALL
),
989 FALSE
, pTab
[nDestPos
] );
992 pTab
[nDestPos
]->SetTabNo(nDestPos
);
996 BOOL bNamesLost
= FALSE
;
997 USHORT nSrcRangeNames
= pSrcDoc
->pRangeName
->GetCount();
998 // array containing range names which might need update of indices
999 ScRangeData
** pSrcRangeNames
= nSrcRangeNames
? new ScRangeData
* [nSrcRangeNames
] : NULL
;
1000 // the index mapping thereof
1001 ScRangeData::IndexMap aSrcRangeMap
;
1002 BOOL bRangeNameReplace
= FALSE
;
1004 // find named ranges that are used in the source sheet
1005 std::set
<USHORT
> aUsedNames
;
1006 pSrcDoc
->pTab
[nSrcPos
]->FindRangeNamesInUse( 0, 0, MAXCOL
, MAXROW
, aUsedNames
);
1008 for (USHORT i
= 0; i
< nSrcRangeNames
; i
++) //! DB-Bereiche Pivot-Bereiche auch !!!
1010 ScRangeData
* pSrcData
= (*pSrcDoc
->pRangeName
)[i
];
1011 USHORT nOldIndex
= pSrcData
->GetIndex();
1012 bool bInUse
= ( aUsedNames
.find(nOldIndex
) != aUsedNames
.end() );
1015 USHORT nExisting
= 0;
1016 if ( pRangeName
->SearchName( pSrcData
->GetName(), nExisting
) )
1018 // the name exists already in the destination document
1019 // -> use the existing name, but show a warning
1020 // (when refreshing links, the existing name is used and the warning not shown)
1022 ScRangeData
* pExistingData
= (*pRangeName
)[nExisting
];
1023 USHORT nExistingIndex
= pExistingData
->GetIndex();
1025 pSrcRangeNames
[i
] = NULL
; // don't modify the named range
1026 aSrcRangeMap
.insert(
1027 ScRangeData::IndexMap::value_type(nOldIndex
, nExistingIndex
));
1028 bRangeNameReplace
= TRUE
;
1033 ScRangeData
* pData
= new ScRangeData( *pSrcData
);
1034 pData
->SetDocument(this);
1035 if ( pRangeName
->FindIndex( pData
->GetIndex() ) )
1036 pData
->SetIndex(0); // need new index, done in Insert
1037 if (!pRangeName
->Insert(pData
))
1039 DBG_ERROR("can't insert name"); // shouldn't happen
1044 pData
->TransferTabRef( nSrcPos
, nDestPos
);
1045 pSrcRangeNames
[i
] = pData
;
1046 USHORT nNewIndex
= pData
->GetIndex();
1047 aSrcRangeMap
.insert(
1048 ScRangeData::IndexMap::value_type(nOldIndex
, nNewIndex
));
1049 if ( !bRangeNameReplace
)
1050 bRangeNameReplace
= ( nOldIndex
!= nNewIndex
);
1056 pSrcRangeNames
[i
] = NULL
;
1057 //aSrcRangeMap.SetPair( i, 0, 0 ); // not needed, defaulted
1060 if ( bRangeNameReplace
)
1062 // first update all inserted named formulas if they contain other
1063 // range names and used indices changed
1064 for (USHORT i
= 0; i
< nSrcRangeNames
; i
++) //! DB-Bereiche Pivot-Bereiche auch
1066 if ( pSrcRangeNames
[i
] )
1067 pSrcRangeNames
[i
]->ReplaceRangeNamesInUse( aSrcRangeMap
);
1069 // then update the formulas, they might need the just updated range names
1070 pTab
[nDestPos
]->ReplaceRangeNamesInUse( 0, 0, MAXCOL
, MAXROW
, aSrcRangeMap
);
1072 if ( pSrcRangeNames
)
1073 delete [] pSrcRangeNames
;
1075 SCsTAB nDz
= ((SCsTAB
)nDestPos
) - (SCsTAB
)nSrcPos
;
1076 pTab
[nDestPos
]->UpdateReference(URM_COPY
, 0, 0, nDestPos
,
1077 MAXCOL
, MAXROW
, nDestPos
,
1079 // Test for outside absolute references for info box
1080 BOOL bIsAbsRef
= pSrcDoc
->pTab
[nSrcPos
]->TestTabRefAbs(nSrcPos
);
1081 // Readjust self-contained absolute references to this sheet
1082 pTab
[nDestPos
]->TestTabRefAbs(nSrcPos
);
1086 // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
1091 // message: duplicate names
1093 pTab
[nDestPos
]->CompileAll();
1096 SetNoListening( FALSE
);
1097 if ( !bResultsOnly
)
1098 pTab
[nDestPos
]->StartAllListeners();
1099 SetDirty( ScRange( 0, 0, nDestPos
, MAXCOL
, MAXROW
, nDestPos
));
1102 pSrcDoc
->SetAutoCalc( bOldAutoCalcSrc
);
1103 SetAutoCalc( bOldAutoCalc
);
1108 TransferDrawPage( pSrcDoc
, nSrcPos
, nDestPos
);
1110 pTab
[nDestPos
]->SetPendingRowHeights( pSrcDoc
->pTab
[nSrcPos
]->IsPendingRowHeights() );
1117 // ----------------------------------------------------------------------------
1119 void ScDocument::SetError( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const USHORT nError
)
1123 pTab
[nTab
]->SetError( nCol
, nRow
, nError
);
1126 void ScDocument::EraseNonUsedSharedNames(USHORT nLevel
)
1128 for (USHORT i
= 0; i
< pRangeName
->GetCount(); i
++)
1130 ScRangeData
* pRangeData
= (*pRangeName
)[i
];
1131 if (pRangeData
&& pRangeData
->HasType(RT_SHARED
))
1134 pRangeData
->GetName(aName
);
1135 aName
.Erase(0, 6); // !!! vgl. Table4, FillFormula !!
1136 USHORT nInd
= (USHORT
) aName
.ToInt32();
1139 USHORT nIndex
= pRangeData
->GetIndex();
1140 BOOL bInUse
= FALSE
;
1141 for (SCTAB j
= 0; !bInUse
&& (j
<= MAXTAB
); j
++)
1144 bInUse
= pTab
[j
]->IsRangeNameInUse(0, 0, MAXCOL
-1, MAXROW
-1,
1148 pRangeName
->AtFree(i
);
1154 // ----------------------------------------------------------------------------
1156 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam
* pData
)
1158 delete pConsolidateDlgData
;
1161 pConsolidateDlgData
= new ScConsolidateParam( *pData
);
1163 pConsolidateDlgData
= NULL
;
1166 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings
& rNew
)
1168 if (pChangeViewSettings
==NULL
)
1169 pChangeViewSettings
= new ScChangeViewSettings
;
1171 DBG_ASSERT( pChangeViewSettings
, "Oops. No ChangeViewSettings :-( by!" );
1173 *pChangeViewSettings
=rNew
;
1176 // ----------------------------------------------------------------------------
1178 ScFieldEditEngine
* ScDocument::CreateFieldEditEngine()
1180 ScFieldEditEngine
* pNewEditEngine
= NULL
;
1181 if (!pCacheFieldEditEngine
)
1183 pNewEditEngine
= new ScFieldEditEngine( GetEnginePool(),
1184 GetEditPool(), FALSE
);
1188 if ( !bImportingXML
)
1190 // #i66209# previous use might not have restored update mode,
1191 // ensure same state as for a new EditEngine (UpdateMode = TRUE)
1192 if ( !pCacheFieldEditEngine
->GetUpdateMode() )
1193 pCacheFieldEditEngine
->SetUpdateMode(TRUE
);
1196 pNewEditEngine
= pCacheFieldEditEngine
;
1197 pCacheFieldEditEngine
= NULL
;
1199 return pNewEditEngine
;
1202 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine
*& rpEditEngine
)
1204 if (!pCacheFieldEditEngine
&& rpEditEngine
)
1206 pCacheFieldEditEngine
= rpEditEngine
;
1207 pCacheFieldEditEngine
->Clear();
1210 delete rpEditEngine
;
1211 rpEditEngine
= NULL
;
1214 // ----------------------------------------------------------------------------
1217 ScRecursionHelper
* ScDocument::CreateRecursionHelperInstance()
1219 return new ScRecursionHelper
;
1222 // ----------------------------------------------------------------------------
1224 ScLookupCache
& ScDocument::GetLookupCache( const ScRange
& rRange
)
1226 ScLookupCache
* pCache
= 0;
1227 if (!pLookupCacheMapImpl
)
1228 pLookupCacheMapImpl
= new ScLookupCacheMapImpl
;
1229 ScLookupCacheMap::iterator
it( pLookupCacheMapImpl
->aCacheMap
.find( rRange
));
1230 if (it
== pLookupCacheMapImpl
->aCacheMap
.end())
1232 pCache
= new ScLookupCache( this, rRange
);
1233 AddLookupCache( *pCache
);
1236 pCache
= (*it
).second
;
1240 void ScDocument::AddLookupCache( ScLookupCache
& rCache
)
1242 if (!pLookupCacheMapImpl
->aCacheMap
.insert( ::std::pair
< const ScRange
,
1243 ScLookupCache
*>( rCache
.getRange(), &rCache
)).second
)
1245 DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
1248 StartListeningArea( rCache
.getRange(), &rCache
);
1251 void ScDocument::RemoveLookupCache( ScLookupCache
& rCache
)
1253 ScLookupCacheMap::iterator
it( pLookupCacheMapImpl
->aCacheMap
.find(
1254 rCache
.getRange()));
1255 if (it
== pLookupCacheMapImpl
->aCacheMap
.end())
1257 DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
1261 ScLookupCache
* pCache
= (*it
).second
;
1262 pLookupCacheMapImpl
->aCacheMap
.erase( it
);
1263 EndListeningArea( pCache
->getRange(), &rCache
);
1267 using namespace com::sun::star
;
1268 uno::Reference
< document::XVbaEventsHelper
>
1269 ScDocument::GetVbaEventsHelper()
1271 if( !mxVbaEventsHelper
.is() )
1275 uno::Reference
< lang::XMultiServiceFactory
> xSF( comphelper::getProcessServiceFactory(), uno::UNO_QUERY
);
1276 uno::Reference
< frame::XModel
> xModel( pShell
? pShell
->GetModel() : NULL
, uno::UNO_QUERY
);
1277 uno::Sequence
< uno::Any
> aArgs(1);
1278 aArgs
[0] = uno::Any( xModel
);
1279 uno::Reference
< document::XVbaEventsHelper
> xVbaEventsHelper( xSF
->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.VbaEventsHelper" ) ), aArgs
), uno::UNO_QUERY
);
1280 // helper will always be created successfully.
1281 mxVbaEventsHelper
.set( xVbaEventsHelper
, uno::UNO_QUERY
);
1283 catch( uno::Exception
& e
)
1287 return mxVbaEventsHelper
;
1290 void ScDocument::ClearLookupCaches()
1292 if( pLookupCacheMapImpl
)
1293 pLookupCacheMapImpl
->clear();