1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 //------------------------------------------------------------------ 28 29 #include "solverutil.hxx" 30 31 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 32 #include <com/sun/star/lang/XServiceInfo.hpp> 33 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 34 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 35 #include <com/sun/star/beans/XPropertySet.hpp> 36 #include <com/sun/star/beans/PropertyValue.hpp> 37 #include <com/sun/star/sheet/XSolver.hpp> 38 #include <com/sun/star/sheet/XSolverDescription.hpp> 39 40 #include <comphelper/processfactory.hxx> 41 42 using namespace com::sun::star; 43 44 //------------------------------------------------------------------ 45 46 #define SCSOLVER_SERVICE "com.sun.star.sheet.Solver" 47 48 uno::Reference<sheet::XSolver> lcl_CreateSolver( const uno::Reference<uno::XInterface>& xIntFac, 49 const uno::Reference<uno::XComponentContext>& xCtx ) 50 { 51 uno::Reference<sheet::XSolver> xSolver; 52 53 uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY ); 54 uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY ); 55 if ( xCFac.is() ) 56 { 57 try 58 { 59 uno::Reference<uno::XInterface> xInterface = xCFac->createInstanceWithContext(xCtx); 60 xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY ); 61 } 62 catch(uno::Exception&) 63 { 64 } 65 } 66 if ( !xSolver.is() && xFac.is() ) 67 { 68 try 69 { 70 uno::Reference<uno::XInterface> xInterface = xFac->createInstance(); 71 xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY ); 72 } 73 catch(uno::Exception&) 74 { 75 } 76 } 77 78 return xSolver; 79 } 80 81 // static 82 void ScSolverUtil::GetImplementations( uno::Sequence<rtl::OUString>& rImplNames, 83 uno::Sequence<rtl::OUString>& rDescriptions ) 84 { 85 rImplNames.realloc(0); // clear 86 rDescriptions.realloc(0); 87 sal_Int32 nCount = 0; 88 89 uno::Reference<uno::XComponentContext> xCtx; 90 uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory(); 91 uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY); 92 try 93 { 94 xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx; 95 } 96 catch ( uno::Exception & ) 97 { 98 } 99 100 uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY ); 101 if ( xCtx.is() && xEnAc.is() ) 102 { 103 uno::Reference<container::XEnumeration> xEnum = 104 xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) ); 105 if ( xEnum.is() ) 106 { 107 while ( xEnum->hasMoreElements() ) 108 { 109 uno::Any aAny = xEnum->nextElement(); 110 uno::Reference<uno::XInterface> xIntFac; 111 aAny >>= xIntFac; 112 if ( xIntFac.is() ) 113 { 114 uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY ); 115 if ( xInfo.is() ) 116 { 117 rtl::OUString sName = xInfo->getImplementationName(); 118 rtl::OUString sDescription; 119 120 uno::Reference<sheet::XSolver> xSolver = lcl_CreateSolver( xIntFac, xCtx ); 121 uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY ); 122 if ( xDesc.is() ) 123 sDescription = xDesc->getComponentDescription(); 124 125 if ( !sDescription.getLength() ) 126 sDescription = sName; // use implementation name if no description available 127 128 rImplNames.realloc( nCount+1 ); 129 rImplNames[nCount] = sName; 130 rDescriptions.realloc( nCount+1 ); 131 rDescriptions[nCount] = sDescription; 132 ++nCount; 133 } 134 } 135 } 136 } 137 } 138 } 139 140 // static 141 uno::Reference<sheet::XSolver> ScSolverUtil::GetSolver( const rtl::OUString& rImplName ) 142 { 143 uno::Reference<sheet::XSolver> xSolver; 144 145 uno::Reference<uno::XComponentContext> xCtx; 146 uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory(); 147 uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY); 148 try 149 { 150 xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx; 151 } 152 catch ( uno::Exception & ) 153 { 154 } 155 156 uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY ); 157 if ( xCtx.is() && xEnAc.is() ) 158 { 159 uno::Reference<container::XEnumeration> xEnum = 160 xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) ); 161 if ( xEnum.is() ) 162 { 163 while ( xEnum->hasMoreElements() && !xSolver.is() ) 164 { 165 uno::Any aAny = xEnum->nextElement(); 166 uno::Reference<uno::XInterface> xIntFac; 167 aAny >>= xIntFac; 168 if ( xIntFac.is() ) 169 { 170 uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY ); 171 if ( xInfo.is() ) 172 { 173 rtl::OUString sName = xInfo->getImplementationName(); 174 if ( sName == rImplName ) 175 xSolver = lcl_CreateSolver( xIntFac, xCtx ); 176 } 177 } 178 } 179 } 180 } 181 182 OSL_ENSURE( xSolver.is(), "can't get solver" ); 183 return xSolver; 184 } 185 186 // static 187 uno::Sequence<beans::PropertyValue> ScSolverUtil::GetDefaults( const rtl::OUString& rImplName ) 188 { 189 uno::Sequence<beans::PropertyValue> aDefaults; 190 191 uno::Reference<sheet::XSolver> xSolver = GetSolver( rImplName ); 192 uno::Reference<beans::XPropertySet> xPropSet( xSolver, uno::UNO_QUERY ); 193 if ( !xPropSet.is() ) 194 { 195 // no XPropertySet - no options 196 return aDefaults; 197 } 198 199 // fill maProperties 200 201 uno::Reference<beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo(); 202 OSL_ENSURE( xInfo.is(), "can't get property set info" ); 203 if ( !xInfo.is() ) 204 return aDefaults; 205 206 uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties(); 207 const sal_Int32 nSize = aPropSeq.getLength(); 208 aDefaults.realloc(nSize); 209 sal_Int32 nValid = 0; 210 for (sal_Int32 nPos=0; nPos<nSize; ++nPos) 211 { 212 const beans::Property& rProp = aPropSeq[nPos]; 213 uno::Any aValue = xPropSet->getPropertyValue( rProp.Name ); 214 uno::TypeClass eClass = aValue.getValueTypeClass(); 215 // only use properties of supported types 216 if ( eClass == uno::TypeClass_BOOLEAN || eClass == uno::TypeClass_LONG || eClass == uno::TypeClass_DOUBLE ) 217 aDefaults[nValid++] = beans::PropertyValue( rProp.Name, -1, aValue, beans::PropertyState_DIRECT_VALUE ); 218 } 219 aDefaults.realloc(nValid); 220 221 //! get user-visible names, sort by them 222 223 return aDefaults; 224 } 225 226