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 "indexmap.hxx"
90 #include "scrdata.hxx"
91 #include "poolhelp.hxx"
92 #include "unoreflist.hxx"
93 #include "listenercalls.hxx"
94 #include "recursionhelper.hxx"
95 #include "lookupcache.hxx"
96 #include "externalrefmgr.hxx"
97 #include "tabprotection.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() ),
133 pNoteItemPool( NULL
),
136 pVirtualDevice_100th_mm( NULL
),
139 pCondFormList( NULL
),
140 pValidationList( NULL
),
141 pFormatExchangeList( NULL
),
142 pDPCollection( NULL
),
143 pLinkManager( NULL
),
144 pFormulaTree( NULL
),
145 pEOFormulaTree( NULL
),
146 pFormulaTrack( NULL
),
147 pEOFormulaTrack( NULL
),
148 pOtherObjects( NULL
),
151 pChangeTrack( NULL
),
152 pUnoBroadcaster( NULL
),
153 pUnoListenerCalls( NULL
),
154 pUnoRefUndoList( NULL
),
155 pChangeViewSettings( NULL
),
156 pScriptTypeData( NULL
),
157 pCacheFieldEditEngine( NULL
),
158 pDocProtection( NULL
),
160 pExternalRefMgr( NULL
),
162 pViewOptions( NULL
),
164 pExtDocOptions( NULL
),
165 pConsolidateDlgData( NULL
),
166 pRecursionHelper( NULL
),
167 pAutoNameCache( NULL
),
168 pLookupCacheMapImpl( NULL
),
170 nRangeOverflowType( 0 ),
171 aCurTextWidthCalcPos(MAXCOL
,0,0),
172 nFormulaCodeInTree(0),
173 nXMLImportedFormulaCount( 0 ),
175 nMacroInterpretLevel(0),
176 nInterpreterTableOpLevel(0),
177 nMaxTableNumber( 0 ),
178 nSrcVer( SC_CURRENT_VERSION
),
179 nSrcMaxRow( MAXROW
),
180 nFormulaTrackCount(0),
183 eLinkMode(LM_UNKNOWN
),
184 bAutoCalc( eMode
== SCDOCMODE_DOCUMENT
),
185 bAutoCalcShellDisabled( FALSE
),
186 bForcedFormulaPending( FALSE
),
187 bCalculatingFormulaTree( FALSE
),
188 bIsClip( eMode
== SCDOCMODE_CLIP
),
189 bIsUndo( eMode
== SCDOCMODE_UNDO
),
191 bIsEmbedded( FALSE
),
192 // bNoSetDirty( TRUE ),
193 bNoSetDirty( FALSE
),
194 bInsertingFromOtherDoc( FALSE
),
195 bLoadingMedium(false),
196 bImportingXML( FALSE
),
197 bXMLFromWrapper( FALSE
),
198 bCalcingAfterLoad( FALSE
),
199 bNoListening( FALSE
),
200 bLoadingDone( TRUE
),
201 bIdleDisabled( FALSE
),
202 bInLinkUpdate( FALSE
),
203 bChartListenerCollectionNeedsUpdate( FALSE
),
204 bHasForcedFormulas( FALSE
),
205 bInDtorClear( FALSE
),
206 bExpandRefs( FALSE
),
207 bDetectiveDirty( FALSE
),
208 nMacroCallMode( SC_MACROCALL_ALLOWED
),
209 bHasMacroFunc( FALSE
),
211 nAsianCompression(SC_ASIANCOMPRESSION_INVALID
),
212 nAsianKerning(SC_ASIANKERNING_INVALID
),
213 bSetDrawDefaults( FALSE
),
214 bPastingDrawFromOtherDoc( FALSE
),
215 nInDdeLinkUpdate( 0 ),
216 bInUnoBroadcast( FALSE
),
217 bInUnoListenerCall( FALSE
),
218 eGrammar( formula::FormulaGrammar::GRAM_NATIVE
),
219 bStyleSheetUsageInvalid( TRUE
),
220 bUndoEnabled( TRUE
),
221 mbAdjustHeightEnabled( true ),
222 mbExecuteLinkEnabled( true ),
223 mbChangeReadOnlyEnabled( false ),
224 mnNamedRangesLockCount( 0 )
226 SetStorageGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT
);
228 eSrcSet
= gsl_getSystemTextEncoding();
230 if ( eMode
== SCDOCMODE_DOCUMENT
)
233 pLinkManager
= new SvxLinkManager( pDocShell
);
235 xPoolHelper
= new ScPoolHelper( this );
238 pBASM
= new ScBroadcastAreaSlotMachine( this );
239 pChartListenerCollection
= new ScChartListenerCollection( this );
240 pRefreshTimerControl
= new ScRefreshTimerControl
;
246 pChartListenerCollection
= NULL
;
247 pRefreshTimerControl
= NULL
;
250 for (SCTAB i
=1; i
<=MAXTAB
; i
++)
253 pRangeName
= new ScRangeName( 4, 4, FALSE
, this );
254 pDBCollection
= new ScDBCollection( 4, 4, FALSE
, this );
255 #if OLD_PIVOT_IMPLEMENTATION
256 pPivotCollection
= new ScPivotCollection(4, 4, this );
258 pSelectionAttr
= NULL
;
259 pChartCollection
= new ScChartCollection
;
260 apTemporaryChartLock
= std::auto_ptr
< ScTemporaryChartLock
>( new ScTemporaryChartLock(this) );
261 xColNameRanges
= new ScRangePairList
;
262 xRowNameRanges
= new ScRangePairList
;
264 // languages for a visible document are set by docshell later (from options)
265 SetLanguage( ScGlobal::eLnge
, ScGlobal::eLnge
, ScGlobal::eLnge
);
267 aTrackTimer
.SetTimeoutHdl( LINK( this, ScDocument
, TrackTimeHdl
) );
268 aTrackTimer
.SetTimeout( 100 );
272 void ScDocument::SetStorageGrammar( formula::FormulaGrammar::Grammar eGram
)
275 eGram
== formula::FormulaGrammar::GRAM_ODFF
||
276 eGram
== formula::FormulaGrammar::GRAM_PODF
,
277 "ScDocument::SetStorageGrammar: wrong storage grammar");
279 eStorageGrammar
= eGram
;
281 // FIXME: the XML import shouldn't strip brackets, the compiler should
282 // digest them instead, which could also speedup reference recognition
285 eXmlImportGrammar
= formula::FormulaGrammar::mergeToGrammar( eGram
,
286 formula::FormulaGrammar::CONV_OOO
);
290 void ScDocument::SetDocVisible( BOOL bSet
)
292 // called from view ctor - only for a visible document,
293 // each new sheet's RTL flag is initialized from the locale
298 sal_uInt32
ScDocument::GetDocumentID() const
300 const ScDocument
* pThis
= this;
301 sal_uInt32 nCrc
= rtl_crc32( 0, &pThis
, sizeof(ScDocument
*) );
302 // the this pointer only might not be sufficient
303 nCrc
= rtl_crc32( nCrc
, &pShell
, sizeof(SfxObjectShell
*) );
308 void ScDocument::StartChangeTracking()
311 pChangeTrack
= new ScChangeTrack( this );
314 void ScDocument::EndChangeTracking()
320 void ScDocument::SetChangeTrack( ScChangeTrack
* pTrack
)
322 DBG_ASSERT( pTrack
->GetDocument() == this, "SetChangeTrack: different documents" );
323 if ( !pTrack
|| pTrack
== pChangeTrack
|| pTrack
->GetDocument() != this )
326 pChangeTrack
= pTrack
;
330 IMPL_LINK( ScDocument
, TrackTimeHdl
, Timer
*, EMPTYARG
)
332 if ( ScDdeLink::IsInUpdate() ) // nicht verschachteln
334 aTrackTimer
.Start(); // spaeter nochmal versuchen
336 else if (pShell
) // ausfuehren
339 pShell
->Broadcast( SfxSimpleHint( FID_DATACHANGED
) );
340 ResetChanged( ScRange(0,0,0,MAXCOL
,MAXROW
,MAXTAB
) );
344 if (!pShell
->IsModified())
346 pShell
->SetModified( TRUE
);
347 SfxBindings
* pBindings
= GetViewBindings();
350 pBindings
->Invalidate( SID_SAVEDOC
);
351 pBindings
->Invalidate( SID_DOC_MODIFIED
);
359 void ScDocument::StartTrackTimer()
361 if (!aTrackTimer
.IsActive()) // nicht ewig aufschieben
365 ScDocument::~ScDocument()
367 DBG_ASSERT( !bInLinkUpdate
, "bInLinkUpdate in dtor" );
371 // first of all disable all refresh timers by deleting the control
372 if ( pRefreshTimerControl
)
373 { // To be sure there isn't anything running do it with a protector,
374 // this ensures also that nothing needs the control anymore.
375 ScRefreshTimerProtector
aProt( GetRefreshTimerControlAddress() );
376 delete pRefreshTimerControl
, pRefreshTimerControl
= NULL
;
383 // BaseLinks freigeben
384 for ( USHORT n
= pLinkManager
->GetServers().Count(); n
; )
385 pLinkManager
->GetServers()[ --n
]->Closed();
387 if ( pLinkManager
->GetLinks().Count() )
388 pLinkManager
->Remove( 0, pLinkManager
->GetLinks().Count() );
391 if (pExternalRefMgr
.get())
392 // Destroy the external ref mgr instance here because it has a timer
393 // which needs to be stopped before the app closes.
394 pExternalRefMgr
.reset(NULL
);
396 ScAddInAsync::RemoveDocument( this );
397 ScAddInListener::RemoveDocument( this );
398 delete pChartListenerCollection
; // vor pBASM wg. evtl. Listener!
399 pChartListenerCollection
= NULL
;
400 DELETEZ( pLookupCacheMapImpl
); // before pBASM because of listeners
401 // BroadcastAreas vor allen Zellen zerstoeren um unnoetige
402 // Einzel-EndListenings der Formelzellen zu vermeiden
403 delete pBASM
; // BroadcastAreaSlotMachine
408 delete pUnoBroadcaster
; // broadcasted nochmal SFX_HINT_DYING
409 pUnoBroadcaster
= NULL
;
412 delete pUnoRefUndoList
;
413 delete pUnoListenerCalls
;
415 Clear( sal_True
); // TRUE = from destructor (needed for SdrModel::ClearModel)
419 pCondFormList
->DeleteAndDestroy( 0, pCondFormList
->Count() );
420 DELETEZ(pCondFormList
);
424 pValidationList
->DeleteAndDestroy( 0, pValidationList
->Count() );
425 DELETEZ(pValidationList
);
428 delete pDBCollection
;
429 #if OLD_PIVOT_IMPLEMENTATION
430 delete pPivotCollection
;
432 delete pSelectionAttr
;
433 apTemporaryChartLock
.reset();
434 delete pChartCollection
;
436 delete pFormatExchangeList
;
439 delete pConsolidateDlgData
;
442 delete pDetOpList
; // loescht auch die Eintraege
446 SfxItemPool::Free(pNoteItemPool
);
447 delete pChangeViewSettings
; // und weg damit
448 delete pVirtualDevice_100th_mm
;
450 delete pDPCollection
;
452 // delete the EditEngine before destroying the xPoolHelper
453 delete pCacheFieldEditEngine
;
455 if ( xPoolHelper
.isValid() && !bIsClip
)
456 xPoolHelper
->SourceDocumentGone();
457 xPoolHelper
.unbind();
460 delete pScriptTypeData
;
461 delete pOtherObjects
;
462 delete pRecursionHelper
;
464 DBG_ASSERT( !pAutoNameCache
, "AutoNameCache still set in dtor" );
467 void ScDocument::InitClipPtrs( ScDocument
* pSourceDoc
)
469 DBG_ASSERT(bIsClip
, "InitClipPtrs und nicht bIsClip");
473 pCondFormList
->DeleteAndDestroy( 0, pCondFormList
->Count() );
474 DELETEZ(pCondFormList
);
478 pValidationList
->DeleteAndDestroy( 0, pValidationList
->Count() );
479 DELETEZ(pValidationList
);
484 xPoolHelper
= pSourceDoc
->xPoolHelper
;
486 // bedingte Formate / Gueltigkeiten
487 //! Vorlagen kopieren?
488 const ScConditionalFormatList
* pSourceCond
= pSourceDoc
->pCondFormList
;
490 pCondFormList
= new ScConditionalFormatList(this, *pSourceCond
);
491 const ScValidationDataList
* pSourceValid
= pSourceDoc
->pValidationList
;
493 pValidationList
= new ScValidationDataList(this, *pSourceValid
);
495 // Links in Stream speichern
497 if (pSourceDoc
->HasDdeLinks())
499 pClipData
= new SvMemoryStream
;
500 pSourceDoc
->SaveDdeLinks(*pClipData
);
505 // Options pointers exist (ImplCreateOptions) for any document.
506 // Must be copied for correct results in OLE objects (#i42666#).
507 SetDocOptions( pSourceDoc
->GetDocOptions() );
508 SetViewOptions( pSourceDoc
->GetViewOptions() );
511 SvNumberFormatter
* ScDocument::GetFormatTable() const
513 return xPoolHelper
->GetFormTable();
516 SfxItemPool
* ScDocument::GetEditPool() const
518 return xPoolHelper
->GetEditPool();
521 SfxItemPool
* ScDocument::GetEnginePool() const
523 return xPoolHelper
->GetEnginePool();
526 ScFieldEditEngine
& ScDocument::GetEditEngine()
530 pEditEngine
= new ScFieldEditEngine( GetEnginePool(), GetEditPool() );
531 pEditEngine
->SetUpdateMode( FALSE
);
532 pEditEngine
->EnableUndo( FALSE
);
533 pEditEngine
->SetRefMapMode( MAP_100TH_MM
);
534 pEditEngine
->SetForbiddenCharsTable( xForbiddenCharacters
);
539 ScNoteEditEngine
& ScDocument::GetNoteEngine()
543 pNoteEngine
= new ScNoteEditEngine( GetEnginePool(), GetEditPool() );
544 pNoteEngine
->SetUpdateMode( FALSE
);
545 pNoteEngine
->EnableUndo( FALSE
);
546 pNoteEngine
->SetRefMapMode( MAP_100TH_MM
);
547 pNoteEngine
->SetForbiddenCharsTable( xForbiddenCharacters
);
548 const SfxItemSet
& rItemSet
= GetDefPattern()->GetItemSet();
549 SfxItemSet
* pEEItemSet
= new SfxItemSet( pNoteEngine
->GetEmptyItemSet() );
550 ScPatternAttr::FillToEditItemSet( *pEEItemSet
, rItemSet
);
551 pNoteEngine
->SetDefaults( pEEItemSet
); // edit engine takes ownership
556 SfxItemPool
& ScDocument::GetNoteItemPool()
558 if ( !pNoteItemPool
)
559 pNoteItemPool
= new SfxItemPool(SdrObject::GetGlobalDrawObjectItemPool());
560 return *pNoteItemPool
;
563 void ScDocument::ResetClip( ScDocument
* pSourceDoc
, const ScMarkData
* pMarks
)
567 InitClipPtrs(pSourceDoc
);
569 for (SCTAB i
= 0; i
<= MAXTAB
; i
++)
570 if (pSourceDoc
->pTab
[i
])
571 if (!pMarks
|| pMarks
->GetTableSelect(i
))
574 pSourceDoc
->pTab
[i
]->GetName(aString
);
575 pTab
[i
] = new ScTable(this, i
, aString
);
576 pTab
[i
]->SetLayoutRTL( pSourceDoc
->pTab
[i
]->IsLayoutRTL() );
577 nMaxTableNumber
= i
+1;
582 DBG_ERROR("ResetClip");
586 void ScDocument::ResetClip( ScDocument
* pSourceDoc
, SCTAB nTab
)
590 InitClipPtrs(pSourceDoc
);
592 pTab
[nTab
] = new ScTable(this, nTab
,
593 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("baeh")));
594 if (pSourceDoc
->pTab
[nTab
])
595 pTab
[nTab
]->SetLayoutRTL( pSourceDoc
->pTab
[nTab
]->IsLayoutRTL() );
596 nMaxTableNumber
= nTab
+1;
600 DBG_ERROR("ResetClip");
604 void ScDocument::DeleteNumberFormat( const sal_uInt32
* /* pDelKeys */, sal_uInt32
/* nCount */ )
607 for (ULONG i = 0; i < nCount; i++)
608 xPoolHelper->GetFormTable()->DeleteEntry(pDelKeys[i]);
612 void ScDocument::PutCell( SCCOL nCol
, SCROW nRow
, SCTAB nTab
,
613 ScBaseCell
* pCell
, ULONG nFormatIndex
, BOOL bForceTab
)
617 if ( bForceTab
&& !pTab
[nTab
] )
619 BOOL bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
621 pTab
[nTab
] = new ScTable(this, nTab
,
622 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
627 pTab
[nTab
]->PutCell( nCol
, nRow
, nFormatIndex
, pCell
);
631 void ScDocument::PutCell( const ScAddress
& rPos
, ScBaseCell
* pCell
,
632 ULONG nFormatIndex
, BOOL bForceTab
)
634 SCTAB nTab
= rPos
.Tab();
635 if ( bForceTab
&& !pTab
[nTab
] )
637 BOOL bExtras
= !bIsUndo
; // Spaltenbreiten, Zeilenhoehen, Flags
639 pTab
[nTab
] = new ScTable(this, nTab
,
640 String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("temp")),
645 pTab
[nTab
]->PutCell( rPos
, nFormatIndex
, pCell
);
648 BOOL
ScDocument::GetPrintArea( SCTAB nTab
, SCCOL
& rEndCol
, SCROW
& rEndRow
,
651 if (ValidTab(nTab
) && pTab
[nTab
])
653 BOOL bAny
= pTab
[nTab
]->GetPrintArea( rEndCol
, rEndRow
, bNotes
);
656 ScRange
aDrawRange(0,0,nTab
, MAXCOL
,MAXROW
,nTab
);
657 if (DrawGetPrintArea( aDrawRange
, TRUE
, TRUE
))
659 if (aDrawRange
.aEnd
.Col()>rEndCol
) rEndCol
=aDrawRange
.aEnd
.Col();
660 if (aDrawRange
.aEnd
.Row()>rEndRow
) rEndRow
=aDrawRange
.aEnd
.Row();
672 BOOL
ScDocument::GetPrintAreaHor( SCTAB nTab
, SCROW nStartRow
, SCROW nEndRow
,
673 SCCOL
& rEndCol
, BOOL bNotes
) const
675 if (ValidTab(nTab
) && pTab
[nTab
])
677 BOOL bAny
= pTab
[nTab
]->GetPrintAreaHor( nStartRow
, nEndRow
, rEndCol
, bNotes
);
680 ScRange
aDrawRange(0,nStartRow
,nTab
, MAXCOL
,nEndRow
,nTab
);
681 if (DrawGetPrintArea( aDrawRange
, TRUE
, FALSE
))
683 if (aDrawRange
.aEnd
.Col()>rEndCol
) rEndCol
=aDrawRange
.aEnd
.Col();
694 BOOL
ScDocument::GetPrintAreaVer( SCTAB nTab
, SCCOL nStartCol
, SCCOL nEndCol
,
695 SCROW
& rEndRow
, BOOL bNotes
) const
697 if (ValidTab(nTab
) && pTab
[nTab
])
699 BOOL bAny
= pTab
[nTab
]->GetPrintAreaVer( nStartCol
, nEndCol
, rEndRow
, bNotes
);
702 ScRange
aDrawRange(nStartCol
,0,nTab
, nEndCol
,MAXROW
,nTab
);
703 if (DrawGetPrintArea( aDrawRange
, FALSE
, TRUE
))
705 if (aDrawRange
.aEnd
.Row()>rEndRow
) rEndRow
=aDrawRange
.aEnd
.Row();
716 BOOL
ScDocument::GetDataStart( SCTAB nTab
, SCCOL
& rStartCol
, SCROW
& rStartRow
) const
718 if (ValidTab(nTab
) && pTab
[nTab
])
720 BOOL bAny
= pTab
[nTab
]->GetDataStart( rStartCol
, rStartRow
);
723 ScRange
aDrawRange(0,0,nTab
, MAXCOL
,MAXROW
,nTab
);
724 if (DrawGetPrintArea( aDrawRange
, TRUE
, TRUE
))
726 if (aDrawRange
.aStart
.Col()<rStartCol
) rStartCol
=aDrawRange
.aStart
.Col();
727 if (aDrawRange
.aStart
.Row()<rStartRow
) rStartRow
=aDrawRange
.aStart
.Row();
739 BOOL
ScDocument::MoveTab( SCTAB nOldPos
, SCTAB nNewPos
)
741 if (nOldPos
== nNewPos
) return FALSE
;
743 if (VALIDTAB(nOldPos
))
747 SCTAB nTabCount
= GetTableCount();
750 BOOL bOldAutoCalc
= GetAutoCalc();
751 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
752 SetNoListening( TRUE
);
753 ScProgress
* pProgress
= new ScProgress( GetDocumentShell(),
754 ScGlobal::GetRscString(STR_UNDO_MOVE_TAB
), GetCodeCount() );
755 if (nNewPos
== SC_TAB_APPEND
)
756 nNewPos
= nTabCount
-1;
758 // Referenz-Updaterei
759 //! mit UpdateReference zusammenfassen!
761 SCsTAB nDz
= ((SCsTAB
)nNewPos
) - (SCsTAB
)nOldPos
;
762 ScRange
aSourceRange( 0,0,nOldPos
, MAXCOL
,MAXROW
,nOldPos
);
763 pRangeName
->UpdateTabRef(nOldPos
, 3, nNewPos
);
764 pDBCollection
->UpdateMoveTab( nOldPos
, nNewPos
);
765 xColNameRanges
->UpdateReference( URM_REORDER
, this, aSourceRange
, 0,0,nDz
);
766 xRowNameRanges
->UpdateReference( URM_REORDER
, this, aSourceRange
, 0,0,nDz
);
767 #if OLD_PIVOT_IMPLEMENTATION
768 if (pPivotCollection
)
769 pPivotCollection
->UpdateReference( URM_REORDER
,
770 0,0,nOldPos
, MAXCOL
,MAXROW
,nOldPos
, 0,0,nDz
);
773 pDPCollection
->UpdateReference( URM_REORDER
, aSourceRange
, 0,0,nDz
);
775 pDetOpList
->UpdateReference( this, URM_REORDER
, aSourceRange
, 0,0,nDz
);
776 UpdateChartRef( URM_REORDER
,
777 0,0,nOldPos
, MAXCOL
,MAXROW
,nOldPos
, 0,0,nDz
);
778 UpdateRefAreaLinks( URM_REORDER
, aSourceRange
, 0,0,nDz
);
780 pCondFormList
->UpdateMoveTab( nOldPos
, nNewPos
);
781 if ( pValidationList
)
782 pValidationList
->UpdateMoveTab( nOldPos
, nNewPos
);
783 if ( pUnoBroadcaster
)
784 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_REORDER
,
785 aSourceRange
, 0,0,nDz
) );
787 ScTable
* pSaveTab
= pTab
[nOldPos
];
789 for (i
= nOldPos
+ 1; i
< nTabCount
; i
++)
790 pTab
[i
- 1] = pTab
[i
];
792 for (i
= nTabCount
- 1; i
> nNewPos
; i
--)
793 pTab
[i
] = pTab
[i
- 1];
794 pTab
[nNewPos
] = pSaveTab
;
795 for (i
= 0; i
<= MAXTAB
; i
++)
797 pTab
[i
]->UpdateMoveTab( nOldPos
, nNewPos
, i
, *pProgress
);
798 delete pProgress
; // freimachen fuer evtl. andere
799 for (i
= 0; i
<= MAXTAB
; i
++)
801 pTab
[i
]->UpdateCompile();
802 SetNoListening( FALSE
);
803 for (i
= 0; i
<= MAXTAB
; i
++)
805 pTab
[i
]->StartAllListeners();
806 // #81844# sheet names of references may not be valid until sheet is moved
807 pChartListenerCollection
->UpdateScheduledSeriesRanges();
809 SetAutoCalc( bOldAutoCalc
);
812 DrawMovePage( static_cast<sal_uInt16
>(nOldPos
), static_cast<sal_uInt16
>(nNewPos
) );
814 // Update cells containing external references.
815 if (pExternalRefMgr
.get())
816 pExternalRefMgr
->updateRefMoveTable(nOldPos
, nNewPos
, false);
825 BOOL
ScDocument::CopyTab( SCTAB nOldPos
, SCTAB nNewPos
, const ScMarkData
* pOnlyMarked
)
827 if (SC_TAB_APPEND
== nNewPos
) nNewPos
= nMaxTableNumber
;
829 GetName(nOldPos
, aName
);
831 // vorneweg testen, ob der Prefix als gueltig erkannt wird
832 // wenn nicht, nur doppelte vermeiden
833 BOOL bPrefix
= ValidTabName( aName
);
834 DBG_ASSERT(bPrefix
, "ungueltiger Tabellenname");
837 CreateValidTabName(aName
);
841 bValid
= ( ValidNewTabName(aName
) && (nMaxTableNumber
<= MAXTAB
) );
843 bValid
= ( !GetTable( aName
, nDummy
) && (nMaxTableNumber
<= MAXTAB
) );
845 BOOL bOldAutoCalc
= GetAutoCalc();
846 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
849 if (nNewPos
== nMaxTableNumber
)
851 pTab
[nMaxTableNumber
] = new ScTable(this, nMaxTableNumber
, aName
);
856 if (VALIDTAB(nNewPos
) && (nNewPos
< nMaxTableNumber
))
858 SetNoListening( TRUE
);
860 ScRange
aRange( 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
);
861 xColNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
862 xRowNameRanges
->UpdateReference( URM_INSDEL
, this, aRange
, 0,0,1 );
863 pRangeName
->UpdateTabRef(nNewPos
, 1);
864 pDBCollection
->UpdateReference(
865 URM_INSDEL
, 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
866 #if OLD_PIVOT_IMPLEMENTATION
867 if (pPivotCollection
)
868 pPivotCollection
->UpdateReference(
869 URM_INSDEL
, 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
872 pDPCollection
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
874 pDetOpList
->UpdateReference( this, URM_INSDEL
, aRange
, 0,0,1 );
875 UpdateChartRef( URM_INSDEL
, 0,0,nNewPos
, MAXCOL
,MAXROW
,MAXTAB
, 0,0,1 );
876 UpdateRefAreaLinks( URM_INSDEL
, aRange
, 0,0,1 );
877 if ( pUnoBroadcaster
)
878 pUnoBroadcaster
->Broadcast( ScUpdateRefHint( URM_INSDEL
, aRange
, 0,0,1 ) );
881 for (i
= 0; i
<= MAXTAB
; i
++)
882 if (pTab
[i
] && i
!= nOldPos
)
883 pTab
[i
]->UpdateInsertTab(nNewPos
);
884 for (i
= nMaxTableNumber
; i
> nNewPos
; i
--)
885 pTab
[i
] = pTab
[i
- 1];
886 if (nNewPos
<= nOldPos
)
888 pTab
[nNewPos
] = new ScTable(this, nNewPos
, aName
);
891 for (i
= 0; i
<= MAXTAB
; i
++)
892 if (pTab
[i
] && i
!= nOldPos
&& i
!= nNewPos
)
893 pTab
[i
]->UpdateCompile();
894 SetNoListening( FALSE
);
895 for (i
= 0; i
<= MAXTAB
; i
++)
896 if (pTab
[i
] && i
!= nOldPos
&& i
!= nNewPos
)
897 pTab
[i
]->StartAllListeners();
899 // update conditional formats after table is inserted
901 pCondFormList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
902 if ( pValidationList
)
903 pValidationList
->UpdateReference( URM_INSDEL
, aRange
, 0,0,1 );
904 // #81844# sheet names of references may not be valid until sheet is copied
905 pChartListenerCollection
->UpdateScheduledSeriesRanges();
913 SetNoListening( TRUE
); // noch nicht bei CopyToTable/Insert
914 pTab
[nOldPos
]->CopyToTable(0, 0, MAXCOL
, MAXROW
, IDF_ALL
, (pOnlyMarked
!= NULL
),
915 pTab
[nNewPos
], pOnlyMarked
);
917 /* if (nNewPos < nOldPos)
918 nDz = ((short)nNewPos) - (short)nOldPos + 1;
920 */ nDz
= ((short)nNewPos
) - (short)nOldPos
;
921 pTab
[nNewPos
]->UpdateReference(URM_COPY
, 0, 0, nNewPos
, MAXCOL
, MAXROW
,
922 nNewPos
, 0, 0, nDz
, NULL
);
924 pTab
[nNewPos
]->UpdateInsertTabAbs(nNewPos
); // alle abs. um eins hoch!!
925 pTab
[nOldPos
]->UpdateInsertTab(nNewPos
);
927 pTab
[nOldPos
]->UpdateCompile();
928 pTab
[nNewPos
]->UpdateCompile( TRUE
); // #67996# maybe already compiled in Clone, but used names need recompilation
929 SetNoListening( FALSE
);
930 pTab
[nOldPos
]->StartAllListeners();
931 pTab
[nNewPos
]->StartAllListeners();
933 SetAutoCalc( bOldAutoCalc
);
936 DrawCopyPage( static_cast<sal_uInt16
>(nOldPos
), static_cast<sal_uInt16
>(nNewPos
) );
938 pTab
[nNewPos
]->SetPageStyle( pTab
[nOldPos
]->GetPageStyle() );
940 // Update cells containing external references.
941 if (pExternalRefMgr
.get())
942 pExternalRefMgr
->updateRefMoveTable(nOldPos
, nNewPos
, true);
945 SetAutoCalc( bOldAutoCalc
);
949 ULONG
ScDocument::TransferTab( ScDocument
* pSrcDoc
, SCTAB nSrcPos
,
950 SCTAB nDestPos
, BOOL bInsertNew
,
953 ULONG nRetVal
= 1; // 0 => Fehler 1 = ok
954 // 2 => RefBox, 3 => NameBox
957 if (bInsertNew
) // neu einfuegen
960 pSrcDoc
->GetName(nSrcPos
, aName
);
961 CreateValidTabName(aName
);
962 bValid
= InsertTab(nDestPos
, aName
);
964 else // bestehende Tabelle ersetzen
966 if (VALIDTAB(nDestPos
) && pTab
[nDestPos
])
968 pTab
[nDestPos
]->DeleteArea( 0,0, MAXCOL
,MAXROW
, IDF_ALL
);
976 BOOL bOldAutoCalcSrc
= FALSE
;
977 BOOL bOldAutoCalc
= GetAutoCalc();
978 SetAutoCalc( FALSE
); // Mehrfachberechnungen vermeiden
979 SetNoListening( TRUE
);
982 bOldAutoCalcSrc
= pSrcDoc
->GetAutoCalc();
983 pSrcDoc
->SetAutoCalc( TRUE
); // falls was berechnet werden muss
987 NumFmtMergeHandler
aNumFmtMergeHdl(this, pSrcDoc
);
989 nDestPos
= Min(nDestPos
, (SCTAB
)(GetTableCount() - 1));
990 { // scope for bulk broadcast
991 ScBulkBroadcast
aBulkBroadcast( pBASM
);
992 pSrcDoc
->pTab
[nSrcPos
]->CopyToTable(0, 0, MAXCOL
, MAXROW
,
993 ( bResultsOnly
? IDF_ALL
& ~IDF_FORMULA
: IDF_ALL
),
994 FALSE
, pTab
[nDestPos
] );
997 pTab
[nDestPos
]->SetTabNo(nDestPos
);
1001 BOOL bNamesLost
= FALSE
;
1002 USHORT nSrcRangeNames
= pSrcDoc
->pRangeName
->GetCount();
1003 // array containing range names which might need update of indices
1004 ScRangeData
** pSrcRangeNames
= nSrcRangeNames
? new ScRangeData
* [nSrcRangeNames
] : NULL
;
1005 // the index mapping thereof
1006 ScIndexMap
aSrcRangeMap( nSrcRangeNames
);
1007 BOOL bRangeNameReplace
= FALSE
;
1009 // find named ranges that are used in the source sheet
1010 std::set
<USHORT
> aUsedNames
;
1011 pSrcDoc
->pTab
[nSrcPos
]->FindRangeNamesInUse( 0, 0, MAXCOL
, MAXROW
, aUsedNames
);
1013 for (USHORT i
= 0; i
< nSrcRangeNames
; i
++) //! DB-Bereiche Pivot-Bereiche auch !!!
1015 ScRangeData
* pSrcData
= (*pSrcDoc
->pRangeName
)[i
];
1016 USHORT nOldIndex
= pSrcData
->GetIndex();
1017 bool bInUse
= ( aUsedNames
.find(nOldIndex
) != aUsedNames
.end() );
1020 USHORT nExisting
= 0;
1021 if ( pRangeName
->SearchName( pSrcData
->GetName(), nExisting
) )
1023 // the name exists already in the destination document
1024 // -> use the existing name, but show a warning
1025 // (when refreshing links, the existing name is used and the warning not shown)
1027 ScRangeData
* pExistingData
= (*pRangeName
)[nExisting
];
1028 USHORT nExistingIndex
= pExistingData
->GetIndex();
1030 pSrcRangeNames
[i
] = NULL
; // don't modify the named range
1031 aSrcRangeMap
.SetPair( i
, nOldIndex
, nExistingIndex
);
1032 bRangeNameReplace
= TRUE
;
1037 ScRangeData
* pData
= new ScRangeData( *pSrcData
);
1038 pData
->SetDocument(this);
1039 if ( pRangeName
->FindIndex( pData
->GetIndex() ) )
1040 pData
->SetIndex(0); // need new index, done in Insert
1041 if (!pRangeName
->Insert(pData
))
1043 DBG_ERROR("can't insert name"); // shouldn't happen
1048 pData
->TransferTabRef( nSrcPos
, nDestPos
);
1049 pSrcRangeNames
[i
] = pData
;
1050 USHORT nNewIndex
= pData
->GetIndex();
1051 aSrcRangeMap
.SetPair( i
, nOldIndex
, nNewIndex
);
1052 if ( !bRangeNameReplace
)
1053 bRangeNameReplace
= ( nOldIndex
!= nNewIndex
);
1059 pSrcRangeNames
[i
] = NULL
;
1060 //aSrcRangeMap.SetPair( i, 0, 0 ); // not needed, defaulted
1063 if ( bRangeNameReplace
)
1065 // first update all inserted named formulas if they contain other
1066 // range names and used indices changed
1067 for (USHORT i
= 0; i
< nSrcRangeNames
; i
++) //! DB-Bereiche Pivot-Bereiche auch
1069 if ( pSrcRangeNames
[i
] )
1070 pSrcRangeNames
[i
]->ReplaceRangeNamesInUse( aSrcRangeMap
);
1072 // then update the formulas, they might need the just updated range names
1073 pTab
[nDestPos
]->ReplaceRangeNamesInUse( 0, 0, MAXCOL
, MAXROW
, aSrcRangeMap
);
1075 if ( pSrcRangeNames
)
1076 delete [] pSrcRangeNames
;
1078 SCsTAB nDz
= ((SCsTAB
)nDestPos
) - (SCsTAB
)nSrcPos
;
1079 pTab
[nDestPos
]->UpdateReference(URM_COPY
, 0, 0, nDestPos
,
1080 MAXCOL
, MAXROW
, nDestPos
,
1082 // Test for outside absolute references for info box
1083 BOOL bIsAbsRef
= pSrcDoc
->pTab
[nSrcPos
]->TestTabRefAbs(nSrcPos
);
1084 // Readjust self-contained absolute references to this sheet
1085 pTab
[nDestPos
]->TestTabRefAbs(nSrcPos
);
1089 // InfoBox AbsoluteRefs sind moeglicherweise nicht mehr korrekt!!
1094 // message: duplicate names
1096 pTab
[nDestPos
]->CompileAll();
1099 SetNoListening( FALSE
);
1100 if ( !bResultsOnly
)
1101 pTab
[nDestPos
]->StartAllListeners();
1102 SetDirty( ScRange( 0, 0, nDestPos
, MAXCOL
, MAXROW
, nDestPos
));
1105 pSrcDoc
->SetAutoCalc( bOldAutoCalcSrc
);
1106 SetAutoCalc( bOldAutoCalc
);
1111 TransferDrawPage( pSrcDoc
, nSrcPos
, nDestPos
);
1118 // ----------------------------------------------------------------------------
1120 void ScDocument::SetError( SCCOL nCol
, SCROW nRow
, SCTAB nTab
, const USHORT nError
)
1124 pTab
[nTab
]->SetError( nCol
, nRow
, nError
);
1127 void ScDocument::EraseNonUsedSharedNames(USHORT nLevel
)
1129 for (USHORT i
= 0; i
< pRangeName
->GetCount(); i
++)
1131 ScRangeData
* pRangeData
= (*pRangeName
)[i
];
1132 if (pRangeData
&& pRangeData
->HasType(RT_SHARED
))
1135 pRangeData
->GetName(aName
);
1136 aName
.Erase(0, 6); // !!! vgl. Table4, FillFormula !!
1137 USHORT nInd
= (USHORT
) aName
.ToInt32();
1140 USHORT nIndex
= pRangeData
->GetIndex();
1141 BOOL bInUse
= FALSE
;
1142 for (SCTAB j
= 0; !bInUse
&& (j
<= MAXTAB
); j
++)
1145 bInUse
= pTab
[j
]->IsRangeNameInUse(0, 0, MAXCOL
-1, MAXROW
-1,
1149 pRangeName
->AtFree(i
);
1155 // ----------------------------------------------------------------------------
1157 void ScDocument::SetConsolidateDlgData( const ScConsolidateParam
* pData
)
1159 delete pConsolidateDlgData
;
1162 pConsolidateDlgData
= new ScConsolidateParam( *pData
);
1164 pConsolidateDlgData
= NULL
;
1167 void ScDocument::SetChangeViewSettings(const ScChangeViewSettings
& rNew
)
1169 if (pChangeViewSettings
==NULL
)
1170 pChangeViewSettings
= new ScChangeViewSettings
;
1172 DBG_ASSERT( pChangeViewSettings
, "Oops. No ChangeViewSettings :-( by!" );
1174 *pChangeViewSettings
=rNew
;
1177 // ----------------------------------------------------------------------------
1179 ScFieldEditEngine
* ScDocument::CreateFieldEditEngine()
1181 ScFieldEditEngine
* pNewEditEngine
= NULL
;
1182 if (!pCacheFieldEditEngine
)
1184 pNewEditEngine
= new ScFieldEditEngine( GetEnginePool(),
1185 GetEditPool(), FALSE
);
1189 if ( !bImportingXML
)
1191 // #i66209# previous use might not have restored update mode,
1192 // ensure same state as for a new EditEngine (UpdateMode = TRUE)
1193 if ( !pCacheFieldEditEngine
->GetUpdateMode() )
1194 pCacheFieldEditEngine
->SetUpdateMode(TRUE
);
1197 pNewEditEngine
= pCacheFieldEditEngine
;
1198 pCacheFieldEditEngine
= NULL
;
1200 return pNewEditEngine
;
1203 void ScDocument::DisposeFieldEditEngine(ScFieldEditEngine
*& rpEditEngine
)
1205 if (!pCacheFieldEditEngine
&& rpEditEngine
)
1207 pCacheFieldEditEngine
= rpEditEngine
;
1208 pCacheFieldEditEngine
->Clear();
1211 delete rpEditEngine
;
1212 rpEditEngine
= NULL
;
1215 // ----------------------------------------------------------------------------
1218 ScRecursionHelper
* ScDocument::CreateRecursionHelperInstance()
1220 return new ScRecursionHelper
;
1223 // ----------------------------------------------------------------------------
1225 ScLookupCache
& ScDocument::GetLookupCache( const ScRange
& rRange
)
1227 ScLookupCache
* pCache
= 0;
1228 if (!pLookupCacheMapImpl
)
1229 pLookupCacheMapImpl
= new ScLookupCacheMapImpl
;
1230 ScLookupCacheMap::iterator
it( pLookupCacheMapImpl
->aCacheMap
.find( rRange
));
1231 if (it
== pLookupCacheMapImpl
->aCacheMap
.end())
1233 pCache
= new ScLookupCache( this, rRange
);
1234 AddLookupCache( *pCache
);
1237 pCache
= (*it
).second
;
1241 void ScDocument::AddLookupCache( ScLookupCache
& rCache
)
1243 if (!pLookupCacheMapImpl
->aCacheMap
.insert( ::std::pair
< const ScRange
,
1244 ScLookupCache
*>( rCache
.getRange(), &rCache
)).second
)
1246 DBG_ERRORFILE( "ScDocument::AddLookupCache: couldn't add to hash map");
1249 StartListeningArea( rCache
.getRange(), &rCache
);
1252 void ScDocument::RemoveLookupCache( ScLookupCache
& rCache
)
1254 ScLookupCacheMap::iterator
it( pLookupCacheMapImpl
->aCacheMap
.find(
1255 rCache
.getRange()));
1256 if (it
== pLookupCacheMapImpl
->aCacheMap
.end())
1258 DBG_ERRORFILE( "ScDocument::RemoveLookupCache: range not found in hash map");
1262 ScLookupCache
* pCache
= (*it
).second
;
1263 pLookupCacheMapImpl
->aCacheMap
.erase( it
);
1264 EndListeningArea( pCache
->getRange(), &rCache
);
1268 using namespace com::sun::star
;
1269 uno::Reference
< document::XVbaEventsHelper
>
1270 ScDocument::GetVbaEventsHelper()
1272 if( !mxVbaEventsHelper
.is() )
1276 uno::Reference
< lang::XMultiServiceFactory
> xSF( comphelper::getProcessServiceFactory(), uno::UNO_QUERY
);
1277 uno::Reference
< frame::XModel
> xModel( pShell
? pShell
->GetModel() : NULL
, uno::UNO_QUERY
);
1278 uno::Sequence
< uno::Any
> aArgs(1);
1279 aArgs
[0] = uno::Any( xModel
);
1280 uno::Reference
< document::XVbaEventsHelper
> xVbaEventsHelper( xSF
->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.document.VbaEventsHelper" ) ), aArgs
), uno::UNO_QUERY
);
1281 // helper will always be created successfully.
1282 mxVbaEventsHelper
.set( xVbaEventsHelper
, uno::UNO_QUERY
);
1284 catch( uno::Exception
& e
)
1288 return mxVbaEventsHelper
;
1291 void ScDocument::ClearLookupCaches()
1293 if( pLookupCacheMapImpl
)
1294 pLookupCacheMapImpl
->clear();