xref: /trunk/main/framework/source/recording/dispatchrecorder.cxx (revision a79a404b26934743545c6dafbc11b12ece90a8e1)
16d739b60SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
36d739b60SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
46d739b60SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
56d739b60SAndrew Rist  * distributed with this work for additional information
66d739b60SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
76d739b60SAndrew Rist  * to you under the Apache License, Version 2.0 (the
86d739b60SAndrew Rist  * "License"); you may not use this file except in compliance
96d739b60SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
116d739b60SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
136d739b60SAndrew Rist  * Unless required by applicable law or agreed to in writing,
146d739b60SAndrew Rist  * software distributed under the License is distributed on an
156d739b60SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
166d739b60SAndrew Rist  * KIND, either express or implied.  See the License for the
176d739b60SAndrew Rist  * specific language governing permissions and limitations
186d739b60SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
206d739b60SAndrew Rist  *************************************************************/
216d739b60SAndrew Rist 
226d739b60SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_framework.hxx"
26cdf0e10cSrcweir #include <recording/dispatchrecorder.hxx>
27cdf0e10cSrcweir #include <com/sun/star/frame/DispatchStatement.hpp>
28cdf0e10cSrcweir #include <threadhelp/writeguard.hxx>
29cdf0e10cSrcweir #include <threadhelp/readguard.hxx>
30cdf0e10cSrcweir #include <services.h>
31cdf0e10cSrcweir #include <vcl/svapp.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir using namespace ::com::sun::star::uno;
34cdf0e10cSrcweir 
35cdf0e10cSrcweir namespace framework{
36cdf0e10cSrcweir 
37*a79a404bSmseidel // used to mark a dispatch as comment (mostly it indicates an error). Changing of this wdefine will impact all using of such comments...
38cdf0e10cSrcweir #define REM_AS_COMMENT    "rem "
39cdf0e10cSrcweir 
40cdf0e10cSrcweir //*****************************************************************************************************************
41cdf0e10cSrcweir //  XInterface, XTypeProvider, XServiceInfo
42cdf0e10cSrcweir //*****************************************************************************************************************
DEFINE_XINTERFACE_6(DispatchRecorder,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::frame::XDispatchRecorder),DIRECT_INTERFACE (css::container::XIndexReplace),DIRECT_INTERFACE (css::container::XIndexAccess),DIRECT_INTERFACE (css::container::XElementAccess))43cdf0e10cSrcweir DEFINE_XINTERFACE_6(
44cdf0e10cSrcweir     DispatchRecorder,
45cdf0e10cSrcweir     OWeakObject,
46cdf0e10cSrcweir     DIRECT_INTERFACE(css::lang::XTypeProvider),
47cdf0e10cSrcweir     DIRECT_INTERFACE(css::lang::XServiceInfo),
48cdf0e10cSrcweir     DIRECT_INTERFACE(css::frame::XDispatchRecorder),
49cdf0e10cSrcweir     DIRECT_INTERFACE(css::container::XIndexReplace),
50cdf0e10cSrcweir     DIRECT_INTERFACE(css::container::XIndexAccess),
51cdf0e10cSrcweir     DIRECT_INTERFACE(css::container::XElementAccess))
52cdf0e10cSrcweir 
53cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_6(
54cdf0e10cSrcweir     DispatchRecorder,
55cdf0e10cSrcweir     css::lang::XTypeProvider,
56cdf0e10cSrcweir     css::lang::XServiceInfo,
57cdf0e10cSrcweir     css::frame::XDispatchRecorder,
58cdf0e10cSrcweir     css::container::XIndexReplace,
59cdf0e10cSrcweir     css::container::XIndexAccess,
60cdf0e10cSrcweir     css::container::XElementAccess)
61cdf0e10cSrcweir 
62cdf0e10cSrcweir DEFINE_XSERVICEINFO_MULTISERVICE(
63cdf0e10cSrcweir     DispatchRecorder,
64cdf0e10cSrcweir     ::cppu::OWeakObject,
65cdf0e10cSrcweir     SERVICENAME_DISPATCHRECORDER,
66cdf0e10cSrcweir     IMPLEMENTATIONNAME_DISPATCHRECORDER)
67cdf0e10cSrcweir 
68cdf0e10cSrcweir DEFINE_INIT_SERVICE(
69cdf0e10cSrcweir     DispatchRecorder,
70cdf0e10cSrcweir     {
71cdf0e10cSrcweir     }
72cdf0e10cSrcweir )
73cdf0e10cSrcweir 
74cdf0e10cSrcweir #include <typelib/typedescription.h>
75cdf0e10cSrcweir 
76cdf0e10cSrcweir //--------------------------------------------------------------------------------------------------
77cdf0e10cSrcweir void flatten_struct_members(
78cdf0e10cSrcweir     ::std::vector< Any > * vec, void const * data,
79cdf0e10cSrcweir     typelib_CompoundTypeDescription * pTD )
80cdf0e10cSrcweir     SAL_THROW( () )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     if (pTD->pBaseTypeDescription)
83cdf0e10cSrcweir     {
84cdf0e10cSrcweir         flatten_struct_members( vec, data, pTD->pBaseTypeDescription );
85cdf0e10cSrcweir     }
86cdf0e10cSrcweir     for ( sal_Int32 nPos = 0; nPos < pTD->nMembers; ++nPos )
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir         vec->push_back(
89cdf0e10cSrcweir             Any( (char const *)data + pTD->pMemberOffsets[ nPos ], pTD->ppTypeRefs[ nPos ] ) );
90cdf0e10cSrcweir     }
91cdf0e10cSrcweir }
92cdf0e10cSrcweir //==================================================================================================
make_seq_out_of_struct(Any const & val)93cdf0e10cSrcweir Sequence< Any > make_seq_out_of_struct(
94cdf0e10cSrcweir     Any const & val )
95cdf0e10cSrcweir     SAL_THROW( (RuntimeException) )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir     Type const & type = val.getValueType();
98cdf0e10cSrcweir     TypeClass eTypeClass = type.getTypeClass();
99cdf0e10cSrcweir     if (TypeClass_STRUCT != eTypeClass && TypeClass_EXCEPTION != eTypeClass)
100cdf0e10cSrcweir     {
101cdf0e10cSrcweir         throw RuntimeException(
102cdf0e10cSrcweir             type.getTypeName() +
103cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("is no struct or exception!") ),
104cdf0e10cSrcweir             Reference< XInterface >() );
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir     typelib_TypeDescription * pTD = 0;
107cdf0e10cSrcweir     TYPELIB_DANGER_GET( &pTD, type.getTypeLibType() );
108cdf0e10cSrcweir     OSL_ASSERT( pTD );
109cdf0e10cSrcweir     if (! pTD)
110cdf0e10cSrcweir     {
111cdf0e10cSrcweir         throw RuntimeException(
112cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get type descr of type ") ) +
113cdf0e10cSrcweir             type.getTypeName(),
114cdf0e10cSrcweir             Reference< XInterface >() );
115cdf0e10cSrcweir     }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     ::std::vector< Any > vec;
118cdf0e10cSrcweir     vec.reserve( ((typelib_CompoundTypeDescription *)pTD)->nMembers ); // good guess
119cdf0e10cSrcweir     flatten_struct_members( &vec, val.getValue(), (typelib_CompoundTypeDescription *)pTD );
120cdf0e10cSrcweir     TYPELIB_DANGER_RELEASE( pTD );
121cdf0e10cSrcweir     return Sequence< Any >( &vec[ 0 ], vec.size() );
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir //***********************************************************************
DispatchRecorder(const css::uno::Reference<css::lang::XMultiServiceFactory> & xSMGR)125cdf0e10cSrcweir DispatchRecorder::DispatchRecorder( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
126cdf0e10cSrcweir         : ThreadHelpBase     ( &Application::GetSolarMutex() )
127cdf0e10cSrcweir         , ::cppu::OWeakObject(                               )
128cdf0e10cSrcweir         , m_xSMGR            ( xSMGR                         )
129cdf0e10cSrcweir         , m_xConverter( m_xSMGR->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), css::uno::UNO_QUERY )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir }
132cdf0e10cSrcweir 
133cdf0e10cSrcweir //************************************************************************
~DispatchRecorder()134cdf0e10cSrcweir DispatchRecorder::~DispatchRecorder()
135cdf0e10cSrcweir {
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir //*************************************************************************
139cdf0e10cSrcweir // generate header
startRecording(const css::uno::Reference<css::frame::XFrame> &)140cdf0e10cSrcweir void SAL_CALL DispatchRecorder::startRecording( const css::uno::Reference< css::frame::XFrame >& ) throw( css::uno::RuntimeException )
141cdf0e10cSrcweir {
142cdf0e10cSrcweir     /* SAFE{ */
143cdf0e10cSrcweir     /* } */
144cdf0e10cSrcweir }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir //*************************************************************************
recordDispatch(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)147cdf0e10cSrcweir void SAL_CALL DispatchRecorder::recordDispatch( const css::util::URL& aURL,
148cdf0e10cSrcweir                                                 const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
149cdf0e10cSrcweir {
150cdf0e10cSrcweir     ::rtl::OUString aTarget;
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     com::sun::star::frame::DispatchStatement aStatement( aURL.Complete, aTarget, lArguments, 0, sal_False );
153cdf0e10cSrcweir     m_aStatements.push_back( aStatement );
154cdf0e10cSrcweir }
155cdf0e10cSrcweir 
156cdf0e10cSrcweir //*************************************************************************
recordDispatchAsComment(const css::util::URL & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments)157cdf0e10cSrcweir void SAL_CALL DispatchRecorder::recordDispatchAsComment( const css::util::URL& aURL,
158cdf0e10cSrcweir                                                          const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) throw( css::uno::RuntimeException )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     ::rtl::OUString aTarget;
161cdf0e10cSrcweir 
162cdf0e10cSrcweir     // last parameter must be set to true -> it's a comment
163cdf0e10cSrcweir         com::sun::star::frame::DispatchStatement aStatement( aURL.Complete, aTarget, lArguments, 0, sal_True );
164cdf0e10cSrcweir     m_aStatements.push_back( aStatement );
165cdf0e10cSrcweir }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir //*************************************************************************
endRecording()168cdf0e10cSrcweir void SAL_CALL DispatchRecorder::endRecording() throw( css::uno::RuntimeException )
169cdf0e10cSrcweir {
170cdf0e10cSrcweir     /* SAFE{ */
171cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
172cdf0e10cSrcweir     m_aStatements.clear();
173cdf0e10cSrcweir     /* } */
174cdf0e10cSrcweir }
175cdf0e10cSrcweir 
176cdf0e10cSrcweir //*************************************************************************
getRecordedMacro()177cdf0e10cSrcweir ::rtl::OUString SAL_CALL DispatchRecorder::getRecordedMacro() throw( css::uno::RuntimeException )
178cdf0e10cSrcweir {
179cdf0e10cSrcweir     /* SAFE{ */
180cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
181cdf0e10cSrcweir 
182cdf0e10cSrcweir     if ( m_aStatements.empty() )
183cdf0e10cSrcweir         return ::rtl::OUString();
184cdf0e10cSrcweir 
185cdf0e10cSrcweir     ::rtl::OUStringBuffer aScriptBuffer;
186cdf0e10cSrcweir     aScriptBuffer.ensureCapacity(10000);
187cdf0e10cSrcweir     m_nRecordingID = 1;
188cdf0e10cSrcweir 
189cdf0e10cSrcweir     aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
190cdf0e10cSrcweir     aScriptBuffer.appendAscii("rem define variables\n");
191cdf0e10cSrcweir     aScriptBuffer.appendAscii("dim document   as object\n");
192cdf0e10cSrcweir     aScriptBuffer.appendAscii("dim dispatcher as object\n");
193cdf0e10cSrcweir     aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
194cdf0e10cSrcweir     aScriptBuffer.appendAscii("rem get access to the document\n");
195cdf0e10cSrcweir     aScriptBuffer.appendAscii("document   = ThisComponent.CurrentController.Frame\n");
196cdf0e10cSrcweir     aScriptBuffer.appendAscii("dispatcher = createUnoService(\"com.sun.star.frame.DispatchHelper\")\n\n");
197cdf0e10cSrcweir 
198cdf0e10cSrcweir     std::vector< com::sun::star::frame::DispatchStatement>::iterator p;
199cdf0e10cSrcweir     for ( p = m_aStatements.begin(); p != m_aStatements.end(); p++ )
200cdf0e10cSrcweir         implts_recordMacro( p->aCommand, p->aArgs, p->bIsComment, aScriptBuffer );
201cdf0e10cSrcweir     ::rtl::OUString sScript = aScriptBuffer.makeStringAndClear();
202cdf0e10cSrcweir     return sScript;
203cdf0e10cSrcweir     /* } */
204cdf0e10cSrcweir }
205cdf0e10cSrcweir 
206cdf0e10cSrcweir //*************************************************************************
AppendToBuffer(css::uno::Any aValue,::rtl::OUStringBuffer & aArgumentBuffer)207cdf0e10cSrcweir void SAL_CALL DispatchRecorder::AppendToBuffer( css::uno::Any aValue, ::rtl::OUStringBuffer& aArgumentBuffer )
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     // if value == bool
210cdf0e10cSrcweir     if (aValue.getValueTypeClass() == css::uno::TypeClass_STRUCT )
211cdf0e10cSrcweir     {
212cdf0e10cSrcweir         // structs are recorded as arrays, convert to "Sequence of any"
213cdf0e10cSrcweir         Sequence< Any > aSeq = make_seq_out_of_struct( aValue );
214cdf0e10cSrcweir         aArgumentBuffer.appendAscii("Array(");
215cdf0e10cSrcweir         for ( sal_Int32 nAny=0; nAny<aSeq.getLength(); nAny++ )
216cdf0e10cSrcweir         {
217cdf0e10cSrcweir             AppendToBuffer( aSeq[nAny], aArgumentBuffer );
218cdf0e10cSrcweir             if ( nAny+1 < aSeq.getLength() )
219cdf0e10cSrcweir                 // not last argument
220cdf0e10cSrcweir                 aArgumentBuffer.appendAscii(",");
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir 
223cdf0e10cSrcweir         aArgumentBuffer.appendAscii(")");
224cdf0e10cSrcweir     }
225cdf0e10cSrcweir     else if (aValue.getValueTypeClass() == css::uno::TypeClass_SEQUENCE )
226cdf0e10cSrcweir     {
227cdf0e10cSrcweir         // convert to "Sequence of any"
228cdf0e10cSrcweir         css::uno::Sequence < css::uno::Any > aSeq;
229cdf0e10cSrcweir         css::uno::Any aNew;
230cdf0e10cSrcweir         try { aNew = m_xConverter->convertTo( aValue, ::getCppuType((const css::uno::Sequence < css::uno::Any >*)0) ); }
231cdf0e10cSrcweir         catch (css::uno::Exception&) {}
232cdf0e10cSrcweir 
233cdf0e10cSrcweir         aNew >>= aSeq;
234cdf0e10cSrcweir         aArgumentBuffer.appendAscii("Array(");
235cdf0e10cSrcweir         for ( sal_Int32 nAny=0; nAny<aSeq.getLength(); nAny++ )
236cdf0e10cSrcweir         {
237cdf0e10cSrcweir             AppendToBuffer( aSeq[nAny], aArgumentBuffer );
238cdf0e10cSrcweir             if ( nAny+1 < aSeq.getLength() )
239cdf0e10cSrcweir                 // not last argument
240cdf0e10cSrcweir                 aArgumentBuffer.appendAscii(",");
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir         aArgumentBuffer.appendAscii(")");
244cdf0e10cSrcweir     }
245cdf0e10cSrcweir     else if (aValue.getValueTypeClass() == css::uno::TypeClass_STRING )
246cdf0e10cSrcweir     {
247cdf0e10cSrcweir         // strings need \"
248cdf0e10cSrcweir         ::rtl::OUString sVal;
249cdf0e10cSrcweir         aValue >>= sVal;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir         // encode non printable characters or '"' by using the CHR$ function
252cdf0e10cSrcweir         if ( sVal.getLength() )
253cdf0e10cSrcweir         {
254cdf0e10cSrcweir             const sal_Unicode* pChars = sVal.getStr();
255cdf0e10cSrcweir             sal_Bool bInString = sal_False;
256cdf0e10cSrcweir             for ( sal_Int32 nChar=0; nChar<sVal.getLength(); nChar ++ )
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir                 if ( pChars[nChar] < 32 || pChars[nChar] == '"' )
259cdf0e10cSrcweir                 {
260cdf0e10cSrcweir                     // problematic character detected
261cdf0e10cSrcweir                     if ( bInString )
262cdf0e10cSrcweir                     {
263cdf0e10cSrcweir                         // close current string
264cdf0e10cSrcweir                         aArgumentBuffer.appendAscii("\"");
265cdf0e10cSrcweir                         bInString = sal_False;
266cdf0e10cSrcweir                     }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir                     if ( nChar>0 )
269cdf0e10cSrcweir                         // if this is not the first character, parts of the string have already been added
270cdf0e10cSrcweir                         aArgumentBuffer.appendAscii("+");
271cdf0e10cSrcweir 
272cdf0e10cSrcweir                     // add the character constant
273cdf0e10cSrcweir                     aArgumentBuffer.appendAscii("CHR$(");
274cdf0e10cSrcweir                     aArgumentBuffer.append( (sal_Int32) pChars[nChar] );
275cdf0e10cSrcweir                     aArgumentBuffer.appendAscii(")");
276cdf0e10cSrcweir                 }
277cdf0e10cSrcweir                 else
278cdf0e10cSrcweir                 {
279cdf0e10cSrcweir                     if ( !bInString )
280cdf0e10cSrcweir                     {
281cdf0e10cSrcweir                         if ( nChar>0 )
282cdf0e10cSrcweir                             // if this is not the first character, parts of the string have already been added
283cdf0e10cSrcweir                             aArgumentBuffer.appendAscii("+");
284cdf0e10cSrcweir 
285cdf0e10cSrcweir                         // start a new string
286cdf0e10cSrcweir                         aArgumentBuffer.appendAscii("\"");
287cdf0e10cSrcweir                         bInString = sal_True;
288cdf0e10cSrcweir                     }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir                     aArgumentBuffer.append( pChars[nChar] );
291cdf0e10cSrcweir                 }
292cdf0e10cSrcweir             }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir             // close string
295cdf0e10cSrcweir             if ( bInString )
296cdf0e10cSrcweir                 aArgumentBuffer.appendAscii("\"");
297cdf0e10cSrcweir         }
298cdf0e10cSrcweir         else
299cdf0e10cSrcweir             aArgumentBuffer.appendAscii("\"\"");
300cdf0e10cSrcweir     }
301cdf0e10cSrcweir     else if (aValue.getValueType() == getCppuCharType())
302cdf0e10cSrcweir     {
303cdf0e10cSrcweir         // character variables are recorded as strings, back conversion must be handled in client code
304cdf0e10cSrcweir         sal_Unicode nVal = *((sal_Unicode*)aValue.getValue());
305cdf0e10cSrcweir         aArgumentBuffer.appendAscii("\"");
306cdf0e10cSrcweir         if ( (sal_Unicode(nVal) == '\"') )
307cdf0e10cSrcweir             // encode \" to \"\"
308cdf0e10cSrcweir             aArgumentBuffer.append((sal_Unicode)nVal);
309cdf0e10cSrcweir         aArgumentBuffer.append((sal_Unicode)nVal);
310cdf0e10cSrcweir         aArgumentBuffer.appendAscii("\"");
311cdf0e10cSrcweir     }
312cdf0e10cSrcweir     else
313cdf0e10cSrcweir     {
314cdf0e10cSrcweir         css::uno::Any aNew;
315cdf0e10cSrcweir         try
316cdf0e10cSrcweir         {
317cdf0e10cSrcweir             aNew = m_xConverter->convertToSimpleType( aValue, css::uno::TypeClass_STRING );
318cdf0e10cSrcweir         }
319cdf0e10cSrcweir         catch (css::script::CannotConvertException&) {}
320cdf0e10cSrcweir         catch (css::uno::Exception&) {}
321cdf0e10cSrcweir         ::rtl::OUString sVal;
322cdf0e10cSrcweir         aNew >>= sVal;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir         if (aValue.getValueTypeClass() == css::uno::TypeClass_ENUM )
325cdf0e10cSrcweir         {
326cdf0e10cSrcweir             ::rtl::OUString aName = aValue.getValueType().getTypeName();
327cdf0e10cSrcweir             aArgumentBuffer.append( aName );
328cdf0e10cSrcweir             aArgumentBuffer.appendAscii(".");
329cdf0e10cSrcweir         }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir         aArgumentBuffer.append(sVal);
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir }
334cdf0e10cSrcweir 
implts_recordMacro(const::rtl::OUString & aURL,const css::uno::Sequence<css::beans::PropertyValue> & lArguments,sal_Bool bAsComment,::rtl::OUStringBuffer & aScriptBuffer)335cdf0e10cSrcweir void SAL_CALL DispatchRecorder::implts_recordMacro( const ::rtl::OUString& aURL,
336cdf0e10cSrcweir                                                     const css::uno::Sequence< css::beans::PropertyValue >& lArguments,
337cdf0e10cSrcweir                                                           sal_Bool bAsComment, ::rtl::OUStringBuffer& aScriptBuffer )
338cdf0e10cSrcweir {
339cdf0e10cSrcweir     ::rtl::OUStringBuffer aArgumentBuffer(1000);
340cdf0e10cSrcweir     ::rtl::OUString       sArrayName;
341cdf0e10cSrcweir     // this value is used to name the arrays of aArgumentBuffer
342cdf0e10cSrcweir     sArrayName = ::rtl::OUString::createFromAscii("args");
343cdf0e10cSrcweir     sArrayName += ::rtl::OUString::valueOf((sal_Int32)m_nRecordingID);
344cdf0e10cSrcweir 
345cdf0e10cSrcweir     aScriptBuffer.appendAscii("rem ----------------------------------------------------------------------\n");
346cdf0e10cSrcweir 
347cdf0e10cSrcweir     sal_Int32 nLength = lArguments.getLength();
348cdf0e10cSrcweir     sal_Int32 nValidArgs = 0;
349cdf0e10cSrcweir     for( sal_Int32 i=0; i<nLength; ++i )
350cdf0e10cSrcweir     {
351cdf0e10cSrcweir         if(!lArguments[i].Value.hasValue())
352cdf0e10cSrcweir             continue;
353cdf0e10cSrcweir 
354cdf0e10cSrcweir         ::rtl::OUStringBuffer sValBuffer(100);
355cdf0e10cSrcweir         try
356cdf0e10cSrcweir         {
357cdf0e10cSrcweir             AppendToBuffer(lArguments[i].Value, sValBuffer);
358cdf0e10cSrcweir         }
359cdf0e10cSrcweir         catch(const css::uno::Exception&)
360cdf0e10cSrcweir         {
361cdf0e10cSrcweir             sValBuffer.setLength(0);
362cdf0e10cSrcweir         }
363cdf0e10cSrcweir         if (!sValBuffer.getLength())
364cdf0e10cSrcweir             continue;
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         {
367cdf0e10cSrcweir             // add arg().Name
368cdf0e10cSrcweir             if(bAsComment)
369cdf0e10cSrcweir                 aArgumentBuffer.appendAscii(REM_AS_COMMENT);
370cdf0e10cSrcweir             aArgumentBuffer.append     (sArrayName);
371cdf0e10cSrcweir             aArgumentBuffer.appendAscii("(");
372cdf0e10cSrcweir             aArgumentBuffer.append     (nValidArgs);
373cdf0e10cSrcweir             aArgumentBuffer.appendAscii(").Name = \"");
374cdf0e10cSrcweir             aArgumentBuffer.append     (lArguments[i].Name);
375cdf0e10cSrcweir             aArgumentBuffer.appendAscii("\"\n");
376cdf0e10cSrcweir 
377cdf0e10cSrcweir             // add arg().Value
378cdf0e10cSrcweir             if(bAsComment)
379cdf0e10cSrcweir                 aArgumentBuffer.appendAscii(REM_AS_COMMENT);
380cdf0e10cSrcweir             aArgumentBuffer.append     (sArrayName);
381cdf0e10cSrcweir             aArgumentBuffer.appendAscii("(");
382cdf0e10cSrcweir             aArgumentBuffer.append     (nValidArgs);
383cdf0e10cSrcweir             aArgumentBuffer.appendAscii(").Value = ");
384cdf0e10cSrcweir             aArgumentBuffer.append     (sValBuffer.makeStringAndClear());
385cdf0e10cSrcweir             aArgumentBuffer.appendAscii("\n");
386cdf0e10cSrcweir 
387cdf0e10cSrcweir             ++nValidArgs;
388cdf0e10cSrcweir         }
389cdf0e10cSrcweir     }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir     // if aArgumentBuffer exist - pack it into the aScriptBuffer
392cdf0e10cSrcweir     if(nValidArgs>0)
393cdf0e10cSrcweir     {
394cdf0e10cSrcweir         if(bAsComment)
395cdf0e10cSrcweir             aScriptBuffer.appendAscii(REM_AS_COMMENT);
396cdf0e10cSrcweir         aScriptBuffer.appendAscii("dim ");
397cdf0e10cSrcweir         aScriptBuffer.append     (sArrayName);
398cdf0e10cSrcweir         aScriptBuffer.appendAscii("(");
399cdf0e10cSrcweir         aScriptBuffer.append     ((sal_Int32)(nValidArgs-1)); // 0 based!
400cdf0e10cSrcweir         aScriptBuffer.appendAscii(") as new com.sun.star.beans.PropertyValue\n");
401cdf0e10cSrcweir         aScriptBuffer.append     (aArgumentBuffer.makeStringAndClear());
402cdf0e10cSrcweir         aScriptBuffer.appendAscii("\n");
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     // add code for dispatches
406cdf0e10cSrcweir     if(bAsComment)
407cdf0e10cSrcweir         aScriptBuffer.appendAscii(REM_AS_COMMENT);
408cdf0e10cSrcweir     aScriptBuffer.appendAscii("dispatcher.executeDispatch(document, \"");
409cdf0e10cSrcweir     aScriptBuffer.append     (aURL);
410cdf0e10cSrcweir     aScriptBuffer.appendAscii("\", \"\", 0, ");
411cdf0e10cSrcweir     if(nValidArgs<1)
412cdf0e10cSrcweir         aScriptBuffer.appendAscii("Array()");
413cdf0e10cSrcweir     else
414cdf0e10cSrcweir     {
415cdf0e10cSrcweir         aScriptBuffer.append( sArrayName.getStr() );
416cdf0e10cSrcweir         aScriptBuffer.appendAscii("()");
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir     aScriptBuffer.appendAscii(")\n\n");
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     /* SAFE { */
421cdf0e10cSrcweir     m_nRecordingID++;
422cdf0e10cSrcweir     /* } */
423cdf0e10cSrcweir }
424cdf0e10cSrcweir 
getElementType()425cdf0e10cSrcweir com::sun::star::uno::Type SAL_CALL DispatchRecorder::getElementType() throw (::com::sun::star::uno::RuntimeException)
426cdf0e10cSrcweir {
427cdf0e10cSrcweir     return ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL);
428cdf0e10cSrcweir }
429cdf0e10cSrcweir 
hasElements()430cdf0e10cSrcweir sal_Bool SAL_CALL DispatchRecorder::hasElements() throw (::com::sun::star::uno::RuntimeException)
431cdf0e10cSrcweir {
432cdf0e10cSrcweir     return (! m_aStatements.empty());
433cdf0e10cSrcweir }
434cdf0e10cSrcweir 
getCount()435cdf0e10cSrcweir sal_Int32 SAL_CALL DispatchRecorder::getCount() throw (::com::sun::star::uno::RuntimeException)
436cdf0e10cSrcweir {
437cdf0e10cSrcweir     return m_aStatements.size();
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
getByIndex(sal_Int32 idx)440cdf0e10cSrcweir com::sun::star::uno::Any SAL_CALL DispatchRecorder::getByIndex(sal_Int32 idx) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
441cdf0e10cSrcweir {
442cdf0e10cSrcweir     if (idx >= (sal_Int32)m_aStatements.size()) {
443cdf0e10cSrcweir         throw com::sun::star::lang::IndexOutOfBoundsException(
444cdf0e10cSrcweir             ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
445cdf0e10cSrcweir                 "Dispatch recorder out of bounds") ),
446cdf0e10cSrcweir                     Reference< XInterface >() );
447cdf0e10cSrcweir 
448cdf0e10cSrcweir     }
449cdf0e10cSrcweir 
450cdf0e10cSrcweir     Any element(&m_aStatements[idx],
451cdf0e10cSrcweir         ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL));
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     return element;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
replaceByIndex(sal_Int32 idx,const com::sun::star::uno::Any & element)456cdf0e10cSrcweir void SAL_CALL DispatchRecorder::replaceByIndex(sal_Int32 idx, const com::sun::star::uno::Any& element) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     if (element.getValueType() !=
459cdf0e10cSrcweir         ::getCppuType((const com::sun::star::frame::DispatchStatement *)NULL)) {
460cdf0e10cSrcweir                         throw com::sun::star::lang::IllegalArgumentException(
461cdf0e10cSrcweir                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
462cdf0e10cSrcweir                                 "Illegal argument in dispatch recorder") ),
463cdf0e10cSrcweir                         Reference< XInterface >(), 2 );
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir 
466cdf0e10cSrcweir     if (idx >= (sal_Int32)m_aStatements.size()) {
467cdf0e10cSrcweir                 throw com::sun::star::lang::IndexOutOfBoundsException(
468cdf0e10cSrcweir                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
469cdf0e10cSrcweir                                 "Dispatch recorder out of bounds") ),
470cdf0e10cSrcweir                         Reference< XInterface >() );
471cdf0e10cSrcweir 
472cdf0e10cSrcweir         }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     com::sun::star::frame::DispatchStatement *pStatement;
475cdf0e10cSrcweir 
476cdf0e10cSrcweir     pStatement = (com::sun::star::frame::DispatchStatement *)element.getValue();
477cdf0e10cSrcweir 
478cdf0e10cSrcweir     com::sun::star::frame::DispatchStatement aStatement(
479cdf0e10cSrcweir         pStatement->aCommand,
480cdf0e10cSrcweir         pStatement->aTarget,
481cdf0e10cSrcweir         pStatement->aArgs,
482cdf0e10cSrcweir         pStatement->nFlags,
483cdf0e10cSrcweir         pStatement->bIsComment);
484cdf0e10cSrcweir 
485cdf0e10cSrcweir     m_aStatements[idx] = aStatement;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
488cdf0e10cSrcweir } // namespace framework
489