Quellcode-Bibliothek propertycomposer.cxx
Sprache: 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 .
*/
// TODO: there are various places where we determine the first handler in our array which // supports a given property id. This is, at the moment, done with searching all handlers, // which is O( n * k ) at worst (n being the number of handlers, k being the maximum number // of supported properties per handler). Shouldn't we cache this? So that it is O( log k )?
// assume DIRECT for the moment. This will stay this way if *all* slaves // tell the property has DIRECT state, and if *all* values equal
PropertyState eState = PropertyState_DIRECT_VALUE;
// check the master state
Reference< XPropertyHandler > xPrimary( *m_aSlaveHandlers.begin() );
Any aPrimaryValue = xPrimary->getPropertyValue( _rPropertyName );
eState = xPrimary->getPropertyState( _rPropertyName );
// loop through the secondary sets
PropertyState eSecondaryState = PropertyState_DIRECT_VALUE; for ( HandlerArray::const_iterator loop = m_aSlaveHandlers.begin() + 1;
loop != m_aSlaveHandlers.end();
++loop
)
{ // the secondary state
eSecondaryState = (*loop)->getPropertyState( _rPropertyName );
// the secondary value
Any aSecondaryValue( (*loop)->getPropertyValue( _rPropertyName ) );
if ( !m_bSupportedPropertiesAreKnown )
{ // we support a property if and only if all of our slaves support it
// initially, use all the properties of an arbitrary handler (we take the first one)
putIntoBag( (*m_aSlaveHandlers.begin())->getSupportedProperties(), m_aSupportedProperties );
// now intersect with the properties of *all* other handlers for ( HandlerArray::const_iterator loop = m_aSlaveHandlers.begin() + 1;
loop != m_aSlaveHandlers.end();
++loop
)
{ // the properties supported by the current handler
PropertyBag aThisRound;
putIntoBag( (*loop)->getSupportedProperties(), aThisRound );
// the intersection of those properties with all we already have
PropertyBag aIntersection;
std::set_intersection( aThisRound.begin(), aThisRound.end(), m_aSupportedProperties.begin(), m_aSupportedProperties.end(),
std::insert_iterator< PropertyBag >( aIntersection, aIntersection.begin() ), PropertyLessByName() );
m_aSupportedProperties.swap( aIntersection ); if ( m_aSupportedProperties.empty() ) break;
}
// remove those properties which are not composable for ( PropertyBag::iterator check = m_aSupportedProperties.begin();
check != m_aSupportedProperties.end();
)
{ bool bIsComposable = isComposable( check->Name ); if ( !bIsComposable )
{
check = m_aSupportedProperties.erase( check );
} else
++check;
}
// we supersede those properties which are superseded by at least one of our slaves
Sequence< OUString > aSuperseded;
uniteStringArrays( m_aSlaveHandlers, &XPropertyHandler::getSupersededProperties, aSuperseded ); return aSuperseded;
}
// we're interested in those properties which at least one handler wants to have
Sequence< OUString > aActuating;
uniteStringArrays( m_aSlaveHandlers, &XPropertyHandler::getActuatingProperties, aActuating ); return aActuating;
}
// ask the first of the handlers
InteractiveSelectionResult eResult = (*m_aSlaveHandlers.begin())->onInteractivePropertySelection(
_rPropertyName,
_bPrimary,
_rData,
m_pUIRequestComposer->getUIForPropertyHandler( *m_aSlaveHandlers.begin() )
);
switch ( eResult )
{ case InteractiveSelectionResult_Cancelled: // fine break;
case InteractiveSelectionResult_Success: case InteractiveSelectionResult_Pending:
OSL_FAIL( "PropertyComposer::onInteractivePropertySelection: no chance to forward the new value to the other handlers!" ); // This means that we cannot know the new property value, which either has already been set // at the first component ("Success"), or will be set later on once the asynchronous input // is finished ("Pending"). So, we also cannot forward this new property value to the other // handlers. // We would need to be a listener at the property at the first component, but even this wouldn't // be sufficient, since the property handler is free to change *any* property during a dedicated // property UI.
eResult = InteractiveSelectionResult_Cancelled; break;
case InteractiveSelectionResult_ObtainedValue: // OK. Our own caller will pass this as setPropertyValue, and we will then pass it to // all slave handlers break;
default:
OSL_FAIL( "OPropertyBrowserController::onInteractivePropertySelection: unknown result value!" ); break;
}
return eResult;
}
void PropertyComposer::impl_ensureUIRequestComposer( const Reference< XObjectInspectorUI >& _rxInspectorUI )
{
OSL_ENSURE(!m_pUIRequestComposer
|| m_pUIRequestComposer->getDelegatorUI().get() == _rxInspectorUI.get(), "PropertyComposer::impl_ensureUIRequestComposer: somebody's changing the horse " "in the mid of the race!");
if (!m_pUIRequestComposer)
m_pUIRequestComposer.reset( new ComposedPropertyUIUpdate( _rxInspectorUI, this ) );
}
// ask all handlers which expressed interest in this particular property, and "compose" their // commands for the UIUpdater for (autoconst& slaveHandler : m_aSlaveHandlers)
{ // TODO: make this cheaper (cache it?) const StlSyntaxSequence< OUString > aThisHandlersActuatingProps( slaveHandler->getActuatingProperties() ); for (constauto & aThisHandlersActuatingProp : aThisHandlersActuatingProps)
{ if ( aThisHandlersActuatingProp == _rActuatingPropertyName )
{
slaveHandler->actuatingPropertyChanged( _rActuatingPropertyName, _rNewValue, _rOldValue,
m_pUIRequestComposer->getUIForPropertyHandler(slaveHandler),
_bFirstTimeInit ); break;
}
}
}
}
// dispose our slave handlers for (autoconst& slaveHandler : m_aSlaveHandlers)
{
slaveHandler->removePropertyChangeListener( this );
slaveHandler->dispose();
}
clearContainer( m_aSlaveHandlers );
if (m_pUIRequestComposer)
m_pUIRequestComposer->dispose();
m_pUIRequestComposer.reset();
}
void SAL_CALL PropertyComposer::propertyChange( const PropertyChangeEvent& evt )
{ if ( !impl_isSupportedProperty_nothrow( evt.PropertyName ) ) // A slave handler might fire events for more properties than we support. Ignore those. return;
¤ 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.0.1Bemerkung:
(vorverarbeitet)
¤
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.