merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / controller / main / SelectionHelper.cxx
blob3ea5b4fa47a6ad31c9e9b0c621cf5a8dad00c1e9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SelectionHelper.cxx,v $
10 * $Revision: 1.11.68.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
33 #include "SelectionHelper.hxx"
34 #include "ObjectIdentifier.hxx"
35 //for C2U
36 #include "macros.hxx"
37 #include "DiagramHelper.hxx"
38 #include "ChartModelHelper.hxx"
40 // header for class SdrObjList
41 #include <svx/svdpage.hxx>
42 #include <svx/svditer.hxx>
43 #include "svx/obj3d.hxx"
44 // header for class SdrPathObj
45 #include <svx/svdopath.hxx>
46 #include <vcl/svapp.hxx>
47 #include <vos/mutex.hxx>
48 #include <basegfx/point/b2dpoint.hxx>
49 #include <com/sun/star/beans/XPropertySet.hpp>
51 //.............................................................................
52 namespace chart
54 //.............................................................................
55 using namespace ::com::sun::star;
56 //using namespace ::com::sun::star::chart2;
58 namespace
61 rtl::OUString lcl_getObjectName( SdrObject* pObj )
63 if(pObj)
64 return pObj->GetName();
65 return rtl::OUString();
68 void impl_selectObject( SdrObject* pObjectToSelect, DrawViewWrapper& rDrawViewWrapper )
70 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
72 if(pObjectToSelect)
74 SelectionHelper aSelectionHelper( pObjectToSelect );
75 SdrObject* pMarkObj = aSelectionHelper.getObjectToMark();
76 rDrawViewWrapper.setMarkHandleProvider(&aSelectionHelper);
77 rDrawViewWrapper.MarkObject(pMarkObj);
78 rDrawViewWrapper.setMarkHandleProvider(NULL);
82 }//anonymous namespace
84 bool Selection::hasSelection()
86 return m_aSelectedObjectCID.getLength() || m_xSelectAdditionalShape.is();
89 rtl::OUString Selection::getSelectedCID()
91 return m_aSelectedObjectCID;
94 uno::Reference< drawing::XShape > Selection::getSelectedAdditionalShape()
96 return m_xSelectAdditionalShape;
99 bool Selection::setSelection( const ::rtl::OUString& rCID )
101 if( !rCID.equals( m_aSelectedObjectCID ) )
103 m_aSelectedObjectCID = rCID;
104 m_xSelectAdditionalShape.set(0);
105 return true;
107 return false;
110 bool Selection::setSelection( const uno::Reference< drawing::XShape >& xShape )
112 if( !(m_xSelectAdditionalShape==xShape) )
114 clearSelection();
115 m_xSelectAdditionalShape = xShape;
116 return true;
118 return false;
121 void Selection::clearSelection()
123 m_aSelectedObjectCID = m_aSelectedObjectCID_beforeMouseDown
124 = m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = rtl::OUString();
125 m_xSelectAdditionalShape.set(0);
128 bool Selection::maybeSwitchSelectionAfterSingleClickWasEnsured()
130 if( m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength()
131 && !m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.equals(m_aSelectedObjectCID) )
133 m_aSelectedObjectCID = m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing;
134 m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U("");
135 return true;
137 return false;
140 void Selection::resetPossibleSelectionAfterSingleClickWasEnsured()
142 if( m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength() )
143 m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U("");
146 void Selection::remindSelectionBeforeMouseDown()
148 m_aSelectedObjectCID_beforeMouseDown = m_aSelectedObjectCID;
151 bool Selection::isSelectionDifferentFromBeforeMouseDown()
153 return !ObjectIdentifier::areIdenticalObjects( m_aSelectedObjectCID, m_aSelectedObjectCID_beforeMouseDown );
156 void Selection::applySelection( DrawViewWrapper* pDrawViewWrapper )
158 if( pDrawViewWrapper )
161 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
162 pDrawViewWrapper->UnmarkAll();
164 SdrObject* pObjectToSelect = 0;
165 if( m_aSelectedObjectCID.getLength() )
166 pObjectToSelect = pDrawViewWrapper->getNamedSdrObject( m_aSelectedObjectCID );
167 else if( m_xSelectAdditionalShape.is() )
168 pObjectToSelect = DrawViewWrapper::getSdrObject( m_xSelectAdditionalShape );
170 impl_selectObject( pObjectToSelect, *pDrawViewWrapper );
174 void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* pDrawViewWrapper
175 , bool bIsRightMouse, bool bWaitingForDoubleClick )
177 if( pDrawViewWrapper )
179 //do not toggel multiclick selection if right clicked on the selected object or waiting for double click
180 bool bAllowMultiClickSelectionChange = !bIsRightMouse && !bWaitingForDoubleClick;
182 const rtl::OUString aNameOfLastSelectedObject( m_aSelectedObjectCID );
184 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
186 //bAllowMultiClickSelectionChange==true -> a second click on the same object can lead to a changed selection (e.g. series -> single data point)
188 //get object to select:
189 SdrObject* pNewObj = 0;
191 m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U("");
192 m_xSelectAdditionalShape.set(0);
194 //the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree)
195 //further we travel along the grouping hierarchy from child to parent
196 pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
197 m_aSelectedObjectCID = lcl_getObjectName( pNewObj );//name of pNewObj
198 rtl::OUString aTestFirstHit = m_aSelectedObjectCID;
200 //ignore handle only objects for hit test
201 while( pNewObj && m_aSelectedObjectCID.match(C2U("HandlesOnly")) )
203 pNewObj->SetMarkProtect(true);
204 pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
205 m_aSelectedObjectCID = lcl_getObjectName( pNewObj );
208 //accept only named objects while searching for the object to select
209 //this call may change m_aSelectedObjectCID
210 if( SelectionHelper::findNamedParent( pNewObj, m_aSelectedObjectCID, true ) )
212 //if the so far found object is a multi click object further steps are necessary
213 while( ObjectIdentifier::isMultiClickObject( m_aSelectedObjectCID ) )
215 bool bSameObjectAsLastSelected = ObjectIdentifier::areIdenticalObjects( aNameOfLastSelectedObject, m_aSelectedObjectCID );
216 if( bSameObjectAsLastSelected )
218 //if the same child is clicked again don't go up further
219 break;
221 if( ObjectIdentifier::areSiblings(aNameOfLastSelectedObject,m_aSelectedObjectCID) )
223 //if a sibling of the last selected object is clicked don't go up further
224 break;
226 SdrObject* pLastChild = pNewObj;
227 rtl::OUString aLastChildName = m_aSelectedObjectCID;
228 if(!SelectionHelper::findNamedParent( pNewObj, m_aSelectedObjectCID, false ))
230 //take the one found so far
231 break;
233 //if the last selected object is found don't go up further
234 //but take the last child if selection change is allowed
235 if( ObjectIdentifier::areIdenticalObjects( aNameOfLastSelectedObject, m_aSelectedObjectCID ) )
237 if( bAllowMultiClickSelectionChange )
239 pNewObj = pLastChild;
240 m_aSelectedObjectCID = aLastChildName;
242 else
243 m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = aLastChildName;
245 break;
249 DBG_ASSERT(pNewObj && m_aSelectedObjectCID.getLength(),"somehow lost selected object");
251 else
253 //maybe an additional shape was hit
254 m_aSelectedObjectCID = rtl::OUString();
255 if( pNewObj )
257 m_xSelectAdditionalShape = uno::Reference< drawing::XShape >( pNewObj->getUnoShape(), uno::UNO_QUERY);
261 if(!m_xSelectAdditionalShape.is())
263 rtl::OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );//@todo read CID from model
265 if( !m_aSelectedObjectCID.getLength() )
266 m_aSelectedObjectCID = aPageCID;
268 //check wether the diagram was hit but not selected (e.g. because it has no filling):
269 rtl::OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) );//@todo read CID from model
270 if( m_aSelectedObjectCID.equals( aPageCID ) || m_aSelectedObjectCID.equals( aWallCID ) || !m_aSelectedObjectCID.getLength() )
272 rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) );
273 //todo: if more than one diagram is available in future do chack the list of all diagrams here
274 SdrObject* pDiagram = pDrawViewWrapper->getNamedSdrObject( aDiagramCID );
275 if( pDiagram )
277 if( pDrawViewWrapper->IsObjectHit( pDiagram, rMousePos ) )
279 m_aSelectedObjectCID = aDiagramCID;
280 pNewObj = pDiagram;
287 if( bIsRightMouse && m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing.getLength() )
288 m_aSelectedObjectCID_selectOnlyIfNoDoubleClickIsFollowing = C2U("");
292 bool Selection::isResizeableObjectSelected()
294 ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelectedObjectCID );
295 switch( eObjectType )
297 case OBJECTTYPE_DIAGRAM:
298 case OBJECTTYPE_DIAGRAM_WALL:
299 return true;
300 default:
301 return false;
303 return false;
306 bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel )
308 return SelectionHelper::isRotateableObject( m_aSelectedObjectCID, xChartModel );
311 bool Selection::isDragableObjectSelected()
313 if( m_aSelectedObjectCID.getLength() )
314 return ObjectIdentifier::isDragableObject( m_aSelectedObjectCID );
315 return m_xSelectAdditionalShape.is();
318 //-----------------------------------------------------------------------------
319 //-----------------------------------------------------------------------------
320 //-----------------------------------------------------------------------------
322 //static
323 bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject
324 , rtl::OUString& rOutName
325 , bool bGivenObjectMayBeResult )
327 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
328 //find the deepest named group
329 SdrObject* pObj = pInOutObject;
330 rtl::OUString aName;
331 if( bGivenObjectMayBeResult )
332 aName = lcl_getObjectName( pObj );
334 while( pObj && !ObjectIdentifier::isCID( aName ) )
336 SdrObjList* pObjList = pObj->GetObjList();
337 if( !pObjList )
338 return false;;
339 SdrObject* pOwner = pObjList->GetOwnerObj();
340 if( !pOwner )
341 return false;
342 pObj = pOwner;
343 aName = lcl_getObjectName( pObj );
346 if(!pObj)
347 return false;
348 if(!aName.getLength())
349 return false;
351 pInOutObject = pObj;
352 rOutName = aName;
353 return true;
356 //static
357 bool SelectionHelper::isDragableObjectHitTwice( const Point& rMPos
358 , const rtl::OUString& rNameOfSelectedObject
359 , const DrawViewWrapper& rDrawViewWrapper )
361 if(!rNameOfSelectedObject.getLength())
362 return false;
363 if( !ObjectIdentifier::isDragableObject(rNameOfSelectedObject) )
364 return false;
365 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
366 SdrObject* pObj = rDrawViewWrapper.getNamedSdrObject( rNameOfSelectedObject );
367 if( !rDrawViewWrapper.IsObjectHit( pObj, rMPos ) )
368 return false;
369 return true;
373 rtl::OUString lcl_getObjectCIDToSelect( const Point& rMPos
374 , const rtl::OUString& rNameOfLastSelectedObject
375 , DrawViewWrapper& rDrawViewWrapper
376 , bool bAllowMultiClickSelectionChange
377 , rtl::OUString& rObjectToSelectIfNoDoubleClickIsFollowing //out parameter only
380 rtl::OUString aRet;
382 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
384 //bAllowMultiClickSelectionChange==true -> a second click on the same object can lead to a changed selection (e.g. series -> single data point)
386 //get object to select:
387 SdrObject* pNewObj = 0;
389 rObjectToSelectIfNoDoubleClickIsFollowing = C2U("");
391 //the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree)
392 //further we travel along the grouping hierarchy from child to parent
393 pNewObj = rDrawViewWrapper.getHitObject(rMPos);
394 aRet = lcl_getObjectName( pNewObj );//name of pNewObj
395 rtl::OUString aTestFirstHit = aRet;
397 //ignore handle only objects for hit test
398 while( pNewObj && aRet.match(C2U("HandlesOnly")) )
400 pNewObj->SetMarkProtect(true);
401 pNewObj = rDrawViewWrapper.getHitObject(rMPos);
402 aRet = lcl_getObjectName( pNewObj );
405 //accept only named objects while searching for the object to select
406 //this call may change aRet
407 if( !findNamedParent( pNewObj, aRet, true ) )
409 return C2U("");
411 //if the so far found object is a multi click object further steps are necessary
412 while( ObjectIdentifier::isMultiClickObject( aRet ) )
414 bool bSameObjectAsLastSelected = ObjectIdentifier::areIdenticalObjects( rNameOfLastSelectedObject, aRet );
415 if( bSameObjectAsLastSelected )
417 //if the same child is clicked again don't go up further
418 break;
420 if( ObjectIdentifier::areSiblings(rNameOfLastSelectedObject,aRet) )
422 //if a sibling of the last selected object is clicked don't go up further
423 break;
425 SdrObject* pLastChild = pNewObj;
426 rtl::OUString aLastChildName = aRet;
427 if(!findNamedParent( pNewObj, aRet, false ))
429 //take the one found so far
430 break;
432 //if the last selected object is found don't go up further
433 //but take the last child if selection change is allowed
434 if( ObjectIdentifier::areIdenticalObjects( rNameOfLastSelectedObject, aRet ) )
436 if( bAllowMultiClickSelectionChange )
438 pNewObj = pLastChild;
439 aRet = aLastChildName;
441 else
442 rObjectToSelectIfNoDoubleClickIsFollowing = aLastChildName;
444 break;
448 //check wether the diagram was hit but not selected:
449 rtl::OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );//@todo read CID from model
450 rtl::OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) );//@todo read CID from model
451 if( aRet.equals( aPageCID ) || aRet.equals( aWallCID ) || !aRet.getLength() )
453 rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) );
454 //todo: if more than one diagram is available in future do chack the list of all diagrams here
455 SdrObject* pDiagram = rDrawViewWrapper.getNamedSdrObject( aDiagramCID );
456 if( pDiagram )
458 if( rDrawViewWrapper.IsObjectHit( pDiagram, rMPos ) )
460 aRet = aDiagramCID;
461 pNewObj = pDiagram;
466 DBG_ASSERT(pNewObj && aRet.getLength(),"somehow lost selected object");
469 return aRet;
473 // static
474 ::rtl::OUString SelectionHelper::getHitObjectCID(
475 const Point& rMPos,
476 DrawViewWrapper& rDrawViewWrapper,
477 bool bGetDiagramInsteadOf_Wall )
479 // //- solar mutex
480 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
481 rtl::OUString aRet;
483 SdrObject* pNewObj = rDrawViewWrapper.getHitObject(rMPos);
484 aRet = lcl_getObjectName( pNewObj );//name of pNewObj
486 //ignore handle only objects for hit test
487 while( pNewObj && aRet.match(C2U("HandlesOnly")) )
489 pNewObj->SetMarkProtect(true);
490 pNewObj = rDrawViewWrapper.getHitObject(rMPos);
491 aRet = lcl_getObjectName( pNewObj );
494 //accept only named objects while searching for the object to select
495 if( !findNamedParent( pNewObj, aRet, true ) )
497 aRet = ::rtl::OUString();
500 rtl::OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) );//@todo read CID from model
501 //get page when nothing was hit
502 if( aRet.getLength() == 0 && !pNewObj )
504 aRet = aPageCID;
507 //get diagram instead wall or page if hit inside diagram
508 if( aRet.getLength() != 0 )
510 if( aRet.equals( aPageCID ) )
512 rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) );
513 //todo: if more than one diagram is available in future do chack the list of all diagrams here
514 SdrObject* pDiagram = rDrawViewWrapper.getNamedSdrObject( aDiagramCID );
515 if( pDiagram )
517 if( rDrawViewWrapper.IsObjectHit( pDiagram, rMPos ) )
519 aRet = aDiagramCID;
523 else if( bGetDiagramInsteadOf_Wall )
525 rtl::OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, rtl::OUString() ) );//@todo read CID from model
527 if( aRet.equals( aWallCID ) )
529 rtl::OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) );
530 aRet = aDiagramCID;
535 return aRet;
536 // \\- solar mutex
539 //static
540 bool SelectionHelper::isRotateableObject( const ::rtl::OUString& rCID
541 , const uno::Reference< frame::XModel >& xChartModel )
543 if( !ObjectIdentifier::isRotateableObject( rCID ) )
544 return false;
546 sal_Int32 nDimensionCount = DiagramHelper::getDimension( ChartModelHelper::findDiagram( xChartModel ) );
548 if( nDimensionCount == 3 )
549 return true;
550 return false;
553 SelectionHelper::SelectionHelper( SdrObject* pSelectedObj )
554 : m_pSelectedObj( pSelectedObj )
558 SelectionHelper::~SelectionHelper()
562 //virtual
563 bool SelectionHelper::getFrameDragSingles()
565 bool bFrameDragSingles = true;//true == green == surrounding handles
566 if( m_pSelectedObj && m_pSelectedObj->ISA(E3dObject) )
567 bFrameDragSingles = false;
568 return bFrameDragSingles;
571 //static
572 SdrObject* SelectionHelper::getMarkHandlesObject( SdrObject* pObj )
574 if(!pObj)
575 return 0;
576 rtl::OUString aName( lcl_getObjectName( pObj ) );
577 if( aName.match(C2U("MarkHandles")) || aName.match(C2U("HandlesOnly")) )
578 return pObj;
579 if( aName.getLength() )//dont't get the markhandles of a different object
580 return 0;
582 //search for a child with name "MarkHandles" or "HandlesOnly"
583 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
584 SdrObjList* pSubList = pObj->GetSubList();
585 if(pSubList)
587 SdrObjListIter aIterator(*pSubList, IM_FLAT);
588 while (aIterator.IsMore())
590 SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
591 if( pMarkHandles )
592 return pMarkHandles;
595 return 0;
598 SdrObject* SelectionHelper::getObjectToMark()
600 //return the selected object itself
601 //or a specific other object if that exsists
602 SdrObject* pObj = m_pSelectedObj;
603 m_pMarkObj = pObj;
605 //search for a child with name "MarkHandles" or "HandlesOnly"
606 if(pObj)
608 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
609 SdrObjList* pSubList = pObj->GetSubList();
610 if(pSubList)
612 SdrObjListIter aIterator(*pSubList, IM_FLAT);
613 while (aIterator.IsMore())
615 SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
616 if( pMarkHandles )
618 m_pMarkObj = pMarkHandles;
619 break;
624 return m_pMarkObj;
627 //static
628 E3dScene* SelectionHelper::getSceneToRotate( SdrObject* pObj )
630 //search wether the object or one of its children is a 3D object
631 //if so, return the accessory 3DScene
633 E3dObject* pRotateable = 0;
635 if(pObj)
637 pRotateable = dynamic_cast<E3dObject*>(pObj);
638 if( !pRotateable )
640 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
641 SdrObjList* pSubList = pObj->GetSubList();
642 if(pSubList)
644 SdrObjListIter aIterator(*pSubList, IM_DEEPWITHGROUPS);
645 while( aIterator.IsMore() && !pRotateable )
647 SdrObject* pSubObj = aIterator.Next();
648 pRotateable = dynamic_cast<E3dObject*>(pSubObj);
654 E3dScene* pScene = 0;
655 if(pRotateable)
657 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
658 pScene = pRotateable->GetScene();
660 return pScene;
664 //virtual
665 bool SelectionHelper::getMarkHandles( SdrHdlList& rHdlList )
667 ::vos::OGuard aSolarGuard( Application::GetSolarMutex());
669 //@todo -> more flexible handle creation
670 //2 scenarios possible:
671 //1. add an additional invisible shape as a child to the selected object
672 //this child needs to be named somehow and handles need to be generated therefrom ...
673 //or 2. offer a central service per view where renderer and so can register for handle creation for a special shape
674 //.. or 3. feature from drawinglayer to create handles for each shape ... (bad performance ... ?) ?
676 //scenario 1 is now used:
677 //if a child with name MarkHandles exsists
678 //this child is marked instead of the logical selected object
681 //if a special mark object was found
682 //that object should be used for marking only
683 if( m_pMarkObj != m_pSelectedObj)
684 return false;
686 //if a special mark object was found
687 //that object should be used to create handles from
688 if( m_pMarkObj && m_pMarkObj != m_pSelectedObj)
690 rHdlList.Clear();
691 if( m_pMarkObj->ISA(SdrPathObj) )
693 //if th object is a polygon
694 //from each point a handle is generated
695 const ::basegfx::B2DPolyPolygon& rPolyPolygon = ((SdrPathObj*)m_pMarkObj)->GetPathPoly();
696 for( sal_uInt32 nN = 0L; nN < rPolyPolygon.count(); nN++)
698 const ::basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nN));
699 for( sal_uInt32 nM = 0L; nM < aPolygon.count(); nM++)
701 const ::basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(nM));
702 SdrHdl* pHdl = new SdrHdl(Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())), HDL_POLY);
703 rHdlList.AddHdl(pHdl);
706 return true;
708 else
709 return false; //use the special MarkObject for marking
712 //@todo:
713 //add and document good marking defaults ...
715 rHdlList.Clear();
717 SdrObject* pObj = m_pSelectedObj;
718 if(!pObj)
719 return false;
720 SdrObjList* pSubList = pObj->GetSubList();
721 if( !pSubList )//no group object !pObj->IsGroupObject()
722 return false;
724 rtl::OUString aName( lcl_getObjectName( pObj ) );
725 ObjectType eObjectType( ObjectIdentifier::getObjectType( aName ) );
726 if( OBJECTTYPE_DATA_POINT == eObjectType
727 || OBJECTTYPE_DATA_LABEL == eObjectType
728 || OBJECTTYPE_LEGEND_ENTRY == eObjectType
729 || OBJECTTYPE_AXIS_UNITLABEL == eObjectType )
731 return false;
734 SdrObjListIter aIterator(*pSubList, IM_FLAT);
736 while (aIterator.IsMore())
738 SdrObject* pSubObj = aIterator.Next();
739 if( OBJECTTYPE_DATA_SERIES == eObjectType )
741 rtl::OUString aSubName( lcl_getObjectName( pSubObj ) );
742 ObjectType eSubObjectType( ObjectIdentifier::getObjectType( aSubName ) );
743 if( eSubObjectType!=OBJECTTYPE_DATA_POINT )
744 return false;
747 Point aPos = pSubObj->GetCurrentBoundRect().Center();
748 SdrHdl* pHdl = new SdrHdl(aPos,HDL_POLY);
749 rHdlList.AddHdl(pHdl);
751 return true;
754 //.............................................................................
755 } //namespace chart
756 //.............................................................................