Branch libreoffice-5-0-4
[LibreOffice.git] / vcl / source / app / vclevent.cxx
blob00c4ffd525e2ae26494ee8409778a62472869828
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "vcl/vclevent.hxx"
21 #include "vcl/window.hxx"
23 #include "svdata.hxx"
25 #include <com/sun/star/accessibility/XAccessible.hpp>
27 using ::com::sun::star::uno::Reference;
28 using ::com::sun::star::accessibility::XAccessible;
30 TYPEINIT0(VclSimpleEvent);
31 TYPEINIT1(VclWindowEvent, VclSimpleEvent);
32 TYPEINIT1(VclMenuEvent, VclSimpleEvent);
34 VclAccessibleEvent::VclAccessibleEvent( sal_uLong n, const Reference<XAccessible>& rxAccessible ) :
35 VclSimpleEvent(n),
36 mxAccessible(rxAccessible)
40 VclAccessibleEvent::~VclAccessibleEvent()
45 void VclEventListeners::Call( VclSimpleEvent* pEvent ) const
47 if ( m_aListeners.empty() )
48 return;
50 // Copy the list, because this can be destroyed when calling a Link...
51 std::list<Link<>> aCopy( m_aListeners );
52 std::list<Link<>>::iterator aIter( aCopy.begin() );
53 std::list<Link<>>::const_iterator aEnd( aCopy.end() );
54 if( pEvent->IsA( VclWindowEvent::StaticType() ) )
56 VclWindowEvent* pWinEvent = static_cast<VclWindowEvent*>(pEvent);
57 ImplDelData aDel( pWinEvent->GetWindow() );
58 while ( aIter != aEnd && ! aDel.IsDead() )
60 Link<> &rLink = *aIter;
61 // check this hasn't been removed in some re-enterancy scenario fdo#47368
62 if( std::find(m_aListeners.begin(), m_aListeners.end(), rLink) != m_aListeners.end() )
63 rLink.Call( pEvent );
64 ++aIter;
67 else
69 while ( aIter != aEnd )
71 Link<> &rLink = *aIter;
72 if( std::find(m_aListeners.begin(), m_aListeners.end(), rLink) != m_aListeners.end() )
73 rLink.Call( pEvent );
74 ++aIter;
79 bool VclEventListeners::Process( VclSimpleEvent* pEvent ) const
81 if ( m_aListeners.empty() )
82 return false;
84 bool bProcessed = false;
85 // Copy the list, because this can be destroyed when calling a Link...
86 std::list<Link<>> aCopy( m_aListeners );
87 std::list<Link<>>::iterator aIter( aCopy.begin() );
88 std::list<Link<>>::const_iterator aEnd( aCopy.end() );
89 while ( aIter != aEnd )
91 if( (*aIter).Call( pEvent ) != 0 )
93 bProcessed = true;
94 break;
96 ++aIter;
98 return bProcessed;
101 void VclEventListeners::addListener( const Link<>& rListener )
103 m_aListeners.push_back( rListener );
106 void VclEventListeners::removeListener( const Link<>& rListener )
108 m_aListeners.remove( rListener );
111 VclEventListeners2::VclEventListeners2()
115 VclEventListeners2::~VclEventListeners2()
119 void VclEventListeners2::addListener( const Link<>& i_rLink )
121 // ensure uniqueness
122 for( std::list< Link<> >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it )
124 if( *it == i_rLink )
125 return;
127 m_aListeners.push_back( i_rLink );
130 void VclEventListeners2::removeListener( const Link<>& i_rLink )
132 size_t n = m_aIterators.size();
133 for( size_t i = 0; i < n; i++ )
135 if( m_aIterators[i].m_aIt != m_aListeners.end() && *m_aIterators[i].m_aIt == i_rLink )
137 m_aIterators[i].m_bWasInvalidated = true;
138 ++m_aIterators[i].m_aIt;
141 m_aListeners.remove( i_rLink );
144 void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent )
146 vcl::DeletionListener aDel( this );
148 m_aIterators.push_back(ListenerIt(m_aListeners.begin()));
149 size_t nIndex = m_aIterators.size() - 1;
150 while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() )
152 m_aIterators[ nIndex ].m_aIt->Call( i_pEvent );
153 if( m_aIterators[ nIndex ].m_bWasInvalidated )
154 // check if the current element was removed and the iterator increased in the meantime
155 m_aIterators[ nIndex ].m_bWasInvalidated = false;
156 else
157 ++m_aIterators[ nIndex ].m_aIt;
159 m_aIterators.pop_back();
163 VclWindowEvent::VclWindowEvent( vcl::Window* pWin, sal_uLong n, void* pDat ) : VclSimpleEvent(n)
165 pWindow = pWin; pData = pDat;
168 VclWindowEvent::~VclWindowEvent() {}
170 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */