2010-10-12 15:59:00 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-07-17 12:30:48 +01:00
|
|
|
/*
|
|
|
|
* This file is part of the LibreOffice project.
|
|
|
|
*
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
|
*
|
|
|
|
* This file incorporates work covered by the following license notice:
|
|
|
|
*
|
|
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
|
|
* with this work for additional information regarding copyright
|
|
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
|
|
*/
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
#include <rtl/math.hxx>
|
|
|
|
|
2018-07-25 18:40:01 +02:00
|
|
|
#include <iterator>
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2017-10-23 22:44:16 +02:00
|
|
|
#include <InternalDataProvider.hxx>
|
|
|
|
#include <LabeledDataSequence.hxx>
|
|
|
|
#include <DataSource.hxx>
|
|
|
|
#include <XMLRangeHelper.hxx>
|
|
|
|
#include <CommonFunctors.hxx>
|
|
|
|
#include <UncachedDataSequence.hxx>
|
|
|
|
#include <DataSourceHelper.hxx>
|
2018-08-05 16:09:23 +02:00
|
|
|
#include <ChartModel.hxx>
|
2017-10-23 22:44:16 +02:00
|
|
|
#include <ChartModelHelper.hxx>
|
|
|
|
#include <DiagramHelper.hxx>
|
|
|
|
#include <ExplicitCategoriesProvider.hxx>
|
2010-01-13 17:06:34 +01:00
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
#include <com/sun/star/chart2/data/XDataSequence.hpp>
|
|
|
|
#include <com/sun/star/chart/ChartDataRowSource.hpp>
|
2014-12-09 08:30:11 +02:00
|
|
|
#include <cppuhelper/supportsservice.hxx>
|
2008-06-16 11:56:50 +00:00
|
|
|
#include <comphelper/sequenceashashmap.hxx>
|
2018-05-21 18:13:17 +02:00
|
|
|
#include <comphelper/property.hxx>
|
2018-04-05 16:20:13 +02:00
|
|
|
#include <tools/diagnose_ex.h>
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
#include <vector>
|
2008-03-06 16:43:34 +00:00
|
|
|
#include <algorithm>
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2020-01-14 15:21:18 +02:00
|
|
|
namespace com::sun::star::chart2 { class XChartDocument; }
|
2018-10-08 01:04:52 +02:00
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
using namespace ::com::sun::star;
|
|
|
|
using namespace ::std;
|
|
|
|
|
|
|
|
using ::com::sun::star::uno::Reference;
|
|
|
|
using ::com::sun::star::uno::Sequence;
|
|
|
|
|
|
|
|
namespace chart
|
|
|
|
{
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
2020-06-30 18:31:56 +02:00
|
|
|
const char lcl_aCategoriesRangeName[] = "categories";
|
|
|
|
const char lcl_aCategoriesLevelRangeNamePrefix[] = "categoriesL "; //L <-> level
|
|
|
|
const char lcl_aCategoriesPointRangeNamePrefix[] = "categoriesP "; //P <-> point
|
|
|
|
const char lcl_aCategoriesRoleName[] = "categories";
|
|
|
|
const char lcl_aLabelRangePrefix[] = "label ";
|
|
|
|
const char lcl_aCompleteRange[] = "all";
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2017-02-15 23:55:18 +02:00
|
|
|
typedef std::multimap< OUString, uno::WeakReference< chart2::data::XDataSequence > >
|
2007-05-22 17:59:49 +00:00
|
|
|
lcl_tSequenceMap;
|
|
|
|
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< OUString > lcl_AnyToStringSequence( const std::vector< uno::Any >& aAnySeq )
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< OUString > aResult;
|
|
|
|
aResult.resize( aAnySeq.size() );
|
|
|
|
int i = 0;
|
|
|
|
for (const uno::Any& aAny : aAnySeq)
|
|
|
|
aResult[i++] = CommonFunctors::AnyToString()(aAny);
|
2010-11-30 01:45:03 +01:00
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< uno::Any > lcl_StringToAnyVector( const css::uno::Sequence< OUString >& aStringSeq )
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< uno::Any > aResult;
|
|
|
|
aResult.resize( aStringSeq.getLength() );
|
|
|
|
int i = 0;
|
|
|
|
for (const OUString& aStr : aStringSeq)
|
|
|
|
aResult[i++] = CommonFunctors::makeAny<OUString>()(aStr);
|
2010-11-30 01:45:03 +01:00
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_setModified
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
void operator() ( const lcl_tSequenceMap::value_type & rMapEntry )
|
|
|
|
{
|
|
|
|
// convert weak reference to reference
|
|
|
|
Reference< chart2::data::XDataSequence > xSeq( rMapEntry.second );
|
|
|
|
if( xSeq.is())
|
|
|
|
{
|
|
|
|
Reference< util::XModifiable > xMod( xSeq, uno::UNO_QUERY );
|
|
|
|
if( xMod.is())
|
2016-04-20 17:15:21 +02:00
|
|
|
xMod->setModified( true );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_internalizeSeries
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2009-12-21 10:27:32 +01:00
|
|
|
lcl_internalizeSeries( InternalData & rInternalData,
|
2010-01-13 17:06:34 +01:00
|
|
|
InternalDataProvider & rProvider,
|
|
|
|
bool bConnectToModel, bool bDataInColumns ) :
|
2007-05-22 17:59:49 +00:00
|
|
|
m_rInternalData( rInternalData ),
|
2010-01-13 17:06:34 +01:00
|
|
|
m_rProvider( rProvider ),
|
|
|
|
m_bConnectToModel( bConnectToModel ),
|
|
|
|
m_bDataInColumns( bDataInColumns )
|
2007-05-22 17:59:49 +00:00
|
|
|
{}
|
|
|
|
void operator() ( const Reference< chart2::XDataSeries > & xSeries )
|
|
|
|
{
|
|
|
|
Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY );
|
|
|
|
Reference< chart2::data::XDataSink > xSink( xSeries, uno::UNO_QUERY );
|
2020-04-18 14:08:51 +02:00
|
|
|
if( !(xSource.is() && xSink.is()) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
Sequence< Reference< chart2::data::XLabeledDataSequence > > aOldSeriesData = xSource->getDataSequences();
|
|
|
|
Sequence< Reference< chart2::data::XLabeledDataSequence > > aNewSeriesData( aOldSeriesData.getLength() );
|
|
|
|
for( sal_Int32 i=0; i<aOldSeriesData.getLength(); ++i )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2020-04-18 14:08:51 +02:00
|
|
|
sal_Int32 nNewIndex( m_bDataInColumns ? m_rInternalData.appendColumn() : m_rInternalData.appendRow() );
|
|
|
|
OUString aIdentifier( OUString::number( nNewIndex ));
|
|
|
|
//@todo: deal also with genericXDataSequence
|
|
|
|
Reference< chart2::data::XNumericalDataSequence > xValues( aOldSeriesData[i]->getValues(), uno::UNO_QUERY );
|
|
|
|
Reference< chart2::data::XTextualDataSequence > xLabel( aOldSeriesData[i]->getLabel(), uno::UNO_QUERY );
|
|
|
|
Reference< chart2::data::XDataSequence > xNewValues;
|
|
|
|
|
|
|
|
if( xValues.is() )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2020-04-18 14:08:51 +02:00
|
|
|
auto aValues( comphelper::sequenceToContainer<std::vector< double >>( xValues->getNumericalData()));
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_rInternalData.setColumnValues( nNewIndex, aValues );
|
|
|
|
else
|
|
|
|
m_rInternalData.setRowValues( nNewIndex, aValues );
|
|
|
|
if( m_bConnectToModel )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2020-04-18 14:08:51 +02:00
|
|
|
xNewValues.set( m_rProvider.createDataSequenceByRangeRepresentation( aIdentifier ));
|
|
|
|
comphelper::copyProperties(
|
|
|
|
Reference< beans::XPropertySet >( xValues, uno::UNO_QUERY ),
|
|
|
|
Reference< beans::XPropertySet >( xNewValues, uno::UNO_QUERY ));
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2020-04-18 14:08:51 +02:00
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
|
2020-04-18 14:08:51 +02:00
|
|
|
if( xLabel.is() )
|
|
|
|
{
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_rInternalData.setComplexColumnLabel( nNewIndex, lcl_StringToAnyVector( xLabel->getTextualData() ) );
|
2010-01-13 17:06:34 +01:00
|
|
|
else
|
2020-04-18 14:08:51 +02:00
|
|
|
m_rInternalData.setComplexRowLabel( nNewIndex, lcl_StringToAnyVector( xLabel->getTextualData() ) );
|
|
|
|
if( m_bConnectToModel )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2020-04-18 14:08:51 +02:00
|
|
|
Reference< chart2::data::XDataSequence > xNewLabel(
|
|
|
|
m_rProvider.createDataSequenceByRangeRepresentation( lcl_aLabelRangePrefix + aIdentifier ));
|
|
|
|
comphelper::copyProperties(
|
|
|
|
Reference< beans::XPropertySet >( xLabel, uno::UNO_QUERY ),
|
|
|
|
Reference< beans::XPropertySet >( xNewLabel, uno::UNO_QUERY ));
|
|
|
|
aNewSeriesData[i].set( new LabeledDataSequence( xNewValues, xNewLabel ) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
}
|
2020-04-18 14:08:51 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if( m_bConnectToModel )
|
|
|
|
aNewSeriesData[i].set( new LabeledDataSequence( xNewValues ) );
|
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2020-04-18 14:08:51 +02:00
|
|
|
if( m_bConnectToModel )
|
|
|
|
xSink->setData( aNewSeriesData );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
2009-12-21 10:27:32 +01:00
|
|
|
InternalData & m_rInternalData;
|
2007-05-22 17:59:49 +00:00
|
|
|
InternalDataProvider & m_rProvider;
|
2010-01-13 17:06:34 +01:00
|
|
|
bool m_bConnectToModel;
|
|
|
|
bool m_bDataInColumns;
|
2007-05-22 17:59:49 +00:00
|
|
|
};
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_copyFromLevel
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
|
|
|
public:
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
explicit lcl_copyFromLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
2010-01-13 17:06:34 +01:00
|
|
|
{}
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
uno::Any operator() ( const vector< uno::Any >& rVector )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
uno::Any aRet;
|
2010-01-29 17:23:04 +01:00
|
|
|
if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
|
2010-11-30 01:45:03 +01:00
|
|
|
aRet = rVector[m_nLevel];
|
|
|
|
return aRet;
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_getStringFromLevelVector
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
explicit lcl_getStringFromLevelVector( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
|
|
|
{}
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
OUString operator() ( const vector< uno::Any >& rVector )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
|
|
|
OUString aString;
|
2010-01-29 17:23:04 +01:00
|
|
|
if( m_nLevel < static_cast< sal_Int32 >(rVector.size()) )
|
2010-11-30 01:45:03 +01:00
|
|
|
aString = CommonFunctors::AnyToString()(rVector[m_nLevel]);
|
2010-01-13 17:06:34 +01:00
|
|
|
return aString;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2017-07-02 17:10:53 +02:00
|
|
|
struct lcl_setAnyAtLevel
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
explicit lcl_setAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
|
|
|
{}
|
|
|
|
|
|
|
|
vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const uno::Any& rNewValue )
|
|
|
|
{
|
|
|
|
vector< uno::Any > aRet( rVector );
|
|
|
|
if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
|
|
|
|
aRet.resize( m_nLevel+1 );
|
|
|
|
aRet[ m_nLevel ]=rNewValue;
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
|
|
|
|
2017-07-02 17:10:53 +02:00
|
|
|
struct lcl_setAnyAtLevelFromStringSequence
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
public:
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
explicit lcl_setAnyAtLevelFromStringSequence( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
2010-01-13 17:06:34 +01:00
|
|
|
{}
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< uno::Any > operator() ( const vector< uno::Any >& rVector, const OUString& rNewValue )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< uno::Any > aRet( rVector );
|
2010-01-29 17:23:04 +01:00
|
|
|
if( m_nLevel >= static_cast< sal_Int32 >(aRet.size()) )
|
2010-01-13 17:06:34 +01:00
|
|
|
aRet.resize( m_nLevel+1 );
|
2017-02-03 08:54:47 +02:00
|
|
|
aRet[ m_nLevel ] <<= rNewValue;
|
2010-01-13 17:06:34 +01:00
|
|
|
return aRet;
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_insertAnyAtLevel
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
explicit lcl_insertAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
2010-01-28 10:52:28 +01:00
|
|
|
{}
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
void operator() ( vector< uno::Any >& rVector )
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
2013-04-01 20:14:27 +02:00
|
|
|
if( m_nLevel >= static_cast< sal_Int32 >(rVector.size()) )
|
|
|
|
{
|
|
|
|
rVector.resize( m_nLevel + 1 );
|
|
|
|
}
|
|
|
|
else
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
2013-04-01 20:14:27 +02:00
|
|
|
rVector.insert( rVector.begin() + m_nLevel, uno::Any() );
|
2010-01-28 10:52:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
|
|
|
|
2017-06-28 21:48:22 +02:00
|
|
|
struct lcl_removeAnyAtLevel
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
explicit lcl_removeAnyAtLevel( sal_Int32 nLevel ) : m_nLevel( nLevel )
|
2010-01-28 10:52:28 +01:00
|
|
|
{}
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
void operator() ( vector< uno::Any >& rVector )
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
2013-04-01 20:14:27 +02:00
|
|
|
if( m_nLevel < static_cast<sal_Int32>(rVector.size()) )
|
2010-01-28 10:52:28 +01:00
|
|
|
{
|
2013-04-01 20:14:27 +02:00
|
|
|
rVector.erase(rVector.begin() + m_nLevel);
|
2010-01-28 10:52:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
sal_Int32 m_nLevel;
|
|
|
|
};
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
} // anonymous namespace
|
|
|
|
|
2017-07-28 07:28:07 +02:00
|
|
|
InternalDataProvider::InternalDataProvider()
|
2010-01-13 17:06:34 +01:00
|
|
|
: m_bDataInColumns( true )
|
|
|
|
{}
|
|
|
|
|
2013-07-01 10:43:33 +00:00
|
|
|
InternalDataProvider::InternalDataProvider(
|
|
|
|
const Reference< chart2::XChartDocument > & xChartDoc,
|
|
|
|
bool bConnectToModel,
|
|
|
|
bool bDefaultDataInColumns)
|
|
|
|
: m_bDataInColumns( bDefaultDataInColumns )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDoc ) );
|
|
|
|
if( xDiagram.is())
|
|
|
|
{
|
2019-07-19 09:50:11 +02:00
|
|
|
Reference< frame::XModel > xChartModel = xChartDoc;
|
2010-01-13 17:06:34 +01:00
|
|
|
|
|
|
|
//data in columns?
|
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString aRangeString;
|
2010-01-13 17:06:34 +01:00
|
|
|
bool bFirstCellAsLabel = true;
|
|
|
|
bool bHasCategories = true;
|
|
|
|
uno::Sequence< sal_Int32 > aSequenceMapping;
|
2013-07-01 10:43:33 +00:00
|
|
|
const bool bSomethingDetected(
|
|
|
|
DataSourceHelper::detectRangeSegmentation(
|
|
|
|
xChartModel, aRangeString, aSequenceMapping, m_bDataInColumns, bFirstCellAsLabel, bHasCategories ));
|
|
|
|
|
|
|
|
// #i120559# if no data was available, restore default
|
|
|
|
if(!bSomethingDetected && m_bDataInColumns != bDefaultDataInColumns)
|
|
|
|
{
|
|
|
|
m_bDataInColumns = bDefaultDataInColumns;
|
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
// categories
|
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aNewCategories;//inner count is level
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2019-01-07 13:52:59 +02:00
|
|
|
ChartModel& rModel = dynamic_cast<ChartModel&>(*xChartModel);
|
2014-06-10 15:37:46 +01:00
|
|
|
ExplicitCategoriesProvider aExplicitCategoriesProvider(ChartModelHelper::getFirstCoordinateSystem(xChartModel), rModel);
|
2010-11-30 01:45:03 +01:00
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
const Sequence< Reference< chart2::data::XLabeledDataSequence> >& rSplitCategoriesList( aExplicitCategoriesProvider.getSplitCategoriesList() );
|
|
|
|
sal_Int32 nLevelCount = rSplitCategoriesList.getLength();
|
|
|
|
for( sal_Int32 nL = 0; nL<nLevelCount; nL++ )
|
|
|
|
{
|
|
|
|
Reference< chart2::data::XLabeledDataSequence > xLDS( rSplitCategoriesList[nL] );
|
|
|
|
if( !xLDS.is() )
|
|
|
|
continue;
|
2010-11-30 01:45:03 +01:00
|
|
|
Sequence< uno::Any > aDataSeq;
|
2011-01-14 18:11:00 +01:00
|
|
|
Reference< chart2::data::XDataSequence > xSeq( xLDS->getValues() );
|
2010-01-13 17:06:34 +01:00
|
|
|
if( xSeq.is() )
|
2011-01-14 18:11:00 +01:00
|
|
|
aDataSeq = xSeq->getData();
|
2010-11-30 01:45:03 +01:00
|
|
|
sal_Int32 nLength = aDataSeq.getLength();
|
2010-10-07 16:43:07 +02:00
|
|
|
sal_Int32 nCatLength = static_cast< sal_Int32 >(aNewCategories.size());
|
|
|
|
if( nCatLength < nLength )
|
2010-01-13 17:06:34 +01:00
|
|
|
aNewCategories.resize( nLength );
|
2010-10-07 16:43:07 +02:00
|
|
|
else if( nLength < nCatLength )
|
2011-01-15 17:21:37 +01:00
|
|
|
aDataSeq.realloc( nCatLength );
|
2010-11-30 01:45:03 +01:00
|
|
|
transform( aNewCategories.begin(), aNewCategories.end(), aDataSeq.getConstArray(),
|
2011-01-17 17:10:29 +01:00
|
|
|
aNewCategories.begin(), lcl_setAnyAtLevel(nL) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
if( !nLevelCount )
|
|
|
|
{
|
|
|
|
Sequence< OUString > aSimplecategories = aExplicitCategoriesProvider.getSimpleCategories();
|
|
|
|
sal_Int32 nLength = aSimplecategories.getLength();
|
|
|
|
aNewCategories.reserve( nLength );
|
|
|
|
for( sal_Int32 nN=0; nN<nLength; nN++)
|
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< uno::Any > aVector(1);
|
2017-02-03 08:54:47 +02:00
|
|
|
aVector[0] <<= aSimplecategories[nN];
|
2010-11-30 01:45:03 +01:00
|
|
|
aNewCategories.push_back( aVector );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_aInternalData.setComplexRowLabels( aNewCategories );
|
|
|
|
else
|
|
|
|
m_aInternalData.setComplexColumnLabels( aNewCategories );
|
|
|
|
if( bConnectToModel )
|
|
|
|
DiagramHelper::setCategoriesToDiagram( new LabeledDataSequence(
|
|
|
|
createDataSequenceByRangeRepresentation( lcl_aCategoriesRangeName )), xDiagram );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// data series
|
2017-02-15 23:55:18 +02:00
|
|
|
std::vector< Reference< chart2::XDataSeries > > aSeriesVector( ChartModelHelper::getDataSeries( xChartDoc ));
|
2015-09-27 19:21:35 -04:00
|
|
|
lcl_internalizeSeries ftor( m_aInternalData, *this, bConnectToModel, m_bDataInColumns );
|
|
|
|
for( const auto& rxScreen : aSeriesVector )
|
|
|
|
ftor( rxScreen );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
2018-04-05 16:20:13 +02:00
|
|
|
catch( const uno::Exception & )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2018-04-05 16:20:13 +02:00
|
|
|
DBG_UNHANDLED_EXCEPTION("chart2");
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// copy-CTOR
|
|
|
|
InternalDataProvider::InternalDataProvider( const InternalDataProvider & rOther ) :
|
2018-09-10 09:29:12 +02:00
|
|
|
impl::InternalDataProvider_Base(rOther),
|
2007-05-22 17:59:49 +00:00
|
|
|
m_aSequenceMap( rOther.m_aSequenceMap ),
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData( rOther.m_aInternalData ),
|
2007-05-22 17:59:49 +00:00
|
|
|
m_bDataInColumns( rOther.m_bDataInColumns )
|
|
|
|
{}
|
|
|
|
|
|
|
|
InternalDataProvider::~InternalDataProvider()
|
|
|
|
{}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
void InternalDataProvider::addDataSequenceToMap(
|
2007-05-22 17:59:49 +00:00
|
|
|
const OUString & rRangeRepresentation,
|
|
|
|
const Reference< chart2::data::XDataSequence > & xSequence )
|
|
|
|
{
|
2017-08-11 11:36:47 +02:00
|
|
|
m_aSequenceMap.emplace(
|
2007-05-22 17:59:49 +00:00
|
|
|
rRangeRepresentation,
|
2017-08-11 11:36:47 +02:00
|
|
|
uno::WeakReference< chart2::data::XDataSequence >( xSequence ));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
void InternalDataProvider::deleteMapReferences( const OUString & rRangeRepresentation )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
// set sequence to deleted by setting its range to an empty string
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( rRangeRepresentation ));
|
|
|
|
for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
|
|
|
|
{
|
|
|
|
Reference< chart2::data::XDataSequence > xSeq( aIt->second );
|
|
|
|
if( xSeq.is())
|
|
|
|
{
|
|
|
|
Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
|
|
|
|
if( xNamed.is())
|
|
|
|
xNamed->setName( OUString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// remove from map
|
|
|
|
m_aSequenceMap.erase( aRange.first, aRange.second );
|
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
void InternalDataProvider::adaptMapReferences(
|
2007-05-22 17:59:49 +00:00
|
|
|
const OUString & rOldRangeRepresentation,
|
|
|
|
const OUString & rNewRangeRepresentation )
|
|
|
|
{
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( rOldRangeRepresentation ));
|
2007-07-25 07:57:46 +00:00
|
|
|
tSequenceMap aNewElements;
|
2007-05-22 17:59:49 +00:00
|
|
|
for( tSequenceMap::iterator aIt( aRange.first ); aIt != aRange.second; ++aIt )
|
|
|
|
{
|
|
|
|
Reference< chart2::data::XDataSequence > xSeq( aIt->second );
|
|
|
|
if( xSeq.is())
|
|
|
|
{
|
|
|
|
Reference< container::XNamed > xNamed( xSeq, uno::UNO_QUERY );
|
|
|
|
if( xNamed.is())
|
|
|
|
xNamed->setName( rNewRangeRepresentation );
|
|
|
|
}
|
2017-08-10 16:43:55 +02:00
|
|
|
aNewElements.emplace( rNewRangeRepresentation, aIt->second );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
// erase map values for old index
|
|
|
|
m_aSequenceMap.erase( aRange.first, aRange.second );
|
|
|
|
// add new entries for values with new index
|
2020-06-23 15:02:35 +02:00
|
|
|
m_aSequenceMap.insert( aNewElements.begin(), aNewElements.end() );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
void InternalDataProvider::increaseMapReferences(
|
2007-05-22 17:59:49 +00:00
|
|
|
sal_Int32 nBegin, sal_Int32 nEnd )
|
|
|
|
{
|
|
|
|
for( sal_Int32 nIndex = nEnd - 1; nIndex >= nBegin; --nIndex )
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
adaptMapReferences( OUString::number( nIndex ),
|
2013-08-21 15:07:31 +02:00
|
|
|
OUString::number( nIndex + 1 ));
|
2014-06-24 18:40:54 -04:00
|
|
|
adaptMapReferences( lcl_aLabelRangePrefix + OUString::number( nIndex ),
|
2013-08-21 15:07:31 +02:00
|
|
|
lcl_aLabelRangePrefix + OUString::number( nIndex + 1 ));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
void InternalDataProvider::decreaseMapReferences(
|
2007-05-22 17:59:49 +00:00
|
|
|
sal_Int32 nBegin, sal_Int32 nEnd )
|
|
|
|
{
|
|
|
|
for( sal_Int32 nIndex = nBegin; nIndex < nEnd; ++nIndex )
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
adaptMapReferences( OUString::number( nIndex ),
|
2013-08-21 15:07:31 +02:00
|
|
|
OUString::number( nIndex - 1 ));
|
2014-06-24 18:40:54 -04:00
|
|
|
adaptMapReferences( lcl_aLabelRangePrefix + OUString::number( nIndex ),
|
2013-08-21 15:07:31 +02:00
|
|
|
lcl_aLabelRangePrefix + OUString::number( nIndex - 1 ));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
Reference< chart2::data::XDataSequence > InternalDataProvider::createDataSequenceAndAddToMap(
|
2007-05-22 17:59:49 +00:00
|
|
|
const OUString & rRangeRepresentation )
|
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
Reference<chart2::data::XDataSequence> xSeq = createDataSequenceFromArray(rRangeRepresentation, OUString());
|
|
|
|
if (xSeq.is())
|
|
|
|
return xSeq;
|
|
|
|
|
|
|
|
xSeq.set(new UncachedDataSequence(this, rRangeRepresentation));
|
|
|
|
addDataSequenceToMap(rRangeRepresentation, xSeq);
|
|
|
|
return xSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
uno::Reference<chart2::data::XDataSequence>
|
|
|
|
InternalDataProvider::createDataSequenceFromArray( const OUString& rArrayStr, const OUString& rRole )
|
|
|
|
{
|
|
|
|
if (rArrayStr.indexOf('{') != 0 || rArrayStr[rArrayStr.getLength()-1] != '}')
|
|
|
|
{
|
|
|
|
// Not an array string.
|
|
|
|
return uno::Reference<chart2::data::XDataSequence>();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool bAllNumeric = true;
|
|
|
|
uno::Reference<chart2::data::XDataSequence> xSeq;
|
|
|
|
|
|
|
|
const sal_Unicode* p = rArrayStr.getStr();
|
|
|
|
const sal_Unicode* pEnd = p + rArrayStr.getLength();
|
2015-11-10 10:11:17 +01:00
|
|
|
const sal_Unicode* pElem = nullptr;
|
2014-07-02 09:53:54 -04:00
|
|
|
OUString aElem;
|
|
|
|
|
|
|
|
std::vector<OUString> aRawElems;
|
|
|
|
++p; // Skip the first '{'.
|
|
|
|
--pEnd; // Skip the last '}'.
|
|
|
|
bool bInQuote = false;
|
|
|
|
for (; p != pEnd; ++p)
|
|
|
|
{
|
|
|
|
if (*p == '"')
|
2010-10-15 15:40:19 +05:30
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
bInQuote = !bInQuote;
|
|
|
|
if (bInQuote)
|
2010-10-15 15:40:19 +05:30
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
// Opening quote.
|
2016-10-18 23:36:51 +02:00
|
|
|
pElem = nullptr;
|
2010-10-15 15:40:19 +05:30
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
// Closing quote.
|
|
|
|
if (pElem)
|
|
|
|
aElem = OUString(pElem, p-pElem);
|
2019-08-27 10:55:30 +02:00
|
|
|
// Non empty string
|
|
|
|
if (!aElem.isEmpty())
|
|
|
|
bAllNumeric = false;
|
2014-07-02 09:53:54 -04:00
|
|
|
aRawElems.push_back(aElem);
|
2015-11-10 10:11:17 +01:00
|
|
|
pElem = nullptr;
|
2014-11-12 14:24:10 +05:30
|
|
|
aElem.clear();
|
2014-07-02 09:53:54 -04:00
|
|
|
|
|
|
|
++p; // Skip '"'.
|
|
|
|
if (p == pEnd)
|
|
|
|
break;
|
2010-10-15 15:40:19 +05:30
|
|
|
}
|
2014-07-02 09:53:54 -04:00
|
|
|
}
|
2016-10-22 18:43:15 +00:00
|
|
|
else if (*p == ';' && !bInQuote)
|
2010-10-15 15:40:19 +05:30
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
// element separator.
|
|
|
|
if (pElem)
|
|
|
|
aElem = OUString(pElem, p-pElem);
|
|
|
|
aRawElems.push_back(aElem);
|
2015-11-10 10:11:17 +01:00
|
|
|
pElem = nullptr;
|
2014-11-12 14:24:10 +05:30
|
|
|
aElem.clear();
|
2010-10-15 15:40:19 +05:30
|
|
|
}
|
2014-07-02 09:53:54 -04:00
|
|
|
else if (!pElem)
|
|
|
|
pElem = p;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pElem)
|
|
|
|
{
|
|
|
|
aElem = OUString(pElem, p-pElem);
|
|
|
|
aRawElems.push_back(aElem);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rRole == "values-y" || rRole == "values-first" || rRole == "values-last" ||
|
2017-07-20 13:15:57 +05:30
|
|
|
rRole == "values-min" || rRole == "values-max" || rRole == "values-size")
|
2014-07-02 09:53:54 -04:00
|
|
|
{
|
|
|
|
// Column values. Append a new data column and populate it.
|
|
|
|
|
|
|
|
std::vector<double> aValues;
|
|
|
|
aValues.reserve(aRawElems.size());
|
2019-08-19 15:10:37 +02:00
|
|
|
for (const OUString & aRawElem : aRawElems)
|
2016-11-28 09:09:55 +01:00
|
|
|
{
|
|
|
|
if (aRawElem.isEmpty())
|
|
|
|
aValues.push_back(NAN);
|
|
|
|
else
|
|
|
|
aValues.push_back(aRawElem.toDouble());
|
|
|
|
}
|
2014-07-02 09:53:54 -04:00
|
|
|
sal_Int32 n = m_aInternalData.appendColumn();
|
|
|
|
|
|
|
|
m_aInternalData.setColumnValues(n, aValues);
|
|
|
|
|
|
|
|
OUString aRangeRep = OUString::number(n);
|
|
|
|
xSeq.set(new UncachedDataSequence(this, aRangeRep));
|
|
|
|
addDataSequenceToMap(aRangeRep, xSeq);
|
|
|
|
}
|
|
|
|
else if (rRole == "values-x")
|
|
|
|
{
|
|
|
|
std::vector<double> aValues;
|
|
|
|
aValues.reserve(aRawElems.size());
|
|
|
|
if (bAllNumeric)
|
2010-10-15 15:40:19 +05:30
|
|
|
{
|
2019-08-19 15:10:37 +02:00
|
|
|
for (const OUString & aRawElem : aRawElems)
|
2019-08-27 10:55:30 +02:00
|
|
|
{
|
|
|
|
if (!aRawElem.isEmpty())
|
|
|
|
aValues.push_back(aRawElem.toDouble());
|
|
|
|
else
|
|
|
|
aValues.push_back(NAN);
|
|
|
|
}
|
2010-10-15 15:40:19 +05:30
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-07-02 09:53:54 -04:00
|
|
|
for (size_t i = 0; i < aRawElems.size(); ++i)
|
|
|
|
aValues.push_back(i+1);
|
|
|
|
}
|
|
|
|
|
|
|
|
sal_Int32 n = m_aInternalData.appendColumn();
|
|
|
|
m_aInternalData.setColumnValues(n, aValues);
|
|
|
|
|
|
|
|
OUString aRangeRep = OUString::number(n);
|
|
|
|
xSeq.set(new UncachedDataSequence(this, aRangeRep));
|
|
|
|
addDataSequenceToMap(aRangeRep, xSeq);
|
|
|
|
}
|
|
|
|
else if (rRole == "categories")
|
|
|
|
{
|
|
|
|
// Category labels.
|
|
|
|
|
|
|
|
for (size_t i = 0; i < aRawElems.size(); ++i)
|
|
|
|
{
|
2017-02-03 08:54:47 +02:00
|
|
|
std::vector<uno::Any> aLabels(1, uno::Any(aRawElems[i]));
|
2014-07-02 09:53:54 -04:00
|
|
|
m_aInternalData.setComplexRowLabel(i, aLabels);
|
|
|
|
}
|
|
|
|
|
|
|
|
xSeq.set(new UncachedDataSequence(this, lcl_aCategoriesRangeName));
|
|
|
|
addDataSequenceToMap(lcl_aCategoriesRangeName, xSeq);
|
|
|
|
}
|
|
|
|
else if (rRole == "label")
|
|
|
|
{
|
|
|
|
// Data series label. There should be only one element. This always
|
|
|
|
// goes to the last data column.
|
|
|
|
sal_Int32 nColSize = m_aInternalData.getColumnCount();
|
|
|
|
if (!aRawElems.empty() && nColSize)
|
|
|
|
{
|
2017-02-03 08:54:47 +02:00
|
|
|
std::vector<uno::Any> aLabels(1, uno::Any(aRawElems[0]));
|
2014-07-02 09:53:54 -04:00
|
|
|
m_aInternalData.setComplexColumnLabel(nColSize-1, aLabels);
|
|
|
|
|
|
|
|
OUString aRangeRep = lcl_aLabelRangePrefix + OUString::number(nColSize-1);
|
|
|
|
xSeq.set(new UncachedDataSequence(this, aRangeRep));
|
|
|
|
addDataSequenceToMap(aRangeRep, xSeq);
|
2010-10-15 15:40:19 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
return xSeq;
|
|
|
|
}
|
|
|
|
|
2014-06-24 18:40:54 -04:00
|
|
|
Reference< chart2::data::XDataSequence > InternalDataProvider::createDataSequenceAndAddToMap(
|
2007-05-22 17:59:49 +00:00
|
|
|
const OUString & rRangeRepresentation,
|
|
|
|
const OUString & rRole )
|
|
|
|
{
|
|
|
|
Reference< chart2::data::XDataSequence > xSeq(
|
|
|
|
new UncachedDataSequence( this, rRangeRepresentation, rRole ));
|
2014-06-24 18:40:54 -04:00
|
|
|
addDataSequenceToMap( rRangeRepresentation, xSeq );
|
2007-05-22 17:59:49 +00:00
|
|
|
return xSeq;
|
|
|
|
}
|
|
|
|
|
|
|
|
// ____ XDataProvider ____
|
2014-04-03 13:52:06 +02:00
|
|
|
sal_Bool SAL_CALL InternalDataProvider::createDataSourcePossible( const Sequence< beans::PropertyValue >& /* aArguments */ )
|
2007-07-25 07:57:46 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
sal_Int32 lcl_getInnerLevelCount( const vector< vector< uno::Any > >& rLabels )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
|
|
|
sal_Int32 nCount = 1;//minimum is 1!
|
2018-03-03 23:26:43 +01:00
|
|
|
for (auto const& elemLabel : rLabels)
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2018-03-03 23:26:43 +01:00
|
|
|
nCount = std::max<sal_Int32>( elemLabel.size(), nCount );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
return nCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
}//end anonymous namespace
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
Reference< chart2::data::XDataSource > SAL_CALL InternalDataProvider::createDataSource(
|
|
|
|
const Sequence< beans::PropertyValue >& aArguments )
|
|
|
|
{
|
|
|
|
OUString aRangeRepresentation;
|
|
|
|
bool bUseColumns = true;
|
|
|
|
bool bFirstCellAsLabel = true;
|
|
|
|
bool bHasCategories = true;
|
|
|
|
uno::Sequence< sal_Int32 > aSequenceMapping;
|
|
|
|
DataSourceHelper::readArguments( aArguments, aRangeRepresentation, aSequenceMapping, bUseColumns, bFirstCellAsLabel, bHasCategories );
|
|
|
|
|
2014-12-18 13:21:05 +01:00
|
|
|
if( aRangeRepresentation == lcl_aCategoriesRangeName )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
|
|
|
//return split complex categories if we have any:
|
2017-02-15 23:55:18 +02:00
|
|
|
std::vector< Reference< chart2::data::XLabeledDataSequence > > aComplexCategories;
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
|
2010-01-13 17:06:34 +01:00
|
|
|
if( bUseColumns==m_bDataInColumns )
|
|
|
|
{
|
|
|
|
sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
|
|
|
|
for( sal_Int32 nL=0; nL<nLevelCount; nL++ )
|
|
|
|
aComplexCategories.push_back( new LabeledDataSequence(
|
|
|
|
new UncachedDataSequence( this
|
2013-08-21 15:07:31 +02:00
|
|
|
, lcl_aCategoriesLevelRangeNamePrefix + OUString::number( nL )
|
2010-01-13 17:06:34 +01:00
|
|
|
, lcl_aCategoriesRoleName ) ) );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_Int32 nPointCount = m_bDataInColumns ? m_aInternalData.getRowCount() : m_aInternalData.getColumnCount();
|
|
|
|
for( sal_Int32 nP=0; nP<nPointCount; nP++ )
|
|
|
|
aComplexCategories.push_back( new LabeledDataSequence(
|
|
|
|
new UncachedDataSequence( this
|
2013-08-21 15:07:31 +02:00
|
|
|
, lcl_aCategoriesPointRangeNamePrefix + OUString::number( nP )
|
2010-01-13 17:06:34 +01:00
|
|
|
, lcl_aCategoriesRoleName ) ) );
|
|
|
|
}
|
|
|
|
//don't add the created sequences to the map as they are used temporarily only ...
|
2015-11-19 09:14:59 +02:00
|
|
|
return new DataSource( comphelper::containerToSequence(aComplexCategories) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
|
2017-05-07 17:03:35 +10:00
|
|
|
OSL_ASSERT( aRangeRepresentation == lcl_aCompleteRange );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2017-02-15 23:55:18 +02:00
|
|
|
std::vector< Reference< chart2::data::XLabeledDataSequence > > aResultLSeqVec;
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
// categories
|
2010-01-13 17:06:34 +01:00
|
|
|
if( bHasCategories )
|
CWS-TOOLING: integrate CWS dba32b
2009-06-03 14:58:08 +0200 fs r272581 : #i102439#
2009-05-29 13:56:18 +0200 fs r272456 : remove the sub form when the 'add subform' setting changes from <true/> to <false/>, not only its controls
2009-05-29 13:19:27 +0200 fs r272454 : display '(Default)' instead of an empty string when a control has the default font
2009-05-28 20:49:18 +0200 fs r272428 : #i98162# getFirstSelectedValue: do not return reference to a temporary
2009-05-27 15:30:22 +0200 msc r272353 : #102303#
2009-05-26 13:03:06 +0200 fs r272295 : spelling
2009-05-26 12:59:54 +0200 fs r272294 : merge m48 version to get latest cygwin related fixes
2009-05-25 14:02:06 +0200 fs r272239 : remove references to local files, needed for debugging sessions only
2009-05-25 14:01:16 +0200 fs r272238 : #i102021# ensure members such as bNumberFormat are initialized before actually returning them
2009-05-25 13:10:20 +0200 fs r272236 : #i10000# reset ENABLE_EVOAB2
2009-05-22 06:44:45 +0200 oj r272167 : #i99104# add import handler for calc-sett
2009-05-22 06:42:27 +0200 oj r272166 : #i99104# impl NullDate as member
2009-05-22 06:36:22 +0200 oj r272165 : #i99104# handle nulldate from parent model
2009-05-22 06:33:13 +0200 oj r272164 : #i99104# export and import calculation-settings and nulldate
2009-05-22 06:27:50 +0200 oj r272163 : #i99104# export and import calculation-settings and nulldate
2009-05-20 13:29:58 +0200 oj r272118 : #i99911# handle invalid name
2009-05-20 13:28:49 +0200 oj r272117 : #i101261# handle different rowsets
2009-05-20 11:29:55 +0200 msc r272111 : #i100000#
2009-05-20 11:28:27 +0200 msc r272110 : merge in change from dba32a
2009-05-20 11:27:38 +0200 msc r272109 : #102082# CTRL + C does not work
2009-05-20 09:43:36 +0200 oj r272106 : clean up includes
2009-05-20 09:32:15 +0200 oj r272105 : #i99060# merge error resovled now VERTICAL_ALIGN is in both stmt
2009-05-20 08:37:21 +0200 msc r272104 : add workaround for issue #102010#
2009-05-20 08:10:12 +0200 oj r272103 : #i99104# use numberformatkey
2009-05-20 08:07:02 +0200 oj r272102 : #i99104# use column info from rowset
2009-05-20 08:04:43 +0200 oj r272101 : #i102032# use a special column type where prec and scale are the values currently set at the column
2009-05-20 08:03:04 +0200 oj r272100 : #i102032# correct type info, we have to use SQL defined type names
2009-05-19 10:27:02 +0200 oj r272061 : #i99104# export null-date
2009-05-19 08:26:53 +0200 oj r272056 : #i99104# export null-date
2009-05-18 13:15:10 +0200 msc r272014 : add issue #102019#
2009-05-18 11:33:07 +0200 msc r272005 : add issue #102019#
2009-05-18 08:59:45 +0200 msc r271996 : add workaroud for issue #102010#
2009-05-15 10:21:24 +0200 msc r271929 : #101944#
2009-05-11 21:18:30 +0200 fs r271792 : #i99914#
2009-05-08 13:52:06 +0200 oj r271715 : #i96423# remember column span
2009-05-08 11:26:19 +0200 oj r271708 : #i98605# impl new scale mode
2009-05-08 10:33:35 +0200 fs r271706 : SendUserCall: only call into the shape notification routine for UserCall types where this is necessary (performance issue)
2009-05-07 20:52:44 +0200 fs r271698 : outsource ShapeProperty from shapepropertynotifier.hxx
2009-05-07 20:43:33 +0200 fs r271697 : #i99056# use notifyShapePropertyChange, instead of getShapePropertyChangeNotifier - the latter throws if no shape exists, yet
2009-05-07 20:33:58 +0200 fs r271696 : #i99056# +notifyShapePropertyChange: allow notifying chages without checking whether there actually already exists an SvxShape
2009-05-07 16:22:15 +0200 fs r271679 : #i10000# cygwin needs quotes around the classpath
2009-05-07 16:21:37 +0200 fs r271678 : #i10000# cygwin needs quotes around the classpath
2009-05-07 16:01:11 +0200 oj r271677 : #i99914# notify parent handler
2009-05-07 15:54:54 +0200 fs r271676 : #i10000# cygwin needs some quoting
2009-05-07 14:49:48 +0200 oj r271672 : #i99277# quote alias name
2009-05-07 14:48:12 +0200 oj r271671 : #i92538# add ~ in front of type
2009-05-07 14:37:13 +0200 oj r271667 : #i99118# change type from char to varchar
2009-05-07 14:36:23 +0200 oj r271666 : #i99118# clear dest columns when changing to create new table
2009-05-07 13:35:32 +0200 oj r271657 : #i94467# handle type 0 as double as well
2009-05-07 13:20:49 +0200 oj r271655 : i99743# setNull when varchar is no text
2009-05-07 12:58:06 +0200 fs r271651 : initialize the SdrObject's property change notifier after the ctor, if necessary
2009-05-07 11:47:18 +0200 fs r271647 : #i10000#
2009-05-07 10:57:16 +0200 fs r271639 : OPropertyBrowserController::propertyChange: care for the current property state, too, and properly forward it to the UI
2009-05-07 10:18:14 +0200 fs r271636 : onNewComponent: do not ask the map for grid columns, it will throw
2009-05-07 10:09:55 +0200 fs r271634 : #i101623#
2009-05-07 09:53:44 +0200 fs r271631 : #i101622#
2009-05-06 21:55:53 +0200 fs r271615 : #i10000#
2009-05-06 21:10:42 +0200 fs r271611 : #i10000#
2009-05-06 13:11:48 +0200 fs r271583 : #i10000#
2009-05-05 22:29:31 +0200 fs r271559 : proper assertion message
2009-05-05 22:29:03 +0200 fs r271558 : diagnostics
2009-05-05 22:16:16 +0200 fs r271557 : #i10000#
2009-05-05 13:50:32 +0200 fs r271513 : #i10000#
2009-05-05 10:21:50 +0200 fs r271503 : #i10000#
2009-05-05 09:30:26 +0200 fs r271501 : why did those survive the rebase -C step?
2009-05-05 09:18:12 +0200 fs r271500 : #i10000#
2009-05-04 17:08:17 +0200 fs r271475 : CWS-TOOLING: rebase CWS dba32b to trunk@271427 (milestone: DEV300:m47)
2009-05-04 14:51:26 +0200 fs r271456 : line ends
2009-04-30 15:55:27 +0200 fs r271418 : NewURL -> PublicConnectionURL
2009-04-22 21:18:34 +0200 fs r271141 : #i100944#
2009-04-22 09:12:26 +0200 oj r271071 : #i101261# little code change
2009-04-22 09:11:43 +0200 oj r271070 : #i101261# only ask for parameters which aren't set before
2009-04-22 09:11:25 +0200 oj r271069 : #i101261# new grabage container for nodes
2009-04-22 09:11:02 +0200 oj r271068 : #i101261# new grabage container for nodes
2009-04-22 09:10:44 +0200 oj r271067 : #i101261# new grabage container for nodes
2009-04-22 09:10:21 +0200 oj r271066 : #i101261# only ask for parameters which aren't set before
2009-04-22 09:08:24 +0200 oj r271065 : #i101261# only ask for parameters which aren't set before
2009-04-22 09:07:25 +0200 oj r271064 : #i101261# only ask for parameters which aren't set before
2009-04-22 08:49:07 +0200 oj r271062 : #i77501# preview only when needed
2009-04-22 08:45:44 +0200 oj r271061 : #i101261# new prop max rows
2009-04-22 08:44:18 +0200 oj r271060 : #i101261# create dataprovider earlier to avoid the wrong legend in chart
2009-04-22 08:42:48 +0200 oj r271059 : #i101261# handle parameter
2009-04-17 21:00:23 +0200 fs r270954 : #i98350#
2009-04-17 13:54:19 +0200 fs r270942 : #i99565#
2009-04-17 13:51:34 +0200 fs r270940 : #i101153# only localize the (potentially) localizable properties when there really is support at the control model
2009-04-17 11:43:14 +0200 fs r270932 : removed superfluous include
2009-04-17 10:10:15 +0200 fs r270926 : #i10000#
2009-04-17 10:02:36 +0200 fs r270925 : #i10000#
2009-04-17 09:15:13 +0200 fs r270918 : #i99056# some more refactoring of the recently introduced property change notification mechanism for UNO shapes
2009-04-17 09:14:56 +0200 fs r270917 : #i99056# some more refactoring of the recently introduced property change notification mechanism for UNO shapes
2009-04-17 09:13:25 +0200 fs r270915 : #i99056# some more refactoring of the recently introduced property change notification mechanism for UNO shapes
2009-04-17 08:30:34 +0200 fs r270914 : removed unotools/servicehelper.hxx in favour of the (duplicated) comphelper/servicehelper.hxx
2009-04-16 21:05:25 +0200 fs r270903 : #i10000#
2009-04-16 20:43:43 +0200 fs r270902 : #i99056# shape notification outsourced to the SdrObject, this is what all other shape implementations (which only aggregate an SvxShape) have access to, too
2009-04-16 15:57:36 +0200 fs r270891 : #i99056# make SetUnoControlModel virtual
2009-04-16 15:44:02 +0200 fs r270890 : #i99056# let the ScShapeObj notify changes in its Anchor property
2009-04-16 15:36:47 +0200 fs r270889 : #i99056# enable the sheet anchor type property, too
2009-04-16 15:33:45 +0200 fs r270887 : #i99056# shape notification outsourced to the SdrObject, this is what all other shape implementations (which only aggregate an SvxShape) have access to, too
2009-04-15 14:53:13 +0200 fs r270844 : #i10000#
2009-04-15 13:08:29 +0200 fs r270836 : #i10000#
2009-04-15 12:28:14 +0200 fs r270832 : #i10000#
2009-04-15 10:59:14 +0200 fs r270827 : #i10000#
2009-04-15 09:41:08 +0200 oj r270823 : fix issues found with findbugs and pmd
2009-04-14 21:08:04 +0200 fs r270808 : #i99056# implement SheetAnchorType - now the only thing missing to enable it is the proper notification when it is modified
2009-04-14 17:09:00 +0200 fs r270799 : #i99056# implement XServiceInfo for the ScShapeObj
2009-04-14 17:07:55 +0200 fs r270798 : #i99056# implement TextAnchorType, partially implement SheetAnchorType
2009-04-14 15:54:05 +0200 fs r270786 : #i99056# SwXShape: notify changes of the AnchorType property
2009-04-14 15:47:32 +0200 fs r270785 : #i99056# deliver shapepropertynotifier.hxx
2009-04-14 15:46:54 +0200 fs r270784 : diagnostics
2009-04-14 15:08:28 +0200 fs r270781 : #i99056# outsourced the SvxShape's property change notification code into a dedicated class
2009-04-14 14:41:09 +0200 fs r270773 : #i99056# outsourced the SvxShape's property change notification code into a dedicated class
2009-04-14 14:37:23 +0200 fs r270772 : in dtor, remove the properties from the temporary component context
2009-04-14 14:36:34 +0200 fs r270771 : getWeakUnoShape made const
2009-04-14 12:23:08 +0200 oj r270757 : #i101064# add missing braces
2009-04-14 12:21:25 +0200 oj r270756 : #i101065# add braces for gcc 4.3.2
2009-04-14 12:17:45 +0200 oj r270755 : #i101059# add dep for manifest
2009-04-09 12:06:58 +0200 oj r270686 : #i93100# use OptimalSize from control to get height
2009-04-08 09:56:55 +0200 oj r270619 : #i92537# handle calculations in the select columns as well
2009-04-08 09:30:39 +0200 oj r270615 : #i96657# throw error message when the key doesn't have any columns
2009-04-07 12:08:26 +0200 oj r270592 : #i77501# impl preview of the executed report
2009-04-07 12:01:56 +0200 oj r270591 : #i77501# impl preview of the executed report
2009-04-07 11:41:03 +0200 oj r270590 : #i77501# impl preview of the executed report
2009-04-07 11:39:32 +0200 oj r270589 : #i77501# impl preview of the executed report
2009-04-07 11:29:25 +0200 oj r270588 : #i77501# convert dos to unix lineends
2009-04-07 11:28:23 +0200 oj r270587 : #i77501# impl preview of the executed report
2009-04-07 11:16:50 +0200 oj r270586 : #i77501# impl preview of the executed report
2009-04-07 11:16:00 +0200 oj r270585 : #i77501# impl preview of the executed report
2009-04-07 11:15:44 +0200 oj r270584 : #i77501# impl preview of the executed report
2009-04-07 11:15:28 +0200 oj r270583 : #i77501# impl preview of the executed report
2009-04-07 11:15:04 +0200 oj r270582 : #i77501# impl preview of the executed report
2009-04-06 15:38:54 +0200 fs r270559 : merge changes from CWS dba32a herein
2009-04-03 15:56:16 +0200 fs r270494 : ImpSvMEdit::Resize: do multiple iterations, if necessary
2009-04-03 14:35:49 +0200 fs r270487 : #i10000#
2009-04-03 13:17:16 +0200 fs r270476 : #i99056# display geometry information for controls, too
2009-04-03 13:16:37 +0200 fs r270475 : #i99056# better ordering of the geometry properties
2009-04-03 13:16:07 +0200 fs r270473 : #i99056# now that SvxShape supports property change listeners, forward add/remove requests to it
2009-04-03 13:13:18 +0200 fs r270472 : #i99056# at SvxShape, allow for PropertyChangeListeners for Size/Position
2009-04-03 09:29:27 +0200 oj r270456 : #i94571# use correct prop name
2009-04-03 09:14:54 +0200 fs r270451 : merge changes from CWS dba32a herein
2009-04-02 17:00:51 +0200 fs r270424 : better diagnostics
2009-04-02 16:35:19 +0200 fs r270421 : diagnostics
2009-04-02 16:34:50 +0200 fs r270420 : #i99056# mxUnoShape not accessible anymore, use impl_setUnoShape instead
2009-04-02 16:32:48 +0200 fs r270419 : #i99056# make getUnoShape cheaper: keep the pointer to the SvxShape all the time, so there's no need to ask for it in getUnoShape. As a consequence, we will later be able to use the pointer in scenarious where performance (potentially) matters
2009-04-02 16:31:13 +0200 fs r270417 : merge changes from CWS dba32a herein
2009-04-02 16:23:16 +0200 fs r270414 : merge changes from CWS dba32a herein
2009-04-02 14:10:35 +0200 fs r270405 : #i10000#
2009-04-02 14:06:26 +0200 fs r270404 : merge changes from CWS dba32a herein
2009-04-02 14:03:03 +0200 fs r270401 : #i10000#
2009-04-02 13:58:13 +0200 fs r270400 : #i10000#
2009-04-02 12:59:44 +0200 fs r270397 : merge changes from CWS dba32a herein
2009-04-02 12:46:30 +0200 fs r270396 : #i99056# let the form page maintain a mapping between control models and control shapes
2009-04-02 12:44:07 +0200 fs r270395 : merge changes from CWS dba32a herein
2009-04-02 12:42:06 +0200 fs r270394 : merge changes from CWS dba32a herein
2009-04-02 12:35:20 +0200 fs r270393 : #i10000# precompiled header
2009-04-02 12:05:31 +0200 fs r270392 : merge changes from CWS dba32a herein
2009-04-02 12:00:42 +0200 fs r270391 : merge changes from CWS dba32a herein
2009-04-02 11:47:26 +0200 fs r270390 : merge changes from CWS dba32a herein
2009-04-02 11:39:15 +0200 oj r270389 : #i94467# foxpro impl several new types
2009-04-02 11:35:58 +0200 fs r270387 : merge changes from CWS dba32a herein
2009-04-01 14:10:51 +0200 fs r270329 : merge changes from CWS dba32a herein
2009-03-31 17:29:50 +0200 fs r270290 : merge changes from CWS dba32a herein
2009-03-30 14:53:56 +0200 fs r270233 : #i100417# don't set grid column widths to 0, but to <void/>
2009-03-30 12:31:03 +0200 oj r270213 : #i100552# wrong orb used
2009-03-30 12:19:20 +0200 oj r270212 : #i98303# convertlike corrected to sal_Unicode
2009-03-30 11:58:25 +0200 fs r270210 : merge changes from CWS dba32a herein
2009-03-30 11:38:16 +0200 oj r270205 : remove duplicate code from merge
2009-03-30 11:02:27 +0200 fs r270202 : merge changes from CWS dba32a herein
2009-03-30 11:02:19 +0200 fs r270201 : merge changes from CWS dba32a herein
2009-03-30 10:31:26 +0200 oj r270200 : #i100665# only throw exception and do not drop table
2009-03-30 09:36:24 +0200 fs r270195 : assertion text
2009-03-28 20:21:58 +0100 fs r270187 : #ii10000#
2009-03-28 20:19:54 +0100 fs r270186 : removed unused help ids
2009-03-28 20:19:40 +0100 fs r270185 : removed unused help ids
2009-03-28 20:19:10 +0100 fs r270184 : #i100237# +DefaultState/XReset
2009-03-28 00:29:29 +0100 fs r270177 : CWS-TOOLING: rebase CWS dba32b to trunk@270033 (milestone: DEV300:m45)
2009-03-27 22:56:46 +0100 fs r270173 : #i100237# DEFAULT_CHECKED -> DEFAULT_STATE
2009-03-27 22:55:52 +0100 fs r270172 : #i100237# DefaultState property for buttons, enabled only when Toggle=Yes
2009-03-27 22:54:15 +0100 fs r270171 : #i100237# DEFAULT_CHECKED -> DEFAULT_STATE
2009-03-27 22:53:54 +0100 fs r270170 : #i100237# introduce a DefaultState property for buttons, which implies buttongs supporting XReset, which needed some refactoring
2009-03-27 13:31:41 +0100 fs r270152 : ignore output paths
2009-03-27 11:23:44 +0100 fs r270139 : tuned behavior with respect to invalid keys/values
2009-03-27 09:57:14 +0100 fs r270136 : don't allow Double.NaN
2009-03-27 09:56:16 +0100 fs r270135 : talk about Double.NaN
2009-03-26 12:14:30 +0100 fs r270067 : removed unused parameter
2009-03-26 12:14:02 +0100 fs r270066 : removed widening conversion when checking keys
2009-03-26 09:17:34 +0100 fs r270053 : separated the enumerator functionality into a dedicated interface, this way not burdening XMap with it
2009-03-26 09:17:11 +0100 fs r270052 : separated the enumerator functionality into a dedicated interface, this way not burdening XMap with it
2009-03-26 09:16:49 +0100 fs r270051 : separated the enumerator functionality into a dedicated interface, this way not burdening XMap with it
2009-03-25 21:55:20 +0100 fs r270044 : #i100541# properly calculat bNeedScrollBox
2009-03-25 12:56:17 +0100 fs r270019 : renamed the previously introduced error condition
2009-03-25 12:11:48 +0100 fs r270015 : #i100095# when the error messages contain non-trivial details (SQLState/ErrorCode), then always display the 'Details' button
2009-03-25 12:10:05 +0100 fs r270012 : renamed the previously introduced error condition
2009-03-25 12:01:04 +0100 fs r270011 : #i100095# when no address book (or respective profile) can be found, then use a dedicated ErrorCondition
2009-03-25 10:29:07 +0100 fs r270003 : add missing localization
2009-03-25 10:23:12 +0100 fs r270001 : in preparation of #i1000095#:
rework the error handling, allow using css.sdb.ErrorCondition values, plus
allow propagating the nsresult
2009-03-25 10:21:55 +0100 fs r270000 : in preparation of #i1000095#:
rework the error handling, allow using css.sdb.ErrorCondition values, plus
allow propagating the nsresult
2009-03-20 23:05:38 +0100 fs r269829 : XMap::getSize removed
2009-03-20 23:05:19 +0100 fs r269828 : changes as suggested by sb
2009-03-20 23:04:56 +0100 fs r269827 : enhanced documentation
2009-03-20 15:31:40 +0100 fs r269815 : changes as suggested by sb
2009-03-20 13:23:52 +0100 oj r269804 : #i92538# correct the zorder that fixedtext is infront of control
2009-03-20 12:59:38 +0100 oj r269801 : #i94571# paraadjust now supports BLOCK
2009-03-20 12:58:11 +0100 oj r269800 : #i94571# export style with data style
2009-03-20 12:57:05 +0100 oj r269799 : #i94571# text align is now paraadjust
2009-03-20 12:37:02 +0100 fs r269797 : enum keys only accepted if they have the exact type, not if they have *any* enum type
2009-03-20 12:28:31 +0100 fs r269794 : some changes requested by sb
2009-03-20 08:52:47 +0100 fs r269780 : doc
2009-03-20 07:37:31 +0100 oj r269779 : #i99913# only notifiy when values are different
2009-03-20 07:36:58 +0100 oj r269778 : #i99913# add undoenv as listener at the dataprovider
2009-03-19 22:52:52 +0100 fs r269771 : added comment
2009-03-19 22:40:06 +0100 fs r269770 : +testEnumeration
2009-03-19 22:39:41 +0100 fs r269769 : implemented enumeration, getKeySet, and getValues. Should be finished now.
2009-03-19 14:01:01 +0100 oj r269743 : #i99913# reset the modified state when selecting an object
2009-03-19 12:19:54 +0100 lla r269739 : #i72390# cleanups
2009-03-19 09:25:27 +0100 fs r269727 : #i10000#
2009-03-18 23:37:02 +0100 fs r269708 : extended checks for value type acceptance
2009-03-18 23:36:41 +0100 fs r269707 : fixed value type checks
2009-03-18 14:59:56 +0100 fs r269678 : initial complex test case for the new css.container.Map implementation
2009-03-18 14:59:24 +0100 fs r269677 : verifyExpectedException moved to base class (in complexlib), and renamed to assureException for consistency
2009-03-18 14:58:35 +0100 fs r269676 : removed unused imports
2009-03-18 14:58:03 +0100 fs r269675 : first implementation of the new css.container.Map service (not completed, yet)
2009-03-18 14:57:17 +0100 fs r269674 : base class for UNO components, freeing you from some repeating work
2009-03-18 14:55:53 +0100 fs r269672 : +assureException: call a given method with given parameters on a given object, ensure that a given exception is thrown by the method implementation
2009-03-18 14:54:58 +0100 fs r269671 : +getComponentContext
2009-03-18 14:54:00 +0100 fs r269670 : isEmpty returns a boolean, not a long
2009-03-18 14:14:43 +0100 oj r269663 : #i99743# now text also supports null
2009-03-18 13:54:14 +0100 oj r269660 : #i99223# remove check for 2 params
2009-03-18 13:33:35 +0100 oj r269659 : #i99060# replace text::ParagraphVertAlign with style::VerticalAlignment
2009-03-18 13:32:18 +0100 oj r269658 : #i99060# don't set void property when void isn't allowed
2009-03-18 13:31:11 +0100 oj r269657 : #i99060# handle vertical alignment
2009-03-18 13:28:28 +0100 oj r269656 : #i99060# remove unused elements from sytle
2009-03-18 09:35:42 +0100 lla r269639 : #i72390# cleanups
2009-03-18 09:31:20 +0100 lla r269638 : #i72390# add ButtonList
2009-03-18 09:30:46 +0100 lla r269637 : #i72390# renamed interface
2009-03-18 09:30:15 +0100 lla r269636 : #i72390# use ButtonList instead of ImageList
2009-03-18 09:29:05 +0100 lla r269635 : #i72390# new ButtonList, cleanups
2009-03-18 09:26:34 +0100 lla r269634 : #i72390# cleanups
2009-03-17 12:21:20 +0100 oj r269590 : #i99222# remove assertion
2009-03-17 12:17:22 +0100 oj r269589 : #i98605# impl scale mode
2009-03-17 12:10:42 +0100 oj r269588 : #i98605# impl scale mode
2009-03-17 11:40:15 +0100 oj r269584 : #i96944# doesn't create equation for shapes
2009-03-17 11:33:16 +0100 oj r269583 : #i96423# switch calc from float to long
2009-03-16 15:19:18 +0100 fs r269550 : #i41930# enable zoom for embedded/outplace documents
2009-03-16 14:25:54 +0100 oj r269542 : #i93734# remove ContextSensitive
2009-03-16 14:21:58 +0100 oj r269541 : #i99274# page header before group header
2009-03-16 14:18:23 +0100 oj r269539 : #i99110# fix value type
2009-03-16 14:14:16 +0100 fs r269537 : line ends
2009-03-16 14:11:06 +0100 fs r269535 : line ends
2009-03-16 14:08:34 +0100 fs r269534 : #i100087# (provided my np): allow for polymorphic types with more than one parameter
2009-03-16 12:30:31 +0100 oj r269521 : compile error
2009-03-16 12:19:12 +0100 oj r269519 : compile error
2009-03-16 10:39:28 +0100 oj r269511 : compile error under linux with swap
2009-03-13 10:33:04 +0100 oj r269462 : CWS-TOOLING: rebase CWS dba32b to trunk@269297 (milestone: DEV300:m43)
2009-03-12 14:37:25 +0100 fs r269416 : interface SequenceOutputStreamTest is unneeded, and pollutes the namespace here :)
2009-03-12 14:35:07 +0100 fs r269414 : not needed
2009-03-12 14:34:15 +0100 fs r269413 : preparation for multiple tests in this module
2009-03-12 14:33:02 +0100 fs r269412 : ShowTargets was moved from module integration.forms to module complexlib
2009-03-12 14:32:48 +0100 fs r269411 : helper class for projects containing multiple complex test cases (and following a certain structure)
2009-03-12 14:00:14 +0100 fs r269407 : proper module after the move
2009-03-12 13:59:10 +0100 fs r269406 : superseded by ../makefile.mk
2009-03-12 13:47:38 +0100 fs r269403 : not needed anymore
2009-03-12 13:45:46 +0100 fs r269402 : moved, in preparation of adding more test cases here, with a common infrastructure
2009-03-12 13:45:07 +0100 fs r269401 : moved from ../
2009-03-12 13:43:59 +0100 fs r269400 : moved to ./comphelper, in preparation of adding more test cases here, with a common infrastructure
2009-03-12 13:29:47 +0100 oj r269396 : #i99914# set parent on dataprovider
2009-03-12 13:10:35 +0100 oj r269393 : #i99832# check thrown exception and show error
2009-03-12 13:08:10 +0100 fs r269392 : reorganizing tests
2009-03-12 12:52:55 +0100 oj r269390 : #i99118# convert formatkey in numberformat
2009-03-12 12:34:53 +0100 fs r269388 : new API tests
2009-03-12 12:29:05 +0100 fs r269386 : Map not yet committed
2009-03-12 12:28:36 +0100 fs r269385 : oops, forgot the SequenceInputStream during the previous refactoring
2009-03-12 12:12:39 +0100 oj r269384 : #i99104# set HasCategories prop
2009-03-12 12:12:08 +0100 oj r269383 : #i99104# check HasCategories even for internal dataprovider
2009-03-12 12:10:40 +0100 oj r269382 : #i99104# set HasCategories prop
2009-03-12 10:51:49 +0100 fs r269373 : #i10000# exception specifications
2009-03-12 10:49:18 +0100 fs r269372 : #i10000# exception specifications
2009-03-12 10:44:02 +0100 fs r269371 : #i10000# exception specifications
2009-03-12 10:30:55 +0100 fs r269368 : refactored the UNO service registration in this module, using the helper classes provided by comphelper itself, so you have less effort when extending the list of to-be-registered components
2009-03-12 10:30:37 +0100 fs r269367 : module-local includes
2009-03-12 07:05:54 +0100 oj r269357 : #i99104# database dataprovider doesn't need dataranges and diagramdata
2009-03-11 10:58:28 +0100 oj r269306 : #i99911# check if name of the report is a valid file name
2009-03-11 10:03:23 +0100 oj r269299 : #i99666# the report is new when the HierarchicalDocumentName is empty
2009-03-10 11:32:45 +0100 oj r269258 : #i99221# use fallback for language
2009-03-10 10:48:40 +0100 oj r269255 : #i99433# now use OStringBuffer
2009-03-10 10:36:21 +0100 fs r269252 : initial version of (X)Map
2009-03-10 09:52:23 +0100 oj r269246 : #i99433# now use OStringBuffer
2009-03-10 08:56:13 +0100 oj r269240 : #i99655# patch applied
2009-03-09 07:35:33 +0100 lla r269058 : #i10000# wrong variable assignment fixed
2009-03-06 17:20:40 +0100 fs r269030 : some explicit defaults
2009-03-06 17:20:30 +0100 fs r269029 : #i98600#
2009-03-06 14:40:34 +0100 fs r269009 : #i87692# during reload, prevent the document being modified just because of some control content changes ...
2009-03-06 12:52:20 +0100 lla r268997 : #i10000# ambigous problem with FontWeight fixed
2009-03-06 11:39:32 +0100 fs r268989 : #i10000# (approved by pl): use --without-t1-library configure option
2009-03-06 10:55:43 +0100 fs r268986 : #i99953# depends on xmlscript module now
2009-03-06 10:54:04 +0100 fs r268985 : #i99953# also adjust the event names found in dialogs embedded in the forms
2009-03-06 09:53:41 +0100 fs r268977 : #i10000#
2009-03-06 09:30:41 +0100 lla r268973 : #i10000# merge problems
2009-03-05 17:52:34 +0100 fs r268932 : #i98593# for sub components which are actually controlled by a DocumentDefinition (aka XComponentSupplier aka XCommandProcessor), close them by executing the 'close' command, not by suspending/closing the controller (which cannot be intercepted)
2009-03-05 11:41:56 +0100 fs r268889 : default the drop down line count for list/combo boxes to 20
2009-03-05 11:39:10 +0100 fs r268887 : do not display empty error messages
2009-03-02 10:13:57 +0100 lla r268639 : #i91541# CWS rebase m41 to m42
2009-03-02 09:06:27 +0100 lla r268635 : #i10000# add ';' to strings
2009-02-26 11:18:00 +0100 fs r268492 : reportdesign depends on REPORTBUILDER, not REPORTDESIGN
2009-02-26 10:11:38 +0100 lla r268489 : CWS-TOOLING: rebase CWS dba32b to trunk@268395 (milestone: DEV300:m42)
2009-02-26 09:04:11 +0100 lla r268488 : CWS-TOOLING: rebase CWS dba32b to trunk@268395 (milestone: DEV300:m42)
2009-02-24 12:09:13 +0100 lla r268392 : #i91541# #i91542# cleanups
2009-02-24 08:08:06 +0100 lla r268382 : merge all dba32a changes into dba32b
2009-02-24 07:14:55 +0100 lla r268381 : merge all dba32a changes into dba32b
2009-02-23 21:44:28 +0100 fs r268377 : oops ... don't tamper with m_aListSourceValues at the end of loadData
2009-02-23 20:57:05 +0100 fs r268376 : #i98162# don't hold the values as strings, but as ORowSetValue, this way preserving their type, and being agnostic to different result/rowset implementations doing different to-string-conversations
2009-02-23 20:55:44 +0100 fs r268375 : getObject: throwFunctionNotSupportedException, instead of silently returning NULL
2009-02-23 20:55:20 +0100 fs r268374 : #i98162# some more supported types
2009-02-23 20:54:43 +0100 fs r268373 : #i98162# +operator !=
2009-02-20 09:35:39 +0100 fs r268306 : #i99422# for a font, display the font name, the style, and the size
2009-02-20 09:33:45 +0100 fs r268305 : #i99422# in the property browser, FONT supersedes CHARFONTNAME: the aggregated FormComponentHandler displays them more nicely now
2009-02-19 16:12:06 +0100 fs r268293 : #i99372# recognize DataType::FLOAT as numeric
2009-02-19 15:43:12 +0100 fs r268291 : #i99415#
2009-02-19 15:40:15 +0100 fs r268290 : #i99242# lcl_firstFocussableControl: take disabled controls into account
2009-02-19 15:34:36 +0100 fs r268289 : #i99396# properly decode the base name of the URL when using it as title
2009-02-19 15:19:05 +0100 fs r268287 : #i98247#
2009-06-05 09:47:55 +00:00
|
|
|
aResultLSeqVec.push_back(
|
2014-06-24 18:40:54 -04:00
|
|
|
new LabeledDataSequence( createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName ) ) );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
// data with labels
|
2017-02-15 23:55:18 +02:00
|
|
|
std::vector< Reference< chart2::data::XLabeledDataSequence > > aDataVec;
|
2010-01-13 17:06:34 +01:00
|
|
|
const sal_Int32 nCount = (bUseColumns ? m_aInternalData.getColumnCount() : m_aInternalData.getRowCount());
|
2018-09-04 18:03:28 +02:00
|
|
|
aDataVec.reserve(nCount);
|
|
|
|
for (sal_Int32 nIdx = 0; nIdx < nCount; ++nIdx)
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
aDataVec.push_back(
|
|
|
|
new LabeledDataSequence(
|
2014-06-24 18:40:54 -04:00
|
|
|
createDataSequenceAndAddToMap( OUString::number( nIdx )),
|
|
|
|
createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::number( nIdx ))));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// attention: this data provider has the limitation that it stores
|
|
|
|
// internally if data comes from columns or rows. It is intended for
|
|
|
|
// creating only one used data source.
|
|
|
|
// @todo: add this information in the range representation strings
|
|
|
|
m_bDataInColumns = bUseColumns;
|
|
|
|
|
|
|
|
//reorder labeled sequences according to aSequenceMapping; ignore categories
|
|
|
|
for( sal_Int32 nNewIndex = 0; nNewIndex < aSequenceMapping.getLength(); nNewIndex++ )
|
|
|
|
{
|
|
|
|
std::vector< LabeledDataSequence* >::size_type nOldIndex = aSequenceMapping[nNewIndex];
|
|
|
|
if( nOldIndex < aDataVec.size() )
|
|
|
|
{
|
|
|
|
if( aDataVec[nOldIndex].is() )
|
|
|
|
{
|
|
|
|
aResultLSeqVec.push_back( aDataVec[nOldIndex] );
|
2015-11-10 10:11:17 +01:00
|
|
|
aDataVec[nOldIndex] = nullptr;
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//add left over data sequences to result
|
2018-03-03 23:26:43 +01:00
|
|
|
for (auto const& elem : aDataVec)
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2018-03-03 23:26:43 +01:00
|
|
|
if( elem.is() )
|
|
|
|
aResultLSeqVec.push_back(elem);
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2015-11-19 09:14:59 +02:00
|
|
|
return new DataSource( comphelper::containerToSequence(aResultLSeqVec) );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Sequence< beans::PropertyValue > SAL_CALL InternalDataProvider::detectArguments(
|
2008-03-18 14:58:12 +00:00
|
|
|
const Reference< chart2::data::XDataSource >& /* xDataSource */ )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
Sequence< beans::PropertyValue > aArguments( 4 );
|
|
|
|
aArguments[0] = beans::PropertyValue(
|
2017-02-03 08:54:47 +02:00
|
|
|
"CellRangeRepresentation", -1, uno::Any( OUString(lcl_aCompleteRange) ),
|
2007-05-22 17:59:49 +00:00
|
|
|
beans::PropertyState_DIRECT_VALUE );
|
|
|
|
aArguments[1] = beans::PropertyValue(
|
2017-02-03 08:54:47 +02:00
|
|
|
"DataRowSource", -1, uno::Any(
|
2007-05-22 17:59:49 +00:00
|
|
|
m_bDataInColumns
|
2015-11-27 11:14:38 +02:00
|
|
|
? css::chart::ChartDataRowSource_COLUMNS
|
|
|
|
: css::chart::ChartDataRowSource_ROWS ),
|
2007-05-22 17:59:49 +00:00
|
|
|
beans::PropertyState_DIRECT_VALUE );
|
|
|
|
// internal data always contains labels and categories
|
|
|
|
aArguments[2] = beans::PropertyValue(
|
2017-02-03 08:54:47 +02:00
|
|
|
"FirstCellAsLabel", -1, uno::Any( true ), beans::PropertyState_DIRECT_VALUE );
|
2007-05-22 17:59:49 +00:00
|
|
|
aArguments[3] = beans::PropertyValue(
|
2017-02-03 08:54:47 +02:00
|
|
|
"HasCategories", -1, uno::Any( true ), beans::PropertyState_DIRECT_VALUE );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2008-03-18 14:58:12 +00:00
|
|
|
// #i85913# Sequence Mapping is not needed for internal data, as it is
|
|
|
|
// applied to the data when the data source is created.
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
return aArguments;
|
|
|
|
}
|
|
|
|
|
2014-04-03 13:52:06 +02:00
|
|
|
sal_Bool SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentationPossible( const OUString& /* aRangeRepresentation */ )
|
2007-07-25 07:57:46 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
Reference< chart2::data::XDataSequence > SAL_CALL InternalDataProvider::createDataSequenceByRangeRepresentation(
|
|
|
|
const OUString& aRangeRepresentation )
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
|
2007-07-25 07:57:46 +00:00
|
|
|
{
|
2017-05-07 17:03:35 +10:00
|
|
|
OSL_ASSERT( aRangeRepresentation == lcl_aCategoriesRangeName );//it is not expected nor implemented that only parts of the categories are really requested
|
2010-01-13 17:06:34 +01:00
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
// categories
|
2014-06-24 18:40:54 -04:00
|
|
|
return createDataSequenceAndAddToMap( lcl_aCategoriesRangeName, lcl_aCategoriesRoleName );
|
2007-07-25 07:57:46 +00:00
|
|
|
}
|
2007-05-22 17:59:49 +00:00
|
|
|
else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
|
|
|
|
{
|
|
|
|
// label
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nIndex = aRangeRepresentation.copy( strlen(lcl_aLabelRangePrefix)).toInt32();
|
2014-06-24 18:40:54 -04:00
|
|
|
return createDataSequenceAndAddToMap( lcl_aLabelRangePrefix + OUString::number( nIndex ));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2012-04-06 14:28:18 +02:00
|
|
|
else if ( aRangeRepresentation == "last" )
|
2008-03-06 16:43:34 +00:00
|
|
|
{
|
|
|
|
sal_Int32 nIndex = (m_bDataInColumns
|
2010-01-13 17:06:34 +01:00
|
|
|
? m_aInternalData.getColumnCount()
|
|
|
|
: m_aInternalData.getRowCount()) - 1;
|
2014-06-24 18:40:54 -04:00
|
|
|
return createDataSequenceAndAddToMap( OUString::number( nIndex ));
|
2008-03-06 16:43:34 +00:00
|
|
|
}
|
2011-12-10 22:03:11 -02:00
|
|
|
else if( !aRangeRepresentation.isEmpty())
|
2008-03-06 16:43:34 +00:00
|
|
|
{
|
|
|
|
// data
|
2014-06-24 18:40:54 -04:00
|
|
|
return createDataSequenceAndAddToMap( aRangeRepresentation );
|
2008-03-06 16:43:34 +00:00
|
|
|
}
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2008-03-06 16:43:34 +00:00
|
|
|
return Reference< chart2::data::XDataSequence >();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2014-07-02 09:53:54 -04:00
|
|
|
Reference<chart2::data::XDataSequence> SAL_CALL
|
|
|
|
InternalDataProvider::createDataSequenceByValueArray(
|
|
|
|
const OUString& aRole, const OUString& aRangeRepresentation )
|
|
|
|
{
|
|
|
|
return createDataSequenceFromArray(aRangeRepresentation, aRole);
|
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
Reference< sheet::XRangeSelection > SAL_CALL InternalDataProvider::getRangeSelection()
|
|
|
|
{
|
|
|
|
// there is no range selection component
|
|
|
|
return Reference< sheet::XRangeSelection >();
|
|
|
|
}
|
|
|
|
|
|
|
|
// ____ XInternalDataProvider ____
|
2014-04-03 13:52:06 +02:00
|
|
|
sal_Bool SAL_CALL InternalDataProvider::hasDataByRangeRepresentation( const OUString& aRange )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2014-04-15 15:17:13 +02:00
|
|
|
bool bResult = false;
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
if( aRange.match( lcl_aCategoriesRangeName ))
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2017-05-07 17:03:35 +10:00
|
|
|
OSL_ASSERT( aRange == lcl_aCategoriesRangeName );//it is not expected nor implemented that only parts of the categories are really requested
|
2007-05-22 17:59:49 +00:00
|
|
|
bResult = true;
|
|
|
|
}
|
|
|
|
else if( aRange.match( lcl_aLabelRangePrefix ))
|
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nIndex = aRange.copy( strlen(lcl_aLabelRangePrefix)).toInt32();
|
2010-01-13 17:06:34 +01:00
|
|
|
bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_Int32 nIndex = aRange.toInt32();
|
2010-01-13 17:06:34 +01:00
|
|
|
bResult = (nIndex < (m_bDataInColumns ? m_aInternalData.getColumnCount(): m_aInternalData.getRowCount()));
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return bResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
Sequence< uno::Any > SAL_CALL InternalDataProvider::getDataByRangeRepresentation( const OUString& aRange )
|
|
|
|
{
|
|
|
|
Sequence< uno::Any > aResult;
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
if( aRange.match( lcl_aLabelRangePrefix ) )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2018-08-05 19:30:53 +01:00
|
|
|
auto nIndex = aRange.copy( strlen(lcl_aLabelRangePrefix)).toUInt32();
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< uno::Any > aComplexLabel = m_bDataInColumns
|
2010-01-13 17:06:34 +01:00
|
|
|
? m_aInternalData.getComplexColumnLabel( nIndex )
|
|
|
|
: m_aInternalData.getComplexRowLabel( nIndex );
|
|
|
|
if( !aComplexLabel.empty() )
|
2015-11-19 09:14:59 +02:00
|
|
|
aResult = comphelper::containerToSequence(aComplexLabel);
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2018-08-05 19:30:53 +01:00
|
|
|
auto nPointIndex = aRange.copy( strlen(lcl_aCategoriesPointRangeNamePrefix) ).toUInt32();
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< uno::Any > aComplexCategory = m_bDataInColumns
|
2010-01-13 17:06:34 +01:00
|
|
|
? m_aInternalData.getComplexRowLabel( nPointIndex )
|
|
|
|
: m_aInternalData.getComplexColumnLabel( nPointIndex );
|
|
|
|
if( !aComplexCategory.empty() )
|
2015-11-19 09:14:59 +02:00
|
|
|
aResult = comphelper::containerToSequence(aComplexCategory);
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
|
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nLevel = aRange.copy( strlen(lcl_aCategoriesLevelRangeNamePrefix) ).toInt32();
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
|
2010-01-13 17:06:34 +01:00
|
|
|
if( nLevel < lcl_getInnerLevelCount( aCategories ) )
|
|
|
|
{
|
|
|
|
aResult.realloc( aCategories.size() );
|
|
|
|
transform( aCategories.begin(), aCategories.end(),
|
2010-11-30 01:45:03 +01:00
|
|
|
aResult.getArray(), lcl_copyFromLevel(nLevel) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
}
|
2014-12-18 13:21:05 +01:00
|
|
|
else if( aRange == lcl_aCategoriesRangeName )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
|
|
|
|
sal_Int32 nLevelCount = lcl_getInnerLevelCount( aCategories );
|
|
|
|
if( nLevelCount == 1 )
|
|
|
|
{
|
2017-08-02 12:57:55 +02:00
|
|
|
aResult = getDataByRangeRepresentation( lcl_aCategoriesLevelRangeNamePrefix + OUString::number( 0 ) );
|
2010-11-30 01:45:03 +01:00
|
|
|
}
|
2011-01-14 18:11:00 +01:00
|
|
|
else
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
2019-07-09 13:30:16 +02:00
|
|
|
// Maybe this 'else' part and the functions is not necessary anymore.
|
2017-08-02 12:57:55 +02:00
|
|
|
Sequence< OUString > aLabels = m_bDataInColumns ? getRowDescriptions() : getColumnDescriptions();
|
2010-11-30 01:45:03 +01:00
|
|
|
aResult.realloc( aLabels.getLength() );
|
2017-07-03 10:53:57 +02:00
|
|
|
transform( aLabels.begin(), aLabels.end(),
|
2010-11-30 01:45:03 +01:00
|
|
|
aResult.getArray(), CommonFunctors::makeAny< OUString >() );
|
|
|
|
}
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2007-05-22 17:59:49 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_Int32 nIndex = aRange.toInt32();
|
2009-12-21 10:27:32 +01:00
|
|
|
if( nIndex >= 0 )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2009-12-21 10:27:32 +01:00
|
|
|
Sequence< double > aData;
|
|
|
|
if( m_bDataInColumns )
|
2010-01-13 17:06:34 +01:00
|
|
|
aData = m_aInternalData.getColumnValues(nIndex);
|
2009-12-21 10:27:32 +01:00
|
|
|
else
|
2010-01-13 17:06:34 +01:00
|
|
|
aData = m_aInternalData.getRowValues(nIndex);
|
2019-05-04 23:16:48 +03:00
|
|
|
if( aData.hasElements() )
|
2009-12-21 10:27:32 +01:00
|
|
|
{
|
|
|
|
aResult.realloc( aData.getLength());
|
2017-07-03 10:53:57 +02:00
|
|
|
transform( aData.begin(), aData.end(),
|
2009-12-21 10:27:32 +01:00
|
|
|
aResult.getArray(), CommonFunctors::makeAny< double >());
|
|
|
|
}
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::setDataByRangeRepresentation(
|
|
|
|
const OUString& aRange, const Sequence< uno::Any >& aNewData )
|
|
|
|
{
|
2019-05-12 12:13:42 +03:00
|
|
|
auto aNewVector( comphelper::sequenceToContainer<vector< uno::Any >>(aNewData) );
|
2010-01-13 17:06:34 +01:00
|
|
|
if( aRange.match( lcl_aLabelRangePrefix ) )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_uInt32 nIndex = aRange.copy( strlen(lcl_aLabelRangePrefix)).toInt32();
|
2010-01-13 17:06:34 +01:00
|
|
|
if( m_bDataInColumns )
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexColumnLabel( nIndex, aNewVector );
|
2010-01-13 17:06:34 +01:00
|
|
|
else
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexRowLabel( nIndex, aNewVector );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
else if( aRange.match( lcl_aCategoriesPointRangeNamePrefix ) )
|
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nPointIndex = aRange.copy( strlen(lcl_aCategoriesLevelRangeNamePrefix)).toInt32();
|
2010-01-13 17:06:34 +01:00
|
|
|
if( m_bDataInColumns )
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexRowLabel( nPointIndex, aNewVector );
|
2010-01-13 17:06:34 +01:00
|
|
|
else
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexColumnLabel( nPointIndex, aNewVector );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
else if( aRange.match( lcl_aCategoriesLevelRangeNamePrefix ) )
|
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nLevel = aRange.copy( strlen(lcl_aCategoriesLevelRangeNamePrefix)).toInt32();
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
|
2010-01-13 17:06:34 +01:00
|
|
|
|
|
|
|
//ensure equal length
|
2010-11-30 01:45:03 +01:00
|
|
|
if( aNewVector.size() > aComplexCategories.size() )
|
|
|
|
aComplexCategories.resize( aNewVector.size() );
|
|
|
|
else if( aNewVector.size() < aComplexCategories.size() )
|
|
|
|
aNewVector.resize( aComplexCategories.size() );
|
2010-01-13 17:06:34 +01:00
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
|
|
|
|
aComplexCategories.begin(), lcl_setAnyAtLevel(nLevel) );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
if( m_bDataInColumns )
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setComplexRowLabels( aComplexCategories );
|
2007-05-22 17:59:49 +00:00
|
|
|
else
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setComplexColumnLabels( aComplexCategories );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2014-12-18 13:21:05 +01:00
|
|
|
else if( aRange == lcl_aCategoriesRangeName )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexCategories;
|
|
|
|
aComplexCategories.resize( aNewVector.size() );
|
|
|
|
transform( aComplexCategories.begin(), aComplexCategories.end(), aNewVector.begin(),
|
|
|
|
aComplexCategories.begin(), lcl_setAnyAtLevel(0) );
|
2010-01-13 17:06:34 +01:00
|
|
|
if( m_bDataInColumns )
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexRowLabels( aComplexCategories );
|
2010-01-13 17:06:34 +01:00
|
|
|
else
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexColumnLabels( aComplexCategories );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_Int32 nIndex = aRange.toInt32();
|
2009-12-21 10:27:32 +01:00
|
|
|
if( nIndex>=0 )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
vector< double > aNewDataVec;
|
2017-07-03 10:53:57 +02:00
|
|
|
transform( aNewData.begin(), aNewData.end(),
|
2007-05-22 17:59:49 +00:00
|
|
|
back_inserter( aNewDataVec ), CommonFunctors::AnyToDouble());
|
2009-12-21 10:27:32 +01:00
|
|
|
if( m_bDataInColumns )
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setColumnValues( nIndex, aNewDataVec );
|
2009-12-21 10:27:32 +01:00
|
|
|
else
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setRowValues( nIndex, aNewDataVec );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::insertSequence( ::sal_Int32 nAfterIndex )
|
|
|
|
{
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
increaseMapReferences( nAfterIndex + 1, m_aInternalData.getColumnCount());
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.insertColumn( nAfterIndex );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
increaseMapReferences( nAfterIndex + 1, m_aInternalData.getRowCount());
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.insertRow( nAfterIndex );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::deleteSequence( ::sal_Int32 nAtIndex )
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
deleteMapReferences( OUString::number( nAtIndex ));
|
|
|
|
deleteMapReferences( lcl_aLabelRangePrefix + OUString::number( nAtIndex ));
|
2007-05-22 17:59:49 +00:00
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
decreaseMapReferences( nAtIndex + 1, m_aInternalData.getColumnCount());
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.deleteColumn( nAtIndex );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-06-24 18:40:54 -04:00
|
|
|
decreaseMapReferences( nAtIndex + 1, m_aInternalData.getRowCount());
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.deleteRow( nAtIndex );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-03-06 16:43:34 +00:00
|
|
|
void SAL_CALL InternalDataProvider::appendSequence()
|
|
|
|
{
|
|
|
|
if( m_bDataInColumns )
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.appendColumn();
|
2008-03-06 16:43:34 +00:00
|
|
|
else
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.appendRow();
|
2008-03-06 16:43:34 +00:00
|
|
|
}
|
|
|
|
|
2010-01-28 10:52:28 +01:00
|
|
|
void SAL_CALL InternalDataProvider::insertComplexCategoryLevel( sal_Int32 nLevel )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( nLevel> 0, "you can only insert category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
|
|
|
|
if( nLevel>0 )
|
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_insertAnyAtLevel(nLevel) );
|
2010-01-28 10:52:28 +01:00
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_aInternalData.setComplexRowLabels( aComplexCategories );
|
|
|
|
else
|
|
|
|
m_aInternalData.setComplexColumnLabels( aComplexCategories );
|
|
|
|
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aRange.first, aRange.second, lcl_setModified());
|
2010-01-28 10:52:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
void SAL_CALL InternalDataProvider::deleteComplexCategoryLevel( sal_Int32 nLevel )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( nLevel>0, "you can only delete category levels > 0" );//the first categories level cannot be deleted, check the calling code for error
|
|
|
|
if( nLevel>0 )
|
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexCategories = m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels();
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aComplexCategories.begin(), aComplexCategories.end(), lcl_removeAnyAtLevel(nLevel) );
|
2010-01-28 10:52:28 +01:00
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_aInternalData.setComplexRowLabels( aComplexCategories );
|
|
|
|
else
|
|
|
|
m_aInternalData.setComplexColumnLabels( aComplexCategories );
|
|
|
|
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aRange.first, aRange.second, lcl_setModified());
|
2010-01-28 10:52:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
void SAL_CALL InternalDataProvider::insertDataPointForAllSequences( ::sal_Int32 nAfterIndex )
|
|
|
|
{
|
|
|
|
sal_Int32 nMaxRep = 0;
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.insertRow( nAfterIndex );
|
|
|
|
nMaxRep = m_aInternalData.getColumnCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.insertColumn( nAfterIndex );
|
|
|
|
nMaxRep = m_aInternalData.getRowCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// notify change to all affected ranges
|
2013-01-30 11:44:23 +01:00
|
|
|
tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
|
2013-08-21 15:07:31 +02:00
|
|
|
tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::number( nMaxRep )));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aBegin, aEnd, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aRange.first, aRange.second, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::deleteDataPointForAllSequences( ::sal_Int32 nAtIndex )
|
|
|
|
{
|
|
|
|
sal_Int32 nMaxRep = 0;
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.deleteRow( nAtIndex );
|
|
|
|
nMaxRep = m_aInternalData.getColumnCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.deleteColumn( nAtIndex );
|
|
|
|
nMaxRep = m_aInternalData.getRowCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// notify change to all affected ranges
|
2013-01-30 11:44:23 +01:00
|
|
|
tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
|
2013-08-21 15:07:31 +02:00
|
|
|
tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::number( nMaxRep )));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aBegin, aEnd, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aRange.first, aRange.second, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::swapDataPointWithNextOneForAllSequences( ::sal_Int32 nAtIndex )
|
|
|
|
{
|
2009-12-21 10:27:32 +01:00
|
|
|
if( m_bDataInColumns )
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.swapRowWithNext( nAtIndex );
|
2009-12-21 10:27:32 +01:00
|
|
|
else
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.swapColumnWithNext( nAtIndex );
|
2007-05-22 17:59:49 +00:00
|
|
|
sal_Int32 nMaxRep = (m_bDataInColumns
|
2010-01-13 17:06:34 +01:00
|
|
|
? m_aInternalData.getColumnCount()
|
|
|
|
: m_aInternalData.getRowCount());
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
// notify change to all affected ranges
|
2013-01-30 11:44:23 +01:00
|
|
|
tSequenceMap::const_iterator aBegin( m_aSequenceMap.lower_bound( "0"));
|
2013-08-21 15:07:31 +02:00
|
|
|
tSequenceMap::const_iterator aEnd( m_aSequenceMap.upper_bound( OUString::number( nMaxRep )));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aBegin, aEnd, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
tSequenceMapRange aRange( m_aSequenceMap.equal_range( lcl_aCategoriesRangeName ));
|
2017-02-15 23:55:18 +02:00
|
|
|
std::for_each( aRange.first, aRange.second, lcl_setModified());
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::registerDataSequenceForChanges( const Reference< chart2::data::XDataSequence >& xSeq )
|
|
|
|
{
|
|
|
|
if( xSeq.is())
|
2014-06-24 18:40:54 -04:00
|
|
|
addDataSequenceToMap( xSeq->getSourceRangeRepresentation(), xSeq );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ____ XRangeXMLConversion ____
|
|
|
|
OUString SAL_CALL InternalDataProvider::convertRangeToXML( const OUString& aRangeRepresentation )
|
|
|
|
{
|
|
|
|
XMLRangeHelper::CellRange aRange;
|
2013-11-15 11:05:19 +02:00
|
|
|
aRange.aTableName = "local-table";
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
// attention: this data provider has the limitation that it stores
|
|
|
|
// internally if data comes from columns or rows. It is intended for
|
|
|
|
// creating only one used data source.
|
|
|
|
// @todo: add this information in the range representation strings
|
2010-01-13 17:06:34 +01:00
|
|
|
if( aRangeRepresentation.match( lcl_aCategoriesRangeName ))
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2017-05-07 17:03:35 +10:00
|
|
|
OSL_ASSERT( aRangeRepresentation == lcl_aCategoriesRangeName );//it is not expected nor implemented that only parts of the categories are really requested
|
2007-05-22 17:59:49 +00:00
|
|
|
aRange.aUpperLeft.bIsEmpty = false;
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = 0;
|
|
|
|
aRange.aUpperLeft.nRow = 1;
|
|
|
|
aRange.aLowerRight = aRange.aUpperLeft;
|
2010-01-13 17:06:34 +01:00
|
|
|
aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = 1;
|
|
|
|
aRange.aUpperLeft.nRow = 0;
|
|
|
|
aRange.aLowerRight = aRange.aUpperLeft;
|
2010-01-13 17:06:34 +01:00
|
|
|
aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if( aRangeRepresentation.match( lcl_aLabelRangePrefix ))
|
|
|
|
{
|
2014-11-03 14:03:54 +02:00
|
|
|
sal_Int32 nIndex = aRangeRepresentation.copy( strlen(lcl_aLabelRangePrefix)).toInt32();
|
2007-05-22 17:59:49 +00:00
|
|
|
aRange.aUpperLeft.bIsEmpty = false;
|
|
|
|
aRange.aLowerRight.bIsEmpty = true;
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = nIndex + 1;
|
|
|
|
aRange.aUpperLeft.nRow = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = 0;
|
|
|
|
aRange.aUpperLeft.nRow = nIndex + 1;
|
|
|
|
}
|
|
|
|
}
|
2014-12-18 13:21:05 +01:00
|
|
|
else if( aRangeRepresentation == lcl_aCompleteRange )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
aRange.aUpperLeft.bIsEmpty = false;
|
|
|
|
aRange.aLowerRight.bIsEmpty = false;
|
|
|
|
aRange.aUpperLeft.nColumn = 0;
|
|
|
|
aRange.aUpperLeft.nRow = 0;
|
2010-01-13 17:06:34 +01:00
|
|
|
aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
|
|
|
|
aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
sal_Int32 nIndex = aRangeRepresentation.toInt32();
|
|
|
|
aRange.aUpperLeft.bIsEmpty = false;
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = nIndex + 1;
|
|
|
|
aRange.aUpperLeft.nRow = 1;
|
|
|
|
aRange.aLowerRight = aRange.aUpperLeft;
|
2010-01-13 17:06:34 +01:00
|
|
|
aRange.aLowerRight.nRow = m_aInternalData.getRowCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
aRange.aUpperLeft.nColumn = 1;
|
|
|
|
aRange.aUpperLeft.nRow = nIndex + 1;
|
|
|
|
aRange.aLowerRight = aRange.aUpperLeft;
|
2010-01-13 17:06:34 +01:00
|
|
|
aRange.aLowerRight.nColumn = m_aInternalData.getColumnCount();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return XMLRangeHelper::getXMLStringFromCellRange( aRange );
|
|
|
|
}
|
|
|
|
|
|
|
|
OUString SAL_CALL InternalDataProvider::convertRangeFromXML( const OUString& aXMLRange )
|
|
|
|
{
|
2017-04-28 18:05:57 +02:00
|
|
|
const OUString aPivotTableID("PT@");
|
|
|
|
if (aXMLRange.startsWith(aPivotTableID))
|
2017-07-11 11:04:35 +02:00
|
|
|
return aXMLRange.copy(aPivotTableID.getLength());
|
2017-04-28 18:05:57 +02:00
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
XMLRangeHelper::CellRange aRange( XMLRangeHelper::getCellRangeFromXMLString( aXMLRange ));
|
|
|
|
if( aRange.aUpperLeft.bIsEmpty )
|
|
|
|
{
|
|
|
|
OSL_ENSURE( aRange.aLowerRight.bIsEmpty, "Weird Range" );
|
|
|
|
return OUString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// "all"
|
|
|
|
if( !aRange.aLowerRight.bIsEmpty &&
|
|
|
|
( aRange.aUpperLeft.nColumn != aRange.aLowerRight.nColumn ) &&
|
|
|
|
( aRange.aUpperLeft.nRow != aRange.aLowerRight.nRow ) )
|
2019-07-30 17:58:03 +02:00
|
|
|
return lcl_aCompleteRange;
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
// attention: this data provider has the limitation that it stores
|
|
|
|
// internally if data comes from columns or rows. It is intended for
|
|
|
|
// creating only one used data source.
|
|
|
|
// @todo: add this information in the range representation strings
|
|
|
|
|
|
|
|
// data in columns
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
{
|
|
|
|
if( aRange.aUpperLeft.nColumn == 0 )
|
2019-07-30 17:58:03 +02:00
|
|
|
return lcl_aCategoriesRangeName;
|
2007-05-22 17:59:49 +00:00
|
|
|
if( aRange.aUpperLeft.nRow == 0 )
|
2013-08-21 15:07:31 +02:00
|
|
|
return lcl_aLabelRangePrefix + OUString::number( aRange.aUpperLeft.nColumn - 1 );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2013-08-21 15:07:31 +02:00
|
|
|
return OUString::number( aRange.aUpperLeft.nColumn - 1 );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// data in rows
|
|
|
|
if( aRange.aUpperLeft.nRow == 0 )
|
2019-07-30 17:58:03 +02:00
|
|
|
return lcl_aCategoriesRangeName;
|
2007-05-22 17:59:49 +00:00
|
|
|
if( aRange.aUpperLeft.nColumn == 0 )
|
2013-08-21 15:07:31 +02:00
|
|
|
return lcl_aLabelRangePrefix + OUString::number( aRange.aUpperLeft.nRow - 1 );
|
2007-05-22 17:59:49 +00:00
|
|
|
|
2013-08-21 15:07:31 +02:00
|
|
|
return OUString::number( aRange.aUpperLeft.nRow - 1 );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
namespace
|
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
|
|
|
|
template< class Type >
|
|
|
|
Sequence< Sequence< Type > > lcl_convertVectorVectorToSequenceSequence( const vector< vector< Type > >& rIn )
|
|
|
|
{
|
|
|
|
Sequence< Sequence< Type > > aRet;
|
|
|
|
sal_Int32 nOuterCount = rIn.size();
|
|
|
|
if( nOuterCount )
|
|
|
|
{
|
|
|
|
aRet.realloc(nOuterCount);
|
|
|
|
for( sal_Int32 nN=0; nN<nOuterCount; nN++)
|
2015-11-19 09:14:59 +02:00
|
|
|
aRet[nN]= comphelper::containerToSequence( rIn[nN] );
|
2010-11-30 01:45:03 +01:00
|
|
|
}
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
template< class Type >
|
|
|
|
vector< vector< Type > > lcl_convertSequenceSequenceToVectorVector( const Sequence< Sequence< Type > >& rIn )
|
|
|
|
{
|
|
|
|
vector< vector< Type > > aRet;
|
|
|
|
sal_Int32 nOuterCount = rIn.getLength();
|
|
|
|
if( nOuterCount )
|
|
|
|
{
|
|
|
|
aRet.resize(nOuterCount);
|
|
|
|
for( sal_Int32 nN=0; nN<nOuterCount; nN++)
|
2019-05-12 12:13:42 +03:00
|
|
|
aRet[nN]= comphelper::sequenceToContainer<vector< Type >>( rIn[nN] );
|
2010-11-30 01:45:03 +01:00
|
|
|
}
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< Sequence< OUString > > lcl_convertComplexAnyVectorToStringSequence( const vector< vector< uno::Any > >& rIn )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
std::vector< Sequence< OUString > > aRet;
|
2010-01-13 17:06:34 +01:00
|
|
|
sal_Int32 nOuterCount = rIn.size();
|
|
|
|
if( nOuterCount )
|
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
aRet.resize(nOuterCount);
|
2010-01-13 17:06:34 +01:00
|
|
|
for( sal_Int32 nN=0; nN<nOuterCount; nN++)
|
2015-12-03 10:28:31 +02:00
|
|
|
aRet[nN] = comphelper::containerToSequence(lcl_AnyToStringSequence( rIn[nN] ));
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > lcl_convertComplexStringSequenceToAnyVector( const Sequence< Sequence< OUString > >& rIn )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aRet;
|
2010-01-13 17:06:34 +01:00
|
|
|
sal_Int32 nOuterCount = rIn.getLength();
|
2018-09-04 18:03:28 +02:00
|
|
|
aRet.reserve(nOuterCount);
|
|
|
|
for (sal_Int32 nN = 0; nN < nOuterCount; nN++)
|
2015-12-03 10:28:31 +02:00
|
|
|
aRet.push_back( lcl_StringToAnyVector( rIn[nN] ) );
|
2010-01-13 17:06:34 +01:00
|
|
|
return aRet;
|
|
|
|
}
|
|
|
|
|
|
|
|
class SplitCategoriesProvider_ForComplexDescriptions : public SplitCategoriesProvider
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
2017-02-15 23:55:18 +02:00
|
|
|
explicit SplitCategoriesProvider_ForComplexDescriptions( const std::vector< std::vector< uno::Any > >& rComplexDescriptions )
|
2010-01-13 17:06:34 +01:00
|
|
|
: m_rComplexDescriptions( rComplexDescriptions )
|
|
|
|
{}
|
|
|
|
|
2015-10-12 16:04:04 +02:00
|
|
|
virtual sal_Int32 getLevelCount() const override;
|
|
|
|
virtual uno::Sequence< OUString > getStringsForLevel( sal_Int32 nIndex ) const override;
|
2010-01-13 17:06:34 +01:00
|
|
|
|
|
|
|
private:
|
2017-02-15 23:55:18 +02:00
|
|
|
const std::vector< std::vector< uno::Any > >& m_rComplexDescriptions;
|
2010-01-13 17:06:34 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
sal_Int32 SplitCategoriesProvider_ForComplexDescriptions::getLevelCount() const
|
|
|
|
{
|
|
|
|
return lcl_getInnerLevelCount( m_rComplexDescriptions );
|
|
|
|
}
|
2013-04-07 12:06:47 +02:00
|
|
|
uno::Sequence< OUString > SplitCategoriesProvider_ForComplexDescriptions::getStringsForLevel( sal_Int32 nLevel ) const
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2013-04-07 12:06:47 +02:00
|
|
|
uno::Sequence< OUString > aResult;
|
2010-01-13 17:06:34 +01:00
|
|
|
if( nLevel < lcl_getInnerLevelCount( m_rComplexDescriptions ) )
|
|
|
|
{
|
|
|
|
aResult.realloc( m_rComplexDescriptions.size() );
|
|
|
|
transform( m_rComplexDescriptions.begin(), m_rComplexDescriptions.end(),
|
|
|
|
aResult.getArray(), lcl_getStringFromLevelVector(nLevel) );
|
|
|
|
}
|
|
|
|
return aResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
}//anonymous namespace
|
|
|
|
|
2010-11-30 01:45:03 +01:00
|
|
|
// ____ XDateCategories ____
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< double > SAL_CALL InternalDataProvider::getDateCategories()
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
double fNan = InternalDataProvider::getNotANumber();
|
|
|
|
double fValue = fNan;
|
|
|
|
vector< vector< uno::Any > > aCategories( m_bDataInColumns ? m_aInternalData.getComplexRowLabels() : m_aInternalData.getComplexColumnLabels());
|
|
|
|
sal_Int32 nCount = aCategories.size();
|
|
|
|
Sequence< double > aDoubles( nCount );
|
2018-03-03 23:26:43 +01:00
|
|
|
sal_Int32 nN=0;
|
|
|
|
for (auto const& category : aCategories)
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
2018-03-03 23:26:43 +01:00
|
|
|
if( !( !category.empty() && (category[0]>>=fValue) ) )
|
2010-11-30 01:45:03 +01:00
|
|
|
fValue = fNan;
|
2018-03-03 23:26:43 +01:00
|
|
|
aDoubles[nN++]=fValue;
|
2010-11-30 01:45:03 +01:00
|
|
|
}
|
|
|
|
return aDoubles;
|
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setDateCategories( const Sequence< double >& rDates )
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
sal_Int32 nCount = rDates.getLength();
|
|
|
|
vector< vector< uno::Any > > aNewCategories;
|
|
|
|
aNewCategories.reserve(nCount);
|
|
|
|
vector< uno::Any > aSingleLabel(1);
|
|
|
|
|
|
|
|
for(sal_Int32 nN=0; nN<nCount; ++nN )
|
|
|
|
{
|
2017-02-03 08:54:47 +02:00
|
|
|
aSingleLabel[0] <<= rDates[nN];
|
2010-11-30 01:45:03 +01:00
|
|
|
aNewCategories.push_back(aSingleLabel);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_bDataInColumns )
|
|
|
|
m_aInternalData.setComplexRowLabels( aNewCategories );
|
|
|
|
else
|
|
|
|
m_aInternalData.setComplexColumnLabels( aNewCategories );
|
|
|
|
}
|
|
|
|
|
|
|
|
// ____ XAnyDescriptionAccess ____
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyRowDescriptions()
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexRowLabels() );
|
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setAnyRowDescriptions( const Sequence< Sequence< uno::Any > >& aRowDescriptions )
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
m_aInternalData.setComplexRowLabels( lcl_convertSequenceSequenceToVectorVector( aRowDescriptions ) );
|
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< Sequence< uno::Any > > SAL_CALL InternalDataProvider::getAnyColumnDescriptions()
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
return lcl_convertVectorVectorToSequenceSequence( m_aInternalData.getComplexColumnLabels() );
|
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setAnyColumnDescriptions( const Sequence< Sequence< uno::Any > >& aColumnDescriptions )
|
2010-11-30 01:45:03 +01:00
|
|
|
{
|
|
|
|
m_aInternalData.setComplexColumnLabels( lcl_convertSequenceSequenceToVectorVector( aColumnDescriptions ) );
|
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
// ____ XComplexDescriptionAccess ____
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexRowDescriptions()
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
return comphelper::containerToSequence(lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexRowLabels() ));
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setComplexRowDescriptions( const Sequence< Sequence< OUString > >& aRowDescriptions )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexRowLabels( lcl_convertComplexStringSequenceToAnyVector(aRowDescriptions) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
Sequence< Sequence< OUString > > SAL_CALL InternalDataProvider::getComplexColumnDescriptions()
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2015-12-03 10:28:31 +02:00
|
|
|
return comphelper::containerToSequence(lcl_convertComplexAnyVectorToStringSequence( m_aInternalData.getComplexColumnLabels() ));
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setComplexColumnDescriptions( const Sequence< Sequence< OUString > >& aColumnDescriptions )
|
2010-01-13 17:06:34 +01:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
m_aInternalData.setComplexColumnLabels( lcl_convertComplexStringSequenceToAnyVector(aColumnDescriptions) );
|
2010-01-13 17:06:34 +01:00
|
|
|
}
|
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
// ____ XChartDataArray ____
|
|
|
|
Sequence< Sequence< double > > SAL_CALL InternalDataProvider::getData()
|
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
return m_aInternalData.getData();
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2009-12-21 10:27:32 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setData( const Sequence< Sequence< double > >& rDataInRows )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-01-13 17:06:34 +01:00
|
|
|
return m_aInternalData.setData( rDataInRows );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setRowDescriptions( const Sequence< OUString >& aRowDescriptions )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexDescriptions( aRowDescriptions.getLength() );
|
2010-01-13 17:06:34 +01:00
|
|
|
transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aRowDescriptions.getConstArray(),
|
2010-11-30 01:45:03 +01:00
|
|
|
aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setComplexRowLabels( aComplexDescriptions );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
void SAL_CALL InternalDataProvider::setColumnDescriptions( const Sequence< OUString >& aColumnDescriptions )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexDescriptions( aColumnDescriptions.getLength() );
|
2010-01-13 17:06:34 +01:00
|
|
|
transform( aComplexDescriptions.begin(), aComplexDescriptions.end(), aColumnDescriptions.getConstArray(),
|
2010-11-30 01:45:03 +01:00
|
|
|
aComplexDescriptions.begin(), lcl_setAnyAtLevelFromStringSequence(0) );
|
2010-01-13 17:06:34 +01:00
|
|
|
m_aInternalData.setComplexColumnLabels( aComplexDescriptions );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
Sequence< OUString > SAL_CALL InternalDataProvider::getRowDescriptions()
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexRowLabels() );
|
2010-01-13 17:06:34 +01:00
|
|
|
SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
|
|
|
|
return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
2010-01-13 17:06:34 +01:00
|
|
|
Sequence< OUString > SAL_CALL InternalDataProvider::getColumnDescriptions()
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2010-11-30 01:45:03 +01:00
|
|
|
vector< vector< uno::Any > > aComplexLabels( m_aInternalData.getComplexColumnLabels() );
|
2010-01-13 17:06:34 +01:00
|
|
|
SplitCategoriesProvider_ForComplexDescriptions aProvider( aComplexLabels );
|
|
|
|
return ExplicitCategoriesProvider::getExplicitSimpleCategories( aProvider );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ____ XChartData (base of XChartDataArray) ____
|
|
|
|
void SAL_CALL InternalDataProvider::addChartDataChangeEventListener(
|
2015-11-27 11:14:38 +02:00
|
|
|
const Reference< css::chart::XChartDataChangeEventListener >& )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SAL_CALL InternalDataProvider::removeChartDataChangeEventListener(
|
2015-11-27 11:14:38 +02:00
|
|
|
const Reference< css::chart::XChartDataChangeEventListener >& )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
double SAL_CALL InternalDataProvider::getNotANumber()
|
|
|
|
{
|
|
|
|
double fNan;
|
|
|
|
::rtl::math::setNan( & fNan );
|
|
|
|
return fNan;
|
|
|
|
}
|
|
|
|
|
2014-04-03 13:52:06 +02:00
|
|
|
sal_Bool SAL_CALL InternalDataProvider::isNotANumber( double nNumber )
|
2007-05-22 17:59:49 +00:00
|
|
|
{
|
2020-03-13 15:41:40 +09:00
|
|
|
return std::isnan( nNumber )
|
2020-03-12 19:45:07 +09:00
|
|
|
|| std::isinf( nNumber );
|
2007-05-22 17:59:49 +00:00
|
|
|
}
|
2008-06-16 11:56:50 +00:00
|
|
|
// lang::XInitialization:
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL InternalDataProvider::initialize(const uno::Sequence< uno::Any > & _aArguments)
|
2008-06-16 11:56:50 +00:00
|
|
|
{
|
|
|
|
comphelper::SequenceAsHashMap aArgs(_aArguments);
|
2015-04-23 17:03:58 +02:00
|
|
|
if ( aArgs.getUnpackedValueOrDefault( "CreateDefaultData", false ) )
|
2016-11-10 15:06:03 +02:00
|
|
|
m_aInternalData.createDefaultData();
|
2008-06-16 11:56:50 +00:00
|
|
|
}
|
2016-11-10 15:06:03 +02:00
|
|
|
|
2007-05-22 17:59:49 +00:00
|
|
|
// ____ XCloneable ____
|
|
|
|
Reference< util::XCloneable > SAL_CALL InternalDataProvider::createClone()
|
|
|
|
{
|
|
|
|
return Reference< util::XCloneable >( new InternalDataProvider( *this ));
|
|
|
|
}
|
|
|
|
|
2014-12-09 08:30:11 +02:00
|
|
|
OUString SAL_CALL InternalDataProvider::getImplementationName()
|
|
|
|
{
|
2016-11-07 10:48:36 +02:00
|
|
|
// note: in xmloff this name is used to indicate usage of own data
|
2019-07-30 17:58:03 +02:00
|
|
|
return "com.sun.star.comp.chart.InternalDataProvider";
|
2014-12-09 08:30:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
sal_Bool SAL_CALL InternalDataProvider::supportsService( const OUString& rServiceName )
|
|
|
|
{
|
|
|
|
return cppu::supportsService(this, rServiceName);
|
|
|
|
}
|
|
|
|
|
|
|
|
css::uno::Sequence< OUString > SAL_CALL InternalDataProvider::getSupportedServiceNames()
|
|
|
|
{
|
2016-11-10 15:06:03 +02:00
|
|
|
return { "com.sun.star.chart2.data.DataProvider" };
|
2014-12-09 08:30:11 +02:00
|
|
|
}
|
2007-05-22 17:59:49 +00:00
|
|
|
|
|
|
|
} // namespace chart
|
2010-10-12 15:59:00 +02:00
|
|
|
|
2017-12-08 15:58:41 +02:00
|
|
|
extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
|
2017-07-28 07:28:07 +02:00
|
|
|
com_sun_star_comp_chart_InternalDataProvider_get_implementation(css::uno::XComponentContext *,
|
2015-02-12 03:47:36 +02:00
|
|
|
css::uno::Sequence<css::uno::Any> const &)
|
|
|
|
{
|
2017-07-28 07:28:07 +02:00
|
|
|
return cppu::acquire(new ::chart::InternalDataProvider);
|
2015-02-12 03:47:36 +02:00
|
|
|
}
|
|
|
|
|
2010-10-12 15:59:00 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|