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