blob: abd35993c3d509de1482b6abd3bf5b3f0bc924e0 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
//------------------------------------------------------------------
#include "solverutil.hxx"
#include <com/sun/star/container/XContentEnumerationAccess.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/XSingleComponentFactory.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/sheet/XSolver.hpp>
#include <com/sun/star/sheet/XSolverDescription.hpp>
#include <comphelper/processfactory.hxx>
using namespace com::sun::star;
//------------------------------------------------------------------
#define SCSOLVER_SERVICE "com.sun.star.sheet.Solver"
uno::Reference<sheet::XSolver> lcl_CreateSolver( const uno::Reference<uno::XInterface>& xIntFac,
const uno::Reference<uno::XComponentContext>& xCtx )
{
uno::Reference<sheet::XSolver> xSolver;
uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY );
uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY );
if ( xCFac.is() )
{
try
{
uno::Reference<uno::XInterface> xInterface = xCFac->createInstanceWithContext(xCtx);
xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY );
}
catch(uno::Exception&)
{
}
}
if ( !xSolver.is() && xFac.is() )
{
try
{
uno::Reference<uno::XInterface> xInterface = xFac->createInstance();
xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY );
}
catch(uno::Exception&)
{
}
}
return xSolver;
}
// static
void ScSolverUtil::GetImplementations( uno::Sequence<rtl::OUString>& rImplNames,
uno::Sequence<rtl::OUString>& rDescriptions )
{
rImplNames.realloc(0); // clear
rDescriptions.realloc(0);
sal_Int32 nCount = 0;
uno::Reference<uno::XComponentContext> xCtx;
uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory();
uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
try
{
xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
}
catch ( uno::Exception & )
{
}
uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY );
if ( xCtx.is() && xEnAc.is() )
{
uno::Reference<container::XEnumeration> xEnum =
xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) );
if ( xEnum.is() )
{
while ( xEnum->hasMoreElements() )
{
uno::Any aAny = xEnum->nextElement();
uno::Reference<uno::XInterface> xIntFac;
aAny >>= xIntFac;
if ( xIntFac.is() )
{
uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
if ( xInfo.is() )
{
rtl::OUString sName = xInfo->getImplementationName();
rtl::OUString sDescription;
uno::Reference<sheet::XSolver> xSolver = lcl_CreateSolver( xIntFac, xCtx );
uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY );
if ( xDesc.is() )
sDescription = xDesc->getComponentDescription();
if ( !sDescription.getLength() )
sDescription = sName; // use implementation name if no description available
rImplNames.realloc( nCount+1 );
rImplNames[nCount] = sName;
rDescriptions.realloc( nCount+1 );
rDescriptions[nCount] = sDescription;
++nCount;
}
}
}
}
}
}
// static
uno::Reference<sheet::XSolver> ScSolverUtil::GetSolver( const rtl::OUString& rImplName )
{
uno::Reference<sheet::XSolver> xSolver;
uno::Reference<uno::XComponentContext> xCtx;
uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory();
uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY);
try
{
xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx;
}
catch ( uno::Exception & )
{
}
uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY );
if ( xCtx.is() && xEnAc.is() )
{
uno::Reference<container::XEnumeration> xEnum =
xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) );
if ( xEnum.is() )
{
while ( xEnum->hasMoreElements() && !xSolver.is() )
{
uno::Any aAny = xEnum->nextElement();
uno::Reference<uno::XInterface> xIntFac;
aAny >>= xIntFac;
if ( xIntFac.is() )
{
uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY );
if ( xInfo.is() )
{
rtl::OUString sName = xInfo->getImplementationName();
if ( sName == rImplName )
xSolver = lcl_CreateSolver( xIntFac, xCtx );
}
}
}
}
}
OSL_ENSURE( xSolver.is(), "can't get solver" );
return xSolver;
}
// static
uno::Sequence<beans::PropertyValue> ScSolverUtil::GetDefaults( const rtl::OUString& rImplName )
{
uno::Sequence<beans::PropertyValue> aDefaults;
uno::Reference<sheet::XSolver> xSolver = GetSolver( rImplName );
uno::Reference<beans::XPropertySet> xPropSet( xSolver, uno::UNO_QUERY );
if ( !xPropSet.is() )
{
// no XPropertySet - no options
return aDefaults;
}
// fill maProperties
uno::Reference<beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo();
OSL_ENSURE( xInfo.is(), "can't get property set info" );
if ( !xInfo.is() )
return aDefaults;
uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties();
const sal_Int32 nSize = aPropSeq.getLength();
aDefaults.realloc(nSize);
sal_Int32 nValid = 0;
for (sal_Int32 nPos=0; nPos<nSize; ++nPos)
{
const beans::Property& rProp = aPropSeq[nPos];
uno::Any aValue = xPropSet->getPropertyValue( rProp.Name );
uno::TypeClass eClass = aValue.getValueTypeClass();
// only use properties of supported types
if ( eClass == uno::TypeClass_BOOLEAN || eClass == uno::TypeClass_LONG || eClass == uno::TypeClass_DOUBLE )
aDefaults[nValid++] = beans::PropertyValue( rProp.Name, -1, aValue, beans::PropertyState_DIRECT_VALUE );
}
aDefaults.realloc(nValid);
//! get user-visible names, sort by them
return aDefaults;
}