1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gluepts.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <com/sun/star/container/XIdentifierContainer.hpp>
34 #include <com/sun/star/container/XIndexContainer.hpp>
35 #ifndef _COM_SUN_STAR_DRAWING_GLUEPOINT2_HDL_
36 #include <com/sun/star/drawing/GluePoint2.hpp>
39 #include <cppuhelper/implbase2.hxx>
41 #include <svx/svdmodel.hxx>
42 #include <svx/svdobj.hxx>
43 #include <svx/svdglue.hxx>
44 #include <svx/svdpage.hxx>
46 using namespace ::com::sun::star
;
47 using namespace ::rtl
;
48 using namespace ::cppu
;
50 const USHORT NON_USER_DEFINED_GLUE_POINTS
= 4;
52 class SvxUnoGluePointAccess
: public WeakImplHelper2
< container::XIndexContainer
, container::XIdentifierContainer
>
55 SdrObjectWeakRef mpObject
;
58 SvxUnoGluePointAccess( SdrObject
* pObject
) throw();
59 virtual ~SvxUnoGluePointAccess() throw();
61 // XIdentifierContainer
62 virtual sal_Int32 SAL_CALL
insert( const uno::Any
& aElement
) throw (lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
);
63 virtual void SAL_CALL
removeByIdentifier( sal_Int32 Identifier
) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
);
66 virtual void SAL_CALL
replaceByIdentifer( sal_Int32 Identifier
, const uno::Any
& aElement
) throw (lang::IllegalArgumentException
, container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
);
69 virtual uno::Any SAL_CALL
getByIdentifier( sal_Int32 Identifier
) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
);
70 virtual uno::Sequence
< sal_Int32
> SAL_CALL
getIdentifiers( ) throw (uno::RuntimeException
);
74 virtual void SAL_CALL
insertByIndex( sal_Int32 Index
, const uno::Any
& Element
) throw(lang::IllegalArgumentException
, lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
);
75 virtual void SAL_CALL
removeByIndex( sal_Int32 Index
) throw(lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
);
79 virtual void SAL_CALL
replaceByIndex( sal_Int32 Index
, const uno::Any
& Element
) throw(lang::IllegalArgumentException
, lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
);
83 virtual sal_Int32 SAL_CALL
getCount( ) throw(uno::RuntimeException
);
84 virtual uno::Any SAL_CALL
getByIndex( sal_Int32 Index
) throw(lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
);
87 virtual uno::Type SAL_CALL
getElementType( ) throw( uno::RuntimeException
);
88 virtual sal_Bool SAL_CALL
hasElements( ) throw( uno::RuntimeException
);
91 static void convert( const SdrGluePoint
& rSdrGlue
, drawing::GluePoint2
& rUnoGlue
) throw()
93 rUnoGlue
.Position
.X
= rSdrGlue
.GetPos().X();
94 rUnoGlue
.Position
.Y
= rSdrGlue
.GetPos().Y();
95 rUnoGlue
.IsRelative
= rSdrGlue
.IsPercent();
97 switch( rSdrGlue
.GetAlign() )
99 case SDRVERTALIGN_TOP
|SDRHORZALIGN_LEFT
:
100 rUnoGlue
.PositionAlignment
= drawing::Alignment_TOP_LEFT
;
102 case SDRHORZALIGN_CENTER
|SDRVERTALIGN_TOP
:
103 rUnoGlue
.PositionAlignment
= drawing::Alignment_TOP
;
105 case SDRVERTALIGN_TOP
|SDRHORZALIGN_RIGHT
:
106 rUnoGlue
.PositionAlignment
= drawing::Alignment_TOP_RIGHT
;
108 case SDRHORZALIGN_CENTER
|SDRVERTALIGN_CENTER
:
109 rUnoGlue
.PositionAlignment
= drawing::Alignment_CENTER
;
111 case SDRHORZALIGN_RIGHT
|SDRVERTALIGN_CENTER
:
112 rUnoGlue
.PositionAlignment
= drawing::Alignment_RIGHT
;
114 case SDRHORZALIGN_LEFT
|SDRVERTALIGN_BOTTOM
:
115 rUnoGlue
.PositionAlignment
= drawing::Alignment_BOTTOM_LEFT
;
117 case SDRHORZALIGN_CENTER
|SDRVERTALIGN_BOTTOM
:
118 rUnoGlue
.PositionAlignment
= drawing::Alignment_BOTTOM
;
120 case SDRHORZALIGN_RIGHT
|SDRVERTALIGN_BOTTOM
:
121 rUnoGlue
.PositionAlignment
= drawing::Alignment_BOTTOM_RIGHT
;
123 // case SDRHORZALIGN_LEFT:
125 rUnoGlue
.PositionAlignment
= drawing::Alignment_LEFT
;
129 switch( rSdrGlue
.GetEscDir() )
132 rUnoGlue
.Escape
= drawing::EscapeDirection_LEFT
;
135 rUnoGlue
.Escape
= drawing::EscapeDirection_RIGHT
;
138 rUnoGlue
.Escape
= drawing::EscapeDirection_UP
;
141 rUnoGlue
.Escape
= drawing::EscapeDirection_DOWN
;
144 rUnoGlue
.Escape
= drawing::EscapeDirection_HORIZONTAL
;
147 rUnoGlue
.Escape
= drawing::EscapeDirection_VERTICAL
;
149 // case SDRESC_SMART:
151 rUnoGlue
.Escape
= drawing::EscapeDirection_SMART
;
156 static void convert( const drawing::GluePoint2
& rUnoGlue
, SdrGluePoint
& rSdrGlue
) throw()
158 rSdrGlue
.SetPos( Point( rUnoGlue
.Position
.X
, rUnoGlue
.Position
.Y
) );
159 rSdrGlue
.SetPercent( rUnoGlue
.IsRelative
);
161 switch( rUnoGlue
.PositionAlignment
)
163 case drawing::Alignment_TOP_LEFT
:
164 rSdrGlue
.SetAlign( SDRVERTALIGN_TOP
|SDRHORZALIGN_LEFT
);
166 case drawing::Alignment_TOP
:
167 rSdrGlue
.SetAlign( SDRHORZALIGN_CENTER
|SDRVERTALIGN_TOP
);
169 case drawing::Alignment_TOP_RIGHT
:
170 rSdrGlue
.SetAlign( SDRVERTALIGN_TOP
|SDRHORZALIGN_RIGHT
);
172 case drawing::Alignment_CENTER
:
173 rSdrGlue
.SetAlign( SDRHORZALIGN_CENTER
|SDRVERTALIGN_CENTER
);
175 case drawing::Alignment_RIGHT
:
176 rSdrGlue
.SetAlign( SDRHORZALIGN_RIGHT
|SDRVERTALIGN_CENTER
);
178 case drawing::Alignment_BOTTOM_LEFT
:
179 rSdrGlue
.SetAlign( SDRHORZALIGN_LEFT
|SDRVERTALIGN_BOTTOM
);
181 case drawing::Alignment_BOTTOM
:
182 rSdrGlue
.SetAlign( SDRHORZALIGN_CENTER
|SDRVERTALIGN_BOTTOM
);
184 case drawing::Alignment_BOTTOM_RIGHT
:
185 rSdrGlue
.SetAlign( SDRHORZALIGN_RIGHT
|SDRVERTALIGN_BOTTOM
);
187 // case SDRHORZALIGN_LEFT:
189 rSdrGlue
.SetAlign( SDRHORZALIGN_LEFT
);
192 switch( rUnoGlue
.Escape
)
194 case drawing::EscapeDirection_LEFT
:
195 rSdrGlue
.SetEscDir(SDRESC_LEFT
);
197 case drawing::EscapeDirection_RIGHT
:
198 rSdrGlue
.SetEscDir(SDRESC_RIGHT
);
200 case drawing::EscapeDirection_UP
:
201 rSdrGlue
.SetEscDir(SDRESC_TOP
);
203 case drawing::EscapeDirection_DOWN
:
204 rSdrGlue
.SetEscDir(SDRESC_BOTTOM
);
206 case drawing::EscapeDirection_HORIZONTAL
:
207 rSdrGlue
.SetEscDir(SDRESC_HORZ
);
209 case drawing::EscapeDirection_VERTICAL
:
210 rSdrGlue
.SetEscDir(SDRESC_VERT
);
212 // case drawing::EscapeDirection_SMART:
214 rSdrGlue
.SetEscDir(SDRESC_SMART
);
219 SvxUnoGluePointAccess::SvxUnoGluePointAccess( SdrObject
* pObject
) throw()
220 : mpObject( pObject
)
224 SvxUnoGluePointAccess::~SvxUnoGluePointAccess() throw()
228 // XIdentifierContainer
229 sal_Int32 SAL_CALL
SvxUnoGluePointAccess::insert( const uno::Any
& aElement
) throw (lang::IllegalArgumentException
, lang::WrappedTargetException
, uno::RuntimeException
)
233 SdrGluePointList
* pList
= mpObject
->ForceGluePointList();
236 // second, insert the new glue point
237 drawing::GluePoint2 aUnoGlue
;
239 if( aElement
>>= aUnoGlue
)
241 SdrGluePoint aSdrGlue
;
242 convert( aUnoGlue
, aSdrGlue
);
243 USHORT nId
= pList
->Insert( aSdrGlue
);
245 // only repaint, no objectchange
246 mpObject
->ActionChanged();
247 // mpObject->BroadcastObjectChange();
249 return (sal_Int32
)((*pList
)[nId
].GetId() + NON_USER_DEFINED_GLUE_POINTS
) - 1;
252 throw lang::IllegalArgumentException();
259 void SAL_CALL
SvxUnoGluePointAccess::removeByIdentifier( sal_Int32 Identifier
) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
261 if( mpObject
.is() && ( Identifier
>= NON_USER_DEFINED_GLUE_POINTS
))
263 const USHORT nId
= (USHORT
)(Identifier
- NON_USER_DEFINED_GLUE_POINTS
) + 1;
265 SdrGluePointList
* pList
= const_cast<SdrGluePointList
*>(mpObject
->GetGluePointList());
266 const USHORT nCount
= pList
? pList
->GetCount() : 0;
269 for( i
= 0; i
< nCount
; i
++ )
271 if( (*pList
)[i
].GetId() == nId
)
275 // only repaint, no objectchange
276 mpObject
->ActionChanged();
277 // mpObject->BroadcastObjectChange();
284 throw container::NoSuchElementException();
287 // XIdentifierReplace
288 void SAL_CALL
SvxUnoGluePointAccess::replaceByIdentifer( sal_Int32 Identifier
, const uno::Any
& aElement
) throw (lang::IllegalArgumentException
, container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
290 if( mpObject
.is() && mpObject
->IsNode() )
292 struct drawing::GluePoint2 aGluePoint
;
293 if( (Identifier
< NON_USER_DEFINED_GLUE_POINTS
) || !(aElement
>>= aGluePoint
))
294 throw lang::IllegalArgumentException();
296 const USHORT nId
= (USHORT
)( Identifier
- NON_USER_DEFINED_GLUE_POINTS
) + 1;
298 SdrGluePointList
* pList
= const_cast< SdrGluePointList
* >( mpObject
->GetGluePointList() );
299 const USHORT nCount
= pList
? pList
->GetCount() : 0;
301 for( i
= 0; i
< nCount
; i
++ )
303 if( (*pList
)[i
].GetId() == nId
)
305 // change the glue point
306 SdrGluePoint
& rTempPoint
= (*pList
)[i
];
307 convert( aGluePoint
, rTempPoint
);
309 // only repaint, no objectchange
310 mpObject
->ActionChanged();
311 // mpObject->BroadcastObjectChange();
317 throw container::NoSuchElementException();
322 uno::Any SAL_CALL
SvxUnoGluePointAccess::getByIdentifier( sal_Int32 Identifier
) throw (container::NoSuchElementException
, lang::WrappedTargetException
, uno::RuntimeException
)
324 if( mpObject
.is() && mpObject
->IsNode() )
326 struct drawing::GluePoint2 aGluePoint
;
328 if( Identifier
< NON_USER_DEFINED_GLUE_POINTS
) // default glue point?
330 SdrGluePoint aTempPoint
= mpObject
->GetVertexGluePoint( (USHORT
)Identifier
);
331 aGluePoint
.IsUserDefined
= sal_False
;
332 convert( aTempPoint
, aGluePoint
);
333 return uno::makeAny( aGluePoint
);
337 const USHORT nId
= (USHORT
)( Identifier
- NON_USER_DEFINED_GLUE_POINTS
) + 1;
339 const SdrGluePointList
* pList
= mpObject
->GetGluePointList();
340 const USHORT nCount
= pList
? pList
->GetCount() : 0;
341 for( USHORT i
= 0; i
< nCount
; i
++ )
343 const SdrGluePoint
& rTempPoint
= (*pList
)[i
];
344 if( rTempPoint
.GetId() == nId
)
347 if(rTempPoint
.IsUserDefined())
349 aGluePoint
.IsUserDefined
= sal_True
;
352 convert( rTempPoint
, aGluePoint
);
353 return uno::makeAny( aGluePoint
);
359 throw lang::IndexOutOfBoundsException();
362 uno::Sequence
< sal_Int32
> SAL_CALL
SvxUnoGluePointAccess::getIdentifiers() throw (uno::RuntimeException
)
366 const SdrGluePointList
* pList
= mpObject
->GetGluePointList();
367 const USHORT nCount
= pList
? pList
->GetCount() : 0;
371 uno::Sequence
< sal_Int32
> aIdSequence( nCount
+ NON_USER_DEFINED_GLUE_POINTS
);
372 sal_Int32
*pIdentifier
= aIdSequence
.getArray();
374 for( i
= 0; i
< NON_USER_DEFINED_GLUE_POINTS
; i
++ )
375 *pIdentifier
++ = (sal_Int32
)i
;
377 for( i
= 0; i
< nCount
; i
++ )
378 *pIdentifier
++ = (sal_Int32
) ( (*pList
)[i
].GetId() + NON_USER_DEFINED_GLUE_POINTS
) - 1;
384 uno::Sequence
< sal_Int32
> aEmpty
;
392 void SAL_CALL
SvxUnoGluePointAccess::insertByIndex( sal_Int32
, const uno::Any
& Element
)
393 throw(lang::IllegalArgumentException
, lang::IndexOutOfBoundsException
,
394 lang::WrappedTargetException
, uno::RuntimeException
)
398 SdrGluePointList
* pList
= mpObject
->ForceGluePointList();
401 SdrGluePoint aSdrGlue
;
402 drawing::GluePoint2 aUnoGlue
;
404 if( Element
>>= aUnoGlue
)
406 convert( aUnoGlue
, aSdrGlue
);
407 pList
->Insert( aSdrGlue
);
409 // only repaint, no objectchange
410 mpObject
->ActionChanged();
411 // mpObject->BroadcastObjectChange();
416 throw lang::IllegalArgumentException();
420 throw lang::IndexOutOfBoundsException();
423 void SAL_CALL
SvxUnoGluePointAccess::removeByIndex( sal_Int32 Index
)
424 throw(lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
)
428 SdrGluePointList
* pList
= mpObject
->ForceGluePointList();
432 if( Index
>= 0 && Index
< pList
->GetCount() )
434 pList
->Delete( (USHORT
)Index
);
436 // only repaint, no objectchange
437 mpObject
->ActionChanged();
438 // mpObject->BroadcastObjectChange();
445 throw lang::IndexOutOfBoundsException();
449 void SAL_CALL
SvxUnoGluePointAccess::replaceByIndex( sal_Int32 Index
, const uno::Any
& Element
)
450 throw(lang::IllegalArgumentException
, lang::IndexOutOfBoundsException
, lang::WrappedTargetException
,
451 uno::RuntimeException
)
453 drawing::GluePoint2 aUnoGlue
;
454 if(!(Element
>>= aUnoGlue
))
455 throw lang::IllegalArgumentException();
458 if( mpObject
.is() && Index
>= 0 )
460 SdrGluePointList
* pList
= const_cast< SdrGluePointList
* >( mpObject
->GetGluePointList() );
461 if( pList
&& Index
< pList
->GetCount() )
463 SdrGluePoint
& rGlue
= (*pList
)[(USHORT
)Index
];
464 convert( aUnoGlue
, rGlue
);
466 // only repaint, no objectchange
467 mpObject
->ActionChanged();
468 // mpObject->BroadcastObjectChange();
472 throw lang::IndexOutOfBoundsException();
476 sal_Int32 SAL_CALL
SvxUnoGluePointAccess::getCount()
477 throw(uno::RuntimeException
)
479 sal_Int32 nCount
= 0;
482 // each node has a default of 4 glue points
483 // and any number of user defined glue points
484 if( mpObject
->IsNode() )
488 const SdrGluePointList
* pList
= mpObject
->GetGluePointList();
490 nCount
+= pList
->GetCount();
497 uno::Any SAL_CALL
SvxUnoGluePointAccess::getByIndex( sal_Int32 Index
)
498 throw(lang::IndexOutOfBoundsException
, lang::WrappedTargetException
, uno::RuntimeException
)
500 if( Index
>= 0 && mpObject
.is() && mpObject
->IsNode() )
502 struct drawing::GluePoint2 aGluePoint
;
504 if( Index
< 4 ) // default glue point?
506 SdrGluePoint aTempPoint
= mpObject
->GetVertexGluePoint( (USHORT
)Index
);
507 aGluePoint
.IsUserDefined
= sal_False
;
508 convert( aTempPoint
, aGluePoint
);
516 const SdrGluePointList
* pList
= mpObject
->GetGluePointList();
517 if( pList
&& Index
< pList
->GetCount() )
519 const SdrGluePoint
& rTempPoint
= (*pList
)[(USHORT
)Index
];
520 aGluePoint
.IsUserDefined
= sal_True
;
521 convert( rTempPoint
, aGluePoint
);
529 throw lang::IndexOutOfBoundsException();
533 uno::Type SAL_CALL
SvxUnoGluePointAccess::getElementType()
534 throw( uno::RuntimeException
)
536 return ::getCppuType((const struct drawing::GluePoint2
*)0);
539 sal_Bool SAL_CALL
SvxUnoGluePointAccess::hasElements()
540 throw( uno::RuntimeException
)
542 return mpObject
.is() && mpObject
->IsNode();
546 * Create a SvxUnoGluePointAccess
548 uno::Reference
< uno::XInterface
> SAL_CALL
SvxUnoGluePointAccess_createInstance( SdrObject
* pObject
)
550 return *new SvxUnoGluePointAccess(pObject
);