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: document.hxx,v $
10 * $Revision: 1.115.36.9 $
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 "macromgr.hxx"
37 #include "document.hxx"
39 #include "basic/basmgr.hxx"
40 #include "cppuhelper/implbase1.hxx"
41 #include "sfx2/objsh.hxx"
43 #include <com/sun/star/container/XContainer.hpp>
47 using namespace ::com::sun::star
;
48 using ::com::sun::star::uno::RuntimeException
;
49 using ::com::sun::star::uno::Reference
;
50 using ::rtl::OUString
;
51 using ::rtl::OUStringHash
;
52 using ::std::hash_map
;
54 using ::std::for_each
;
57 // ============================================================================
60 * A simple container to keep track of cells that depend on basic modules
61 * changes. We don't check for duplicates at insertion time; instead, we
62 * remove duplicates at query time.
64 class ScUserMacroDepTracker
67 void addCell(const OUString
& rModuleName
, ScFormulaCell
* pCell
)
69 ModuleCellMap::iterator itr
= maCells
.find(rModuleName
);
70 if (itr
== maCells
.end())
72 pair
<ModuleCellMap::iterator
, bool> r
= maCells
.insert(
73 ModuleCellMap::value_type(rModuleName
, list
<ScFormulaCell
*>()));
81 itr
->second
.push_back(pCell
);
84 void removeCell(ScFormulaCell
* pCell
)
86 ModuleCellMap::iterator itr
= maCells
.begin(), itrEnd
= maCells
.end();
87 for (; itr
!= itrEnd
; ++itr
)
88 itr
->second
.remove(pCell
);
91 void getCellsByModule(const OUString
& rModuleName
, list
<ScFormulaCell
*>& rCells
)
93 ModuleCellMap::iterator itr
= maCells
.find(rModuleName
);
94 if (itr
== maCells
.end())
97 list
<ScFormulaCell
*>& rCellList
= itr
->second
;
102 // exception safe copy
103 list
<ScFormulaCell
*> temp(rCellList
);
108 typedef hash_map
<OUString
, list
<ScFormulaCell
*>, OUStringHash
> ModuleCellMap
;
109 ModuleCellMap maCells
;
113 // ============================================================================
115 ScMacroManager::ScMacroManager(ScDocument
* pDoc
) :
116 mpDepTracker(new ScUserMacroDepTracker
),
121 ScMacroManager::~ScMacroManager()
125 typedef ::cppu::WeakImplHelper1
< ::com::sun::star::container::XContainerListener
> ContainerListenerHelper
;
127 class VBAProjectListener
: public ContainerListenerHelper
129 ScMacroManager
* mpMacroMgr
;
131 VBAProjectListener( ScMacroManager
* pMacroMgr
) : mpMacroMgr( pMacroMgr
) {}
133 virtual void SAL_CALL
disposing( const lang::EventObject
& /*Source*/ ) throw(RuntimeException
) {}
135 // XContainerListener
136 virtual void SAL_CALL
elementInserted( const container::ContainerEvent
& /*Event*/ ) throw(RuntimeException
){}
137 virtual void SAL_CALL
elementReplaced( const container::ContainerEvent
& Event
) throw(RuntimeException
)
139 rtl::OUString sModuleName
;
140 Event
.Accessor
>>= sModuleName
;
141 OSL_TRACE("VBAProjectListener::elementReplaced(%s)", rtl::OUStringToOString( sModuleName
, RTL_TEXTENCODING_UTF8
).getStr() );
142 mpMacroMgr
->InitUserFuncData();
143 mpMacroMgr
->BroadcastModuleUpdate(sModuleName
);
145 virtual void SAL_CALL
elementRemoved( const container::ContainerEvent
& /*Event*/ ) throw(RuntimeException
){}
149 void ScMacroManager::InitUserFuncData()
152 mhFuncToVolatile
.clear();
153 String
sProjectName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
155 Reference
< container::XContainer
> xModuleContainer
;
156 SfxObjectShell
* pShell
= mpDoc
->GetDocumentShell();
157 if ( pShell
&& pShell
->GetBasicManager()->GetName().Len() > 0 )
158 sProjectName
= pShell
->GetBasicManager()->GetName();
161 Reference
< script::XLibraryContainer
> xLibraries( pShell
->GetBasicContainer(), uno::UNO_QUERY_THROW
);
162 xModuleContainer
.set( xLibraries
->getByName( sProjectName
), uno::UNO_QUERY_THROW
);
164 if ( xModuleContainer
.is() )
166 // remove old listener ( if there was one )
167 if ( mxContainerListener
.is() )
168 xModuleContainer
->removeContainerListener( mxContainerListener
);
170 mxContainerListener
= new VBAProjectListener( this );
171 xModuleContainer
->addContainerListener( mxContainerListener
);
174 catch( uno::Exception
& )
179 void ScMacroManager::SetUserFuncVolatile( const OUString
& sName
, bool isVolatile
)
181 mhFuncToVolatile
[ sName
] = isVolatile
;
184 bool ScMacroManager::GetUserFuncVolatile( const OUString
& sName
)
186 NameBoolMap::iterator it
= mhFuncToVolatile
.find( sName
);
187 if ( it
== mhFuncToVolatile
.end() )
192 void ScMacroManager::AddDependentCell(const OUString
& aModuleName
, ScFormulaCell
* pCell
)
194 mpDepTracker
->addCell(aModuleName
, pCell
);
197 void ScMacroManager::RemoveDependentCell(ScFormulaCell
* pCell
)
199 mpDepTracker
->removeCell(pCell
);
202 void ScMacroManager::BroadcastModuleUpdate(const OUString
& aModuleName
)
204 list
<ScFormulaCell
*> aCells
;
205 mpDepTracker
->getCellsByModule(aModuleName
, aCells
);
206 list
<ScFormulaCell
*>::iterator itr
= aCells
.begin(), itrEnd
= aCells
.end();
207 for (; itr
!= itrEnd
; ++itr
)
209 ScFormulaCell
* pCell
= *itr
;
210 mpDoc
->PutInFormulaTree(pCell
); // for F9 recalc
212 // for recalc on cell value change. If the cell is not volatile, the
213 // cell stops listening right away after it gets re-interpreted.
214 mpDoc
->StartListeningArea(BCA_LISTEN_ALWAYS
, pCell
);