xref: /trunk/main/svtools/source/uno/unoevent.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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
SvBaseEventDescriptor(const SvEventDescription * pSupportedMacroItems)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 
~SvBaseEventDescriptor()69 SvBaseEventDescriptor::~SvBaseEventDescriptor()
70 {
71 }
72 
replaceByName(const OUString & rName,const Any & rElement)73 void SvBaseEventDescriptor::replaceByName(
74     const OUString& rName,
75     const Any& rElement )
76 {
77     sal_uInt16 nMacroID = getMacroID(rName);
78 
79     // error checking
80     if (0 == nMacroID)
81         throw NoSuchElementException();
82     if (rElement.getValueType() != getElementType())
83         throw IllegalArgumentException();
84 
85     // get sequence
86     Sequence<PropertyValue> aSequence;
87     rElement >>= aSequence;
88 
89     // perform replace (in subclass)
90     SvxMacro aMacro(sEmpty,sEmpty);
91     getMacroFromAny(aMacro, rElement);
92     replaceByName(nMacroID, aMacro);
93 }
94 
getByName(const OUString & rName)95 Any SvBaseEventDescriptor::getByName(
96     const OUString& rName )
97 {
98     sal_uInt16 nMacroID = getMacroID(rName);
99 
100     // error checking
101     if (0 == nMacroID)
102         throw NoSuchElementException();
103 
104     // perform get (in subclass)
105     Any aAny;
106     SvxMacro aMacro( sEmpty, sEmpty );
107     getByName(aMacro, nMacroID);
108     getAnyFromMacro(aAny, aMacro);
109     return aAny;
110 }
111 
getElementNames()112 Sequence<OUString> SvBaseEventDescriptor::getElementNames()
113 {
114     // create and fill sequence
115     Sequence<OUString> aSequence(mnMacroItems);
116     for( sal_Int16 i = 0; i < mnMacroItems; i++)
117     {
118         aSequence[i] = OUString::createFromAscii( mpSupportedMacroItems[i].mpEventName );
119     }
120 
121     return aSequence;
122 }
123 
hasByName(const OUString & rName)124 sal_Bool SvBaseEventDescriptor::hasByName(
125     const OUString& rName )
126 {
127     sal_uInt16 nMacroID = getMacroID(rName);
128     return (nMacroID != 0);
129 }
130 
getElementType()131 Type SvBaseEventDescriptor::getElementType()
132 {
133     return ::getCppuType((Sequence<PropertyValue> *)0);
134 }
135 
hasElements()136 sal_Bool SvBaseEventDescriptor::hasElements()
137 {
138     return mnMacroItems != 0;
139 }
140 
supportsService(const OUString & rServiceName)141 sal_Bool SvBaseEventDescriptor::supportsService(const OUString& rServiceName)
142 {
143     return sServiceName.equals(rServiceName);
144 }
145 
getSupportedServiceNames(void)146 Sequence<OUString> SvBaseEventDescriptor::getSupportedServiceNames(void)
147 {
148     Sequence<OUString> aSequence(1);
149     aSequence[0] = sServiceName;
150 
151     return aSequence;
152 }
153 
mapNameToEventID(const OUString & rName) const154 sal_uInt16 SvBaseEventDescriptor::mapNameToEventID(const OUString& rName) const
155 {
156     // iterate over known event names
157     for(sal_Int16 i = 0; i < mnMacroItems; i++)
158     {
159         if (0 == rName.compareToAscii(mpSupportedMacroItems[i].mpEventName))
160         {
161             return mpSupportedMacroItems[i].mnEvent;
162         }
163     }
164 
165     // not found -> return zero
166     return 0;
167 }
168 
mapEventIDToName(sal_uInt16 nPoolID) const169 OUString SvBaseEventDescriptor::mapEventIDToName(sal_uInt16 nPoolID) const
170 {
171     // iterate over known event IDs
172     for(sal_Int16 i = 0; i < mnMacroItems; i++)
173     {
174         if (nPoolID == mpSupportedMacroItems[i].mnEvent)
175         {
176             return OUString::createFromAscii(mpSupportedMacroItems[i].mpEventName);
177         }
178     }
179 
180     // not found -> return empty string
181     return OUString();
182 }
183 
getMacroID(const OUString & rName) const184 sal_uInt16 SvBaseEventDescriptor::getMacroID(const OUString& rName) const
185 {
186     return mapNameToEventID(rName);
187 }
188 
getAnyFromMacro(Any & rAny,const SvxMacro & rMacro)189 void SvBaseEventDescriptor::getAnyFromMacro(Any& rAny,
190                                        const SvxMacro& rMacro)
191 {
192     sal_Bool bRetValueOK = sal_False;   // do we have a ret value?
193 
194     if (rMacro.HasMacro())
195     {
196         switch (rMacro.GetScriptType())
197         {
198             case STARBASIC:
199             {
200                 // create sequence
201                 Sequence<PropertyValue> aSequence(3);
202                 Any aTmp;
203 
204                 // create type
205                 PropertyValue aTypeValue;
206                 aTypeValue.Name = sEventType;
207                 aTmp <<= sStarBasic;
208                 aTypeValue.Value = aTmp;
209                 aSequence[0] = aTypeValue;
210 
211                 // macro name
212                 PropertyValue aNameValue;
213                 aNameValue.Name = sMacroName;
214                 OUString sNameTmp(rMacro.GetMacName());
215                 aTmp <<= sNameTmp;
216                 aNameValue.Value = aTmp;
217                 aSequence[1] = aNameValue;
218 
219                 // library name
220                 PropertyValue aLibValue;
221                 aLibValue.Name = sLibrary;
222                 OUString sLibTmp(rMacro.GetLibName());
223                 aTmp <<= sLibTmp;
224                 aLibValue.Value = aTmp;
225                 aSequence[2] = aLibValue;
226 
227                 rAny <<= aSequence;
228                 bRetValueOK = sal_True;
229                 break;
230             }
231             case EXTENDED_STYPE:
232             {
233                 // create sequence
234                 Sequence<PropertyValue> aSequence(2);
235                 Any aTmp;
236 
237                 // create type
238                 PropertyValue aTypeValue;
239                 aTypeValue.Name = sEventType;
240                 aTmp <<= sScript;
241                 aTypeValue.Value = aTmp;
242                 aSequence[0] = aTypeValue;
243 
244                 // macro name
245                 PropertyValue aNameValue;
246                 aNameValue.Name = sScript;
247                 OUString sNameTmp(rMacro.GetMacName());
248                 aTmp <<= sNameTmp;
249                 aNameValue.Value = aTmp;
250                 aSequence[1] = aNameValue;
251 
252                 rAny <<= aSequence;
253                 bRetValueOK = sal_True;
254                 break;
255             }
256             case JAVASCRIPT:
257             default:
258                 DBG_ERROR("not implemented");
259         }
260     }
261     // else: bRetValueOK not set
262 
263     // if we don't have a return value, make an empty one
264     if (! bRetValueOK)
265     {
266         // create "None" macro
267         Sequence<PropertyValue> aSequence(1);
268 
269         PropertyValue aKindValue;
270         aKindValue.Name = sEventType;
271         Any aTmp;
272         aTmp <<= sNone;
273         aKindValue.Value = aTmp;
274         aSequence[0] = aKindValue;
275 
276         rAny <<= aSequence;
277         bRetValueOK = sal_True;
278     }
279 }
280 
281 
getMacroFromAny(SvxMacro & rMacro,const Any & rAny)282 void SvBaseEventDescriptor::getMacroFromAny(
283     SvxMacro& rMacro,
284     const Any& rAny)
285 {
286     // get sequence
287     Sequence<PropertyValue> aSequence;
288     rAny >>= aSequence;
289 
290     // process ...
291     sal_Bool bTypeOK = sal_False;
292     sal_Bool bNone = sal_False; // true if EventType=="None"
293     enum ScriptType eType = EXTENDED_STYPE;
294     OUString sScriptVal;
295     OUString sMacroVal;
296     OUString sLibVal;
297     sal_Int32 nCount = aSequence.getLength();
298     for (sal_Int32 i = 0; i < nCount; i++)
299     {
300         PropertyValue& aValue = aSequence[i];
301         if (aValue.Name.equals(sEventType))
302         {
303             OUString sTmp;
304             aValue.Value >>= sTmp;
305             if (sTmp.equals(sStarBasic))
306             {
307                 eType = STARBASIC;
308                 bTypeOK = sal_True;
309             }
310             else if (sTmp.equals(sJavaScript))
311             {
312                 eType = JAVASCRIPT;
313                 bTypeOK = sal_True;
314             }
315             else if (sTmp.equals(sScript))
316             {
317                 eType = EXTENDED_STYPE;
318                 bTypeOK = sal_True;
319             }
320             else if (sTmp.equals(sNone))
321             {
322                 bNone = sal_True;
323                 bTypeOK = sal_True;
324             }
325             // else: unknown script type
326         }
327         else if (aValue.Name.equals(sMacroName))
328         {
329             aValue.Value >>= sMacroVal;
330         }
331         else if (aValue.Name.equals(sLibrary))
332         {
333             aValue.Value >>= sLibVal;
334         }
335         else if (aValue.Name.equals(sScript))
336         {
337             aValue.Value >>= sScriptVal;
338         }
339         // else: unknown PropertyValue -> ignore
340     }
341 
342     if (bTypeOK)
343     {
344         if (bNone)
345         {
346             // return empty macro
347             rMacro = SvxMacro( sEmpty, sEmpty );
348         }
349         else
350         {
351             if (eType == STARBASIC)
352             {
353                 // create macro and return
354                 SvxMacro aMacro(sMacroVal, sLibVal, eType);
355                 rMacro = aMacro;
356             }
357             else if (eType == EXTENDED_STYPE)
358             {
359                 SvxMacro aMacro(sScriptVal, sScript);
360                 rMacro = aMacro;
361             }
362             else
363             {
364                 // we can't process type: abort
365                 // TODO: JavaScript macros
366                 throw IllegalArgumentException();
367             }
368         }
369     }
370     else
371     {
372         // no valid type: abort
373         throw IllegalArgumentException();
374     }
375 }
376 
377 
378 // SvEventDescriptor
SvEventDescriptor(XInterface & rParent,const SvEventDescription * pSupportedMacroItems)379 SvEventDescriptor::SvEventDescriptor(
380     XInterface& rParent,
381     const SvEventDescription* pSupportedMacroItems) :
382         SvBaseEventDescriptor(pSupportedMacroItems),
383         xParentRef(&rParent)
384 {
385 }
386 
387 
~SvEventDescriptor()388 SvEventDescriptor::~SvEventDescriptor()
389 {
390     // automatically release xParentRef !
391 }
392 
replaceByName(const sal_uInt16 nEvent,const SvxMacro & rMacro)393 void SvEventDescriptor::replaceByName(
394     const sal_uInt16 nEvent,
395     const SvxMacro& rMacro)
396 {
397     SvxMacroItem aItem(getMacroItemWhich());
398     aItem.SetMacroTable(getMacroItem().GetMacroTable());
399     aItem.SetMacro(nEvent, rMacro);
400     setMacroItem(aItem);
401 }
402 
getByName(SvxMacro & rMacro,const sal_uInt16 nEvent)403 void SvEventDescriptor::getByName(
404     SvxMacro& rMacro,
405     const sal_uInt16 nEvent )
406 {
407     const SvxMacroItem& rItem = getMacroItem();
408     if( rItem.HasMacro( nEvent ) )
409         rMacro = rItem.GetMacro(nEvent);
410     else
411     {
412         SvxMacro aEmptyMacro(sEmpty, sEmpty);
413         rMacro = aEmptyMacro;
414     }
415 }
416 
417 
418 // SvDetachedEventDescriptor
SvDetachedEventDescriptor(const SvEventDescription * pSupportedMacroItems)419 SvDetachedEventDescriptor::SvDetachedEventDescriptor(
420     const SvEventDescription* pSupportedMacroItems) :
421     SvBaseEventDescriptor(pSupportedMacroItems),
422     sImplName(RTL_CONSTASCII_USTRINGPARAM(sAPI_SvDetachedEventDescriptor))
423 {
424     // allocate aMacros
425     aMacros = new SvxMacro*[mnMacroItems];
426 
427     // ... and initialize
428     for(sal_Int16 i = 0; i < mnMacroItems; i++)
429     {
430         aMacros[i] = NULL;
431     }
432 }
433 
~SvDetachedEventDescriptor()434 SvDetachedEventDescriptor::~SvDetachedEventDescriptor()
435 {
436     // delete contents of aMacros
437     for(sal_Int16 i = 0; i < mnMacroItems; i++)
438     {
439         if (NULL != aMacros[i])
440             delete aMacros[i];
441     }
442 
443     delete [] aMacros;
444 }
445 
getIndex(const sal_uInt16 nID) const446 sal_Int16 SvDetachedEventDescriptor::getIndex(const sal_uInt16 nID) const
447 {
448     // iterate over supported events
449     sal_Int16 nIndex = 0;
450     while ( (mpSupportedMacroItems[nIndex].mnEvent != nID) &&
451             (mpSupportedMacroItems[nIndex].mnEvent != 0)      )
452     {
453         nIndex++;
454     }
455     return (mpSupportedMacroItems[nIndex].mnEvent == nID) ? nIndex : -1;
456 }
457 
getImplementationName()458 OUString SvDetachedEventDescriptor::getImplementationName()
459 {
460     return sImplName;
461 }
462 
463 
replaceByName(const sal_uInt16 nEvent,const SvxMacro & rMacro)464 void SvDetachedEventDescriptor::replaceByName(
465     const sal_uInt16 nEvent,
466     const SvxMacro& rMacro)
467 {
468     sal_Int16 nIndex = getIndex(nEvent);
469     if (-1 == nIndex)
470         throw IllegalArgumentException();
471 
472     aMacros[nIndex] = new SvxMacro(rMacro.GetMacName(), rMacro.GetLibName(),
473                                    rMacro.GetScriptType() );
474 }
475 
476 
getByName(SvxMacro & rMacro,const sal_uInt16 nEvent)477 void SvDetachedEventDescriptor::getByName(
478     SvxMacro& rMacro,
479     const sal_uInt16 nEvent )
480 {
481     sal_Int16 nIndex = getIndex(nEvent);
482     if (-1 == nIndex )
483         throw NoSuchElementException();
484 
485     if( aMacros[nIndex] )
486         rMacro = (*aMacros[nIndex]);
487 }
488 
hasByName(const sal_uInt16 nEvent) const489 sal_Bool SvDetachedEventDescriptor::hasByName(
490     const sal_uInt16 nEvent ) const     // item ID of event
491 {
492     sal_Int16 nIndex = getIndex(nEvent);
493     if (-1 == nIndex)
494         throw IllegalArgumentException();
495 
496     return (NULL == aMacros[nIndex]) ? sal_False : aMacros[nIndex]->HasMacro();
497 }
498 
499 
500 // SvMacroTableEventDescriptor
SvMacroTableEventDescriptor(const SvEventDescription * pSupportedMacroItems)501 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(const SvEventDescription* pSupportedMacroItems) :
502     SvDetachedEventDescriptor(pSupportedMacroItems)
503 {
504 }
505 
SvMacroTableEventDescriptor(const SvxMacroTableDtor & rMacroTable,const SvEventDescription * pSupportedMacroItems)506 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(
507     const SvxMacroTableDtor& rMacroTable,
508     const SvEventDescription* pSupportedMacroItems) :
509         SvDetachedEventDescriptor(pSupportedMacroItems)
510 {
511     copyMacrosFromTable(rMacroTable);
512 }
513 
~SvMacroTableEventDescriptor()514 SvMacroTableEventDescriptor::~SvMacroTableEventDescriptor()
515 {
516 }
517 
copyMacrosFromTable(const SvxMacroTableDtor & rMacroTable)518 void SvMacroTableEventDescriptor::copyMacrosFromTable(
519     const SvxMacroTableDtor& rMacroTable)
520 {
521     for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
522     {
523         const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
524         const SvxMacro* pMacro = rMacroTable.Get(nEvent);
525         if (NULL != pMacro)
526             replaceByName(nEvent, *pMacro);
527     }
528 
529 }
530 
copyMacrosIntoTable(SvxMacroTableDtor & rMacroTable)531 void SvMacroTableEventDescriptor::copyMacrosIntoTable(
532     SvxMacroTableDtor& rMacroTable)
533 {
534     for(sal_Int16 i = 0; mpSupportedMacroItems[i].mnEvent != 0; i++)
535     {
536         const sal_uInt16 nEvent = mpSupportedMacroItems[i].mnEvent;
537         if (hasByName(nEvent))
538         {
539             SvxMacro* pMacro = new SvxMacro(sEmpty, sEmpty);
540             getByName(*pMacro, nEvent);
541             rMacroTable.Insert(nEvent, pMacro);
542         }
543     }
544 }
545 
546 /* vim: set noet sw=4 ts=4: */
547