xref: /aoo42x/main/editeng/source/uno/unonrule.cxx (revision 6de4612a)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 #define PROPERTY_NONE 0
28 
29 #include <com/sun/star/text/HoriOrientation.hpp>
30 #include <com/sun/star/awt/XBitmap.hpp>
31 
32 #include <vcl/svapp.hxx>
33 #include <vos/mutex.hxx>
34 #include <vcl/graph.hxx>
35 #include <svtools/grfmgr.hxx>
36 #include <toolkit/unohlp.hxx>
37 #include <rtl/uuid.h>
38 #include <rtl/memory.h>
39 
40 #include <editeng/brshitem.hxx>
41 #include <editeng/unoprnms.hxx>
42 #include <editeng/numitem.hxx>
43 #include <editeng/eeitem.hxx>
44 #include <editeng/unotext.hxx>
45 #include <editeng/numitem.hxx>
46 #include <editeng/unofdesc.hxx>
47 #include <editeng/unonrule.hxx>
48 #include <editeng/editids.hrc>
49 
50 using ::rtl::OUString;
51 using ::com::sun::star::util::XCloneable;
52 using ::com::sun::star::ucb::XAnyCompare;
53 
54 
55 using namespace ::vos;
56 using namespace ::std;
57 using namespace ::com::sun::star;
58 using namespace ::com::sun::star::uno;
59 using namespace ::com::sun::star::lang;
60 using namespace ::com::sun::star::container;
61 
62 const SvxAdjust aUnoToSvxAdjust[] =
63 {
64 	SVX_ADJUST_LEFT,
65 	SVX_ADJUST_RIGHT,
66 	SVX_ADJUST_CENTER,
67 	SVX_ADJUST_LEFT,
68 	SVX_ADJUST_LEFT,
69 	SVX_ADJUST_LEFT,
70 	SVX_ADJUST_BLOCK
71 };
72 
73 const unsigned short aSvxToUnoAdjust[] =
74 {
75 	text::HoriOrientation::LEFT,
76 	text::HoriOrientation::RIGHT,
77 	text::HoriOrientation::FULL,
78 	text::HoriOrientation::CENTER,
79 	text::HoriOrientation::FULL,
80 	text::HoriOrientation::LEFT
81 };
82 
83 SvxAdjust ConvertUnoAdjust( unsigned short nAdjust )
84 {
85 	DBG_ASSERT( nAdjust <= 7, "Enum hat sich geaendert! [CL]" );
86 	return aUnoToSvxAdjust[nAdjust];
87 }
88 
89 unsigned short ConvertUnoAdjust( SvxAdjust eAdjust )
90 {
91 	DBG_ASSERT( eAdjust <= 6, "Enum hat sich geaendert! [CL]" );
92 	return aSvxToUnoAdjust[eAdjust];
93 }
94 
95 /******************************************************************
96  * SvxUnoNumberingRules
97  ******************************************************************/
98 
99 UNO3_GETIMPLEMENTATION_IMPL( SvxUnoNumberingRules );
100 
101 SvxUnoNumberingRules::SvxUnoNumberingRules( const SvxNumRule& rRule ) throw()
102 : maRule( rRule )
103 {
104 }
105 
106 SvxUnoNumberingRules::~SvxUnoNumberingRules() throw()
107 {
108 }
109 
110 //XIndexReplace
111 void SAL_CALL SvxUnoNumberingRules::replaceByIndex( sal_Int32 Index, const uno::Any& Element )
112 	throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
113 {
114 	OGuard aGuard( Application::GetSolarMutex() );
115 
116 	if( Index < 0 || Index >= maRule.GetLevelCount() )
117 		throw IndexOutOfBoundsException();
118 
119 	Sequence< beans::PropertyValue > aSeq;
120 
121 	if( !( Element >>= aSeq) )
122 		throw IllegalArgumentException();
123 	setNumberingRuleByIndex( aSeq, Index );
124 }
125 
126 // XIndexAccess
127 sal_Int32 SAL_CALL SvxUnoNumberingRules::getCount() throw( RuntimeException )
128 {
129 	OGuard aGuard( Application::GetSolarMutex() );
130 
131 	return maRule.GetLevelCount();
132 }
133 
134 Any SAL_CALL SvxUnoNumberingRules::getByIndex( sal_Int32 Index )
135 	throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
136 {
137 	OGuard aGuard( Application::GetSolarMutex() );
138 
139 	if( Index < 0 || Index >= maRule.GetLevelCount() )
140 		throw IndexOutOfBoundsException();
141 
142 	return Any( getNumberingRuleByIndex(Index) );
143 }
144 
145 //XElementAccess
146 Type SAL_CALL SvxUnoNumberingRules::getElementType()
147 	throw( RuntimeException )
148 {
149 	return ::getCppuType(( const Sequence< beans::PropertyValue >*)0);
150 }
151 
152 sal_Bool SAL_CALL SvxUnoNumberingRules::hasElements() throw( RuntimeException )
153 {
154 	return sal_True;
155 }
156 
157 // XAnyCompare
158 sal_Int16 SAL_CALL SvxUnoNumberingRules::compare( const Any& rAny1, const Any& rAny2 ) throw(RuntimeException)
159 {
160     return SvxUnoNumberingRules::Compare( rAny1, rAny2 );
161 }
162 
163 // XCloneable
164 Reference< XCloneable > SAL_CALL SvxUnoNumberingRules::createClone(  ) throw (RuntimeException)
165 {
166     return new SvxUnoNumberingRules(maRule);
167 }
168 
169 // XServiceInfo
170 sal_Char pSvxUnoNumberingRulesService[sizeof("com.sun.star.text.NumberingRules")] = "com.sun.star.text.NumberingRules";
171 
172 OUString SAL_CALL SvxUnoNumberingRules::getImplementationName(  ) throw(RuntimeException)
173 {
174 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "SvxUnoNumberingRules" ) );
175 }
176 
177 sal_Bool SAL_CALL SvxUnoNumberingRules::supportsService( const OUString& ServiceName ) throw(RuntimeException)
178 {
179 	return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( pSvxUnoNumberingRulesService ) );
180 }
181 
182 Sequence< OUString > SAL_CALL SvxUnoNumberingRules::getSupportedServiceNames(  ) throw(RuntimeException)
183 {
184 	OUString aService( RTL_CONSTASCII_USTRINGPARAM( pSvxUnoNumberingRulesService ) );
185 	Sequence< OUString > aSeq( &aService, 1 );
186 	return aSeq;
187 }
188 
189 Sequence<beans::PropertyValue> SvxUnoNumberingRules::getNumberingRuleByIndex( sal_Int32 nIndex) const throw()
190 {
191 	//	NumberingRule aRule;
192 	const SvxNumberFormat& rFmt = maRule.GetLevel((sal_uInt16) nIndex);
193 	sal_uInt16 nIdx = 0;
194 
195 	const int nProps = 15;
196 	beans::PropertyValue* pArray = new beans::PropertyValue[nProps];
197 
198 	Any aVal;
199 	{
200 		aVal <<= rFmt.GetNumberingType();
201 		beans::PropertyValue aAlignProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_NUMBERINGTYPE)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
202 		pArray[nIdx++] = aAlignProp;
203 	}
204 
205 	{
206 		SvxAdjust eAdj = rFmt.GetNumAdjust();
207 		aVal <<= ConvertUnoAdjust(eAdj);
208 		pArray[nIdx++] = beans::PropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_ADJUST)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
209 	}
210 
211 	{
212 		aVal <<= OUString(rFmt.GetPrefix());
213 		beans::PropertyValue aPrefixProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_PREFIX)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
214 		pArray[nIdx++] = aPrefixProp;
215 	}
216 
217 	{
218 		aVal <<= OUString(rFmt.GetSuffix());
219 		beans::PropertyValue aSuffixProp( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_SUFFIX)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
220 		pArray[nIdx++] = aSuffixProp;
221 	}
222 
223 	{
224 		sal_Unicode nCode = rFmt.GetBulletChar();
225 		OUString aStr( &nCode, 1 );
226 		aVal <<= aStr;
227 		beans::PropertyValue aBulletProp( OUString(RTL_CONSTASCII_USTRINGPARAM("BulletChar")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
228 		pArray[nIdx++] = aBulletProp;
229 	}
230 
231 	if( rFmt.GetBulletFont() )
232 	{
233 		awt::FontDescriptor aDesc;
234 		SvxUnoFontDescriptor::ConvertFromFont( *rFmt.GetBulletFont(), aDesc );
235 		aVal.setValue(&aDesc, ::getCppuType((const awt::FontDescriptor*)0));
236 		pArray[nIdx++] = beans::PropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_FONT)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
237 	}
238 
239 	{
240 		const SvxBrushItem* pBrush = rFmt.GetBrush();
241 		if(pBrush && pBrush->GetGraphicObject())
242 		{
243 			const GraphicObject* pGrafObj = pBrush->GetGraphicObject();
244 			OUString aURL( RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX));
245 			aURL += OUString::createFromAscii( pGrafObj->GetUniqueID().GetBuffer() );
246 
247 			aVal <<= aURL;
248 			const beans::PropertyValue aGraphicProp( OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicURL")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
249 			pArray[nIdx++] = aGraphicProp;
250 		}
251 	}
252 
253 	{
254 		const Size aSize( rFmt.GetGraphicSize() );
255 		const awt::Size aUnoSize( aSize.Width(), aSize.Height() );
256 		aVal <<= aUnoSize;
257 		const beans::PropertyValue aGraphicSizeProp(OUString(RTL_CONSTASCII_USTRINGPARAM("GraphicSize")), -1, aVal, beans::PropertyState_DIRECT_VALUE );
258 		pArray[nIdx++] = aGraphicSizeProp;
259 	}
260 
261 	aVal <<= (sal_Int16)rFmt.GetStart();
262 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_START_WITH)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
263 
264 	aVal <<= (sal_Int32)rFmt.GetAbsLSpace();
265 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_LEFT_MARGIN)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
266 
267 	aVal <<= (sal_Int32)rFmt.GetFirstLineOffset();
268 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_FIRST_LINE_OFFSET)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
269 
270 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("SymbolTextDistance")), -1, aVal, beans::PropertyState_DIRECT_VALUE);
271 
272 	aVal <<= (sal_Int32)rFmt.GetBulletColor().GetColor();
273 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_COLOR)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
274 
275 	aVal <<= (sal_Int16)rFmt.GetBulletRelSize();
276 	pArray[nIdx++] = beans::PropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(UNO_NAME_NRULE_BULLET_RELSIZE)), -1, aVal, beans::PropertyState_DIRECT_VALUE);
277 
278 	DBG_ASSERT( nIdx <= nProps, "FixMe: Array uebergelaufen!!!! [CL]" );
279 	Sequence< beans::PropertyValue> aSeq(pArray, nIdx);
280 
281 	delete [] pArray;
282 	return aSeq;
283 }
284 
285 void SvxUnoNumberingRules::setNumberingRuleByIndex(	const Sequence< beans::PropertyValue >& rProperties, sal_Int32 nIndex)
286 	throw( RuntimeException, IllegalArgumentException )
287 {
288 	SvxNumberFormat aFmt(maRule.GetLevel( (sal_uInt16)nIndex ));
289 	const beans::PropertyValue* pPropArray = rProperties.getConstArray();
290 	for(int i = 0; i < rProperties.getLength(); i++)
291 	{
292 		const beans::PropertyValue& rProp = pPropArray[i];
293 		const OUString& rPropName = rProp.Name;
294 		const Any& aVal = rProp.Value;
295 
296 		if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_NUMBERINGTYPE)))
297 		{
298 			sal_Int16 nSet = sal_Int16();
299 			aVal >>= nSet;
300 
301 			// There is no reason to limit numbering types.
302 			if ( nSet>=0 )
303 			{
304 				aFmt.SetNumberingType(nSet);
305 				continue;
306 			}
307 		}
308 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_PREFIX)))
309 		{
310 			OUString aPrefix;
311 			if( aVal >>= aPrefix )
312 			{
313 				aFmt.SetPrefix(aPrefix);
314 				continue;
315 			}
316 		}
317 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_SUFFIX)))
318 		{
319 			OUString aSuffix;
320 			if( aVal >>= aSuffix )
321 			{
322 				aFmt.SetSuffix(aSuffix);
323 				continue;
324 			}
325 		}
326 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLETID)))
327 		{
328 			sal_Int16 nSet = sal_Int16();
329 			if( aVal >>= nSet )
330 			{
331 				if(nSet < 0x100)
332 				{
333 					aFmt.SetBulletChar(nSet);
334 					continue;
335 				}
336 			}
337 		}
338 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("BulletChar")))
339 		{
340 			OUString aStr;
341 			if( aVal >>= aStr )
342 			{
343 				if(aStr.getLength())
344 				{
345 					aFmt.SetBulletChar(aStr[0]);
346 				}
347 				else
348 				{
349 					aFmt.SetBulletChar(0);
350 				}
351 				continue;
352 			}
353 		}
354 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_ADJUST)))
355 		{
356 			sal_Int16 nAdjust = sal_Int16();
357 			if( aVal >>= nAdjust )
358 			{
359 				aFmt.SetNumAdjust(ConvertUnoAdjust( (unsigned short)nAdjust ));
360 				continue;
361 			}
362 		}
363 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_FONT)))
364 		{
365 			awt::FontDescriptor aDesc;
366 			if( aVal >>= aDesc )
367 			{
368 				Font aFont;
369 				SvxUnoFontDescriptor::ConvertToFont( aDesc, aFont );
370 				aFmt.SetBulletFont(&aFont);
371 				continue;
372 			}
373 		}
374 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Graphic")))
375 		{
376 			Reference< awt::XBitmap > xBmp;
377 			if( aVal >>= xBmp )
378 			{
379 				Graphic aGraf( VCLUnoHelper::GetBitmap( xBmp ) );
380                 SvxBrushItem aBrushItem(aGraf, GPOS_AREA, SID_ATTR_BRUSH);
381 				aFmt.SetGraphicBrush( &aBrushItem );
382 				continue;
383 			}
384 		}
385 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("GraphicURL")))
386 		{
387 			OUString aURL;
388 			if( aVal >>= aURL )
389 			{
390 				GraphicObject aGrafObj( GraphicObject::CreateGraphicObjectFromURL( aURL ) );
391                 SvxBrushItem aBrushItem( aGrafObj, GPOS_AREA, SID_ATTR_BRUSH );
392 				aFmt.SetGraphicBrush( &aBrushItem );
393 				continue;
394 			}
395 		}
396 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("GraphicSize")))
397 		{
398 			awt::Size aUnoSize;
399 			if( aVal >>= aUnoSize )
400 			{
401 				aFmt.SetGraphicSize( Size( aUnoSize.Width, aUnoSize.Height ) );
402 				continue;
403 			}
404 		}
405 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_START_WITH)))
406 		{
407 			sal_Int16 nStart = sal_Int16();
408 			if( aVal >>= nStart )
409 			{
410 				aFmt.SetStart( nStart );
411 				continue;
412 			}
413 		}
414 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_LEFT_MARGIN)))
415 		{
416 			sal_Int32 nMargin = 0;
417 			if( aVal >>= nMargin )
418 			{
419 				aFmt.SetAbsLSpace((sal_uInt16)nMargin);
420 				continue;
421 			}
422 		}
423 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_FIRST_LINE_OFFSET)))
424 		{
425 			sal_Int32 nMargin = 0;
426 			if( aVal >>= nMargin )
427 			{
428 				aFmt.SetFirstLineOffset((sal_uInt16)nMargin);
429 				continue;
430 			}
431 		}
432 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("SymbolTextDistance")))
433 		{
434 			sal_Int32 nTextDistance = 0;
435 			if( aVal >>= nTextDistance )
436 			{
437 				aFmt.SetCharTextDistance((sal_uInt16)nTextDistance);
438 				continue;
439 			}
440 		}
441 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_COLOR)))
442 		{
443 			sal_Int32 nColor = 0;
444 			if( aVal >>= nColor )
445 			{
446 				aFmt.SetBulletColor( (Color) nColor );
447 				continue;
448 			}
449 		}
450 		else if(rPropName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_NRULE_BULLET_RELSIZE)))
451 		{
452 			sal_Int16 nSize = sal_Int16();
453 			if( aVal >>= nSize )
454 			{
455                 // [Bug 120650] the slide content corrupt when open in Aoo
456                 if ((nSize>250)||(nSize<=0))
457                 {
458                     nSize = 100;
459                 }
460 
461 				aFmt.SetBulletRelSize( (short)nSize );
462 				continue;
463 			}
464 		}
465 		else
466 		{
467 			continue;
468 		}
469 
470 		throw IllegalArgumentException();
471 	}
472 
473 	// check that we always have a brush item for bitmap numbering
474 	if( aFmt.GetNumberingType() == SVX_NUM_BITMAP )
475 	{
476 		if( NULL == aFmt.GetBrush() )
477 		{
478 			GraphicObject aGrafObj;
479             SvxBrushItem aBrushItem( aGrafObj, GPOS_AREA, SID_ATTR_BRUSH );
480 			aFmt.SetGraphicBrush( &aBrushItem );
481 		}
482 	}
483 	maRule.SetLevel( (sal_uInt16)nIndex, aFmt );
484 }
485 
486 ///////////////////////////////////////////////////////////////////////
487 
488 const SvxNumRule& SvxGetNumRule( Reference< XIndexReplace > xRule ) throw( IllegalArgumentException )
489 {
490 	SvxUnoNumberingRules* pRule = SvxUnoNumberingRules::getImplementation( xRule );
491 	if( pRule == NULL )
492 		throw IllegalArgumentException();
493 
494 	return pRule->getNumRule();
495 }
496 
497 bool SvxGetNumRule( Reference< XIndexReplace > xRule, SvxNumRule& rNumRule )
498 {
499 	SvxUnoNumberingRules* pRule = SvxUnoNumberingRules::getImplementation( xRule );
500 	if( pRule )
501 	{
502 		rNumRule = pRule->getNumRule();
503 	}
504 	else if( xRule.is() )
505 	{
506 		try
507 		{
508 			pRule = new SvxUnoNumberingRules( rNumRule );
509 
510 			Reference< XIndexReplace > xDestRule( pRule );
511 
512 			const sal_Int32 nCount = min( xRule->getCount(), xDestRule->getCount() );
513 			sal_Int32 nLevel;
514 			for( nLevel = 0; nLevel < nCount; nLevel++ )
515 			{
516 				xDestRule->replaceByIndex( nLevel, xRule->getByIndex( nLevel ) );
517 			}
518 
519 			rNumRule = pRule->getNumRule();
520 		}
521 		catch( Exception& )
522 		{
523 			return false;
524 		}
525 	}
526 	else
527 	{
528 		return false;
529 	}
530 
531 	return true;
532 }
533 
534 ///////////////////////////////////////////////////////////////////////
535 com::sun::star::uno::Reference< com::sun::star::container::XIndexReplace > SvxCreateNumRule( const SvxNumRule* pRule ) throw()
536 {
537 	DBG_ASSERT( pRule, "No default SvxNumRule!" );
538 	if( pRule )
539 	{
540 		return new SvxUnoNumberingRules( *pRule );
541 	}
542 	else
543 	{
544 		SvxNumRule aDefaultRule( NUM_BULLET_REL_SIZE|NUM_BULLET_COLOR|NUM_CHAR_TEXT_DISTANCE, 10 , sal_False);
545 		return new SvxUnoNumberingRules( aDefaultRule );
546 	}
547 }
548 
549 
550 ///////////////////////////////////////////////////////////////////////
551 
552 class SvxUnoNumberingRulesCompare : public ::cppu::WeakAggImplHelper1< XAnyCompare >
553 {
554 public:
555     virtual sal_Int16 SAL_CALL compare( const Any& Any1, const Any& Any2 ) throw(RuntimeException);
556 };
557 
558 sal_Int16 SAL_CALL SvxUnoNumberingRulesCompare::compare( const Any& Any1, const Any& Any2 ) throw(RuntimeException)
559 {
560     return SvxUnoNumberingRules::Compare( Any1, Any2 );
561 }
562 
563 sal_Int16 SvxUnoNumberingRules::Compare( const Any& Any1, const Any& Any2 )
564 {
565 	Reference< XIndexReplace > x1( Any1, UNO_QUERY ), x2( Any2, UNO_QUERY );
566 	if( x1.is() && x2.is() )
567 	{
568 		if( x1.get() == x2.get() )
569 			return 0;
570 
571 		SvxUnoNumberingRules* pRule1 = SvxUnoNumberingRules::getImplementation( x1 );
572 		if( pRule1 )
573 		{
574 			SvxUnoNumberingRules* pRule2 = SvxUnoNumberingRules::getImplementation( x2 );
575 			if( pRule2 )
576 			{
577 				const SvxNumRule& rRule1 = pRule1->getNumRule();
578 				const SvxNumRule& rRule2 = pRule2->getNumRule();
579 
580 				const sal_uInt16 nLevelCount1 = rRule1.GetLevelCount();
581 				const sal_uInt16 nLevelCount2 = rRule2.GetLevelCount();
582 
583 				if( nLevelCount1 == 0 || nLevelCount2 == 0 )
584 					return -1;
585 
586 				for( sal_uInt16 i = 0; (i < nLevelCount1) && (i < nLevelCount2); i++ )
587 				{
588 					if( rRule1.GetLevel(i) != rRule2.GetLevel(i) )
589 						return -1;
590 				}
591 				return  0;
592 			}
593 		}
594 	}
595 
596 	return -1;
597 }
598 
599 Reference< XAnyCompare > SvxCreateNumRuleCompare() throw()
600 {
601 	return new SvxUnoNumberingRulesCompare();
602 }
603 
604 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexReplace > SvxCreateNumRule() throw()
605 {
606 	SvxNumRule aTempRule( 0, 10, false );
607 	return SvxCreateNumRule( &aTempRule );
608 }
609