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