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