update dev300-m58
[ooovba.git] / chart2 / source / tools / RangeHighlighter.cxx
blob42731296664c8f7d3a9f9ce27a64ccccefda1565
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: RangeHighlighter.cxx,v $
10 * $Revision: 1.6.44.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "RangeHighlighter.hxx"
35 #include "WeakListenerAdapter.hxx"
36 #include "ChartModelHelper.hxx"
37 #include "DataSourceHelper.hxx"
38 #include "ContainerHelper.hxx"
39 #include "macros.hxx"
40 #include "ObjectIdentifier.hxx"
41 #include "DataSeriesHelper.hxx"
43 #include <com/sun/star/chart2/XDataSeries.hpp>
44 #include <com/sun/star/chart/ErrorBarStyle.hpp>
46 #define PREFERED_DEFAULT_COLOR 0x0000ff
48 using namespace ::com::sun::star;
50 using ::com::sun::star::uno::Reference;
51 using ::com::sun::star::uno::Sequence;
52 using ::rtl::OUString;
54 namespace
57 void lcl_fillRanges(
58 Sequence< chart2::data::HighlightedRange > & rOutRanges,
59 Sequence< OUString > aRangeStrings,
60 sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR,
61 sal_Int32 nIndex = -1 )
63 rOutRanges.realloc( aRangeStrings.getLength());
64 for( sal_Int32 i=0; i<aRangeStrings.getLength(); ++i )
66 rOutRanges[i].RangeRepresentation = aRangeStrings[i];
67 rOutRanges[i].PreferredColor = nPreferredColor;
68 rOutRanges[i].AllowMerginigWithOtherRanges = sal_False;
69 rOutRanges[i].Index = nIndex;
73 } // anonymous namespace
75 namespace chart
78 RangeHighlighter::RangeHighlighter(
79 const Reference< view::XSelectionSupplier > & xSelectionSupplier ) :
80 impl::RangeHighlighter_Base( m_aMutex ),
81 m_xSelectionSupplier( xSelectionSupplier ),
82 m_nAddedListenerCount( 0 ),
83 m_bIncludeHiddenCells(true)
87 RangeHighlighter::~RangeHighlighter()
90 // ____ XRangeHighlighter ____
91 Sequence< chart2::data::HighlightedRange > SAL_CALL RangeHighlighter::getSelectedRanges()
92 throw (uno::RuntimeException)
94 return m_aSelectedRanges;
97 void RangeHighlighter::determineRanges()
99 m_aSelectedRanges.realloc( 0 );
100 if( m_xSelectionSupplier.is())
104 Reference< frame::XController > xController( m_xSelectionSupplier, uno::UNO_QUERY );
105 Reference< frame::XModel > xChartModel;
106 if( xController.is())
107 xChartModel.set( xController->getModel());
109 m_bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( xChartModel );
111 uno::Any aSelection( m_xSelectionSupplier->getSelection());
112 OUString aCID;
113 if(( aSelection >>= aCID ) &&
114 aCID.getLength() > 0 )
116 // @todo??: maybe getSelection() should return a model object rather than a CID
118 ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
119 sal_Int32 nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aCID );
120 Reference< chart2::XDataSeries > xDataSeries( ObjectIdentifier::getDataSeriesForCID( aCID, xChartModel ) );
121 if( OBJECTTYPE_LEGEND_ENTRY == eObjectType )
123 OUString aParentParticel( ObjectIdentifier::getFullParentParticle( aCID ) );
124 ObjectType eParentObjectType = ObjectIdentifier::getObjectType( aParentParticel );
125 eObjectType = eParentObjectType;
126 if( OBJECTTYPE_DATA_POINT == eObjectType )
127 nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aParentParticel );
130 if( OBJECTTYPE_DATA_POINT == eObjectType || OBJECTTYPE_DATA_LABEL == eObjectType )
132 // Data Point
133 fillRangesForDataPoint( xDataSeries, nIndex );
134 return;
136 else if( OBJECTTYPE_DATA_ERRORS == eObjectType )
138 // select error bar ranges, or data series, if the style is
139 // not set to FROM_DATA
140 fillRangesForErrorBars( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), xDataSeries );
141 return;
143 else if( xDataSeries.is() )
145 // Data Series
146 fillRangesForDataSeries( xDataSeries );
147 return;
149 else if( OBJECTTYPE_AXIS == eObjectType )
151 // Axis (Categories)
152 Reference< chart2::XAxis > xAxis( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), uno::UNO_QUERY );
153 if( xAxis.is())
155 fillRangesForCategories( xAxis );
156 return;
159 else if( OBJECTTYPE_PAGE == eObjectType
160 || OBJECTTYPE_DIAGRAM == eObjectType
161 || OBJECTTYPE_DIAGRAM_WALL == eObjectType
162 || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
165 // Diagram
166 Reference< chart2::XDiagram > xDia( ObjectIdentifier::getDiagramForCID( aCID, xChartModel ) );
167 if( xDia.is())
169 fillRangesForDiagram( xDia );
170 return;
174 else
176 //if nothing is selected select all ranges
177 Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY_THROW );
178 fillRangesForDiagram( xChartDoc->getFirstDiagram() );
179 return;
182 catch( const uno::Exception & ex )
184 ASSERT_EXCEPTION( ex );
189 void RangeHighlighter::fillRangesForDiagram( const Reference< chart2::XDiagram > & xDiagram )
191 Sequence< OUString > aSelectedRanges( DataSourceHelper::getUsedDataRanges( xDiagram ));
192 m_aSelectedRanges.realloc( aSelectedRanges.getLength());
193 // @todo: merge ranges
194 for( sal_Int32 i=0; i<aSelectedRanges.getLength(); ++i )
196 m_aSelectedRanges[i].RangeRepresentation = aSelectedRanges[i];
197 m_aSelectedRanges[i].Index = -1;
198 m_aSelectedRanges[i].PreferredColor = PREFERED_DEFAULT_COLOR;
199 m_aSelectedRanges[i].AllowMerginigWithOtherRanges = sal_True;
203 void RangeHighlighter::fillRangesForDataSeries( const uno::Reference< chart2::XDataSeries > & xSeries )
205 sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
206 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
207 if( xSource.is())
208 lcl_fillRanges( m_aSelectedRanges,
209 ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
210 nPreferredColor );
213 void RangeHighlighter::fillRangesForErrorBars(
214 const uno::Reference< beans::XPropertySet > & xErrorBar,
215 const uno::Reference< chart2::XDataSeries > & xSeries )
217 // only show error bar ranges, if the style is set to FROM_DATA
218 bool bUsesRangesAsErrorBars = false;
221 sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
222 bUsesRangesAsErrorBars =
223 ( xErrorBar.is() &&
224 (xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle) &&
225 nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
227 catch( const uno::Exception & ex )
229 ASSERT_EXCEPTION( ex );
232 if( bUsesRangesAsErrorBars )
234 sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
235 Reference< chart2::data::XDataSource > xSource( xErrorBar, uno::UNO_QUERY );
236 if( xSource.is())
237 lcl_fillRanges( m_aSelectedRanges,
238 ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
239 nPreferredColor );
241 else
243 fillRangesForDataSeries( xSeries );
247 void RangeHighlighter::fillRangesForCategories( const Reference< chart2::XAxis > & xAxis )
249 if( ! xAxis.is())
250 return;
251 chart2::ScaleData aData( xAxis->getScaleData());
252 lcl_fillRanges( m_aSelectedRanges,
253 DataSourceHelper::getRangesFromLabeledDataSequence( aData.Categories ));
256 void RangeHighlighter::fillRangesForDataPoint( const Reference< uno::XInterface > & xDataSeries, sal_Int32 nIndex )
258 sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
259 if( xDataSeries.is())
261 Reference< chart2::data::XDataSource > xSource( xDataSeries, uno::UNO_QUERY );
262 if( xSource.is() )
264 ::std::vector< chart2::data::HighlightedRange > aHilightedRanges;
265 Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeqSeq( xSource->getDataSequences());
266 for( sal_Int32 i=0; i<aLSeqSeq.getLength(); ++i )
268 Reference< chart2::data::XDataSequence > xLabel( aLSeqSeq[i]->getLabel());
269 Reference< chart2::data::XDataSequence > xValues( aLSeqSeq[i]->getValues());
271 if( xLabel.is())
272 aHilightedRanges.push_back(
273 chart2::data::HighlightedRange(
274 xLabel->getSourceRangeRepresentation(),
276 nPreferredColor,
277 sal_False ));
279 sal_Int32 nUnhiddenIndex = DataSeriesHelper::translateIndexFromHiddenToFullSequence( nIndex, xValues, !m_bIncludeHiddenCells );
280 if( xValues.is())
281 aHilightedRanges.push_back(
282 chart2::data::HighlightedRange(
283 xValues->getSourceRangeRepresentation(),
284 nUnhiddenIndex,
285 nPreferredColor,
286 sal_False ));
288 m_aSelectedRanges = ContainerHelper::ContainerToSequence( aHilightedRanges );
293 void SAL_CALL RangeHighlighter::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
294 throw (uno::RuntimeException)
296 if(!xListener.is())
297 return;
299 if( m_nAddedListenerCount == 0 )
300 startListening();
301 rBHelper.addListener( ::getCppuType( & xListener ), xListener);
302 ++m_nAddedListenerCount;
304 //bring the new listener up to the current state
305 lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
306 xListener->selectionChanged( aEvent );
309 void SAL_CALL RangeHighlighter::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
310 throw (uno::RuntimeException)
312 rBHelper.removeListener( ::getCppuType( & xListener ), xListener );
313 --m_nAddedListenerCount;
314 if( m_nAddedListenerCount == 0 )
315 stopListening();
318 // ____ XSelectionChangeListener ____
319 void SAL_CALL RangeHighlighter::selectionChanged( const lang::EventObject& /*aEvent*/ )
320 throw (uno::RuntimeException)
322 determineRanges();
324 // determine ranges of selected view objects
325 // if changed, fire an event
326 fireSelectionEvent();
329 void RangeHighlighter::fireSelectionEvent()
331 ::cppu::OInterfaceContainerHelper* pIC = rBHelper.getContainer(
332 ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
333 if( pIC )
335 lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
336 ::cppu::OInterfaceIteratorHelper aIt( *pIC );
337 while( aIt.hasMoreElements() )
338 (static_cast< view::XSelectionChangeListener*>(aIt.next()))->selectionChanged( aEvent );
342 void SAL_CALL RangeHighlighter::disposing( const lang::EventObject& Source )
343 throw (uno::RuntimeException)
345 if( Source.Source == m_xSelectionSupplier )
347 m_xSelectionSupplier.clear();
348 m_aSelectedRanges.realloc( 0 );
349 fireSelectionEvent();
353 void RangeHighlighter::startListening()
355 if( m_xSelectionSupplier.is())
357 if( ! m_xListener.is())
359 m_xListener.set( new WeakSelectionChangeListenerAdapter( this ));
360 determineRanges();
362 m_xSelectionSupplier->addSelectionChangeListener( m_xListener );
366 void RangeHighlighter::stopListening()
368 if( m_xSelectionSupplier.is() && m_xListener.is())
370 m_xSelectionSupplier->removeSelectionChangeListener( m_xListener );
371 m_xListener.clear();
376 // ____ WeakComponentImplHelperBase ____
377 // is called when dispose() is called at this component
378 void SAL_CALL RangeHighlighter::disposing()
380 // @todo: remove listener. Currently the controller shows an assertion
381 // because it is already disposed
382 // stopListening();
383 m_xListener.clear();
384 m_xSelectionSupplier.clear();
385 m_nAddedListenerCount = 0;
386 m_aSelectedRanges.realloc( 0 );
389 } // namespace chart