Bump version to 24.04.3.4
[LibreOffice.git] / svx / source / unodraw / gluepts.cxx
blob1547b9fed7f03063c2a6bb69fb402d3da42c25a2
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/container/NoSuchElementException.hpp>
21 #include <com/sun/star/container/XIdentifierContainer.hpp>
22 #include <com/sun/star/container/XIndexContainer.hpp>
23 #include <com/sun/star/drawing/GluePoint2.hpp>
24 #include <com/sun/star/lang/IllegalArgumentException.hpp>
25 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
27 #include <cppuhelper/implbase.hxx>
28 #include <tools/weakbase.hxx>
29 #include <unotools/weakref.hxx>
31 #include <svx/svdobj.hxx>
32 #include <svx/svdglue.hxx>
34 #include "gluepts.hxx"
36 using namespace ::com::sun::star;
37 using namespace ::cppu;
39 const sal_uInt16 NON_USER_DEFINED_GLUE_POINTS = 4;
41 namespace {
43 class SvxUnoGluePointAccess : public WeakImplHelper< container::XIndexContainer, container::XIdentifierContainer >
45 private:
46 unotools::WeakReference<SdrObject> mpObject;
48 public:
49 explicit SvxUnoGluePointAccess( SdrObject* pObject ) noexcept;
51 // XIdentifierContainer
52 virtual sal_Int32 SAL_CALL insert( const uno::Any& aElement ) override;
53 virtual void SAL_CALL removeByIdentifier( sal_Int32 Identifier ) override;
55 // XIdentifierReplace
56 virtual void SAL_CALL replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement ) override;
58 // XIdentifierReplace
59 virtual uno::Any SAL_CALL getByIdentifier( sal_Int32 Identifier ) override;
60 virtual uno::Sequence< sal_Int32 > SAL_CALL getIdentifiers( ) override;
62 /* deprecated */
63 // XIndexContainer
64 virtual void SAL_CALL insertByIndex( sal_Int32 Index, const uno::Any& Element ) override;
65 virtual void SAL_CALL removeByIndex( sal_Int32 Index ) override;
67 /* deprecated */
68 // XIndexReplace
69 virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const uno::Any& Element ) override;
71 /* deprecated */
72 // XIndexAccess
73 virtual sal_Int32 SAL_CALL getCount( ) override;
74 virtual uno::Any SAL_CALL getByIndex( sal_Int32 Index ) override;
76 // XElementAccess
77 virtual uno::Type SAL_CALL getElementType( ) override;
78 virtual sal_Bool SAL_CALL hasElements( ) override;
83 static void convert( const SdrGluePoint& rSdrGlue, drawing::GluePoint2& rUnoGlue ) noexcept
85 rUnoGlue.Position.X = rSdrGlue.GetPos().X();
86 rUnoGlue.Position.Y = rSdrGlue.GetPos().Y();
87 rUnoGlue.IsRelative = rSdrGlue.IsPercent();
89 SdrAlign eAlign = rSdrGlue.GetAlign();
90 if (eAlign == (SdrAlign::VERT_TOP|SdrAlign::HORZ_LEFT))
91 rUnoGlue.PositionAlignment = drawing::Alignment_TOP_LEFT;
92 else if (eAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_TOP))
93 rUnoGlue.PositionAlignment = drawing::Alignment_TOP;
94 else if (eAlign == (SdrAlign::VERT_TOP|SdrAlign::HORZ_RIGHT))
95 rUnoGlue.PositionAlignment = drawing::Alignment_TOP_RIGHT;
96 else if (eAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_CENTER))
97 rUnoGlue.PositionAlignment = drawing::Alignment_CENTER;
98 else if (eAlign == (SdrAlign::HORZ_RIGHT|SdrAlign::VERT_CENTER))
99 rUnoGlue.PositionAlignment = drawing::Alignment_RIGHT;
100 else if (eAlign == (SdrAlign::HORZ_LEFT|SdrAlign::VERT_BOTTOM))
101 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_LEFT;
102 else if (eAlign == (SdrAlign::HORZ_CENTER|SdrAlign::VERT_BOTTOM))
103 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM;
104 else if (eAlign == (SdrAlign::HORZ_RIGHT|SdrAlign::VERT_BOTTOM))
105 rUnoGlue.PositionAlignment = drawing::Alignment_BOTTOM_RIGHT;
106 else {
107 rUnoGlue.PositionAlignment = drawing::Alignment_LEFT;
110 switch( rSdrGlue.GetEscDir() )
112 case SdrEscapeDirection::LEFT:
113 rUnoGlue.Escape = drawing::EscapeDirection_LEFT;
114 break;
115 case SdrEscapeDirection::RIGHT:
116 rUnoGlue.Escape = drawing::EscapeDirection_RIGHT;
117 break;
118 case SdrEscapeDirection::TOP:
119 rUnoGlue.Escape = drawing::EscapeDirection_UP;
120 break;
121 case SdrEscapeDirection::BOTTOM:
122 rUnoGlue.Escape = drawing::EscapeDirection_DOWN;
123 break;
124 case SdrEscapeDirection::HORZ:
125 rUnoGlue.Escape = drawing::EscapeDirection_HORIZONTAL;
126 break;
127 case SdrEscapeDirection::VERT:
128 rUnoGlue.Escape = drawing::EscapeDirection_VERTICAL;
129 break;
130 // case SdrEscapeDirection::SMART:
131 default:
132 rUnoGlue.Escape = drawing::EscapeDirection_SMART;
133 break;
137 static void convert( const drawing::GluePoint2& rUnoGlue, SdrGluePoint& rSdrGlue ) noexcept
139 rSdrGlue.SetPos( Point( rUnoGlue.Position.X, rUnoGlue.Position.Y ) );
140 rSdrGlue.SetPercent( rUnoGlue.IsRelative );
142 switch( rUnoGlue.PositionAlignment )
144 case drawing::Alignment_TOP_LEFT:
145 rSdrGlue.SetAlign( SdrAlign::VERT_TOP|SdrAlign::HORZ_LEFT );
146 break;
147 case drawing::Alignment_TOP:
148 rSdrGlue.SetAlign( SdrAlign::HORZ_CENTER|SdrAlign::VERT_TOP );
149 break;
150 case drawing::Alignment_TOP_RIGHT:
151 rSdrGlue.SetAlign( SdrAlign::VERT_TOP|SdrAlign::HORZ_RIGHT );
152 break;
153 case drawing::Alignment_CENTER:
154 rSdrGlue.SetAlign( SdrAlign::HORZ_CENTER|SdrAlign::VERT_CENTER );
155 break;
156 case drawing::Alignment_RIGHT:
157 rSdrGlue.SetAlign( SdrAlign::HORZ_RIGHT|SdrAlign::VERT_CENTER );
158 break;
159 case drawing::Alignment_BOTTOM_LEFT:
160 rSdrGlue.SetAlign( SdrAlign::HORZ_LEFT|SdrAlign::VERT_BOTTOM );
161 break;
162 case drawing::Alignment_BOTTOM:
163 rSdrGlue.SetAlign( SdrAlign::HORZ_CENTER|SdrAlign::VERT_BOTTOM );
164 break;
165 case drawing::Alignment_BOTTOM_RIGHT:
166 rSdrGlue.SetAlign( SdrAlign::HORZ_RIGHT|SdrAlign::VERT_BOTTOM );
167 break;
168 // case SdrAlign::HORZ_LEFT:
169 default:
170 rSdrGlue.SetAlign( SdrAlign::HORZ_LEFT );
171 break;
173 switch( rUnoGlue.Escape )
175 case drawing::EscapeDirection_LEFT:
176 rSdrGlue.SetEscDir(SdrEscapeDirection::LEFT);
177 break;
178 case drawing::EscapeDirection_RIGHT:
179 rSdrGlue.SetEscDir(SdrEscapeDirection::RIGHT);
180 break;
181 case drawing::EscapeDirection_UP:
182 rSdrGlue.SetEscDir(SdrEscapeDirection::TOP);
183 break;
184 case drawing::EscapeDirection_DOWN:
185 rSdrGlue.SetEscDir(SdrEscapeDirection::BOTTOM);
186 break;
187 case drawing::EscapeDirection_HORIZONTAL:
188 rSdrGlue.SetEscDir(SdrEscapeDirection::HORZ);
189 break;
190 case drawing::EscapeDirection_VERTICAL:
191 rSdrGlue.SetEscDir(SdrEscapeDirection::VERT);
192 break;
193 // case drawing::EscapeDirection_SMART:
194 default:
195 rSdrGlue.SetEscDir(SdrEscapeDirection::SMART);
196 break;
200 SvxUnoGluePointAccess::SvxUnoGluePointAccess( SdrObject* pObject ) noexcept
201 : mpObject( pObject )
205 // XIdentifierContainer
206 sal_Int32 SAL_CALL SvxUnoGluePointAccess::insert( const uno::Any& aElement )
208 if( auto pObject = mpObject.get() )
210 SdrGluePointList* pList = pObject->ForceGluePointList();
211 if( pList )
213 // second, insert the new gluepoint
214 drawing::GluePoint2 aUnoGlue;
216 if( aElement >>= aUnoGlue )
218 SdrGluePoint aSdrGlue;
219 convert( aUnoGlue, aSdrGlue );
220 sal_uInt16 nId = pList->Insert( aSdrGlue );
222 // only repaint, no objectchange
223 pObject->ActionChanged();
224 // mpObject->BroadcastObjectChange();
226 return static_cast<sal_Int32>((*pList)[nId].GetId() + NON_USER_DEFINED_GLUE_POINTS) - 1;
229 throw lang::IllegalArgumentException();
233 return -1;
236 void SAL_CALL SvxUnoGluePointAccess::removeByIdentifier( sal_Int32 Identifier )
238 auto pObject = mpObject.get();
239 if( pObject && ( Identifier >= NON_USER_DEFINED_GLUE_POINTS ))
241 const sal_uInt16 nId = static_cast<sal_uInt16>(Identifier - NON_USER_DEFINED_GLUE_POINTS) + 1;
243 SdrGluePointList* pList = const_cast<SdrGluePointList*>(pObject->GetGluePointList());
244 const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
245 sal_uInt16 i;
247 for( i = 0; i < nCount; i++ )
249 if( (*pList)[i].GetId() == nId )
251 pList->Delete( i );
253 // only repaint, no objectchange
254 pObject->ActionChanged();
255 // pObject->BroadcastObjectChange();
257 return;
262 throw container::NoSuchElementException();
265 // XIdentifierReplace
266 void SAL_CALL SvxUnoGluePointAccess::replaceByIdentifer( sal_Int32 Identifier, const uno::Any& aElement )
268 auto pObject = mpObject.get();
269 if( !pObject )
270 return;
272 struct drawing::GluePoint2 aGluePoint;
273 if( (Identifier < NON_USER_DEFINED_GLUE_POINTS) || !(aElement >>= aGluePoint))
274 throw lang::IllegalArgumentException();
276 const sal_uInt16 nId = static_cast<sal_uInt16>( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1;
278 SdrGluePointList* pList = const_cast< SdrGluePointList* >( pObject->GetGluePointList() );
279 const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
280 sal_uInt16 i;
281 for( i = 0; i < nCount; i++ )
283 if( (*pList)[i].GetId() == nId )
285 // change the gluepoint
286 SdrGluePoint& rTempPoint = (*pList)[i];
287 convert( aGluePoint, rTempPoint );
289 // only repaint, no objectchange
290 pObject->ActionChanged();
291 // pObject->BroadcastObjectChange();
293 return;
297 throw container::NoSuchElementException();
300 // XIdentifierAccess
301 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIdentifier( sal_Int32 Identifier )
303 auto pObject = mpObject.get();
304 if( pObject )
306 struct drawing::GluePoint2 aGluePoint;
308 if( Identifier < NON_USER_DEFINED_GLUE_POINTS ) // default gluepoint?
310 SdrGluePoint aTempPoint = pObject->GetVertexGluePoint( static_cast<sal_uInt16>(Identifier) );
311 aGluePoint.IsUserDefined = false;
312 convert( aTempPoint, aGluePoint );
313 return uno::Any( aGluePoint );
315 else
317 const sal_uInt16 nId = static_cast<sal_uInt16>( Identifier - NON_USER_DEFINED_GLUE_POINTS ) + 1;
319 const SdrGluePointList* pList = pObject->GetGluePointList();
320 const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
321 for( sal_uInt16 i = 0; i < nCount; i++ )
323 const SdrGluePoint& rTempPoint = (*pList)[i];
324 if( rTempPoint.GetId() == nId )
326 // #i38892#
327 if(rTempPoint.IsUserDefined())
329 aGluePoint.IsUserDefined = true;
332 convert( rTempPoint, aGluePoint );
333 return uno::Any( aGluePoint );
339 throw container::NoSuchElementException();
342 uno::Sequence< sal_Int32 > SAL_CALL SvxUnoGluePointAccess::getIdentifiers()
344 auto pObject = mpObject.get();
345 if( pObject )
347 const SdrGluePointList* pList = pObject->GetGluePointList();
348 const sal_uInt16 nCount = pList ? pList->GetCount() : 0;
350 sal_uInt16 i;
352 uno::Sequence< sal_Int32 > aIdSequence( nCount + NON_USER_DEFINED_GLUE_POINTS );
353 sal_Int32 *pIdentifier = aIdSequence.getArray();
355 for( i = 0; i < NON_USER_DEFINED_GLUE_POINTS; i++ )
356 *pIdentifier++ = static_cast<sal_Int32>(i);
358 for( i = 0; i < nCount; i++ )
359 *pIdentifier++ = static_cast<sal_Int32>( (*pList)[i].GetId() + NON_USER_DEFINED_GLUE_POINTS ) - 1;
361 return aIdSequence;
363 else
365 uno::Sequence< sal_Int32 > aEmpty;
366 return aEmpty;
370 /* deprecated */
372 // XIndexContainer
373 void SAL_CALL SvxUnoGluePointAccess::insertByIndex( sal_Int32, const uno::Any& Element )
375 auto pObject = mpObject.get();
376 if( pObject )
378 SdrGluePointList* pList = pObject->ForceGluePointList();
379 if( pList )
381 drawing::GluePoint2 aUnoGlue;
383 if( Element >>= aUnoGlue )
385 SdrGluePoint aSdrGlue;
386 convert( aUnoGlue, aSdrGlue );
387 pList->Insert( aSdrGlue );
389 // only repaint, no objectchange
390 pObject->ActionChanged();
391 // pObject->BroadcastObjectChange();
393 return;
396 throw lang::IllegalArgumentException();
400 throw lang::IndexOutOfBoundsException();
403 void SAL_CALL SvxUnoGluePointAccess::removeByIndex( sal_Int32 Index )
405 auto pObject = mpObject.get();
406 if( pObject )
408 SdrGluePointList* pList = pObject->ForceGluePointList();
409 if( pList )
411 Index -= 4;
412 if( Index >= 0 && Index < pList->GetCount() )
414 pList->Delete( static_cast<sal_uInt16>(Index) );
416 // only repaint, no objectchange
417 pObject->ActionChanged();
418 // pObject->BroadcastObjectChange();
420 return;
425 throw lang::IndexOutOfBoundsException();
428 // XIndexReplace
429 void SAL_CALL SvxUnoGluePointAccess::replaceByIndex( sal_Int32 Index, const uno::Any& Element )
431 drawing::GluePoint2 aUnoGlue;
432 if(!(Element >>= aUnoGlue))
433 throw lang::IllegalArgumentException();
435 auto pObject = mpObject.get();
436 Index -= 4;
437 if( pObject && Index >= 0 )
439 SdrGluePointList* pList = const_cast< SdrGluePointList* >( pObject->GetGluePointList() );
440 if( pList && Index < pList->GetCount() )
442 SdrGluePoint& rGlue = (*pList)[static_cast<sal_uInt16>(Index)];
443 convert( aUnoGlue, rGlue );
445 // only repaint, no objectchange
446 pObject->ActionChanged();
447 // pObject->BroadcastObjectChange();
451 throw lang::IndexOutOfBoundsException();
454 // XIndexAccess
455 sal_Int32 SAL_CALL SvxUnoGluePointAccess::getCount()
457 auto pObject = mpObject.get();
458 sal_Int32 nCount = 0;
459 if( pObject )
461 // each node has a default of 4 gluepoints
462 // and any number of user defined gluepoints
463 nCount += 4;
465 const SdrGluePointList* pList = pObject->GetGluePointList();
466 if( pList )
467 nCount += pList->GetCount();
470 return nCount;
473 uno::Any SAL_CALL SvxUnoGluePointAccess::getByIndex( sal_Int32 Index )
475 auto pObject = mpObject.get();
476 if( Index >= 0 && pObject )
478 struct drawing::GluePoint2 aGluePoint;
480 if( Index < 4 ) // default gluepoint?
482 SdrGluePoint aTempPoint = pObject->GetVertexGluePoint( static_cast<sal_uInt16>(Index) );
483 aGluePoint.IsUserDefined = false;
484 convert( aTempPoint, aGluePoint );
485 return uno::Any(aGluePoint);
487 else
489 Index -= 4;
490 const SdrGluePointList* pList = pObject->GetGluePointList();
491 if( pList && Index < pList->GetCount() )
493 const SdrGluePoint& rTempPoint = (*pList)[static_cast<sal_uInt16>(Index)];
494 aGluePoint.IsUserDefined = true;
495 convert( rTempPoint, aGluePoint );
496 return uno::Any(aGluePoint);
501 throw lang::IndexOutOfBoundsException();
504 // XElementAccess
505 uno::Type SAL_CALL SvxUnoGluePointAccess::getElementType()
507 return cppu::UnoType<drawing::GluePoint2>::get();
510 sal_Bool SAL_CALL SvxUnoGluePointAccess::hasElements()
512 return bool(mpObject.get());
516 * Create a SvxUnoGluePointAccess
518 uno::Reference< uno::XInterface > SvxUnoGluePointAccess_createInstance( SdrObject* pObject )
520 return *new SvxUnoGluePointAccess(pObject);
523 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */