6fc92adb8f
Change-Id: Ib0a06d94f8b51cce1f29f20d1c00d54be939c076
659 lines
22 KiB
C++
659 lines
22 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include "SelectionHelper.hxx"
|
|
#include "ObjectIdentifier.hxx"
|
|
#include "macros.hxx"
|
|
#include "DiagramHelper.hxx"
|
|
#include "ChartModelHelper.hxx"
|
|
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svditer.hxx>
|
|
#include "svx/obj3d.hxx"
|
|
#include <svx/svdopath.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <osl/mutex.hxx>
|
|
#include <basegfx/point/b2dpoint.hxx>
|
|
#include <com/sun/star/beans/XPropertySet.hpp>
|
|
|
|
namespace chart
|
|
{
|
|
using namespace ::com::sun::star;
|
|
|
|
namespace
|
|
{
|
|
|
|
OUString lcl_getObjectName( SdrObject* pObj )
|
|
{
|
|
if(pObj)
|
|
return pObj->GetName();
|
|
return OUString();
|
|
}
|
|
|
|
void impl_selectObject( SdrObject* pObjectToSelect, DrawViewWrapper& rDrawViewWrapper )
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
|
|
if(pObjectToSelect)
|
|
{
|
|
SelectionHelper aSelectionHelper( pObjectToSelect );
|
|
SdrObject* pMarkObj = aSelectionHelper.getObjectToMark();
|
|
rDrawViewWrapper.setMarkHandleProvider(&aSelectionHelper);
|
|
rDrawViewWrapper.MarkObject(pMarkObj);
|
|
rDrawViewWrapper.setMarkHandleProvider(nullptr);
|
|
}
|
|
}
|
|
|
|
}//anonymous namespace
|
|
|
|
bool Selection::hasSelection()
|
|
{
|
|
return m_aSelectedOID.isValid();
|
|
}
|
|
|
|
OUString Selection::getSelectedCID()
|
|
{
|
|
return m_aSelectedOID.getObjectCID();
|
|
}
|
|
|
|
uno::Reference< drawing::XShape > Selection::getSelectedAdditionalShape()
|
|
{
|
|
return m_aSelectedOID.getAdditionalShape();
|
|
}
|
|
|
|
bool Selection::setSelection( const OUString& rCID )
|
|
{
|
|
if ( !rCID.equals( m_aSelectedOID.getObjectCID() ) )
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier( rCID );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Selection::setSelection( const uno::Reference< drawing::XShape >& xShape )
|
|
{
|
|
if ( !( xShape == m_aSelectedOID.getAdditionalShape() ) )
|
|
{
|
|
clearSelection();
|
|
m_aSelectedOID = ObjectIdentifier( xShape );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Selection::clearSelection()
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier();
|
|
m_aSelectedOID_beforeMouseDown = ObjectIdentifier();
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
|
|
}
|
|
|
|
bool Selection::maybeSwitchSelectionAfterSingleClickWasEnsured()
|
|
{
|
|
if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid()
|
|
&& m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing != m_aSelectedOID )
|
|
{
|
|
m_aSelectedOID = m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing;
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Selection::resetPossibleSelectionAfterSingleClickWasEnsured()
|
|
{
|
|
if ( m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() )
|
|
{
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
|
|
}
|
|
}
|
|
|
|
void Selection::remindSelectionBeforeMouseDown()
|
|
{
|
|
m_aSelectedOID_beforeMouseDown = m_aSelectedOID;
|
|
}
|
|
|
|
bool Selection::isSelectionDifferentFromBeforeMouseDown() const
|
|
{
|
|
return ( m_aSelectedOID != m_aSelectedOID_beforeMouseDown );
|
|
}
|
|
|
|
void Selection::applySelection( DrawViewWrapper* pDrawViewWrapper )
|
|
{
|
|
if( pDrawViewWrapper )
|
|
{
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
pDrawViewWrapper->UnmarkAll();
|
|
}
|
|
SdrObject* pObjectToSelect = nullptr;
|
|
if ( m_aSelectedOID.isAutoGeneratedObject() )
|
|
{
|
|
pObjectToSelect = pDrawViewWrapper->getNamedSdrObject( m_aSelectedOID.getObjectCID() );
|
|
}
|
|
else if( m_aSelectedOID.isAdditionalShape() )
|
|
{
|
|
pObjectToSelect = DrawViewWrapper::getSdrObject( m_aSelectedOID.getAdditionalShape() );
|
|
}
|
|
|
|
impl_selectObject( pObjectToSelect, *pDrawViewWrapper );
|
|
}
|
|
}
|
|
|
|
void Selection::adaptSelectionToNewPos( const Point& rMousePos, DrawViewWrapper* pDrawViewWrapper
|
|
, bool bIsRightMouse, bool bWaitingForDoubleClick )
|
|
{
|
|
if( pDrawViewWrapper )
|
|
{
|
|
//do not toggle multiclick selection if right clicked on the selected object or waiting for double click
|
|
bool bAllowMultiClickSelectionChange = !bIsRightMouse && !bWaitingForDoubleClick;
|
|
|
|
ObjectIdentifier aLastSelectedObject( m_aSelectedOID );
|
|
|
|
SolarMutexGuard aSolarGuard;
|
|
|
|
//bAllowMultiClickSelectionChange==true -> a second click on the same object can lead to a changed selection (e.g. series -> single data point)
|
|
|
|
//get object to select:
|
|
{
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
|
|
|
|
//the search for the object to select starts with the hit object deepest in the grouping hierarchy (a leaf in the tree)
|
|
//further we travel along the grouping hierarchy from child to parent
|
|
SdrObject* pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
|
|
m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) );//name of pNewObj
|
|
|
|
//ignore handle only objects for hit test
|
|
while( pNewObj && m_aSelectedOID.getObjectCID().match( "HandlesOnly" ) )
|
|
{
|
|
pNewObj->SetMarkProtect(true);
|
|
pNewObj = pDrawViewWrapper->getHitObject(rMousePos);
|
|
m_aSelectedOID = ObjectIdentifier( lcl_getObjectName( pNewObj ) );
|
|
}
|
|
|
|
//accept only named objects while searching for the object to select
|
|
//this call may change m_aSelectedOID
|
|
if ( SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, true ) )
|
|
{
|
|
//if the so far found object is a multi click object further steps are necessary
|
|
while( ObjectIdentifier::isMultiClickObject( m_aSelectedOID.getObjectCID() ) )
|
|
{
|
|
bool bSameObjectAsLastSelected = ( aLastSelectedObject == m_aSelectedOID );
|
|
if( bSameObjectAsLastSelected )
|
|
{
|
|
//if the same child is clicked again don't go up further
|
|
break;
|
|
}
|
|
if ( ObjectIdentifier::areSiblings( aLastSelectedObject.getObjectCID(), m_aSelectedOID.getObjectCID() ) )
|
|
{
|
|
//if a sibling of the last selected object is clicked don't go up further
|
|
break;
|
|
}
|
|
ObjectIdentifier aLastChild = m_aSelectedOID;
|
|
if ( !SelectionHelper::findNamedParent( pNewObj, m_aSelectedOID, false ) )
|
|
{
|
|
//take the one found so far
|
|
break;
|
|
}
|
|
//if the last selected object is found don't go up further
|
|
//but take the last child if selection change is allowed
|
|
if ( aLastSelectedObject == m_aSelectedOID )
|
|
{
|
|
if( bAllowMultiClickSelectionChange )
|
|
{
|
|
m_aSelectedOID = aLastChild;
|
|
}
|
|
else
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = aLastChild;
|
|
break;
|
|
}
|
|
}
|
|
|
|
OSL_ENSURE(m_aSelectedOID.isValid(), "somehow lost selected object");
|
|
}
|
|
else
|
|
{
|
|
//maybe an additional shape was hit
|
|
if ( pNewObj )
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier( uno::Reference< drawing::XShape >( pNewObj->getUnoShape(), uno::UNO_QUERY ) );
|
|
}
|
|
else
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier();
|
|
}
|
|
}
|
|
|
|
if ( !m_aSelectedOID.isAdditionalShape() )
|
|
{
|
|
OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );//@todo read CID from model
|
|
|
|
if ( !m_aSelectedOID.isAutoGeneratedObject() )
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier( aPageCID );
|
|
}
|
|
|
|
//check whether the diagram was hit but not selected (e.g. because it has no filling):
|
|
OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) );
|
|
OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
|
|
bool bBackGroundHit = m_aSelectedOID.getObjectCID().equals( aPageCID ) || m_aSelectedOID.getObjectCID().equals( aWallCID ) || !m_aSelectedOID.isAutoGeneratedObject();
|
|
if( bBackGroundHit )
|
|
{
|
|
//todo: if more than one diagram is available in future do check the list of all diagrams here
|
|
SdrObject* pDiagram = pDrawViewWrapper->getNamedSdrObject( aDiagramCID );
|
|
if( pDiagram )
|
|
{
|
|
if( DrawViewWrapper::IsObjectHit( pDiagram, rMousePos ) )
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier( aDiagramCID );
|
|
}
|
|
}
|
|
}
|
|
//check whether the legend was hit but not selected (e.g. because it has no filling):
|
|
if( bBackGroundHit || m_aSelectedOID.getObjectCID().equals( aDiagramCID ) )
|
|
{
|
|
OUString aLegendCID( ObjectIdentifier::createClassifiedIdentifierForParticle( ObjectIdentifier::createParticleForLegend(nullptr,nullptr) ) );//@todo read CID from model
|
|
SdrObject* pLegend = pDrawViewWrapper->getNamedSdrObject( aLegendCID );
|
|
if( pLegend )
|
|
{
|
|
if( DrawViewWrapper::IsObjectHit( pLegend, rMousePos ) )
|
|
{
|
|
m_aSelectedOID = ObjectIdentifier( aLegendCID );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( bIsRightMouse && m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing.isValid() )
|
|
{
|
|
m_aSelectedOID_selectOnlyIfNoDoubleClickIsFollowing = ObjectIdentifier();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Selection::isResizeableObjectSelected()
|
|
{
|
|
ObjectType eObjectType = m_aSelectedOID.getObjectType();
|
|
switch( eObjectType )
|
|
{
|
|
case OBJECTTYPE_DIAGRAM:
|
|
case OBJECTTYPE_DIAGRAM_WALL:
|
|
case OBJECTTYPE_SHAPE:
|
|
case OBJECTTYPE_LEGEND:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool Selection::isRotateableObjectSelected( const uno::Reference< frame::XModel >& xChartModel )
|
|
{
|
|
return SelectionHelper::isRotateableObject( m_aSelectedOID.getObjectCID(), xChartModel );
|
|
}
|
|
|
|
bool Selection::isDragableObjectSelected()
|
|
{
|
|
return m_aSelectedOID.isDragableObject();
|
|
}
|
|
|
|
bool Selection::isAdditionalShapeSelected() const
|
|
{
|
|
return m_aSelectedOID.isAdditionalShape();
|
|
}
|
|
|
|
bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject
|
|
, OUString& rOutName
|
|
, bool bGivenObjectMayBeResult )
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
//find the deepest named group
|
|
SdrObject* pObj = pInOutObject;
|
|
OUString aName;
|
|
if( bGivenObjectMayBeResult )
|
|
aName = lcl_getObjectName( pObj );
|
|
|
|
while( pObj && !ObjectIdentifier::isCID( aName ) )
|
|
{
|
|
SdrObjList* pObjList = pObj->GetObjList();
|
|
if( !pObjList )
|
|
return false;
|
|
SdrObject* pOwner = pObjList->GetOwnerObj();
|
|
if( !pOwner )
|
|
return false;
|
|
pObj = pOwner;
|
|
aName = lcl_getObjectName( pObj );
|
|
}
|
|
|
|
if(!pObj)
|
|
return false;
|
|
if(aName.isEmpty())
|
|
return false;
|
|
|
|
pInOutObject = pObj;
|
|
rOutName = aName;
|
|
return true;
|
|
}
|
|
|
|
bool SelectionHelper::findNamedParent( SdrObject*& pInOutObject
|
|
, ObjectIdentifier& rOutObject
|
|
, bool bGivenObjectMayBeResult )
|
|
{
|
|
OUString aName;
|
|
if ( findNamedParent( pInOutObject, aName, bGivenObjectMayBeResult ) )
|
|
{
|
|
rOutObject = ObjectIdentifier( aName );
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SelectionHelper::isDragableObjectHitTwice( const Point& rMPos
|
|
, const OUString& rNameOfSelectedObject
|
|
, const DrawViewWrapper& rDrawViewWrapper )
|
|
{
|
|
if(rNameOfSelectedObject.isEmpty())
|
|
return false;
|
|
if( !ObjectIdentifier::isDragableObject(rNameOfSelectedObject) )
|
|
return false;
|
|
SolarMutexGuard aSolarGuard;
|
|
SdrObject* pObj = rDrawViewWrapper.getNamedSdrObject( rNameOfSelectedObject );
|
|
if( !DrawViewWrapper::IsObjectHit( pObj, rMPos ) )
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
OUString SelectionHelper::getHitObjectCID(
|
|
const Point& rMPos,
|
|
DrawViewWrapper& rDrawViewWrapper,
|
|
bool bGetDiagramInsteadOf_Wall )
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
OUString aRet;
|
|
|
|
SdrObject* pNewObj = rDrawViewWrapper.getHitObject(rMPos);
|
|
aRet = lcl_getObjectName( pNewObj );//name of pNewObj
|
|
|
|
//ignore handle only objects for hit test
|
|
while( pNewObj && aRet.match("HandlesOnly") )
|
|
{
|
|
pNewObj->SetMarkProtect(true);
|
|
pNewObj = rDrawViewWrapper.getHitObject(rMPos);
|
|
aRet = lcl_getObjectName( pNewObj );
|
|
}
|
|
|
|
//accept only named objects while searching for the object to select
|
|
if( !findNamedParent( pNewObj, aRet, true ) )
|
|
{
|
|
aRet.clear();
|
|
}
|
|
|
|
OUString aPageCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) );//@todo read CID from model
|
|
//get page when nothing was hit
|
|
if( aRet.isEmpty() && !pNewObj )
|
|
{
|
|
aRet = aPageCID;
|
|
}
|
|
|
|
//get diagram instead wall or page if hit inside diagram
|
|
if( !aRet.isEmpty() )
|
|
{
|
|
if( aRet.equals( aPageCID ) )
|
|
{
|
|
OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) );
|
|
//todo: if more than one diagram is available in future do check the list of all diagrams here
|
|
SdrObject* pDiagram = rDrawViewWrapper.getNamedSdrObject( aDiagramCID );
|
|
if( pDiagram )
|
|
{
|
|
if( DrawViewWrapper::IsObjectHit( pDiagram, rMPos ) )
|
|
{
|
|
aRet = aDiagramCID;
|
|
}
|
|
}
|
|
}
|
|
else if( bGetDiagramInsteadOf_Wall )
|
|
{
|
|
OUString aWallCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM_WALL, OUString() ) );//@todo read CID from model
|
|
|
|
if( aRet.equals( aWallCID ) )
|
|
{
|
|
OUString aDiagramCID = ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, OUString::number( 0 ) );
|
|
aRet = aDiagramCID;
|
|
}
|
|
}
|
|
}
|
|
|
|
return aRet;
|
|
// \\- solar mutex
|
|
}
|
|
|
|
bool SelectionHelper::isRotateableObject( const OUString& rCID
|
|
, const uno::Reference< frame::XModel >& xChartModel )
|
|
{
|
|
if( !ObjectIdentifier::isRotateableObject( rCID ) )
|
|
return false;
|
|
|
|
sal_Int32 nDimensionCount = DiagramHelper::getDimension( ChartModelHelper::findDiagram( xChartModel ) );
|
|
|
|
if( nDimensionCount == 3 )
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
SelectionHelper::SelectionHelper( SdrObject* pSelectedObj )
|
|
: m_pSelectedObj( pSelectedObj ), m_pMarkObj(nullptr)
|
|
{
|
|
|
|
}
|
|
SelectionHelper::~SelectionHelper()
|
|
{
|
|
}
|
|
|
|
bool SelectionHelper::getFrameDragSingles()
|
|
{
|
|
bool bFrameDragSingles = true;//true == green == surrounding handles
|
|
if( m_pSelectedObj && dynamic_cast<const E3dObject*>( m_pSelectedObj) != nullptr )
|
|
bFrameDragSingles = false;
|
|
return bFrameDragSingles;
|
|
}
|
|
|
|
SdrObject* SelectionHelper::getMarkHandlesObject( SdrObject* pObj )
|
|
{
|
|
if(!pObj)
|
|
return nullptr;
|
|
OUString aName( lcl_getObjectName( pObj ) );
|
|
if( aName.match("MarkHandles") || aName.match("HandlesOnly") )
|
|
return pObj;
|
|
if( !aName.isEmpty() )//don't get the markhandles of a different object
|
|
return nullptr;
|
|
|
|
//search for a child with name "MarkHandles" or "HandlesOnly"
|
|
SolarMutexGuard aSolarGuard;
|
|
SdrObjList* pSubList = pObj->GetSubList();
|
|
if(pSubList)
|
|
{
|
|
SdrObjListIter aIterator(*pSubList, SdrIterMode::Flat);
|
|
while (aIterator.IsMore())
|
|
{
|
|
SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
|
|
if( pMarkHandles )
|
|
return pMarkHandles;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
SdrObject* SelectionHelper::getObjectToMark()
|
|
{
|
|
//return the selected object itself
|
|
//or a specific other object if that exsists
|
|
SdrObject* pObj = m_pSelectedObj;
|
|
m_pMarkObj = pObj;
|
|
|
|
//search for a child with name "MarkHandles" or "HandlesOnly"
|
|
if(pObj)
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
SdrObjList* pSubList = pObj->GetSubList();
|
|
if(pSubList)
|
|
{
|
|
SdrObjListIter aIterator(*pSubList, SdrIterMode::Flat);
|
|
while (aIterator.IsMore())
|
|
{
|
|
SdrObject* pMarkHandles = SelectionHelper::getMarkHandlesObject( aIterator.Next() );
|
|
if( pMarkHandles )
|
|
{
|
|
m_pMarkObj = pMarkHandles;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return m_pMarkObj;
|
|
}
|
|
|
|
E3dScene* SelectionHelper::getSceneToRotate( SdrObject* pObj )
|
|
{
|
|
//search whether the object or one of its children is a 3D object
|
|
//if so, return the accessory 3DScene
|
|
|
|
E3dObject* pRotateable = nullptr;
|
|
|
|
if(pObj)
|
|
{
|
|
pRotateable = dynamic_cast<E3dObject*>(pObj);
|
|
if( !pRotateable )
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
SdrObjList* pSubList = pObj->GetSubList();
|
|
if(pSubList)
|
|
{
|
|
SdrObjListIter aIterator(*pSubList, SdrIterMode::DeepWithGroups);
|
|
while( aIterator.IsMore() && !pRotateable )
|
|
{
|
|
SdrObject* pSubObj = aIterator.Next();
|
|
pRotateable = dynamic_cast<E3dObject*>(pSubObj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
E3dScene* pScene = nullptr;
|
|
if(pRotateable)
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
pScene = pRotateable->GetScene();
|
|
}
|
|
return pScene;
|
|
|
|
}
|
|
|
|
bool SelectionHelper::getMarkHandles( SdrHdlList& rHdlList )
|
|
{
|
|
SolarMutexGuard aSolarGuard;
|
|
|
|
//@todo -> more flexible handle creation
|
|
//2 scenarios possible:
|
|
//1. add an additional invisible shape as a child to the selected object
|
|
//this child needs to be named somehow and handles need to be generated therefrom ...
|
|
//or 2. offer a central service per view where renderer and so can register for handle creation for a special shape
|
|
//.. or 3. feature from drawinglayer to create handles for each shape ... (bad performance ... ?) ?
|
|
|
|
//scenario 1 is now used:
|
|
//if a child with name MarkHandles exsists
|
|
//this child is marked instead of the logical selected object
|
|
|
|
/*
|
|
//if a special mark object was found
|
|
//that object should be used for marking only
|
|
if( m_pMarkObj != m_pSelectedObj)
|
|
return false;
|
|
*/
|
|
//if a special mark object was found
|
|
//that object should be used to create handles from
|
|
if( m_pMarkObj && m_pMarkObj != m_pSelectedObj)
|
|
{
|
|
rHdlList.Clear();
|
|
if( dynamic_cast<const SdrPathObj*>( m_pMarkObj) != nullptr )
|
|
{
|
|
//if th object is a polygon
|
|
//from each point a handle is generated
|
|
const ::basegfx::B2DPolyPolygon& rPolyPolygon = static_cast<SdrPathObj*>(m_pMarkObj)->GetPathPoly();
|
|
for( sal_uInt32 nN = 0L; nN < rPolyPolygon.count(); nN++)
|
|
{
|
|
const ::basegfx::B2DPolygon aPolygon(rPolyPolygon.getB2DPolygon(nN));
|
|
for( sal_uInt32 nM = 0L; nM < aPolygon.count(); nM++)
|
|
{
|
|
const ::basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(nM));
|
|
SdrHdl* pHdl = new SdrHdl(Point(basegfx::fround(aPoint.getX()), basegfx::fround(aPoint.getY())), SdrHdlKind::Poly);
|
|
rHdlList.AddHdl(pHdl);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
return false; //use the special MarkObject for marking
|
|
}
|
|
|
|
//@todo:
|
|
//add and document good marking defaults ...
|
|
|
|
rHdlList.Clear();
|
|
|
|
SdrObject* pObj = m_pSelectedObj;
|
|
if(!pObj)
|
|
return false;
|
|
SdrObjList* pSubList = pObj->GetSubList();
|
|
if( !pSubList )//no group object !pObj->IsGroupObject()
|
|
return false;
|
|
|
|
OUString aName( lcl_getObjectName( pObj ) );
|
|
ObjectType eObjectType( ObjectIdentifier::getObjectType( aName ) );
|
|
if( OBJECTTYPE_DATA_POINT == eObjectType
|
|
|| OBJECTTYPE_DATA_LABEL == eObjectType
|
|
|| OBJECTTYPE_LEGEND_ENTRY == eObjectType
|
|
|| OBJECTTYPE_AXIS_UNITLABEL == eObjectType )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
SdrObjListIter aIterator(*pSubList, SdrIterMode::Flat);
|
|
|
|
while (aIterator.IsMore())
|
|
{
|
|
SdrObject* pSubObj = aIterator.Next();
|
|
if( OBJECTTYPE_DATA_SERIES == eObjectType )
|
|
{
|
|
OUString aSubName( lcl_getObjectName( pSubObj ) );
|
|
ObjectType eSubObjectType( ObjectIdentifier::getObjectType( aSubName ) );
|
|
if( eSubObjectType!=OBJECTTYPE_DATA_POINT )
|
|
return false;
|
|
}
|
|
|
|
Point aPos = pSubObj->GetCurrentBoundRect().Center();
|
|
SdrHdl* pHdl = new SdrHdl(aPos,SdrHdlKind::Poly);
|
|
rHdlList.AddHdl(pHdl);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} //namespace chart
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|