1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 //------------------------------------------------------------------ 32 33 #include "solverutil.hxx" 34 35 #include <com/sun/star/container/XContentEnumerationAccess.hpp> 36 #include <com/sun/star/lang/XServiceInfo.hpp> 37 #include <com/sun/star/lang/XSingleComponentFactory.hpp> 38 #include <com/sun/star/lang/XSingleServiceFactory.hpp> 39 #include <com/sun/star/beans/XPropertySet.hpp> 40 #include <com/sun/star/beans/PropertyValue.hpp> 41 #include <com/sun/star/sheet/XSolver.hpp> 42 #include <com/sun/star/sheet/XSolverDescription.hpp> 43 44 #include <comphelper/processfactory.hxx> 45 46 using namespace com::sun::star; 47 48 //------------------------------------------------------------------ 49 50 #define SCSOLVER_SERVICE "com.sun.star.sheet.Solver" 51 52 uno::Reference<sheet::XSolver> lcl_CreateSolver( const uno::Reference<uno::XInterface>& xIntFac, 53 const uno::Reference<uno::XComponentContext>& xCtx ) 54 { 55 uno::Reference<sheet::XSolver> xSolver; 56 57 uno::Reference<lang::XSingleComponentFactory> xCFac( xIntFac, uno::UNO_QUERY ); 58 uno::Reference<lang::XSingleServiceFactory> xFac( xIntFac, uno::UNO_QUERY ); 59 if ( xCFac.is() ) 60 { 61 try 62 { 63 uno::Reference<uno::XInterface> xInterface = xCFac->createInstanceWithContext(xCtx); 64 xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY ); 65 } 66 catch(uno::Exception&) 67 { 68 } 69 } 70 if ( !xSolver.is() && xFac.is() ) 71 { 72 try 73 { 74 uno::Reference<uno::XInterface> xInterface = xFac->createInstance(); 75 xSolver = uno::Reference<sheet::XSolver>( xInterface, uno::UNO_QUERY ); 76 } 77 catch(uno::Exception&) 78 { 79 } 80 } 81 82 return xSolver; 83 } 84 85 // static 86 void ScSolverUtil::GetImplementations( uno::Sequence<rtl::OUString>& rImplNames, 87 uno::Sequence<rtl::OUString>& rDescriptions ) 88 { 89 rImplNames.realloc(0); // clear 90 rDescriptions.realloc(0); 91 sal_Int32 nCount = 0; 92 93 uno::Reference<uno::XComponentContext> xCtx; 94 uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory(); 95 uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY); 96 try 97 { 98 xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx; 99 } 100 catch ( uno::Exception & ) 101 { 102 } 103 104 uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY ); 105 if ( xCtx.is() && xEnAc.is() ) 106 { 107 uno::Reference<container::XEnumeration> xEnum = 108 xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) ); 109 if ( xEnum.is() ) 110 { 111 while ( xEnum->hasMoreElements() ) 112 { 113 uno::Any aAny = xEnum->nextElement(); 114 uno::Reference<uno::XInterface> xIntFac; 115 aAny >>= xIntFac; 116 if ( xIntFac.is() ) 117 { 118 uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY ); 119 if ( xInfo.is() ) 120 { 121 rtl::OUString sName = xInfo->getImplementationName(); 122 rtl::OUString sDescription; 123 124 uno::Reference<sheet::XSolver> xSolver = lcl_CreateSolver( xIntFac, xCtx ); 125 uno::Reference<sheet::XSolverDescription> xDesc( xSolver, uno::UNO_QUERY ); 126 if ( xDesc.is() ) 127 sDescription = xDesc->getComponentDescription(); 128 129 if ( !sDescription.getLength() ) 130 sDescription = sName; // use implementation name if no description available 131 132 rImplNames.realloc( nCount+1 ); 133 rImplNames[nCount] = sName; 134 rDescriptions.realloc( nCount+1 ); 135 rDescriptions[nCount] = sDescription; 136 ++nCount; 137 } 138 } 139 } 140 } 141 } 142 } 143 144 // static 145 uno::Reference<sheet::XSolver> ScSolverUtil::GetSolver( const rtl::OUString& rImplName ) 146 { 147 uno::Reference<sheet::XSolver> xSolver; 148 149 uno::Reference<uno::XComponentContext> xCtx; 150 uno::Reference<lang::XMultiServiceFactory> xMSF = comphelper::getProcessServiceFactory(); 151 uno::Reference<beans::XPropertySet> xPropset(xMSF, uno::UNO_QUERY); 152 try 153 { 154 xPropset->getPropertyValue(rtl::OUString::createFromAscii("DefaultContext")) >>= xCtx; 155 } 156 catch ( uno::Exception & ) 157 { 158 } 159 160 uno::Reference<container::XContentEnumerationAccess> xEnAc( xMSF, uno::UNO_QUERY ); 161 if ( xCtx.is() && xEnAc.is() ) 162 { 163 uno::Reference<container::XEnumeration> xEnum = 164 xEnAc->createContentEnumeration( rtl::OUString::createFromAscii(SCSOLVER_SERVICE) ); 165 if ( xEnum.is() ) 166 { 167 while ( xEnum->hasMoreElements() && !xSolver.is() ) 168 { 169 uno::Any aAny = xEnum->nextElement(); 170 uno::Reference<uno::XInterface> xIntFac; 171 aAny >>= xIntFac; 172 if ( xIntFac.is() ) 173 { 174 uno::Reference<lang::XServiceInfo> xInfo( xIntFac, uno::UNO_QUERY ); 175 if ( xInfo.is() ) 176 { 177 rtl::OUString sName = xInfo->getImplementationName(); 178 if ( sName == rImplName ) 179 xSolver = lcl_CreateSolver( xIntFac, xCtx ); 180 } 181 } 182 } 183 } 184 } 185 186 OSL_ENSURE( xSolver.is(), "can't get solver" ); 187 return xSolver; 188 } 189 190 // static 191 uno::Sequence<beans::PropertyValue> ScSolverUtil::GetDefaults( const rtl::OUString& rImplName ) 192 { 193 uno::Sequence<beans::PropertyValue> aDefaults; 194 195 uno::Reference<sheet::XSolver> xSolver = GetSolver( rImplName ); 196 uno::Reference<beans::XPropertySet> xPropSet( xSolver, uno::UNO_QUERY ); 197 if ( !xPropSet.is() ) 198 { 199 // no XPropertySet - no options 200 return aDefaults; 201 } 202 203 // fill maProperties 204 205 uno::Reference<beans::XPropertySetInfo> xInfo = xPropSet->getPropertySetInfo(); 206 OSL_ENSURE( xInfo.is(), "can't get property set info" ); 207 if ( !xInfo.is() ) 208 return aDefaults; 209 210 uno::Sequence<beans::Property> aPropSeq = xInfo->getProperties(); 211 const sal_Int32 nSize = aPropSeq.getLength(); 212 aDefaults.realloc(nSize); 213 sal_Int32 nValid = 0; 214 for (sal_Int32 nPos=0; nPos<nSize; ++nPos) 215 { 216 const beans::Property& rProp = aPropSeq[nPos]; 217 uno::Any aValue = xPropSet->getPropertyValue( rProp.Name ); 218 uno::TypeClass eClass = aValue.getValueTypeClass(); 219 // only use properties of supported types 220 if ( eClass == uno::TypeClass_BOOLEAN || eClass == uno::TypeClass_LONG || eClass == uno::TypeClass_DOUBLE ) 221 aDefaults[nValid++] = beans::PropertyValue( rProp.Name, -1, aValue, beans::PropertyState_DIRECT_VALUE ); 222 } 223 aDefaults.realloc(nValid); 224 225 //! get user-visible names, sort by them 226 227 return aDefaults; 228 } 229 230