xref: /aoo41x/main/svx/source/unodraw/gluepts.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_svx.hxx"
30 #include <com/sun/star/container/XIdentifierContainer.hpp>
31 #include <com/sun/star/container/XIndexContainer.hpp>
32 #ifndef _COM_SUN_STAR_DRAWING_GLUEPOINT2_HDL_
33 #include <com/sun/star/drawing/GluePoint2.hpp>
34 #endif
35 
36 #include <cppuhelper/implbase2.hxx>
37 
38 #include <svx/svdmodel.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/svdglue.hxx>
41 #include <svx/svdpage.hxx>
42 
43 using namespace ::com::sun::star;
44 using namespace ::rtl;
45 using namespace ::cppu;
46 
47 const sal_uInt16 NON_USER_DEFINED_GLUE_POINTS = 4;
48 
49 class SvxUnoGluePointAccess : public WeakImplHelper2< container::XIndexContainer, container::XIdentifierContainer >
50 {
51 private:
52 	SdrObjectWeakRef    mpObject;
53 
54 public:
55 	SvxUnoGluePointAccess( SdrObject* pObject ) throw();
56 	virtual	~SvxUnoGluePointAccess() throw();
57 
58 	// XIdentifierContainer
59     virtual sal_Int32 SAL_CALL insert( const uno::Any& aElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException);
60     virtual void SAL_CALL removeByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
61 
62 	// XIdentifierReplace
63     virtual void SAL_CALL replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
64 
65 	// XIdentifierReplace
66     virtual uno::Any SAL_CALL getByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException);
67     virtual uno::Sequence< sal_Int32 > SAL_CALL getIdentifiers(  ) throw (uno::RuntimeException);
68 
69 	/* deprecated */
70 	// XIndexContainer
71     virtual void SAL_CALL insertByIndex( sal_Int32 Index, const uno::Any& Element ) throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
72     virtual void SAL_CALL removeByIndex( sal_Int32 Index ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
73 
74 	/* deprecated */
75 	// XIndexReplace
76     virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const uno::Any& Element ) throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
77 
78 	/* deprecated */
79 	// XIndexAccess
80     virtual sal_Int32 SAL_CALL getCount(  ) throw(uno::RuntimeException);
81     virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException);
82 
83 	// XElementAccess
84     virtual uno::Type SAL_CALL getElementType(  ) throw( uno::RuntimeException);
85     virtual sal_Bool SAL_CALL hasElements(  ) throw( uno::RuntimeException);
86 };
87 
88 static void convert( const SdrGluePoint& rSdrGlue, drawing::GluePoint2& rUnoGlue ) throw()
89 {
90 	rUnoGlue.Position.X = rSdrGlue.GetPos().X();
91 	rUnoGlue.Position.Y = rSdrGlue.GetPos().Y();
92 	rUnoGlue.IsRelative = rSdrGlue.IsPercent();
93 
94 	switch( rSdrGlue.GetAlign() )
95 	{
96 	case SDRVERTALIGN_TOP|SDRHORZALIGN_LEFT:
97 		rUnoGlue.PositionAlignment = drawing::Alignment_TOP_LEFT;
98 		break;
99 	case SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP:
100 		rUnoGlue.PositionAlignment = drawing::Alignment_TOP;
101 		break;
102 	case SDRVERTALIGN_TOP|SDRHORZALIGN_RIGHT:
103 		rUnoGlue.PositionAlignment = drawing::Alignment_TOP_RIGHT;
104 		break;
105 	case SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER:
106 		rUnoGlue.PositionAlignment = drawing::Alignment_CENTER;
107 		break;
108 	case SDRHORZALIGN_RIGHT|SDRVERTALIGN_CENTER:
109 		rUnoGlue.PositionAlignment = drawing::Alignment_RIGHT;
110 		break;
111 	case SDRHORZALIGN_LEFT|SDRVERTALIGN_BOTTOM:
112 		rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_LEFT;
113 		break;
114 	case SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM:
115 		rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM;
116 		break;
117 	case SDRHORZALIGN_RIGHT|SDRVERTALIGN_BOTTOM:
118 		rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_RIGHT;
119 		break;
120 //	case SDRHORZALIGN_LEFT:
121 	default:
122 		rUnoGlue.PositionAlignment = drawing::Alignment_LEFT;
123 		break;
124 	}
125 
126 	switch( rSdrGlue.GetEscDir() )
127 	{
128 	case SDRESC_LEFT:
129 		rUnoGlue.Escape = drawing::EscapeDirection_LEFT;
130 		break;
131 	case SDRESC_RIGHT:
132 		rUnoGlue.Escape = drawing::EscapeDirection_RIGHT;
133 		break;
134 	case SDRESC_TOP:
135 		rUnoGlue.Escape = drawing::EscapeDirection_UP;
136 		break;
137 	case SDRESC_BOTTOM:
138 		rUnoGlue.Escape = drawing::EscapeDirection_DOWN;
139 		break;
140 	case SDRESC_HORZ:
141 		rUnoGlue.Escape = drawing::EscapeDirection_HORIZONTAL;
142 		break;
143 	case SDRESC_VERT:
144 		rUnoGlue.Escape = drawing::EscapeDirection_VERTICAL;
145 		break;
146 //			case SDRESC_SMART:
147 	default:
148 		rUnoGlue.Escape = drawing::EscapeDirection_SMART;
149 		break;
150 	}
151 }
152 
153 static void convert( const drawing::GluePoint2& rUnoGlue, SdrGluePoint& rSdrGlue ) throw()
154 {
155 	rSdrGlue.SetPos( Point( rUnoGlue.Position.X, rUnoGlue.Position.Y ) );
156 	rSdrGlue.SetPercent( rUnoGlue.IsRelative );
157 
158 	switch( rUnoGlue.PositionAlignment )
159 	{
160 	case drawing::Alignment_TOP_LEFT:
161 		rSdrGlue.SetAlign( SDRVERTALIGN_TOP|SDRHORZALIGN_LEFT );
162 		break;
163 	case drawing::Alignment_TOP:
164 		rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_TOP );
165 		break;
166 	case drawing::Alignment_TOP_RIGHT:
167 		rSdrGlue.SetAlign( SDRVERTALIGN_TOP|SDRHORZALIGN_RIGHT );
168 		break;
169 	case drawing::Alignment_CENTER:
170 		rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_CENTER );
171 		break;
172 	case drawing::Alignment_RIGHT:
173 		rSdrGlue.SetAlign( SDRHORZALIGN_RIGHT|SDRVERTALIGN_CENTER );
174 		break;
175 	case drawing::Alignment_BOTTOM_LEFT:
176 		rSdrGlue.SetAlign( SDRHORZALIGN_LEFT|SDRVERTALIGN_BOTTOM );
177 		break;
178 	case drawing::Alignment_BOTTOM:
179 		rSdrGlue.SetAlign( SDRHORZALIGN_CENTER|SDRVERTALIGN_BOTTOM );
180 		break;
181 	case drawing::Alignment_BOTTOM_RIGHT:
182 		rSdrGlue.SetAlign( SDRHORZALIGN_RIGHT|SDRVERTALIGN_BOTTOM );
183 		break;
184 //	case SDRHORZALIGN_LEFT:
185 	default:
186 		rSdrGlue.SetAlign( SDRHORZALIGN_LEFT );
187 		break;
188 	}
189 	switch( rUnoGlue.Escape )
190 	{
191 	case drawing::EscapeDirection_LEFT:
192 		rSdrGlue.SetEscDir(SDRESC_LEFT);
193 		break;
194 	case drawing::EscapeDirection_RIGHT:
195 		rSdrGlue.SetEscDir(SDRESC_RIGHT);
196 		break;
197 	case drawing::EscapeDirection_UP:
198 		rSdrGlue.SetEscDir(SDRESC_TOP);
199 		break;
200 	case drawing::EscapeDirection_DOWN:
201 		rSdrGlue.SetEscDir(SDRESC_BOTTOM);
202 		break;
203 	case drawing::EscapeDirection_HORIZONTAL:
204 		rSdrGlue.SetEscDir(SDRESC_HORZ);
205 		break;
206 	case drawing::EscapeDirection_VERTICAL:
207 		rSdrGlue.SetEscDir(SDRESC_VERT);
208 		break;
209 //	case drawing::EscapeDirection_SMART:
210 	default:
211 		rSdrGlue.SetEscDir(SDRESC_SMART);
212 		break;
213 	}
214 }
215 
216 SvxUnoGluePointAccess::SvxUnoGluePointAccess( SdrObject* pObject ) throw()
217 : mpObject( pObject )
218 {
219 }
220 
221 SvxUnoGluePointAccess::~SvxUnoGluePointAccess() throw()
222 {
223 }
224 
225 // XIdentifierContainer
226 sal_Int32 SAL_CALL SvxUnoGluePointAccess::insert( const uno::Any& aElement ) throw (lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
227 {
228 	if( mpObject.is() )
229 	{
230 		SdrGluePointList* pList = mpObject->ForceGluePointList();
231 		if( pList )
232 		{
233 			// second, insert the new glue point
234 			drawing::GluePoint2 aUnoGlue;
235 
236 			if( aElement >>= aUnoGlue )
237 			{
238 				SdrGluePoint aSdrGlue;
239 				convert( aUnoGlue, aSdrGlue );
240 				sal_uInt16 nId = pList->Insert( aSdrGlue );
241 
242 				// only repaint, no objectchange
243 				mpObject->ActionChanged();
244 				// mpObject->BroadcastObjectChange();
245 
246 				return (sal_Int32)((*pList)[nId].GetId() + NON_USER_DEFINED_GLUE_POINTS) - 1;
247 			}
248 
249 			throw lang::IllegalArgumentException();
250 		}
251 	}
252 
253 	return -1;
254 }
255 
256 void SAL_CALL SvxUnoGluePointAccess::removeByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
257 {
258 	if( mpObject.is() && ( Identifier >= NON_USER_DEFINED_GLUE_POINTS ))
259 	{
260 		const sal_uInt16 nId = (sal_uInt16)(Identifier - NON_USER_DEFINED_GLUE_POINTS) + 1;
261 
262 		SdrGluePointList* pList = const_cast<SdrGluePointList*>(mpObject->GetGluePointList());
263 		const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
264 		sal_uInt16 i;
265 
266 		for( i = 0; i < nCount; i++ )
267 		{
268 			if( (*pList)[i].GetId() == nId )
269 			{
270 				pList->Delete( i );
271 
272 				// only repaint, no objectchange
273 				mpObject->ActionChanged();
274 				// mpObject->BroadcastObjectChange();
275 
276 				return;
277 			}
278 		}
279 	}
280 
281 	throw container::NoSuchElementException();
282 }
283 
284 // XIdentifierReplace
285 void SAL_CALL SvxUnoGluePointAccess::replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement ) throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
286 {
287 	if( mpObject.is() && mpObject->IsNode() )
288 	{
289 		struct drawing::GluePoint2 aGluePoint;
290 		if( (Identifier < NON_USER_DEFINED_GLUE_POINTS) || !(aElement >>= aGluePoint))
291 			throw lang::IllegalArgumentException();
292 
293 		const sal_uInt16 nId = (sal_uInt16)( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1;
294 
295 		SdrGluePointList* pList = const_cast< SdrGluePointList* >( mpObject->GetGluePointList() );
296 		const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
297 		sal_uInt16 i;
298 		for( i = 0; i < nCount; i++ )
299 		{
300 			if( (*pList)[i].GetId() == nId )
301 			{
302 				// change the glue point
303 				SdrGluePoint& rTempPoint = (*pList)[i];
304 				convert( aGluePoint, rTempPoint );
305 
306 				// only repaint, no objectchange
307 				mpObject->ActionChanged();
308 				// mpObject->BroadcastObjectChange();
309 
310 				return;
311 			}
312 		}
313 
314 		throw container::NoSuchElementException();
315 	}
316 }
317 
318 // XIdentifierAccess
319 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIdentifier( sal_Int32 Identifier ) throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException)
320 {
321 	if( mpObject.is() && mpObject->IsNode() )
322 	{
323 		struct drawing::GluePoint2 aGluePoint;
324 
325 		if( Identifier < NON_USER_DEFINED_GLUE_POINTS ) // default glue point?
326 		{
327 			SdrGluePoint aTempPoint = mpObject->GetVertexGluePoint( (sal_uInt16)Identifier );
328 			aGluePoint.IsUserDefined = sal_False;
329 			convert( aTempPoint, aGluePoint );
330 			return uno::makeAny( aGluePoint );
331 		}
332 		else
333 		{
334 			const sal_uInt16 nId = (sal_uInt16)( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1;
335 
336 			const SdrGluePointList* pList = mpObject->GetGluePointList();
337 			const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
338 			for( sal_uInt16 i = 0; i < nCount; i++ )
339 			{
340 				const SdrGluePoint& rTempPoint = (*pList)[i];
341 				if( rTempPoint.GetId() == nId )
342 				{
343 					// #i38892#
344 					if(rTempPoint.IsUserDefined())
345 					{
346 						aGluePoint.IsUserDefined = sal_True;
347 					}
348 
349 					convert( rTempPoint, aGluePoint );
350 					return uno::makeAny( aGluePoint );
351 				}
352 			}
353 		}
354 	}
355 
356 	throw lang::IndexOutOfBoundsException();
357 }
358 
359 uno::Sequence< sal_Int32 > SAL_CALL SvxUnoGluePointAccess::getIdentifiers() throw (uno::RuntimeException)
360 {
361     if( mpObject.is() )
362     {
363 	    const SdrGluePointList* pList = mpObject->GetGluePointList();
364 	    const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
365 
366 	    sal_uInt16 i;
367 
368 	    uno::Sequence< sal_Int32 > aIdSequence( nCount + NON_USER_DEFINED_GLUE_POINTS );
369 	    sal_Int32 *pIdentifier = aIdSequence.getArray();
370 
371 	    for( i = 0; i < NON_USER_DEFINED_GLUE_POINTS; i++ )
372 		    *pIdentifier++ = (sal_Int32)i;
373 
374 	    for( i = 0; i < nCount; i++ )
375 		    *pIdentifier++ = (sal_Int32) ( (*pList)[i].GetId() + NON_USER_DEFINED_GLUE_POINTS ) - 1;
376 
377 	    return aIdSequence;
378     }
379     else
380     {
381         uno::Sequence< sal_Int32 > aEmpty;
382         return aEmpty;
383     }
384 }
385 
386 /* deprecated */
387 
388 // XIndexContainer
389 void SAL_CALL SvxUnoGluePointAccess::insertByIndex( sal_Int32, const uno::Any& Element )
390 	throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException,
391 			lang::WrappedTargetException, uno::RuntimeException)
392 {
393 	if( mpObject.is() )
394 	{
395 		SdrGluePointList* pList = mpObject->ForceGluePointList();
396 		if( pList )
397 		{
398 			SdrGluePoint aSdrGlue;
399 			drawing::GluePoint2 aUnoGlue;
400 
401 			if( Element >>= aUnoGlue )
402 			{
403 				convert( aUnoGlue, aSdrGlue );
404 				pList->Insert( aSdrGlue );
405 
406 				// only repaint, no objectchange
407 				mpObject->ActionChanged();
408 				// mpObject->BroadcastObjectChange();
409 
410 				return;
411 			}
412 
413 			throw lang::IllegalArgumentException();
414 		}
415 	}
416 
417 	throw lang::IndexOutOfBoundsException();
418 }
419 
420 void SAL_CALL SvxUnoGluePointAccess::removeByIndex( sal_Int32 Index )
421 	throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
422 {
423 	if( mpObject.is() )
424 	{
425 		SdrGluePointList* pList = mpObject->ForceGluePointList();
426 		if( pList )
427 		{
428 			Index -= 4;
429 			if( Index >= 0 && Index < pList->GetCount() )
430 			{
431 				pList->Delete( (sal_uInt16)Index );
432 
433 				// only repaint, no objectchange
434 				mpObject->ActionChanged();
435 				// mpObject->BroadcastObjectChange();
436 
437 				return;
438 			}
439 		}
440 	}
441 
442 	throw lang::IndexOutOfBoundsException();
443 }
444 
445 // XIndexReplace
446 void SAL_CALL SvxUnoGluePointAccess::replaceByIndex( sal_Int32 Index, const uno::Any& Element )
447 	throw(lang::IllegalArgumentException, lang::IndexOutOfBoundsException, lang::WrappedTargetException,
448 	uno::RuntimeException)
449 {
450 	drawing::GluePoint2 aUnoGlue;
451 	if(!(Element >>= aUnoGlue))
452 		throw lang::IllegalArgumentException();
453 
454 	Index -= 4;
455 	if( mpObject.is() && Index >= 0 )
456 	{
457 		SdrGluePointList* pList = const_cast< SdrGluePointList* >( mpObject->GetGluePointList() );
458 		if( pList && Index < pList->GetCount() )
459 		{
460 			SdrGluePoint& rGlue = (*pList)[(sal_uInt16)Index];
461 			convert( aUnoGlue, rGlue );
462 
463 			// only repaint, no objectchange
464 			mpObject->ActionChanged();
465 			// mpObject->BroadcastObjectChange();
466 		}
467 	}
468 
469 	throw lang::IndexOutOfBoundsException();
470 }
471 
472 // XIndexAccess
473 sal_Int32 SAL_CALL SvxUnoGluePointAccess::getCount()
474 	throw(uno::RuntimeException)
475 {
476 	sal_Int32 nCount = 0;
477 	if( mpObject.is() )
478 	{
479 		// each node has a default of 4 glue points
480 		// and any number of user defined glue points
481 		if( mpObject->IsNode() )
482 		{
483 			nCount += 4;
484 
485 			const SdrGluePointList* pList = mpObject->GetGluePointList();
486 			if( pList )
487 				nCount += pList->GetCount();
488 		}
489 	}
490 
491 	return nCount;
492 }
493 
494 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIndex( sal_Int32 Index )
495 	throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException)
496 {
497 	if( Index >= 0 && mpObject.is() && mpObject->IsNode() )
498 	{
499 		struct drawing::GluePoint2 aGluePoint;
500 
501 		if( Index < 4 ) // default glue point?
502 		{
503 			SdrGluePoint aTempPoint = mpObject->GetVertexGluePoint( (sal_uInt16)Index );
504 			aGluePoint.IsUserDefined = sal_False;
505 			convert( aTempPoint, aGluePoint );
506 			uno::Any aAny;
507 			aAny <<= aGluePoint;
508 			return aAny;
509 		}
510 		else
511 		{
512 			Index -= 4;
513 			const SdrGluePointList* pList = mpObject->GetGluePointList();
514 			if( pList && Index < pList->GetCount() )
515 			{
516 				const SdrGluePoint& rTempPoint = (*pList)[(sal_uInt16)Index];
517 				aGluePoint.IsUserDefined = sal_True;
518 				convert( rTempPoint, aGluePoint );
519 				uno::Any aAny;
520 				aAny <<= aGluePoint;
521 				return aAny;
522 			}
523 		}
524 	}
525 
526 	throw lang::IndexOutOfBoundsException();
527 }
528 
529 // XElementAccess
530 uno::Type SAL_CALL SvxUnoGluePointAccess::getElementType()
531 	throw( uno::RuntimeException)
532 {
533 	return ::getCppuType((const struct drawing::GluePoint2*)0);
534 }
535 
536 sal_Bool SAL_CALL SvxUnoGluePointAccess::hasElements()
537 	throw( uno::RuntimeException)
538 {
539 	return mpObject.is() && mpObject->IsNode();
540 }
541 
542 /**
543  * Create a SvxUnoGluePointAccess
544  */
545 uno::Reference< uno::XInterface > SAL_CALL SvxUnoGluePointAccess_createInstance( SdrObject* pObject )
546 {
547 	return *new SvxUnoGluePointAccess(pObject);
548 }
549