1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_chart2.hxx" 26 27 #include "InternalData.hxx" 28 #include "ResId.hxx" 29 #include "Strings.hrc" 30 #include "macros.hxx" 31 32 #include <rtl/math.hxx> 33 #include <algorithm> 34 35 using ::com::sun::star::uno::Sequence; 36 using ::rtl::OUString; 37 38 using namespace ::com::sun::star; 39 using namespace ::std; 40 41 namespace chart 42 { 43 44 // ---------------------------------------- 45 namespace 46 { 47 struct lcl_NumberedStringGenerator 48 { 49 lcl_NumberedStringGenerator( const OUString & rStub, const OUString & rWildcard ) : 50 m_aStub( rStub ), 51 m_nCounter( 0 ), 52 m_nStubStartIndex( rStub.indexOf( rWildcard )), 53 m_nWildcardLength( rWildcard.getLength()) 54 { 55 } 56 vector< uno::Any > operator()() 57 { 58 vector< uno::Any > aRet(1); 59 aRet[0] = uno::makeAny( m_aStub.replaceAt( m_nStubStartIndex, m_nWildcardLength, OUString::valueOf( ++m_nCounter )) ); 60 return aRet; 61 } 62 private: 63 OUString m_aStub; 64 sal_Int32 m_nCounter; 65 const sal_Int32 m_nStubStartIndex; 66 const sal_Int32 m_nWildcardLength; 67 }; 68 69 template< typename T > 70 Sequence< T > lcl_ValarrayToSequence( const ::std::valarray< T > & rValarray ) 71 { 72 // is there a more elegant way of conversion? 73 Sequence< T > aResult( rValarray.size()); 74 for( size_t i = 0; i < rValarray.size(); ++i ) 75 aResult[i] = rValarray[i]; 76 return aResult; 77 } 78 79 } // anonymous namespace 80 // ---------------------------------------- 81 82 InternalData::InternalData() 83 : m_nColumnCount( 0 ) 84 , m_nRowCount( 0 ) 85 , m_aRowLabels( 0 ) 86 , m_aColumnLabels( 0 ) 87 {} 88 89 void InternalData::createDefaultData() 90 { 91 const sal_Int32 nRowCount = 4; 92 const sal_Int32 nColumnCount = 3; 93 94 m_nRowCount = nRowCount; 95 m_nColumnCount = nColumnCount; 96 const sal_Int32 nSize = nColumnCount * nRowCount; 97 // @todo: localize this! 98 const OUString aRowName( ::chart::SchResId::getResString( STR_ROW_LABEL )); 99 const OUString aColName( ::chart::SchResId::getResString( STR_COLUMN_LABEL )); 100 101 const double fDefaultData[ nSize ] = 102 { 9.10, 3.20, 4.54, 103 2.40, 8.80, 9.65, 104 3.10, 1.50, 3.70, 105 4.30, 9.02, 6.20 }; 106 107 m_aData.resize( nSize ); 108 for( sal_Int32 i=0; i<nSize; ++i ) 109 m_aData[i] = fDefaultData[i]; 110 111 m_aRowLabels.clear(); 112 m_aRowLabels.reserve( m_nRowCount ); 113 generate_n( back_inserter( m_aRowLabels ), m_nRowCount, 114 lcl_NumberedStringGenerator( aRowName, C2U("%ROWNUMBER") )); 115 116 m_aColumnLabels.clear(); 117 m_aColumnLabels.reserve( m_nColumnCount ); 118 generate_n( back_inserter( m_aColumnLabels ), m_nColumnCount, 119 lcl_NumberedStringGenerator( aColName, C2U("%COLUMNNUMBER") )); 120 } 121 122 void InternalData::setData( const Sequence< Sequence< double > >& rDataInRows ) 123 { 124 m_nRowCount = rDataInRows.getLength(); 125 m_nColumnCount = (m_nRowCount ? rDataInRows[0].getLength() : 0); 126 127 if( m_aRowLabels.size() != static_cast< sal_uInt32 >( m_nRowCount )) 128 m_aRowLabels.resize( m_nRowCount ); 129 if( m_aColumnLabels.size() != static_cast< sal_uInt32 >( m_nColumnCount )) 130 m_aColumnLabels.resize( m_nColumnCount ); 131 132 m_aData.resize( m_nRowCount * m_nColumnCount ); 133 double fNan; 134 ::rtl::math::setNan( & fNan ); 135 // set all values to Nan 136 m_aData = fNan; 137 138 for( sal_Int32 nRow=0; nRow<m_nRowCount; ++nRow ) 139 { 140 int nDataIdx = nRow*m_nColumnCount; 141 const sal_Int32 nMax = ::std::min( rDataInRows[nRow].getLength(), m_nColumnCount ); 142 for( sal_Int32 nCol=0; nCol < nMax; ++nCol ) 143 { 144 m_aData[nDataIdx] = rDataInRows[nRow][nCol]; 145 nDataIdx += 1; 146 } 147 } 148 } 149 150 Sequence< Sequence< double > > InternalData::getData() const 151 { 152 Sequence< Sequence< double > > aResult( m_nRowCount ); 153 154 for( sal_Int32 i=0; i<m_nRowCount; ++i ) 155 aResult[i] = lcl_ValarrayToSequence< tDataType::value_type >( 156 m_aData[ ::std::slice( i*m_nColumnCount, m_nColumnCount, 1 ) ] ); 157 158 return aResult; 159 } 160 161 Sequence< double > InternalData::getColumnValues( sal_Int32 nColumnIndex ) const 162 { 163 if( nColumnIndex >= 0 && nColumnIndex < m_nColumnCount ) 164 return lcl_ValarrayToSequence< tDataType::value_type >( 165 m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] ); 166 return Sequence< double >(); 167 } 168 Sequence< double > InternalData::getRowValues( sal_Int32 nRowIndex ) const 169 { 170 if( nRowIndex >= 0 && nRowIndex < m_nRowCount ) 171 return lcl_ValarrayToSequence< tDataType::value_type >( 172 m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ] ); 173 return Sequence< double >(); 174 } 175 176 void InternalData::setColumnValues( sal_Int32 nColumnIndex, const vector< double > & rNewData ) 177 { 178 if( nColumnIndex < 0 ) 179 return; 180 enlargeData( nColumnIndex + 1, rNewData.size() ); 181 182 tDataType aSlice = m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ]; 183 for( vector< double >::size_type i = 0; i < rNewData.size(); ++i ) 184 aSlice[i] = rNewData[i]; 185 m_aData[ ::std::slice( nColumnIndex, m_nRowCount, m_nColumnCount ) ] = aSlice; 186 } 187 188 void InternalData::setRowValues( sal_Int32 nRowIndex, const vector< double > & rNewData ) 189 { 190 if( nRowIndex < 0 ) 191 return; 192 enlargeData( rNewData.size(), nRowIndex+1 ); 193 194 tDataType aSlice = m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]; 195 for( vector< double >::size_type i = 0; i < rNewData.size(); ++i ) 196 aSlice[i] = rNewData[i]; 197 m_aData[ ::std::slice( nRowIndex*m_nColumnCount, m_nColumnCount, 1 ) ]= aSlice; 198 } 199 200 void InternalData::setComplexColumnLabel( sal_Int32 nColumnIndex, const vector< uno::Any >& rComplexLabel ) 201 { 202 if( nColumnIndex < 0 ) 203 return; 204 if( nColumnIndex >= static_cast< sal_Int32 >( m_aColumnLabels.size() ) ) 205 { 206 m_aColumnLabels.resize(nColumnIndex+1); 207 enlargeData( nColumnIndex+1, 0 ); 208 } 209 m_aColumnLabels[nColumnIndex]=rComplexLabel; 210 } 211 212 void InternalData::setComplexRowLabel( sal_Int32 nRowIndex, const vector< uno::Any >& rComplexLabel ) 213 { 214 if( nRowIndex < 0 ) 215 return; 216 if( nRowIndex >= static_cast< sal_Int32 >( m_aRowLabels.size() ) ) 217 { 218 m_aRowLabels.resize(nRowIndex+1); 219 enlargeData( 0, nRowIndex+1 ); 220 } 221 m_aRowLabels[nRowIndex] = rComplexLabel; 222 } 223 224 vector< uno::Any > InternalData::getComplexColumnLabel( sal_Int32 nColumnIndex ) const 225 { 226 if( nColumnIndex < static_cast< sal_Int32 >( m_aColumnLabels.size() ) ) 227 return m_aColumnLabels[nColumnIndex]; 228 else 229 return vector< uno::Any >(); 230 } 231 vector< uno::Any > InternalData::getComplexRowLabel( sal_Int32 nRowIndex ) const 232 { 233 if( nRowIndex < static_cast< sal_Int32 >( m_aRowLabels.size() ) ) 234 return m_aRowLabels[nRowIndex]; 235 else 236 return vector< uno::Any >(); 237 } 238 239 void InternalData::swapRowWithNext( sal_Int32 nRowIndex ) 240 { 241 if( nRowIndex < m_nRowCount - 1 ) 242 { 243 const sal_Int32 nMax = m_nColumnCount; 244 for( sal_Int32 nColIdx=0; nColIdx<nMax; ++nColIdx ) 245 { 246 size_t nIndex1 = nColIdx + nRowIndex*m_nColumnCount; 247 size_t nIndex2 = nIndex1 + m_nColumnCount; 248 double fTemp = m_aData[nIndex1]; 249 m_aData[nIndex1] = m_aData[nIndex2]; 250 m_aData[nIndex2] = fTemp; 251 } 252 253 vector< uno::Any > aTemp( m_aRowLabels[nRowIndex] ); 254 m_aRowLabels[nRowIndex] = m_aRowLabels[nRowIndex + 1]; 255 m_aRowLabels[nRowIndex + 1] = aTemp; 256 } 257 } 258 259 void InternalData::swapColumnWithNext( sal_Int32 nColumnIndex ) 260 { 261 if( nColumnIndex < m_nColumnCount - 1 ) 262 { 263 const sal_Int32 nMax = m_nRowCount; 264 for( sal_Int32 nRowIdx=0; nRowIdx<nMax; ++nRowIdx ) 265 { 266 size_t nIndex1 = nColumnIndex + nRowIdx*m_nColumnCount; 267 size_t nIndex2 = nIndex1 + 1; 268 double fTemp = m_aData[nIndex1]; 269 m_aData[nIndex1] = m_aData[nIndex2]; 270 m_aData[nIndex2] = fTemp; 271 } 272 273 vector< uno::Any > aTemp( m_aColumnLabels[nColumnIndex] ); 274 m_aColumnLabels[nColumnIndex] = m_aColumnLabels[nColumnIndex + 1]; 275 m_aColumnLabels[nColumnIndex + 1] = aTemp; 276 } 277 } 278 279 bool InternalData::enlargeData( sal_Int32 nColumnCount, sal_Int32 nRowCount ) 280 { 281 sal_Int32 nNewColumnCount( ::std::max<sal_Int32>( m_nColumnCount, nColumnCount ) ); 282 sal_Int32 nNewRowCount( ::std::max<sal_Int32>( m_nRowCount, nRowCount ) ); 283 sal_Int32 nNewSize( nNewColumnCount*nNewRowCount ); 284 285 bool bGrow = (nNewSize > m_nColumnCount*m_nRowCount); 286 287 if( bGrow ) 288 { 289 double fNan; 290 ::rtl::math::setNan( &fNan ); 291 tDataType aNewData( fNan, nNewSize ); 292 // copy old data 293 for( int nCol=0; nCol<m_nColumnCount; ++nCol ) 294 static_cast< tDataType >( 295 aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] ) = 296 m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ]; 297 298 m_aData.resize( nNewSize ); 299 m_aData = aNewData; 300 } 301 m_nColumnCount = nNewColumnCount; 302 m_nRowCount = nNewRowCount; 303 return bGrow; 304 } 305 306 void InternalData::insertColumn( sal_Int32 nAfterIndex ) 307 { 308 // note: -1 is allowed, as we insert after the given index 309 OSL_ASSERT( nAfterIndex < m_nColumnCount && nAfterIndex >= -1 ); 310 if( nAfterIndex >= m_nColumnCount || nAfterIndex < -1 ) 311 return; 312 sal_Int32 nNewColumnCount = m_nColumnCount + 1; 313 sal_Int32 nNewSize( nNewColumnCount * m_nRowCount ); 314 315 double fNan; 316 ::rtl::math::setNan( &fNan ); 317 tDataType aNewData( fNan, nNewSize ); 318 319 // copy old data 320 int nCol=0; 321 for( ; nCol<=nAfterIndex; ++nCol ) 322 aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] = 323 static_cast< tDataType >( 324 m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] ); 325 for( ++nCol; nCol<nNewColumnCount; ++nCol ) 326 aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] = 327 static_cast< tDataType >( 328 m_aData[ ::std::slice( nCol - 1, m_nRowCount, m_nColumnCount ) ] ); 329 330 m_nColumnCount = nNewColumnCount; 331 m_aData.resize( nNewSize ); 332 m_aData = aNewData; 333 334 // labels 335 if( nAfterIndex < static_cast< sal_Int32 >( m_aColumnLabels.size())) 336 m_aColumnLabels.insert( m_aColumnLabels.begin() + (nAfterIndex + 1), vector< uno::Any >(1) ); 337 338 #if OSL_DEBUG_LEVEL > 2 339 traceData(); 340 #endif 341 } 342 343 sal_Int32 InternalData::appendColumn() 344 { 345 insertColumn( getColumnCount() - 1 ); 346 return getColumnCount() - 1; 347 } 348 349 sal_Int32 InternalData::appendRow() 350 { 351 insertRow( getRowCount() - 1 ); 352 return getRowCount() - 1; 353 } 354 355 void InternalData::insertRow( sal_Int32 nAfterIndex ) 356 { 357 // note: -1 is allowed, as we insert after the given index 358 OSL_ASSERT( nAfterIndex < m_nRowCount && nAfterIndex >= -1 ); 359 if( nAfterIndex >= m_nRowCount || nAfterIndex < -1 ) 360 return; 361 sal_Int32 nNewRowCount = m_nRowCount + 1; 362 sal_Int32 nNewSize( m_nColumnCount * nNewRowCount ); 363 364 double fNan; 365 ::rtl::math::setNan( &fNan ); 366 tDataType aNewData( fNan, nNewSize ); 367 368 // copy old data 369 sal_Int32 nIndex = nAfterIndex + 1; 370 aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] = 371 static_cast< tDataType >( 372 m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] ); 373 374 if( nIndex < m_nRowCount ) 375 { 376 sal_Int32 nRemainingCount = m_nColumnCount * (m_nRowCount - nIndex); 377 aNewData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] = 378 static_cast< tDataType >( 379 m_aData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] ); 380 } 381 382 m_nRowCount = nNewRowCount; 383 m_aData.resize( nNewSize ); 384 m_aData = aNewData; 385 386 // labels 387 if( nAfterIndex < static_cast< sal_Int32 >( m_aRowLabels.size())) 388 m_aRowLabels.insert( m_aRowLabels.begin() + nIndex, vector< uno::Any > (1)); 389 390 #if OSL_DEBUG_LEVEL > 2 391 traceData(); 392 #endif 393 } 394 395 void InternalData::deleteColumn( sal_Int32 nAtIndex ) 396 { 397 OSL_ASSERT( nAtIndex < m_nColumnCount && nAtIndex >= 0 ); 398 if( nAtIndex >= m_nColumnCount || m_nColumnCount < 1 || nAtIndex < 0 ) 399 return; 400 sal_Int32 nNewColumnCount = m_nColumnCount - 1; 401 sal_Int32 nNewSize( nNewColumnCount * m_nRowCount ); 402 403 double fNan; 404 ::rtl::math::setNan( &fNan ); 405 tDataType aNewData( fNan, nNewSize ); 406 407 // copy old data 408 int nCol=0; 409 for( ; nCol<nAtIndex; ++nCol ) 410 aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] = 411 static_cast< tDataType >( 412 m_aData[ ::std::slice( nCol, m_nRowCount, m_nColumnCount ) ] ); 413 for( ; nCol<nNewColumnCount; ++nCol ) 414 aNewData[ ::std::slice( nCol, m_nRowCount, nNewColumnCount ) ] = 415 static_cast< tDataType >( 416 m_aData[ ::std::slice( nCol + 1, m_nRowCount, m_nColumnCount ) ] ); 417 418 m_nColumnCount = nNewColumnCount; 419 m_aData.resize( nNewSize ); 420 m_aData = aNewData; 421 422 // labels 423 if( nAtIndex < static_cast< sal_Int32 >( m_aColumnLabels.size())) 424 m_aColumnLabels.erase( m_aColumnLabels.begin() + nAtIndex ); 425 426 #if OSL_DEBUG_LEVEL > 2 427 traceData(); 428 #endif 429 } 430 431 void InternalData::deleteRow( sal_Int32 nAtIndex ) 432 { 433 OSL_ASSERT( nAtIndex < m_nRowCount && nAtIndex >= 0 ); 434 if( nAtIndex >= m_nRowCount || m_nRowCount < 1 || nAtIndex < 0 ) 435 return; 436 sal_Int32 nNewRowCount = m_nRowCount - 1; 437 sal_Int32 nNewSize( m_nColumnCount * nNewRowCount ); 438 439 double fNan; 440 ::rtl::math::setNan( &fNan ); 441 tDataType aNewData( fNan, nNewSize ); 442 443 // copy old data 444 sal_Int32 nIndex = nAtIndex; 445 if( nIndex ) 446 aNewData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] = 447 static_cast< tDataType >( 448 m_aData[ ::std::slice( 0, nIndex * m_nColumnCount, 1 ) ] ); 449 450 if( nIndex < nNewRowCount ) 451 { 452 sal_Int32 nRemainingCount = m_nColumnCount * (nNewRowCount - nIndex); 453 aNewData[ ::std::slice( nIndex * m_nColumnCount, nRemainingCount, 1 ) ] = 454 static_cast< tDataType >( 455 m_aData[ ::std::slice( (nIndex + 1) * m_nColumnCount, nRemainingCount, 1 ) ] ); 456 } 457 458 m_nRowCount = nNewRowCount; 459 m_aData.resize( nNewSize ); 460 m_aData = aNewData; 461 462 // labels 463 if( nAtIndex < static_cast< sal_Int32 >( m_aRowLabels.size())) 464 m_aRowLabels.erase( m_aRowLabels.begin() + nAtIndex ); 465 466 #if OSL_DEBUG_LEVEL > 2 467 traceData(); 468 #endif 469 } 470 471 sal_Int32 InternalData::getRowCount() const 472 { 473 return m_nRowCount; 474 } 475 476 sal_Int32 InternalData::getColumnCount() const 477 { 478 return m_nColumnCount; 479 } 480 481 void InternalData::setComplexRowLabels( const vector< vector< uno::Any > >& rNewRowLabels ) 482 { 483 m_aRowLabels = rNewRowLabels; 484 sal_Int32 nNewRowCount = static_cast< sal_Int32 >( m_aRowLabels.size() ); 485 if( nNewRowCount < m_nRowCount ) 486 m_aRowLabels.resize( m_nRowCount ); 487 else 488 enlargeData( 0, nNewRowCount ); 489 } 490 491 vector< vector< uno::Any > > InternalData::getComplexRowLabels() const 492 { 493 return m_aRowLabels; 494 } 495 496 void InternalData::setComplexColumnLabels( const vector< vector< uno::Any > >& rNewColumnLabels ) 497 { 498 m_aColumnLabels = rNewColumnLabels; 499 sal_Int32 nNewColumnCount = static_cast< sal_Int32 >( m_aColumnLabels.size() ); 500 if( nNewColumnCount < m_nColumnCount ) 501 m_aColumnLabels.resize( m_nColumnCount ); 502 else 503 enlargeData( nNewColumnCount, 0 ); 504 } 505 506 vector< vector< uno::Any > > InternalData::getComplexColumnLabels() const 507 { 508 return m_aColumnLabels; 509 } 510 511 #if OSL_DEBUG_LEVEL > 2 512 void InternalData::traceData() const 513 { 514 OSL_TRACE( "InternalData: Data in rows\n" ); 515 516 for( sal_Int32 i=0; i<m_nRowCount; ++i ) 517 { 518 tDataType aSlice( m_aData[ ::std::slice( i*m_nColumnCount, m_nColumnCount, 1 ) ] ); 519 for( sal_Int32 j=0; j<m_nColumnCount; ++j ) 520 OSL_TRACE( "%lf ", aSlice[j] ); 521 OSL_TRACE( "\n" ); 522 } 523 OSL_TRACE( "\n" ); 524 } 525 #endif 526 527 } // namespace chart 528