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