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