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 <memory>
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 243 : 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 243 : Reference< XModel > xDoc( getXModel( static_cast< XContainer *> ( this ) ) );
121 243 : if ( !xDoc.is() )
122 0 : break;
123 :
124 249 : Reference< XMultiServiceFactory > xDocFac( xDoc, UNO_QUERY_THROW );
125 244 : Reference< XCodeNameQuery > xNameQuery( xDocFac->createInstance("ooo.vba.VBACodeNameProvider"), UNO_QUERY );
126 238 : if ( !xNameQuery.is() )
127 237 : 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 243 : }
168 : //==================================================================
169 : //= ElementDescription
170 : //==================================================================
171 : //------------------------------------------------------------------
172 515 : ElementDescription::ElementDescription( )
173 : {
174 515 : }
175 :
176 : //------------------------------------------------------------------
177 972 : ElementDescription::~ElementDescription()
178 : {
179 972 : }
180 :
181 : //==================================================================
182 : //= OInterfaceContainer
183 : //==================================================================
184 : //------------------------------------------------------------------
185 394 : 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 394 : ,m_xContext(_rxContext)
194 : {
195 394 : impl_createEventAttacher_nothrow();
196 394 : }
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 394 : void OInterfaceContainer::impl_createEventAttacher_nothrow()
235 : {
236 : try
237 : {
238 394 : m_xEventAttacher.set( ::comphelper::createEventAttacherManager( m_xContext ), UNO_SET_THROW );
239 : }
240 0 : catch( const Exception& )
241 : {
242 : DBG_UNHANDLED_EXCEPTION();
243 : }
244 394 : }
245 :
246 : //------------------------------------------------------------------------------
247 388 : OInterfaceContainer::~OInterfaceContainer()
248 : {
249 388 : }
250 :
251 : //------------------------------------------------------------------------------
252 390 : void OInterfaceContainer::disposing()
253 : {
254 : // dispose all elements
255 650 : for (sal_Int32 i = m_aItems.size(); i > 0; --i)
256 : {
257 260 : Reference<XPropertySet> xSet(m_aItems[i - 1], UNO_QUERY);
258 260 : if (xSet.is())
259 260 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
260 :
261 : // revoke event knittings
262 260 : if ( m_xEventAttacher.is() )
263 : {
264 260 : m_xEventAttacher->detach( i - 1, xSet );
265 260 : m_xEventAttacher->removeEntry( i - 1 );
266 : }
267 :
268 520 : Reference<XComponent> xComponent(xSet, UNO_QUERY);
269 260 : if (xComponent.is())
270 260 : xComponent->dispose();
271 260 : }
272 390 : m_aMap.clear();
273 390 : m_aItems.clear();
274 :
275 390 : EventObject aEvt(static_cast<XContainer*>(this));
276 390 : m_aContainerListeners.disposeAndClear(aEvt);
277 390 : }
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 ( 0 == _rDescriptor.ScriptType.compareToAscii( "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( 0 == sPrefix.compareToAscii( "document" )
374 : || 0 == sPrefix.compareToAscii( "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 ( 0 == _rDescriptor.ScriptType.compareToAscii( "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 : OUString sNewScriptCode( "document:" );
395 0 : sNewScriptCode += _rDescriptor.ScriptCode;
396 0 : _rDescriptor.ScriptCode = sNewScriptCode;
397 : }
398 : }
399 0 : }
400 : };
401 :
402 : //------------------------------------------------------------------------------
403 1 : void OInterfaceContainer::transformEvents( const EventFormat _eTargetFormat )
404 : {
405 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::transformEvents: no event attacher manager!" );
406 1 : if ( !m_xEventAttacher.is() )
407 1 : return;
408 :
409 : try
410 : {
411 : // loop through all our children
412 1 : sal_Int32 nItems = m_aItems.size();
413 1 : Sequence< ScriptEventDescriptor > aChildEvents;
414 :
415 3 : for (sal_Int32 i=0; i<nItems; ++i)
416 : {
417 : // get the script events for this object
418 2 : aChildEvents = m_xEventAttacher->getScriptEvents( i );
419 :
420 2 : if ( aChildEvents.getLength() )
421 : {
422 : // the "iterators" for the events for this child
423 0 : ScriptEventDescriptor* pChildEvents = aChildEvents.getArray();
424 0 : ScriptEventDescriptor* pChildEventsEnd = pChildEvents + aChildEvents.getLength();
425 :
426 : // do the transformation
427 0 : if ( efVersionSO6x == _eTargetFormat )
428 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo60Format() );
429 : else
430 0 : ::std::for_each( pChildEvents, pChildEventsEnd, TransformEventTo52Format() );
431 :
432 : // revoke the script events
433 0 : m_xEventAttacher->revokeScriptEvents( i );
434 : // and re-register them
435 0 : m_xEventAttacher->registerScriptEvents( i, aChildEvents );
436 : }
437 1 : }
438 : }
439 0 : catch( const Exception& )
440 : {
441 : DBG_UNHANDLED_EXCEPTION();
442 : }
443 : }
444 :
445 : //------------------------------------------------------------------------------
446 0 : void SAL_CALL OInterfaceContainer::readEvents(const Reference<XObjectInputStream>& _rxInStream)
447 : {
448 0 : ::osl::MutexGuard aGuard( m_rMutex );
449 :
450 : // Scripting Info lesen
451 0 : Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
452 0 : sal_Int32 nObjLen = _rxInStream->readLong();
453 0 : if (nObjLen)
454 : {
455 0 : sal_Int32 nMark = xMark->createMark();
456 0 : Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
457 0 : if (xObj.is())
458 0 : xObj->read(_rxInStream);
459 0 : xMark->jumpToMark(nMark);
460 0 : _rxInStream->skipBytes(nObjLen);
461 0 : xMark->deleteMark(nMark);
462 : }
463 :
464 : // Attachement lesen
465 0 : if ( m_xEventAttacher.is() )
466 : {
467 0 : OInterfaceArray::const_iterator aAttach = m_aItems.begin();
468 0 : OInterfaceArray::const_iterator aAttachEnd = m_aItems.end();
469 0 : for ( sal_Int32 i=0; aAttach != aAttachEnd; ++aAttach, ++i )
470 : {
471 0 : Reference< XInterface > xAsIFace( *aAttach, UNO_QUERY ); // important to normalize this ....
472 0 : Reference< XPropertySet > xAsSet( xAsIFace, UNO_QUERY );
473 0 : m_xEventAttacher->attach( i, xAsIFace, makeAny( xAsSet ) );
474 0 : }
475 0 : }
476 0 : }
477 :
478 : //------------------------------------------------------------------------------
479 0 : void SAL_CALL OInterfaceContainer::write( const Reference< XObjectOutputStream >& _rxOutStream ) throw(IOException, RuntimeException)
480 : {
481 0 : ::osl::MutexGuard aGuard( m_rMutex );
482 0 : sal_Int32 nLen = m_aItems.size();
483 :
484 : // schreiben der laenge
485 0 : _rxOutStream->writeLong(nLen);
486 :
487 0 : if (nLen)
488 : {
489 : // 1. Version
490 0 : _rxOutStream->writeShort(0x0001);
491 :
492 : // 2. Objekte
493 0 : for (sal_Int32 i = 0; i < nLen; i++)
494 : {
495 0 : Reference<XPersistObject> xObj(m_aItems[i], UNO_QUERY);
496 0 : if (xObj.is())
497 0 : _rxOutStream->writeObject(xObj);
498 : else
499 : {
500 : // ::com::sun::star::chaos::Error
501 : }
502 0 : }
503 :
504 : // 3. Scripts
505 0 : writeEvents(_rxOutStream);
506 0 : }
507 0 : }
508 :
509 : //------------------------------------------------------------------------------
510 : namespace
511 : {
512 0 : Reference< XPersistObject > lcl_createPlaceHolder( const Reference< XComponentContext >& _rxORB )
513 : {
514 0 : Reference< XPersistObject > xObject( _rxORB->getServiceManager()->createInstanceWithContext(FRM_COMPONENT_HIDDENCONTROL, _rxORB), UNO_QUERY );
515 : DBG_ASSERT( xObject.is(), "lcl_createPlaceHolder: could not create a substitute for the unknown object!" );
516 0 : if ( xObject.is() )
517 : {
518 : // set some properties describing what we did
519 0 : Reference< XPropertySet > xObjProps( xObject, UNO_QUERY );
520 0 : if ( xObject.is() )
521 : {
522 : try
523 : {
524 0 : xObjProps->setPropertyValue( PROPERTY_NAME, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_NAME ) ) );
525 0 : xObjProps->setPropertyValue( PROPERTY_TAG, makeAny( FRM_RES_STRING( RID_STR_CONTROL_SUBSTITUTED_EPXPLAIN ) ) );
526 : }
527 0 : catch(const Exception&)
528 : {
529 : }
530 0 : }
531 : }
532 0 : return xObject;
533 : }
534 : }
535 :
536 : //------------------------------------------------------------------------------
537 0 : void SAL_CALL OInterfaceContainer::read( const Reference< XObjectInputStream >& _rxInStream ) throw(IOException, RuntimeException)
538 : {
539 0 : ::osl::MutexGuard aGuard( m_rMutex );
540 :
541 : // after ::read the object is expected to be in the state it was when ::write was called, so we have
542 : // to empty ourself here
543 0 : while (getCount())
544 0 : removeByIndex(0);
545 :
546 : // Schreibt nur in Abhaengigkeit der Laenge
547 0 : sal_Int32 nLen = _rxInStream->readLong();
548 :
549 0 : if (nLen)
550 : {
551 : // 1. Version
552 0 : sal_uInt16 nVersion = _rxInStream->readShort(); (void)nVersion;
553 :
554 : // 2. Objekte
555 0 : for (sal_Int32 i = 0; i < nLen; i++)
556 : {
557 0 : Reference<XPersistObject> xObj;
558 : try
559 : {
560 0 : xObj = _rxInStream->readObject();
561 : }
562 0 : catch(const WrongFormatException&)
563 : {
564 : // the object could not be read
565 : // create a object (so the readEvents below will assign the events to the right controls)
566 0 : xObj = lcl_createPlaceHolder( m_xContext );
567 0 : if ( !xObj.is() )
568 : // couldn't handle it
569 0 : throw;
570 : }
571 0 : catch(const Exception&)
572 : {
573 : // unsere Map leeren
574 0 : while (!m_aItems.empty())
575 0 : removeElementsNoEvents(0);
576 :
577 : // und die Exception nach aussen
578 0 : throw;
579 : }
580 :
581 0 : if ( xObj.is() )
582 : {
583 0 : Reference< XPropertySet > xElement( xObj, UNO_QUERY );
584 : try
585 : {
586 : implInsert(
587 0 : m_aItems.size(), // position
588 : xElement, // element to insert
589 : sal_False, // no event attacher manager handling
590 : NULL, // not yet approved - let implInsert do it
591 : sal_True // fire the event
592 0 : );
593 : }
594 0 : catch( const Exception& )
595 : {
596 : SAL_WARN("forms.misc", "OInterfaceContainerHelper::read: reading succeeded, but not inserting!" );
597 : // create a placeholder
598 0 : xElement = xElement.query( lcl_createPlaceHolder( m_xContext ) );
599 0 : if ( !xElement.is() )
600 : // couldn't handle it
601 0 : throw;
602 : // insert the placeholder
603 0 : implInsert( m_aItems.size(), xElement, sal_False, NULL, sal_True );
604 0 : }
605 : }
606 0 : }
607 :
608 0 : readEvents(_rxInStream);
609 : }
610 : else
611 : {
612 : try
613 : {
614 0 : m_xEventAttacher = ::comphelper::createEventAttacherManager( m_xContext );
615 : OSL_ENSURE( m_xEventAttacher.is(), "OInterfaceContainer::read: could not create an event attacher manager!" );
616 : }
617 0 : catch( const Exception& )
618 : {
619 : DBG_UNHANDLED_EXCEPTION();
620 : }
621 0 : }
622 0 : }
623 :
624 : // XContainer
625 : //------------------------------------------------------------------------------
626 820 : void SAL_CALL OInterfaceContainer::addContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
627 : {
628 820 : m_aContainerListeners.addInterface(_rxListener);
629 820 : }
630 :
631 : //------------------------------------------------------------------------------
632 658 : void SAL_CALL OInterfaceContainer::removeContainerListener(const Reference<XContainerListener>& _rxListener) throw( RuntimeException )
633 : {
634 658 : m_aContainerListeners.removeInterface(_rxListener);
635 658 : }
636 :
637 : // XEventListener
638 : //------------------------------------------------------------------------------
639 51 : void SAL_CALL OInterfaceContainer::disposing(const EventObject& _rSource) throw( RuntimeException )
640 : {
641 51 : ::osl::MutexGuard aGuard( m_rMutex );
642 :
643 102 : Reference< XInterface > xSource( _rSource.Source, UNO_QUERY );
644 : // normalized source
645 :
646 51 : OInterfaceArray::iterator j;
647 293 : for ( j = m_aItems.begin(); j != m_aItems.end(); ++j )
648 : {
649 : DBG_ASSERT( j->get() == Reference< XInterface >( *j, UNO_QUERY ).get(),
650 : "OInterfaceContainer::disposing: vector element not normalized!" );
651 :
652 277 : if ( xSource.get() == j->get() )
653 : // found the element
654 35 : break;
655 : }
656 :
657 51 : if ( m_aItems.end() != j )
658 : {
659 35 : m_aItems.erase(j);
660 :
661 : // look up in, and erase from, m_aMap, too
662 35 : OInterfaceMap::iterator i = m_aMap.begin();
663 233 : while ( i != m_aMap.end() )
664 : {
665 : DBG_ASSERT( i->second.get() == Reference< XInterface >( i->second, UNO_QUERY ).get(),
666 : "OInterfaceContainer::disposing: map element not normalized!" );
667 :
668 198 : if ( i->second.get() == xSource.get() )
669 : {
670 : // found it
671 35 : m_aMap.erase(i);
672 35 : break;
673 : }
674 :
675 163 : ++i;
676 :
677 : DBG_ASSERT( i != m_aMap.end(), "OInterfaceContainer::disposing: inconsistency: the element was in m_aItems, but not in m_aMap!" );
678 : }
679 51 : }
680 51 : }
681 :
682 : // XPropertyChangeListener
683 : //------------------------------------------------------------------------------
684 231 : void OInterfaceContainer::propertyChange(const PropertyChangeEvent& evt)
685 : throw (::com::sun::star::uno::RuntimeException) {
686 231 : if (evt.PropertyName == PROPERTY_NAME)
687 : {
688 231 : ::osl::MutexGuard aGuard( m_rMutex );
689 : OInterfaceMap::iterator i = ::std::find(m_aMap.begin(), m_aMap.end(),
690 231 : ::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.OldValue),evt.Source));
691 231 : if (i != m_aMap.end())
692 : {
693 231 : InterfaceRef xCorrectType((*i).second);
694 231 : m_aMap.erase(i);
695 231 : m_aMap.insert(::std::pair<const OUString, InterfaceRef >(::comphelper::getString(evt.NewValue),xCorrectType));
696 231 : }
697 : }
698 231 : }
699 :
700 : // XElementAccess
701 : //------------------------------------------------------------------------------
702 238 : sal_Bool SAL_CALL OInterfaceContainer::hasElements() throw( RuntimeException )
703 : {
704 238 : return !m_aMap.empty();
705 : }
706 :
707 : //------------------------------------------------------------------------------
708 1 : Type SAL_CALL OInterfaceContainer::getElementType() throw(RuntimeException)
709 : {
710 1 : return m_aElementType;
711 : }
712 :
713 : // XEnumerationAccess
714 : //------------------------------------------------------------------------------
715 1 : Reference<XEnumeration> SAL_CALL OInterfaceContainer::createEnumeration() throw( RuntimeException )
716 : {
717 1 : ::osl::MutexGuard aGuard( m_rMutex );
718 1 : return new ::comphelper::OEnumerationByIndex(static_cast<XIndexAccess*>(this));
719 : }
720 :
721 : // XNameAccess
722 : //------------------------------------------------------------------------------
723 10 : Any SAL_CALL OInterfaceContainer::getByName( const OUString& _rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
724 : {
725 : ::std::pair <OInterfaceMap::iterator,
726 10 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
727 :
728 10 : if (aPair.first == aPair.second)
729 1 : throw NoSuchElementException();
730 :
731 9 : return (*aPair.first).second->queryInterface( m_aElementType );
732 : }
733 :
734 : //------------------------------------------------------------------------------
735 11 : StringSequence SAL_CALL OInterfaceContainer::getElementNames() throw(RuntimeException)
736 : {
737 11 : StringSequence aNameList(m_aItems.size());
738 11 : OUString* pStringArray = aNameList.getArray();
739 :
740 33 : for (OInterfaceMap::const_iterator i = m_aMap.begin(); i != m_aMap.end(); ++i, ++pStringArray)
741 : {
742 22 : *pStringArray = (*i).first;
743 : }
744 11 : return aNameList;
745 : }
746 :
747 : //------------------------------------------------------------------------------
748 287 : sal_Bool SAL_CALL OInterfaceContainer::hasByName( const OUString& _rName ) throw(RuntimeException)
749 : {
750 : ::std::pair <OInterfaceMap::iterator,
751 287 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(_rName);
752 287 : return aPair.first != aPair.second;
753 : }
754 :
755 : // XIndexAccess
756 : //------------------------------------------------------------------------------
757 3383 : sal_Int32 OInterfaceContainer::getCount() throw( RuntimeException )
758 : {
759 3383 : return m_aItems.size();
760 : }
761 :
762 : //------------------------------------------------------------------------------
763 2788 : Any OInterfaceContainer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
764 : {
765 2788 : if (_nIndex < 0 || (_nIndex >= (sal_Int32)m_aItems.size()))
766 25 : throw IndexOutOfBoundsException();
767 :
768 2763 : return m_aItems[_nIndex]->queryInterface( m_aElementType );
769 : }
770 :
771 : //------------------------------------------------------------------------------
772 512 : void OInterfaceContainer::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
773 : {
774 : // it has to be non-NULL
775 512 : if ( !_rxObject.is() )
776 0 : throw IllegalArgumentException(FRM_RES_STRING(RID_STR_NEED_NON_NULL_OBJECT), static_cast<XContainer*>(this), 1);
777 :
778 : // it has to support our element type interface
779 512 : Any aCorrectType = _rxObject->queryInterface( m_aElementType );
780 512 : if ( !aCorrectType.hasValue() )
781 0 : lcl_throwIllegalArgumentException();
782 :
783 : // it has to have a "Name" property
784 512 : if ( !hasProperty( PROPERTY_NAME, _rxObject ) )
785 0 : lcl_throwIllegalArgumentException();
786 :
787 : // it has to be a child, and it must not have a parent already
788 1024 : Reference< XChild > xChild( _rxObject, UNO_QUERY );
789 512 : if ( !xChild.is() || xChild->getParent().is() )
790 : {
791 0 : lcl_throwIllegalArgumentException();
792 : }
793 :
794 : // passed all tests. cache the information we have so far
795 : DBG_ASSERT( _pElement, "OInterfaceContainer::approveNewElement: invalid event descriptor!" );
796 512 : if ( _pElement )
797 : {
798 512 : _pElement->xPropertySet = _rxObject;
799 512 : _pElement->xChild = xChild;
800 512 : _pElement->aElementTypeInterface = aCorrectType;
801 512 : _pElement->xInterface = Reference< XInterface >( _rxObject, UNO_QUERY ); // normalized XInterface
802 512 : }
803 512 : }
804 :
805 : //------------------------------------------------------------------------------
806 507 : void OInterfaceContainer::implInsert(sal_Int32 _nIndex, const Reference< XPropertySet >& _rxElement,
807 : sal_Bool _bEvents, ElementDescription* _pApprovalResult, sal_Bool _bFire ) throw( IllegalArgumentException )
808 : {
809 507 : const bool bHandleEvents = _bEvents && m_xEventAttacher.is();
810 :
811 : // SYNCHRONIZED ----->
812 507 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
813 :
814 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
815 1014 : ::std::auto_ptr< ElementDescription > aAutoDeleteMetaData;
816 : SAL_WNODEPRECATED_DECLARATIONS_POP
817 507 : ElementDescription* pElementMetaData = _pApprovalResult;
818 507 : if ( !pElementMetaData )
819 : { // not yet approved by the caller -> do ourself
820 276 : pElementMetaData = createElementMetaData();
821 : DBG_ASSERT( pElementMetaData, "OInterfaceContainer::implInsert: createElementMetaData returned nonsense!" );
822 :
823 : // ensure that the meta data structure will be deleted later on
824 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
825 276 : aAutoDeleteMetaData = ::std::auto_ptr< ElementDescription >( pElementMetaData );
826 : SAL_WNODEPRECATED_DECLARATIONS_POP
827 :
828 : // will throw an exception if necessary
829 276 : approveNewElement( _rxElement, pElementMetaData );
830 : }
831 :
832 :
833 : // approveNewElement (no matter if called here or outside) has ensure that all relevant interfaces
834 : // exist
835 :
836 : // set the name, and add as change listener for the name
837 1012 : OUString sName;
838 506 : _rxElement->getPropertyValue(PROPERTY_NAME) >>= sName;
839 506 : _rxElement->addPropertyChangeListener(PROPERTY_NAME, this);
840 :
841 : // insert the object into our internal structures
842 506 : if (_nIndex > (sal_Int32)m_aItems.size()) // ermitteln des tatsaechlichen Indexs
843 : {
844 0 : _nIndex = m_aItems.size();
845 0 : m_aItems.push_back( pElementMetaData->xInterface );
846 : }
847 : else
848 506 : m_aItems.insert( m_aItems.begin() + _nIndex, pElementMetaData->xInterface );
849 :
850 506 : m_aMap.insert( ::std::pair< const OUString, InterfaceRef >( sName, pElementMetaData->xInterface ) );
851 :
852 : // announce ourself as parent to the new element
853 506 : pElementMetaData->xChild->setParent(static_cast<XContainer*>(this));
854 :
855 : // handle the events
856 506 : if ( bHandleEvents )
857 : {
858 504 : m_xEventAttacher->insertEntry(_nIndex);
859 504 : m_xEventAttacher->attach( _nIndex, pElementMetaData->xInterface, makeAny( _rxElement ) );
860 : }
861 :
862 : // notify derived classes
863 506 : implInserted( pElementMetaData );
864 :
865 506 : aGuard.clear();
866 : // <----- SYNCHRONIZED
867 :
868 : // insert faked VBA events?
869 506 : bool bHandleVbaEvents = false;
870 : try
871 : {
872 676 : _rxElement->getPropertyValue("GenerateVbaEvents") >>= bHandleVbaEvents;
873 : }
874 170 : catch( const Exception& )
875 : {
876 : }
877 506 : if ( bHandleVbaEvents )
878 : {
879 0 : Reference< XEventAttacherManager > xMgr ( pElementMetaData->xInterface, UNO_QUERY );
880 0 : if ( xMgr.is() )
881 : {
882 0 : OInterfaceContainer* pIfcMgr = dynamic_cast< OInterfaceContainer* >( xMgr.get() );
883 0 : sal_Int32 nLen = pIfcMgr->getCount();
884 0 : for ( sal_Int32 i = 0; (i < nLen) && pIfcMgr ; ++i )
885 : {
886 : // add fake events to the control at index i
887 0 : pIfcMgr->impl_addVbEvents_nolck_nothrow( i );
888 : }
889 : }
890 : else
891 : {
892 : // add fake events to the control at index i
893 0 : impl_addVbEvents_nolck_nothrow( _nIndex );
894 0 : }
895 : }
896 :
897 : // fire the notification about the change
898 506 : if ( _bFire )
899 : {
900 : // notify listeners
901 504 : ContainerEvent aEvt;
902 504 : aEvt.Source = static_cast<XContainer*>(this);
903 504 : aEvt.Accessor <<= _nIndex;
904 504 : aEvt.Element = pElementMetaData->aElementTypeInterface;
905 :
906 504 : aGuard.clear();
907 504 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
908 507 : }
909 506 : }
910 :
911 : //------------------------------------------------------------------------------
912 0 : void OInterfaceContainer::removeElementsNoEvents(sal_Int32 nIndex)
913 : {
914 0 : OInterfaceArray::iterator i = m_aItems.begin() + nIndex;
915 0 : InterfaceRef xElement(*i);
916 :
917 0 : OInterfaceMap::iterator j = m_aMap.begin();
918 0 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
919 :
920 0 : m_aItems.erase(i);
921 0 : m_aMap.erase(j);
922 :
923 0 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
924 0 : if (xSet.is())
925 0 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
926 :
927 0 : Reference<XChild> xChild(xElement, UNO_QUERY);
928 0 : if (xChild.is())
929 0 : xChild->setParent(InterfaceRef ());
930 0 : }
931 :
932 : //------------------------------------------------------------------------------
933 506 : void OInterfaceContainer::implInserted( const ElementDescription* /*_pElement*/ )
934 : {
935 : // not inrerested in
936 506 : }
937 :
938 : //------------------------------------------------------------------------------
939 224 : void OInterfaceContainer::implRemoved( const InterfaceRef& /*_rxObject*/ )
940 : {
941 : // not inrerested in
942 224 : }
943 :
944 : //------------------------------------------------------------------------------
945 6 : void OInterfaceContainer::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
946 : {
947 6 : _rInstanceLock.clear();
948 6 : m_aContainerListeners.notifyEach( &XContainerListener::elementReplaced, _rEvent );
949 6 : }
950 :
951 : // XIndexContainer
952 : //------------------------------------------------------------------------------
953 274 : void SAL_CALL OInterfaceContainer::insertByIndex( sal_Int32 _nIndex, const Any& _rElement ) throw(IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
954 : {
955 274 : Reference< XPropertySet > xElement;
956 274 : _rElement >>= xElement;
957 275 : implInsert( _nIndex, xElement, sal_True /* event handling */ , NULL /* not yet approved */ , sal_True /* notification */ );
958 273 : }
959 :
960 : //------------------------------------------------------------------------------
961 7 : void OInterfaceContainer::implReplaceByIndex( const sal_Int32 _nIndex, const Any& _rNewElement, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
962 : {
963 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implReplaceByIndex: precondition not met (index)!" );
964 :
965 : // approve the new object
966 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
967 7 : ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
968 : SAL_WNODEPRECATED_DECLARATIONS_POP
969 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::implReplaceByIndex: createElementMetaData returned nonsense!" );
970 : {
971 7 : Reference< XPropertySet > xElementProps;
972 7 : _rNewElement >>= xElementProps;
973 8 : approveNewElement( xElementProps, aElementMetaData.get() );
974 : }
975 :
976 : // get the old element
977 12 : InterfaceRef xOldElement( m_aItems[ _nIndex ] );
978 : DBG_ASSERT( xOldElement.get() == Reference< XInterface >( xOldElement, UNO_QUERY ).get(),
979 : "OInterfaceContainer::implReplaceByIndex: elements should be held normalized!" );
980 :
981 : // locate the old element in the map
982 6 : OInterfaceMap::iterator j = m_aMap.begin();
983 13 : while ( ( j != m_aMap.end() ) && ( j->second.get() != xOldElement.get() ) )
984 1 : ++j;
985 :
986 : // remove event knittings
987 6 : if ( m_xEventAttacher.is() )
988 : {
989 6 : InterfaceRef xNormalized( xOldElement, UNO_QUERY );
990 6 : m_xEventAttacher->detach( _nIndex, xNormalized );
991 6 : m_xEventAttacher->removeEntry( _nIndex );
992 : }
993 :
994 : // don't listen for property changes anymore
995 12 : Reference<XPropertySet> xSet( xOldElement, UNO_QUERY );
996 6 : if (xSet.is())
997 6 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
998 :
999 : // give the old element a new (void) parent
1000 12 : Reference<XChild> xChild(xOldElement, UNO_QUERY);
1001 6 : if (xChild.is())
1002 6 : xChild->setParent(InterfaceRef ());
1003 :
1004 : // remove the old one
1005 6 : m_aMap.erase(j);
1006 :
1007 : // examine the new element
1008 12 : OUString sName;
1009 : DBG_ASSERT( aElementMetaData.get()->xPropertySet.is(), "OInterfaceContainer::implReplaceByIndex: what did approveNewElement do?" );
1010 :
1011 6 : aElementMetaData.get()->xPropertySet->getPropertyValue(PROPERTY_NAME) >>= sName;
1012 6 : aElementMetaData.get()->xPropertySet->addPropertyChangeListener(PROPERTY_NAME, this);
1013 :
1014 : // insert the new one
1015 6 : m_aMap.insert( ::std::pair<const OUString, InterfaceRef >( sName, aElementMetaData.get()->xInterface ) );
1016 6 : m_aItems[ _nIndex ] = aElementMetaData.get()->xInterface;
1017 :
1018 6 : aElementMetaData.get()->xChild->setParent(static_cast<XContainer*>(this));
1019 :
1020 6 : if ( m_xEventAttacher.is() )
1021 : {
1022 6 : m_xEventAttacher->insertEntry( _nIndex );
1023 6 : m_xEventAttacher->attach( _nIndex, aElementMetaData.get()->xInterface, makeAny( aElementMetaData.get()->xPropertySet ) );
1024 : }
1025 :
1026 12 : ContainerEvent aReplaceEvent;
1027 6 : aReplaceEvent.Source = static_cast< XContainer* >( this );
1028 6 : aReplaceEvent.Accessor <<= _nIndex;
1029 6 : aReplaceEvent.Element = aElementMetaData.get()->xInterface->queryInterface( m_aElementType );
1030 6 : aReplaceEvent.ReplacedElement = xOldElement->queryInterface( m_aElementType );
1031 :
1032 13 : impl_replacedElement( aReplaceEvent, _rClearBeforeNotify );
1033 6 : }
1034 :
1035 : //------------------------------------------------------------------------------
1036 229 : void OInterfaceContainer::implCheckIndex( const sal_Int32 _nIndex ) SAL_THROW( ( ::com::sun::star::lang::IndexOutOfBoundsException ) )
1037 : {
1038 229 : if (_nIndex < 0 || _nIndex >= (sal_Int32)m_aItems.size())
1039 2 : throw IndexOutOfBoundsException();
1040 227 : }
1041 :
1042 : //------------------------------------------------------------------------------
1043 4 : void SAL_CALL OInterfaceContainer::replaceByIndex(sal_Int32 _nIndex, const Any& Element) throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1044 : {
1045 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1046 : // check the index
1047 4 : implCheckIndex( _nIndex );
1048 : // do the replace
1049 5 : implReplaceByIndex( _nIndex, Element, aGuard );
1050 2 : }
1051 :
1052 : //------------------------------------------------------------------------------
1053 224 : void OInterfaceContainer::implRemoveByIndex( const sal_Int32 _nIndex, ::osl::ClearableMutexGuard& _rClearBeforeNotify )
1054 : {
1055 : OSL_PRECOND( ( _nIndex >= 0 ) && ( _nIndex < (sal_Int32)m_aItems.size() ), "OInterfaceContainer::implRemoveByIndex: precondition not met (index)!" );
1056 :
1057 224 : OInterfaceArray::iterator i = m_aItems.begin() + _nIndex;
1058 224 : InterfaceRef xElement(*i);
1059 :
1060 224 : OInterfaceMap::iterator j = m_aMap.begin();
1061 224 : while (j != m_aMap.end() && (*j).second != xElement) ++j;
1062 :
1063 224 : m_aItems.erase(i);
1064 224 : m_aMap.erase(j);
1065 :
1066 : // remove event knittings
1067 224 : if ( m_xEventAttacher.is() )
1068 : {
1069 224 : InterfaceRef xNormalized( xElement, UNO_QUERY );
1070 224 : m_xEventAttacher->detach( _nIndex, xNormalized );
1071 224 : m_xEventAttacher->removeEntry( _nIndex );
1072 : }
1073 :
1074 448 : Reference<XPropertySet> xSet(xElement, UNO_QUERY);
1075 224 : if (xSet.is())
1076 224 : xSet->removePropertyChangeListener(PROPERTY_NAME, this);
1077 :
1078 448 : Reference<XChild> xChild(xElement, UNO_QUERY);
1079 224 : if (xChild.is())
1080 224 : xChild->setParent(InterfaceRef ());
1081 :
1082 : // notify derived classes
1083 224 : implRemoved(xElement);
1084 :
1085 : // notify listeners
1086 448 : ContainerEvent aEvt;
1087 224 : aEvt.Source = static_cast<XContainer*>(this);
1088 224 : aEvt.Element = xElement->queryInterface( m_aElementType );
1089 224 : aEvt.Accessor <<= _nIndex;
1090 :
1091 224 : _rClearBeforeNotify.clear();
1092 448 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
1093 224 : }
1094 :
1095 : //------------------------------------------------------------------------------
1096 225 : void SAL_CALL OInterfaceContainer::removeByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
1097 : {
1098 225 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1099 : // check the index
1100 225 : implCheckIndex( _nIndex );
1101 : // do the removal
1102 225 : implRemoveByIndex( _nIndex, aGuard );
1103 224 : }
1104 :
1105 : //------------------------------------------------------------------------
1106 457 : ElementDescription* OInterfaceContainer::createElementMetaData( )
1107 : {
1108 457 : return new ElementDescription;
1109 : }
1110 :
1111 : //------------------------------------------------------------------------
1112 232 : void SAL_CALL OInterfaceContainer::insertByName(const OUString& _rName, const Any& _rElement) throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
1113 : {
1114 232 : Reference< XPropertySet > xElementProps;
1115 :
1116 : SAL_WNODEPRECATED_DECLARATIONS_PUSH
1117 464 : ::std::auto_ptr< ElementDescription > aElementMetaData( createElementMetaData() );
1118 : SAL_WNODEPRECATED_DECLARATIONS_POP
1119 : DBG_ASSERT( aElementMetaData.get(), "OInterfaceContainer::insertByName: createElementMetaData returned nonsense!" );
1120 :
1121 : // ensure the correct name of the element
1122 : try
1123 : {
1124 232 : _rElement >>= xElementProps;
1125 232 : approveNewElement( xElementProps, aElementMetaData.get() );
1126 :
1127 231 : xElementProps->setPropertyValue( PROPERTY_NAME, makeAny( _rName ) );
1128 : }
1129 2 : catch( const IllegalArgumentException& )
1130 : {
1131 1 : throw; // allowed to leave
1132 : }
1133 0 : catch( const ElementExistException& )
1134 : {
1135 0 : throw; // allowed to leave
1136 : }
1137 0 : catch( const Exception& )
1138 : {
1139 : SAL_WARN("forms.misc", "OInterfaceContainer::insertByName: caught an exception!" );
1140 : }
1141 463 : implInsert( m_aItems.size(), xElementProps, sal_True, aElementMetaData.get(), sal_True );
1142 231 : }
1143 :
1144 : //------------------------------------------------------------------------
1145 4 : void SAL_CALL OInterfaceContainer::replaceByName(const OUString& Name, const Any& Element) throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
1146 : {
1147 4 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1148 : ::std::pair <OInterfaceMap::iterator,
1149 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1150 4 : if (aPair.first == aPair.second)
1151 0 : throw NoSuchElementException();
1152 :
1153 4 : if (Element.getValueType().getTypeClass() != TypeClass_INTERFACE)
1154 0 : lcl_throwIllegalArgumentException();
1155 :
1156 8 : Reference<XPropertySet> xSet;
1157 4 : Element >>= xSet;
1158 4 : if (xSet.is())
1159 : {
1160 4 : if (!hasProperty(PROPERTY_NAME, xSet))
1161 0 : lcl_throwIllegalArgumentException();
1162 :
1163 4 : xSet->setPropertyValue(PROPERTY_NAME, makeAny(Name));
1164 : }
1165 :
1166 : // determine the element pos
1167 4 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1168 :
1169 8 : implReplaceByIndex( nPos, Element, aGuard );
1170 4 : }
1171 :
1172 : //------------------------------------------------------------------------
1173 4 : void SAL_CALL OInterfaceContainer::removeByName(const OUString& Name) throw( NoSuchElementException, WrappedTargetException, RuntimeException )
1174 : {
1175 4 : ::osl::MutexGuard aGuard( m_rMutex );
1176 : ::std::pair <OInterfaceMap::iterator,
1177 4 : OInterfaceMap::iterator> aPair = m_aMap.equal_range(Name);
1178 4 : if (aPair.first == aPair.second)
1179 1 : throw NoSuchElementException();
1180 :
1181 3 : sal_Int32 nPos = ::std::find(m_aItems.begin(), m_aItems.end(), (*aPair.first).second) - m_aItems.begin();
1182 4 : removeByIndex(nPos);
1183 3 : }
1184 :
1185 :
1186 : // XEventAttacherManager
1187 : //------------------------------------------------------------------------
1188 3 : void SAL_CALL OInterfaceContainer::registerScriptEvent( sal_Int32 nIndex, const ScriptEventDescriptor& aScriptEvent ) throw(IllegalArgumentException, RuntimeException)
1189 : {
1190 3 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1191 3 : if ( m_xEventAttacher.is() )
1192 : {
1193 3 : m_xEventAttacher->registerScriptEvent( nIndex, aScriptEvent );
1194 3 : aGuard.clear();
1195 3 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1196 3 : }
1197 3 : }
1198 :
1199 : //------------------------------------------------------------------------
1200 240 : void SAL_CALL OInterfaceContainer::registerScriptEvents( sal_Int32 nIndex, const Sequence< ScriptEventDescriptor >& aScriptEvents ) throw(IllegalArgumentException, RuntimeException)
1201 : {
1202 240 : ::osl::ClearableMutexGuard aGuard( m_rMutex );
1203 240 : if ( m_xEventAttacher.is() )
1204 : {
1205 240 : m_xEventAttacher->registerScriptEvents( nIndex, aScriptEvents );
1206 240 : aGuard.clear();
1207 240 : impl_addVbEvents_nolck_nothrow( nIndex ); // add fake vba events
1208 240 : }
1209 240 : }
1210 :
1211 : //------------------------------------------------------------------------
1212 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvent( sal_Int32 nIndex, const OUString& aListenerType, const OUString& aEventMethod, const OUString& aRemoveListenerParam ) throw(IllegalArgumentException, RuntimeException)
1213 : {
1214 1 : if ( m_xEventAttacher.is() )
1215 1 : m_xEventAttacher->revokeScriptEvent( nIndex, aListenerType, aEventMethod, aRemoveListenerParam );
1216 1 : }
1217 :
1218 : //------------------------------------------------------------------------
1219 1 : void SAL_CALL OInterfaceContainer::revokeScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1220 : {
1221 1 : if ( m_xEventAttacher.is() )
1222 1 : m_xEventAttacher->revokeScriptEvents( nIndex );
1223 1 : }
1224 :
1225 : //------------------------------------------------------------------------
1226 1 : void SAL_CALL OInterfaceContainer::insertEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1227 : {
1228 1 : if ( m_xEventAttacher.is() )
1229 1 : m_xEventAttacher->insertEntry( nIndex );
1230 1 : }
1231 :
1232 : //------------------------------------------------------------------------
1233 1 : void SAL_CALL OInterfaceContainer::removeEntry( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1234 : {
1235 1 : if ( m_xEventAttacher.is() )
1236 1 : m_xEventAttacher->removeEntry( nIndex );
1237 1 : }
1238 :
1239 : //------------------------------------------------------------------------
1240 8 : Sequence< ScriptEventDescriptor > SAL_CALL OInterfaceContainer::getScriptEvents( sal_Int32 nIndex ) throw(IllegalArgumentException, RuntimeException)
1241 : {
1242 8 : Sequence< ScriptEventDescriptor > aReturn;
1243 8 : if ( m_xEventAttacher.is() )
1244 : {
1245 8 : aReturn = m_xEventAttacher->getScriptEvents( nIndex );
1246 8 : if ( lcl_hasVbaEvents( aReturn ) )
1247 : {
1248 0 : aReturn = lcl_stripVbaEvents( aReturn );
1249 : }
1250 : }
1251 8 : return aReturn;
1252 : }
1253 :
1254 : //------------------------------------------------------------------------
1255 143 : void SAL_CALL OInterfaceContainer::attach( sal_Int32 nIndex, const Reference< XInterface >& xObject, const Any& aHelper ) throw(IllegalArgumentException, ServiceNotRegisteredException, RuntimeException)
1256 : {
1257 143 : if ( m_xEventAttacher.is() )
1258 143 : m_xEventAttacher->attach( nIndex, xObject, aHelper );
1259 143 : }
1260 :
1261 : //------------------------------------------------------------------------
1262 143 : void SAL_CALL OInterfaceContainer::detach( sal_Int32 nIndex, const Reference< XInterface >& xObject ) throw(IllegalArgumentException, RuntimeException)
1263 : {
1264 143 : if ( m_xEventAttacher.is() )
1265 143 : m_xEventAttacher->detach( nIndex, xObject );
1266 143 : }
1267 :
1268 : //------------------------------------------------------------------------
1269 757 : void SAL_CALL OInterfaceContainer::addScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1270 : {
1271 757 : if ( m_xEventAttacher.is() )
1272 757 : m_xEventAttacher->addScriptListener( xListener );
1273 757 : }
1274 :
1275 : //------------------------------------------------------------------------
1276 753 : void SAL_CALL OInterfaceContainer::removeScriptListener( const Reference< XScriptListener >& xListener ) throw(IllegalArgumentException, RuntimeException)
1277 : {
1278 753 : if ( m_xEventAttacher.is() )
1279 753 : m_xEventAttacher->removeScriptListener( xListener );
1280 753 : }
1281 :
1282 : //==================================================================
1283 : //= OFormComponents
1284 : //==================================================================
1285 : //------------------------------------------------------------------------------
1286 5640 : Any SAL_CALL OFormComponents::queryAggregation(const Type& _rType) throw(RuntimeException)
1287 : {
1288 5640 : Any aReturn = OFormComponents_BASE::queryInterface(_rType);
1289 5640 : if (!aReturn.hasValue())
1290 : {
1291 5630 : aReturn = OInterfaceContainer::queryInterface(_rType);
1292 :
1293 5630 : if (!aReturn.hasValue())
1294 2524 : aReturn = FormComponentsBase::queryAggregation(_rType);
1295 : }
1296 :
1297 5640 : return aReturn;
1298 : }
1299 :
1300 : //------------------------------------------------------------------
1301 0 : Sequence<Type> SAL_CALL OFormComponents::getTypes() throw(RuntimeException)
1302 : {
1303 0 : return ::comphelper::concatSequences(OInterfaceContainer::getTypes(), FormComponentsBase::getTypes(), OFormComponents_BASE::getTypes());
1304 : }
1305 :
1306 : //------------------------------------------------------------------------------
1307 169 : OFormComponents::OFormComponents(const Reference<XComponentContext>& _rxFactory)
1308 : :FormComponentsBase( m_aMutex )
1309 169 : ,OInterfaceContainer( _rxFactory, m_aMutex, XFormComponent::static_type() )
1310 338 : ,OFormComponents_BASE()
1311 : {
1312 169 : }
1313 :
1314 : //------------------------------------------------------------------------------
1315 0 : OFormComponents::OFormComponents( const OFormComponents& _cloneSource )
1316 : :FormComponentsBase( m_aMutex )
1317 : ,OInterfaceContainer( m_aMutex, _cloneSource )
1318 0 : ,OFormComponents_BASE()
1319 : {
1320 0 : }
1321 :
1322 : //------------------------------------------------------------------------------
1323 332 : OFormComponents::~OFormComponents()
1324 : {
1325 166 : if (!FormComponentsBase::rBHelper.bDisposed)
1326 : {
1327 10 : acquire();
1328 10 : dispose();
1329 : }
1330 166 : }
1331 :
1332 : // OComponentHelper
1333 : //------------------------------------------------------------------------------
1334 168 : void OFormComponents::disposing()
1335 : {
1336 168 : OInterfaceContainer::disposing();
1337 168 : FormComponentsBase::disposing();
1338 168 : m_xParent = NULL;
1339 168 : }
1340 :
1341 : //XChild
1342 : //------------------------------------------------------------------------------
1343 157 : void OFormComponents::setParent(const InterfaceRef& Parent) throw( NoSupportException, RuntimeException )
1344 : {
1345 157 : ::osl::MutexGuard aGuard( m_aMutex );
1346 157 : m_xParent = Parent;
1347 157 : }
1348 :
1349 : //------------------------------------------------------------------------------
1350 1492 : InterfaceRef OFormComponents::getParent() throw( RuntimeException )
1351 : {
1352 1492 : return m_xParent;
1353 : }
1354 :
1355 : //.........................................................................
1356 : } // namespace frm
1357 : //.........................................................................
1358 :
1359 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|