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 9 : lcl_hasVbaEvents( const Sequence< ScriptEventDescriptor >& sEvents )
82 : {
83 9 : const ScriptEventDescriptor* pDesc = sEvents.getConstArray();
84 9 : const ScriptEventDescriptor* pEnd = ( pDesc + sEvents.getLength() );
85 15 : for ( ; pDesc != pEnd; ++pDesc )
86 : {
87 6 : if ( pDesc->ScriptType == "VBAInterop" )
88 0 : return true;
89 : }
90 9 : 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 244 : 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 244 : Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
121 244 : if ( !xDoc.is() )
122 0 : break;
123 :
124 250 : Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
125 245 : Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance("ooo.vba.VBACodeNameProvider"), UNO_QUERY );
126 239 : if ( !xNameQuery.is() )
127 238 : break;
128 :
129 2 : ::osl::MutexGuard aGuard( m_rMutex );
130 1 : bool hasVBABindings = lcl_hasVbaEvents( m_xEventAttacher->getScriptEvents( i_nIndex ) );
131 1 : if ( hasVBABindings )
132 0 : break;
133 :
134 2 : Reference< XInterface > xElement( getByIndex( i_nIndex ) , UNO_QUERY_THROW );
135 2 : Reference< XForm > xElementAsForm( xElement, UNO_QUERY );
136 1 : 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 2 : Reference<XInterface> xThis = static_cast<XContainer*>(this);
142 2 : OUString sCodeName = xNameQuery->getCodeNameForContainer(xThis);
143 1 : if (sCodeName.isEmpty())
144 0 : sCodeName = xNameQuery->getCodeNameForObject(xElement);
145 :
146 2 : Reference< XPropertySet > xProps( xElement, UNO_QUERY_THROW );
147 2 : OUString sServiceName;
148 1 : xProps->getPropertyValue("DefaultControl") >>= sServiceName;
149 :
150 2 : Reference< ooo::vba::XVBAToOOEventDescGen > xDescSupplier( m_xContext->getServiceManager()->createInstanceWithContext("ooo.vba.VBAToOOEventDesc", m_xContext), UNO_QUERY_THROW );
151 2 : Sequence< ScriptEventDescriptor > vbaEvents = xDescSupplier->getEventDescriptions( sServiceName , sCodeName );
152 :
153 : // register the vba script events
154 7 : m_xEventAttacher->registerScriptEvents( i_nIndex, vbaEvents );
155 : }
156 : while ( false );
157 : }
158 5 : 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 244 : }
168 :
169 : //= ElementDescription
170 :
171 :
172 523 : ElementDescription::ElementDescription( )
173 : {
174 523 : }
175 :
176 :
177 988 : ElementDescription::~ElementDescription()
178 : {
179 988 : }
180 :
181 :
182 : //= OInterfaceContainer
183 :
184 :
185 463 : 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 463 : ,m_xContext(_rxContext)
194 : {
195 463 : impl_createEventAttacher_nothrow();
196 463 : }
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 463 : void OInterfaceContainer::impl_createEventAttacher_nothrow()
235 : {
236 : try
237 : {
238 463 : m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xContext ), UNO_SET_THROW );
239 : }
240 0 : catch( const Exception& )
241 : {
242 : DBG_UNHANDLED_EXCEPTION();
243 : }
244 463 : }
245 :
246 :
247 456 : OInterfaceContainer::~OInterfaceContainer()
248 : {
249 456 : }
250 :
251 :
252 458 : void OInterfaceContainer::disposing()
253 : {
254 : // dispose all elements
255 724 : for (sal_Int32 i = m_aItems.size(); i > 0; --i)
256 : {
257 266 : Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
258 266 : if (xSet.is())
259 266 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
260 :
261 : // revoke event knittings
262 266 : if ( m_xEventAttacher.is() )
263 : {
264 266 : m_xEventAttacher->detach( i - 1, xSet );
265 266 : m_xEventAttacher->removeEntry( i - 1 );
266 : }
267 :
268 532 : Reference<XComponent> xComponent(xSet, UNO_QUERY);
269 266 : if (xComponent.is())
270 266 : xComponent->dispose();
271 266 : }
272 458 : m_aMap.clear();
273 458 : m_aItems.clear();
274 :
275 458 : EventObject aEvt(static_cast<XContainer*>(this));
276 458 : m_aContainerListeners.disposeAndClear(aEvt);
277 458 : }
278 :
279 : // XPersistObject
280 :
281 : namespace
282 : {
283 :
284 1 : 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 1 : if ( !_rxManager.is() )
289 1 : return;
290 :
291 : // reserve the space needed
292 1 : _rSave.reserve( _nItemCount );
293 :
294 : // copy the events
295 3 : for (sal_Int32 i=0; i<_nItemCount; ++i)
296 2 : _rSave.push_back(_rxManager->getScriptEvents( i ));
297 : }
298 :
299 :
300 1 : 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 1 : if ( !_rxManager.is() )
305 1 : return;
306 :
307 1 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aLoop = _rSave.begin();
308 1 : ::std::vector< Sequence< ScriptEventDescriptor > >::const_iterator aEnd = _rSave.end();
309 3 : for ( sal_Int32 i=0; aLoop != aEnd; ++aLoop, ++i )
310 : {
311 2 : _rxManager->revokeScriptEvents( i );
312 2 : _rxManager->registerScriptEvents( i, *aLoop );
313 : }
314 : }
315 : }
316 :
317 :
318 1 : 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 1 : ::std::vector< Sequence< ScriptEventDescriptor > > aSave;
324 1 : if ( m_xEventAttacher.is() )
325 1 : lcl_saveEvents( aSave, m_xEventAttacher, m_aItems.size() );
326 :
327 1 : transformEvents( efVersionSO5x );
328 :
329 : try
330 : {
331 1 : Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
332 1 : sal_Int32 nMark = xMark->createMark();
333 :
334 1 : sal_Int32 nObjLen = 0;
335 1 : _rxOutStream->writeLong(nObjLen);
336 :
337 2 : Reference<XPersistObject> xScripts(m_xEventAttacher, UNO_QUERY);
338 1 : if (xScripts.is())
339 1 : xScripts->write(_rxOutStream);
340 :
341 : // feststellen der Laenge
342 1 : nObjLen = xMark->offsetToMark(nMark) - 4;
343 1 : xMark->jumpToMark(nMark);
344 1 : _rxOutStream->writeLong(nObjLen);
345 1 : xMark->jumpToFurthest();
346 2 : 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 1 : if ( m_xEventAttacher.is() )
358 1 : lcl_restoreEvents( aSave, m_xEventAttacher );
359 1 : }
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 1 : void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
402 : {
403 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
404 1 : if ( !m_xEventAttacher.is() )
405 1 : return;
406 :
407 : try
408 : {
409 : // loop through all our children
410 1 : sal_Int32 nItems = m_aItems.size();
411 1 : Sequence< ScriptEventDescriptor > aChildEvents;
412 :
413 3 : for (sal_Int32 i=0; i<nItems; ++i)
414 : {
415 : // get the script events for this object
416 2 : aChildEvents = m_xEventAttacher->getScriptEvents( i );
417 :
418 2 : 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 1 : }
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 884 : void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
625 : {
626 884 : m_aContainerListeners.addInterface(_rxListener);
627 884 : }
628 :
629 :
630 718 : void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException, std::exception )
631 : {
632 718 : m_aContainerListeners.removeInterface(_rxListener);
633 718 : }
634 :
635 : // XEventListener
636 :
637 51 : void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException, std::exception )
638 : {
639 51 : ::osl::MutexGuard aGuard( m_rMutex );
640 :
641 102 : Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
642 : // normalized source
643 :
644 51 : OInterfaceArray::iterator j;
645 293 : 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 277 : if ( xSource.get() == j->get() )
651 : // found the element
652 35 : break;
653 : }
654 :
655 51 : if ( m_aItems.end() != j )
656 : {
657 35 : m_aItems.erase(j);
658 :
659 : // look up in, and erase from, m_aMap, too
660 35 : OInterfaceMap::iterator i = m_aMap.begin();
661 233 : 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 198 : if ( i->second.get() == xSource.get() )
667 : {
668 : // found it
669 35 : m_aMap.erase(i);
670 35 : break;
671 : }
672 :
673 163 : ++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 51 : }
678 51 : }
679 :
680 : // XPropertyChangeListener
681 :
682 231 : void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
683 : throw (::com::sun::star::uno::RuntimeException, std::exception) {
684 231 : if (evt.PropertyName == PROPERTY_NAME)
685 : {
686 231 : ::osl::MutexGuard aGuard( m_rMutex );
687 : OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
688 231 : ::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
689 231 : if (i != m_aMap.end())
690 : {
691 231 : InterfaceRef xCorrectType((*i).second);
692 231 : m_aMap.erase(i);
693 231 : m_aMap.insert(::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
694 231 : }
695 : }
696 231 : }
697 :
698 : // XElementAccess
699 :
700 315 : sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException, std::exception )
701 : {
702 315 : return !m_aMap.empty();
703 : }
704 :
705 :
706 1 : Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException, std::exception)
707 : {
708 1 : return m_aElementType;
709 : }
710 :
711 : // XEnumerationAccess
712 :
713 1 : Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException, std::exception )
714 : {
715 1 : ::osl::MutexGuard aGuard( m_rMutex );
716 1 : return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
717 : }
718 :
719 : // XNameAccess
720 :
721 10 : Any SAL_CALL OInterfaceContainer::getByName( const OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException, std::exception)
722 : {
723 : ::std::pair <OInterfaceMap::iterator,
724 10 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
725 :
726 10 : if (aPair.first == aPair.second)
727 1 : throw NoSuchElementException();
728 :
729 9 : return (*aPair.first).second->queryInterface( m_aElementType );
730 : }
731 :
732 :
733 11 : StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException, std::exception)
734 : {
735 11 : StringSequence aNameList(m_aItems.size());
736 11 : OUString* pStringArray = aNameList.getArray();
737 :
738 33 : for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
739 : {
740 22 : *pStringArray = (*i).first;
741 : }
742 11 : return aNameList;
743 : }
744 :
745 :
746 287 : sal_Bool SAL_CALL OInterfaceContainer::hasByName( const OUString& _rName ) throw(RuntimeException, std::exception)
747 : {
748 : ::std::pair <OInterfaceMap::iterator,
749 287 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
750 287 : return aPair.first != aPair.second;
751 : }
752 :
753 : // XIndexAccess
754 :
755 3617 : sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException, std::exception )
756 : {
757 3617 : return m_aItems.size();
758 : }
759 :
760 :
761 2820 : Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
762 : {
763 2820 : if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
764 25 : throw IndexOutOfBoundsException();
765 :
766 2795 : return m_aItems[_nIndex]->queryInterface( m_aElementType );
767 : }
768 :
769 :
770 520 : void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
771 : {
772 : // it has to be non-NULL
773 520 : 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 520 : Any aCorrectType = _rxObject->queryInterface( m_aElementType );
778 520 : if ( !aCorrectType.hasValue() )
779 0 : lcl_throwIllegalArgumentException();
780 :
781 : // it has to have a "Name" property
782 520 : 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 1040 : Reference< XChild > xChild( _rxObject, UNO_QUERY );
787 520 : 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 520 : if ( _pElement )
795 : {
796 520 : _pElement->xPropertySet = _rxObject;
797 520 : _pElement->xChild = xChild;
798 520 : _pElement->aElementTypeInterface = aCorrectType;
799 520 : _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
800 520 : }
801 520 : }
802 :
803 :
804 515 : void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
805 : sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
806 : {
807 515 : const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
808 :
809 : // SYNCHRONIZED ----->
810 515 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
811 :
812 1030 : boost::scoped_ptr< ElementDescription > aAutoDeleteMetaData;
813 515 : ElementDescription* pElementMetaData = _pApprovalResult;
814 515 : if ( !pElementMetaData )
815 : { // not yet approved by the caller -> do ourself
816 282 : 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 282 : aAutoDeleteMetaData.reset( pElementMetaData );
821 :
822 : // will throw an exception if necessary
823 282 : 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 1028 : OUString sName;
832 514 : _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
833 514 : _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
834 :
835 : // insert the object into our internal structures
836 514 : 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 514 : m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
843 :
844 514 : m_aMap.insert( ::std::pair< const OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
845 :
846 : // announce ourself as parent to the new element
847 514 : pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
848 :
849 : // handle the events
850 514 : if ( bHandleEvents )
851 : {
852 512 : m_xEventAttacher->insertEntry(_nIndex);
853 512 : m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
854 : }
855 :
856 : // notify derived classes
857 514 : implInserted( pElementMetaData );
858 :
859 514 : aGuard.clear();
860 : // <----- SYNCHRONIZED
861 :
862 : // insert faked VBA events?
863 514 : bool bHandleVbaEvents = false;
864 : try
865 : {
866 689 : _rxElement->getPropertyValue("GenerateVbaEvents") >>= bHandleVbaEvents;
867 : }
868 175 : catch( const Exception& )
869 : {
870 : }
871 514 : 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 514 : if ( _bFire )
893 : {
894 : // notify listeners
895 512 : ContainerEvent aEvt;
896 512 : aEvt.Source = static_cast<XContainer*>(this);
897 512 : aEvt.Accessor <<= _nIndex;
898 512 : aEvt.Element = pElementMetaData->aElementTypeInterface;
899 :
900 512 : aGuard.clear();
901 512 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
902 515 : }
903 514 : }
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 514 : void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
928 : {
929 : // not inrerested in
930 514 : }
931 :
932 :
933 226 : void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
934 : {
935 : // not inrerested in
936 226 : }
937 :
938 :
939 6 : void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
940 : {
941 6 : _rInstanceLock.clear();
942 6 : m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
943 6 : }
944 :
945 : // XIndexContainer
946 :
947 280 : void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception)
948 : {
949 280 : Reference< XPropertySet > xElement;
950 280 : _rElement >>= xElement;
951 281 : implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
952 279 : }
953 :
954 :
955 7 : 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 7 : boost::scoped_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
961 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
962 : {
963 7 : Reference< XPropertySet > xElementProps;
964 7 : _rNewElement >>= xElementProps;
965 8 : approveNewElement( xElementProps, aElementMetaData.get() );
966 : }
967 :
968 : // get the old element
969 12 : 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 6 : OInterfaceMap::iterator j = m_aMap.begin();
975 13 : while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
976 1 : ++j;
977 :
978 : // remove event knittings
979 6 : if ( m_xEventAttacher.is() )
980 : {
981 6 : InterfaceRef xNormalized( xOldElement, UNO_QUERY );
982 6 : m_xEventAttacher->detach( _nIndex, xNormalized );
983 6 : m_xEventAttacher->removeEntry( _nIndex );
984 : }
985 :
986 : // don't listen for property changes anymore
987 12 : Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
988 6 : if (xSet.is())
989 6 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
990 :
991 : // give the old element a new (void) parent
992 12 : Reference<XChild> xChild(xOldElement, UNO_QUERY);
993 6 : if (xChild.is())
994 6 : xChild->setParent(InterfaceRef ());
995 :
996 : // remove the old one
997 6 : m_aMap.erase(j);
998 :
999 : // examine the new element
1000 12 : OUString sName;
1001 : DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1002 :
1003 6 : aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1004 6 : aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1005 :
1006 : // insert the new one
1007 6 : m_aMap.insert( ::std::pair<const OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1008 6 : m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1009 :
1010 6 : aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1011 :
1012 6 : if ( m_xEventAttacher.is() )
1013 : {
1014 6 : m_xEventAttacher->insertEntry( _nIndex );
1015 6 : m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1016 : }
1017 :
1018 12 : ContainerEvent aReplaceEvent;
1019 6 : aReplaceEvent.Source = static_cast< XContainer* >( this );
1020 6 : aReplaceEvent.Accessor <<= _nIndex;
1021 6 : aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1022 6 : aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1023 :
1024 13 : impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1025 6 : }
1026 :
1027 :
1028 231 : void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1029 : {
1030 231 : if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1031 2 : throw IndexOutOfBoundsException();
1032 229 : }
1033 :
1034 :
1035 4 : void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1036 : {
1037 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1038 : // check the index
1039 4 : implCheckIndex( _nIndex );
1040 : // do the replace
1041 5 : implReplaceByIndex( _nIndex, Element, aGuard );
1042 2 : }
1043 :
1044 :
1045 226 : 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 226 : OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1050 226 : InterfaceRef xElement(*i);
1051 :
1052 226 : OInterfaceMap::iterator j = m_aMap.begin();
1053 226 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
1054 :
1055 226 : m_aItems.erase(i);
1056 226 : m_aMap.erase(j);
1057 :
1058 : // remove event knittings
1059 226 : if ( m_xEventAttacher.is() )
1060 : {
1061 226 : InterfaceRef xNormalized( xElement, UNO_QUERY );
1062 226 : m_xEventAttacher->detach( _nIndex, xNormalized );
1063 226 : m_xEventAttacher->removeEntry( _nIndex );
1064 : }
1065 :
1066 452 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1067 226 : if (xSet.is())
1068 226 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1069 :
1070 452 : Reference<XChild> xChild(xElement, UNO_QUERY);
1071 226 : if (xChild.is())
1072 226 : xChild->setParent(InterfaceRef ());
1073 :
1074 : // notify derived classes
1075 226 : implRemoved(xElement);
1076 :
1077 : // notify listeners
1078 452 : ContainerEvent aEvt;
1079 226 : aEvt.Source = static_cast<XContainer*>(this);
1080 226 : aEvt.Element = xElement->queryInterface( m_aElementType );
1081 226 : aEvt.Accessor <<= _nIndex;
1082 :
1083 226 : _rClearBeforeNotify.clear();
1084 452 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1085 226 : }
1086 :
1087 :
1088 227 : void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
1089 : {
1090 227 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1091 : // check the index
1092 227 : implCheckIndex( _nIndex );
1093 : // do the removal
1094 227 : implRemoveByIndex( _nIndex, aGuard );
1095 226 : }
1096 :
1097 :
1098 465 : ElementDescription* OInterfaceContainer::createElementMetaData( )
1099 : {
1100 465 : return new ElementDescription;
1101 : }
1102 :
1103 :
1104 234 : void SAL_CALL OInterfaceContainer::insertByName(const OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException, std::exception )
1105 : {
1106 234 : Reference< XPropertySet > xElementProps;
1107 :
1108 468 : 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 234 : _rElement >>= xElementProps;
1115 234 : approveNewElement( xElementProps, aElementMetaData.get() );
1116 :
1117 233 : xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1118 : }
1119 2 : catch( const IllegalArgumentException& )
1120 : {
1121 1 : 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 467 : implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1132 233 : }
1133 :
1134 :
1135 4 : void SAL_CALL OInterfaceContainer::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1136 : {
1137 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1138 : ::std::pair <OInterfaceMap::iterator,
1139 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1140 4 : if (aPair.first == aPair.second)
1141 0 : throw NoSuchElementException();
1142 :
1143 4 : if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1144 0 : lcl_throwIllegalArgumentException();
1145 :
1146 8 : Reference<XPropertySet> xSet;
1147 4 : Element >>= xSet;
1148 4 : if (xSet.is())
1149 : {
1150 4 : if (!hasProperty(PROPERTY_NAME, xSet))
1151 0 : lcl_throwIllegalArgumentException();
1152 :
1153 4 : xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1154 : }
1155 :
1156 : // determine the element pos
1157 4 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1158 :
1159 8 : implReplaceByIndex( nPos, Element, aGuard );
1160 4 : }
1161 :
1162 :
1163 4 : void SAL_CALL OInterfaceContainer::removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException, std::exception )
1164 : {
1165 4 : ::osl::MutexGuard aGuard( m_rMutex );
1166 : ::std::pair <OInterfaceMap::iterator,
1167 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1168 4 : if (aPair.first == aPair.second)
1169 1 : throw NoSuchElementException();
1170 :
1171 3 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1172 4 : removeByIndex(nPos);
1173 3 : }
1174 :
1175 :
1176 : // XEventAttacherManager
1177 :
1178 3 : void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException, std::exception)
1179 : {
1180 3 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1181 3 : if ( m_xEventAttacher.is() )
1182 : {
1183 3 : m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1184 3 : aGuard.clear();
1185 3 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1186 3 : }
1187 3 : }
1188 :
1189 :
1190 241 : void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException, std::exception)
1191 : {
1192 241 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1193 241 : if ( m_xEventAttacher.is() )
1194 : {
1195 241 : m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1196 241 : aGuard.clear();
1197 241 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1198 241 : }
1199 241 : }
1200 :
1201 :
1202 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const OUString& aListenerType, const OUString& aEventMethod, const OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException, std::exception)
1203 : {
1204 1 : if ( m_xEventAttacher.is() )
1205 1 : m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1206 1 : }
1207 :
1208 :
1209 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1210 : {
1211 1 : if ( m_xEventAttacher.is() )
1212 1 : m_xEventAttacher->revokeScriptEvents( nIndex );
1213 1 : }
1214 :
1215 :
1216 1 : void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1217 : {
1218 1 : if ( m_xEventAttacher.is() )
1219 1 : m_xEventAttacher->insertEntry( nIndex );
1220 1 : }
1221 :
1222 :
1223 1 : void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1224 : {
1225 1 : if ( m_xEventAttacher.is() )
1226 1 : m_xEventAttacher->removeEntry( nIndex );
1227 1 : }
1228 :
1229 :
1230 8 : Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException, std::exception)
1231 : {
1232 8 : Sequence< ScriptEventDescriptor > aReturn;
1233 8 : if ( m_xEventAttacher.is() )
1234 : {
1235 8 : aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1236 8 : if ( lcl_hasVbaEvents( aReturn ) )
1237 : {
1238 0 : aReturn = lcl_stripVbaEvents( aReturn );
1239 : }
1240 : }
1241 8 : return aReturn;
1242 : }
1243 :
1244 :
1245 146 : void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException, std::exception)
1246 : {
1247 146 : if ( m_xEventAttacher.is() )
1248 146 : m_xEventAttacher->attach( nIndex, xObject, aHelper );
1249 146 : }
1250 :
1251 :
1252 146 : void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException, std::exception)
1253 : {
1254 146 : if ( m_xEventAttacher.is() )
1255 146 : m_xEventAttacher->detach( nIndex, xObject );
1256 146 : }
1257 :
1258 :
1259 853 : void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1260 : {
1261 853 : if ( m_xEventAttacher.is() )
1262 853 : m_xEventAttacher->addScriptListener( xListener );
1263 853 : }
1264 :
1265 :
1266 847 : void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException, std::exception)
1267 : {
1268 847 : if ( m_xEventAttacher.is() )
1269 847 : m_xEventAttacher->removeScriptListener( xListener );
1270 847 : }
1271 :
1272 :
1273 : //= OFormComponents
1274 :
1275 :
1276 5735 : Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException, std::exception)
1277 : {
1278 5735 : Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1279 5735 : if (!aReturn.hasValue())
1280 : {
1281 5705 : aReturn = OInterfaceContainer::queryInterface(_rType);
1282 :
1283 5705 : if (!aReturn.hasValue())
1284 2555 : aReturn = FormComponentsBase::queryAggregation(_rType);
1285 : }
1286 :
1287 5735 : 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 192 : OFormComponents::OFormComponents(const Reference<XComponentContext>& _rxFactory)
1298 : :FormComponentsBase( m_aMutex )
1299 192 : ,OInterfaceContainer( _rxFactory, m_aMutex, cppu::UnoType<XFormComponent>::get() )
1300 384 : ,OFormComponents_BASE()
1301 : {
1302 192 : }
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 378 : OFormComponents::~OFormComponents()
1314 : {
1315 189 : if (!FormComponentsBase::rBHelper.bDisposed)
1316 : {
1317 30 : acquire();
1318 30 : dispose();
1319 : }
1320 189 : }
1321 :
1322 : // OComponentHelper
1323 :
1324 191 : void OFormComponents::disposing()
1325 : {
1326 191 : OInterfaceContainer::disposing();
1327 191 : FormComponentsBase::disposing();
1328 191 : m_xParent = NULL;
1329 191 : }
1330 :
1331 : //XChild
1332 :
1333 160 : void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException, std::exception )
1334 : {
1335 160 : ::osl::MutexGuard aGuard( m_aMutex );
1336 160 : m_xParent = Parent;
1337 160 : }
1338 :
1339 :
1340 1511 : InterfaceRef OFormComponents::getParent() throw( RuntimeException, std::exception )
1341 : {
1342 1511 : return m_xParent;
1343 : }
1344 :
1345 :
1346 : } // namespace frm
1347 :
1348 :
1349 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|