create new OPropertyChangeListener2 and use it in FmFieldWin
create OPropertyChangeListener2 as a modified copy of OPropertyChangeListener which uses std::mutex instead of osl::Mutex Change-Id: Ic6be1c62992749e4f0dd23a8c95de63dc45eba3d Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147430 Tested-by: Jenkins Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
@@ -154,6 +154,7 @@ $(eval $(call gb_Library_add_exception_objects,comphelper,\
|
||||
comphelper/source/property/propertysetinfo \
|
||||
comphelper/source/property/propertystatecontainer \
|
||||
comphelper/source/property/propmultiplex \
|
||||
comphelper/source/property/propmultiplex2 \
|
||||
comphelper/source/property/propstate \
|
||||
comphelper/source/streaming/basicio \
|
||||
comphelper/source/streaming/memorystream \
|
||||
|
149
comphelper/source/property/propmultiplex2.cxx
Normal file
149
comphelper/source/property/propmultiplex2.cxx
Normal file
@@ -0,0 +1,149 @@
|
||||
/* -*- 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 .
|
||||
*/
|
||||
|
||||
#include <com/sun/star/beans/XPropertySet.hpp>
|
||||
#include <comphelper/propmultiplex2.hxx>
|
||||
#include <osl/diagnose.h>
|
||||
|
||||
namespace comphelper
|
||||
{
|
||||
using namespace ::com::sun::star::uno;
|
||||
using namespace ::com::sun::star::lang;
|
||||
using namespace ::com::sun::star::beans;
|
||||
|
||||
OPropertyChangeListener2::~OPropertyChangeListener2()
|
||||
{
|
||||
if (m_xAdapter.is())
|
||||
m_xAdapter->onListenerDestruction();
|
||||
}
|
||||
|
||||
void OPropertyChangeListener2::_disposing(const EventObject&)
|
||||
{
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
void OPropertyChangeListener2::disposeAdapter(std::unique_lock<std::mutex>& rGuard)
|
||||
{
|
||||
if (m_xAdapter.is())
|
||||
m_xAdapter->dispose(rGuard);
|
||||
|
||||
// will automatically set a new adapter
|
||||
OSL_ENSURE(!m_xAdapter.is(), "OPropertyChangeListener::disposeAdapter: what did dispose do?");
|
||||
}
|
||||
|
||||
void OPropertyChangeListener2::setAdapter(std::unique_lock<std::mutex>& /*rGuard*/,
|
||||
OPropertyChangeMultiplexer2* pAdapter)
|
||||
{
|
||||
m_xAdapter = pAdapter;
|
||||
}
|
||||
|
||||
OPropertyChangeMultiplexer2::OPropertyChangeMultiplexer2(std::mutex& rMutex,
|
||||
std::unique_lock<std::mutex>& rGuard,
|
||||
OPropertyChangeListener2* _pListener,
|
||||
const Reference<XPropertySet>& _rxSet,
|
||||
bool _bAutoReleaseSet)
|
||||
: m_rMutex(rMutex)
|
||||
, m_xSet(_rxSet)
|
||||
, m_pListener(_pListener)
|
||||
, m_nLockCount(0)
|
||||
, m_bListening(false)
|
||||
, m_bAutoSetRelease(_bAutoReleaseSet)
|
||||
{
|
||||
m_pListener->setAdapter(rGuard, this);
|
||||
}
|
||||
|
||||
OPropertyChangeMultiplexer2::~OPropertyChangeMultiplexer2() {}
|
||||
|
||||
void OPropertyChangeMultiplexer2::lock() { ++m_nLockCount; }
|
||||
|
||||
void OPropertyChangeMultiplexer2::unlock() { --m_nLockCount; }
|
||||
|
||||
void OPropertyChangeMultiplexer2::dispose(std::unique_lock<std::mutex>& rGuard)
|
||||
{
|
||||
if (!m_bListening)
|
||||
return;
|
||||
|
||||
Reference<XPropertyChangeListener> xPreventDelete(this);
|
||||
|
||||
for (const OUString& rProp : m_aProperties)
|
||||
m_xSet->removePropertyChangeListener(rProp, static_cast<XPropertyChangeListener*>(this));
|
||||
|
||||
m_pListener->setAdapter(rGuard, nullptr);
|
||||
|
||||
m_pListener = nullptr;
|
||||
m_bListening = false;
|
||||
|
||||
if (m_bAutoSetRelease)
|
||||
m_xSet = nullptr;
|
||||
}
|
||||
|
||||
void OPropertyChangeMultiplexer2::onListenerDestruction()
|
||||
{
|
||||
if (!m_bListening)
|
||||
return;
|
||||
|
||||
Reference<XPropertyChangeListener> xPreventDelete(this);
|
||||
|
||||
for (const OUString& rProp : m_aProperties)
|
||||
m_xSet->removePropertyChangeListener(rProp, static_cast<XPropertyChangeListener*>(this));
|
||||
}
|
||||
|
||||
// XEventListener
|
||||
|
||||
void SAL_CALL OPropertyChangeMultiplexer2::disposing(const EventObject& _rSource)
|
||||
{
|
||||
std::unique_lock g(m_rMutex);
|
||||
if (m_pListener)
|
||||
{
|
||||
// tell the listener
|
||||
if (!locked())
|
||||
m_pListener->_disposing(_rSource);
|
||||
// disconnect the listener
|
||||
if (m_pListener) // may have been reset whilst calling into _disposing
|
||||
m_pListener->setAdapter(g, nullptr);
|
||||
}
|
||||
|
||||
m_pListener = nullptr;
|
||||
m_bListening = false;
|
||||
|
||||
if (m_bAutoSetRelease)
|
||||
m_xSet = nullptr;
|
||||
}
|
||||
|
||||
// XPropertyChangeListener
|
||||
|
||||
void SAL_CALL OPropertyChangeMultiplexer2::propertyChange(const PropertyChangeEvent& _rEvent)
|
||||
{
|
||||
if (m_pListener && !locked())
|
||||
m_pListener->_propertyChanged(_rEvent);
|
||||
}
|
||||
|
||||
void OPropertyChangeMultiplexer2::addProperty(const OUString& _sPropertyName)
|
||||
{
|
||||
if (m_xSet.is())
|
||||
{
|
||||
m_xSet->addPropertyChangeListener(_sPropertyName,
|
||||
static_cast<XPropertyChangeListener*>(this));
|
||||
m_aProperties.push_back(_sPropertyName);
|
||||
m_bListening = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
115
include/comphelper/propmultiplex2.hxx
Normal file
115
include/comphelper/propmultiplex2.hxx
Normal file
@@ -0,0 +1,115 @@
|
||||
/* -*- 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 .
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <com/sun/star/beans/XPropertyChangeListener.hpp>
|
||||
#include <cppuhelper/implbase.hxx>
|
||||
#include <comphelper/comphelperdllapi.h>
|
||||
#include <rtl/ref.hxx>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
namespace com::sun::star::beans
|
||||
{
|
||||
class XPropertySet;
|
||||
}
|
||||
|
||||
//= property helper classes
|
||||
|
||||
namespace comphelper
|
||||
{
|
||||
class OPropertyChangeMultiplexer2;
|
||||
|
||||
//= OPropertyChangeListener
|
||||
|
||||
/// simple listener adapter for property sets
|
||||
class COMPHELPER_DLLPUBLIC OPropertyChangeListener2
|
||||
{
|
||||
friend class OPropertyChangeMultiplexer2;
|
||||
|
||||
rtl::Reference<OPropertyChangeMultiplexer2> m_xAdapter;
|
||||
|
||||
public:
|
||||
virtual ~OPropertyChangeListener2();
|
||||
|
||||
/// @throws css::uno::RuntimeException
|
||||
virtual void _propertyChanged(const css::beans::PropertyChangeEvent& _rEvent) = 0;
|
||||
/// @throws css::uno::RuntimeException
|
||||
virtual void _disposing(const css::lang::EventObject& _rSource);
|
||||
|
||||
protected:
|
||||
/** If the derivee also owns the mutex which we know as reference, then call this within your
|
||||
derivee's dtor.
|
||||
*/
|
||||
void disposeAdapter(std::unique_lock<std::mutex>& rGuard);
|
||||
|
||||
private:
|
||||
void setAdapter(std::unique_lock<std::mutex>& rGuard, OPropertyChangeMultiplexer2* _pAdapter);
|
||||
};
|
||||
|
||||
//= OPropertyChangeMultiplexer2
|
||||
// A copy of OPropertyChangeMultiplexer except that it uses std::mutex instead osl::Mutex
|
||||
|
||||
/// multiplexer for property changes
|
||||
// workaround for incremental linking bugs in MSVC2019
|
||||
class SAL_DLLPUBLIC_TEMPLATE OPropertyChangeMultiplexer_Base2
|
||||
: public cppu::WeakImplHelper<css::beans::XPropertyChangeListener>
|
||||
{
|
||||
};
|
||||
class COMPHELPER_DLLPUBLIC OPropertyChangeMultiplexer2 final
|
||||
: public OPropertyChangeMultiplexer_Base2
|
||||
{
|
||||
friend class OPropertyChangeListener2;
|
||||
std::mutex& m_rMutex;
|
||||
std::vector<OUString> m_aProperties;
|
||||
css::uno::Reference<css::beans::XPropertySet> m_xSet;
|
||||
OPropertyChangeListener2* m_pListener;
|
||||
sal_Int32 m_nLockCount;
|
||||
bool m_bListening : 1;
|
||||
bool const m_bAutoSetRelease : 1;
|
||||
|
||||
void onListenerDestruction();
|
||||
virtual ~OPropertyChangeMultiplexer2() override;
|
||||
|
||||
public:
|
||||
OPropertyChangeMultiplexer2(std::mutex& rMutex, std::unique_lock<std::mutex>& rGuard,
|
||||
OPropertyChangeListener2* _pListener,
|
||||
const css::uno::Reference<css::beans::XPropertySet>& _rxSet,
|
||||
bool _bAutoReleaseSet = true);
|
||||
|
||||
// XEventListener
|
||||
virtual void SAL_CALL disposing(const css::lang::EventObject& Source) override;
|
||||
|
||||
// XPropertyChangeListener
|
||||
virtual void SAL_CALL propertyChange(const css::beans::PropertyChangeEvent& evt) override;
|
||||
|
||||
/// incremental lock
|
||||
void lock();
|
||||
/// incremental unlock
|
||||
void unlock();
|
||||
/// get the lock count
|
||||
sal_Int32 locked() const { return m_nLockCount; }
|
||||
|
||||
void addProperty(const OUString& aPropertyName);
|
||||
void dispose(std::unique_lock<std::mutex>& rGuard);
|
||||
};
|
||||
|
||||
} // namespace comphelper
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
@@ -112,7 +112,7 @@ IMPL_LINK(FmFieldWin, DragBeginHdl, bool&, rUnsetDragIcon, bool)
|
||||
FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, weld::Window* _pParent)
|
||||
: SfxModelessDialogController(_pBindings, _pMgr, _pParent, "svx/ui/formfielddialog.ui", "FormFieldDialog")
|
||||
, SfxControllerItem(SID_FM_FIELDS_CONTROL, *_pBindings)
|
||||
, comphelper::OPropertyChangeListener(m_aMutex)
|
||||
, comphelper::OPropertyChangeListener2()
|
||||
, m_xListBox(m_xBuilder->weld_tree_view("treeview"))
|
||||
, m_nObjectType(0)
|
||||
{
|
||||
@@ -133,10 +133,13 @@ FmFieldWin::FmFieldWin(SfxBindings* _pBindings, SfxChildWindow* _pMgr, weld::Win
|
||||
|
||||
FmFieldWin::~FmFieldWin()
|
||||
{
|
||||
if (m_xChangeListener.is())
|
||||
{
|
||||
m_xChangeListener->dispose();
|
||||
m_xChangeListener.clear();
|
||||
std::unique_lock g(m_aMutex);
|
||||
if (m_xChangeListener.is())
|
||||
{
|
||||
m_xChangeListener->dispose(g);
|
||||
m_xChangeListener.clear();
|
||||
}
|
||||
}
|
||||
::SfxControllerItem::dispose();
|
||||
}
|
||||
@@ -265,12 +268,13 @@ void FmFieldWin::UpdateContent(const css::uno::Reference< css::form::XForm > & x
|
||||
}
|
||||
|
||||
// listen for changes at ControlSource in PropertySet
|
||||
std::unique_lock g(m_aMutex);
|
||||
if (m_xChangeListener.is())
|
||||
{
|
||||
m_xChangeListener->dispose();
|
||||
m_xChangeListener->dispose(g);
|
||||
m_xChangeListener.clear();
|
||||
}
|
||||
m_xChangeListener = new ::comphelper::OPropertyChangeMultiplexer(this, xSet);
|
||||
m_xChangeListener = new ::comphelper::OPropertyChangeMultiplexer2(m_aMutex, g, this, xSet);
|
||||
m_xChangeListener->addProperty(FM_PROP_DATASOURCE);
|
||||
m_xChangeListener->addProperty(FM_PROP_COMMAND);
|
||||
m_xChangeListener->addProperty(FM_PROP_COMMANDTYPE);
|
||||
|
@@ -25,7 +25,7 @@
|
||||
#include <svx/dbaexchange.hxx>
|
||||
#include <com/sun/star/form/XForm.hpp>
|
||||
|
||||
#include <comphelper/propmultiplex.hxx>
|
||||
#include <comphelper/propmultiplex2.hxx>
|
||||
#include <connectivity/dbtools.hxx>
|
||||
|
||||
class FmFormShell;
|
||||
@@ -33,9 +33,9 @@ struct ColumnInfo;
|
||||
|
||||
class FmFieldWin final : public SfxModelessDialogController
|
||||
, public SfxControllerItem
|
||||
, public ::comphelper::OPropertyChangeListener
|
||||
, public ::comphelper::OPropertyChangeListener2
|
||||
{
|
||||
::osl::Mutex m_aMutex;
|
||||
std::mutex m_aMutex;
|
||||
std::unique_ptr<weld::TreeView> m_xListBox;
|
||||
std::vector<std::unique_ptr<ColumnInfo>> m_aListBoxData;
|
||||
::dbtools::SharedConnection
|
||||
@@ -44,7 +44,7 @@ class FmFieldWin final : public SfxModelessDialogController
|
||||
m_aObjectName;
|
||||
sal_Int32 m_nObjectType;
|
||||
|
||||
rtl::Reference<comphelper::OPropertyChangeMultiplexer> m_xChangeListener;
|
||||
rtl::Reference<comphelper::OPropertyChangeMultiplexer2> m_xChangeListener;
|
||||
rtl::Reference<svx::OColumnTransferable> m_xHelper;
|
||||
|
||||
void addToList(const css::uno::Reference<css::container::XNameAccess>& i_xColumns);
|
||||
|
Reference in New Issue
Block a user