Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "frm_resource.hrc"
22 : #include "frm_resource.hxx"
23 : #include "InterfaceContainer.hxx"
24 : #include "componenttools.hxx"
25 : #include "property.hrc"
26 : #include "services.hxx"
27 :
28 : #include <com/sun/star/beans/XPropertySet.hpp>
29 : #include <com/sun/star/container/XNamed.hpp>
30 : #include <com/sun/star/io/WrongFormatException.hpp>
31 : #include <com/sun/star/io/XMarkableStream.hpp>
32 : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
33 : #include <com/sun/star/lang/XComponent.hpp>
34 : #include <com/sun/star/util/XCloneable.hpp>
35 : #include <com/sun/star/form/XForm.hpp>
36 :
37 : #include <comphelper/container.hxx>
38 : #include <comphelper/enumhelper.hxx>
39 : #include <comphelper/eventattachermgr.hxx>
40 : #include <comphelper/property.hxx>
41 : #include <comphelper/sequence.hxx>
42 : #include <comphelper/types.hxx>
43 : #include <cppuhelper/exc_hlp.hxx>
44 : #include <cppuhelper/queryinterface.hxx>
45 : #include <tools/debug.hxx>
46 : #include <tools/diagnose_ex.h>
47 :
48 : #include <algorithm>
49 : #include <boost/scoped_ptr.hpp>
50 :
51 :
52 : #include <com/sun/star/frame/XModel.hpp>
53 : #include <com/sun/star/document/XCodeNameQuery.hpp>
54 : #include <ooo/vba/XVBAToOOEventDescGen.hpp>
55 : #include <comphelper/processfactory.hxx>
56 :
57 : namespace frm
58 : {
59 :
60 :
61 : using namespace ::com::sun::star::frame;
62 : using namespace ::com::sun::star::lang;
63 : using namespace ::com::sun::star::uno;
64 : using namespace ::com::sun::star::beans;
65 : using namespace ::com::sun::star::document;
66 : using namespace ::com::sun::star::container;
67 : using namespace ::com::sun::star::script;
68 : using namespace ::com::sun::star::io;
69 : using namespace ::com::sun::star::form;
70 : using namespace ::com::sun::star::util;
71 :
72 : namespace
73 : {
74 :
75 0 : static void lcl_throwIllegalArgumentException()
76 : {
77 0 : throw IllegalArgumentException();
78 : }
79 : }
80 :
81 : bool
82 48 : lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
83 : {
84 48 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
85 48 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
86 54 : for ( ; pDesc != pEnd; ++pDesc )
87 : {
88 6 : if ( pDesc->ScriptType == "VBAInterop" )
89 0 : return true;
90 : }
91 48 : return false;
92 : }
93 :
94 : Sequence< ScriptEventDescriptor >
95 0 : lcl_stripVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
96 : {
97 0 : Sequence< ScriptEventDescriptor > sStripped( sEvents.getLength() );
98 :
99 0 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
100 0 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
101 0 : sal_Int32 nCopied = 0;
102 0 : for ( ; pDesc != pEnd; ++pDesc )
103 : {
104 0 : if ( pDesc->ScriptType != "VBAInterop" )
105 : {
106 0 : sStripped[ nCopied++ ] = *pDesc;
107 : }
108 : }
109 0 : if ( nCopied )
110 0 : sStripped.realloc( nCopied );
111 0 : return sStripped;
112 : }
113 :
114 266 : void OInterfaceContainer::impl_addVbEvents_nolck_nothrow( const sal_Int32 i_nIndex )
115 : {
116 : // we are dealing with form controls
117 : try
118 : {
119 : do
120 : {
121 266 : Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
122 266 : if ( !xDoc.is() )
123 0 : break;
124 :
125 302 : Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
126 297 : Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance("ooo.vba.VBACodeNameProvider"), UNO_QUERY );
127 261 : if ( !xNameQuery.is() )
128 230 : break;
129 :
130 62 : ::osl::MutexGuard aGuard( m_rMutex );
131 31 : bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
132 31 : if ( hasVBABindings )
133 0 : break;
134 :
135 62 : Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
136 62 : Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
137 31 : if ( xElementAsForm.is() )
138 0 : break;
139 :
140 : // Try getting the code name from the container first (faster),
141 : // then from the element if that fails (slower).
142 62 : Reference<XInterface> xThis = static_cast<XContainer*>(this);
143 62 : OUString sCodeName = xNameQuery->getCodeNameForContainer(xThis);
144 31 : if (sCodeName.isEmpty())
145 30 : sCodeName = xNameQuery->getCodeNameForObject(xElement);
146 :
147 62 : Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
148 62 : OUString sServiceName;
149 31 : xProps->getPropertyValue("DefaultControl") >>= sServiceName;
150 :
151 62 : Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xContext->getServiceManager()->createInstanceWithContext("ooo.vba.VBAToOOEventDesc", m_xContext), UNO_QUERY_THROW );
152 2 : Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( sServiceName , sCodeName );
153 :
154 : // register the vba script events
155 37 : m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
156 : }
157 : while ( false );
158 : }
159 5 : catch ( const ServiceNotRegisteredException& )
160 : {
161 : // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
162 : }
163 30 : catch( const Exception& )
164 : {
165 : DBG_UNHANDLED_EXCEPTION();
166 : }
167 :
168 266 : }
169 :
170 580 : ElementDescription::ElementDescription( )
171 : {
172 580 : }
173 :
174 :
175 1102 : ElementDescription::~ElementDescription()
176 : {
177 1102 : }
178 :
179 609 : OInterfaceContainer::OInterfaceContainer(
180 : const Reference<XComponentContext>& _rxContext,
181 : ::osl::Mutex& _rMutex,
182 : const Type& _rElementType)
183 : :OInterfaceContainer_BASE()
184 : ,m_rMutex(_rMutex)
185 : ,m_aContainerListeners(_rMutex)
186 : ,m_aElementType(_rElementType)
187 609 : ,m_xContext(_rxContext)
188 : {
189 609 : impl_createEventAttacher_nothrow();
190 609 : }
191 :
192 :
193 0 : OInterfaceContainer::OInterfaceContainer( ::osl::Mutex& _rMutex, const OInterfaceContainer& _cloneSource )
194 : :OInterfaceContainer_BASE()
195 : ,m_rMutex( _rMutex )
196 : ,m_aContainerListeners( _rMutex )
197 : ,m_aElementType( _cloneSource.m_aElementType )
198 0 : ,m_xContext( _cloneSource.m_xContext )
199 : {
200 0 : impl_createEventAttacher_nothrow();
201 0 : }
202 :
203 0 : void OInterfaceContainer::clonedFrom(const OInterfaceContainer& _cloneSource) throw(RuntimeException, std::exception)
204 : {
205 : try
206 : {
207 0 : const Reference< XIndexAccess > xSourceHierarchy( const_cast< OInterfaceContainer* >( &_cloneSource ) );
208 0 : const sal_Int32 nCount = xSourceHierarchy->getCount();
209 0 : for ( sal_Int32 i=0; i<nCount; ++i )
210 : {
211 0 : Reference< XCloneable > xCloneable( xSourceHierarchy->getByIndex( i ), UNO_QUERY_THROW );
212 0 : Reference< XInterface > xClone( xCloneable->createClone() );
213 0 : insertByIndex( i, makeAny( xClone ) );
214 0 : }
215 : }
216 0 : catch (const RuntimeException&)
217 : {
218 0 : throw;
219 : }
220 0 : catch (const Exception&)
221 : {
222 : throw WrappedTargetRuntimeException(
223 : "Could not clone the given interface hierarchy.",
224 : static_cast< XIndexContainer* >( const_cast< OInterfaceContainer* >( &_cloneSource ) ),
225 : ::cppu::getCaughtException()
226 0 : );
227 : }
228 0 : }
229 :
230 609 : void OInterfaceContainer::impl_createEventAttacher_nothrow()
231 : {
232 : try
233 : {
234 609 : m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xContext ), UNO_SET_THROW );
235 : }
236 0 : catch( const Exception& )
237 : {
238 : DBG_UNHANDLED_EXCEPTION();
239 : }
240 609 : }
241 :
242 :
243 604 : OInterfaceContainer::~OInterfaceContainer()
244 : {
245 604 : }
246 :
247 :
248 605 : void OInterfaceContainer::disposing()
249 : {
250 : // dispose all elements
251 895 : for (sal_Int32 i = m_aItems.size(); i > 0; --i)
252 : {
253 290 : Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
254 290 : if (xSet.is())
255 290 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
256 :
257 : // revoke event knittings
258 290 : if ( m_xEventAttacher.is() )
259 : {
260 290 : m_xEventAttacher->detach( i - 1, Reference<XInterface>(xSet, UNO_QUERY) );
261 290 : m_xEventAttacher->removeEntry( i - 1 );
262 : }
263 :
264 580 : Reference<XComponent> xComponent(xSet, UNO_QUERY);
265 290 : if (xComponent.is())
266 290 : xComponent->dispose();
267 290 : }
268 605 : m_aMap.clear();
269 605 : m_aItems.clear();
270 :
271 605 : css::lang::EventObject aEvt(static_cast<XContainer*>(this));
272 605 : m_aContainerListeners.disposeAndClear(aEvt);
273 605 : }
274 :
275 : // XPersistObject
276 :
277 : namespace
278 : {
279 :
280 1 : void lcl_saveEvents( ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
281 : const Reference< XEventAttacherManager >& _rxManager, const sal_Int32 _nItemCount )
282 : {
283 : OSL_ENSURE( _rxManager.is(), "lcl_saveEvents: invalid event attacher manager!" );
284 1 : if ( !_rxManager.is() )
285 1 : return;
286 :
287 : // reserve the space needed
288 1 : _rSave.reserve( _nItemCount );
289 :
290 : // copy the events
291 3 : for (sal_Int32 i=0; i<_nItemCount; ++i)
292 2 : _rSave.push_back(_rxManager->getScriptEvents( i ));
293 : }
294 :
295 :
296 1 : void lcl_restoreEvents( const ::std::vector< Sequence< ScriptEventDescriptor > >& _rSave,
297 : const Reference< XEventAttacherManager >& _rxManager )
298 : {
299 : OSL_ENSURE( _rxManager.is(), "lcl_restoreEvents: invalid event attacher manager!" );
300 1 : if ( !_rxManager.is() )
301 1 : return;
302 :
303 1 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
304 1 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
305 3 : for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
306 : {
307 2 : _rxManager->revokeScriptEvents( i );
308 2 : _rxManager->registerScriptEvents( i, *aLoop );
309 : }
310 : }
311 : }
312 :
313 :
314 1 : void SAL_CALL OInterfaceContainer::writeEvents(const Reference<XObjectOutputStream>& _rxOutStream)
315 : {
316 : // We're writing a document in SO 5.2 format (or even from earlier versions)
317 : // -> convert the events from the new runtime format to the format of the 5.2 files
318 : // but before, remember the current script events set for our children
319 1 : ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
320 1 : if ( m_xEventAttacher.is() )
321 1 : lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
322 :
323 1 : transformEvents( efVersionSO5x );
324 :
325 : try
326 : {
327 1 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
328 1 : sal_Int32 nMark = xMark->createMark();
329 :
330 1 : sal_Int32 nObjLen = 0;
331 1 : _rxOutStream->writeLong(nObjLen);
332 :
333 2 : Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
334 1 : if (xScripts.is())
335 1 : xScripts->write(_rxOutStream);
336 :
337 : // Determine length
338 1 : nObjLen = xMark->offsetToMark(nMark) - 4;
339 1 : xMark->jumpToMark(nMark);
340 1 : _rxOutStream->writeLong(nObjLen);
341 1 : xMark->jumpToFurthest();
342 2 : xMark->deleteMark(nMark);
343 : }
344 0 : catch( const Exception& )
345 : {
346 : // restore the events
347 0 : if ( m_xEventAttacher.is() )
348 0 : lcl_restoreEvents( aSave, m_xEventAttacher );
349 0 : throw;
350 : }
351 :
352 : // restore the events
353 1 : if ( m_xEventAttacher.is() )
354 1 : lcl_restoreEvents( aSave, m_xEventAttacher );
355 1 : }
356 :
357 :
358 : struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
359 : {
360 0 : void operator()( ScriptEventDescriptor& _rDescriptor )
361 : {
362 0 : if ( _rDescriptor.ScriptType == "StarBasic" )
363 : { // it's a starbasic macro
364 0 : sal_Int32 nPrefixLength = _rDescriptor.ScriptCode.indexOf( ':' );
365 0 : if ( 0 <= nPrefixLength )
366 : { // the macro name does not already contain a :
367 : #ifdef DBG_UTIL
368 : const OUString sPrefix = _rDescriptor.ScriptCode.copy( 0, nPrefixLength );
369 : DBG_ASSERT( sPrefix == "document"
370 : || sPrefix == "application",
371 : "TransformEventTo52Format: invalid (unknown) prefix!" );
372 : #endif
373 : // cut the prefix
374 0 : _rDescriptor.ScriptCode = _rDescriptor.ScriptCode.copy( nPrefixLength + 1 );
375 : }
376 : }
377 0 : }
378 : };
379 :
380 :
381 : struct TransformEventTo60Format : public ::std::unary_function< ScriptEventDescriptor, void >
382 : {
383 0 : void operator()( ScriptEventDescriptor& _rDescriptor )
384 : {
385 0 : if ( _rDescriptor.ScriptType == "StarBasic" )
386 : { // it's a starbasic macro
387 0 : if ( _rDescriptor.ScriptCode.indexOf( ':' ) < 0 )
388 : { // the macro name does not already contain a :
389 : // -> default the type to "document"
390 0 : _rDescriptor.ScriptCode = "document:" + _rDescriptor.ScriptCode;
391 : }
392 : }
393 0 : }
394 : };
395 :
396 :
397 1 : void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
398 : {
399 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
400 1 : if ( !m_xEventAttacher.is() )
401 1 : return;
402 :
403 : try
404 : {
405 : // loop through all our children
406 1 : sal_Int32 nItems = m_aItems.size();
407 1 : Sequence< ScriptEventDescriptor > aChildEvents;
408 :
409 3 : for (sal_Int32 i=0; i<nItems; ++i)
410 : {
411 : // get the script events for this object
412 2 : aChildEvents = m_xEventAttacher->getScriptEvents( i );
413 :
414 2 : if ( aChildEvents.getLength() )
415 : {
416 : // the "iterators" for the events for this child
417 0 : ScriptEventDescriptor* pChildEvents = aChildEvents.getArray();
418 0 : ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength();
419 :
420 : // do the transformation
421 0 : if ( efVersionSO6x == _eTargetFormat )
422 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
423 : else
424 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
425 :
426 : // revoke the script events
427 0 : m_xEventAttacher->revokeScriptEvents( i );
428 : // and re-register them
429 0 : m_xEventAttacher->registerScriptEvents( i, aChildEvents );
430 : }
431 1 : }
432 : }
433 0 : catch( const Exception& )
434 : {
435 : DBG_UNHANDLED_EXCEPTION();
436 : }
437 : }
438 :
439 :
440 0 : void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
441 : {
442 0 : ::osl::MutexGuard aGuard( m_rMutex );
443 :
444 : // Read scripting info
445 0 : Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
446 0 : sal_Int32 nObjLen = _rxInStream->readLong();
447 0 : if (nObjLen)
448 : {
449 0 : sal_Int32 nMark = xMark->createMark();
450 0 : Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
451 0 : if (xObj.is())
452 0 : xObj->read(_rxInStream);
453 0 : xMark->jumpToMark(nMark);
454 0 : _rxInStream->skipBytes(nObjLen);
455 0 : xMark->deleteMark(nMark);
456 : }
457 :
458 : // Read Attachment
459 0 : if ( m_xEventAttacher.is() )
460 : {
461 0 : OInterfaceArray::const_iterator aAttach = m_aItems.begin();
462 0 : OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
463 0 : for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
464 : {
465 0 : Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this ....
466 0 : Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
467 0 : m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
468 0 : }
469 0 : }
470 0 : }
471 :
472 :
473 0 : void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException, std::exception)
474 : {
475 0 : ::osl::MutexGuard aGuard( m_rMutex );
476 0 : sal_Int32 nLen = m_aItems.size();
477 :
478 : // Write length
479 0 : _rxOutStream->writeLong(nLen);
480 :
481 0 : if (nLen)
482 : {
483 : // 1. Version
484 0 : _rxOutStream->writeShort(0x0001);
485 :
486 : // 2. Objects
487 0 : for (sal_Int32 i = 0; i < nLen; i++)
488 : {
489 0 : Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY);
490 0 : if (xObj.is())
491 0 : _rxOutStream->writeObject(xObj);
492 : else
493 : {
494 : // Error
495 : }
496 0 : }
497 :
498 : // 3. Scripts
499 0 : writeEvents(_rxOutStream);
500 0 : }
501 0 : }
502 :
503 :
504 : namespace
505 : {
506 0 : Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XComponentContext >& _rxORB )
507 : {
508 0 : Reference< XPersistObject > xObject( _rxORB->getServiceManager()->createInstanceWithContext(FRM_COMPONENT_HIDDENCONTROL, _rxORB), UNO_QUERY );
509 : DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
510 0 : if ( xObject.is() )
511 : {
512 : // set some properties describing what we did
513 0 : Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
514 0 : if ( xObject.is() )
515 : {
516 : try
517 : {
518 0 : xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
519 0 : xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
520 : }
521 0 : catch(const Exception&)
522 : {
523 : }
524 0 : }
525 : }
526 0 : return xObject;
527 : }
528 : }
529 :
530 :
531 0 : void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException, std::exception)
532 : {
533 0 : ::osl::MutexGuard aGuard( m_rMutex );
534 :
535 : // after ::read the object is expected to be in the state it was when ::write was called, so we have
536 : // to empty ourself here
537 0 : while (getCount())
538 0 : removeByIndex(0);
539 :
540 : // Only writes depending on the length
541 0 : sal_Int32 nLen = _rxInStream->readLong();
542 :
543 0 : if (nLen)
544 : {
545 : // 1. Version
546 0 : sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
547 :
548 : // 2. Objects
549 0 : for (sal_Int32 i = 0; i < nLen; i++)
550 : {
551 0 : Reference<XPersistObject> xObj;
552 : try
553 : {
554 0 : xObj = _rxInStream->readObject();
555 : }
556 0 : catch(const WrongFormatException&)
557 : {
558 : // the object could not be read
559 : // create a object (so the readEvents below will assign the events to the right controls)
560 0 : xObj = lcl_createPlaceHolder( m_xContext );
561 0 : if ( !xObj.is() )
562 : // couldn't handle it
563 0 : throw;
564 : }
565 0 : catch(const Exception&)
566 : {
567 : // Clear the map
568 0 : while (!m_aItems.empty())
569 0 : removeElementsNoEvents(0);
570 :
571 : // Rethrow the exception
572 0 : throw;
573 : }
574 :
575 0 : if ( xObj.is() )
576 : {
577 0 : Reference< XPropertySet > xElement( xObj, UNO_QUERY );
578 : try
579 : {
580 : implInsert(
581 0 : m_aItems.size(), // position
582 : xElement, // element to insert
583 : false, // no event attacher manager handling
584 : NULL, // not yet approved - let implInsert do it
585 : true // fire the event
586 0 : );
587 : }
588 0 : catch( const Exception& )
589 : {
590 : SAL_WARN("forms.misc", "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
591 : // create a placeholder
592 0 : xElement.set(lcl_createPlaceHolder( m_xContext ), css::uno::UNO_QUERY);
593 0 : if ( !xElement.is() )
594 : // couldn't handle it
595 0 : throw;
596 : // insert the placeholder
597 0 : implInsert( m_aItems.size(), xElement, false, NULL, true );
598 0 : }
599 : }
600 0 : }
601 :
602 0 : readEvents(_rxInStream);
603 : }
604 : else
605 : {
606 : try
607 : {
608 0 : m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xContext );
609 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
610 : }
611 0 : catch( const Exception& )
612 : {
613 : DBG_UNHANDLED_EXCEPTION();
614 : }
615 0 : }
616 0 : }
617 :
618 : // XContainer
619 :
620 1096 : void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
621 : {
622 1096 : m_aContainerListeners.addInterface(_rxListener);
623 1096 : }
624 :
625 :
626 909 : void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
627 : {
628 909 : m_aContainerListeners.removeInterface(_rxListener);
629 909 : }
630 :
631 : // XEventListener
632 :
633 51 : void SAL_CALL OInterfaceContainer::disposing(const css::lang::EventObject& _rSource) throw( RuntimeException, std::exception )
634 : {
635 51 : ::osl::MutexGuard aGuard( m_rMutex );
636 :
637 102 : Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
638 : // normalized source
639 :
640 51 : OInterfaceArray::iterator j;
641 293 : for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
642 : {
643 : DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
644 : "OInterfaceContainer::disposing: vector element not normalized!" );
645 :
646 277 : if ( xSource.get() == j->get() )
647 : // found the element
648 35 : break;
649 : }
650 :
651 51 : if ( m_aItems.end() != j )
652 : {
653 35 : m_aItems.erase(j);
654 :
655 : // look up in, and erase from, m_aMap, too
656 35 : OInterfaceMap::iterator i = m_aMap.begin();
657 297 : while ( i != m_aMap.end() )
658 : {
659 : DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
660 : "OInterfaceContainer::disposing: map element not normalized!" );
661 :
662 262 : if ( i->second.get() == xSource.get() )
663 : {
664 : // found it
665 35 : m_aMap.erase(i);
666 35 : break;
667 : }
668 :
669 227 : ++i;
670 :
671 : DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
672 : }
673 51 : }
674 51 : }
675 :
676 : // XPropertyChangeListener
677 :
678 219 : void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
679 : throw (::com::sun::star::uno::RuntimeException, std::exception) {
680 219 : if (evt.PropertyName == PROPERTY_NAME)
681 : {
682 219 : ::osl::MutexGuard aGuard( m_rMutex );
683 219 : OInterfaceMap::iterator i = m_aMap.find(::comphelper::getString(evt.OldValue));
684 219 : if (i != m_aMap.end() && (*i).second != evt.Source)
685 : {
686 0 : InterfaceRef xCorrectType((*i).second);
687 0 : m_aMap.erase(i);
688 0 : m_aMap.insert(::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
689 219 : }
690 : }
691 219 : }
692 :
693 : // XElementAccess
694 :
695 655 : sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException, std::exception )
696 : {
697 655 : return !m_aMap.empty();
698 : }
699 :
700 :
701 1 : Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException, std::exception)
702 : {
703 1 : return m_aElementType;
704 : }
705 :
706 : // XEnumerationAccess
707 :
708 1 : Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException, std::exception )
709 : {
710 1 : ::osl::MutexGuard aGuard( m_rMutex );
711 1 : return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
712 : }
713 :
714 : // XNameAccess
715 :
716 10 : Any SAL_CALL OInterfaceContainer::getByName( const OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
717 : {
718 : ::std::pair <OInterfaceMap::iterator,
719 10 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
720 :
721 10 : if (aPair.first == aPair.second)
722 1 : throw NoSuchElementException();
723 :
724 9 : return (*aPair.first).second->queryInterface( m_aElementType );
725 : }
726 :
727 :
728 11 : StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException, std::exception)
729 : {
730 11 : StringSequence aNameList(m_aItems.size());
731 11 : OUString* pStringArray = aNameList.getArray();
732 :
733 33 : for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
734 : {
735 22 : *pStringArray = (*i).first;
736 : }
737 11 : return aNameList;
738 : }
739 :
740 :
741 322 : sal_Bool SAL_CALL OInterfaceContainer::hasByName( const OUString& _rName ) throw(RuntimeException, std::exception)
742 : {
743 : ::std::pair <OInterfaceMap::iterator,
744 322 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
745 322 : return aPair.first != aPair.second;
746 : }
747 :
748 : // XIndexAccess
749 :
750 4669 : sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException, std::exception )
751 : {
752 4669 : return m_aItems.size();
753 : }
754 :
755 :
756 3510 : Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
757 : {
758 3510 : if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
759 25 : throw IndexOutOfBoundsException();
760 :
761 3485 : return m_aItems[_nIndex]->queryInterface( m_aElementType );
762 : }
763 :
764 :
765 577 : void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
766 : {
767 : // it has to be non-NULL
768 577 : if ( !_rxObject.is() )
769 0 : throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
770 :
771 : // it has to support our element type interface
772 577 : Any aCorrectType = _rxObject->queryInterface( m_aElementType );
773 577 : if ( !aCorrectType.hasValue() )
774 0 : lcl_throwIllegalArgumentException();
775 :
776 : // it has to have a "Name" property
777 577 : if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
778 0 : lcl_throwIllegalArgumentException();
779 :
780 : // it has to be a child, and it must not have a parent already
781 1154 : Reference< XChild > xChild( _rxObject, UNO_QUERY );
782 577 : if ( !xChild.is() || xChild->getParent().is() )
783 : {
784 0 : lcl_throwIllegalArgumentException();
785 : }
786 :
787 : // passed all tests. cache the information we have so far
788 : DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
789 577 : if ( _pElement )
790 : {
791 577 : _pElement->xPropertySet = _rxObject;
792 577 : _pElement->xChild = xChild;
793 577 : _pElement->aElementTypeInterface = aCorrectType;
794 577 : _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
795 577 : }
796 577 : }
797 :
798 :
799 572 : void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
800 : bool _bEvents, ElementDescription* _pApprovalResult, bool _bFire ) throw( IllegalArgumentException )
801 : {
802 572 : const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
803 :
804 : // SYNCHRONIZED ----->
805 572 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
806 :
807 1144 : boost::scoped_ptr< ElementDescription > aAutoDeleteMetaData;
808 572 : ElementDescription* pElementMetaData = _pApprovalResult;
809 572 : if ( !pElementMetaData )
810 : { // not yet approved by the caller -> do ourself
811 309 : pElementMetaData = createElementMetaData();
812 : DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
813 :
814 : // ensure that the meta data structure will be deleted later on
815 309 : aAutoDeleteMetaData.reset( pElementMetaData );
816 :
817 : // will throw an exception if necessary
818 309 : approveNewElement( _rxElement, pElementMetaData );
819 : }
820 :
821 :
822 : // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
823 : // exist
824 :
825 : // set the name, and add as change listener for the name
826 1142 : OUString sName;
827 571 : _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
828 571 : _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
829 :
830 : // insert the object into our internal structures
831 571 : if (_nIndex > (sal_Int32)m_aItems.size()) // Calculate the actual index
832 : {
833 0 : _nIndex = m_aItems.size();
834 0 : m_aItems.push_back( pElementMetaData->xInterface );
835 : }
836 : else
837 571 : m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
838 :
839 571 : m_aMap.insert( ::std::pair< const OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
840 :
841 : // announce ourself as parent to the new element
842 571 : pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
843 :
844 : // handle the events
845 571 : if ( bHandleEvents )
846 : {
847 569 : m_xEventAttacher->insertEntry(_nIndex);
848 569 : m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
849 : }
850 :
851 : // notify derived classes
852 571 : implInserted( pElementMetaData );
853 :
854 571 : aGuard.clear();
855 : // <----- SYNCHRONIZED
856 :
857 : // insert faked VBA events?
858 571 : bool bHandleVbaEvents = false;
859 : try
860 : {
861 767 : _rxElement->getPropertyValue("GenerateVbaEvents") >>= bHandleVbaEvents;
862 : }
863 196 : catch( const Exception& )
864 : {
865 : }
866 571 : if ( bHandleVbaEvents )
867 : {
868 0 : Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
869 0 : OInterfaceContainer* pIfcMgr = xMgr.is() ? dynamic_cast<OInterfaceContainer*>(xMgr.get()) : NULL;
870 0 : if (pIfcMgr)
871 : {
872 0 : sal_Int32 nLen = pIfcMgr->getCount();
873 0 : for (sal_Int32 i = 0; i < nLen; ++i)
874 : {
875 : // add fake events to the control at index i
876 0 : pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
877 : }
878 : }
879 : else
880 : {
881 : // add fake events to the control at index i
882 0 : impl_addVbEvents_nolck_nothrow( _nIndex );
883 0 : }
884 : }
885 :
886 : // fire the notification about the change
887 571 : if ( _bFire )
888 : {
889 : // notify listeners
890 569 : ContainerEvent aEvt;
891 569 : aEvt.Source = static_cast<XContainer*>(this);
892 569 : aEvt.Accessor <<= _nIndex;
893 569 : aEvt.Element = pElementMetaData->aElementTypeInterface;
894 :
895 569 : aGuard.clear();
896 569 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
897 572 : }
898 571 : }
899 :
900 :
901 0 : void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
902 : {
903 0 : OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
904 0 : InterfaceRef xElement(*i);
905 :
906 0 : OInterfaceMap::iterator j = m_aMap.begin();
907 0 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
908 :
909 0 : m_aItems.erase(i);
910 0 : m_aMap.erase(j);
911 :
912 0 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
913 0 : if (xSet.is())
914 0 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
915 :
916 0 : Reference<XChild> xChild(xElement, UNO_QUERY);
917 0 : if (xChild.is())
918 0 : xChild->setParent(InterfaceRef ());
919 0 : }
920 :
921 :
922 571 : void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
923 : {
924 : // not inrerested in
925 571 : }
926 :
927 :
928 259 : void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
929 : {
930 : // not inrerested in
931 259 : }
932 :
933 :
934 6 : void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
935 : {
936 6 : _rInstanceLock.clear();
937 6 : m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
938 6 : }
939 :
940 : // XIndexContainer
941 :
942 307 : void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
943 : {
944 307 : Reference< XPropertySet > xElement;
945 307 : _rElement >>= xElement;
946 308 : implInsert( _nIndex, xElement, true /* event handling */ , NULL /* not yet approved */ , true /* notification */ );
947 306 : }
948 :
949 :
950 7 : void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
951 : {
952 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
953 :
954 : // approve the new object
955 7 : boost::scoped_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
956 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
957 : {
958 7 : Reference< XPropertySet > xElementProps;
959 7 : _rNewElement >>= xElementProps;
960 8 : approveNewElement( xElementProps, aElementMetaData.get() );
961 : }
962 :
963 : // get the old element
964 12 : InterfaceRef xOldElement( m_aItems[ _nIndex ] );
965 : DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
966 : "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
967 :
968 : // locate the old element in the map
969 6 : OInterfaceMap::iterator j = m_aMap.begin();
970 15 : while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
971 3 : ++j;
972 :
973 : // remove event knittings
974 6 : if ( m_xEventAttacher.is() )
975 : {
976 6 : InterfaceRef xNormalized( xOldElement, UNO_QUERY );
977 6 : m_xEventAttacher->detach( _nIndex, xNormalized );
978 6 : m_xEventAttacher->removeEntry( _nIndex );
979 : }
980 :
981 : // don't listen for property changes anymore
982 12 : Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
983 6 : if (xSet.is())
984 6 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
985 :
986 : // give the old element a new (void) parent
987 12 : Reference<XChild> xChild(xOldElement, UNO_QUERY);
988 6 : if (xChild.is())
989 6 : xChild->setParent(InterfaceRef ());
990 :
991 : // remove the old one
992 6 : m_aMap.erase(j);
993 :
994 : // examine the new element
995 12 : OUString sName;
996 : DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
997 :
998 6 : aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
999 6 : aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1000 :
1001 : // insert the new one
1002 6 : m_aMap.insert( ::std::pair<const OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1003 6 : m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1004 :
1005 6 : aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1006 :
1007 6 : if ( m_xEventAttacher.is() )
1008 : {
1009 6 : m_xEventAttacher->insertEntry( _nIndex );
1010 6 : m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1011 : }
1012 :
1013 12 : ContainerEvent aReplaceEvent;
1014 6 : aReplaceEvent.Source = static_cast< XContainer* >( this );
1015 6 : aReplaceEvent.Accessor <<= _nIndex;
1016 6 : aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1017 6 : aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1018 :
1019 13 : impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1020 6 : }
1021 :
1022 :
1023 264 : void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex )
1024 : {
1025 264 : if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1026 2 : throw IndexOutOfBoundsException();
1027 262 : }
1028 :
1029 :
1030 4 : void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1031 : {
1032 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1033 : // check the index
1034 4 : implCheckIndex( _nIndex );
1035 : // do the replace
1036 5 : implReplaceByIndex( _nIndex, Element, aGuard );
1037 2 : }
1038 :
1039 :
1040 259 : void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1041 : {
1042 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1043 :
1044 259 : OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1045 259 : InterfaceRef xElement(*i);
1046 :
1047 259 : OInterfaceMap::iterator j = m_aMap.begin();
1048 259 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
1049 :
1050 259 : m_aItems.erase(i);
1051 259 : m_aMap.erase(j);
1052 :
1053 : // remove event knittings
1054 259 : if ( m_xEventAttacher.is() )
1055 : {
1056 259 : InterfaceRef xNormalized( xElement, UNO_QUERY );
1057 259 : m_xEventAttacher->detach( _nIndex, xNormalized );
1058 259 : m_xEventAttacher->removeEntry( _nIndex );
1059 : }
1060 :
1061 518 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1062 259 : if (xSet.is())
1063 259 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1064 :
1065 518 : Reference<XChild> xChild(xElement, UNO_QUERY);
1066 259 : if (xChild.is())
1067 259 : xChild->setParent(InterfaceRef ());
1068 :
1069 : // notify derived classes
1070 259 : implRemoved(xElement);
1071 :
1072 : // notify listeners
1073 518 : ContainerEvent aEvt;
1074 259 : aEvt.Source = static_cast<XContainer*>(this);
1075 259 : aEvt.Element = xElement->queryInterface( m_aElementType );
1076 259 : aEvt.Accessor <<= _nIndex;
1077 :
1078 259 : _rClearBeforeNotify.clear();
1079 518 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1080 259 : }
1081 :
1082 :
1083 260 : void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1084 : {
1085 260 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1086 : // check the index
1087 260 : implCheckIndex( _nIndex );
1088 : // do the removal
1089 260 : implRemoveByIndex( _nIndex, aGuard );
1090 259 : }
1091 :
1092 :
1093 522 : ElementDescription* OInterfaceContainer::createElementMetaData( )
1094 : {
1095 522 : return new ElementDescription;
1096 : }
1097 :
1098 :
1099 264 : void SAL_CALL OInterfaceContainer::insertByName(const OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
1100 : {
1101 264 : Reference< XPropertySet > xElementProps;
1102 :
1103 528 : boost::scoped_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1104 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1105 :
1106 : // ensure the correct name of the element
1107 : try
1108 : {
1109 264 : _rElement >>= xElementProps;
1110 264 : approveNewElement( xElementProps, aElementMetaData.get() );
1111 :
1112 263 : xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1113 : }
1114 2 : catch( const IllegalArgumentException& )
1115 : {
1116 1 : throw; // allowed to leave
1117 : }
1118 0 : catch( const ElementExistException& )
1119 : {
1120 0 : throw; // allowed to leave
1121 : }
1122 0 : catch( const Exception& )
1123 : {
1124 : SAL_WARN("forms.misc", "OInterfaceContainer::insertByName: caught an exception!" );
1125 : }
1126 527 : implInsert( m_aItems.size(), xElementProps, true, aElementMetaData.get(), true );
1127 263 : }
1128 :
1129 :
1130 4 : void SAL_CALL OInterfaceContainer::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1131 : {
1132 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1133 : ::std::pair <OInterfaceMap::iterator,
1134 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1135 4 : if (aPair.first == aPair.second)
1136 0 : throw NoSuchElementException();
1137 :
1138 4 : if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1139 0 : lcl_throwIllegalArgumentException();
1140 :
1141 8 : Reference<XPropertySet> xSet;
1142 4 : Element >>= xSet;
1143 4 : if (xSet.is())
1144 : {
1145 4 : if (!hasProperty(PROPERTY_NAME, xSet))
1146 0 : lcl_throwIllegalArgumentException();
1147 :
1148 4 : xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1149 : }
1150 :
1151 : // determine the element pos
1152 4 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1153 :
1154 8 : implReplaceByIndex( nPos, Element, aGuard );
1155 4 : }
1156 :
1157 :
1158 4 : void SAL_CALL OInterfaceContainer::removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1159 : {
1160 4 : ::osl::MutexGuard aGuard( m_rMutex );
1161 : ::std::pair <OInterfaceMap::iterator,
1162 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1163 4 : if (aPair.first == aPair.second)
1164 1 : throw NoSuchElementException();
1165 :
1166 3 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1167 4 : removeByIndex(nPos);
1168 3 : }
1169 :
1170 :
1171 : // XEventAttacherManager
1172 :
1173 3 : void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException, std::exception)
1174 : {
1175 3 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1176 3 : if ( m_xEventAttacher.is() )
1177 : {
1178 3 : m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1179 3 : aGuard.clear();
1180 3 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1181 3 : }
1182 3 : }
1183 :
1184 :
1185 263 : void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException, std::exception)
1186 : {
1187 263 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1188 263 : if ( m_xEventAttacher.is() )
1189 : {
1190 263 : m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1191 263 : aGuard.clear();
1192 263 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1193 263 : }
1194 263 : }
1195 :
1196 :
1197 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const OUString& aListenerType, const OUString& aEventMethod, const OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException, std::exception)
1198 : {
1199 1 : if ( m_xEventAttacher.is() )
1200 1 : m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1201 1 : }
1202 :
1203 :
1204 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1205 : {
1206 1 : if ( m_xEventAttacher.is() )
1207 1 : m_xEventAttacher->revokeScriptEvents( nIndex );
1208 1 : }
1209 :
1210 :
1211 1 : void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1212 : {
1213 1 : if ( m_xEventAttacher.is() )
1214 1 : m_xEventAttacher->insertEntry( nIndex );
1215 1 : }
1216 :
1217 :
1218 1 : void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1219 : {
1220 1 : if ( m_xEventAttacher.is() )
1221 1 : m_xEventAttacher->removeEntry( nIndex );
1222 1 : }
1223 :
1224 :
1225 17 : Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1226 : {
1227 17 : Sequence< ScriptEventDescriptor > aReturn;
1228 17 : if ( m_xEventAttacher.is() )
1229 : {
1230 17 : aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1231 17 : if ( lcl_hasVbaEvents( aReturn ) )
1232 : {
1233 0 : aReturn = lcl_stripVbaEvents( aReturn );
1234 : }
1235 : }
1236 17 : return aReturn;
1237 : }
1238 :
1239 :
1240 183 : void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException, std::exception)
1241 : {
1242 183 : if ( m_xEventAttacher.is() )
1243 183 : m_xEventAttacher->attach( nIndex, xObject, aHelper );
1244 183 : }
1245 :
1246 :
1247 183 : void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException, std::exception)
1248 : {
1249 183 : if ( m_xEventAttacher.is() )
1250 183 : m_xEventAttacher->detach( nIndex, xObject );
1251 183 : }
1252 :
1253 :
1254 1185 : void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1255 : {
1256 1185 : if ( m_xEventAttacher.is() )
1257 1185 : m_xEventAttacher->addScriptListener( xListener );
1258 1185 : }
1259 :
1260 :
1261 1181 : void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1262 : {
1263 1181 : if ( m_xEventAttacher.is() )
1264 1181 : m_xEventAttacher->removeScriptListener( xListener );
1265 1181 : }
1266 :
1267 :
1268 : //= OFormComponents
1269 :
1270 :
1271 6514 : Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException, std::exception)
1272 : {
1273 6514 : Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1274 6514 : if (!aReturn.hasValue())
1275 : {
1276 6506 : aReturn = OInterfaceContainer::queryInterface(_rType);
1277 :
1278 6506 : if (!aReturn.hasValue())
1279 2888 : aReturn = FormComponentsBase::queryAggregation(_rType);
1280 : }
1281 :
1282 6514 : return aReturn;
1283 : }
1284 :
1285 :
1286 0 : Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException, std::exception)
1287 : {
1288 0 : return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1289 : }
1290 :
1291 :
1292 192 : OFormComponents::OFormComponents(const Reference<XComponentContext>& _rxFactory)
1293 : :FormComponentsBase( m_aMutex )
1294 192 : ,OInterfaceContainer( _rxFactory, m_aMutex, cppu::UnoType<XFormComponent>::get() )
1295 384 : ,OFormComponents_BASE()
1296 : {
1297 192 : }
1298 :
1299 :
1300 0 : OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1301 : :FormComponentsBase( m_aMutex )
1302 : ,OInterfaceContainer( m_aMutex, _cloneSource )
1303 0 : ,OFormComponents_BASE()
1304 : {
1305 0 : }
1306 :
1307 :
1308 380 : OFormComponents::~OFormComponents()
1309 : {
1310 190 : if (!FormComponentsBase::rBHelper.bDisposed)
1311 : {
1312 8 : acquire();
1313 8 : dispose();
1314 : }
1315 190 : }
1316 :
1317 : // OComponentHelper
1318 :
1319 191 : void OFormComponents::disposing()
1320 : {
1321 191 : OInterfaceContainer::disposing();
1322 191 : FormComponentsBase::disposing();
1323 191 : m_xParent = NULL;
1324 191 : }
1325 :
1326 : //XChild
1327 :
1328 181 : void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException, std::exception )
1329 : {
1330 181 : ::osl::MutexGuard aGuard( m_aMutex );
1331 181 : m_xParent = Parent;
1332 181 : }
1333 :
1334 :
1335 1726 : InterfaceRef OFormComponents::getParent() throw( RuntimeException, std::exception )
1336 : {
1337 1726 : return m_xParent;
1338 : }
1339 :
1340 :
1341 : } // namespace frm
1342 :
1343 :
1344 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|