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