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 // header for class SvNumberformat 28 #ifndef _ZFORMAT_HXX 29 #ifndef _ZFORLIST_DECLARE_TABLE 30 #define _ZFORLIST_DECLARE_TABLE 31 #endif 32 #include <svl/zformat.hxx> 33 #endif 34 // header for SvNumberFormatter 35 #include <svl/zforlist.hxx> 36 37 #include "DataBrowser.hxx" 38 #include "DataBrowserModel.hxx" 39 #include "Strings.hrc" 40 #include "ContainerHelper.hxx" 41 #include "DataSeriesHelper.hxx" 42 #include "DiagramHelper.hxx" 43 #include "ChartModelHelper.hxx" 44 #include "CommonConverters.hxx" 45 #include "macros.hxx" 46 #include "NumberFormatterWrapper.hxx" 47 #include "servicenames_charttypes.hxx" 48 #include "ResId.hxx" 49 #include "Bitmaps.hrc" 50 #include "Bitmaps_HC.hrc" 51 #include "HelpIds.hrc" 52 53 #include <vcl/fixed.hxx> 54 #include <vcl/image.hxx> 55 #include <vcl/msgbox.hxx> 56 #include <rtl/math.hxx> 57 58 #include <com/sun/star/util/XCloneable.hpp> 59 #include <com/sun/star/chart2/XChartDocument.hpp> 60 #include <com/sun/star/chart2/XChartType.hpp> 61 62 #include <com/sun/star/container/XIndexReplace.hpp> 63 #include <com/sun/star/util/XNumberFormats.hpp> 64 65 #include <algorithm> 66 #include <functional> 67 68 #define SELECT_IMAGE(name,hc) Image( SchResId( hc ? name ## _HC : name )) 69 70 /* BROWSER_COLUMNSELECTION : single cells may be selected rather than only 71 entire rows 72 BROWSER_(H|V)LINES : show horizontal or vertical grid-lines 73 74 BROWSER_AUTO_(H|V)SCROLL : scroll automated horizontally or vertically when 75 cursor is moved beyond the edge of the dialog 76 BROWSER_HIGHLIGHT_NONE : Do not mark the current row with selection color 77 (usually blue) 78 79 */ 80 #define BROWSER_STANDARD_FLAGS \ 81 BROWSER_COLUMNSELECTION | \ 82 BROWSER_HLINES | BROWSER_VLINES | \ 83 BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL | \ 84 BROWSER_HIGHLIGHT_NONE 85 86 // BROWSER_HIDECURSOR would prevent flickering in edit fields, but navigating 87 // with shift up/down, and entering non-editable cells would be problematic, 88 // e.g. the first cell, or when being in read-only mode 89 90 91 using namespace ::com::sun::star; 92 using ::com::sun::star::uno::Sequence; 93 using ::com::sun::star::uno::Reference; 94 using ::rtl::OUString; 95 96 using namespace ::svt; 97 98 namespace 99 { 100 sal_Int32 lcl_getRowInData( long nRow ) 101 { 102 return static_cast< sal_Int32 >( nRow ); 103 } 104 105 sal_Int32 lcl_getColumnInData( sal_uInt16 nCol ) 106 { 107 return static_cast< sal_Int32 >( nCol ) - 1; 108 } 109 110 } // anonymous namespace 111 112 // -------------------------------------------------------------------------------- 113 114 namespace chart 115 { 116 117 // ---------------------------------------- 118 namespace impl 119 { 120 121 class SeriesHeaderEdit : public Edit 122 { 123 public: 124 SeriesHeaderEdit( Window * pParent ); 125 virtual ~SeriesHeaderEdit(); 126 virtual void MouseButtonDown( const MouseEvent& rMEvt ); 127 128 void setStartColumn( sal_Int32 nStartColumn ); 129 sal_Int32 getStartColumn() const; 130 void SetShowWarningBox( bool bShowWarning = true ); 131 132 private: 133 sal_Int32 m_nStartColumn; 134 bool m_bShowWarningBox; 135 }; 136 137 SeriesHeaderEdit::SeriesHeaderEdit( Window * pParent ) : 138 Edit( pParent ), 139 m_nStartColumn( 0 ), 140 m_bShowWarningBox( false ) 141 {} 142 SeriesHeaderEdit::~SeriesHeaderEdit() 143 {} 144 145 void SeriesHeaderEdit::setStartColumn( sal_Int32 nStartColumn ) 146 { 147 m_nStartColumn = nStartColumn; 148 } 149 150 sal_Int32 SeriesHeaderEdit::getStartColumn() const 151 { 152 return m_nStartColumn; 153 } 154 155 void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning ) 156 { 157 m_bShowWarningBox = bShowWarning; 158 } 159 160 void SeriesHeaderEdit::MouseButtonDown( const MouseEvent& rMEvt ) 161 { 162 Edit::MouseButtonDown( rMEvt ); 163 164 if( m_bShowWarningBox ) 165 WarningBox( this, WinBits( WB_OK ), 166 String( SchResId( STR_INVALID_NUMBER ))).Execute(); 167 } 168 169 class SeriesHeader 170 { 171 public: 172 explicit SeriesHeader( Window * pParent ); 173 174 void SetColor( const Color & rCol ); 175 void SetPos( const Point & rPos ); 176 void SetWidth( sal_Int32 nWidth ); 177 void SetChartType( const Reference< chart2::XChartType > & xChartType, 178 bool bSwapXAndYAxis, 179 bool bIsHighContrast ); 180 void SetSeriesName( const String & rName ); 181 void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol ); 182 183 void SetPixelPosX( sal_Int32 nPos ); 184 void SetPixelWidth( sal_Int32 nWidth ); 185 186 sal_Int32 GetStartColumn() const; 187 sal_Int32 GetEndColumn() const; 188 189 static sal_Int32 GetRelativeAppFontXPosForNameField(); 190 191 void Show(); 192 193 /** call this before destroying the class. This notifies the listeners to 194 changes of the edit field for the series name. 195 */ 196 void applyChanges(); 197 198 void SetGetFocusHdl( const Link& rLink ); 199 200 void SetEditChangedHdl( const Link & rLink ); 201 202 bool HasFocus() const; 203 204 private: 205 ::boost::shared_ptr< FixedImage > m_spSymbol; 206 ::boost::shared_ptr< SeriesHeaderEdit > m_spSeriesName; 207 ::boost::shared_ptr< FixedText > m_spColorBar; 208 OutputDevice * m_pDevice; 209 Link m_aChangeLink; 210 211 void notifyChanges(); 212 DECL_LINK( SeriesNameChanged, void * ); 213 DECL_LINK( SeriesNameEdited, void * ); 214 215 /// @param bHC </sal_True> for hight-contrast image 216 static Image GetChartTypeImage( 217 const Reference< chart2::XChartType > & xChartType, 218 bool bSwapXAndYAxis, 219 bool bHC ); 220 221 sal_Int32 m_nStartCol, m_nEndCol; 222 sal_Int32 m_nWidth; 223 Point m_aPos; 224 bool m_bSeriesNameChangePending; 225 }; 226 227 SeriesHeader::SeriesHeader( Window * pParent ) : 228 m_spSymbol( new FixedImage( pParent, WB_NOBORDER )), 229 m_spSeriesName( new SeriesHeaderEdit( pParent )), 230 m_spColorBar( new FixedText( pParent, WB_NOBORDER )), 231 m_pDevice( pParent ), 232 m_nStartCol( 0 ), 233 m_nEndCol( 0 ), 234 m_nWidth( 42 ), 235 m_aPos( 0, 22 ), 236 m_bSeriesNameChangePending( false ) 237 { 238 m_spSeriesName->EnableUpdateData( 4 * EDIT_UPDATEDATA_TIMEOUT ); // define is in vcl/edit.hxx 239 m_spSeriesName->SetUpdateDataHdl( LINK( this, SeriesHeader, SeriesNameChanged )); 240 m_spSeriesName->SetModifyHdl( LINK( this, SeriesHeader, SeriesNameEdited )); 241 m_spSeriesName->SetHelpId( HID_SCH_DATA_SERIES_LABEL ); 242 Show(); 243 } 244 245 void SeriesHeader::notifyChanges() 246 { 247 if( m_aChangeLink.IsSet()) 248 m_aChangeLink.Call( m_spSeriesName.get()); 249 250 m_bSeriesNameChangePending = false; 251 } 252 253 void SeriesHeader::applyChanges() 254 { 255 if( m_bSeriesNameChangePending ) 256 { 257 notifyChanges(); 258 } 259 } 260 261 void SeriesHeader::SetColor( const Color & rCol ) 262 { 263 m_spColorBar->SetControlBackground( rCol ); 264 } 265 266 const sal_Int32 nSymbolHeight = 10; 267 const sal_Int32 nSymbolDistance = 2; 268 269 sal_Int32 SeriesHeader::GetRelativeAppFontXPosForNameField() 270 { 271 return nSymbolHeight + nSymbolDistance; 272 } 273 274 void SeriesHeader::SetPos( const Point & rPos ) 275 { 276 m_aPos = rPos; 277 278 // chart type symbol 279 Point aPos( rPos ); 280 aPos.setY( aPos.getY() + nSymbolDistance ); 281 Size aSize( nSymbolHeight, nSymbolHeight ); 282 m_spSymbol->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); 283 m_spSymbol->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); 284 aPos.setY( aPos.getY() - nSymbolDistance ); 285 286 // series name edit field 287 aPos.setX( aPos.getX() + nSymbolHeight + nSymbolDistance ); 288 aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance ); 289 sal_Int32 nHeight = 12; 290 aSize.setHeight( nHeight ); 291 m_spSeriesName->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); 292 m_spSeriesName->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); 293 294 // color bar 295 aPos.setX( rPos.getX() + 1 ); 296 aPos.setY( aPos.getY() + nHeight + 2 ); 297 nHeight = 3; 298 aSize.setWidth( m_nWidth - 1 ); 299 aSize.setHeight( nHeight ); 300 m_spColorBar->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); 301 m_spColorBar->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); 302 } 303 304 void SeriesHeader::SetWidth( sal_Int32 nWidth ) 305 { 306 m_nWidth = nWidth; 307 SetPos( m_aPos ); 308 } 309 310 311 void SeriesHeader::SetPixelPosX( sal_Int32 nPos ) 312 { 313 Point aPos( m_pDevice->LogicToPixel( m_aPos, MAP_APPFONT )); 314 aPos.setX( nPos ); 315 SetPos( m_pDevice->PixelToLogic( aPos, MAP_APPFONT )); 316 } 317 318 void SeriesHeader::SetPixelWidth( sal_Int32 nWidth ) 319 { 320 SetWidth( m_pDevice->PixelToLogic( Size( nWidth, 0 ), MAP_APPFONT ).getWidth()); 321 } 322 323 void SeriesHeader::SetChartType( 324 const Reference< chart2::XChartType > & xChartType, 325 bool bSwapXAndYAxis, 326 bool bIsHighContrast ) 327 { 328 m_spSymbol->SetImage( GetChartTypeImage( xChartType, bSwapXAndYAxis, bIsHighContrast )); 329 } 330 331 void SeriesHeader::SetSeriesName( const String & rName ) 332 { 333 m_spSeriesName->SetText( rName ); 334 } 335 336 void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol ) 337 { 338 m_nStartCol = nStartCol; 339 m_nEndCol = (nEndCol > nStartCol) ? nEndCol : nStartCol; 340 m_spSeriesName->setStartColumn( nStartCol ); 341 } 342 343 sal_Int32 SeriesHeader::GetStartColumn() const 344 { 345 return m_nStartCol; 346 } 347 348 sal_Int32 SeriesHeader::GetEndColumn() const 349 { 350 return m_nEndCol; 351 } 352 353 void SeriesHeader::Show() 354 { 355 m_spSymbol->Show(); 356 m_spSeriesName->Show(); 357 m_spColorBar->Show(); 358 } 359 360 void SeriesHeader::SetEditChangedHdl( const Link & rLink ) 361 { 362 m_aChangeLink = rLink; 363 } 364 365 IMPL_LINK( SeriesHeader, SeriesNameChanged, void * , EMPTYARG ) 366 { 367 notifyChanges(); 368 return 0; 369 } 370 371 IMPL_LINK( SeriesHeader, SeriesNameEdited, void * , EMPTYARG ) 372 { 373 m_bSeriesNameChangePending = true; 374 return 0; 375 } 376 377 void SeriesHeader::SetGetFocusHdl( const Link& rLink ) 378 { 379 m_spSeriesName->SetGetFocusHdl( rLink ); 380 } 381 382 bool SeriesHeader::HasFocus() const 383 { 384 return m_spSeriesName->HasFocus(); 385 } 386 387 Image SeriesHeader::GetChartTypeImage( 388 const Reference< chart2::XChartType > & xChartType, 389 bool bSwapXAndYAxis, 390 bool bHC ) 391 { 392 Image aResult; 393 if( !xChartType.is()) 394 return aResult; 395 OUString aChartTypeName( xChartType->getChartType()); 396 397 if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_AREA )) 398 { 399 aResult = SELECT_IMAGE( IMG_TYPE_AREA, bHC ); 400 } 401 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )) 402 { 403 if( bSwapXAndYAxis ) 404 aResult = SELECT_IMAGE( IMG_TYPE_BAR, bHC ); 405 else 406 aResult = SELECT_IMAGE( IMG_TYPE_COLUMN, bHC ); 407 } 408 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_LINE )) 409 { 410 aResult = SELECT_IMAGE( IMG_TYPE_LINE, bHC ); 411 } 412 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )) 413 { 414 aResult = SELECT_IMAGE( IMG_TYPE_XY, bHC ); 415 } 416 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_PIE )) 417 { 418 aResult = SELECT_IMAGE( IMG_TYPE_PIE, bHC ); 419 } 420 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_NET ) 421 || aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) ) 422 { 423 aResult = SELECT_IMAGE( IMG_TYPE_NET, bHC ); 424 } 425 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )) 426 { 427 // @todo: correct image for candle-stick type 428 aResult = SELECT_IMAGE( IMG_TYPE_STOCK, bHC ); 429 } 430 else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE )) 431 { 432 aResult = SELECT_IMAGE( IMG_TYPE_BUBBLE, bHC ); 433 } 434 435 return aResult; 436 } 437 438 struct applyChangesFunctor : public ::std::unary_function< ::boost::shared_ptr< SeriesHeader >, void > 439 { 440 void operator() ( ::boost::shared_ptr< SeriesHeader > spHeader ) 441 { 442 spHeader->applyChanges(); 443 } 444 }; 445 446 } // namespace impl 447 // ---------------------------------------- 448 449 namespace 450 { 451 452 /** returns false, if no header as the focus. 453 454 If a header has the focus, true is returned and the index of the header 455 with focus is set at pIndex if pOutIndex is not 0. 456 */ 457 bool lcl_SeriesHeaderHasFocus( 458 const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader, 459 sal_Int32 * pOutIndex = 0 ) 460 { 461 sal_Int32 nIndex = 0; 462 for( ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > >::const_iterator aIt( rSeriesHeader.begin()); 463 aIt != rSeriesHeader.end(); ++aIt, ++nIndex ) 464 { 465 if( (*aIt)->HasFocus()) 466 { 467 if( pOutIndex ) 468 *pOutIndex = nIndex; 469 return true; 470 } 471 } 472 return false; 473 } 474 475 sal_Int32 lcl_getColumnInDataOrHeader( 476 sal_uInt16 nCol, const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader ) 477 { 478 sal_Int32 nColIdx = 0; 479 bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx )); 480 481 if( bHeaderHasFocus ) 482 nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn())); 483 else 484 nColIdx = lcl_getColumnInData( nCol ); 485 486 return nColIdx; 487 } 488 489 } // anonymous namespace 490 491 492 DataBrowser::DataBrowser( Window* pParent, const ResId& rId, bool bLiveUpdate ) : 493 ::svt::EditBrowseBox( pParent, rId, EBBF_SMART_TAB_TRAVEL | EBBF_HANDLE_COLUMN_TEXT, BROWSER_STANDARD_FLAGS ), 494 m_nSeekRow( 0 ), 495 m_bIsReadOnly( false ), 496 m_bIsDirty( false ), 497 m_bLiveUpdate( bLiveUpdate ), 498 m_bDataValid( true ), 499 m_aNumberEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ), 500 m_aTextEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ), 501 m_rNumberEditController( new ::svt::FormattedFieldCellController( & m_aNumberEditField )), 502 m_rTextEditController( new ::svt::EditCellController( & m_aTextEditField )) 503 { 504 double fNan; 505 ::rtl::math::setNan( & fNan ); 506 m_aNumberEditField.SetDefaultValue( fNan ); 507 m_aNumberEditField.TreatAsNumber( sal_True ); 508 RenewTable(); 509 SetClean(); 510 } 511 512 DataBrowser::~DataBrowser() 513 { 514 } 515 516 bool DataBrowser::MayInsertRow() const 517 { 518 return ! IsReadOnly() 519 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )); 520 } 521 522 bool DataBrowser::MayInsertColumn() const 523 { 524 return ! IsReadOnly(); 525 } 526 527 bool DataBrowser::MayDeleteRow() const 528 { 529 return ! IsReadOnly() 530 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) 531 && ( GetCurRow() >= 0 ) 532 && ( GetRowCount() > 1 ); 533 } 534 535 bool DataBrowser::MayDeleteColumn() const 536 { 537 // if a series header has the focus 538 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) 539 return true; 540 541 return ! IsReadOnly() 542 && ( GetCurColumnId() > 1 ) 543 && ( ColCount() > 2 ); 544 } 545 546 bool DataBrowser::MaySwapRows() const 547 { 548 return ! IsReadOnly() 549 && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) 550 && ( GetCurRow() >= 0 ) 551 && ( GetCurRow() < GetRowCount() - 1 ); 552 } 553 554 bool DataBrowser::MaySwapColumns() const 555 { 556 // if a series header (except the last one) has the focus 557 { 558 sal_Int32 nColIndex(0); 559 if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex )) 560 return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1)); 561 } 562 563 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); 564 return ! IsReadOnly() 565 && ( nColIdx > 0 ) 566 && ( nColIdx < ColCount()-2 ) 567 && m_apDataBrowserModel.get() 568 && !m_apDataBrowserModel->isCategoriesColumn( nColIdx ); 569 } 570 571 void DataBrowser::clearHeaders() 572 { 573 ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor()); 574 m_aSeriesHeaders.clear(); 575 } 576 577 void DataBrowser::RenewTable() 578 { 579 if( ! m_apDataBrowserModel.get()) 580 return; 581 582 long nOldRow = GetCurRow(); 583 sal_uInt16 nOldColId = GetCurColumnId(); 584 585 sal_Bool bLastUpdateMode = GetUpdateMode(); 586 SetUpdateMode( sal_False ); 587 588 if( IsModified() ) 589 SaveModified(); 590 591 DeactivateCell(); 592 593 RemoveColumns(); 594 RowRemoved( 1, GetRowCount() ); 595 596 // for row numbers 597 InsertHandleColumn( static_cast< sal_uInt16 >( 598 GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() )); 599 600 OUString aDefaultSeriesName( ::chart::SchResId::getResString( STR_COLUMN_LABEL )); 601 replaceParamterInString( aDefaultSeriesName, C2U("%COLUMNNUMBER"), OUString::valueOf( sal_Int32(24) ) ); 602 sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName ) 603 + GetDataWindow().LogicToPixel( Point( 4 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0 ), MAP_APPFONT ).X(); 604 sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount(); 605 // nRowCount is a member of a base class 606 sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount(); 607 for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx ) 608 { 609 InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth ); 610 } 611 612 RowInserted( 1, nRowCountLocal ); 613 GoToRow( ::std::min( nOldRow, GetRowCount() - 1 )); 614 GoToColumnId( ::std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 ))); 615 616 Window * pWin = this->GetParent(); 617 if( !pWin ) 618 pWin = this; 619 620 // fill series headers 621 clearHeaders(); 622 const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders()); 623 Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus )); 624 Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged )); 625 bool bIsHighContrast = pWin ? (pWin->GetSettings().GetStyleSettings().GetHighContrastMode()) : false; 626 627 for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin()); 628 aIt != aHeaders.end(); ++aIt ) 629 { 630 ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin )); 631 Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY ); 632 sal_Int32 nColor = 0; 633 // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc. 634 if( xSeriesProp.is() && 635 ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor )) 636 spHeader->SetColor( Color( nColor )); 637 spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis, bIsHighContrast ); 638 spHeader->SetSeriesName( 639 String( DataSeriesHelper::getDataSeriesLabel( 640 aIt->m_xDataSeries, 641 (aIt->m_xChartType.is() ? 642 aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() : 643 OUString( RTL_CONSTASCII_USTRINGPARAM("values-y")))))); 644 // index is 1-based, as 0 is for the column that contains the row-numbers 645 spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 ); 646 spHeader->SetGetFocusHdl( aFocusLink ); 647 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink ); 648 m_aSeriesHeaders.push_back( spHeader ); 649 } 650 651 ImplAdjustHeaderControls(); 652 SetDirty(); 653 SetUpdateMode( bLastUpdateMode ); 654 ActivateCell(); 655 Invalidate(); 656 } 657 658 String DataBrowser::GetColString( sal_Int32 nColumnId ) const 659 { 660 OSL_ASSERT( m_apDataBrowserModel.get()); 661 if( nColumnId > 0 ) 662 return String( m_apDataBrowserModel->getRoleOfColumn( static_cast< sal_Int32 >( nColumnId ) - 1 )); 663 return String(); 664 } 665 666 String DataBrowser::GetRowString( sal_Int32 nRow ) const 667 { 668 return String::CreateFromInt32( nRow + 1 ); 669 } 670 671 String DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const 672 { 673 String aResult; 674 675 if( nColumnId == 0 ) 676 { 677 aResult = GetRowString( static_cast< sal_Int32 >( nRow )); 678 } 679 else if( nRow >= 0 && 680 m_apDataBrowserModel.get()) 681 { 682 sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1; 683 684 if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::NUMBER ) 685 { 686 double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow )); 687 sal_Int32 nLabelColor; 688 bool bColorChanged = false; 689 690 if( ! ::rtl::math::isNan( fData ) && 691 m_spNumberFormatterWrapper.get() ) 692 aResult = String( m_spNumberFormatterWrapper->getFormattedString( 693 GetNumberFormatKey( nRow, nColumnId ), 694 fData, nLabelColor, bColorChanged )); 695 } 696 else if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXTORDATE ) 697 { 698 uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow ); 699 OUString aText; 700 double fDouble=0.0; 701 if( aAny>>=aText ) 702 aResult = aText; 703 else if( aAny>>=fDouble ) 704 { 705 sal_Int32 nLabelColor; 706 bool bColorChanged = false; 707 sal_Int32 nDateNumberFormat = DiagramHelper::getDateNumberFormat( Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY) ); 708 if( ! ::rtl::math::isNan( fDouble ) && m_spNumberFormatterWrapper.get() ) 709 aResult = String( m_spNumberFormatterWrapper->getFormattedString( 710 nDateNumberFormat, fDouble, nLabelColor, bColorChanged )); 711 } 712 } 713 else 714 { 715 OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXT ); 716 aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow ); 717 } 718 } 719 720 return aResult; 721 } 722 723 double DataBrowser::GetCellNumber( long nRow, sal_uInt16 nColumnId ) const 724 { 725 double fResult; 726 ::rtl::math::setNan( & fResult ); 727 728 if(( nColumnId >= 1 ) && ( nRow >= 0 ) && 729 m_apDataBrowserModel.get()) 730 { 731 fResult = m_apDataBrowserModel->getCellNumber( 732 static_cast< sal_Int32 >( nColumnId ) - 1, nRow ); 733 } 734 735 return fResult; 736 } 737 738 void DataBrowser::Resize() 739 { 740 sal_Bool bLastUpdateMode = GetUpdateMode(); 741 SetUpdateMode( sal_False ); 742 743 ::svt::EditBrowseBox::Resize(); 744 ImplAdjustHeaderControls(); 745 SetUpdateMode( bLastUpdateMode ); 746 } 747 748 bool DataBrowser::SetReadOnly( bool bNewState ) 749 { 750 bool bResult = m_bIsReadOnly; 751 752 if( m_bIsReadOnly != bNewState ) 753 { 754 m_bIsReadOnly = bNewState; 755 Invalidate(); 756 DeactivateCell(); 757 } 758 759 return bResult; 760 } 761 762 bool DataBrowser::IsReadOnly() const 763 { 764 return m_bIsReadOnly; 765 } 766 767 768 void DataBrowser::SetClean() 769 { 770 m_bIsDirty = false; 771 } 772 773 void DataBrowser::SetDirty() 774 { 775 if( !m_bLiveUpdate ) 776 m_bIsDirty = true; 777 } 778 779 void DataBrowser::CursorMoved() 780 { 781 EditBrowseBox::CursorMoved(); 782 783 if( GetUpdateMode() && m_aCursorMovedHdlLink.IsSet()) 784 m_aCursorMovedHdlLink.Call( this ); 785 } 786 787 void DataBrowser::SetCellModifiedHdl( const Link& rLink ) 788 { 789 m_aCellModifiedLink = rLink; 790 } 791 792 void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt ) 793 { 794 if( !m_bDataValid ) 795 ShowWarningBox(); 796 else 797 EditBrowseBox::MouseButtonDown( rEvt ); 798 } 799 800 void DataBrowser::ShowWarningBox() 801 { 802 WarningBox( this, WinBits( WB_OK ), 803 String( SchResId( STR_INVALID_NUMBER ))).Execute(); 804 } 805 806 bool DataBrowser::ShowQueryBox() 807 { 808 QueryBox* pQueryBox = new QueryBox( this, WB_YES_NO, String( SchResId( STR_DATA_EDITOR_INCORRECT_INPUT ))); 809 810 return ( pQueryBox->Execute() == RET_YES ); 811 } 812 813 bool DataBrowser::IsDataValid() 814 { 815 bool bValid = true; 816 const sal_Int32 nRow = lcl_getRowInData( GetCurRow()); 817 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId()); 818 819 if( m_apDataBrowserModel->getCellType( nCol, nRow ) == DataBrowserModel::NUMBER ) 820 { 821 sal_uInt32 nDummy = 0; 822 double fDummy = 0.0; 823 String aText( m_aNumberEditField.GetText()); 824 825 if( aText.Len() > 0 && 826 m_spNumberFormatterWrapper.get() && 827 m_spNumberFormatterWrapper->getSvNumberFormatter() && 828 ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat( 829 aText, nDummy, fDummy )) 830 { 831 bValid = false; 832 } 833 } 834 835 return bValid; 836 } 837 838 bool DataBrowser::IsEnableItem() 839 { 840 return m_bDataValid; 841 } 842 843 void DataBrowser::CellModified() 844 { 845 m_bDataValid = IsDataValid(); 846 SetDirty(); 847 if( m_aCellModifiedLink.IsSet()) 848 m_aCursorMovedHdlLink.Call( this ); 849 } 850 851 void DataBrowser::SetDataFromModel( 852 const Reference< chart2::XChartDocument > & xChartDoc, 853 const Reference< uno::XComponentContext > & xContext ) 854 { 855 if( m_bLiveUpdate ) 856 { 857 m_xChartDoc.set( xChartDoc ); 858 } 859 else 860 { 861 Reference< util::XCloneable > xCloneable( xChartDoc, uno::UNO_QUERY ); 862 if( xCloneable.is()) 863 m_xChartDoc.set( xCloneable->createClone(), uno::UNO_QUERY ); 864 } 865 866 m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext )); 867 m_spNumberFormatterWrapper.reset( 868 new NumberFormatterWrapper( 869 Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ))); 870 871 if( m_spNumberFormatterWrapper.get() ) 872 m_aNumberEditField.SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() ); 873 874 RenewTable(); 875 876 const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount(); 877 const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount(); 878 if( nRowCnt && nColCnt ) 879 { 880 GoToRow( 0 ); 881 GoToColumnId( 1 ); 882 } 883 SetClean(); 884 } 885 886 void DataBrowser::InsertColumn() 887 { 888 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); 889 890 if( nColIdx >= 0 && 891 m_apDataBrowserModel.get()) 892 { 893 // save changes made to edit-field 894 if( IsModified() ) 895 SaveModified(); 896 897 m_apDataBrowserModel->insertDataSeries( nColIdx ); 898 RenewTable(); 899 } 900 } 901 902 void DataBrowser::InsertTextColumn() 903 { 904 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); 905 906 if( nColIdx >= 0 && 907 m_apDataBrowserModel.get()) 908 { 909 // save changes made to edit-field 910 if( IsModified() ) 911 SaveModified(); 912 913 m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx ); 914 RenewTable(); 915 } 916 } 917 918 void DataBrowser::RemoveColumn() 919 { 920 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); 921 922 if( nColIdx >= 0 && 923 m_apDataBrowserModel.get()) 924 { 925 // save changes made to edit-field 926 if( IsModified() ) 927 SaveModified(); 928 929 m_bDataValid = true; 930 m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx ); 931 RenewTable(); 932 } 933 } 934 935 void DataBrowser::InsertRow() 936 { 937 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); 938 939 if( nRowIdx >= 0 && 940 m_apDataBrowserModel.get()) 941 { 942 // save changes made to edit-field 943 if( IsModified() ) 944 SaveModified(); 945 946 m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx ); 947 RenewTable(); 948 } 949 } 950 951 void DataBrowser::RemoveRow() 952 { 953 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); 954 955 if( nRowIdx >= 0 && 956 m_apDataBrowserModel.get()) 957 { 958 // save changes made to edit-field 959 if( IsModified() ) 960 SaveModified(); 961 962 m_bDataValid = true; 963 m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx ); 964 RenewTable(); 965 } 966 } 967 968 void DataBrowser::SwapColumn() 969 { 970 sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); 971 972 if( nColIdx >= 0 && 973 m_apDataBrowserModel.get()) 974 { 975 // save changes made to edit-field 976 if( IsModified() ) 977 SaveModified(); 978 979 m_apDataBrowserModel->swapDataSeries( nColIdx ); 980 981 // keep cursor in swapped column 982 if( GetCurColumnId() < ColCount() - 1 ) 983 { 984 Dispatch( BROWSER_CURSORRIGHT ); 985 } 986 RenewTable(); 987 } 988 } 989 990 void DataBrowser::SwapRow() 991 { 992 sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); 993 994 if( nRowIdx >= 0 && 995 m_apDataBrowserModel.get()) 996 { 997 // save changes made to edit-field 998 if( IsModified() ) 999 SaveModified(); 1000 1001 m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx ); 1002 1003 // keep cursor in swapped row 1004 if( GetCurRow() < GetRowCount() - 1 ) 1005 { 1006 Dispatch( BROWSER_CURSORDOWN ); 1007 } 1008 RenewTable(); 1009 } 1010 } 1011 1012 void DataBrowser::SetCursorMovedHdl( const Link& rLink ) 1013 { 1014 m_aCursorMovedHdlLink = rLink; 1015 } 1016 1017 // implementations for ::svt::EditBrowseBox (pure virtual methods) 1018 void DataBrowser::PaintCell( 1019 OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const 1020 { 1021 Point aPos( rRect.TopLeft()); 1022 aPos.X() += 1; 1023 1024 String aText = GetCellText( m_nSeekRow, nColumnId ); 1025 Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight()); 1026 1027 // clipping 1028 if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() || 1029 aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom()) 1030 rDev.SetClipRegion( rRect ); 1031 1032 // allow for a disabled control ... 1033 sal_Bool bEnabled = IsEnabled(); 1034 Color aOriginalColor = rDev.GetTextColor(); 1035 if( ! bEnabled ) 1036 rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() ); 1037 1038 // TEST 1039 // if( nColumnId == 1 ) 1040 // // categories 1041 // rDev.SetFillColor( Color( 0xff, 0xff, 0xff )); 1042 // else if( nColumnId == 2 ) 1043 // // x-values 1044 // rDev.SetFillColor( Color( 0xf0, 0xf0, 0xff )); 1045 // else 1046 // // y-values 1047 // rDev.SetFillColor( Color( 0xff, 0xff, 0xf0 )); 1048 1049 // rDev.DrawRect( rRect ); 1050 1051 // draw the text 1052 rDev.DrawText( aPos, aText ); 1053 1054 // reset the color (if necessary) 1055 if( ! bEnabled ) 1056 rDev.SetTextColor( aOriginalColor ); 1057 1058 if( rDev.IsClipRegion()) 1059 rDev.SetClipRegion(); 1060 } 1061 1062 sal_Bool DataBrowser::SeekRow( long nRow ) 1063 { 1064 if( ! EditBrowseBox::SeekRow( nRow )) 1065 return sal_False; 1066 1067 if( nRow < 0 ) 1068 m_nSeekRow = - 1; 1069 else 1070 m_nSeekRow = nRow; 1071 1072 return sal_True; 1073 } 1074 1075 sal_Bool DataBrowser::IsTabAllowed( sal_Bool bForward ) const 1076 { 1077 long nRow = GetCurRow(); 1078 long nCol = GetCurColumnId(); 1079 1080 // column 0 is header-column 1081 long nBadCol = bForward 1082 ? GetColumnCount() - 1 1083 : 1; 1084 long nBadRow = bForward 1085 ? GetRowCount() - 1 1086 : 0; 1087 1088 if( !m_bDataValid ) 1089 { 1090 const_cast< DataBrowser* >( this )->ShowWarningBox(); 1091 return sal_False; 1092 } 1093 1094 return ( nRow != nBadRow || 1095 nCol != nBadCol ); 1096 } 1097 1098 ::svt::CellController* DataBrowser::GetController( long nRow, sal_uInt16 nCol ) 1099 { 1100 if( m_bIsReadOnly ) 1101 return 0; 1102 1103 if( CellContainsNumbers( nRow, nCol )) 1104 { 1105 m_aNumberEditField.UseInputStringForFormatting(); 1106 m_aNumberEditField.SetFormatKey( GetNumberFormatKey( nRow, nCol )); 1107 return m_rNumberEditController; 1108 } 1109 1110 return m_rTextEditController; 1111 } 1112 1113 void DataBrowser::InitController( 1114 ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) 1115 { 1116 if( rController == m_rTextEditController ) 1117 { 1118 String aText( GetCellText( nRow, nCol ) ); 1119 m_aTextEditField.SetText( aText ); 1120 m_aTextEditField.SetSelection( Selection( 0, aText.Len() )); 1121 } 1122 else if( rController == m_rNumberEditController ) 1123 { 1124 // treat invalid and empty text as Nan 1125 m_aNumberEditField.EnableNotANumber( true ); 1126 if( ::rtl::math::isNan( GetCellNumber( nRow, nCol ))) 1127 m_aNumberEditField.SetTextValue( String()); 1128 else 1129 m_aNumberEditField.SetValue( GetCellNumber( nRow, nCol ) ); 1130 String aText( m_aNumberEditField.GetText()); 1131 m_aNumberEditField.SetSelection( Selection( 0, aText.Len())); 1132 } 1133 else 1134 { 1135 DBG_ERROR( "Invalid Controller" ); 1136 } 1137 } 1138 1139 bool DataBrowser::CellContainsNumbers( sal_Int32 nRow, sal_uInt16 nCol ) const 1140 { 1141 if( ! m_apDataBrowserModel.get()) 1142 return false; 1143 return (m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )) == 1144 DataBrowserModel::NUMBER); 1145 } 1146 1147 sal_uInt32 DataBrowser::GetNumberFormatKey( sal_Int32 nRow, sal_uInt16 nCol ) const 1148 { 1149 if( ! m_apDataBrowserModel.get()) 1150 return 0; 1151 return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )); 1152 } 1153 1154 bool DataBrowser::isDateString( rtl::OUString aInputString, double& fOutDateValue ) 1155 { 1156 sal_uInt32 nNumberFormat=0; 1157 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0; 1158 if( aInputString.getLength() > 0 && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateValue ) ) 1159 { 1160 Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_xChartDoc, uno::UNO_QUERY ); 1161 Reference< util::XNumberFormats > xNumberFormats; 1162 if( xNumberFormatsSupplier.is() ) 1163 xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); 1164 if( DiagramHelper::isDateNumberFormat( nNumberFormat, xNumberFormats ) ) 1165 return true; 1166 } 1167 return false; 1168 } 1169 1170 sal_Bool DataBrowser::SaveModified() 1171 { 1172 if( ! IsModified() ) 1173 return sal_True; 1174 1175 sal_Bool bChangeValid = sal_True; 1176 1177 const sal_Int32 nRow = lcl_getRowInData( GetCurRow()); 1178 const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId()); 1179 1180 DBG_ASSERT( nRow >= 0 || nCol >= 0, "This cell should not be modified!" ); 1181 1182 SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0; 1183 switch( m_apDataBrowserModel->getCellType( nCol, nRow )) 1184 { 1185 case DataBrowserModel::NUMBER: 1186 { 1187 sal_uInt32 nDummy = 0; 1188 double fDummy = 0.0; 1189 String aText( m_aNumberEditField.GetText()); 1190 // an empty string is valid, if no numberformatter exists, all 1191 // values are treated as valid 1192 if( aText.Len() > 0 && pSvNumberFormatter && 1193 ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) ) 1194 { 1195 bChangeValid = sal_False; 1196 } 1197 else 1198 { 1199 double fData = m_aNumberEditField.GetValue(); 1200 bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData ); 1201 } 1202 } 1203 break; 1204 case DataBrowserModel::TEXTORDATE: 1205 { 1206 OUString aText( m_aTextEditField.GetText() ); 1207 double fDateValue=0.0; 1208 bChangeValid = sal_False; 1209 if( isDateString( aText, fDateValue ) ) 1210 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( fDateValue ) ); 1211 if(!bChangeValid) 1212 bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( aText ) ); 1213 } 1214 break; 1215 case DataBrowserModel::TEXT: 1216 { 1217 OUString aText( m_aTextEditField.GetText()); 1218 bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText ); 1219 } 1220 break; 1221 } 1222 1223 // the first valid change changes this to true 1224 if( bChangeValid ) 1225 { 1226 RowModified( GetCurRow(), GetCurColumnId()); 1227 ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId()); 1228 if( pCtrl ) 1229 pCtrl->ClearModified(); 1230 SetDirty(); 1231 } 1232 1233 return bChangeValid; 1234 } 1235 1236 bool DataBrowser::EndEditing() 1237 { 1238 if( IsModified()) 1239 SaveModified(); 1240 1241 // apply changes made to series headers 1242 ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor()); 1243 1244 if( m_bDataValid ) 1245 return true; 1246 else 1247 return ShowQueryBox(); 1248 } 1249 1250 sal_Int16 DataBrowser::GetFirstVisibleColumNumber() const 1251 { 1252 return GetFirstVisibleColNumber(); 1253 } 1254 1255 void DataBrowser::ColumnResized( sal_uInt16 nColId ) 1256 { 1257 sal_Bool bLastUpdateMode = GetUpdateMode(); 1258 SetUpdateMode( sal_False ); 1259 1260 EditBrowseBox::ColumnResized( nColId ); 1261 ImplAdjustHeaderControls(); 1262 SetUpdateMode( bLastUpdateMode ); 1263 } 1264 1265 // virtual void MouseMove( const MouseEvent& rEvt ); 1266 1267 void DataBrowser::EndScroll() 1268 { 1269 sal_Bool bLastUpdateMode = GetUpdateMode(); 1270 SetUpdateMode( sal_False ); 1271 1272 EditBrowseBox::EndScroll(); 1273 RenewSeriesHeaders(); 1274 1275 SetUpdateMode( bLastUpdateMode ); 1276 } 1277 1278 void DataBrowser::RenewSeriesHeaders() 1279 { 1280 Window * pWin = this->GetParent(); 1281 if( !pWin ) 1282 pWin = this; 1283 1284 clearHeaders(); 1285 DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders()); 1286 Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus )); 1287 Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged )); 1288 bool bIsHighContrast = pWin ? (pWin->GetSettings().GetStyleSettings().GetHighContrastMode()) : false; 1289 1290 for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin()); 1291 aIt != aHeaders.end(); ++aIt ) 1292 { 1293 ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin )); 1294 Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY ); 1295 sal_Int32 nColor = 0; 1296 if( xSeriesProp.is() && 1297 ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor )) 1298 spHeader->SetColor( Color( nColor )); 1299 spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis, bIsHighContrast ); 1300 spHeader->SetSeriesName( 1301 String( DataSeriesHelper::getDataSeriesLabel( 1302 aIt->m_xDataSeries, 1303 (aIt->m_xChartType.is() ? 1304 aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() : 1305 OUString( RTL_CONSTASCII_USTRINGPARAM("values-y")))))); 1306 spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 ); 1307 spHeader->SetGetFocusHdl( aFocusLink ); 1308 spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink ); 1309 m_aSeriesHeaders.push_back( spHeader ); 1310 } 1311 1312 ImplAdjustHeaderControls(); 1313 } 1314 1315 void DataBrowser::ImplAdjustHeaderControls() 1316 { 1317 sal_uInt16 nColCount = this->GetColumnCount(); 1318 sal_uInt32 nCurrentPos = this->GetPosPixel().getX(); 1319 sal_uInt32 nMaxPos = nCurrentPos + this->GetOutputSizePixel().getWidth(); 1320 sal_uInt32 nStartPos = nCurrentPos; 1321 1322 // width of header column 1323 nCurrentPos += this->GetColumnWidth( 0 ); 1324 tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin()); 1325 sal_uInt16 i = this->GetFirstVisibleColumNumber(); 1326 while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) ) 1327 ++aIt; 1328 for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i ) 1329 { 1330 if( (*aIt)->GetStartColumn() == i ) 1331 nStartPos = nCurrentPos; 1332 1333 nCurrentPos += (this->GetColumnWidth( i )); 1334 1335 if( (*aIt)->GetEndColumn() == i ) 1336 { 1337 if( nStartPos < nMaxPos ) 1338 { 1339 (*aIt)->SetPixelPosX( nStartPos + 2 ); 1340 (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 ); 1341 } 1342 else 1343 // do not hide, to get focus events. Move outside the dialog for "hiding" 1344 (*aIt)->SetPixelPosX( nMaxPos + 42 ); 1345 ++aIt; 1346 } 1347 } 1348 } 1349 1350 IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit*, pEdit ) 1351 { 1352 if( pEdit ) 1353 { 1354 pEdit->SetShowWarningBox( !m_bDataValid ); 1355 1356 if( !m_bDataValid ) 1357 GoToCell( 0, 0 ); 1358 else 1359 { 1360 //DeactivateCell(); 1361 MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( pEdit->getStartColumn()), true /* bComplete */ ); 1362 ActivateCell(); 1363 m_aCursorMovedHdlLink.Call( this ); 1364 } 1365 } 1366 return 0; 1367 } 1368 1369 IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit*, pEdit ) 1370 { 1371 if( pEdit ) 1372 { 1373 Reference< chart2::XDataSeries > xSeries( 1374 m_apDataBrowserModel->getDataSeriesByColumn( pEdit->getStartColumn() - 1 )); 1375 Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); 1376 if( xSource.is()) 1377 { 1378 Reference< chart2::XChartType > xChartType( 1379 m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType ); 1380 if( xChartType.is()) 1381 { 1382 Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( 1383 DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel())); 1384 if( xLabeledSeq.is()) 1385 { 1386 Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY ); 1387 if( xIndexReplace.is()) 1388 xIndexReplace->replaceByIndex( 1389 0, uno::makeAny( OUString( pEdit->GetText()))); 1390 } 1391 } 1392 } 1393 } 1394 return 0; 1395 } 1396 1397 sal_Int32 DataBrowser::GetTotalWidth() const 1398 { 1399 sal_uLong nWidth = 0; 1400 for ( sal_uInt16 nCol = 0; nCol < ColCount(); ++nCol ) 1401 nWidth += GetColumnWidth( nCol ); 1402 return static_cast< sal_Int32 >( nWidth ); 1403 } 1404 1405 } // namespace chart 1406