1
0
Fork 0
libreoffice/sd/source/ui/framework/configuration/Configuration.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

285 lines
8.8 KiB
C++

/* -*- 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 <framework/Configuration.hxx>
#include <framework/FrameworkHelper.hxx>
#include <com/sun/star/drawing/framework/ConfigurationChangeEvent.hpp>
#include <com/sun/star/drawing/framework/XConfigurationControllerBroadcaster.hpp>
#include <comphelper/sequence.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <rtl/ustrbuf.hxx>
#include <sal/log.hxx>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::sd::framework::FrameworkHelper;
namespace {
/** Use the XResourceId::compareTo() method to implement a compare operator
for STL containers.
*/
class XResourceIdLess
{
public:
bool operator () (const Reference<XResourceId>& rId1, const Reference<XResourceId>& rId2) const
{
return rId1->compareTo(rId2) == -1;
}
};
} // end of anonymous namespace
namespace sd::framework {
class Configuration::ResourceContainer
: public ::std::set<Reference<XResourceId>, XResourceIdLess>
{
public:
ResourceContainer() {}
};
//===== Configuration =========================================================
Configuration::Configuration (
const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster,
bool bBroadcastRequestEvents)
: mpResourceContainer(new ResourceContainer()),
mxBroadcaster(rxBroadcaster),
mbBroadcastRequestEvents(bBroadcastRequestEvents)
{
}
Configuration::Configuration (
const Reference<XConfigurationControllerBroadcaster>& rxBroadcaster,
bool bBroadcastRequestEvents,
const ResourceContainer& rResourceContainer)
: mpResourceContainer(new ResourceContainer(rResourceContainer)),
mxBroadcaster(rxBroadcaster),
mbBroadcastRequestEvents(bBroadcastRequestEvents)
{
}
Configuration::~Configuration()
{
}
void Configuration::disposing(std::unique_lock<std::mutex>&)
{
mpResourceContainer->clear();
mxBroadcaster = nullptr;
}
//----- XConfiguration --------------------------------------------------------
void SAL_CALL Configuration::addResource (const Reference<XResourceId>& rxResourceId)
{
ThrowIfDisposed();
if ( ! rxResourceId.is() || rxResourceId->getResourceURL().isEmpty())
throw css::lang::IllegalArgumentException();
if (mpResourceContainer->insert(rxResourceId).second)
{
SAL_INFO("sd.fwk", __func__ << ": Configuration::addResource() " <<
FrameworkHelper::ResourceIdToString(rxResourceId));
PostEvent(rxResourceId, true);
}
}
void SAL_CALL Configuration::removeResource (const Reference<XResourceId>& rxResourceId)
{
ThrowIfDisposed();
if ( ! rxResourceId.is() || rxResourceId->getResourceURL().isEmpty())
throw css::lang::IllegalArgumentException();
ResourceContainer::iterator iResource (mpResourceContainer->find(rxResourceId));
if (iResource != mpResourceContainer->end())
{
SAL_INFO("sd.fwk", __func__ << ": Configuration::removeResource() " <<
FrameworkHelper::ResourceIdToString(rxResourceId));
PostEvent(rxResourceId,false);
mpResourceContainer->erase(iResource);
}
}
Sequence<Reference<XResourceId> > SAL_CALL Configuration::getResources (
const Reference<XResourceId>& rxAnchorId,
const OUString& rsResourceURLPrefix,
AnchorBindingMode eMode)
{
std::unique_lock aGuard (m_aMutex);
ThrowIfDisposed();
const bool bFilterResources (!rsResourceURLPrefix.isEmpty());
// Collect the matching resources in a vector.
::std::vector<Reference<XResourceId> > aResources;
for (const auto& rxResource : *mpResourceContainer)
{
if ( ! rxResource->isBoundTo(rxAnchorId,eMode))
continue;
if (bFilterResources)
{
// Apply the given resource prefix as filter.
// Make sure that the resource is bound directly to the anchor.
if (eMode != AnchorBindingMode_DIRECT
&& ! rxResource->isBoundTo(rxAnchorId, AnchorBindingMode_DIRECT))
{
continue;
}
// Make sure that the resource URL matches the given prefix.
if ( ! rxResource->getResourceURL().match(rsResourceURLPrefix))
{
continue;
}
}
aResources.push_back(rxResource);
}
return comphelper::containerToSequence(aResources);
}
sal_Bool SAL_CALL Configuration::hasResource (const Reference<XResourceId>& rxResourceId)
{
std::unique_lock aGuard (m_aMutex);
ThrowIfDisposed();
return rxResourceId.is()
&& mpResourceContainer->find(rxResourceId) != mpResourceContainer->end();
}
//----- XCloneable ------------------------------------------------------------
Reference<util::XCloneable> SAL_CALL Configuration::createClone()
{
std::unique_lock aGuard (m_aMutex);
ThrowIfDisposed();
return new Configuration(
mxBroadcaster,
mbBroadcastRequestEvents,
*mpResourceContainer);
}
//----- XNamed ----------------------------------------------------------------
OUString SAL_CALL Configuration::getName()
{
std::unique_lock aGuard (m_aMutex);
OUStringBuffer aString;
if (m_bDisposed)
aString.append("DISPOSED ");
aString.append("Configuration[");
ResourceContainer::const_iterator iResource;
for (iResource=mpResourceContainer->begin();
iResource!=mpResourceContainer->end();
++iResource)
{
if (iResource != mpResourceContainer->begin())
aString.append(", ");
aString.append(FrameworkHelper::ResourceIdToString(*iResource));
}
aString.append("]");
return aString.makeStringAndClear();
}
void SAL_CALL Configuration::setName (const OUString&)
{
// ignored.
}
void Configuration::PostEvent (
const Reference<XResourceId>& rxResourceId,
const bool bActivation)
{
OSL_ASSERT(rxResourceId.is());
if (!mxBroadcaster.is())
return;
ConfigurationChangeEvent aEvent;
aEvent.ResourceId = rxResourceId;
if (bActivation)
if (mbBroadcastRequestEvents)
aEvent.Type = FrameworkHelper::msResourceActivationRequestEvent;
else
aEvent.Type = FrameworkHelper::msResourceActivationEvent;
else
if (mbBroadcastRequestEvents)
aEvent.Type = FrameworkHelper::msResourceDeactivationRequestEvent;
else
aEvent.Type = FrameworkHelper::msResourceDeactivationEvent;
aEvent.Configuration = this;
mxBroadcaster->notifyEvent(aEvent);
}
void Configuration::ThrowIfDisposed() const
{
if (m_bDisposed)
{
throw lang::DisposedException (u"Configuration object has already been disposed"_ustr,
const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
}
}
bool AreConfigurationsEquivalent (
const Reference<XConfiguration>& rxConfiguration1,
const Reference<XConfiguration>& rxConfiguration2)
{
if (rxConfiguration1.is() != rxConfiguration2.is())
return false;
if ( ! rxConfiguration1.is() && ! rxConfiguration2.is())
return true;
// Get the lists of resources from the two given configurations.
const Sequence<Reference<XResourceId> > aResources1(
rxConfiguration1->getResources(
nullptr, OUString(), AnchorBindingMode_INDIRECT));
const Sequence<Reference<XResourceId> > aResources2(
rxConfiguration2->getResources(
nullptr, OUString(), AnchorBindingMode_INDIRECT));
// When the number of resources differ then the configurations can not
// be equivalent.
// Comparison of the two lists of resource ids relies on their
// ordering.
return std::equal(aResources1.begin(), aResources1.end(), aResources2.begin(), aResources2.end(),
[](const Reference<XResourceId>& a, const Reference<XResourceId>& b) {
if (a.is() && b.is())
return a->compareTo(b) == 0;
return a.is() == b.is();
});
}
} // end of namespace sd::framework
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */