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