diff options
author | Noel Grandin <noel@peralex.com> | 2015-09-15 12:18:40 +0200 |
---|---|---|
committer | Noel Grandin <noel@peralex.com> | 2015-09-16 08:38:54 +0200 |
commit | c52baea785109ff546159128c7502533477c9331 (patch) | |
tree | 54d001522ba6fd16976e4758408600e6a1fbfbd8 /vcl | |
parent | 91d06b09ae019f09bca54718c1c24907762aa3ea (diff) |
clean up VclEventListeners and VclEventListeners2
Move them inside the vcl module. there is no need to expose their
implementation.
Make the VclEventListeners2 implementation similar to the
VclEventListeners implemenation - I can't see the benefit of this extra
complication with invalidated iterators, given the very small number
of listeners typically on such a list.
Change-Id: I040ddd24b10d2109af13ee25b5181703af17a109
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/inc/svdata.hxx | 1 | ||||
-rw-r--r-- | vcl/inc/vcleventlisteners.hxx | 58 | ||||
-rw-r--r-- | vcl/inc/window.h | 1 | ||||
-rw-r--r-- | vcl/opengl/salbmp.cxx | 1 | ||||
-rw-r--r-- | vcl/source/app/vclevent.cxx | 47 | ||||
-rw-r--r-- | vcl/source/window/menu.cxx | 16 | ||||
-rw-r--r-- | vcl/unx/gtk/window/gtksalmenu.cxx | 2 |
7 files changed, 92 insertions, 34 deletions
diff --git a/vcl/inc/svdata.hxx b/vcl/inc/svdata.hxx index 0d8e02c8e110..e7496aa71d24 100644 --- a/vcl/inc/svdata.hxx +++ b/vcl/inc/svdata.hxx @@ -35,6 +35,7 @@ #include "vcl/keycod.hxx" #include "vcl/svapp.hxx" #include "vcl/vclevent.hxx" +#include "vcleventlisteners.hxx" #include "unotools/options.hxx" diff --git a/vcl/inc/vcleventlisteners.hxx b/vcl/inc/vcleventlisteners.hxx new file mode 100644 index 000000000000..8e3b026ca953 --- /dev/null +++ b/vcl/inc/vcleventlisteners.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#ifndef INCLUDED_VCL_INC_VCLEVENTLISTENERS_HXX +#define INCLUDED_VCL_INC_VCLEVENTLISTENERS_HXX + +#include <tools/link.hxx> +#include <tools/rtti.hxx> +#include <vcl/dllapi.h> +#include <vcl/impdel.hxx> +#include <vcl/vclptr.hxx> +#include <vcl/window.hxx> + +#include <com/sun/star/uno/Reference.hxx> + +#include <vector> + +class VCL_DLLPUBLIC VclEventListeners +{ +public: + void Call( VclSimpleEvent* pEvent ) const; + void addListener( const Link<>& rListener ); + void removeListener( const Link<>& rListener ); +private: + std::vector<Link<>> m_aListeners; +}; + +class VCL_DLLPUBLIC VclEventListeners2 : public vcl::DeletionNotifier +{ + std::vector<Link<>> m_aListeners; +public: + VclEventListeners2(); + ~VclEventListeners2(); + + void addListener( const Link<>& ); + void removeListener( const Link<>& ); + void callListeners( VclSimpleEvent* ); +}; + +#endif // INCLUDED_VCL_INC_VCLEVENTLISTENERS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/inc/window.h b/vcl/inc/window.h index 2e56cc77e71e..4745bf6a4372 100644 --- a/vcl/inc/window.h +++ b/vcl/inc/window.h @@ -37,6 +37,7 @@ #include <vcl/vclevent.hxx> #include <vcl/vclptr.hxx> #include <vcl/rendersettings.hxx> +#include "vcleventlisteners.hxx" #include <vector> struct SalPaintEvent; diff --git a/vcl/opengl/salbmp.cxx b/vcl/opengl/salbmp.cxx index fefa3817b8b2..05c100058567 100644 --- a/vcl/opengl/salbmp.cxx +++ b/vcl/opengl/salbmp.cxx @@ -27,6 +27,7 @@ #include "vcl/salbtype.hxx" #include "svdata.hxx" #include "salgdi.hxx" +#include "vcleventlisteners.hxx" #include "opengl/zone.hxx" #include "opengl/program.hxx" diff --git a/vcl/source/app/vclevent.cxx b/vcl/source/app/vclevent.cxx index bc3ca538f285..7cb291d95eb5 100644 --- a/vcl/source/app/vclevent.cxx +++ b/vcl/source/app/vclevent.cxx @@ -21,6 +21,7 @@ #include "vcl/window.hxx" #include "svdata.hxx" +#include "vcleventlisteners.hxx" #include <com/sun/star/accessibility/XAccessible.hpp> @@ -94,47 +95,35 @@ VclEventListeners2::~VclEventListeners2() { } -void VclEventListeners2::addListener( const Link<>& i_rLink ) +void VclEventListeners2::addListener( const Link<>& rListener ) { // ensure uniqueness - for( std::list< Link<> >::const_iterator it = m_aListeners.begin(); it != m_aListeners.end(); ++it ) - { - if( *it == i_rLink ) - return; - } - m_aListeners.push_back( i_rLink ); + if (std::find(m_aListeners.begin(), m_aListeners.end(), rListener) == m_aListeners.end()) + m_aListeners.push_back( rListener ); } -void VclEventListeners2::removeListener( const Link<>& i_rLink ) +void VclEventListeners2::removeListener( const Link<>& rListener ) { - size_t n = m_aIterators.size(); - for( size_t i = 0; i < n; i++ ) - { - if( m_aIterators[i].m_aIt != m_aListeners.end() && *m_aIterators[i].m_aIt == i_rLink ) - { - m_aIterators[i].m_bWasInvalidated = true; - ++m_aIterators[i].m_aIt; - } - } - m_aListeners.remove( i_rLink ); + m_aListeners.erase( std::remove(m_aListeners.begin(), m_aListeners.end(), rListener ), m_aListeners.end() ); } -void VclEventListeners2::callListeners( VclSimpleEvent* i_pEvent ) +void VclEventListeners2::callListeners( VclSimpleEvent* pEvent ) { vcl::DeletionListener aDel( this ); - m_aIterators.push_back(ListenerIt(m_aListeners.begin())); - size_t nIndex = m_aIterators.size() - 1; - while( ! aDel.isDeleted() && m_aIterators[ nIndex ].m_aIt != m_aListeners.end() ) + // Copy the list, because this can be destroyed when calling a Link... + std::vector<Link<>> aCopy( m_aListeners ); + std::vector<Link<>>::iterator aIter( aCopy.begin() ); + std::vector<Link<>>::const_iterator aEnd( aCopy.end() ); + + while ( aIter != aEnd && ! aDel.isDeleted() ) { - m_aIterators[ nIndex ].m_aIt->Call( i_pEvent ); - if( m_aIterators[ nIndex ].m_bWasInvalidated ) - // check if the current element was removed and the iterator increased in the meantime - m_aIterators[ nIndex ].m_bWasInvalidated = false; - else - ++m_aIterators[ nIndex ].m_aIt; + Link<> &rLink = *aIter; + // check this hasn't been removed in some re-enterancy scenario fdo#47368 + if( std::find(m_aListeners.begin(), m_aListeners.end(), rLink) != m_aListeners.end() ) + rLink.Call( pEvent ); + ++aIter; } - m_aIterators.pop_back(); } diff --git a/vcl/source/window/menu.cxx b/vcl/source/window/menu.cxx index e49ff60f5ec4..e5acc2eca589 100644 --- a/vcl/source/window/menu.cxx +++ b/vcl/source/window/menu.cxx @@ -3240,16 +3240,24 @@ ImplMenuDelData::~ImplMenuDelData() namespace vcl { namespace MenuInvalidator { static VclEventListeners2* pMenuInvalidateListeners = NULL; - VclEventListeners2* GetMenuInvalidateListeners() + void AddMenuInvalidateListener(const Link<>& rLink) { if(!pMenuInvalidateListeners) pMenuInvalidateListeners = new VclEventListeners2(); - return pMenuInvalidateListeners; + pMenuInvalidateListeners->addListener(rLink); + } + void CallMenuInvalidateListeners(VclSimpleEvent* pEvent) + { + if(pMenuInvalidateListeners) + pMenuInvalidateListeners->callListeners(pEvent); } void Invalidated() { - VclSimpleEvent aEvent(0); - GetMenuInvalidateListeners()->callListeners(&aEvent); + if(pMenuInvalidateListeners) + { + VclSimpleEvent aEvent(0); + pMenuInvalidateListeners->callListeners(&aEvent); + } }; } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/vcl/unx/gtk/window/gtksalmenu.cxx b/vcl/unx/gtk/window/gtksalmenu.cxx index 0dce1c49baf1..ba2c894a86db 100644 --- a/vcl/unx/gtk/window/gtksalmenu.cxx +++ b/vcl/unx/gtk/window/gtksalmenu.cxx @@ -414,7 +414,7 @@ void GtkSalMenu::SetFrame( const SalFrame* pFrame ) { SolarMutexGuard aGuard; { - vcl::MenuInvalidator::GetMenuInvalidateListeners()->addListener(*getRefreshLinkInstance()); + vcl::MenuInvalidator::AddMenuInvalidateListener(*getRefreshLinkInstance()); } assert(mbMenuBar); |