xref: /aoo42x/main/svtools/source/uno/unoevent.cxx (revision cdf0e10c)
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