Update ooo320-m1
[ooovba.git] / sc / source / ui / docshell / macromgr.cxx
blob97623f3b2d63810c19870c9ceb60d03262b32b06
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"
42 #include "cell.hxx"
43 #include <com/sun/star/container/XContainer.hpp>
45 #include <list>
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;
53 using ::std::list;
54 using ::std::for_each;
55 using ::std::pair;
57 // ============================================================================
59 /**
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
66 public:
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*>()));
75 if (!r.second)
76 // insertion failed.
77 return;
79 itr = r.first;
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())
95 return;
97 list<ScFormulaCell*>& rCellList = itr->second;
99 // Remove duplicates.
100 rCellList.sort();
101 rCellList.unique();
102 // exception safe copy
103 list<ScFormulaCell*> temp(rCellList);
104 rCells.swap(temp);
107 private:
108 typedef hash_map<OUString, list<ScFormulaCell*>, OUStringHash> ModuleCellMap;
109 ModuleCellMap maCells;
113 // ============================================================================
115 ScMacroManager::ScMacroManager(ScDocument* pDoc) :
116 mpDepTracker(new ScUserMacroDepTracker),
117 mpDoc(pDoc)
121 ScMacroManager::~ScMacroManager()
125 typedef ::cppu::WeakImplHelper1< ::com::sun::star::container::XContainerListener > ContainerListenerHelper;
127 class VBAProjectListener : public ContainerListenerHelper
129 ScMacroManager* mpMacroMgr;
130 public:
131 VBAProjectListener( ScMacroManager* pMacroMgr ) : mpMacroMgr( pMacroMgr ) {}
132 // XEventListener
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()
151 // Clear hash_map
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 );
169 // Create listener
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() )
188 return false;
189 return it->second;
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);