xref: /aoo41x/main/sc/source/ui/miscdlgs/solverutil.cxx (revision cdf0e10c)
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