/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_chart2.hxx" #include "InternalData.hxx" #include "ResId.hxx" #include "Strings.hrc" #include "macros.hxx" #include using ::com::sun::star::uno::Sequence; using ::rtl::OUString; using namespace ::com::sun::star; using namespace ::std; namespace chart { // ---------------------------------------- namespace { struct lcl_NumberedStringGenerator { lcl_NumberedStringGenerator( const OUString & rStub, const OUString & rWildcard ) : m_aStub( rStub ), m_nCounter( 0 ), m_nStubStartIndex( rStub.indexOf( rWildcard )), m_nWildcardLength( rWildcard.getLength()) { } vector< uno::Any > operator()() { vector< uno::Any > aRet(1); aRet[0] = uno::makeAny( m_aStub.replaceAt( m_nStubStartIndex, m_nWildcardLength, OUString::valueOf( ++m_nCounter )) ); return aRet; } private: OUString m_aStub; sal_Int32 m_nCounter; const sal_Int32 m_nStubStartIndex; const sal_Int32 m_nWildcardLength; }; template< typename T > Sequence< T > lcl_ValarrayToSequence( const ::std::valarray< T > & rValarray ) { // is there a more elegant way of conversion? Sequence< T > aResult( rValarray.size()); for( size_t i = 0; i < rValarray.size(); ++i ) aResult[i] = rValarray[i]; return aResult; } } // anonymous namespace // ---------------------------------------- InternalData::InternalData() : m_nColumnCount( 0 ) , m_nRowCount( 0 ) , m_aRowLabels( 0 ) , m_aColumnLabels( 0 ) {} void InternalData::createDefaultData() { const sal_Int32 nRowCount = 4; const sal_Int32 nColumnCount = 3; m_nRowCount = nRowCount; m_nColumnCount = nColumnCount; const sal_Int32 nSize = nColumnCount * nRowCount; // @todo: localize this! const OUString aRowName( ::chart::SchResId::getResString( STR_ROW_LABEL )); const OUString aColName( ::chart::SchResId::getResString( STR_COLUMN_LABEL )); const double fDefaultData[ nSize ] = { 9.10, 3.20, 4.54, 2.40, 8.80, 9.65, 3.10, 1.50, 3.70, 4.30, 9.02, 6.20 }; m_aData.resize( nSize ); for( sal_Int32 i=0; i >& rDataInRows ) { m_nRowCount = rDataInRows.getLength(); m_nColumnCount = (m_nRowCount ? rDataInRows[0].getLength() : 0); if( m_aRowLabels.size() != static_cast< sal_uInt32 >( m_nRowCount )) m_aRowLabels.resize( m_nRowCount ); if( m_aColumnLabels.size() != static_cast< sal_uInt32 >( m_nColumnCount )) m_aColumnLabels.resize( m_nColumnCount ); m_aData.resize( m_nRowCount * m_nColumnCount ); double fNan; ::rtl::math::setNan( & fNan ); // set all values to Nan m_aData = fNan; for( sal_Int32 nRow=0; nRow > InternalData::getData() const { Sequence< Sequence< double > > aResult( m_nRowCount ); for( sal_Int32 i=0; i( m_aData[ ::std::slice( i*m_nColumnCount, m_nColumnCount, 1 ) ] ); return aResult; } Sequence< double > InternalData::getColumnValues( sal_Int32 nColumnIndex ) const { if( nColumnIndex >= 0 && nColumnIndex < m_nColumnCount ) return lcl_ValarrayToSequence< tDataType::value_type >( m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] ); return Sequence< double >(); } Sequence< double > InternalData::getRowValues( sal_Int32 nRowIndex ) const { if( nRowIndex >= 0 && nRowIndex < m_nRowCount ) return lcl_ValarrayToSequence< tDataType::value_type >( m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ] ); return Sequence< double >(); } void InternalData::setColumnValues( sal_Int32 nColumnIndex, const vector< double > & rNewData ) { if( nColumnIndex < 0 ) return; enlargeData( nColumnIndex + 1, rNewData.size() ); tDataType aSlice = m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ]; for( vector< double >::size_type i = 0; i < rNewData.size(); ++i ) aSlice[i] = rNewData[i]; m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] = aSlice; } void InternalData::setRowValues( sal_Int32 nRowIndex, const vector< double > & rNewData ) { if( nRowIndex < 0 ) return; enlargeData( rNewData.size(), nRowIndex+1 ); tDataType aSlice = m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]; for( vector< double >::size_type i = 0; i < rNewData.size(); ++i ) aSlice[i] = rNewData[i]; m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]= aSlice; } void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< uno::Any >& rComplexLabel ) { if( nColumnIndex < 0 ) return; if( nColumnIndex >= static_cast< sal_Int32 >( m_aColumnLabels.size() ) ) { m_aColumnLabels.resize(nColumnIndex+1); enlargeData( nColumnIndex+1, 0 ); } m_aColumnLabels[nColumnIndex]=rComplexLabel; } void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< uno::Any >& rComplexLabel ) { if( nRowIndex < 0 ) return; if( nRowIndex >= static_cast< sal_Int32 >( m_aRowLabels.size() ) ) { m_aRowLabels.resize(nRowIndex+1); enlargeData( 0, nRowIndex+1 ); } m_aRowLabels[nRowIndex] = rComplexLabel; } vector< uno::Any > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const { if( nColumnIndex < static_cast< sal_Int32 >( m_aColumnLabels.size() ) ) return m_aColumnLabels[nColumnIndex]; else return vector< uno::Any >(); } vector< uno::Any > InternalData::getComplexRowLabel( sal_Int32 nRowIndex ) const { if( nRowIndex < static_cast< sal_Int32 >( m_aRowLabels.size() ) ) return m_aRowLabels[nRowIndex]; else return vector< uno::Any >(); } void InternalData::swapRowWithNext( sal_Int32 nRowIndex ) { if( nRowIndex < m_nRowCount - 1 ) { const sal_Int32 nMax = m_nColumnCount; for( sal_Int32 nColIdx=0; nColIdx aTemp( m_aRowLabels[nRowIndex] ); m_aRowLabels[nRowIndex] = m_aRowLabels[nRowIndex + 1]; m_aRowLabels[nRowIndex + 1] = aTemp; } } void InternalData::swapColumnWithNext( sal_Int32 nColumnIndex ) { if( nColumnIndex < m_nColumnCount - 1 ) { const sal_Int32 nMax = m_nRowCount; for( sal_Int32 nRowIdx=0; nRowIdx aTemp( m_aColumnLabels[nColumnIndex] ); m_aColumnLabels[nColumnIndex] = m_aColumnLabels[nColumnIndex + 1]; m_aColumnLabels[nColumnIndex + 1] = aTemp; } } bool InternalData::enlargeData( sal_Int32 nColumnCount, sal_Int32 nRowCount ) { sal_Int32 nNewColumnCount( ::std::max( m_nColumnCount, nColumnCount ) ); sal_Int32 nNewRowCount( ::std::max( m_nRowCount, nRowCount ) ); sal_Int32 nNewSize( nNewColumnCount*nNewRowCount ); bool bGrow = (nNewSize > m_nColumnCount*m_nRowCount); if( bGrow ) { double fNan; ::rtl::math::setNan( &fNan ); tDataType aNewData( fNan, nNewSize ); // copy old data for( int nCol=0; nCol( aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] ) = m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ]; m_aData.resize( nNewSize ); m_aData = aNewData; } m_nColumnCount = nNewColumnCount; m_nRowCount = nNewRowCount; return bGrow; } void InternalData::insertColumn( sal_Int32 nAfterIndex ) { // note: -1 is allowed, as we insert after the given index OSL_ASSERT( nAfterIndex < m_nColumnCount && nAfterIndex >= -1 ); if( nAfterIndex >= m_nColumnCount || nAfterIndex < -1 ) return; sal_Int32 nNewColumnCount = m_nColumnCount + 1; sal_Int32 nNewSize( nNewColumnCount * m_nRowCount ); double fNan; ::rtl::math::setNan( &fNan ); tDataType aNewData( fNan, nNewSize ); // copy old data int nCol=0; for( ; nCol<=nAfterIndex; ++nCol ) aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] = static_cast< tDataType >( m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] ); for( ++nCol; nCol( m_aData[ ::std::slice( nCol - 1, m_nRowCount, m_nColumnCount ) ] ); m_nColumnCount = nNewColumnCount; m_aData.resize( nNewSize ); m_aData = aNewData; // labels if( nAfterIndex < static_cast< sal_Int32 >( m_aColumnLabels.size())) m_aColumnLabels.insert( m_aColumnLabels.begin() + (nAfterIndex + 1), vector< uno::Any >(1) ); #if OSL_DEBUG_LEVEL > 2 traceData(); #endif } sal_Int32 InternalData::appendColumn() { insertColumn( getColumnCount() - 1 ); return getColumnCount() - 1; } sal_Int32 InternalData::appendRow() { insertRow( getRowCount() - 1 ); return getRowCount() - 1; } void InternalData::insertRow( sal_Int32 nAfterIndex ) { // note: -1 is allowed, as we insert after the given index OSL_ASSERT( nAfterIndex < m_nRowCount && nAfterIndex >= -1 ); if( nAfterIndex >= m_nRowCount || nAfterIndex < -1 ) return; sal_Int32 nNewRowCount = m_nRowCount + 1; sal_Int32 nNewSize( m_nColumnCount * nNewRowCount ); double fNan; ::rtl::math::setNan( &fNan ); tDataType aNewData( fNan, nNewSize ); // copy old data sal_Int32 nIndex = nAfterIndex + 1; aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] = static_cast< tDataType >( m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] ); if( nIndex < m_nRowCount ) { sal_Int32 nRemainingCount = m_nColumnCount * (m_nRowCount - nIndex); aNewData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] = static_cast< tDataType >( m_aData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] ); } m_nRowCount = nNewRowCount; m_aData.resize( nNewSize ); m_aData = aNewData; // labels if( nAfterIndex < static_cast< sal_Int32 >( m_aRowLabels.size())) m_aRowLabels.insert( m_aRowLabels.begin() + nIndex, vector< uno::Any > (1)); #if OSL_DEBUG_LEVEL > 2 traceData(); #endif } void InternalData::deleteColumn( sal_Int32 nAtIndex ) { OSL_ASSERT( nAtIndex < m_nColumnCount && nAtIndex >= 0 ); if( nAtIndex >= m_nColumnCount || m_nColumnCount < 1 || nAtIndex < 0 ) return; sal_Int32 nNewColumnCount = m_nColumnCount - 1; sal_Int32 nNewSize( nNewColumnCount * m_nRowCount ); double fNan; ::rtl::math::setNan( &fNan ); tDataType aNewData( fNan, nNewSize ); // copy old data int nCol=0; for( ; nCol( m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] ); for( ; nCol( m_aData[ ::std::slice( nCol + 1, m_nRowCount, m_nColumnCount ) ] ); m_nColumnCount = nNewColumnCount; m_aData.resize( nNewSize ); m_aData = aNewData; // labels if( nAtIndex < static_cast< sal_Int32 >( m_aColumnLabels.size())) m_aColumnLabels.erase( m_aColumnLabels.begin() + nAtIndex ); #if OSL_DEBUG_LEVEL > 2 traceData(); #endif } void InternalData::deleteRow( sal_Int32 nAtIndex ) { OSL_ASSERT( nAtIndex < m_nRowCount && nAtIndex >= 0 ); if( nAtIndex >= m_nRowCount || m_nRowCount < 1 || nAtIndex < 0 ) return; sal_Int32 nNewRowCount = m_nRowCount - 1; sal_Int32 nNewSize( m_nColumnCount * nNewRowCount ); double fNan; ::rtl::math::setNan( &fNan ); tDataType aNewData( fNan, nNewSize ); // copy old data sal_Int32 nIndex = nAtIndex; if( nIndex ) aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] = static_cast< tDataType >( m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] ); if( nIndex < nNewRowCount ) { sal_Int32 nRemainingCount = m_nColumnCount * (nNewRowCount - nIndex); aNewData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] = static_cast< tDataType >( m_aData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] ); } m_nRowCount = nNewRowCount; m_aData.resize( nNewSize ); m_aData = aNewData; // labels if( nAtIndex < static_cast< sal_Int32 >( m_aRowLabels.size())) m_aRowLabels.erase( m_aRowLabels.begin() + nAtIndex ); #if OSL_DEBUG_LEVEL > 2 traceData(); #endif } sal_Int32 InternalData::getRowCount() const { return m_nRowCount; } sal_Int32 InternalData::getColumnCount() const { return m_nColumnCount; } void InternalData::setComplexRowLabels( const vector< vector< uno::Any > >& rNewRowLabels ) { m_aRowLabels = rNewRowLabels; sal_Int32 nNewRowCount = static_cast< sal_Int32 >( m_aRowLabels.size() ); if( nNewRowCount < m_nRowCount ) m_aRowLabels.resize( m_nRowCount ); else enlargeData( 0, nNewRowCount ); } vector< vector< uno::Any > > InternalData::getComplexRowLabels() const { return m_aRowLabels; } void InternalData::setComplexColumnLabels( const vector< vector< uno::Any > >& rNewColumnLabels ) { m_aColumnLabels = rNewColumnLabels; sal_Int32 nNewColumnCount = static_cast< sal_Int32 >( m_aColumnLabels.size() ); if( nNewColumnCount < m_nColumnCount ) m_aColumnLabels.resize( m_nColumnCount ); else enlargeData( nNewColumnCount, 0 ); } vector< vector< uno::Any > > InternalData::getComplexColumnLabels() const { return m_aColumnLabels; } #if OSL_DEBUG_LEVEL > 2 void InternalData::traceData() const { OSL_TRACE( "InternalData: Data in rows\n" ); for( sal_Int32 i=0; i