1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_chart2.hxx"
26*b1cdbd2cSJim Jagielski 
27*b1cdbd2cSJim Jagielski #include "RangeHighlighter.hxx"
28*b1cdbd2cSJim Jagielski #include "WeakListenerAdapter.hxx"
29*b1cdbd2cSJim Jagielski #include "ChartModelHelper.hxx"
30*b1cdbd2cSJim Jagielski #include "DataSourceHelper.hxx"
31*b1cdbd2cSJim Jagielski #include "ContainerHelper.hxx"
32*b1cdbd2cSJim Jagielski #include "macros.hxx"
33*b1cdbd2cSJim Jagielski #include "ObjectIdentifier.hxx"
34*b1cdbd2cSJim Jagielski #include "DataSeriesHelper.hxx"
35*b1cdbd2cSJim Jagielski 
36*b1cdbd2cSJim Jagielski #include <com/sun/star/chart2/XDataSeries.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/chart/ErrorBarStyle.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/drawing/XShape.hpp>
39*b1cdbd2cSJim Jagielski 
40*b1cdbd2cSJim Jagielski #define PREFERED_DEFAULT_COLOR 0x0000ff
41*b1cdbd2cSJim Jagielski 
42*b1cdbd2cSJim Jagielski using namespace ::com::sun::star;
43*b1cdbd2cSJim Jagielski 
44*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Reference;
45*b1cdbd2cSJim Jagielski using ::com::sun::star::uno::Sequence;
46*b1cdbd2cSJim Jagielski using ::rtl::OUString;
47*b1cdbd2cSJim Jagielski 
48*b1cdbd2cSJim Jagielski namespace
49*b1cdbd2cSJim Jagielski {
50*b1cdbd2cSJim Jagielski 
lcl_fillRanges(Sequence<chart2::data::HighlightedRange> & rOutRanges,Sequence<OUString> aRangeStrings,sal_Int32 nPreferredColor=PREFERED_DEFAULT_COLOR,sal_Int32 nIndex=-1)51*b1cdbd2cSJim Jagielski void lcl_fillRanges(
52*b1cdbd2cSJim Jagielski     Sequence< chart2::data::HighlightedRange > & rOutRanges,
53*b1cdbd2cSJim Jagielski     Sequence< OUString > aRangeStrings,
54*b1cdbd2cSJim Jagielski     sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR,
55*b1cdbd2cSJim Jagielski     sal_Int32 nIndex = -1 )
56*b1cdbd2cSJim Jagielski {
57*b1cdbd2cSJim Jagielski     rOutRanges.realloc( aRangeStrings.getLength());
58*b1cdbd2cSJim Jagielski     for( sal_Int32 i=0; i<aRangeStrings.getLength(); ++i )
59*b1cdbd2cSJim Jagielski     {
60*b1cdbd2cSJim Jagielski         rOutRanges[i].RangeRepresentation = aRangeStrings[i];
61*b1cdbd2cSJim Jagielski         rOutRanges[i].PreferredColor = nPreferredColor;
62*b1cdbd2cSJim Jagielski         rOutRanges[i].AllowMerginigWithOtherRanges = sal_False;
63*b1cdbd2cSJim Jagielski         rOutRanges[i].Index = nIndex;
64*b1cdbd2cSJim Jagielski     }
65*b1cdbd2cSJim Jagielski }
66*b1cdbd2cSJim Jagielski 
67*b1cdbd2cSJim Jagielski } // anonymous namespace
68*b1cdbd2cSJim Jagielski 
69*b1cdbd2cSJim Jagielski namespace chart
70*b1cdbd2cSJim Jagielski {
71*b1cdbd2cSJim Jagielski 
RangeHighlighter(const Reference<view::XSelectionSupplier> & xSelectionSupplier)72*b1cdbd2cSJim Jagielski RangeHighlighter::RangeHighlighter(
73*b1cdbd2cSJim Jagielski     const Reference< view::XSelectionSupplier > & xSelectionSupplier ) :
74*b1cdbd2cSJim Jagielski         impl::RangeHighlighter_Base( m_aMutex ),
75*b1cdbd2cSJim Jagielski         m_xSelectionSupplier( xSelectionSupplier ),
76*b1cdbd2cSJim Jagielski         m_nAddedListenerCount( 0 ),
77*b1cdbd2cSJim Jagielski         m_bIncludeHiddenCells(true)
78*b1cdbd2cSJim Jagielski {
79*b1cdbd2cSJim Jagielski }
80*b1cdbd2cSJim Jagielski 
~RangeHighlighter()81*b1cdbd2cSJim Jagielski RangeHighlighter::~RangeHighlighter()
82*b1cdbd2cSJim Jagielski {}
83*b1cdbd2cSJim Jagielski 
84*b1cdbd2cSJim Jagielski // ____ XRangeHighlighter ____
getSelectedRanges()85*b1cdbd2cSJim Jagielski Sequence< chart2::data::HighlightedRange > SAL_CALL RangeHighlighter::getSelectedRanges()
86*b1cdbd2cSJim Jagielski     throw (uno::RuntimeException)
87*b1cdbd2cSJim Jagielski {
88*b1cdbd2cSJim Jagielski     return m_aSelectedRanges;
89*b1cdbd2cSJim Jagielski }
90*b1cdbd2cSJim Jagielski 
determineRanges()91*b1cdbd2cSJim Jagielski void RangeHighlighter::determineRanges()
92*b1cdbd2cSJim Jagielski {
93*b1cdbd2cSJim Jagielski     m_aSelectedRanges.realloc( 0 );
94*b1cdbd2cSJim Jagielski     if( m_xSelectionSupplier.is())
95*b1cdbd2cSJim Jagielski     {
96*b1cdbd2cSJim Jagielski         try
97*b1cdbd2cSJim Jagielski         {
98*b1cdbd2cSJim Jagielski             Reference< frame::XController > xController( m_xSelectionSupplier, uno::UNO_QUERY );
99*b1cdbd2cSJim Jagielski             Reference< frame::XModel > xChartModel;
100*b1cdbd2cSJim Jagielski             if( xController.is())
101*b1cdbd2cSJim Jagielski                 xChartModel.set( xController->getModel());
102*b1cdbd2cSJim Jagielski 
103*b1cdbd2cSJim Jagielski             m_bIncludeHiddenCells = ChartModelHelper::isIncludeHiddenCells( xChartModel );
104*b1cdbd2cSJim Jagielski 
105*b1cdbd2cSJim Jagielski             uno::Any aSelection( m_xSelectionSupplier->getSelection());
106*b1cdbd2cSJim Jagielski             const uno::Type& rType = aSelection.getValueType();
107*b1cdbd2cSJim Jagielski 
108*b1cdbd2cSJim Jagielski             if ( rType == ::getCppuType( static_cast< const OUString* >( 0 ) ) )
109*b1cdbd2cSJim Jagielski             {
110*b1cdbd2cSJim Jagielski                 // @todo??: maybe getSelection() should return a model object rather than a CID
111*b1cdbd2cSJim Jagielski 
112*b1cdbd2cSJim Jagielski                 OUString aCID;
113*b1cdbd2cSJim Jagielski                 aSelection >>= aCID;
114*b1cdbd2cSJim Jagielski                 if ( !aCID.isEmpty() )
115*b1cdbd2cSJim Jagielski                 {
116*b1cdbd2cSJim Jagielski                     ObjectType eObjectType = ObjectIdentifier::getObjectType( aCID );
117*b1cdbd2cSJim Jagielski                     sal_Int32 nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aCID );
118*b1cdbd2cSJim Jagielski                     Reference< chart2::XDataSeries > xDataSeries( ObjectIdentifier::getDataSeriesForCID( aCID, xChartModel ) );
119*b1cdbd2cSJim Jagielski                     if( OBJECTTYPE_LEGEND_ENTRY == eObjectType )
120*b1cdbd2cSJim Jagielski                     {
121*b1cdbd2cSJim Jagielski                         OUString aParentParticel( ObjectIdentifier::getFullParentParticle( aCID ) );
122*b1cdbd2cSJim Jagielski                         ObjectType eParentObjectType = ObjectIdentifier::getObjectType( aParentParticel );
123*b1cdbd2cSJim Jagielski                         eObjectType = eParentObjectType;
124*b1cdbd2cSJim Jagielski                         if( OBJECTTYPE_DATA_POINT == eObjectType )
125*b1cdbd2cSJim Jagielski                             nIndex = ObjectIdentifier::getIndexFromParticleOrCID( aParentParticel );
126*b1cdbd2cSJim Jagielski                     }
127*b1cdbd2cSJim Jagielski 
128*b1cdbd2cSJim Jagielski                     if( OBJECTTYPE_DATA_POINT == eObjectType || OBJECTTYPE_DATA_LABEL == eObjectType )
129*b1cdbd2cSJim Jagielski                     {
130*b1cdbd2cSJim Jagielski                         // Data Point
131*b1cdbd2cSJim Jagielski                         fillRangesForDataPoint( xDataSeries, nIndex );
132*b1cdbd2cSJim Jagielski                         return;
133*b1cdbd2cSJim Jagielski                     }
134*b1cdbd2cSJim Jagielski                     else if( OBJECTTYPE_DATA_ERRORS == eObjectType )
135*b1cdbd2cSJim Jagielski                     {
136*b1cdbd2cSJim Jagielski                         // select error bar ranges, or data series, if the style is
137*b1cdbd2cSJim Jagielski                         // not set to FROM_DATA
138*b1cdbd2cSJim Jagielski                         fillRangesForErrorBars( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), xDataSeries );
139*b1cdbd2cSJim Jagielski                         return;
140*b1cdbd2cSJim Jagielski                     }
141*b1cdbd2cSJim Jagielski                     else if( xDataSeries.is() )
142*b1cdbd2cSJim Jagielski                     {
143*b1cdbd2cSJim Jagielski                         // Data Series
144*b1cdbd2cSJim Jagielski                         fillRangesForDataSeries( xDataSeries );
145*b1cdbd2cSJim Jagielski                         return;
146*b1cdbd2cSJim Jagielski                     }
147*b1cdbd2cSJim Jagielski                     else if( OBJECTTYPE_AXIS == eObjectType )
148*b1cdbd2cSJim Jagielski                     {
149*b1cdbd2cSJim Jagielski                         // Axis (Categories)
150*b1cdbd2cSJim Jagielski                         Reference< chart2::XAxis > xAxis( ObjectIdentifier::getObjectPropertySet( aCID, xChartModel ), uno::UNO_QUERY );
151*b1cdbd2cSJim Jagielski                         if( xAxis.is())
152*b1cdbd2cSJim Jagielski                         {
153*b1cdbd2cSJim Jagielski                             fillRangesForCategories( xAxis );
154*b1cdbd2cSJim Jagielski                             return;
155*b1cdbd2cSJim Jagielski                         }
156*b1cdbd2cSJim Jagielski                     }
157*b1cdbd2cSJim Jagielski                     else if( OBJECTTYPE_PAGE == eObjectType
158*b1cdbd2cSJim Jagielski                              || OBJECTTYPE_DIAGRAM == eObjectType
159*b1cdbd2cSJim Jagielski                              || OBJECTTYPE_DIAGRAM_WALL == eObjectType
160*b1cdbd2cSJim Jagielski                              || OBJECTTYPE_DIAGRAM_FLOOR == eObjectType
161*b1cdbd2cSJim Jagielski                         )
162*b1cdbd2cSJim Jagielski                     {
163*b1cdbd2cSJim Jagielski                         // Diagram
164*b1cdbd2cSJim Jagielski                         Reference< chart2::XDiagram > xDia( ObjectIdentifier::getDiagramForCID( aCID, xChartModel ) );
165*b1cdbd2cSJim Jagielski                         if( xDia.is())
166*b1cdbd2cSJim Jagielski                         {
167*b1cdbd2cSJim Jagielski                             fillRangesForDiagram( xDia );
168*b1cdbd2cSJim Jagielski                             return;
169*b1cdbd2cSJim Jagielski                         }
170*b1cdbd2cSJim Jagielski                     }
171*b1cdbd2cSJim Jagielski                 }
172*b1cdbd2cSJim Jagielski             }
173*b1cdbd2cSJim Jagielski             else if ( rType == ::getCppuType( static_cast< const Reference< drawing::XShape >* >( 0 ) ) )
174*b1cdbd2cSJim Jagielski             {
175*b1cdbd2cSJim Jagielski                 // #i12587# support for shapes in chart
176*b1cdbd2cSJim Jagielski                 Reference< drawing::XShape > xShape;
177*b1cdbd2cSJim Jagielski                 aSelection >>= xShape;
178*b1cdbd2cSJim Jagielski                 if ( xShape.is() )
179*b1cdbd2cSJim Jagielski                 {
180*b1cdbd2cSJim Jagielski                     return;
181*b1cdbd2cSJim Jagielski                 }
182*b1cdbd2cSJim Jagielski             }
183*b1cdbd2cSJim Jagielski             else
184*b1cdbd2cSJim Jagielski             {
185*b1cdbd2cSJim Jagielski                 //if nothing is selected select all ranges
186*b1cdbd2cSJim Jagielski                 Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY_THROW );
187*b1cdbd2cSJim Jagielski                 fillRangesForDiagram( xChartDoc->getFirstDiagram() );
188*b1cdbd2cSJim Jagielski                 return;
189*b1cdbd2cSJim Jagielski             }
190*b1cdbd2cSJim Jagielski         }
191*b1cdbd2cSJim Jagielski         catch( const uno::Exception & ex )
192*b1cdbd2cSJim Jagielski         {
193*b1cdbd2cSJim Jagielski             ASSERT_EXCEPTION( ex );
194*b1cdbd2cSJim Jagielski         }
195*b1cdbd2cSJim Jagielski     }
196*b1cdbd2cSJim Jagielski }
197*b1cdbd2cSJim Jagielski 
fillRangesForDiagram(const Reference<chart2::XDiagram> & xDiagram)198*b1cdbd2cSJim Jagielski void RangeHighlighter::fillRangesForDiagram( const Reference< chart2::XDiagram > & xDiagram )
199*b1cdbd2cSJim Jagielski {
200*b1cdbd2cSJim Jagielski     Sequence< OUString > aSelectedRanges( DataSourceHelper::getUsedDataRanges( xDiagram ));
201*b1cdbd2cSJim Jagielski     m_aSelectedRanges.realloc( aSelectedRanges.getLength());
202*b1cdbd2cSJim Jagielski     // @todo: merge ranges
203*b1cdbd2cSJim Jagielski     for( sal_Int32 i=0; i<aSelectedRanges.getLength(); ++i )
204*b1cdbd2cSJim Jagielski     {
205*b1cdbd2cSJim Jagielski         m_aSelectedRanges[i].RangeRepresentation = aSelectedRanges[i];
206*b1cdbd2cSJim Jagielski         m_aSelectedRanges[i].Index = -1;
207*b1cdbd2cSJim Jagielski         m_aSelectedRanges[i].PreferredColor = PREFERED_DEFAULT_COLOR;
208*b1cdbd2cSJim Jagielski         m_aSelectedRanges[i].AllowMerginigWithOtherRanges = sal_True;
209*b1cdbd2cSJim Jagielski     }
210*b1cdbd2cSJim Jagielski }
211*b1cdbd2cSJim Jagielski 
fillRangesForDataSeries(const uno::Reference<chart2::XDataSeries> & xSeries)212*b1cdbd2cSJim Jagielski void RangeHighlighter::fillRangesForDataSeries( const uno::Reference< chart2::XDataSeries > & xSeries )
213*b1cdbd2cSJim Jagielski {
214*b1cdbd2cSJim Jagielski     sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
215*b1cdbd2cSJim Jagielski     Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
216*b1cdbd2cSJim Jagielski     if( xSource.is())
217*b1cdbd2cSJim Jagielski         lcl_fillRanges( m_aSelectedRanges,
218*b1cdbd2cSJim Jagielski                         ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
219*b1cdbd2cSJim Jagielski                         nPreferredColor );
220*b1cdbd2cSJim Jagielski }
221*b1cdbd2cSJim Jagielski 
fillRangesForErrorBars(const uno::Reference<beans::XPropertySet> & xErrorBar,const uno::Reference<chart2::XDataSeries> & xSeries)222*b1cdbd2cSJim Jagielski void RangeHighlighter::fillRangesForErrorBars(
223*b1cdbd2cSJim Jagielski     const uno::Reference< beans::XPropertySet > & xErrorBar,
224*b1cdbd2cSJim Jagielski     const uno::Reference< chart2::XDataSeries > & xSeries )
225*b1cdbd2cSJim Jagielski {
226*b1cdbd2cSJim Jagielski     // only show error bar ranges, if the style is set to FROM_DATA
227*b1cdbd2cSJim Jagielski     bool bUsesRangesAsErrorBars = false;
228*b1cdbd2cSJim Jagielski     try
229*b1cdbd2cSJim Jagielski     {
230*b1cdbd2cSJim Jagielski         sal_Int32 nStyle = ::com::sun::star::chart::ErrorBarStyle::NONE;
231*b1cdbd2cSJim Jagielski         bUsesRangesAsErrorBars =
232*b1cdbd2cSJim Jagielski             ( xErrorBar.is() &&
233*b1cdbd2cSJim Jagielski               (xErrorBar->getPropertyValue( C2U("ErrorBarStyle")) >>= nStyle) &&
234*b1cdbd2cSJim Jagielski               nStyle == ::com::sun::star::chart::ErrorBarStyle::FROM_DATA );
235*b1cdbd2cSJim Jagielski     }
236*b1cdbd2cSJim Jagielski     catch( const uno::Exception & ex )
237*b1cdbd2cSJim Jagielski     {
238*b1cdbd2cSJim Jagielski         ASSERT_EXCEPTION( ex );
239*b1cdbd2cSJim Jagielski     }
240*b1cdbd2cSJim Jagielski 
241*b1cdbd2cSJim Jagielski     if( bUsesRangesAsErrorBars )
242*b1cdbd2cSJim Jagielski     {
243*b1cdbd2cSJim Jagielski         sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
244*b1cdbd2cSJim Jagielski         Reference< chart2::data::XDataSource > xSource( xErrorBar, uno::UNO_QUERY );
245*b1cdbd2cSJim Jagielski         if( xSource.is())
246*b1cdbd2cSJim Jagielski             lcl_fillRanges( m_aSelectedRanges,
247*b1cdbd2cSJim Jagielski                             ::chart::DataSourceHelper::getRangesFromDataSource( xSource ),
248*b1cdbd2cSJim Jagielski                             nPreferredColor );
249*b1cdbd2cSJim Jagielski     }
250*b1cdbd2cSJim Jagielski     else
251*b1cdbd2cSJim Jagielski     {
252*b1cdbd2cSJim Jagielski         fillRangesForDataSeries( xSeries );
253*b1cdbd2cSJim Jagielski     }
254*b1cdbd2cSJim Jagielski }
255*b1cdbd2cSJim Jagielski 
fillRangesForCategories(const Reference<chart2::XAxis> & xAxis)256*b1cdbd2cSJim Jagielski void RangeHighlighter::fillRangesForCategories( const Reference< chart2::XAxis > & xAxis )
257*b1cdbd2cSJim Jagielski {
258*b1cdbd2cSJim Jagielski     if( ! xAxis.is())
259*b1cdbd2cSJim Jagielski         return;
260*b1cdbd2cSJim Jagielski     chart2::ScaleData aData( xAxis->getScaleData());
261*b1cdbd2cSJim Jagielski     lcl_fillRanges( m_aSelectedRanges,
262*b1cdbd2cSJim Jagielski                     DataSourceHelper::getRangesFromLabeledDataSequence( aData.Categories ));
263*b1cdbd2cSJim Jagielski }
264*b1cdbd2cSJim Jagielski 
fillRangesForDataPoint(const Reference<uno::XInterface> & xDataSeries,sal_Int32 nIndex)265*b1cdbd2cSJim Jagielski void RangeHighlighter::fillRangesForDataPoint( const Reference< uno::XInterface > & xDataSeries, sal_Int32 nIndex )
266*b1cdbd2cSJim Jagielski {
267*b1cdbd2cSJim Jagielski     sal_Int32 nPreferredColor = PREFERED_DEFAULT_COLOR;
268*b1cdbd2cSJim Jagielski     if( xDataSeries.is())
269*b1cdbd2cSJim Jagielski     {
270*b1cdbd2cSJim Jagielski         Reference< chart2::data::XDataSource > xSource( xDataSeries, uno::UNO_QUERY );
271*b1cdbd2cSJim Jagielski         if( xSource.is() )
272*b1cdbd2cSJim Jagielski         {
273*b1cdbd2cSJim Jagielski             ::std::vector< chart2::data::HighlightedRange > aHilightedRanges;
274*b1cdbd2cSJim Jagielski             Sequence< Reference< chart2::data::XLabeledDataSequence > > aLSeqSeq( xSource->getDataSequences());
275*b1cdbd2cSJim Jagielski             for( sal_Int32 i=0; i<aLSeqSeq.getLength(); ++i )
276*b1cdbd2cSJim Jagielski             {
277*b1cdbd2cSJim Jagielski                 Reference< chart2::data::XDataSequence > xLabel( aLSeqSeq[i]->getLabel());
278*b1cdbd2cSJim Jagielski                 Reference< chart2::data::XDataSequence > xValues( aLSeqSeq[i]->getValues());
279*b1cdbd2cSJim Jagielski 
280*b1cdbd2cSJim Jagielski                 if( xLabel.is())
281*b1cdbd2cSJim Jagielski                     aHilightedRanges.push_back(
282*b1cdbd2cSJim Jagielski                         chart2::data::HighlightedRange(
283*b1cdbd2cSJim Jagielski                             xLabel->getSourceRangeRepresentation(),
284*b1cdbd2cSJim Jagielski                             -1,
285*b1cdbd2cSJim Jagielski                             nPreferredColor,
286*b1cdbd2cSJim Jagielski                             sal_False ));
287*b1cdbd2cSJim Jagielski 
288*b1cdbd2cSJim Jagielski                 sal_Int32 nUnhiddenIndex = DataSeriesHelper::translateIndexFromHiddenToFullSequence( nIndex, xValues, !m_bIncludeHiddenCells );
289*b1cdbd2cSJim Jagielski                 if( xValues.is())
290*b1cdbd2cSJim Jagielski                     aHilightedRanges.push_back(
291*b1cdbd2cSJim Jagielski                         chart2::data::HighlightedRange(
292*b1cdbd2cSJim Jagielski                             xValues->getSourceRangeRepresentation(),
293*b1cdbd2cSJim Jagielski                             nUnhiddenIndex,
294*b1cdbd2cSJim Jagielski                             nPreferredColor,
295*b1cdbd2cSJim Jagielski                             sal_False ));
296*b1cdbd2cSJim Jagielski             }
297*b1cdbd2cSJim Jagielski             m_aSelectedRanges = ContainerHelper::ContainerToSequence( aHilightedRanges );
298*b1cdbd2cSJim Jagielski         }
299*b1cdbd2cSJim Jagielski     }
300*b1cdbd2cSJim Jagielski }
301*b1cdbd2cSJim Jagielski 
addSelectionChangeListener(const Reference<view::XSelectionChangeListener> & xListener)302*b1cdbd2cSJim Jagielski void SAL_CALL RangeHighlighter::addSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
303*b1cdbd2cSJim Jagielski     throw (uno::RuntimeException)
304*b1cdbd2cSJim Jagielski {
305*b1cdbd2cSJim Jagielski     if(!xListener.is())
306*b1cdbd2cSJim Jagielski         return;
307*b1cdbd2cSJim Jagielski 
308*b1cdbd2cSJim Jagielski     if( m_nAddedListenerCount == 0 )
309*b1cdbd2cSJim Jagielski         startListening();
310*b1cdbd2cSJim Jagielski     rBHelper.addListener( ::getCppuType( & xListener ), xListener);
311*b1cdbd2cSJim Jagielski     ++m_nAddedListenerCount;
312*b1cdbd2cSJim Jagielski 
313*b1cdbd2cSJim Jagielski     //bring the new listener up to the current state
314*b1cdbd2cSJim Jagielski     lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
315*b1cdbd2cSJim Jagielski     xListener->selectionChanged( aEvent );
316*b1cdbd2cSJim Jagielski }
317*b1cdbd2cSJim Jagielski 
removeSelectionChangeListener(const Reference<view::XSelectionChangeListener> & xListener)318*b1cdbd2cSJim Jagielski void SAL_CALL RangeHighlighter::removeSelectionChangeListener( const Reference< view::XSelectionChangeListener >& xListener )
319*b1cdbd2cSJim Jagielski     throw (uno::RuntimeException)
320*b1cdbd2cSJim Jagielski {
321*b1cdbd2cSJim Jagielski     rBHelper.removeListener( ::getCppuType( & xListener ), xListener );
322*b1cdbd2cSJim Jagielski     --m_nAddedListenerCount;
323*b1cdbd2cSJim Jagielski     if( m_nAddedListenerCount == 0 )
324*b1cdbd2cSJim Jagielski         stopListening();
325*b1cdbd2cSJim Jagielski }
326*b1cdbd2cSJim Jagielski 
327*b1cdbd2cSJim Jagielski // ____ XSelectionChangeListener ____
selectionChanged(const lang::EventObject &)328*b1cdbd2cSJim Jagielski void SAL_CALL RangeHighlighter::selectionChanged( const lang::EventObject& /*aEvent*/ )
329*b1cdbd2cSJim Jagielski     throw (uno::RuntimeException)
330*b1cdbd2cSJim Jagielski {
331*b1cdbd2cSJim Jagielski     determineRanges();
332*b1cdbd2cSJim Jagielski 
333*b1cdbd2cSJim Jagielski     // determine ranges of selected view objects
334*b1cdbd2cSJim Jagielski     // if changed, fire an event
335*b1cdbd2cSJim Jagielski     fireSelectionEvent();
336*b1cdbd2cSJim Jagielski }
337*b1cdbd2cSJim Jagielski 
fireSelectionEvent()338*b1cdbd2cSJim Jagielski void RangeHighlighter::fireSelectionEvent()
339*b1cdbd2cSJim Jagielski {
340*b1cdbd2cSJim Jagielski 	::cppu::OInterfaceContainerHelper* pIC = rBHelper.getContainer(
341*b1cdbd2cSJim Jagielski         ::getCppuType((const uno::Reference< view::XSelectionChangeListener >*)0) );
342*b1cdbd2cSJim Jagielski 	if( pIC )
343*b1cdbd2cSJim Jagielski 	{
344*b1cdbd2cSJim Jagielski 		lang::EventObject aEvent( static_cast< lang::XComponent* >( this ) );
345*b1cdbd2cSJim Jagielski 		::cppu::OInterfaceIteratorHelper aIt( *pIC );
346*b1cdbd2cSJim Jagielski 		while( aIt.hasMoreElements() )
347*b1cdbd2cSJim Jagielski         {
348*b1cdbd2cSJim Jagielski             uno::Reference< view::XSelectionChangeListener > xListener( aIt.next(), uno::UNO_QUERY );
349*b1cdbd2cSJim Jagielski             if( xListener.is() )
350*b1cdbd2cSJim Jagielski                 xListener->selectionChanged( aEvent );
351*b1cdbd2cSJim Jagielski         }
352*b1cdbd2cSJim Jagielski 	}
353*b1cdbd2cSJim Jagielski }
354*b1cdbd2cSJim Jagielski 
disposing(const lang::EventObject & Source)355*b1cdbd2cSJim Jagielski void SAL_CALL RangeHighlighter::disposing( const lang::EventObject& Source )
356*b1cdbd2cSJim Jagielski     throw (uno::RuntimeException)
357*b1cdbd2cSJim Jagielski {
358*b1cdbd2cSJim Jagielski     if( Source.Source == m_xSelectionSupplier )
359*b1cdbd2cSJim Jagielski     {
360*b1cdbd2cSJim Jagielski         m_xSelectionSupplier.clear();
361*b1cdbd2cSJim Jagielski         m_aSelectedRanges.realloc( 0 );
362*b1cdbd2cSJim Jagielski         fireSelectionEvent();
363*b1cdbd2cSJim Jagielski     }
364*b1cdbd2cSJim Jagielski }
365*b1cdbd2cSJim Jagielski 
startListening()366*b1cdbd2cSJim Jagielski void RangeHighlighter::startListening()
367*b1cdbd2cSJim Jagielski {
368*b1cdbd2cSJim Jagielski     if( m_xSelectionSupplier.is())
369*b1cdbd2cSJim Jagielski     {
370*b1cdbd2cSJim Jagielski         if( ! m_xListener.is())
371*b1cdbd2cSJim Jagielski         {
372*b1cdbd2cSJim Jagielski             m_xListener.set( new WeakSelectionChangeListenerAdapter( this ));
373*b1cdbd2cSJim Jagielski             determineRanges();
374*b1cdbd2cSJim Jagielski         }
375*b1cdbd2cSJim Jagielski         m_xSelectionSupplier->addSelectionChangeListener( m_xListener );
376*b1cdbd2cSJim Jagielski     }
377*b1cdbd2cSJim Jagielski }
378*b1cdbd2cSJim Jagielski 
stopListening()379*b1cdbd2cSJim Jagielski void RangeHighlighter::stopListening()
380*b1cdbd2cSJim Jagielski {
381*b1cdbd2cSJim Jagielski     if( m_xSelectionSupplier.is() && m_xListener.is())
382*b1cdbd2cSJim Jagielski     {
383*b1cdbd2cSJim Jagielski         m_xSelectionSupplier->removeSelectionChangeListener( m_xListener );
384*b1cdbd2cSJim Jagielski         m_xListener.clear();
385*b1cdbd2cSJim Jagielski     }
386*b1cdbd2cSJim Jagielski }
387*b1cdbd2cSJim Jagielski 
388*b1cdbd2cSJim Jagielski 
389*b1cdbd2cSJim Jagielski // ____ WeakComponentImplHelperBase ____
390*b1cdbd2cSJim Jagielski // is called when dispose() is called at this component
disposing()391*b1cdbd2cSJim Jagielski void SAL_CALL RangeHighlighter::disposing()
392*b1cdbd2cSJim Jagielski {
393*b1cdbd2cSJim Jagielski     // @todo: remove listener. Currently the controller shows an assertion
394*b1cdbd2cSJim Jagielski     // because it is already disposed
395*b1cdbd2cSJim Jagielski //     stopListening();
396*b1cdbd2cSJim Jagielski     m_xListener.clear();
397*b1cdbd2cSJim Jagielski     m_xSelectionSupplier.clear();
398*b1cdbd2cSJim Jagielski     m_nAddedListenerCount =  0;
399*b1cdbd2cSJim Jagielski     m_aSelectedRanges.realloc( 0 );
400*b1cdbd2cSJim Jagielski }
401*b1cdbd2cSJim Jagielski 
402*b1cdbd2cSJim Jagielski } //  namespace chart
403