Line data Source code
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 "SelectionHelper.hxx"
21 : #include "ObjectIdentifier.hxx"
22 : #include "macros.hxx"
23 : #include "DiagramHelper.hxx"
24 : #include "ChartModelHelper.hxx"
25 :
26 : // header for class SdrObjList
27 : #include <svx/svdpage.hxx>
28 : #include <svx/svditer.hxx>
29 : #include "svx/obj3d.hxx"
30 : // header for class SdrPathObj
31 : #include <svx/svdopath.hxx>
32 : #include <vcl/svapp.hxx>
33 : #include <osl/mutex.hxx>
34 : #include <basegfx/point/b2dpoint.hxx>
35 : #include <com/sun/star/beans/XPropertySet.hpp>
36 :
37 : //.............................................................................
38 : namespace chart
39 : {
40 : //.............................................................................
41 : using namespace ::com::sun::star;
42 :
43 : namespace
44 : {
45 :
46 0 : OUString lcl_getObjectName( SdrObject* pObj )
47 : {
48 0 : if(pObj)
49 0 : return pObj->GetName();
50 0 : return OUString();
51 : }
52 :
53 0 : void impl_selectObject( SdrObject* pObjectToSelect, DrawViewWrapper& rDrawViewWrapper )
54 : {
55 0 : SolarMutexGuard aSolarGuard;
56 :
57 0 : if(pObjectToSelect)
58 : {
59 0 : SelectionHelper aSelectionHelper( pObjectToSelect );
60 0 : SdrObject* pMarkObj = aSelectionHelper.getObjectToMark();
61 0 : rDrawViewWrapper.setMarkHandleProvider(&aSelectionHelper);
62 0 : rDrawViewWrapper.MarkObject(pMarkObj);
63 0 : rDrawViewWrapper.setMarkHandleProvider(NULL);
64 0 : }
65 0 : }
66 :
67 : }//anonymous namespace
68 :
69 2230 : bool Selection::hasSelection()
70 : {
71 2230 : return m_aSelectedOID.isValid();
72 : }
73 :
74 0 : OUString Selection::getSelectedCID()
75 : {
76 0 : return m_aSelectedOID.getObjectCID();
77 : }
78 :
79 0 : uno::Reference< drawing::XShape > Selection::getSelectedAdditionalShape()
80 : {
81 0 : return m_aSelectedOID.getAdditionalShape();
82 : }
83 :
84 0 : ObjectIdentifier Selection::getSelectedOID() const
85 : {
86 0 : return m_aSelectedOID;
87 : }
88 :
89 0 : bool Selection::setSelection( const OUString& rCID )
90 : {
91 0 : if ( !rCID.equals( m_aSelectedOID.getObjectCID() ) )
92 : {
93 0 : m_aSelectedOID = ObjectIdentifier( rCID );
94 0 : return true;
95 : }
96 0 : return false;
97 : }
98 :
99 0 : bool Selection::setSelection( const uno::Reference< drawing::XShape >& xShape )
100 : {
101 0 : if ( !( xShape == m_aSelectedOID.getAdditionalShape() ) )
102 : {
103 0 : clearSelection();
104 0 : m_aSelectedOID = ObjectIdentifier( xShape );
105 0 : return true;
106 : }
107 0 : return false;
108 : }
109 :
110 0 : void Selection::clearSelection()
111 : {
112 0 : m_aSelectedOID = ObjectIdentifier();
113 0 : m_aSelectedOID_beforeMouseDown = ObjectIdentifier();
114 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
115 0 : }
116 :
117 0 : bool Selection::maybeSwitchSelectionAfterSingleClickWasEnsured()
118 : {
119 0 : if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid()
120 0 : && m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing != m_aSelectedOID )
121 : {
122 0 : m_aSelectedOID = m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing;
123 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
124 0 : return true;
125 : }
126 0 : return false;
127 : }
128 :
129 0 : void Selection::resetPossibleSelectionAfterSingleClickWasEnsured()
130 : {
131 0 : if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() )
132 : {
133 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
134 : }
135 0 : }
136 :
137 0 : void Selection::remindSelectionBeforeMouseDown()
138 : {
139 0 : m_aSelectedOID_beforeMouseDown = m_aSelectedOID;
140 0 : }
141 :
142 0 : bool Selection::isSelectionDifferentFromBeforeMouseDown() const
143 : {
144 0 : return ( m_aSelectedOID != m_aSelectedOID_beforeMouseDown );
145 : }
146 :
147 0 : void Selection::applySelection( DrawViewWrapper* pDrawViewWrapper )
148 : {
149 0 : if( pDrawViewWrapper )
150 : {
151 : {
152 0 : SolarMutexGuard aSolarGuard;
153 0 : pDrawViewWrapper->UnmarkAll();
154 : }
155 0 : SdrObject* pObjectToSelect = 0;
156 0 : if ( m_aSelectedOID.isAutoGeneratedObject() )
157 : {
158 0 : pObjectToSelect = pDrawViewWrapper->getNamedSdrObject( m_aSelectedOID.getObjectCID() );
159 : }
160 0 : else if( m_aSelectedOID.isAdditionalShape() )
161 : {
162 0 : pObjectToSelect = DrawViewWrapper::getSdrObject( m_aSelectedOID.getAdditionalShape() );
163 : }
164 :
165 0 : impl_selectObject( pObjectToSelect, *pDrawViewWrapper );
166 : }
167 0 : }
168 :
169 0 : void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* pDrawViewWrapper
170 : , bool bIsRightMouse, bool bWaitingForDoubleClick )
171 : {
172 0 : if( pDrawViewWrapper )
173 : {
174 : //do not toggel multiclick selection if right clicked on the selected object or waiting for double click
175 0 : bool bAllowMultiClickSelectionChange = !bIsRightMouse && !bWaitingForDoubleClick;
176 :
177 0 : ObjectIdentifier aLastSelectedObject( m_aSelectedOID );
178 :
179 0 : SolarMutexGuard aSolarGuard;
180 :
181 : //bAllowMultiClickSelectionChange==true -> a second click on the same object can lead to a changed selection (e.g. series -> single data point)
182 :
183 : //get object to select:
184 0 : SdrObject* pNewObj = 0;
185 : {
186 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
187 :
188 : //the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree)
189 : //further we travel along the grouping hierarchy from child to parent
190 0 : pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
191 0 : m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) );//name of pNewObj
192 :
193 : //ignore handle only objects for hit test
194 0 : while( pNewObj && m_aSelectedOID.getObjectCID().match( "HandlesOnly" ) )
195 : {
196 0 : pNewObj->SetMarkProtect(true);
197 0 : pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
198 0 : m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) );
199 : }
200 :
201 : //accept only named objects while searching for the object to select
202 : //this call may change m_aSelectedOID
203 0 : if ( SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, true ) )
204 : {
205 : //if the so far found object is a multi click object further steps are necessary
206 0 : while( ObjectIdentifier::isMultiClickObject( m_aSelectedOID.getObjectCID() ) )
207 : {
208 0 : bool bSameObjectAsLastSelected = ( aLastSelectedObject == m_aSelectedOID );
209 0 : if( bSameObjectAsLastSelected )
210 : {
211 : //if the same child is clicked again don't go up further
212 0 : break;
213 : }
214 0 : if ( ObjectIdentifier::areSiblings( aLastSelectedObject.getObjectCID(), m_aSelectedOID.getObjectCID() ) )
215 : {
216 : //if a sibling of the last selected object is clicked don't go up further
217 0 : break;
218 : }
219 0 : SdrObject* pLastChild = pNewObj;
220 0 : ObjectIdentifier aLastChild = m_aSelectedOID;
221 0 : if ( !SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, false ) )
222 : {
223 : //take the one found so far
224 0 : break;
225 : }
226 : //if the last selected object is found don't go up further
227 : //but take the last child if selection change is allowed
228 0 : if ( aLastSelectedObject == m_aSelectedOID )
229 : {
230 0 : if( bAllowMultiClickSelectionChange )
231 : {
232 0 : pNewObj = pLastChild;
233 0 : m_aSelectedOID = aLastChild;
234 : }
235 : else
236 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = aLastChild;
237 :
238 0 : break;
239 : }
240 0 : }
241 :
242 : OSL_ENSURE( pNewObj && m_aSelectedOID.isValid(), "somehow lost selected object" );
243 : }
244 : else
245 : {
246 : //maybe an additional shape was hit
247 0 : if ( pNewObj )
248 : {
249 0 : m_aSelectedOID = ObjectIdentifier( uno::Reference< drawing::XShape >( pNewObj->getUnoShape(), uno::UNO_QUERY ) );
250 : }
251 : else
252 : {
253 0 : m_aSelectedOID = ObjectIdentifier();
254 : }
255 : }
256 :
257 0 : if ( !m_aSelectedOID.isAdditionalShape() )
258 : {
259 0 : OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );//@todo read CID from model
260 :
261 0 : if ( !m_aSelectedOID.isAutoGeneratedObject() )
262 : {
263 0 : m_aSelectedOID = ObjectIdentifier( aPageCID );
264 : }
265 :
266 : //check whether the diagram was hit but not selected (e.g. because it has no filling):
267 0 : OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::valueOf( sal_Int32(0) ) );
268 0 : OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
269 0 : bool bBackGroundHit = m_aSelectedOID.getObjectCID().equals( aPageCID ) || m_aSelectedOID.getObjectCID().equals( aWallCID ) || !m_aSelectedOID.isAutoGeneratedObject();
270 0 : if( bBackGroundHit )
271 : {
272 : //todo: if more than one diagram is available in future do chack the list of all diagrams here
273 0 : SdrObject* pDiagram = pDrawViewWrapper->getNamedSdrObject( aDiagramCID );
274 0 : if( pDiagram )
275 : {
276 0 : if( pDrawViewWrapper->IsObjectHit( pDiagram, rMousePos ) )
277 : {
278 0 : m_aSelectedOID = ObjectIdentifier( aDiagramCID );
279 0 : pNewObj = pDiagram;
280 : }
281 : }
282 : }
283 : //check whether the legend was hit but not selected (e.g. because it has no filling):
284 0 : if( bBackGroundHit || m_aSelectedOID.getObjectCID().equals( aDiagramCID ) )
285 : {
286 0 : OUString aLegendCID( ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::createParticleForLegend(0,0) ) );//@todo read CID from model
287 0 : SdrObject* pLegend = pDrawViewWrapper->getNamedSdrObject( aLegendCID );
288 0 : if( pLegend )
289 : {
290 0 : if( pDrawViewWrapper->IsObjectHit( pLegend, rMousePos ) )
291 : {
292 0 : m_aSelectedOID = ObjectIdentifier( aLegendCID );
293 0 : pNewObj = pLegend;
294 : }
295 0 : }
296 0 : }
297 : }
298 : }
299 :
300 0 : if ( bIsRightMouse && m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() )
301 : {
302 0 : m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
303 0 : }
304 : }
305 0 : }
306 :
307 0 : bool Selection::isResizeableObjectSelected()
308 : {
309 0 : ObjectType eObjectType = m_aSelectedOID.getObjectType();
310 0 : switch( eObjectType )
311 : {
312 : case OBJECTTYPE_DIAGRAM:
313 : case OBJECTTYPE_DIAGRAM_WALL:
314 : case OBJECTTYPE_SHAPE:
315 : case OBJECTTYPE_LEGEND:
316 0 : return true;
317 : default:
318 0 : return false;
319 : }
320 : }
321 :
322 0 : bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel )
323 : {
324 0 : return SelectionHelper::isRotateableObject( m_aSelectedOID.getObjectCID(), xChartModel );
325 : }
326 :
327 0 : bool Selection::isDragableObjectSelected()
328 : {
329 0 : return m_aSelectedOID.isDragableObject();
330 : }
331 :
332 789 : bool Selection::isAdditionalShapeSelected() const
333 : {
334 789 : return m_aSelectedOID.isAdditionalShape();
335 : }
336 :
337 : //-----------------------------------------------------------------------------
338 : //-----------------------------------------------------------------------------
339 : //-----------------------------------------------------------------------------
340 0 : bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject
341 : , OUString& rOutName
342 : , bool bGivenObjectMayBeResult )
343 : {
344 0 : SolarMutexGuard aSolarGuard;
345 : //find the deepest named group
346 0 : SdrObject* pObj = pInOutObject;
347 0 : OUString aName;
348 0 : if( bGivenObjectMayBeResult )
349 0 : aName = lcl_getObjectName( pObj );
350 :
351 0 : while( pObj && !ObjectIdentifier::isCID( aName ) )
352 : {
353 0 : SdrObjList* pObjList = pObj->GetObjList();
354 0 : if( !pObjList )
355 0 : return false;;
356 0 : SdrObject* pOwner = pObjList->GetOwnerObj();
357 0 : if( !pOwner )
358 0 : return false;
359 0 : pObj = pOwner;
360 0 : aName = lcl_getObjectName( pObj );
361 : }
362 :
363 0 : if(!pObj)
364 0 : return false;
365 0 : if(aName.isEmpty())
366 0 : return false;
367 :
368 0 : pInOutObject = pObj;
369 0 : rOutName = aName;
370 0 : return true;
371 : }
372 :
373 0 : bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject
374 : , ObjectIdentifier& rOutObject
375 : , bool bGivenObjectMayBeResult )
376 : {
377 0 : OUString aName;
378 0 : if ( findNamedParent( pInOutObject, aName, bGivenObjectMayBeResult ) )
379 : {
380 0 : rOutObject = ObjectIdentifier( aName );
381 0 : return true;
382 : }
383 0 : return false;
384 : }
385 :
386 0 : bool SelectionHelper::isDragableObjectHitTwice( const Point& rMPos
387 : , const OUString& rNameOfSelectedObject
388 : , const DrawViewWrapper& rDrawViewWrapper )
389 : {
390 0 : if(rNameOfSelectedObject.isEmpty())
391 0 : return false;
392 0 : if( !ObjectIdentifier::isDragableObject(rNameOfSelectedObject) )
393 0 : return false;
394 0 : SolarMutexGuard aSolarGuard;
395 0 : SdrObject* pObj = rDrawViewWrapper.getNamedSdrObject( rNameOfSelectedObject );
396 0 : if( !rDrawViewWrapper.IsObjectHit( pObj, rMPos ) )
397 0 : return false;
398 0 : return true;
399 : }
400 :
401 0 : OUString SelectionHelper::getHitObjectCID(
402 : const Point& rMPos,
403 : DrawViewWrapper& rDrawViewWrapper,
404 : bool bGetDiagramInsteadOf_Wall )
405 : {
406 : // //- solar mutex
407 0 : SolarMutexGuard aSolarGuard;
408 0 : OUString aRet;
409 :
410 0 : SdrObject* pNewObj = rDrawViewWrapper.getHitObject(rMPos);
411 0 : aRet = lcl_getObjectName( pNewObj );//name of pNewObj
412 :
413 : //ignore handle only objects for hit test
414 0 : while( pNewObj && aRet.match("HandlesOnly") )
415 : {
416 0 : pNewObj->SetMarkProtect(true);
417 0 : pNewObj = rDrawViewWrapper.getHitObject(rMPos);
418 0 : aRet = lcl_getObjectName( pNewObj );
419 : }
420 :
421 : //accept only named objects while searching for the object to select
422 0 : if( !findNamedParent( pNewObj, aRet, true ) )
423 : {
424 0 : aRet = OUString();
425 : }
426 :
427 0 : OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );//@todo read CID from model
428 : //get page when nothing was hit
429 0 : if( aRet.isEmpty() && !pNewObj )
430 : {
431 0 : aRet = aPageCID;
432 : }
433 :
434 : //get diagram instead wall or page if hit inside diagram
435 0 : if( !aRet.isEmpty() )
436 : {
437 0 : if( aRet.equals( aPageCID ) )
438 : {
439 0 : OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::valueOf( sal_Int32(0) ) );
440 : //todo: if more than one diagram is available in future do chack the list of all diagrams here
441 0 : SdrObject* pDiagram = rDrawViewWrapper.getNamedSdrObject( aDiagramCID );
442 0 : if( pDiagram )
443 : {
444 0 : if( rDrawViewWrapper.IsObjectHit( pDiagram, rMPos ) )
445 : {
446 0 : aRet = aDiagramCID;
447 : }
448 0 : }
449 : }
450 0 : else if( bGetDiagramInsteadOf_Wall )
451 : {
452 0 : OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
453 :
454 0 : if( aRet.equals( aWallCID ) )
455 : {
456 0 : OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::valueOf( sal_Int32(0) ) );
457 0 : aRet = aDiagramCID;
458 0 : }
459 : }
460 : }
461 :
462 0 : return aRet;
463 : // \\- solar mutex
464 : }
465 :
466 0 : bool SelectionHelper::isRotateableObject( const OUString& rCID
467 : , const uno::Reference< frame::XModel >& xChartModel )
468 : {
469 0 : if( !ObjectIdentifier::isRotateableObject( rCID ) )
470 0 : return false;
471 :
472 0 : sal_Int32 nDimensionCount = DiagramHelper::getDimension( ChartModelHelper::findDiagram( xChartModel ) );
473 :
474 0 : if( nDimensionCount == 3 )
475 0 : return true;
476 0 : return false;
477 : }
478 :
479 0 : SelectionHelper::SelectionHelper( SdrObject* pSelectedObj )
480 0 : : m_pSelectedObj( pSelectedObj ), m_pMarkObj(NULL)
481 : {
482 :
483 0 : }
484 0 : SelectionHelper::~SelectionHelper()
485 : {
486 0 : }
487 :
488 0 : bool SelectionHelper::getFrameDragSingles()
489 : {
490 0 : bool bFrameDragSingles = true;//true == green == surrounding handles
491 0 : if( m_pSelectedObj && m_pSelectedObj->ISA(E3dObject) )
492 0 : bFrameDragSingles = false;
493 0 : return bFrameDragSingles;
494 : }
495 :
496 0 : SdrObject* SelectionHelper::getMarkHandlesObject( SdrObject* pObj )
497 : {
498 0 : if(!pObj)
499 0 : return 0;
500 0 : OUString aName( lcl_getObjectName( pObj ) );
501 0 : if( aName.match("MarkHandles") || aName.match("HandlesOnly") )
502 0 : return pObj;
503 0 : if( !aName.isEmpty() )//dont't get the markhandles of a different object
504 0 : return 0;
505 :
506 : //search for a child with name "MarkHandles" or "HandlesOnly"
507 0 : SolarMutexGuard aSolarGuard;
508 0 : SdrObjList* pSubList = pObj->GetSubList();
509 0 : if(pSubList)
510 : {
511 0 : SdrObjListIter aIterator(*pSubList, IM_FLAT);
512 0 : while (aIterator.IsMore())
513 : {
514 0 : SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
515 0 : if( pMarkHandles )
516 0 : return pMarkHandles;
517 0 : }
518 : }
519 0 : return 0;
520 : }
521 :
522 0 : SdrObject* SelectionHelper::getObjectToMark()
523 : {
524 : //return the selected object itself
525 : //or a specific other object if that exsists
526 0 : SdrObject* pObj = m_pSelectedObj;
527 0 : m_pMarkObj = pObj;
528 :
529 : //search for a child with name "MarkHandles" or "HandlesOnly"
530 0 : if(pObj)
531 : {
532 0 : SolarMutexGuard aSolarGuard;
533 0 : SdrObjList* pSubList = pObj->GetSubList();
534 0 : if(pSubList)
535 : {
536 0 : SdrObjListIter aIterator(*pSubList, IM_FLAT);
537 0 : while (aIterator.IsMore())
538 : {
539 0 : SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
540 0 : if( pMarkHandles )
541 : {
542 0 : m_pMarkObj = pMarkHandles;
543 0 : break;
544 : }
545 0 : }
546 0 : }
547 : }
548 0 : return m_pMarkObj;
549 : }
550 :
551 0 : E3dScene* SelectionHelper::getSceneToRotate( SdrObject* pObj )
552 : {
553 : //search whether the object or one of its children is a 3D object
554 : //if so, return the accessory 3DScene
555 :
556 0 : E3dObject* pRotateable = 0;
557 :
558 0 : if(pObj)
559 : {
560 0 : pRotateable = dynamic_cast<E3dObject*>(pObj);
561 0 : if( !pRotateable )
562 : {
563 0 : SolarMutexGuard aSolarGuard;
564 0 : SdrObjList* pSubList = pObj->GetSubList();
565 0 : if(pSubList)
566 : {
567 0 : SdrObjListIter aIterator(*pSubList, IM_DEEPWITHGROUPS);
568 0 : while( aIterator.IsMore() && !pRotateable )
569 : {
570 0 : SdrObject* pSubObj = aIterator.Next();
571 0 : pRotateable = dynamic_cast<E3dObject*>(pSubObj);
572 0 : }
573 0 : }
574 : }
575 : }
576 :
577 0 : E3dScene* pScene = 0;
578 0 : if(pRotateable)
579 : {
580 0 : SolarMutexGuard aSolarGuard;
581 0 : pScene = pRotateable->GetScene();
582 : }
583 0 : return pScene;
584 :
585 : }
586 :
587 0 : bool SelectionHelper::getMarkHandles( SdrHdlList& rHdlList )
588 : {
589 0 : SolarMutexGuard aSolarGuard;
590 :
591 : //@todo -> more flexible handle creation
592 : //2 scenarios possible:
593 : //1. add an additional invisible shape as a child to the selected object
594 : //this child needs to be named somehow and handles need to be generated therefrom ...
595 : //or 2. offer a central service per view where renderer and so can register for handle creation for a special shape
596 : //.. or 3. feature from drawinglayer to create handles for each shape ... (bad performance ... ?) ?
597 :
598 : //scenario 1 is now used:
599 : //if a child with name MarkHandles exsists
600 : //this child is marked instead of the logical selected object
601 :
602 : /*
603 : //if a special mark object was found
604 : //that object should be used for marking only
605 : if( m_pMarkObj != m_pSelectedObj)
606 : return false;
607 : */
608 : //if a special mark object was found
609 : //that object should be used to create handles from
610 0 : if( m_pMarkObj && m_pMarkObj != m_pSelectedObj)
611 : {
612 0 : rHdlList.Clear();
613 0 : if( m_pMarkObj->ISA(SdrPathObj) )
614 : {
615 : //if th object is a polygon
616 : //from each point a handle is generated
617 0 : const ::basegfx::B2DPolyPolygon& rPolyPolygon = ((SdrPathObj*)m_pMarkObj)->GetPathPoly();
618 0 : for( sal_uInt32 nN = 0L; nN < rPolyPolygon.count(); nN++)
619 : {
620 0 : const ::basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nN));
621 0 : for( sal_uInt32 nM = 0L; nM < aPolygon.count(); nM++)
622 : {
623 0 : const ::basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(nM));
624 0 : SdrHdl* pHdl = new SdrHdl(Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())), HDL_POLY);
625 0 : rHdlList.AddHdl(pHdl);
626 0 : }
627 0 : }
628 0 : return true;
629 : }
630 : else
631 0 : return false; //use the special MarkObject for marking
632 : }
633 :
634 : //@todo:
635 : //add and document good marking defaults ...
636 :
637 0 : rHdlList.Clear();
638 :
639 0 : SdrObject* pObj = m_pSelectedObj;
640 0 : if(!pObj)
641 0 : return false;
642 0 : SdrObjList* pSubList = pObj->GetSubList();
643 0 : if( !pSubList )//no group object !pObj->IsGroupObject()
644 0 : return false;
645 :
646 0 : OUString aName( lcl_getObjectName( pObj ) );
647 0 : ObjectType eObjectType( ObjectIdentifier::getObjectType( aName ) );
648 0 : if( OBJECTTYPE_DATA_POINT == eObjectType
649 0 : || OBJECTTYPE_DATA_LABEL == eObjectType
650 0 : || OBJECTTYPE_LEGEND_ENTRY == eObjectType
651 0 : || OBJECTTYPE_AXIS_UNITLABEL == eObjectType )
652 : {
653 0 : return false;
654 : }
655 :
656 0 : SdrObjListIter aIterator(*pSubList, IM_FLAT);
657 :
658 0 : while (aIterator.IsMore())
659 : {
660 0 : SdrObject* pSubObj = aIterator.Next();
661 0 : if( OBJECTTYPE_DATA_SERIES == eObjectType )
662 : {
663 0 : OUString aSubName( lcl_getObjectName( pSubObj ) );
664 0 : ObjectType eSubObjectType( ObjectIdentifier::getObjectType( aSubName ) );
665 0 : if( eSubObjectType!=OBJECTTYPE_DATA_POINT )
666 0 : return false;
667 : }
668 :
669 0 : Point aPos = pSubObj->GetCurrentBoundRect().Center();
670 0 : SdrHdl* pHdl = new SdrHdl(aPos,HDL_POLY);
671 0 : rHdlList.AddHdl(pHdl);
672 : }
673 0 : return true;
674 : }
675 :
676 : //.............................................................................
677 33 : } //namespace chart
678 : //.............................................................................
679 :
680 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|