/* -*- 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 .
*/
/* The ConfigChangeListener_Impl receives notifications from the configuration about changes that have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its "CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired before doing so.
*/
void ConfigItem::CallNotify( const css::uno::Sequence<OUString>& rPropertyNames )
{ // the call is forwarded to the virtual Notify() method // it is pure virtual, so all classes deriving from ConfigItem have to decide how they // want to notify listeners if(m_nInValueChange <= 0 || m_bEnableInternalNotification)
Notify(rPropertyNames);
}
// In special mode ALL_LOCALES we must support reading/writing of localized cfg entries as Sequence< PropertyValue >. // These methods are helper to convert given lists of names and Any-values. // format: PropertyValue.Name = <locale as ISO string> // PropertyValue.Value = <value; type depends from cfg entry!> // e.g. // LOCALIZED NODE // "UIName" // LOCALE VALUE // "de" "Mein Name" // "en-US" "my name"
staticvoid impl_packLocalizedProperties( const Sequence< OUString >& lInNames , const Sequence< Any >& lInValues ,
Sequence< Any >& lOutValues )
{ // This method should be called for special AllLocales ConfigItem-mode only!
// Optimise follow algorithm ... A LITTLE BIT :-) // There exist two different possibilities: // i ) There exist no localized entries ... => size of lOutValues will be the same like lInNames/lInValues! // ii) There exist some (mostly one or two) localized entries ... => size of lOutValues will be the same like lInNames/lInValues! // ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service). // We read all his child nodes and pack it into Sequence< PropertyValue >. // The result list we pack into the return any. We never change size of lists!
lOutValues.realloc(lInNames.getLength());
// Algorithm: // Copy all names and values from in to out lists. // Look for special localized entries ... You can detect it as "XInterface" packed into an Any. // Use this XInterface-object to read all localized values and pack it into Sequence< PropertyValue >. // Add this list to out lists then.
std::transform(lInValues.begin(), lInValues.end(), lOutValues.getArray(), [](const Any& value)
{ // If item is a special localized one ... convert and pack it ... if (value.getValueTypeName() == "com.sun.star.uno.XInterface")
{ if (auto xSetAccess = value.query<XNameContainer>())
{ // list of all locales for localized entry
Sequence<OUString> locales = xSetAccess->getElementNames(); // localized values of a configuration entry packed for return
Sequence<PropertyValue> lProperties(locales.getLength());
return Any(lProperties);
}
} // ... or copy normal items to return lists directly. return value;
});
}
staticvoid impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames , const Sequence< Any >& lInValues ,
Sequence< OUString >& lOutNames ,
Sequence< Any >& lOutValues)
{ // This method should be called for special AllLocales ConfigItem-mode only!
sal_Int32 nSourceSize; // marks end of loop over input lists
sal_Int32 nDestinationCounter; // actual position in output lists
sal_Int32 nPropertiesSize; // marks end of inner loop
OUString sNodeName; // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
Sequence< PropertyValue > lProperties; // localized values of a configuration entry gotten from lInValues-Any
// Optimise follow algorithm ... A LITTLE BIT :-) // There exist two different possibilities: // i ) There exist no localized entries ... => size of lOutNames/lOutValues will be the same like lInNames/lInValues! // ii) There exist some (mostly one or two) localized entries ... => size of lOutNames/lOutValues will be some bytes greater than lInNames/lInValues. // => I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast. // We should reserve same space for output list like input ones first. // Follow algorithm looks for these borders and change it for ii) only! // It will be faster then a "realloc()" call in every loop ...
nSourceSize = lInNames.getLength();
lOutNames.realloc ( nSourceSize ); auto plOutNames = lOutNames.getArray();
lOutValues.realloc ( nSourceSize ); auto plOutValues = lOutValues.getArray();
// Algorithm: // Copy all names and values from const to return lists. // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any. // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
nDestinationCounter = 0; for( sal_Int32 nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
{ // If item a special localized one ... split it and insert his parts to output lists ... if( lInValues[nSourceCounter].getValueType() == cppu::UnoType<Sequence<PropertyValue>>::get() )
{
lInValues[nSourceCounter] >>= lProperties;
nPropertiesSize = lProperties.getLength();
// size of return list is fix! // Every item must match to length of incoming name list.
sal_Int32 nCount = rNames.getLength();
Sequence< sal_Bool > lStates(nCount);
sal_Bool* plStates = lStates.getArray();
// We must be sure to return a valid information every time! // Set default to non readonly... similar to the configuration handling of this property.
std::fill_n(plStates, lStates.getLength(), false);
// no access - no information...
Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree(); if (!xHierarchyAccess.is()) return lStates;
bool ConfigItem::PutProperties(
css::uno::Reference<css::container::XHierarchicalNameAccess> const & xHierarchyAccess, const Sequence< OUString >& rNames, const Sequence< Any>& rValues, bool bAllLocales)
{
Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY); bool bRet = xTopNodeReplace.is(); if(bRet)
{
Sequence< OUString > lNames;
Sequence< Any > lValues; const OUString* pNames = nullptr; const Any* pValues = nullptr;
sal_Int32 nNameCount; if(bAllLocales)
{ // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue > // as value of a localized configuration entry! // How we can do that? // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
pNames = lNames.getConstArray ();
pValues = lValues.getConstArray ();
nNameCount = lNames.getLength ();
} else
{ // This is the normal mode ... // Use given input lists directly.
pNames = rNames.getConstArray ();
pValues = rValues.getConstArray ();
nNameCount = rNames.getLength ();
} for(int i = 0; i < nNameCount; i++)
{ try
{
OUString sNode, sProperty; if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
{
Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
// JB: Change: now the same name handling for sets of simple values const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.