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