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 28 : lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
83 : {
84 28 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
85 28 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
86 40 : for ( ; pDesc != pEnd; ++pDesc )
87 : {
88 12 : if ( pDesc->ScriptType == "VBAInterop" )
89 0 : return true;
90 : }
91 28 : 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 488 : 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 488 : Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
122 488 : if ( !xDoc.is() )
123 0 : break;
124 :
125 500 : Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
126 490 : Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance("ooo.vba.VBACodeNameProvider"), UNO_QUERY );
127 478 : if ( !xNameQuery.is() )
128 476 : break;
129 :
130 4 : ::osl::MutexGuard aGuard( m_rMutex );
131 2 : bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
132 2 : if ( hasVBABindings )
133 0 : break;
134 :
135 4 : Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
136 4 : Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
137 2 : 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 4 : Reference<XInterface> xThis = static_cast<XContainer*>(this);
143 4 : OUString sCodeName = xNameQuery->getCodeNameForContainer(xThis);
144 2 : if (sCodeName.isEmpty())
145 0 : sCodeName = xNameQuery->getCodeNameForObject(xElement);
146 :
147 4 : Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
148 4 : OUString sServiceName;
149 2 : xProps->getPropertyValue("DefaultControl") >>= sServiceName;
150 :
151 4 : Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xContext->getServiceManager()->createInstanceWithContext("ooo.vba.VBAToOOEventDesc", m_xContext), UNO_QUERY_THROW );
152 4 : Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( sServiceName , sCodeName );
153 :
154 : // register the vba script events
155 14 : m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
156 : }
157 : while ( false );
158 : }
159 10 : catch ( const ServiceNotRegisteredException& )
160 : {
161 : // silence this, not all document types support the ooo.vba.VBACodeNameProvider service
162 : }
163 0 : catch( const Exception& )
164 : {
165 : DBG_UNHANDLED_EXCEPTION();
166 : }
167 :
168 488 : }
169 :
170 1056 : ElementDescription::ElementDescription( )
171 : {
172 1056 : }
173 :
174 :
175 1996 : ElementDescription::~ElementDescription()
176 : {
177 1996 : }
178 :
179 1098 : 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 1098 : ,m_xContext(_rxContext)
188 : {
189 1098 : impl_createEventAttacher_nothrow();
190 1098 : }
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 1098 : void OInterfaceContainer::impl_createEventAttacher_nothrow()
231 : {
232 : try
233 : {
234 1098 : m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xContext ), UNO_SET_THROW );
235 : }
236 0 : catch( const Exception& )
237 : {
238 : DBG_UNHANDLED_EXCEPTION();
239 : }
240 1098 : }
241 :
242 :
243 1090 : OInterfaceContainer::~OInterfaceContainer()
244 : {
245 1090 : }
246 :
247 :
248 1092 : void OInterfaceContainer::disposing()
249 : {
250 : // dispose all elements
251 1626 : for (sal_Int32 i = m_aItems.size(); i > 0; --i)
252 : {
253 534 : Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
254 534 : if (xSet.is())
255 534 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
256 :
257 : // revoke event knittings
258 534 : if ( m_xEventAttacher.is() )
259 : {
260 534 : m_xEventAttacher->detach( i - 1, Reference<XInterface>(xSet, UNO_QUERY) );
261 534 : m_xEventAttacher->removeEntry( i - 1 );
262 : }
263 :
264 1068 : Reference<XComponent> xComponent(xSet, UNO_QUERY);
265 534 : if (xComponent.is())
266 534 : xComponent->dispose();
267 534 : }
268 1092 : m_aMap.clear();
269 1092 : m_aItems.clear();
270 :
271 1092 : css::lang::EventObject aEvt(static_cast<XContainer*>(this));
272 1092 : m_aContainerListeners.disposeAndClear(aEvt);
273 1092 : }
274 :
275 : // XPersistObject
276 :
277 : namespace
278 : {
279 :
280 2 : 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 2 : if ( !_rxManager.is() )
285 2 : return;
286 :
287 : // reserve the space needed
288 2 : _rSave.reserve( _nItemCount );
289 :
290 : // copy the events
291 6 : for (sal_Int32 i=0; i<_nItemCount; ++i)
292 4 : _rSave.push_back(_rxManager->getScriptEvents( i ));
293 : }
294 :
295 :
296 2 : 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 2 : if ( !_rxManager.is() )
301 2 : return;
302 :
303 2 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
304 2 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
305 6 : for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
306 : {
307 4 : _rxManager->revokeScriptEvents( i );
308 4 : _rxManager->registerScriptEvents( i, *aLoop );
309 : }
310 : }
311 : }
312 :
313 :
314 2 : 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 2 : ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
320 2 : if ( m_xEventAttacher.is() )
321 2 : lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
322 :
323 2 : transformEvents( efVersionSO5x );
324 :
325 : try
326 : {
327 2 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
328 2 : sal_Int32 nMark = xMark->createMark();
329 :
330 2 : sal_Int32 nObjLen = 0;
331 2 : _rxOutStream->writeLong(nObjLen);
332 :
333 4 : Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
334 2 : if (xScripts.is())
335 2 : xScripts->write(_rxOutStream);
336 :
337 : // Determine length
338 2 : nObjLen = xMark->offsetToMark(nMark) - 4;
339 2 : xMark->jumpToMark(nMark);
340 2 : _rxOutStream->writeLong(nObjLen);
341 2 : xMark->jumpToFurthest();
342 4 : 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 2 : if ( m_xEventAttacher.is() )
354 2 : lcl_restoreEvents( aSave, m_xEventAttacher );
355 2 : }
356 :
357 :
358 : struct TransformEventTo52Format : public ::std::unary_function< ScriptEventDescriptor, void >
359 : {
360 0 : void operator()( ScriptEventDescriptor& _rDescriptor )
361 : {
362 0 : if ( _rDescriptor.ScriptType.equalsAscii( "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.equalsAscii( "document" )
370 : || sPrefix.equalsAscii( "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.equalsAscii( "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 2 : void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
398 : {
399 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
400 2 : if ( !m_xEventAttacher.is() )
401 2 : return;
402 :
403 : try
404 : {
405 : // loop through all our children
406 2 : sal_Int32 nItems = m_aItems.size();
407 2 : Sequence< ScriptEventDescriptor > aChildEvents;
408 :
409 6 : for (sal_Int32 i=0; i<nItems; ++i)
410 : {
411 : // get the script events for this object
412 4 : aChildEvents = m_xEventAttacher->getScriptEvents( i );
413 :
414 4 : 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 2 : }
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 Attachement
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 1889 : void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
621 : {
622 1889 : m_aContainerListeners.addInterface(_rxListener);
623 1889 : }
624 :
625 :
626 1559 : void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
627 : {
628 1559 : m_aContainerListeners.removeInterface(_rxListener);
629 1559 : }
630 :
631 : // XEventListener
632 :
633 102 : void SAL_CALL OInterfaceContainer::disposing(const css::lang::EventObject& _rSource) throw( RuntimeException, std::exception )
634 : {
635 102 : ::osl::MutexGuard aGuard( m_rMutex );
636 :
637 204 : Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
638 : // normalized source
639 :
640 102 : OInterfaceArray::iterator j;
641 586 : 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 554 : if ( xSource.get() == j->get() )
647 : // found the element
648 70 : break;
649 : }
650 :
651 102 : if ( m_aItems.end() != j )
652 : {
653 70 : m_aItems.erase(j);
654 :
655 : // look up in, and erase from, m_aMap, too
656 70 : OInterfaceMap::iterator i = m_aMap.begin();
657 556 : 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 486 : if ( i->second.get() == xSource.get() )
663 : {
664 : // found it
665 70 : m_aMap.erase(i);
666 70 : break;
667 : }
668 :
669 416 : ++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 102 : }
674 102 : }
675 :
676 : // XPropertyChangeListener
677 :
678 463 : void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
679 : throw (::com::sun::star::uno::RuntimeException, std::exception) {
680 463 : if (evt.PropertyName == PROPERTY_NAME)
681 : {
682 463 : ::osl::MutexGuard aGuard( m_rMutex );
683 : OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
684 463 : ::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
685 463 : if (i != m_aMap.end())
686 : {
687 463 : InterfaceRef xCorrectType((*i).second);
688 463 : m_aMap.erase(i);
689 463 : m_aMap.insert(::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
690 463 : }
691 : }
692 463 : }
693 :
694 : // XElementAccess
695 :
696 840 : sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException, std::exception )
697 : {
698 840 : return !m_aMap.empty();
699 : }
700 :
701 :
702 2 : Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException, std::exception)
703 : {
704 2 : return m_aElementType;
705 : }
706 :
707 : // XEnumerationAccess
708 :
709 2 : Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException, std::exception )
710 : {
711 2 : ::osl::MutexGuard aGuard( m_rMutex );
712 2 : return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
713 : }
714 :
715 : // XNameAccess
716 :
717 20 : Any SAL_CALL OInterfaceContainer::getByName( const OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
718 : {
719 : ::std::pair <OInterfaceMap::iterator,
720 20 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
721 :
722 20 : if (aPair.first == aPair.second)
723 2 : throw NoSuchElementException();
724 :
725 18 : return (*aPair.first).second->queryInterface( m_aElementType );
726 : }
727 :
728 :
729 22 : StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException, std::exception)
730 : {
731 22 : StringSequence aNameList(m_aItems.size());
732 22 : OUString* pStringArray = aNameList.getArray();
733 :
734 66 : for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
735 : {
736 44 : *pStringArray = (*i).first;
737 : }
738 22 : return aNameList;
739 : }
740 :
741 :
742 576 : sal_Bool SAL_CALL OInterfaceContainer::hasByName( const OUString& _rName ) throw(RuntimeException, std::exception)
743 : {
744 : ::std::pair <OInterfaceMap::iterator,
745 576 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
746 576 : return aPair.first != aPair.second;
747 : }
748 :
749 : // XIndexAccess
750 :
751 7805 : sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException, std::exception )
752 : {
753 7805 : return m_aItems.size();
754 : }
755 :
756 :
757 5765 : Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
758 : {
759 5765 : if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
760 50 : throw IndexOutOfBoundsException();
761 :
762 5715 : return m_aItems[_nIndex]->queryInterface( m_aElementType );
763 : }
764 :
765 :
766 1050 : void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
767 : {
768 : // it has to be non-NULL
769 1050 : if ( !_rxObject.is() )
770 0 : throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
771 :
772 : // it has to support our element type interface
773 1050 : Any aCorrectType = _rxObject->queryInterface( m_aElementType );
774 1050 : if ( !aCorrectType.hasValue() )
775 0 : lcl_throwIllegalArgumentException();
776 :
777 : // it has to have a "Name" property
778 1050 : if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
779 0 : lcl_throwIllegalArgumentException();
780 :
781 : // it has to be a child, and it must not have a parent already
782 2100 : Reference< XChild > xChild( _rxObject, UNO_QUERY );
783 1050 : if ( !xChild.is() || xChild->getParent().is() )
784 : {
785 0 : lcl_throwIllegalArgumentException();
786 : }
787 :
788 : // passed all tests. cache the information we have so far
789 : DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
790 1050 : if ( _pElement )
791 : {
792 1050 : _pElement->xPropertySet = _rxObject;
793 1050 : _pElement->xChild = xChild;
794 1050 : _pElement->aElementTypeInterface = aCorrectType;
795 1050 : _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
796 1050 : }
797 1050 : }
798 :
799 :
800 1040 : void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
801 : bool _bEvents, ElementDescription* _pApprovalResult, bool _bFire ) throw( IllegalArgumentException )
802 : {
803 1040 : const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
804 :
805 : // SYNCHRONIZED ----->
806 1040 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
807 :
808 2080 : boost::scoped_ptr< ElementDescription > aAutoDeleteMetaData;
809 1040 : ElementDescription* pElementMetaData = _pApprovalResult;
810 1040 : if ( !pElementMetaData )
811 : { // not yet approved by the caller -> do ourself
812 574 : pElementMetaData = createElementMetaData();
813 : DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
814 :
815 : // ensure that the meta data structure will be deleted later on
816 574 : aAutoDeleteMetaData.reset( pElementMetaData );
817 :
818 : // will throw an exception if necessary
819 574 : approveNewElement( _rxElement, pElementMetaData );
820 : }
821 :
822 :
823 : // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
824 : // exist
825 :
826 : // set the name, and add as change listener for the name
827 2076 : OUString sName;
828 1038 : _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
829 1038 : _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
830 :
831 : // insert the object into our internal structures
832 1038 : if (_nIndex > (sal_Int32)m_aItems.size()) // Calculate the actual index
833 : {
834 0 : _nIndex = m_aItems.size();
835 0 : m_aItems.push_back( pElementMetaData->xInterface );
836 : }
837 : else
838 1038 : m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
839 :
840 1038 : m_aMap.insert( ::std::pair< const OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
841 :
842 : // announce ourself as parent to the new element
843 1038 : pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
844 :
845 : // handle the events
846 1038 : if ( bHandleEvents )
847 : {
848 1034 : m_xEventAttacher->insertEntry(_nIndex);
849 1034 : m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
850 : }
851 :
852 : // notify derived classes
853 1038 : implInserted( pElementMetaData );
854 :
855 1038 : aGuard.clear();
856 : // <----- SYNCHRONIZED
857 :
858 : // insert faked VBA events?
859 1038 : bool bHandleVbaEvents = false;
860 : try
861 : {
862 1390 : _rxElement->getPropertyValue("GenerateVbaEvents") >>= bHandleVbaEvents;
863 : }
864 352 : catch( const Exception& )
865 : {
866 : }
867 1038 : if ( bHandleVbaEvents )
868 : {
869 0 : Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
870 0 : OInterfaceContainer* pIfcMgr = xMgr.is() ? dynamic_cast<OInterfaceContainer*>(xMgr.get()) : NULL;
871 0 : if (pIfcMgr)
872 : {
873 0 : sal_Int32 nLen = pIfcMgr->getCount();
874 0 : for (sal_Int32 i = 0; i < nLen; ++i)
875 : {
876 : // add fake events to the control at index i
877 0 : pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
878 : }
879 : }
880 : else
881 : {
882 : // add fake events to the control at index i
883 0 : impl_addVbEvents_nolck_nothrow( _nIndex );
884 0 : }
885 : }
886 :
887 : // fire the notification about the change
888 1038 : if ( _bFire )
889 : {
890 : // notify listeners
891 1034 : ContainerEvent aEvt;
892 1034 : aEvt.Source = static_cast<XContainer*>(this);
893 1034 : aEvt.Accessor <<= _nIndex;
894 1034 : aEvt.Element = pElementMetaData->aElementTypeInterface;
895 :
896 1034 : aGuard.clear();
897 1034 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
898 1040 : }
899 1038 : }
900 :
901 :
902 0 : void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
903 : {
904 0 : OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
905 0 : InterfaceRef xElement(*i);
906 :
907 0 : OInterfaceMap::iterator j = m_aMap.begin();
908 0 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
909 :
910 0 : m_aItems.erase(i);
911 0 : m_aMap.erase(j);
912 :
913 0 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
914 0 : if (xSet.is())
915 0 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
916 :
917 0 : Reference<XChild> xChild(xElement, UNO_QUERY);
918 0 : if (xChild.is())
919 0 : xChild->setParent(InterfaceRef ());
920 0 : }
921 :
922 :
923 1038 : void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
924 : {
925 : // not inrerested in
926 1038 : }
927 :
928 :
929 460 : void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
930 : {
931 : // not inrerested in
932 460 : }
933 :
934 :
935 12 : void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
936 : {
937 12 : _rInstanceLock.clear();
938 12 : m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
939 12 : }
940 :
941 : // XIndexContainer
942 :
943 570 : void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
944 : {
945 570 : Reference< XPropertySet > xElement;
946 570 : _rElement >>= xElement;
947 572 : implInsert( _nIndex, xElement, true /* event handling */ , NULL /* not yet approved */ , true /* notification */ );
948 568 : }
949 :
950 :
951 14 : void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
952 : {
953 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
954 :
955 : // approve the new object
956 14 : boost::scoped_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
957 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
958 : {
959 14 : Reference< XPropertySet > xElementProps;
960 14 : _rNewElement >>= xElementProps;
961 16 : approveNewElement( xElementProps, aElementMetaData.get() );
962 : }
963 :
964 : // get the old element
965 24 : InterfaceRef xOldElement( m_aItems[ _nIndex ] );
966 : DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
967 : "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
968 :
969 : // locate the old element in the map
970 12 : OInterfaceMap::iterator j = m_aMap.begin();
971 26 : while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
972 2 : ++j;
973 :
974 : // remove event knittings
975 12 : if ( m_xEventAttacher.is() )
976 : {
977 12 : InterfaceRef xNormalized( xOldElement, UNO_QUERY );
978 12 : m_xEventAttacher->detach( _nIndex, xNormalized );
979 12 : m_xEventAttacher->removeEntry( _nIndex );
980 : }
981 :
982 : // don't listen for property changes anymore
983 24 : Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
984 12 : if (xSet.is())
985 12 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
986 :
987 : // give the old element a new (void) parent
988 24 : Reference<XChild> xChild(xOldElement, UNO_QUERY);
989 12 : if (xChild.is())
990 12 : xChild->setParent(InterfaceRef ());
991 :
992 : // remove the old one
993 12 : m_aMap.erase(j);
994 :
995 : // examine the new element
996 24 : OUString sName;
997 : DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
998 :
999 12 : aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1000 12 : aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1001 :
1002 : // insert the new one
1003 12 : m_aMap.insert( ::std::pair<const OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1004 12 : m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1005 :
1006 12 : aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1007 :
1008 12 : if ( m_xEventAttacher.is() )
1009 : {
1010 12 : m_xEventAttacher->insertEntry( _nIndex );
1011 12 : m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1012 : }
1013 :
1014 24 : ContainerEvent aReplaceEvent;
1015 12 : aReplaceEvent.Source = static_cast< XContainer* >( this );
1016 12 : aReplaceEvent.Accessor <<= _nIndex;
1017 12 : aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1018 12 : aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1019 :
1020 26 : impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1021 12 : }
1022 :
1023 :
1024 470 : void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex )
1025 : {
1026 470 : if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1027 4 : throw IndexOutOfBoundsException();
1028 466 : }
1029 :
1030 :
1031 8 : void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1032 : {
1033 8 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1034 : // check the index
1035 8 : implCheckIndex( _nIndex );
1036 : // do the replace
1037 10 : implReplaceByIndex( _nIndex, Element, aGuard );
1038 4 : }
1039 :
1040 :
1041 460 : void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1042 : {
1043 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1044 :
1045 460 : OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1046 460 : InterfaceRef xElement(*i);
1047 :
1048 460 : OInterfaceMap::iterator j = m_aMap.begin();
1049 460 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
1050 :
1051 460 : m_aItems.erase(i);
1052 460 : m_aMap.erase(j);
1053 :
1054 : // remove event knittings
1055 460 : if ( m_xEventAttacher.is() )
1056 : {
1057 460 : InterfaceRef xNormalized( xElement, UNO_QUERY );
1058 460 : m_xEventAttacher->detach( _nIndex, xNormalized );
1059 460 : m_xEventAttacher->removeEntry( _nIndex );
1060 : }
1061 :
1062 920 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1063 460 : if (xSet.is())
1064 460 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1065 :
1066 920 : Reference<XChild> xChild(xElement, UNO_QUERY);
1067 460 : if (xChild.is())
1068 460 : xChild->setParent(InterfaceRef ());
1069 :
1070 : // notify derived classes
1071 460 : implRemoved(xElement);
1072 :
1073 : // notify listeners
1074 920 : ContainerEvent aEvt;
1075 460 : aEvt.Source = static_cast<XContainer*>(this);
1076 460 : aEvt.Element = xElement->queryInterface( m_aElementType );
1077 460 : aEvt.Accessor <<= _nIndex;
1078 :
1079 460 : _rClearBeforeNotify.clear();
1080 920 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1081 460 : }
1082 :
1083 :
1084 462 : void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1085 : {
1086 462 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1087 : // check the index
1088 462 : implCheckIndex( _nIndex );
1089 : // do the removal
1090 462 : implRemoveByIndex( _nIndex, aGuard );
1091 460 : }
1092 :
1093 :
1094 940 : ElementDescription* OInterfaceContainer::createElementMetaData( )
1095 : {
1096 940 : return new ElementDescription;
1097 : }
1098 :
1099 :
1100 468 : void SAL_CALL OInterfaceContainer::insertByName(const OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
1101 : {
1102 468 : Reference< XPropertySet > xElementProps;
1103 :
1104 936 : boost::scoped_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1105 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1106 :
1107 : // ensure the correct name of the element
1108 : try
1109 : {
1110 468 : _rElement >>= xElementProps;
1111 468 : approveNewElement( xElementProps, aElementMetaData.get() );
1112 :
1113 466 : xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1114 : }
1115 4 : catch( const IllegalArgumentException& )
1116 : {
1117 2 : throw; // allowed to leave
1118 : }
1119 0 : catch( const ElementExistException& )
1120 : {
1121 0 : throw; // allowed to leave
1122 : }
1123 0 : catch( const Exception& )
1124 : {
1125 : SAL_WARN("forms.misc", "OInterfaceContainer::insertByName: caught an exception!" );
1126 : }
1127 934 : implInsert( m_aItems.size(), xElementProps, true, aElementMetaData.get(), true );
1128 466 : }
1129 :
1130 :
1131 8 : void SAL_CALL OInterfaceContainer::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1132 : {
1133 8 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1134 : ::std::pair <OInterfaceMap::iterator,
1135 8 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1136 8 : if (aPair.first == aPair.second)
1137 0 : throw NoSuchElementException();
1138 :
1139 8 : if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1140 0 : lcl_throwIllegalArgumentException();
1141 :
1142 16 : Reference<XPropertySet> xSet;
1143 8 : Element >>= xSet;
1144 8 : if (xSet.is())
1145 : {
1146 8 : if (!hasProperty(PROPERTY_NAME, xSet))
1147 0 : lcl_throwIllegalArgumentException();
1148 :
1149 8 : xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1150 : }
1151 :
1152 : // determine the element pos
1153 8 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1154 :
1155 16 : implReplaceByIndex( nPos, Element, aGuard );
1156 8 : }
1157 :
1158 :
1159 8 : void SAL_CALL OInterfaceContainer::removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1160 : {
1161 8 : ::osl::MutexGuard aGuard( m_rMutex );
1162 : ::std::pair <OInterfaceMap::iterator,
1163 8 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1164 8 : if (aPair.first == aPair.second)
1165 2 : throw NoSuchElementException();
1166 :
1167 6 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1168 8 : removeByIndex(nPos);
1169 6 : }
1170 :
1171 :
1172 : // XEventAttacherManager
1173 :
1174 6 : void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException, std::exception)
1175 : {
1176 6 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1177 6 : if ( m_xEventAttacher.is() )
1178 : {
1179 6 : m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1180 6 : aGuard.clear();
1181 6 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1182 6 : }
1183 6 : }
1184 :
1185 :
1186 482 : void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException, std::exception)
1187 : {
1188 482 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1189 482 : if ( m_xEventAttacher.is() )
1190 : {
1191 482 : m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1192 482 : aGuard.clear();
1193 482 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1194 482 : }
1195 482 : }
1196 :
1197 :
1198 2 : void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const OUString& aListenerType, const OUString& aEventMethod, const OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException, std::exception)
1199 : {
1200 2 : if ( m_xEventAttacher.is() )
1201 2 : m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1202 2 : }
1203 :
1204 :
1205 2 : void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1206 : {
1207 2 : if ( m_xEventAttacher.is() )
1208 2 : m_xEventAttacher->revokeScriptEvents( nIndex );
1209 2 : }
1210 :
1211 :
1212 2 : void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1213 : {
1214 2 : if ( m_xEventAttacher.is() )
1215 2 : m_xEventAttacher->insertEntry( nIndex );
1216 2 : }
1217 :
1218 :
1219 2 : void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1220 : {
1221 2 : if ( m_xEventAttacher.is() )
1222 2 : m_xEventAttacher->removeEntry( nIndex );
1223 2 : }
1224 :
1225 :
1226 26 : Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1227 : {
1228 26 : Sequence< ScriptEventDescriptor > aReturn;
1229 26 : if ( m_xEventAttacher.is() )
1230 : {
1231 26 : aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1232 26 : if ( lcl_hasVbaEvents( aReturn ) )
1233 : {
1234 0 : aReturn = lcl_stripVbaEvents( aReturn );
1235 : }
1236 : }
1237 26 : return aReturn;
1238 : }
1239 :
1240 :
1241 298 : void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException, std::exception)
1242 : {
1243 298 : if ( m_xEventAttacher.is() )
1244 298 : m_xEventAttacher->attach( nIndex, xObject, aHelper );
1245 298 : }
1246 :
1247 :
1248 298 : void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException, std::exception)
1249 : {
1250 298 : if ( m_xEventAttacher.is() )
1251 298 : m_xEventAttacher->detach( nIndex, xObject );
1252 298 : }
1253 :
1254 :
1255 1898 : void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1256 : {
1257 1898 : if ( m_xEventAttacher.is() )
1258 1898 : m_xEventAttacher->addScriptListener( xListener );
1259 1898 : }
1260 :
1261 :
1262 1894 : void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1263 : {
1264 1894 : if ( m_xEventAttacher.is() )
1265 1894 : m_xEventAttacher->removeScriptListener( xListener );
1266 1894 : }
1267 :
1268 :
1269 : //= OFormComponents
1270 :
1271 :
1272 11636 : Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException, std::exception)
1273 : {
1274 11636 : Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1275 11636 : if (!aReturn.hasValue())
1276 : {
1277 11500 : aReturn = OInterfaceContainer::queryInterface(_rType);
1278 :
1279 11500 : if (!aReturn.hasValue())
1280 5144 : aReturn = FormComponentsBase::queryAggregation(_rType);
1281 : }
1282 :
1283 11636 : return aReturn;
1284 : }
1285 :
1286 :
1287 0 : Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException, std::exception)
1288 : {
1289 0 : return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1290 : }
1291 :
1292 :
1293 462 : OFormComponents::OFormComponents(const Reference<XComponentContext>& _rxFactory)
1294 : :FormComponentsBase( m_aMutex )
1295 462 : ,OInterfaceContainer( _rxFactory, m_aMutex, cppu::UnoType<XFormComponent>::get() )
1296 924 : ,OFormComponents_BASE()
1297 : {
1298 462 : }
1299 :
1300 :
1301 0 : OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1302 : :FormComponentsBase( m_aMutex )
1303 : ,OInterfaceContainer( m_aMutex, _cloneSource )
1304 0 : ,OFormComponents_BASE()
1305 : {
1306 0 : }
1307 :
1308 :
1309 916 : OFormComponents::~OFormComponents()
1310 : {
1311 458 : if (!FormComponentsBase::rBHelper.bDisposed)
1312 : {
1313 136 : acquire();
1314 136 : dispose();
1315 : }
1316 458 : }
1317 :
1318 : // OComponentHelper
1319 :
1320 460 : void OFormComponents::disposing()
1321 : {
1322 460 : OInterfaceContainer::disposing();
1323 460 : FormComponentsBase::disposing();
1324 460 : m_xParent = NULL;
1325 460 : }
1326 :
1327 : //XChild
1328 :
1329 322 : void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException, std::exception )
1330 : {
1331 322 : ::osl::MutexGuard aGuard( m_aMutex );
1332 322 : m_xParent = Parent;
1333 322 : }
1334 :
1335 :
1336 3040 : InterfaceRef OFormComponents::getParent() throw( RuntimeException, std::exception )
1337 : {
1338 3040 : return m_xParent;
1339 : }
1340 :
1341 :
1342 : } // namespace frm
1343 :
1344 :
1345 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|