xref: /AOO41X/main/svx/source/unodraw/gluepts.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
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