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