xref: /trunk/main/sw/source/core/doc/docbasic.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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_sw.hxx"
30 
31 
32 #include <hintids.hxx>
33 
34 #ifndef _RTL_USTRING_HXX //autogen
35 #include <rtl/ustring.hxx>
36 #endif
37 #include <svtools/imap.hxx>
38 #include <svtools/imapobj.hxx>
39 #include <basic/sbx.hxx>
40 #include <frmfmt.hxx>
41 #include <fmtinfmt.hxx>
42 #include <fmturl.hxx>
43 #include <frmatr.hxx>
44 #include <docary.hxx>
45 #include <doc.hxx>
46 #ifndef _DOCSH_HXX
47 #include <docsh.hxx>
48 #endif
49 #include <swevent.hxx>
50 
51 using namespace ::com::sun::star::uno;
52 using ::rtl::OUString;
53 
54 static Sequence<Any> *lcl_docbasic_convertArgs( SbxArray& rArgs )
55 {
56     Sequence<Any> *pRet = 0;
57 
58     sal_uInt16 nCount = rArgs.Count();
59     if( nCount > 1 )
60     {
61         nCount--;
62         pRet = new Sequence<Any>( nCount );
63         Any *pUnoArgs = pRet->getArray();
64         for( sal_uInt16 i=0; i<nCount; i++ )
65         {
66             SbxVariable *pVar = rArgs.Get( i+1 );
67             switch( pVar->GetType() )
68             {
69             case SbxSTRING:
70                 pUnoArgs[i] <<= OUString( pVar->GetString() );
71                 break;
72             case SbxCHAR:
73                 pUnoArgs[i] <<= (sal_Int16)pVar->GetChar() ;
74                 break;
75             case SbxUSHORT:
76                 pUnoArgs[i] <<= (sal_Int16)pVar->GetUShort();
77                 break;
78             case SbxLONG:
79                 pUnoArgs[i] <<= (sal_Int32)pVar->GetLong();
80                 break;
81             default:
82                 pUnoArgs[i].setValue(0, ::getVoidCppuType());
83                 break;
84             }
85         }
86     }
87 
88     return pRet;
89 }
90 
91 sal_Bool SwDoc::ExecMacro( const SvxMacro& rMacro, String* pRet, SbxArray* pArgs )
92 {
93     ErrCode eErr = 0;
94     switch( rMacro.GetScriptType() )
95     {
96     case STARBASIC:
97         {
98             SbxBaseRef aRef;
99             SbxValue* pRetValue = new SbxValue;
100             aRef = pRetValue;
101             eErr = pDocShell->CallBasic( rMacro.GetMacName(),
102                                          rMacro.GetLibName(),
103                                          pArgs, pRet ? pRetValue : 0 );
104 
105             if( pRet && SbxNULL <  pRetValue->GetType() &&
106                         SbxVOID != pRetValue->GetType() )
107                 // gueltiger Wert, also setzen
108                 *pRet = pRetValue->GetString();
109         }
110         break;
111     case JAVASCRIPT:
112         // ignore JavaScript calls
113         break;
114     case EXTENDED_STYPE:
115         {
116             Sequence<Any> *pUnoArgs = 0;
117             if( pArgs )
118             {
119                 // better to rename the local function to lcl_translateBasic2Uno and
120                 // a much shorter routine can be found in sfx2/source/doc/objmisc.cxx
121                 pUnoArgs = lcl_docbasic_convertArgs( *pArgs );
122             }
123 
124             if (!pUnoArgs)
125             {
126                 pUnoArgs = new Sequence< Any > (0);
127             }
128 
129             // TODO - return value is not handled
130             Any aRet;
131             Sequence< sal_Int16 > aOutArgsIndex;
132             Sequence< Any > aOutArgs;
133 
134             OSL_TRACE( "SwDoc::ExecMacro URL is %s", ByteString( rMacro.GetMacName(),
135                 RTL_TEXTENCODING_UTF8).GetBuffer() );
136 
137             eErr = pDocShell->CallXScript(
138                 rMacro.GetMacName(), *pUnoArgs, aRet, aOutArgsIndex, aOutArgs);
139 
140             //*pRet = pRetValue->GetString();
141             // use the AnyConverter to return a String if appropriate?
142 
143             // need to call something like lcl_translateUno2Basic
144             // pArgs = lcl_translateUno2Basic( pUnoArgs );
145 
146             delete pUnoArgs;
147             break;
148         }
149     }
150 
151     return 0 == eErr;
152 }
153 
154 
155 
156 sal_uInt16 SwDoc::CallEvent( sal_uInt16 nEvent, const SwCallMouseEvent& rCallEvent,
157                     sal_Bool bCheckPtr, SbxArray* pArgs, const Link* )
158 {
159     if( !pDocShell )        // ohne DocShell geht das nicht!
160         return 0;
161 
162     sal_uInt16 nRet = 0;
163     const SvxMacroTableDtor* pTbl = 0;
164     switch( rCallEvent.eType )
165     {
166     case EVENT_OBJECT_INETATTR:
167         if( bCheckPtr  )
168         {
169             const SfxPoolItem* pItem;
170             sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
171             for( n = 0; n < nMaxItems; ++n )
172                 if( 0 != (pItem = GetAttrPool().GetItem2( RES_TXTATR_INETFMT, n ) )
173                     && rCallEvent.PTR.pINetAttr == pItem )
174                 {
175                     bCheckPtr = sal_False;      // als Flag missbrauchen
176                     break;
177                 }
178         }
179         if( !bCheckPtr )
180             pTbl = rCallEvent.PTR.pINetAttr->GetMacroTbl();
181         break;
182 
183     case EVENT_OBJECT_URLITEM:
184     case EVENT_OBJECT_IMAGE:
185         {
186             const SwFrmFmtPtr pFmt = (SwFrmFmtPtr)rCallEvent.PTR.pFmt;
187             if( bCheckPtr )
188             {
189                 sal_uInt16 nPos = GetSpzFrmFmts()->GetPos( pFmt );
190                 if( USHRT_MAX != nPos )
191                     bCheckPtr = sal_False;      // als Flag missbrauchen
192             }
193             if( !bCheckPtr )
194                 pTbl = &pFmt->GetMacro().GetMacroTable();
195         }
196         break;
197 
198     case EVENT_OBJECT_IMAGEMAP:
199         {
200             const IMapObject* pIMapObj = rCallEvent.PTR.IMAP.pIMapObj;
201             if( bCheckPtr )
202             {
203                 const SwFrmFmtPtr pFmt = (SwFrmFmtPtr)rCallEvent.PTR.IMAP.pFmt;
204                 sal_uInt16 nPos = GetSpzFrmFmts()->GetPos( pFmt );
205                 const ImageMap* pIMap;
206                 if( USHRT_MAX != nPos &&
207                     0 != (pIMap = pFmt->GetURL().GetMap()) )
208                 {
209                     for( nPos = pIMap->GetIMapObjectCount(); nPos; )
210                         if( pIMapObj == pIMap->GetIMapObject( --nPos ))
211                         {
212                             bCheckPtr = sal_False;      // als Flag missbrauchen
213                             break;
214                         }
215                 }
216             }
217             if( !bCheckPtr )
218                 pTbl = &pIMapObj->GetMacroTable();
219         }
220         break;
221     default:
222         break;
223     }
224 
225     if( pTbl )
226     {
227         nRet = 0x1;
228         if( pTbl->IsKeyValid( nEvent ) )
229         {
230             const SvxMacro& rMacro = *pTbl->Get( nEvent );
231             if( STARBASIC == rMacro.GetScriptType() )
232             {
233                 nRet += 0 == pDocShell->CallBasic( rMacro.GetMacName(),
234                                     rMacro.GetLibName(), pArgs ) ? 1 : 0;
235             }
236             else if( EXTENDED_STYPE == rMacro.GetScriptType() )
237             {
238                 Sequence<Any> *pUnoArgs = 0;
239 
240                 if( pArgs )
241                 {
242                     pUnoArgs = lcl_docbasic_convertArgs( *pArgs );
243                 }
244 
245                 if (!pUnoArgs)
246                 {
247                     pUnoArgs = new Sequence <Any> (0);
248                 }
249 
250                 Any aRet;
251                 Sequence< sal_Int16 > aOutArgsIndex;
252                 Sequence< Any > aOutArgs;
253 
254                 OSL_TRACE( "SwDoc::CallEvent URL is %s", ByteString(
255                     rMacro.GetMacName(), RTL_TEXTENCODING_UTF8).GetBuffer() );
256 
257                 nRet += 0 == pDocShell->CallXScript(
258                     rMacro.GetMacName(), *pUnoArgs,aRet, aOutArgsIndex, aOutArgs) ? 1 : 0;
259 
260                 //*pRet = pRetValue->GetString();
261                 // use the AnyConverter to return a String if appropriate?
262 
263                 // need to call something like lcl_translateUno2Basic
264                 // pArgs = lcl_translateUno2Basic( pUnoArgs );
265 
266                 delete pUnoArgs;
267             }
268             // JavaScript calls are ignored
269         }
270     }
271     return nRet;
272 }
273 
274 
275 
276 
277