xref: /trunk/main/svtools/source/uno/unoevent.cxx (revision a3cdc23e488c57f3433f22cd4458e65c27aa499c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_svtools.hxx"
24 
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <rtl/ustrbuf.hxx>
27 #include <tools/rtti.hxx>
28 #include <tools/solar.h>
29 #include <svtools/unoevent.hxx>
30 #include <svl/macitem.hxx>
31 
32 using namespace ::com::sun::star;
33 using namespace ::com::sun::star::uno;
34 
35 using ::com::sun::star::container::NoSuchElementException;
36 using ::com::sun::star::container::XNameReplace;
37 using ::com::sun::star::lang::IllegalArgumentException;
38 using ::com::sun::star::lang::WrappedTargetException;
39 using ::com::sun::star::lang::XServiceInfo;
40 using ::com::sun::star::beans::PropertyValue;
41 using ::cppu::WeakImplHelper2;
42 using ::rtl::OUString;
43 using ::rtl::OUStringBuffer;
44 
45 
46 const sal_Char sAPI_ServiceName[] = "com.sun.star.container.XNameReplace";
47 const sal_Char sAPI_SvDetachedEventDescriptor[] = "SvDetachedEventDescriptor";
48 
49 // SvBaseEventDescriptor
50 SvBaseEventDescriptor::SvBaseEventDescriptor( const SvEventDescription* pSupportedMacroItems ) :
51         sEventType(RTL_CONSTASCII_USTRINGPARAM("EventType")),
52         sMacroName(RTL_CONSTASCII_USTRINGPARAM("MacroName")),
53         sLibrary(RTL_CONSTASCII_USTRINGPARAM("Library")),
54         sStarBasic(RTL_CONSTASCII_USTRINGPARAM("StarBasic")),
55         sJavaScript(RTL_CONSTASCII_USTRINGPARAM("JavaScript")),
56         sScript(RTL_CONSTASCII_USTRINGPARAM("Script")),
57         sNone(RTL_CONSTASCII_USTRINGPARAM("None")),
58         sServiceName(RTL_CONSTASCII_USTRINGPARAM(sAPI_ServiceName)),
59         sEmpty(),
60         mpSupportedMacroItems(pSupportedMacroItems),
61         mnMacroItems(0)
62 {
63     DBG_ASSERT(pSupportedMacroItems != NULL, "Need a list of supported events!");
64 
65     for( ; mpSupportedMacroItems[mnMacroItems].mnEvent != 0; mnMacroItems++) ;
66 }
67 
68 
69 SvBaseEventDescriptor::~SvBaseEventDescriptor()
70 {
71 }
72 
73 void SvBaseEventDescriptor::replaceByName(
74     const OUString& rName,
75     const Any& rElement )
76     throw(
77         IllegalArgumentException,
78         NoSuchElementException,
79         WrappedTargetException,
80         RuntimeException)
81 {
82     sal_uInt16 nMacroID = getMacroID(rName);
83 
84     // error checking
85     if (0 == nMacroID)
86         throw NoSuchElementException();
87     if (rElement.getValueType() != getElementType())
88         throw IllegalArgumentException();
89 
90     // get sequence
91     Sequence<PropertyValue> aSequence;
92     rElement >>= aSequence;
93 
94     // perform replace (in subclass)
95     SvxMacro aMacro(sEmpty,sEmpty);
96     getMacroFromAny(aMacro, rElement);
97     replaceByName(nMacroID, aMacro);
98 }
99 
100 Any SvBaseEventDescriptor::getByName(
101     const OUString& rName )
102     throw(
103         NoSuchElementException,
104         WrappedTargetException,
105         RuntimeException)
106 {
107     sal_uInt16 nMacroID = getMacroID(rName);
108 
109     // error checking
110     if (0 == nMacroID)
111         throw NoSuchElementException();
112 
113     // perform get (in subclass)
114     Any aAny;
115     SvxMacro aMacro( sEmpty, sEmpty );
116     getByName(aMacro, nMacroID);
117     getAnyFromMacro(aAny, aMacro);
118     return aAny;
119 }
120 
121 Sequence<OUString> SvBaseEventDescriptor::getElementNames()
122     throw(RuntimeException)
123 {
124     // create and fill sequence
125     Sequence<OUString> aSequence(mnMacroItems);
126     for( sal_Int16 i = 0; i < mnMacroItems; i++)
127     {
128         aSequence[i] = OUString::createFromAscii( mpSupportedMacroItems[i].mpEventName );
129     }
130 
131     return aSequence;
132 }
133 
134 sal_Bool SvBaseEventDescriptor::hasByName(
135     const OUString& rName )
136     throw(RuntimeException)
137 {
138     sal_uInt16 nMacroID = getMacroID(rName);
139     return (nMacroID != 0);
140 }
141 
142 Type SvBaseEventDescriptor::getElementType()
143     throw(RuntimeException)
144 {
145     return ::getCppuType((Sequence<PropertyValue> *)0);
146 }
147 
148 sal_Bool SvBaseEventDescriptor::hasElements()
149     throw(RuntimeException)
150 {
151     return mnMacroItems != 0;
152 }
153 
154 sal_Bool SvBaseEventDescriptor::supportsService(const OUString& rServiceName)
155     throw(RuntimeException)
156 {
157     return sServiceName.equals(rServiceName);
158 }
159 
160 Sequence<OUString> SvBaseEventDescriptor::getSupportedServiceNames(void)
161     throw(RuntimeException)
162 {
163     Sequence<OUString> aSequence(1);
164     aSequence[0] = sServiceName;
165 
166     return aSequence;
167 }
168 
169 sal_uInt16 SvBaseEventDescriptor::mapNameToEventID(const OUString& rName) const
170 {
171     // iterate over known event names
172     for(sal_Int16 i = 0; i < mnMacroItems; i++)
173     {
174         if (0 == rName.compareToAscii(mpSupportedMacroItems[i].mpEventName))
175         {
176             return mpSupportedMacroItems[i].mnEvent;
177         }
178     }
179 
180     // not found -> return zero
181     return 0;
182 }
183 
184 OUString SvBaseEventDescriptor::mapEventIDToName(sal_uInt16 nPoolID) const
185 {
186     // iterate over known event IDs
187     for(sal_Int16 i = 0; i < mnMacroItems; i++)
188     {
189         if (nPoolID == mpSupportedMacroItems[i].mnEvent)
190         {
191             return OUString::createFromAscii(mpSupportedMacroItems[i].mpEventName);
192         }
193     }
194 
195     // not found -> return empty string
196     return OUString();
197 }
198 
199 sal_uInt16 SvBaseEventDescriptor::getMacroID(const OUString& rName) const
200 {
201     return mapNameToEventID(rName);
202 }
203 
204 void SvBaseEventDescriptor::getAnyFromMacro(Any& rAny,
205                                        const SvxMacro& rMacro)
206 {
207     sal_Bool bRetValueOK = sal_False;   // do we have a ret value?
208 
209     if (rMacro.HasMacro())
210     {
211         switch (rMacro.GetScriptType())
212         {
213             case STARBASIC:
214             {
215                 // create sequence
216                 Sequence<PropertyValue> aSequence(3);
217                 Any aTmp;
218 
219                 // create type
220                 PropertyValue aTypeValue;
221                 aTypeValue.Name = sEventType;
222                 aTmp <<= sStarBasic;
223                 aTypeValue.Value = aTmp;
224                 aSequence[0] = aTypeValue;
225 
226                 // macro name
227                 PropertyValue aNameValue;
228                 aNameValue.Name = sMacroName;
229                 OUString sNameTmp(rMacro.GetMacName());
230                 aTmp <<= sNameTmp;
231                 aNameValue.Value = aTmp;
232                 aSequence[1] = aNameValue;
233 
234                 // library name
235                 PropertyValue aLibValue;
236                 aLibValue.Name = sLibrary;
237                 OUString sLibTmp(rMacro.GetLibName());
238                 aTmp <<= sLibTmp;
239                 aLibValue.Value = aTmp;
240                 aSequence[2] = aLibValue;
241 
242                 rAny <<= aSequence;
243                 bRetValueOK = sal_True;
244                 break;
245             }
246             case EXTENDED_STYPE:
247             {
248                 // create sequence
249                 Sequence<PropertyValue> aSequence(2);
250                 Any aTmp;
251 
252                 // create type
253                 PropertyValue aTypeValue;
254                 aTypeValue.Name = sEventType;
255                 aTmp <<= sScript;
256                 aTypeValue.Value = aTmp;
257                 aSequence[0] = aTypeValue;
258 
259                 // macro name
260                 PropertyValue aNameValue;
261                 aNameValue.Name = sScript;
262                 OUString sNameTmp(rMacro.GetMacName());
263                 aTmp <<= sNameTmp;
264                 aNameValue.Value = aTmp;
265                 aSequence[1] = aNameValue;
266 
267                 rAny <<= aSequence;
268                 bRetValueOK = sal_True;
269                 break;
270             }
271             case JAVASCRIPT:
272             default:
273                 DBG_ERROR("not implemented");
274         }
275     }
276     // else: bRetValueOK not set
277 
278     // if we don't have a return value, make an empty one
279     if (! bRetValueOK)
280     {
281         // create "None" macro
282         Sequence<PropertyValue> aSequence(1);
283 
284         PropertyValue aKindValue;
285         aKindValue.Name = sEventType;
286         Any aTmp;
287         aTmp <<= sNone;
288         aKindValue.Value = aTmp;
289         aSequence[0] = aKindValue;
290 
291         rAny <<= aSequence;
292         bRetValueOK = sal_True;
293     }
294 }
295 
296 
297 void SvBaseEventDescriptor::getMacroFromAny(
298     SvxMacro& rMacro,
299     const Any& rAny)
300         throw ( IllegalArgumentException )
301 {
302     // get sequence
303     Sequence<PropertyValue> aSequence;
304     rAny >>= aSequence;
305 
306     // process ...
307     sal_Bool bTypeOK = sal_False;
308     sal_Bool bNone = sal_False; // true if EventType=="None"
309     enum ScriptType eType = EXTENDED_STYPE;
310     OUString sScriptVal;
311     OUString sMacroVal;
312     OUString sLibVal;
313     sal_Int32 nCount = aSequence.getLength();
314     for (sal_Int32 i = 0; i < nCount; i++)
315     {
316         PropertyValue& aValue = aSequence[i];
317         if (aValue.Name.equals(sEventType))
318         {
319             OUString sTmp;
320             aValue.Value >>= sTmp;
321             if (sTmp.equals(sStarBasic))
322             {
323                 eType = STARBASIC;
324                 bTypeOK = sal_True;
325             }
326             else if (sTmp.equals(sJavaScript))
327             {
328                 eType = JAVASCRIPT;
329                 bTypeOK = sal_True;
330             }
331             else if (sTmp.equals(sScript))
332             {
333                 eType = EXTENDED_STYPE;
334                 bTypeOK = sal_True;
335             }
336             else if (sTmp.equals(sNone))
337             {
338                 bNone = sal_True;
339                 bTypeOK = sal_True;
340             }
341             // else: unknown script type
342         }
343         else if (aValue.Name.equals(sMacroName))
344         {
345             aValue.Value >>= sMacroVal;
346         }
347         else if (aValue.Name.equals(sLibrary))
348         {
349             aValue.Value >>= sLibVal;
350         }
351         else if (aValue.Name.equals(sScript))
352         {
353             aValue.Value >>= sScriptVal;
354         }
355         // else: unknown PropertyValue -> ignore
356     }
357 
358     if (bTypeOK)
359     {
360         if (bNone)
361         {
362             // return empty macro
363             rMacro = SvxMacro( sEmpty, sEmpty );
364         }
365         else
366         {
367             if (eType == STARBASIC)
368             {
369                 // create macro and return
370                 SvxMacro aMacro(sMacroVal, sLibVal, eType);
371                 rMacro = aMacro;
372             }
373             else if (eType == EXTENDED_STYPE)
374             {
375                 SvxMacro aMacro(sScriptVal, sScript);
376                 rMacro = aMacro;
377             }
378             else
379             {
380                 // we can't process type: abort
381                 // TODO: JavaScript macros
382                 throw IllegalArgumentException();
383             }
384         }
385     }
386     else
387     {
388         // no valid type: abort
389         throw IllegalArgumentException();
390     }
391 }
392 
393 
394 // SvEventDescriptor
395 SvEventDescriptor::SvEventDescriptor(
396     XInterface& rParent,
397     const SvEventDescription* pSupportedMacroItems) :
398         SvBaseEventDescriptor(pSupportedMacroItems),
399         xParentRef(&rParent)
400 {
401 }
402 
403 
404 SvEventDescriptor::~SvEventDescriptor()
405 {
406     // automatically release xParentRef !
407 }
408 
409 void SvEventDescriptor::replaceByName(
410     const sal_uInt16 nEvent,
411     const SvxMacro& rMacro)
412         throw(
413             IllegalArgumentException,
414             NoSuchElementException,
415             WrappedTargetException,
416             RuntimeException)
417 {
418     SvxMacroItem aItem(getMacroItemWhich());
419     aItem.SetMacroTable(getMacroItem().GetMacroTable());
420     aItem.SetMacro(nEvent, rMacro);
421     setMacroItem(aItem);
422 }
423 
424 void SvEventDescriptor::getByName(
425     SvxMacro& rMacro,
426     const sal_uInt16 nEvent )
427         throw(
428             NoSuchElementException,
429             WrappedTargetException,
430             RuntimeException)
431 {
432     const SvxMacroItem& rItem = getMacroItem();
433     if( rItem.HasMacro( nEvent ) )
434         rMacro = rItem.GetMacro(nEvent);
435     else
436     {
437         SvxMacro aEmptyMacro(sEmpty, sEmpty);
438         rMacro = aEmptyMacro;
439     }
440 }
441 
442 
443 // SvDetachedEventDescriptor
444 SvDetachedEventDescriptor::SvDetachedEventDescriptor(
445     const SvEventDescription* pSupportedMacroItems) :
446     SvBaseEventDescriptor(pSupportedMacroItems),
447     sImplName(RTL_CONSTASCII_USTRINGPARAM(sAPI_SvDetachedEventDescriptor))
448 {
449     // allocate aMacros
450     aMacros = new SvxMacro*[mnMacroItems];
451 
452     // ... and initialize
453     for(sal_Int16 i = 0; i < mnMacroItems; i++)
454     {
455         aMacros[i] = NULL;
456     }
457 }
458 
459 SvDetachedEventDescriptor::~SvDetachedEventDescriptor()
460 {
461     // delete contents of aMacros
462     for(sal_Int16 i = 0; i < mnMacroItems; i++)
463     {
464         if (NULL != aMacros[i])
465             delete aMacros[i];
466     }
467 
468     delete [] aMacros;
469 }
470 
471 sal_Int16 SvDetachedEventDescriptor::getIndex(const sal_uInt16 nID) const
472 {
473     // iterate over supported events
474     sal_Int16 nIndex = 0;
475     while ( (mpSupportedMacroItems[nIndex].mnEvent != nID) &&
476             (mpSupportedMacroItems[nIndex].mnEvent != 0)      )
477     {
478         nIndex++;
479     }
480     return (mpSupportedMacroItems[nIndex].mnEvent == nID) ? nIndex : -1;
481 }
482 
483 OUString SvDetachedEventDescriptor::getImplementationName()
484     throw( ::com::sun::star::uno::RuntimeException )
485 {
486     return sImplName;
487 }
488 
489 
490 void SvDetachedEventDescriptor::replaceByName(
491     const sal_uInt16 nEvent,
492     const SvxMacro& rMacro)
493     throw(
494         IllegalArgumentException,
495         NoSuchElementException,
496         WrappedTargetException,
497         RuntimeException)
498 {
499     sal_Int16 nIndex = getIndex(nEvent);
500     if (-1 == nIndex)
501         throw IllegalArgumentException();
502 
503     aMacros[nIndex] = new SvxMacro(rMacro.GetMacName(), rMacro.GetLibName(),
504                                    rMacro.GetScriptType() );
505 }
506 
507 
508 void SvDetachedEventDescriptor::getByName(
509     SvxMacro& rMacro,
510     const sal_uInt16 nEvent )
511     throw(
512         NoSuchElementException,
513         WrappedTargetException,
514         RuntimeException)
515 {
516     sal_Int16 nIndex = getIndex(nEvent);
517     if (-1 == nIndex )
518         throw NoSuchElementException();
519 
520     if( aMacros[nIndex] )
521         rMacro = (*aMacros[nIndex]);
522 }
523 
524 sal_Bool SvDetachedEventDescriptor::hasByName(
525     const sal_uInt16 nEvent ) const     // item ID of event
526         throw(IllegalArgumentException)
527 {
528     sal_Int16 nIndex = getIndex(nEvent);
529     if (-1 == nIndex)
530         throw IllegalArgumentException();
531 
532     return (NULL == aMacros[nIndex]) ? sal_False : aMacros[nIndex]->HasMacro();
533 }
534 
535 
536 // SvMacroTableEventDescriptor
537 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(const SvEventDescription* pSupportedMacroItems) :
538     SvDetachedEventDescriptor(pSupportedMacroItems)
539 {
540 }
541 
542 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(
543     const SvxMacroTableDtor& rMacroTable,
544     const SvEventDescription* pSupportedMacroItems) :
545         SvDetachedEventDescriptor(pSupportedMacroItems)
546 {
547     copyMacrosFromTable(rMacroTable);
548 }
549 
550 SvMacroTableEventDescriptor::~SvMacroTableEventDescriptor()
551 {
552 }
553 
554 void SvMacroTableEventDescriptor::copyMacrosFromTable(
555     const SvxMacroTableDtor& rMacroTable)
556 {
557     for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
558     {
559         const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
560         const SvxMacro* pMacro = rMacroTable.Get(nEvent);
561         if (NULL != pMacro)
562             replaceByName(nEvent, *pMacro);
563     }
564 
565 }
566 
567 void SvMacroTableEventDescriptor::copyMacrosIntoTable(
568     SvxMacroTableDtor& rMacroTable)
569 {
570     for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
571     {
572         const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
573         if (hasByName(nEvent))
574         {
575             SvxMacro* pMacro = new SvxMacro(sEmpty, sEmpty);
576             getByName(*pMacro, nEvent);
577             rMacroTable.Insert(nEvent, pMacro);
578         }
579     }
580 }
581 
582 /* vim: set noet sw=4 ts=4: */
583