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 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
getByName(const OUString & rName)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
getElementNames()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
hasByName(const OUString & rName)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
getElementType()142 Type SvBaseEventDescriptor::getElementType()
143 throw(RuntimeException)
144 {
145 return ::getCppuType((Sequence<PropertyValue> *)0);
146 }
147
hasElements()148 sal_Bool SvBaseEventDescriptor::hasElements()
149 throw(RuntimeException)
150 {
151 return mnMacroItems != 0;
152 }
153
supportsService(const OUString & rServiceName)154 sal_Bool SvBaseEventDescriptor::supportsService(const OUString& rServiceName)
155 throw(RuntimeException)
156 {
157 return sServiceName.equals(rServiceName);
158 }
159
getSupportedServiceNames(void)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
mapNameToEventID(const OUString & rName) const169 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
mapEventIDToName(sal_uInt16 nPoolID) const184 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
getMacroID(const OUString & rName) const199 sal_uInt16 SvBaseEventDescriptor::getMacroID(const OUString& rName) const
200 {
201 return mapNameToEventID(rName);
202 }
203
getAnyFromMacro(Any & rAny,const SvxMacro & rMacro)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
getMacroFromAny(SvxMacro & rMacro,const Any & rAny)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
SvEventDescriptor(XInterface & rParent,const SvEventDescription * pSupportedMacroItems)395 SvEventDescriptor::SvEventDescriptor(
396 XInterface& rParent,
397 const SvEventDescription* pSupportedMacroItems) :
398 SvBaseEventDescriptor(pSupportedMacroItems),
399 xParentRef(&rParent)
400 {
401 }
402
403
~SvEventDescriptor()404 SvEventDescriptor::~SvEventDescriptor()
405 {
406 // automatically release xParentRef !
407 }
408
replaceByName(const sal_uInt16 nEvent,const SvxMacro & rMacro)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
getByName(SvxMacro & rMacro,const sal_uInt16 nEvent)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
SvDetachedEventDescriptor(const SvEventDescription * pSupportedMacroItems)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
~SvDetachedEventDescriptor()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
getIndex(const sal_uInt16 nID) const471 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
getImplementationName()483 OUString SvDetachedEventDescriptor::getImplementationName()
484 throw( ::com::sun::star::uno::RuntimeException )
485 {
486 return sImplName;
487 }
488
489
replaceByName(const sal_uInt16 nEvent,const SvxMacro & rMacro)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
getByName(SvxMacro & rMacro,const sal_uInt16 nEvent)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
hasByName(const sal_uInt16 nEvent) const524 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
SvMacroTableEventDescriptor(const SvEventDescription * pSupportedMacroItems)537 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(const SvEventDescription* pSupportedMacroItems) :
538 SvDetachedEventDescriptor(pSupportedMacroItems)
539 {
540 }
541
SvMacroTableEventDescriptor(const SvxMacroTableDtor & rMacroTable,const SvEventDescription * pSupportedMacroItems)542 SvMacroTableEventDescriptor::SvMacroTableEventDescriptor(
543 const SvxMacroTableDtor& rMacroTable,
544 const SvEventDescription* pSupportedMacroItems) :
545 SvDetachedEventDescriptor(pSupportedMacroItems)
546 {
547 copyMacrosFromTable(rMacroTable);
548 }
549
~SvMacroTableEventDescriptor()550 SvMacroTableEventDescriptor::~SvMacroTableEventDescriptor()
551 {
552 }
553
copyMacrosFromTable(const SvxMacroTableDtor & rMacroTable)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
copyMacrosIntoTable(SvxMacroTableDtor & rMacroTable)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