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 "ObjectIdentifier.hxx"
21 : #include "macros.hxx"
22 : #include "TitleHelper.hxx"
23 : #include "ChartModelHelper.hxx"
24 : #include "AxisHelper.hxx"
25 : #include "servicenames_charttypes.hxx"
26 : #include "DiagramHelper.hxx"
27 : #include "AxisIndexDefines.hxx"
28 : #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp>
29 : #include <com/sun/star/chart2/XChartDocument.hpp>
30 : #include <com/sun/star/chart2/XChartTypeContainer.hpp>
31 : #include <com/sun/star/chart2/XDataSeriesContainer.hpp>
32 : #include <com/sun/star/chart2/XAxis.hpp>
33 : #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
34 :
35 : // header for define DBG_ASSERT
36 : #include <tools/debug.hxx>
37 : #include <comphelper/InlineContainer.hxx>
38 :
39 : #include <rtl/ustrbuf.hxx>
40 :
41 : namespace chart
42 : {
43 : using namespace ::com::sun::star;
44 : using namespace ::com::sun::star::chart2;
45 :
46 : using ::com::sun::star::uno::Reference;
47 : using ::com::sun::star::uno::Any;
48 :
49 0 : static OUString m_aMultiClick( "MultiClick" );
50 0 : static OUString m_aDragMethodEquals( "DragMethod=" );
51 0 : static OUString m_aDragParameterEquals( "DragParameter=" );
52 0 : static OUString m_aProtocol( "CID/" );
53 0 : static OUString m_aEmptyString;
54 0 : static OUString m_aPieSegmentDragMethodServiceName( "PieSegmentDraging" );
55 :
56 : namespace
57 : {
58 :
59 0 : OUString lcl_createClassificationStringForType( ObjectType eObjectType
60 : , const OUString& rDragMethodServiceName
61 : , const OUString& rDragParameterString
62 : )
63 : {
64 0 : OUStringBuffer aRet;
65 0 : switch( eObjectType )
66 : {
67 : //these object types are all selected only after their parents was selected before
68 : case OBJECTTYPE_LEGEND_ENTRY: //parent is intended to be OBJECTTYPE_LEGEND
69 : case OBJECTTYPE_DATA_POINT: //parent is intended to be OBJECTTYPE_DATA_SERIES
70 : case OBJECTTYPE_DATA_LABEL: //parent is intended to be OBJECTTYPE_DATA_LABELS
71 : case OBJECTTYPE_DATA_ERRORS_X: //parent is intended to be OBJECTTYPE_DATA_ERRORS
72 : case OBJECTTYPE_DATA_ERRORS_Y: //parent is intended to be OBJECTTYPE_DATA_ERRORS
73 : case OBJECTTYPE_DATA_ERRORS_Z: //parent is intended to be OBJECTTYPE_DATA_ERRORS
74 0 : aRet=m_aMultiClick;
75 : default:
76 : ;//empty string
77 : }
78 0 : if( !rDragMethodServiceName.isEmpty() )
79 : {
80 0 : if( !aRet.isEmpty() )
81 0 : aRet.appendAscii(":");
82 0 : aRet.append( m_aDragMethodEquals );
83 0 : aRet.append( rDragMethodServiceName );
84 :
85 0 : if( !rDragParameterString.isEmpty() )
86 : {
87 0 : if( !aRet.isEmpty() )
88 0 : aRet.appendAscii(":");
89 0 : aRet.append( m_aDragParameterEquals );
90 0 : aRet.append( rDragParameterString );
91 : }
92 : }
93 0 : return aRet.makeStringAndClear();
94 : }
95 :
96 : typedef ::comphelper::MakeMap< TitleHelper::eTitleType, OUString > tTitleMap;
97 0 : const tTitleMap& lcl_getTitleMap()
98 : {
99 : //maps the title type to the ParentParticle for that title
100 : static tTitleMap m_aTitleMap = tTitleMap
101 : ( TitleHelper::MAIN_TITLE, "" )
102 0 : ( TitleHelper::SUB_TITLE, "D=0" )
103 0 : ( TitleHelper::X_AXIS_TITLE, "D=0:CS=0:Axis=0,0" )
104 0 : ( TitleHelper::Y_AXIS_TITLE, "D=0:CS=0:Axis=1,0" )
105 0 : ( TitleHelper::Z_AXIS_TITLE, "D=0:CS=0:Axis=2,0" )
106 0 : ( TitleHelper::SECONDARY_X_AXIS_TITLE, "D=0:CS=0:Axis=0,1" )
107 0 : ( TitleHelper::SECONDARY_Y_AXIS_TITLE, "D=0:CS=0:Axis=1,1" )
108 : ;
109 0 : return m_aTitleMap;
110 : }
111 :
112 0 : OUString lcl_getTitleParentParticle( TitleHelper::eTitleType aTitleType )
113 : {
114 0 : OUString aRet;
115 :
116 0 : const tTitleMap& rMap = lcl_getTitleMap();
117 0 : tTitleMap::const_iterator aIt( rMap.find( aTitleType ) );
118 0 : if( aIt != rMap.end())
119 0 : aRet = (*aIt).second;
120 :
121 0 : return aRet;
122 : }
123 :
124 0 : Reference<XChartType> lcl_getFirstStockChartType( const Reference< frame::XModel >& xChartModel )
125 : {
126 0 : Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
127 0 : if(!xDiagram.is())
128 0 : return 0;
129 :
130 : //iterate through all coordinate systems
131 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
132 0 : if( !xCooSysContainer.is())
133 0 : return 0;
134 :
135 0 : uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
136 0 : for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS )
137 : {
138 : //iterate through all chart types in the current coordinate system
139 0 : Reference< XChartTypeContainer > xChartTypeContainer( aCooSysList[nCS], uno::UNO_QUERY );
140 0 : if( !xChartTypeContainer.is() )
141 0 : continue;
142 :
143 0 : uno::Sequence< Reference< XChartType > > aChartTypeList( xChartTypeContainer->getChartTypes() );
144 0 : for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT )
145 : {
146 0 : Reference< XChartType > xChartType( aChartTypeList[nT] );
147 0 : if(!xChartType.is())
148 0 : continue;
149 0 : OUString aChartType = xChartType->getChartType();
150 0 : if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK) )
151 0 : return xChartType;
152 0 : }
153 0 : }
154 0 : return 0;
155 : }
156 :
157 0 : OUString lcl_getIndexStringAfterString( const OUString& rString, const OUString& rSearchString )
158 : {
159 0 : OUStringBuffer aRet;
160 :
161 0 : sal_Int32 nIndexStart = rString.lastIndexOf( rSearchString );
162 0 : if( nIndexStart != -1 )
163 : {
164 0 : nIndexStart += rSearchString.getLength();
165 0 : sal_Int32 nIndexEnd = rString.getLength();
166 0 : sal_Int32 nNextColon = rString.indexOf( ':', nIndexStart );
167 0 : if( nNextColon != -1 )
168 0 : nIndexEnd = nNextColon;
169 0 : aRet = rString.copy(nIndexStart,nIndexEnd-nIndexStart);
170 : }
171 :
172 0 : return aRet.makeStringAndClear();
173 : }
174 :
175 0 : sal_Int32 lcl_StringToIndex( const OUString& rIndexString )
176 : {
177 0 : sal_Int32 nRet = -1;
178 0 : if( !rIndexString.isEmpty() )
179 : {
180 0 : nRet = rIndexString.toInt32();
181 0 : if( nRet < -1 )
182 0 : nRet = -1;
183 : }
184 0 : return nRet;
185 : }
186 :
187 0 : void lcl_parseCooSysIndices( sal_Int32& rnDiagram, sal_Int32& rnCooSys, const OUString& rString )
188 : {
189 0 : rnDiagram = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "D=" ) );
190 0 : rnCooSys = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "CS=" ) );
191 0 : }
192 :
193 0 : void lcl_parseAxisIndices( sal_Int32& rnDimensionIndex, sal_Int32& rnAxisIndex, const OUString& rString )
194 : {
195 0 : OUString aAxisIndexString = lcl_getIndexStringAfterString( rString, ":Axis=" );
196 0 : sal_Int32 nCharacterIndex=0;
197 0 : rnDimensionIndex = lcl_StringToIndex( aAxisIndexString.getToken( 0, ',', nCharacterIndex ) );
198 0 : rnAxisIndex = lcl_StringToIndex( aAxisIndexString.getToken( 0, ',', nCharacterIndex ) );
199 0 : }
200 :
201 0 : void lcl_parseGridIndices( sal_Int32& rnSubGridIndex, const OUString& rString )
202 : {
203 0 : rnSubGridIndex = -1;
204 0 : rnSubGridIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, ":SubGrid=" ) );
205 0 : }
206 :
207 0 : void lcl_parseSeriesIndices( sal_Int32& rnChartTypeIndex, sal_Int32& rnSeriesIndex, sal_Int32& rnPointIndex, const OUString& rString )
208 : {
209 0 : rnChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "CT=" ) );
210 0 : rnSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "Series=" ) );
211 0 : rnPointIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rString, "Point=" ) );
212 0 : }
213 :
214 0 : void lcl_getDiagramAndCooSys( const OUString& rObjectCID
215 : , const Reference< frame::XModel >& xChartModel
216 : , Reference< XDiagram >& xDiagram
217 : , Reference< XCoordinateSystem >& xCooSys )
218 : {
219 0 : sal_Int32 nDiagramIndex = -1;
220 0 : sal_Int32 nCooSysIndex = -1;
221 0 : lcl_parseCooSysIndices( nDiagramIndex, nCooSysIndex, rObjectCID );
222 0 : xDiagram = ChartModelHelper::findDiagram( xChartModel );//todo use nDiagramIndex when more than one diagram is possible in future
223 0 : if( !xDiagram.is() )
224 0 : return;
225 :
226 0 : if( nCooSysIndex > -1 )
227 : {
228 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
229 0 : if( xCooSysContainer.is() )
230 : {
231 0 : uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
232 0 : if( nCooSysIndex < aCooSysList.getLength() )
233 0 : xCooSys = aCooSysList[nCooSysIndex];
234 0 : }
235 : }
236 : }
237 :
238 : } //anonymous namespace
239 :
240 0 : ObjectIdentifier::ObjectIdentifier()
241 : :m_aObjectCID( OUString() )
242 0 : ,m_xAdditionalShape( 0 )
243 : {
244 0 : }
245 :
246 0 : ObjectIdentifier::ObjectIdentifier( const OUString& rObjectCID )
247 : :m_aObjectCID( rObjectCID )
248 0 : ,m_xAdditionalShape( 0 )
249 : {
250 0 : }
251 :
252 0 : ObjectIdentifier::ObjectIdentifier( const Reference< drawing::XShape >& rxShape )
253 : :m_aObjectCID( OUString() )
254 0 : ,m_xAdditionalShape( rxShape )
255 : {
256 0 : }
257 :
258 0 : ObjectIdentifier::ObjectIdentifier( const Any& rAny )
259 : :m_aObjectCID( OUString() )
260 0 : ,m_xAdditionalShape( 0 )
261 : {
262 0 : const uno::Type& rType = rAny.getValueType();
263 0 : if ( rType == ::getCppuType( static_cast< const OUString* >( 0 ) ) )
264 : {
265 0 : rAny >>= m_aObjectCID;
266 : }
267 0 : else if ( rType == ::getCppuType( static_cast< const Reference< drawing::XShape >* >( 0 ) ) )
268 : {
269 0 : rAny >>= m_xAdditionalShape;
270 : }
271 0 : }
272 :
273 0 : ObjectIdentifier::~ObjectIdentifier()
274 : {
275 0 : }
276 :
277 0 : ObjectIdentifier::ObjectIdentifier( const ObjectIdentifier& rOID )
278 : :m_aObjectCID( rOID.m_aObjectCID )
279 0 : ,m_xAdditionalShape( rOID.m_xAdditionalShape )
280 : {
281 :
282 0 : }
283 :
284 0 : ObjectIdentifier& ObjectIdentifier::operator=( const ObjectIdentifier& rOID )
285 : {
286 0 : m_aObjectCID = rOID.m_aObjectCID;
287 0 : m_xAdditionalShape = rOID.m_xAdditionalShape;
288 0 : return *this;
289 : }
290 :
291 0 : bool ObjectIdentifier::operator==( const ObjectIdentifier& rOID ) const
292 : {
293 0 : if ( areIdenticalObjects( m_aObjectCID, rOID.m_aObjectCID ) &&
294 0 : ( m_xAdditionalShape == rOID.m_xAdditionalShape ) )
295 : {
296 0 : return true;
297 : }
298 0 : return false;
299 : }
300 :
301 0 : bool ObjectIdentifier::operator!=( const ObjectIdentifier& rOID ) const
302 : {
303 0 : return !operator==( rOID );
304 : }
305 :
306 0 : bool ObjectIdentifier::operator<( const ObjectIdentifier& rOID ) const
307 : {
308 0 : bool bReturn = false;
309 0 : if ( !(m_aObjectCID.isEmpty() || rOID.m_aObjectCID.isEmpty()) )
310 : {
311 0 : bReturn = ( m_aObjectCID.compareTo( rOID.m_aObjectCID ) < 0 );
312 : }
313 0 : else if ( !m_aObjectCID.isEmpty() )
314 : {
315 0 : bReturn = true;
316 : }
317 0 : else if ( !rOID.m_aObjectCID.isEmpty() )
318 : {
319 0 : bReturn = false;
320 : }
321 0 : else if ( m_xAdditionalShape.is() && rOID.m_xAdditionalShape.is() )
322 : {
323 0 : bReturn = ( m_xAdditionalShape < rOID.m_xAdditionalShape );
324 : }
325 0 : return bReturn;
326 : }
327 :
328 0 : OUString ObjectIdentifier::createClassifiedIdentifierForObject(
329 : const Reference< uno::XInterface >& xObject
330 : , ChartModel& rModel)
331 : {
332 0 : OUString aRet;
333 :
334 0 : enum ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
335 0 : OUString aObjectID;
336 0 : OUString aParentParticle;
337 0 : OUString aDragMethodServiceName;
338 0 : OUString aDragParameterString;
339 :
340 : try
341 : {
342 : //title
343 0 : Reference< XTitle > xTitle( xObject, uno::UNO_QUERY );
344 0 : if( xTitle.is() )
345 : {
346 : TitleHelper::eTitleType aTitleType;
347 0 : if( TitleHelper::getTitleType( aTitleType, xTitle, rModel ) )
348 : {
349 0 : eObjectType = OBJECTTYPE_TITLE;
350 0 : aParentParticle = lcl_getTitleParentParticle( aTitleType );
351 0 : aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
352 0 : eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
353 : }
354 0 : return aRet;
355 :
356 : }
357 :
358 : //axis
359 0 : Reference< XAxis > xAxis( xObject, uno::UNO_QUERY );
360 0 : if( xAxis.is() )
361 : {
362 0 : Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, rModel.getFirstDiagram() ) );
363 0 : OUString aCooSysParticle( createParticleForCoordinateSystem( xCooSys, rModel ) );
364 0 : sal_Int32 nDimensionIndex=-1;
365 0 : sal_Int32 nAxisIndex=-1;
366 0 : AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
367 0 : OUString aAxisParticle( createParticleForAxis( nDimensionIndex, nAxisIndex ) );
368 0 : return createClassifiedIdentifierForParticles( aCooSysParticle, aAxisParticle );
369 : }
370 :
371 : //legend
372 0 : Reference< XLegend > xLegend( xObject, uno::UNO_QUERY );
373 0 : if( xLegend.is() )
374 : {
375 0 : return createClassifiedIdentifierForParticle( createParticleForLegend( xLegend, rModel ) );
376 : }
377 :
378 : //diagram
379 0 : Reference< XDiagram > xDiagram( xObject, uno::UNO_QUERY );
380 0 : if( xDiagram.is() )
381 : {
382 0 : return createClassifiedIdentifierForParticle( createParticleForDiagram( xDiagram, rModel ) );
383 0 : }
384 :
385 : //todo
386 : //XDataSeries
387 : //CooSys
388 : //charttype
389 : //datapoint?
390 : //Gridproperties
391 : }
392 0 : catch(const uno::Exception& ex)
393 : {
394 : ASSERT_EXCEPTION( ex );
395 : }
396 :
397 0 : if( eObjectType != OBJECTTYPE_UNKNOWN )
398 : {
399 0 : aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
400 0 : eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
401 : }
402 : else
403 : {
404 : OSL_FAIL("give object could not be identifed in createClassifiedIdentifierForObject");
405 : }
406 :
407 0 : return aRet;
408 : }
409 :
410 0 : OUString ObjectIdentifier::createClassifiedIdentifierForObject(
411 : const Reference< uno::XInterface >& xObject
412 : , const Reference< frame::XModel >& xChartModel )
413 : {
414 0 : OUString aRet;
415 :
416 0 : enum ObjectType eObjectType = OBJECTTYPE_UNKNOWN;
417 0 : OUString aObjectID;
418 0 : OUString aParentParticle;
419 0 : OUString aDragMethodServiceName;
420 0 : OUString aDragParameterString;
421 :
422 : try
423 : {
424 : //title
425 0 : Reference< XTitle > xTitle( xObject, uno::UNO_QUERY );
426 0 : if( xTitle.is() )
427 : {
428 : TitleHelper::eTitleType aTitleType;
429 0 : if( TitleHelper::getTitleType( aTitleType, xTitle, xChartModel ) )
430 : {
431 0 : eObjectType = OBJECTTYPE_TITLE;
432 0 : aParentParticle = lcl_getTitleParentParticle( aTitleType );
433 0 : aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
434 0 : eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
435 : }
436 0 : return aRet;
437 :
438 : }
439 :
440 : //axis
441 0 : Reference< XAxis > xAxis( xObject, uno::UNO_QUERY );
442 0 : if( xAxis.is() )
443 : {
444 0 : Reference< XCoordinateSystem > xCooSys( AxisHelper::getCoordinateSystemOfAxis( xAxis, ChartModelHelper::findDiagram( xChartModel ) ) );
445 0 : OUString aCooSysParticle( createParticleForCoordinateSystem( xCooSys, xChartModel ) );
446 0 : sal_Int32 nDimensionIndex=-1;
447 0 : sal_Int32 nAxisIndex=-1;
448 0 : AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
449 0 : OUString aAxisParticle( createParticleForAxis( nDimensionIndex, nAxisIndex ) );
450 0 : return createClassifiedIdentifierForParticles( aCooSysParticle, aAxisParticle );
451 : }
452 :
453 : //legend
454 0 : Reference< XLegend > xLegend( xObject, uno::UNO_QUERY );
455 0 : if( xLegend.is() )
456 : {
457 0 : return createClassifiedIdentifierForParticle( createParticleForLegend( xLegend, xChartModel ) );
458 : }
459 :
460 : //diagram
461 0 : Reference< XDiagram > xDiagram( xObject, uno::UNO_QUERY );
462 0 : if( xDiagram.is() )
463 : {
464 0 : return createClassifiedIdentifierForParticle( createParticleForDiagram( xDiagram, xChartModel ) );
465 0 : }
466 :
467 : //todo
468 : //XDataSeries
469 : //CooSys
470 : //charttype
471 : //datapoint?
472 : //Gridproperties
473 : }
474 0 : catch(const uno::Exception& ex)
475 : {
476 : ASSERT_EXCEPTION( ex );
477 : }
478 :
479 0 : if( eObjectType != OBJECTTYPE_UNKNOWN )
480 : {
481 0 : aRet = ObjectIdentifier::createClassifiedIdentifierWithParent(
482 0 : eObjectType, aObjectID, aParentParticle, aDragMethodServiceName, aDragParameterString );
483 : }
484 : else
485 : {
486 : OSL_FAIL("give object could not be identifed in createClassifiedIdentifierForObject");
487 : }
488 :
489 0 : return aRet;
490 : }
491 :
492 0 : OUString ObjectIdentifier::createClassifiedIdentifierForParticle(
493 : const OUString& rParticle )
494 : {
495 0 : return ObjectIdentifier::createClassifiedIdentifierForParticles( rParticle, OUString() );
496 : }
497 :
498 0 : OUString ObjectIdentifier::createClassifiedIdentifierForParticles(
499 : const OUString& rParentParticle
500 : , const OUString& rChildParticle
501 : , const OUString& rDragMethodServiceName
502 : , const OUString& rDragParameterString )
503 : {
504 0 : ObjectType eObjectType( ObjectIdentifier::getObjectType( rChildParticle ) );
505 0 : if( eObjectType == OBJECTTYPE_UNKNOWN )
506 0 : eObjectType = ObjectIdentifier::getObjectType( rParentParticle );
507 :
508 0 : OUStringBuffer aRet( m_aProtocol );
509 0 : aRet.append( lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
510 0 : if(aRet.getLength()>m_aProtocol.getLength())
511 0 : aRet.appendAscii("/");
512 :
513 0 : if(!rParentParticle.isEmpty())
514 : {
515 0 : aRet.append(rParentParticle);
516 0 : if( !rChildParticle.isEmpty() )
517 0 : aRet.appendAscii(":");
518 : }
519 0 : aRet.append(rChildParticle);
520 :
521 0 : return aRet.makeStringAndClear();
522 : }
523 :
524 0 : OUString ObjectIdentifier::createParticleForDiagram(
525 : const Reference< XDiagram >& /*xDiagram*/
526 : , ChartModel& /*xChartModel*/ )
527 : {
528 0 : static OUString aRet("D=0");
529 : //todo: if more than one diagram is implemeted, add the correct diagram index here
530 0 : return aRet;
531 : }
532 :
533 0 : OUString ObjectIdentifier::createParticleForDiagram(
534 : const Reference< XDiagram >& /*xDiagram*/
535 : , const Reference< frame::XModel >& /*xChartModel*/ )
536 : {
537 0 : static OUString aRet("D=0");
538 : //todo: if more than one diagram is implemeted, add the correct diagram index here
539 0 : return aRet;
540 : }
541 :
542 0 : OUString ObjectIdentifier::createParticleForCoordinateSystem(
543 : const Reference< XCoordinateSystem >& xCooSys
544 : , ChartModel& rModel )
545 : {
546 0 : OUStringBuffer aRet;
547 :
548 0 : Reference< XDiagram > xDiagram( rModel.getFirstDiagram() );
549 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
550 0 : if( xCooSysContainer.is() )
551 : {
552 0 : sal_Int32 nCooSysIndex = 0;
553 0 : uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
554 0 : for( ; nCooSysIndex < aCooSysList.getLength(); ++nCooSysIndex )
555 : {
556 0 : Reference< XCoordinateSystem > xCurrentCooSys( aCooSysList[nCooSysIndex] );
557 0 : if( xCooSys == xCurrentCooSys )
558 : {
559 0 : aRet = ObjectIdentifier::createParticleForDiagram( xDiagram, rModel );
560 0 : aRet.appendAscii(":CS=");
561 0 : aRet.append( OUString::number( nCooSysIndex ) );
562 0 : break;
563 : }
564 0 : }
565 : }
566 :
567 0 : return aRet.makeStringAndClear();
568 : }
569 :
570 0 : OUString ObjectIdentifier::createParticleForCoordinateSystem(
571 : const Reference< XCoordinateSystem >& xCooSys
572 : , const Reference< frame::XModel >& xChartModel )
573 : {
574 0 : OUStringBuffer aRet;
575 :
576 0 : Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
577 0 : Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY );
578 0 : if( xCooSysContainer.is() )
579 : {
580 0 : sal_Int32 nCooSysIndex = 0;
581 0 : uno::Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() );
582 0 : for( ; nCooSysIndex < aCooSysList.getLength(); ++nCooSysIndex )
583 : {
584 0 : Reference< XCoordinateSystem > xCurrentCooSys( aCooSysList[nCooSysIndex] );
585 0 : if( xCooSys == xCurrentCooSys )
586 : {
587 0 : aRet = ObjectIdentifier::createParticleForDiagram( xDiagram, xChartModel );
588 0 : aRet.appendAscii(":CS=");
589 0 : aRet.append( OUString::number( nCooSysIndex ) );
590 0 : break;
591 : }
592 0 : }
593 : }
594 :
595 0 : return aRet.makeStringAndClear();
596 : }
597 :
598 0 : OUString ObjectIdentifier::createParticleForAxis(
599 : sal_Int32 nDimensionIndex
600 : , sal_Int32 nAxisIndex )
601 : {
602 0 : OUStringBuffer aRet("Axis=");
603 :
604 0 : aRet.append( OUString::number( nDimensionIndex ) );
605 0 : aRet.appendAscii(",");
606 0 : aRet.append( OUString::number( nAxisIndex ) );
607 :
608 0 : return aRet.makeStringAndClear();
609 : }
610 :
611 0 : OUString ObjectIdentifier::createParticleForGrid(
612 : sal_Int32 nDimensionIndex
613 : , sal_Int32 nAxisIndex )
614 : {
615 0 : OUStringBuffer aRet("Axis=");
616 0 : aRet.append( OUString::number( nDimensionIndex ) );
617 0 : aRet.appendAscii(",");
618 0 : aRet.append( OUString::number( nAxisIndex ) );
619 0 : aRet.append( ":Grid=0" );
620 :
621 0 : return aRet.makeStringAndClear();
622 : }
623 :
624 0 : OUString ObjectIdentifier::createClassifiedIdentifierForGrid(
625 : const Reference< XAxis >& xAxis
626 : , const Reference< frame::XModel >& xChartModel
627 : , sal_Int32 nSubGridIndex )
628 : {
629 : //-1: main grid, 0: first subgrid etc
630 :
631 0 : OUString aAxisCID( createClassifiedIdentifierForObject( xAxis, xChartModel ) );
632 : OUString aGridCID( addChildParticle( aAxisCID
633 0 : , createChildParticleWithIndex( OBJECTTYPE_GRID, 0 ) ) );
634 0 : if( nSubGridIndex >= 0 )
635 : {
636 0 : aGridCID = addChildParticle( aGridCID
637 0 : , createChildParticleWithIndex( OBJECTTYPE_SUBGRID, 0 ) );
638 : }
639 0 : return aGridCID;
640 : }
641 :
642 0 : OUString ObjectIdentifier::createParticleForSeries(
643 : sal_Int32 nDiagramIndex, sal_Int32 nCooSysIndex
644 : , sal_Int32 nChartTypeIndex, sal_Int32 nSeriesIndex )
645 : {
646 0 : OUStringBuffer aRet;
647 :
648 0 : aRet.appendAscii("D=");
649 0 : aRet.append( OUString::number( nDiagramIndex ) );
650 0 : aRet.appendAscii(":CS=");
651 0 : aRet.append( OUString::number( nCooSysIndex ) );
652 0 : aRet.appendAscii(":CT=");
653 0 : aRet.append( OUString::number( nChartTypeIndex ) );
654 0 : aRet.appendAscii(":");
655 0 : aRet.append(getStringForType( OBJECTTYPE_DATA_SERIES ));
656 0 : aRet.appendAscii("=");
657 0 : aRet.append( OUString::number( nSeriesIndex ) );
658 :
659 0 : return aRet.makeStringAndClear();
660 : }
661 :
662 0 : OUString ObjectIdentifier::createParticleForLegend(
663 : const Reference< XLegend >& /*xLegend*/
664 : , ChartModel& rModel )
665 : {
666 0 : OUStringBuffer aRet;
667 :
668 0 : Reference< XDiagram > xDiagram( rModel.getFirstDiagram() );
669 : //todo: if more than one diagram is implemeted, find the correct diagram which is owner of the given legend
670 :
671 0 : aRet.append( ObjectIdentifier::createParticleForDiagram( xDiagram, rModel ) );
672 0 : aRet.appendAscii(":");
673 0 : aRet.append(getStringForType( OBJECTTYPE_LEGEND ));
674 0 : aRet.appendAscii("=");
675 :
676 0 : return aRet.makeStringAndClear();
677 : }
678 :
679 0 : OUString ObjectIdentifier::createParticleForLegend(
680 : const Reference< XLegend >& /*xLegend*/
681 : , const Reference< frame::XModel >& xChartModel )
682 : {
683 0 : OUStringBuffer aRet;
684 :
685 0 : Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartModel ) );
686 : //todo: if more than one diagram is implemeted, find the correct diagram which is owner of the given legend
687 :
688 0 : aRet.append( ObjectIdentifier::createParticleForDiagram( xDiagram, xChartModel ) );
689 0 : aRet.appendAscii(":");
690 0 : aRet.append(getStringForType( OBJECTTYPE_LEGEND ));
691 0 : aRet.appendAscii("=");
692 :
693 0 : return aRet.makeStringAndClear();
694 : }
695 :
696 0 : OUString ObjectIdentifier::createClassifiedIdentifier(
697 : enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_SERIES
698 : , const OUString& rParticleID )//e.g. SeriesID
699 : {
700 : return createClassifiedIdentifierWithParent(
701 0 : eObjectType, rParticleID, m_aEmptyString );
702 : }
703 :
704 0 : OUString ObjectIdentifier::createClassifiedIdentifierWithParent(
705 : enum ObjectType eObjectType //e.g. OBJECTTYPE_DATA_POINT or OBJECTTYPE_GRID
706 : , const OUString& rParticleID //e.g. Point Index or SubGrid Index
707 : , const OUString& rParentPartical //e.g. "Series=SeriesID" or "Grid=GridId"
708 : , const OUString& rDragMethodServiceName
709 : , const OUString& rDragParameterString
710 : )
711 : //, bool bIsMultiClickObject ) //e.g. true
712 : {
713 : //e.g. "MultiClick/Series=2:Point=34"
714 :
715 0 : OUStringBuffer aRet( m_aProtocol );
716 0 : aRet.append( lcl_createClassificationStringForType( eObjectType, rDragMethodServiceName, rDragParameterString ));
717 0 : if(aRet.getLength()>m_aProtocol.getLength())
718 0 : aRet.appendAscii("/");
719 0 : aRet.append(rParentPartical);
720 0 : if(!rParentPartical.isEmpty())
721 0 : aRet.appendAscii(":");
722 :
723 0 : aRet.append(getStringForType( eObjectType ));
724 0 : aRet.appendAscii("=");
725 0 : aRet.append(rParticleID);
726 :
727 0 : return aRet.makeStringAndClear();
728 : }
729 :
730 0 : const OUString& ObjectIdentifier::getPieSegmentDragMethodServiceName()
731 : {
732 0 : return m_aPieSegmentDragMethodServiceName;
733 : }
734 :
735 0 : OUString ObjectIdentifier::createPieSegmentDragParameterString(
736 : sal_Int32 nOffsetPercent
737 : , const awt::Point& rMinimumPosition
738 : , const awt::Point& rMaximumPosition )
739 : {
740 0 : OUStringBuffer aRet( OUString::number( nOffsetPercent ) );
741 0 : aRet.append( ',');
742 0 : aRet.append( OUString::number( rMinimumPosition.X ) );
743 0 : aRet.append( ',');
744 0 : aRet.append( OUString::number( rMinimumPosition.Y ) );
745 0 : aRet.append( ',');
746 0 : aRet.append( OUString::number( rMaximumPosition.X ) );
747 0 : aRet.append( ',');
748 0 : aRet.append( OUString::number( rMaximumPosition.Y ) );
749 0 : return aRet.makeStringAndClear();
750 : }
751 :
752 0 : bool ObjectIdentifier::parsePieSegmentDragParameterString(
753 : const OUString& rDragParameterString
754 : , sal_Int32& rOffsetPercent
755 : , awt::Point& rMinimumPosition
756 : , awt::Point& rMaximumPosition )
757 : {
758 0 : sal_Int32 nCharacterIndex = 0;
759 :
760 0 : OUString aValueString( rDragParameterString.getToken( 0, ',', nCharacterIndex ) );
761 0 : rOffsetPercent = aValueString.toInt32();
762 0 : if( nCharacterIndex < 0 )
763 0 : return false;
764 :
765 0 : aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
766 0 : rMinimumPosition.X = aValueString.toInt32();
767 0 : if( nCharacterIndex < 0 )
768 0 : return false;
769 :
770 0 : aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
771 0 : rMinimumPosition.Y = aValueString.toInt32();
772 0 : if( nCharacterIndex < 0 )
773 0 : return false;
774 :
775 0 : aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
776 0 : rMaximumPosition.X = aValueString.toInt32();
777 0 : if( nCharacterIndex < 0 )
778 0 : return false;
779 :
780 0 : aValueString = rDragParameterString.getToken( 0, ',', nCharacterIndex );
781 0 : rMaximumPosition.Y = aValueString.toInt32();
782 0 : if( nCharacterIndex < 0 )
783 0 : return false;
784 :
785 0 : return true;
786 : }
787 :
788 0 : OUString ObjectIdentifier::getDragMethodServiceName( const OUString& rCID )
789 : {
790 0 : OUString aRet;
791 :
792 0 : sal_Int32 nIndexStart = rCID.indexOf( m_aDragMethodEquals );
793 0 : if( nIndexStart != -1 )
794 : {
795 0 : nIndexStart = rCID.indexOf( '=', nIndexStart );
796 0 : if( nIndexStart != -1 )
797 : {
798 0 : nIndexStart++;
799 0 : sal_Int32 nNextSlash = rCID.indexOf( '/', nIndexStart );
800 0 : if( nNextSlash != -1 )
801 : {
802 0 : sal_Int32 nIndexEnd = nNextSlash;
803 0 : sal_Int32 nNextColon = rCID.indexOf( ':', nIndexStart );
804 0 : if( nNextColon < nNextSlash )
805 0 : nIndexEnd = nNextColon;
806 0 : aRet = rCID.copy(nIndexStart,nIndexEnd-nIndexStart);
807 : }
808 : }
809 : }
810 0 : return aRet;
811 : }
812 :
813 0 : OUString ObjectIdentifier::getDragParameterString( const OUString& rCID )
814 : {
815 0 : OUString aRet;
816 :
817 0 : sal_Int32 nIndexStart = rCID.indexOf( m_aDragParameterEquals );
818 0 : if( nIndexStart != -1 )
819 : {
820 0 : nIndexStart = rCID.indexOf( '=', nIndexStart );
821 0 : if( nIndexStart != -1 )
822 : {
823 0 : nIndexStart++;
824 0 : sal_Int32 nNextSlash = rCID.indexOf( '/', nIndexStart );
825 0 : if( nNextSlash != -1 )
826 : {
827 0 : sal_Int32 nIndexEnd = nNextSlash;
828 0 : sal_Int32 nNextColon = rCID.indexOf( ':', nIndexStart );
829 0 : if( nNextColon < nNextSlash )
830 0 : nIndexEnd = nNextColon;
831 0 : aRet = rCID.copy(nIndexStart,nIndexEnd-nIndexStart);
832 : }
833 : }
834 : }
835 0 : return aRet;
836 : }
837 :
838 0 : bool ObjectIdentifier::isDragableObject( const OUString& rClassifiedIdentifier )
839 : {
840 0 : bool bReturn = false;
841 0 : ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier );
842 0 : switch( eObjectType )
843 : {
844 : case OBJECTTYPE_TITLE:
845 : case OBJECTTYPE_LEGEND:
846 : case OBJECTTYPE_DIAGRAM:
847 : case OBJECTTYPE_DATA_CURVE_EQUATION:
848 : //case OBJECTTYPE_DIAGRAM_WALL:
849 0 : bReturn = true;
850 0 : break;
851 : default:
852 0 : OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( rClassifiedIdentifier ) );
853 0 : bReturn = !aDragMethodServiceName.isEmpty();
854 0 : break;
855 : }
856 0 : return bReturn;
857 : }
858 :
859 0 : bool ObjectIdentifier::isDragableObject()
860 : {
861 0 : bool bReturn = false;
862 0 : if ( isAutoGeneratedObject() )
863 : {
864 0 : bReturn = isDragableObject( m_aObjectCID );
865 : }
866 0 : else if ( isAdditionalShape() )
867 : {
868 0 : bReturn = true;
869 : }
870 0 : return bReturn;
871 : }
872 :
873 0 : bool ObjectIdentifier::isRotateableObject( const OUString& rClassifiedIdentifier )
874 : {
875 0 : bool bReturn = false;
876 0 : ObjectType eObjectType = ObjectIdentifier::getObjectType( rClassifiedIdentifier );
877 0 : switch( eObjectType )
878 : {
879 : case OBJECTTYPE_DIAGRAM:
880 : //case OBJECTTYPE_DIAGRAM_WALL:
881 0 : bReturn = true;
882 0 : break;
883 : default:
884 0 : bReturn = false;
885 0 : break;
886 : }
887 0 : return bReturn;
888 : }
889 :
890 0 : bool ObjectIdentifier::isMultiClickObject( const OUString& rClassifiedIdentifier )
891 : {
892 : //the name of a shape is it's ClassifiedIdentifier
893 :
894 : //a MultiClickObject is an object that is selectable by more than one click only ;
895 : //before a MultiClickObject can be selected it is necessary that a named parent group object
896 : //was selected before;
897 :
898 : //!!!!! by definition the name of a MultiClickObject starts with "CID/MultiClick:"
899 0 : bool bRet = rClassifiedIdentifier.match( m_aMultiClick, m_aProtocol.getLength() );
900 0 : return bRet;
901 : }
902 :
903 0 : bool ObjectIdentifier::areSiblings( const OUString& rCID1, const OUString& rCID2 )
904 : {
905 0 : bool bRet=false;
906 0 : sal_Int32 nLastSign1 = rCID1.lastIndexOf( '=' );
907 0 : sal_Int32 nLastSign2 = rCID2.lastIndexOf( '=' );
908 0 : if( nLastSign1 == rCID1.indexOf( '=' ) )//CID cannot be sibling if only one "=" occurs
909 0 : bRet=false;
910 0 : else if( nLastSign2 == rCID2.indexOf( '=' ) )//CID cannot be sibling if only one "=" occurs
911 0 : bRet=false;
912 0 : else if( ObjectIdentifier::areIdenticalObjects( rCID1, rCID2 ) )
913 0 : bRet=false;
914 : else
915 : {
916 0 : OUString aParent1( ObjectIdentifier::getFullParentParticle( rCID1 ) );
917 0 : if( !aParent1.isEmpty() )
918 : {
919 0 : OUString aParent2( ObjectIdentifier::getFullParentParticle( rCID2 ) );
920 0 : bRet=aParent1.equals(aParent2);
921 : }
922 : //legend entries are special:
923 0 : if(!bRet)
924 : {
925 0 : if( OBJECTTYPE_LEGEND_ENTRY == getObjectType(rCID1)
926 0 : && OBJECTTYPE_LEGEND_ENTRY == getObjectType(rCID2) )
927 0 : bRet = true;
928 0 : }
929 : }
930 0 : return bRet;
931 : }
932 :
933 0 : bool ObjectIdentifier::areIdenticalObjects( const OUString& rCID1, const OUString& rCID2 )
934 : {
935 0 : if( rCID1.equals( rCID2 ) )
936 0 : return true;
937 : //draggable pie or donut segments need special treatment, as their CIDs do change with offset
938 : {
939 0 : if( rCID1.indexOf( m_aPieSegmentDragMethodServiceName ) < 0
940 0 : || rCID2.indexOf( m_aPieSegmentDragMethodServiceName ) < 0 )
941 0 : return false;
942 :
943 0 : OUString aID1( ObjectIdentifier::getObjectID( rCID1 ) );
944 0 : OUString aID2( ObjectIdentifier::getObjectID( rCID2 ) );
945 0 : if( !aID1.isEmpty() && aID1.equals( aID2 ) )
946 0 : return true;
947 : }
948 0 : return false;
949 : }
950 :
951 0 : OUString ObjectIdentifier::getStringForType( ObjectType eObjectType )
952 : {
953 0 : OUString aRet;
954 0 : switch( eObjectType )
955 : {
956 : case OBJECTTYPE_PAGE:
957 0 : aRet="Page";
958 0 : break;
959 : case OBJECTTYPE_TITLE:
960 0 : aRet="Title";
961 0 : break;
962 : case OBJECTTYPE_LEGEND:
963 0 : aRet="Legend";
964 0 : break;
965 : case OBJECTTYPE_LEGEND_ENTRY:
966 0 : aRet="LegendEntry";
967 0 : break;
968 : case OBJECTTYPE_DIAGRAM:
969 0 : aRet="D";
970 0 : break;
971 : case OBJECTTYPE_DIAGRAM_WALL:
972 0 : aRet="DiagramWall";
973 0 : break;
974 : case OBJECTTYPE_DIAGRAM_FLOOR:
975 0 : aRet="DiagramFloor";
976 0 : break;
977 : case OBJECTTYPE_AXIS:
978 0 : aRet="Axis";
979 0 : break;
980 : case OBJECTTYPE_AXIS_UNITLABEL:
981 0 : aRet="AxisUnitLabel";
982 0 : break;
983 : case OBJECTTYPE_GRID:
984 0 : aRet="Grid";
985 0 : break;
986 : case OBJECTTYPE_SUBGRID:
987 0 : aRet="SubGrid";
988 0 : break;
989 : case OBJECTTYPE_DATA_SERIES:
990 0 : aRet="Series";
991 0 : break;
992 : case OBJECTTYPE_DATA_POINT:
993 0 : aRet="Point";
994 0 : break;
995 : case OBJECTTYPE_DATA_LABELS:
996 0 : aRet="DataLabels";
997 0 : break;
998 : case OBJECTTYPE_DATA_LABEL:
999 0 : aRet="DataLabel";
1000 0 : break;
1001 : case OBJECTTYPE_DATA_ERRORS_X:
1002 0 : aRet="ErrorsX";
1003 0 : break;
1004 : case OBJECTTYPE_DATA_ERRORS_Y:
1005 0 : aRet="ErrorsY";
1006 0 : break;
1007 : case OBJECTTYPE_DATA_ERRORS_Z:
1008 0 : aRet="ErrorsZ";
1009 0 : break;
1010 : case OBJECTTYPE_DATA_CURVE:
1011 0 : aRet="Curve";
1012 0 : break;
1013 : case OBJECTTYPE_DATA_CURVE_EQUATION:
1014 0 : aRet="Equation";
1015 0 : break;
1016 : case OBJECTTYPE_DATA_AVERAGE_LINE:
1017 0 : aRet="Average";
1018 0 : break;
1019 : case OBJECTTYPE_DATA_STOCK_RANGE:
1020 0 : aRet="StockRange";
1021 0 : break;
1022 : case OBJECTTYPE_DATA_STOCK_LOSS:
1023 0 : aRet="StockLoss";
1024 0 : break;
1025 : case OBJECTTYPE_DATA_STOCK_GAIN:
1026 0 : aRet="StockGain";
1027 0 : break;
1028 : default: //OBJECTTYPE_UNKNOWN
1029 : ;
1030 : }
1031 0 : return aRet;
1032 : }
1033 :
1034 0 : ObjectType ObjectIdentifier::getObjectType( const OUString& rCID )
1035 : {
1036 : ObjectType eRet;
1037 0 : sal_Int32 nLastSign = rCID.lastIndexOf( ':' );//last sign before the type string
1038 0 : if(nLastSign==-1)
1039 0 : nLastSign = rCID.lastIndexOf( '/' );
1040 0 : if(nLastSign==-1)
1041 : {
1042 0 : sal_Int32 nEndIndex = rCID.lastIndexOf( '=' );
1043 0 : if(nEndIndex==-1)
1044 0 : return OBJECTTYPE_UNKNOWN;
1045 0 : nLastSign = 0;
1046 : }
1047 0 : if( nLastSign>0 )
1048 0 : nLastSign++;
1049 :
1050 0 : if( rCID.match("Page",nLastSign) )
1051 0 : eRet = OBJECTTYPE_PAGE;
1052 0 : else if( rCID.match("Title",nLastSign) )
1053 0 : eRet = OBJECTTYPE_TITLE;
1054 0 : else if( rCID.match("LegendEntry",nLastSign) )
1055 0 : eRet = OBJECTTYPE_LEGEND_ENTRY;
1056 0 : else if( rCID.match("Legend",nLastSign) )
1057 0 : eRet = OBJECTTYPE_LEGEND;
1058 0 : else if( rCID.match("DiagramWall",nLastSign) )
1059 0 : eRet = OBJECTTYPE_DIAGRAM_WALL;
1060 0 : else if( rCID.match("DiagramFloor",nLastSign) )
1061 0 : eRet = OBJECTTYPE_DIAGRAM_FLOOR;
1062 0 : else if( rCID.match("D=",nLastSign) )
1063 0 : eRet = OBJECTTYPE_DIAGRAM;
1064 0 : else if( rCID.match("AxisUnitLabel",nLastSign) )
1065 0 : eRet = OBJECTTYPE_AXIS_UNITLABEL;
1066 0 : else if( rCID.match("Axis",nLastSign) )
1067 0 : eRet = OBJECTTYPE_AXIS;
1068 0 : else if( rCID.match("Grid",nLastSign) )
1069 0 : eRet = OBJECTTYPE_GRID;
1070 0 : else if( rCID.match("SubGrid",nLastSign) )
1071 0 : eRet = OBJECTTYPE_SUBGRID;
1072 0 : else if( rCID.match("Series",nLastSign) )
1073 0 : eRet = OBJECTTYPE_DATA_SERIES;
1074 0 : else if( rCID.match("Point",nLastSign) )
1075 0 : eRet = OBJECTTYPE_DATA_POINT;
1076 0 : else if( rCID.match("DataLabels",nLastSign) )
1077 0 : eRet = OBJECTTYPE_DATA_LABELS;
1078 0 : else if( rCID.match("DataLabel",nLastSign) )
1079 0 : eRet = OBJECTTYPE_DATA_LABEL;
1080 0 : else if( rCID.match("ErrorsX",nLastSign) )
1081 0 : eRet = OBJECTTYPE_DATA_ERRORS_X;
1082 0 : else if( rCID.match("ErrorsY",nLastSign) )
1083 0 : eRet = OBJECTTYPE_DATA_ERRORS_Y;
1084 0 : else if( rCID.match("ErrorsZ",nLastSign) )
1085 0 : eRet = OBJECTTYPE_DATA_ERRORS_Z;
1086 0 : else if( rCID.match("Curve",nLastSign) )
1087 0 : eRet = OBJECTTYPE_DATA_CURVE;
1088 0 : else if( rCID.match("Equation",nLastSign) )
1089 0 : eRet = OBJECTTYPE_DATA_CURVE_EQUATION;
1090 0 : else if( rCID.match("Average",nLastSign) )
1091 0 : eRet = OBJECTTYPE_DATA_AVERAGE_LINE;
1092 0 : else if( rCID.match("StockRange",nLastSign) )
1093 0 : eRet = OBJECTTYPE_DATA_STOCK_RANGE;
1094 0 : else if( rCID.match("StockLoss",nLastSign) )
1095 0 : eRet = OBJECTTYPE_DATA_STOCK_LOSS;
1096 0 : else if( rCID.match("StockGain",nLastSign) )
1097 0 : eRet = OBJECTTYPE_DATA_STOCK_GAIN;
1098 : else
1099 0 : eRet = OBJECTTYPE_UNKNOWN;
1100 :
1101 0 : return eRet;
1102 : }
1103 :
1104 0 : ObjectType ObjectIdentifier::getObjectType()
1105 : {
1106 0 : ObjectType eObjectType( OBJECTTYPE_UNKNOWN );
1107 0 : if ( isAutoGeneratedObject() )
1108 : {
1109 0 : eObjectType = getObjectType( m_aObjectCID );
1110 : }
1111 0 : else if ( isAdditionalShape() )
1112 : {
1113 0 : eObjectType = OBJECTTYPE_SHAPE;
1114 : }
1115 0 : return eObjectType;
1116 : }
1117 :
1118 0 : OUString ObjectIdentifier::createDataCurveCID(
1119 : const OUString& rSeriesParticle
1120 : , sal_Int32 nCurveIndex
1121 : , bool bAverageLine )
1122 : {
1123 0 : OUString aParticleID( OUString::number( nCurveIndex ) );
1124 0 : ObjectType eType = bAverageLine ? OBJECTTYPE_DATA_AVERAGE_LINE : OBJECTTYPE_DATA_CURVE;
1125 0 : return createClassifiedIdentifierWithParent( eType, aParticleID, rSeriesParticle );
1126 : }
1127 :
1128 0 : OUString ObjectIdentifier::createDataCurveEquationCID(
1129 : const OUString& rSeriesParticle
1130 : , sal_Int32 nCurveIndex )
1131 : {
1132 0 : OUString aParticleID( OUString::number( nCurveIndex ) );
1133 0 : return createClassifiedIdentifierWithParent( OBJECTTYPE_DATA_CURVE_EQUATION, aParticleID, rSeriesParticle );
1134 : }
1135 :
1136 0 : OUString ObjectIdentifier::addChildParticle( const OUString& rParticle, const OUString& rChildParticle )
1137 : {
1138 0 : OUStringBuffer aRet(rParticle);
1139 :
1140 0 : if( !aRet.isEmpty() && !rChildParticle.isEmpty() )
1141 0 : aRet.appendAscii(":");
1142 0 : if( !rChildParticle.isEmpty() )
1143 0 : aRet.append(rChildParticle);
1144 :
1145 0 : return aRet.makeStringAndClear();
1146 : }
1147 :
1148 0 : OUString ObjectIdentifier::createChildParticleWithIndex( ObjectType eObjectType, sal_Int32 nIndex )
1149 : {
1150 0 : OUStringBuffer aRet( getStringForType( eObjectType ) );
1151 0 : if( !aRet.isEmpty() )
1152 : {
1153 0 : aRet.appendAscii("=");
1154 0 : aRet.append(OUString::number(nIndex));
1155 : }
1156 0 : return aRet.makeStringAndClear();
1157 : }
1158 :
1159 0 : sal_Int32 ObjectIdentifier::getIndexFromParticleOrCID( const OUString& rParticleOrCID )
1160 : {
1161 0 : OUString aIndexString = lcl_getIndexStringAfterString( rParticleOrCID, "=" );
1162 0 : sal_Int32 nCharacterIndex=0;
1163 0 : sal_Int32 nRet = lcl_StringToIndex( aIndexString.getToken( 0, ',', nCharacterIndex ) );
1164 :
1165 0 : return nRet;
1166 : }
1167 :
1168 0 : OUString ObjectIdentifier::createSeriesSubObjectStub( ObjectType eSubObjectType
1169 : , const OUString& rSeriesParticle
1170 : , const OUString& rDragMethodServiceName
1171 : , const OUString& rDragParameterString )
1172 : {
1173 0 : OUString aChildParticle( getStringForType( eSubObjectType ) );
1174 0 : aChildParticle+=("=");
1175 :
1176 : return createClassifiedIdentifierForParticles(
1177 : rSeriesParticle, aChildParticle
1178 0 : , rDragMethodServiceName, rDragParameterString );
1179 : }
1180 :
1181 0 : OUString ObjectIdentifier::createPointCID( const OUString& rPointCID_Stub, sal_Int32 nIndex )
1182 : {
1183 0 : OUString aRet(rPointCID_Stub);
1184 0 : return aRet+=OUString::number( nIndex );
1185 : }
1186 :
1187 0 : OUString ObjectIdentifier::getParticleID( const OUString& rCID )
1188 : {
1189 0 : OUString aRet;
1190 0 : sal_Int32 nLast = rCID.lastIndexOf('=');
1191 0 : if(nLast>=0)
1192 0 : aRet = rCID.copy(++nLast);
1193 0 : return aRet;
1194 : }
1195 :
1196 0 : OUString ObjectIdentifier::getFullParentParticle( const OUString& rCID )
1197 : {
1198 0 : OUString aRet;
1199 :
1200 0 : sal_Int32 nStartPos = rCID.lastIndexOf('/');
1201 0 : if( nStartPos>=0 )
1202 : {
1203 0 : nStartPos++;
1204 0 : sal_Int32 nEndPos = rCID.lastIndexOf(':');
1205 0 : if( nEndPos>=0 && nStartPos < nEndPos )
1206 : {
1207 0 : aRet = rCID.copy(nStartPos,nEndPos-nStartPos);
1208 : }
1209 : }
1210 :
1211 0 : return aRet;
1212 : }
1213 :
1214 0 : OUString ObjectIdentifier::getObjectID( const OUString& rCID )
1215 : {
1216 0 : OUString aRet;
1217 :
1218 0 : sal_Int32 nStartPos = rCID.lastIndexOf('/');
1219 0 : if( nStartPos>=0 )
1220 : {
1221 0 : nStartPos++;
1222 0 : sal_Int32 nEndPos = rCID.getLength();
1223 0 : aRet = rCID.copy(nStartPos,nEndPos-nStartPos);
1224 : }
1225 :
1226 0 : return aRet;
1227 : }
1228 :
1229 0 : bool ObjectIdentifier::isCID( const OUString& rName )
1230 : {
1231 0 : return !rName.isEmpty() && rName.match( m_aProtocol );
1232 : }
1233 :
1234 0 : Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet(
1235 : const OUString& rObjectCID,
1236 : const Reference< chart2::XChartDocument >& xChartDocument )
1237 : {
1238 : return ObjectIdentifier::getObjectPropertySet(
1239 0 : rObjectCID, Reference< frame::XModel >( xChartDocument, uno::UNO_QUERY ));
1240 : }
1241 :
1242 0 : Reference< beans::XPropertySet > ObjectIdentifier::getObjectPropertySet(
1243 : const OUString& rObjectCID
1244 : , const Reference< frame::XModel >& xChartModel )
1245 : {
1246 : //return the model object that is indicated by rObjectCID
1247 0 : if(rObjectCID.isEmpty())
1248 0 : return NULL;
1249 0 : if(!xChartModel.is())
1250 0 : return NULL;
1251 :
1252 0 : Reference< beans::XPropertySet > xObjectProperties = NULL;
1253 : try
1254 : {
1255 0 : ObjectType eObjectType = ObjectIdentifier::getObjectType( rObjectCID );
1256 0 : OUString aParticleID = ObjectIdentifier::getParticleID( rObjectCID );
1257 :
1258 0 : Reference< XDiagram > xDiagram;
1259 0 : Reference< XCoordinateSystem > xCooSys;
1260 0 : lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
1261 :
1262 0 : switch(eObjectType)
1263 : {
1264 : case OBJECTTYPE_PAGE:
1265 : {
1266 0 : Reference< XChartDocument > xChartDocument( xChartModel, uno::UNO_QUERY );
1267 0 : if( xChartDocument.is())
1268 0 : xObjectProperties.set( xChartDocument->getPageBackground() );
1269 : }
1270 0 : break;
1271 : case OBJECTTYPE_TITLE:
1272 : {
1273 0 : TitleHelper::eTitleType aTitleType = getTitleTypeForCID( rObjectCID );
1274 0 : Reference< XTitle > xTitle( TitleHelper::getTitle( aTitleType, xChartModel ) );
1275 0 : xObjectProperties.set( xTitle, uno::UNO_QUERY );
1276 : }
1277 0 : break;
1278 : case OBJECTTYPE_LEGEND:
1279 : {
1280 0 : if( xDiagram.is() )
1281 0 : xObjectProperties.set( xDiagram->getLegend(), uno::UNO_QUERY );
1282 : }
1283 0 : break;
1284 : case OBJECTTYPE_LEGEND_ENTRY:
1285 0 : break;
1286 : case OBJECTTYPE_DIAGRAM:
1287 : {
1288 0 : xObjectProperties.set( xDiagram, uno::UNO_QUERY );
1289 : }
1290 0 : break;
1291 : case OBJECTTYPE_DIAGRAM_WALL:
1292 : {
1293 0 : if( xDiagram.is() )
1294 0 : xObjectProperties.set( xDiagram->getWall() );
1295 : }
1296 0 : break;
1297 : case OBJECTTYPE_DIAGRAM_FLOOR:
1298 : {
1299 0 : if( xDiagram.is() )
1300 0 : xObjectProperties.set( xDiagram->getFloor() );
1301 : }
1302 0 : break;
1303 : case OBJECTTYPE_AXIS:
1304 : {
1305 0 : sal_Int32 nDimensionIndex = -1;
1306 0 : sal_Int32 nAxisIndex = -1;
1307 0 : lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
1308 :
1309 : Reference< chart2::XAxis > xAxis(
1310 0 : AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys ) );
1311 0 : if( xAxis.is() )
1312 0 : xObjectProperties.set( xAxis, uno::UNO_QUERY );
1313 : }
1314 0 : break;
1315 : case OBJECTTYPE_AXIS_UNITLABEL:
1316 0 : break;
1317 : case OBJECTTYPE_GRID:
1318 : case OBJECTTYPE_SUBGRID:
1319 : {
1320 0 : sal_Int32 nDimensionIndex = -1;
1321 0 : sal_Int32 nAxisIndex = -1;
1322 0 : lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
1323 :
1324 0 : sal_Int32 nSubGridIndex = -1;
1325 0 : lcl_parseGridIndices( nSubGridIndex, rObjectCID );
1326 :
1327 0 : xObjectProperties.set( AxisHelper::getGridProperties( xCooSys , nDimensionIndex, nAxisIndex, nSubGridIndex ) );
1328 : }
1329 0 : break;
1330 : case OBJECTTYPE_DATA_LABELS:
1331 : case OBJECTTYPE_DATA_SERIES:
1332 : {
1333 : Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
1334 0 : rObjectCID, xChartModel ) );
1335 0 : if( xSeries.is() )
1336 0 : xObjectProperties = Reference< beans::XPropertySet >( xSeries, uno::UNO_QUERY );
1337 :
1338 0 : break;
1339 : }
1340 : case OBJECTTYPE_DATA_LABEL:
1341 : case OBJECTTYPE_DATA_POINT:
1342 : {
1343 : Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
1344 0 : rObjectCID, xChartModel ) );
1345 0 : if(xSeries.is())
1346 : {
1347 0 : sal_Int32 nIndex = aParticleID.toInt32();
1348 0 : xObjectProperties = xSeries->getDataPointByIndex( nIndex );
1349 : }
1350 0 : break;
1351 : }
1352 : case OBJECTTYPE_DATA_ERRORS_X:
1353 : case OBJECTTYPE_DATA_ERRORS_Y:
1354 : case OBJECTTYPE_DATA_ERRORS_Z:
1355 : {
1356 : Reference< XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID(
1357 0 : rObjectCID, xChartModel ) );
1358 0 : if(xSeries.is())
1359 : {
1360 0 : Reference< beans::XPropertySet > xSeriesProp( xSeries, uno::UNO_QUERY );
1361 0 : Reference< beans::XPropertySet > xErrorBarProp;
1362 0 : if( xSeriesProp.is() )
1363 : {
1364 0 : OUString errorBar;
1365 :
1366 0 : if ( eObjectType == OBJECTTYPE_DATA_ERRORS_X)
1367 0 : errorBar = "ErrorBarX";
1368 0 : else if (eObjectType == OBJECTTYPE_DATA_ERRORS_Y)
1369 0 : errorBar = "ErrorBarY";
1370 : else
1371 0 : errorBar = "ErrorBarZ";
1372 :
1373 0 : xSeriesProp->getPropertyValue( errorBar ) >>= xErrorBarProp;
1374 0 : xObjectProperties = Reference< beans::XPropertySet >( xErrorBarProp, uno::UNO_QUERY );
1375 0 : }
1376 : }
1377 0 : break;
1378 : }
1379 : case OBJECTTYPE_DATA_AVERAGE_LINE:
1380 : case OBJECTTYPE_DATA_CURVE:
1381 : case OBJECTTYPE_DATA_CURVE_EQUATION:
1382 : {
1383 : Reference< XRegressionCurveContainer > xRegressionContainer( ObjectIdentifier::getDataSeriesForCID(
1384 0 : rObjectCID, xChartModel ), uno::UNO_QUERY );
1385 0 : if(xRegressionContainer.is())
1386 : {
1387 0 : sal_Int32 nIndex = aParticleID.toInt32();
1388 : uno::Sequence< Reference< XRegressionCurve > > aCurveList =
1389 0 : xRegressionContainer->getRegressionCurves();
1390 0 : if( nIndex >= 0 && nIndex <aCurveList.getLength() )
1391 : {
1392 0 : if( eObjectType == OBJECTTYPE_DATA_CURVE_EQUATION )
1393 0 : xObjectProperties.set( aCurveList[nIndex]->getEquationProperties());
1394 : else
1395 0 : xObjectProperties.set( aCurveList[nIndex], uno::UNO_QUERY );
1396 0 : }
1397 : }
1398 0 : break;
1399 : }
1400 : case OBJECTTYPE_DATA_STOCK_RANGE:
1401 0 : break;
1402 : case OBJECTTYPE_DATA_STOCK_LOSS:
1403 : {
1404 0 : Reference<XChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
1405 0 : Reference< beans::XPropertySet > xChartTypeProps( xChartType, uno::UNO_QUERY );
1406 0 : if(xChartTypeProps.is())
1407 0 : xChartTypeProps->getPropertyValue( "BlackDay" ) >>= xObjectProperties;
1408 : }
1409 0 : break;
1410 : case OBJECTTYPE_DATA_STOCK_GAIN:
1411 : {
1412 0 : Reference<XChartType> xChartType( lcl_getFirstStockChartType( xChartModel ) );
1413 0 : Reference< beans::XPropertySet > xChartTypeProps( xChartType, uno::UNO_QUERY );
1414 0 : if(xChartTypeProps.is())
1415 0 : xChartTypeProps->getPropertyValue( "WhiteDay" ) >>= xObjectProperties;
1416 : }
1417 0 : break;
1418 : default: //OBJECTTYPE_UNKNOWN
1419 0 : break;
1420 0 : }
1421 : }
1422 0 : catch(const uno::Exception& ex)
1423 : {
1424 : ASSERT_EXCEPTION( ex );
1425 : }
1426 0 : return xObjectProperties;
1427 : }
1428 :
1429 0 : Reference< XAxis > ObjectIdentifier::getAxisForCID(
1430 : const OUString& rObjectCID
1431 : , const Reference< frame::XModel >& xChartModel )
1432 : {
1433 0 : Reference< XDiagram > xDiagram;
1434 0 : Reference< XCoordinateSystem > xCooSys;
1435 0 : lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
1436 :
1437 0 : sal_Int32 nDimensionIndex = -1;
1438 0 : sal_Int32 nAxisIndex = -1;
1439 0 : lcl_parseAxisIndices( nDimensionIndex, nAxisIndex, rObjectCID );
1440 :
1441 0 : return AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys );
1442 : }
1443 :
1444 0 : Reference< XDataSeries > ObjectIdentifier::getDataSeriesForCID(
1445 : const OUString& rObjectCID
1446 : , const Reference< frame::XModel >& xChartModel )
1447 : {
1448 0 : Reference< XDataSeries > xSeries(NULL);
1449 :
1450 0 : Reference< XDiagram > xDiagram;
1451 0 : Reference< XCoordinateSystem > xCooSys;
1452 0 : lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
1453 :
1454 0 : sal_Int32 nChartTypeIndex = -1;
1455 0 : sal_Int32 nSeriesIndex = -1;
1456 0 : sal_Int32 nPointIndex = -1;
1457 0 : lcl_parseSeriesIndices( nChartTypeIndex, nSeriesIndex, nPointIndex, rObjectCID );
1458 :
1459 0 : Reference< XDataSeriesContainer > xDataSeriesContainer( DiagramHelper::getChartTypeByIndex( xDiagram, nChartTypeIndex ), uno::UNO_QUERY );
1460 0 : if( xDataSeriesContainer.is() )
1461 : {
1462 0 : uno::Sequence< uno::Reference< XDataSeries > > aDataSeriesSeq( xDataSeriesContainer->getDataSeries() );
1463 0 : if( nSeriesIndex >= 0 && nSeriesIndex < aDataSeriesSeq.getLength() )
1464 0 : xSeries.set( aDataSeriesSeq[nSeriesIndex] );
1465 : }
1466 :
1467 0 : return xSeries;
1468 : }
1469 :
1470 0 : Reference< XDiagram > ObjectIdentifier::getDiagramForCID(
1471 : const OUString& rObjectCID
1472 : , const uno::Reference< frame::XModel >& xChartModel )
1473 : {
1474 0 : Reference< XDiagram > xDiagram;
1475 :
1476 0 : Reference< XCoordinateSystem > xCooSys;
1477 0 : lcl_getDiagramAndCooSys( rObjectCID, xChartModel, xDiagram, xCooSys );
1478 :
1479 0 : return xDiagram;
1480 : }
1481 :
1482 0 : TitleHelper::eTitleType ObjectIdentifier::getTitleTypeForCID( const OUString& rCID )
1483 : {
1484 0 : TitleHelper::eTitleType eRet( TitleHelper::MAIN_TITLE );
1485 :
1486 0 : OUString aParentParticle = ObjectIdentifier::getFullParentParticle( rCID );
1487 0 : const tTitleMap& rMap = lcl_getTitleMap();
1488 0 : tTitleMap::const_iterator aIt( rMap.begin() );
1489 0 : for( ;aIt != rMap.end(); ++aIt )
1490 : {
1491 0 : if( aParentParticle.equals( (*aIt).second ) )
1492 : {
1493 0 : eRet = (*aIt).first;
1494 0 : break;
1495 : }
1496 : }
1497 :
1498 0 : return eRet;
1499 : }
1500 :
1501 0 : OUString ObjectIdentifier::getSeriesParticleFromCID( const OUString& rCID )
1502 : {
1503 0 : sal_Int32 nDiagramIndex = -1;
1504 0 : sal_Int32 nCooSysIndex = -1;
1505 0 : lcl_parseCooSysIndices( nDiagramIndex, nCooSysIndex, rCID );
1506 :
1507 0 : sal_Int32 nChartTypeIndex = -1;
1508 0 : sal_Int32 nSeriesIndex = -1;
1509 0 : sal_Int32 nPointIndex = -1;
1510 0 : lcl_parseSeriesIndices( nChartTypeIndex, nSeriesIndex, nPointIndex, rCID );
1511 :
1512 0 : return ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCooSysIndex, nChartTypeIndex, nSeriesIndex );
1513 : }
1514 :
1515 0 : OUString ObjectIdentifier::getMovedSeriesCID( const OUString& rObjectCID, sal_Bool bForward )
1516 : {
1517 0 : sal_Int32 nDiagramIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CID/D=" ) );
1518 0 : sal_Int32 nCooSysIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CS=" ) );
1519 0 : sal_Int32 nChartTypeIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "CT=" ) );
1520 0 : sal_Int32 nSeriesIndex = lcl_StringToIndex( lcl_getIndexStringAfterString( rObjectCID, "Series=" ) );
1521 :
1522 0 : if( bForward )
1523 0 : nSeriesIndex--;
1524 : else
1525 0 : nSeriesIndex++;
1526 :
1527 0 : OUString aRet = ObjectIdentifier::createParticleForSeries( nDiagramIndex, nCooSysIndex, nChartTypeIndex, nSeriesIndex );
1528 0 : return ObjectIdentifier::createClassifiedIdentifierForParticle( aRet );
1529 : }
1530 :
1531 0 : bool ObjectIdentifier::isValid() const
1532 : {
1533 0 : return ( isAutoGeneratedObject() || isAdditionalShape() );
1534 : }
1535 :
1536 0 : bool ObjectIdentifier::isAutoGeneratedObject() const
1537 : {
1538 0 : return ( !m_aObjectCID.isEmpty() );
1539 : }
1540 :
1541 0 : bool ObjectIdentifier::isAdditionalShape() const
1542 : {
1543 0 : return m_xAdditionalShape.is();
1544 : }
1545 :
1546 0 : OUString ObjectIdentifier::getObjectCID() const
1547 : {
1548 0 : return m_aObjectCID;
1549 : }
1550 :
1551 0 : Reference< drawing::XShape > ObjectIdentifier::getAdditionalShape() const
1552 : {
1553 0 : return m_xAdditionalShape;
1554 : }
1555 :
1556 0 : Any ObjectIdentifier::getAny() const
1557 : {
1558 0 : Any aAny;
1559 0 : if ( isAutoGeneratedObject() )
1560 : {
1561 0 : aAny = uno::makeAny( getObjectCID() );
1562 : }
1563 0 : else if ( isAdditionalShape() )
1564 : {
1565 0 : aAny = uno::makeAny( getAdditionalShape() );
1566 : }
1567 0 : return aAny;
1568 : }
1569 :
1570 0 : } //namespace chart
1571 :
1572 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|