summaryrefslogtreecommitdiff
path: root/vcl
diff options
context:
space:
mode:
authorNoel Grandin <noel@peralex.com>2015-09-15 12:18:40 +0200
committerNoel Grandin <noel@peralex.com>2015-09-16 08:38:54 +0200
commitc52baea785109ff546159128c7502533477c9331 (patch)
tree54d001522ba6fd16976e4758408600e6a1fbfbd8 /vcl
parent91d06b09ae019f09bca54718c1c24907762aa3ea (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.hxx1
-rw-r--r--vcl/inc/vcleventlisteners.hxx58
-rw-r--r--vcl/inc/window.h1
-rw-r--r--vcl/opengl/salbmp.cxx1
-rw-r--r--vcl/source/app/vclevent.cxx47
-rw-r--r--vcl/source/window/menu.cxx16
-rw-r--r--vcl/unx/gtk/window/gtksalmenu.cxx2
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);