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_scripting.hxx"
30 #include "basmethnode.hxx"
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/frame/XDesktop.hpp>
33 #include <com/sun/star/frame/XDispatchHelper.hpp>
34 #include <com/sun/star/frame/XDispatchProvider.hpp>
35 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
36 #include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
37 #include <vos/mutex.hxx>
38 #include <vcl/svapp.hxx>
39 #include <basic/sbstar.hxx>
40 #include <basic/sbmeth.hxx>
41 #include <basic/sbmod.hxx>
42 
43 #include <util/MiscUtils.hxx>
44 
45 using namespace ::com::sun::star;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using namespace ::comphelper;
50 using namespace ::com::sun::star::script;
51 using namespace ::sf_misc;
52 
53 #define BASPROV_PROPERTY_ID_URI         1
54 #define BASPROV_PROPERTY_ID_EDITABLE    2
55 
56 #define BASPROV_PROPERTY_URI            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URI" ) )
57 #define BASPROV_PROPERTY_EDITABLE       ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Editable" ) )
58 
59 #define BASPROV_DEFAULT_ATTRIBS()       PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT | PropertyAttribute::READONLY
60 
61 
62 //.........................................................................
63 namespace basprov
64 {
65 //.........................................................................
66 
67     // =============================================================================
68     // BasicMethodNodeImpl
69     // =============================================================================
70 
71     BasicMethodNodeImpl::BasicMethodNodeImpl( const Reference< XComponentContext >& rxContext,
72         const ::rtl::OUString& sScriptingContext, SbMethod* pMethod, bool isAppScript )
73         : ::scripting_helper::OBroadcastHelperHolder( m_aMutex )
74         ,OPropertyContainer( GetBroadcastHelper() )
75         ,m_xContext( rxContext )
76         ,m_sScriptingContext( sScriptingContext )
77         ,m_pMethod( pMethod )
78         ,m_bIsAppScript( isAppScript )
79         ,m_bEditable( sal_True )
80     {
81         if ( m_pMethod )
82         {
83             SbModule* pModule = m_pMethod->GetModule();
84             if ( pModule )
85             {
86                 StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() );
87                 if ( pBasic )
88                 {
89                     m_sURI = ::rtl::OUString::createFromAscii( "vnd.sun.star.script:" );
90                     m_sURI += pBasic->GetName();
91                     m_sURI += ::rtl::OUString::createFromAscii( "." );
92                     m_sURI += pModule->GetName();
93                     m_sURI += ::rtl::OUString::createFromAscii( "." );
94                     m_sURI += m_pMethod->GetName();
95                     m_sURI += ::rtl::OUString::createFromAscii( "?language=Basic&location=" );
96                     if ( m_bIsAppScript )
97                         m_sURI += ::rtl::OUString::createFromAscii( "application" );
98                     else
99                         m_sURI += ::rtl::OUString::createFromAscii( "document" );
100                 }
101             }
102         }
103 
104         registerProperty( BASPROV_PROPERTY_URI,      BASPROV_PROPERTY_ID_URI,      BASPROV_DEFAULT_ATTRIBS(), &m_sURI,      ::getCppuType( &m_sURI ) );
105         registerProperty( BASPROV_PROPERTY_EDITABLE, BASPROV_PROPERTY_ID_EDITABLE, BASPROV_DEFAULT_ATTRIBS(), &m_bEditable, ::getCppuType( &m_bEditable ) );
106     }
107 
108     // -----------------------------------------------------------------------------
109 
110     BasicMethodNodeImpl::~BasicMethodNodeImpl()
111     {
112     }
113 
114     // -----------------------------------------------------------------------------
115     // XInterface
116     // -----------------------------------------------------------------------------
117 
118     IMPLEMENT_FORWARD_XINTERFACE2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer )
119 
120     // -----------------------------------------------------------------------------
121     // XTypeProvider
122     // -----------------------------------------------------------------------------
123 
124     IMPLEMENT_FORWARD_XTYPEPROVIDER2( BasicMethodNodeImpl, BasicMethodNodeImpl_BASE, OPropertyContainer )
125 
126     // -----------------------------------------------------------------------------
127     // XBrowseNode
128     // -----------------------------------------------------------------------------
129 
130     ::rtl::OUString BasicMethodNodeImpl::getName(  ) throw (RuntimeException)
131     {
132         ::vos::OGuard aGuard( Application::GetSolarMutex() );
133 
134         ::rtl::OUString sMethodName;
135         if ( m_pMethod )
136             sMethodName = m_pMethod->GetName();
137 
138         return sMethodName;
139     }
140 
141     // -----------------------------------------------------------------------------
142 
143     Sequence< Reference< browse::XBrowseNode > > BasicMethodNodeImpl::getChildNodes(  ) throw (RuntimeException)
144     {
145         ::vos::OGuard aGuard( Application::GetSolarMutex() );
146 
147         return Sequence< Reference< browse::XBrowseNode > >();
148     }
149 
150     // -----------------------------------------------------------------------------
151 
152     sal_Bool BasicMethodNodeImpl::hasChildNodes(  ) throw (RuntimeException)
153     {
154         ::vos::OGuard aGuard( Application::GetSolarMutex() );
155 
156         return sal_False;
157     }
158 
159     // -----------------------------------------------------------------------------
160 
161     sal_Int16 BasicMethodNodeImpl::getType(  ) throw (RuntimeException)
162     {
163         ::vos::OGuard aGuard( Application::GetSolarMutex() );
164 
165         return browse::BrowseNodeTypes::SCRIPT;
166     }
167 
168     // -----------------------------------------------------------------------------
169     // OPropertySetHelper
170     // -----------------------------------------------------------------------------
171 
172     ::cppu::IPropertyArrayHelper& BasicMethodNodeImpl::getInfoHelper(  )
173     {
174         return *getArrayHelper();
175     }
176 
177     // -----------------------------------------------------------------------------
178     // OPropertyArrayUsageHelper
179     // -----------------------------------------------------------------------------
180 
181     ::cppu::IPropertyArrayHelper* BasicMethodNodeImpl::createArrayHelper(  ) const
182     {
183         Sequence< Property > aProps;
184         describeProperties( aProps );
185         return new ::cppu::OPropertyArrayHelper( aProps );
186     }
187 
188     // -----------------------------------------------------------------------------
189     // XPropertySet
190     // -----------------------------------------------------------------------------
191 
192     Reference< XPropertySetInfo > BasicMethodNodeImpl::getPropertySetInfo(  ) throw (RuntimeException)
193     {
194         Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) );
195         return xInfo;
196     }
197 
198     // -----------------------------------------------------------------------------
199     // XInvocation
200     // -----------------------------------------------------------------------------
201 
202     Reference< XIntrospectionAccess > BasicMethodNodeImpl::getIntrospection(  ) throw (RuntimeException)
203     {
204         return Reference< XIntrospectionAccess >();
205     }
206 
207     // -----------------------------------------------------------------------------
208 
209     Any BasicMethodNodeImpl::invoke( const ::rtl::OUString& aFunctionName, const Sequence< Any >& aParams,
210         Sequence< sal_Int16 >& aOutParamIndex, Sequence< Any >& aOutParam )
211         throw (IllegalArgumentException, script::CannotConvertException,
212                reflection::InvocationTargetException, RuntimeException)
213     {
214 		(void)aParams;
215 		(void)aOutParamIndex;
216 		(void)aOutParam;
217 
218         if ( aFunctionName == BASPROV_PROPERTY_EDITABLE )
219         {
220             ::rtl::OUString sDocURL, sLibName, sModName;
221             sal_uInt16 nLine1 = 0, nLine2;
222 
223             if ( !m_bIsAppScript )
224             {
225                 Reference< frame::XModel > xModel = MiscUtils::tDocUrlToModel( m_sScriptingContext );
226 
227                 if ( xModel.is() )
228                 {
229                     sDocURL = xModel->getURL();
230                     if ( sDocURL.getLength() == 0 )
231                     {
232                         Sequence < PropertyValue > aProps = xModel->getArgs();
233                         sal_Int32 nProps = aProps.getLength();
234                         const PropertyValue* pProps = aProps.getConstArray();
235                         for ( sal_Int32 i = 0; i < nProps; ++i )
236                         {
237                             // TODO: according to MBA the property 'Title' may change in future
238                             if ( pProps[i].Name == ::rtl::OUString::createFromAscii( "Title" ) )
239                             {
240                                 pProps[i].Value >>= sDocURL;
241                                 break;
242                             }
243                         }
244                     }
245                 }
246             }
247 
248             if ( m_pMethod )
249             {
250                 m_pMethod->GetLineRange( nLine1, nLine2 );
251                 SbModule* pModule = m_pMethod->GetModule();
252                 if ( pModule )
253                 {
254                     sModName = pModule->GetName();
255                     StarBASIC* pBasic = static_cast< StarBASIC* >( pModule->GetParent() );
256                     if ( pBasic )
257                         sLibName = pBasic->GetName();
258                 }
259             }
260 
261             if ( m_xContext.is() )
262             {
263                 Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager() );
264 
265                 if ( xSMgr.is() )
266                 {
267                     Reference< frame::XDesktop > xDesktop( xSMgr->createInstanceWithContext(
268                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.Desktop" ) ), m_xContext ), UNO_QUERY );
269 
270                     if ( xDesktop.is() )
271                     {
272                         Reference < frame::XDispatchProvider > xProv( xDesktop->getCurrentFrame(), UNO_QUERY );
273 
274                         if ( xProv.is() )
275                         {
276                             Reference< frame::XDispatchHelper > xHelper( xSMgr->createInstanceWithContext(
277                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.frame.DispatchHelper" ) ), m_xContext ), UNO_QUERY );
278 
279                             if ( xHelper.is() )
280                             {
281                                 Sequence < PropertyValue > aArgs(7);
282                                 aArgs[0].Name = ::rtl::OUString::createFromAscii( "Document" );
283                                 aArgs[0].Value <<= sDocURL;
284                                 aArgs[1].Name = ::rtl::OUString::createFromAscii( "LibName" );
285                                 aArgs[1].Value <<= sLibName;
286                                 aArgs[2].Name = ::rtl::OUString::createFromAscii( "Name" );
287                                 aArgs[2].Value <<= sModName;
288                                 aArgs[3].Name = ::rtl::OUString::createFromAscii( "Type" );
289                                 aArgs[3].Value <<= ::rtl::OUString::createFromAscii( "Module" );
290                                 aArgs[4].Name = ::rtl::OUString::createFromAscii( "Line" );
291                                 aArgs[4].Value <<= static_cast< sal_uInt32 >( nLine1 );
292                                 xHelper->executeDispatch( xProv, ::rtl::OUString::createFromAscii( ".uno:BasicIDEAppear" ), ::rtl::OUString(), 0, aArgs );
293                             }
294                         }
295                     }
296                 }
297             }
298         }
299         else
300         {
301             throw IllegalArgumentException(
302                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::invoke: function name not supported!" ) ),
303                 Reference< XInterface >(), 1 );
304         }
305 
306         return Any();
307     }
308 
309     // -----------------------------------------------------------------------------
310 
311     void BasicMethodNodeImpl::setValue( const ::rtl::OUString& aPropertyName, const Any& aValue )
312         throw (UnknownPropertyException, script::CannotConvertException,
313                reflection::InvocationTargetException, RuntimeException)
314     {
315 		(void)aPropertyName;
316 		(void)aValue;
317 
318         throw UnknownPropertyException(
319             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::setValue: property name is unknown!" ) ),
320             Reference< XInterface >() );
321     }
322 
323     // -----------------------------------------------------------------------------
324 
325     Any BasicMethodNodeImpl::getValue( const ::rtl::OUString& aPropertyName ) throw (UnknownPropertyException, RuntimeException)
326     {
327 		(void)aPropertyName;
328 
329         throw UnknownPropertyException(
330             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "BasicMethodNodeImpl::getValue: property name is unknown!" ) ),
331             Reference< XInterface >() );
332     }
333 
334     // -----------------------------------------------------------------------------
335 
336     sal_Bool BasicMethodNodeImpl::hasMethod( const ::rtl::OUString& aName ) throw (RuntimeException)
337     {
338         sal_Bool bReturn = sal_False;
339         if ( aName == BASPROV_PROPERTY_EDITABLE )
340             bReturn = sal_True;
341 
342         return bReturn;
343     }
344 
345     // -----------------------------------------------------------------------------
346 
347     sal_Bool BasicMethodNodeImpl::hasProperty( const ::rtl::OUString& aName ) throw (RuntimeException)
348     {
349 		(void)aName;
350 
351         return sal_False;
352     }
353 
354     // -----------------------------------------------------------------------------
355 
356 //.........................................................................
357 }	// namespace basprov
358 //.........................................................................
359