| /************************************************************** |
| * |
| * 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" |
| |
| // header for class SvNumberformat |
| #ifndef _ZFORMAT_HXX |
| #ifndef _ZFORLIST_DECLARE_TABLE |
| #define _ZFORLIST_DECLARE_TABLE |
| #endif |
| #include <svl/zformat.hxx> |
| #endif |
| // header for SvNumberFormatter |
| #include <svl/zforlist.hxx> |
| |
| #include "DataBrowser.hxx" |
| #include "DataBrowserModel.hxx" |
| #include "Strings.hrc" |
| #include "ContainerHelper.hxx" |
| #include "DataSeriesHelper.hxx" |
| #include "DiagramHelper.hxx" |
| #include "ChartModelHelper.hxx" |
| #include "CommonConverters.hxx" |
| #include "macros.hxx" |
| #include "NumberFormatterWrapper.hxx" |
| #include "servicenames_charttypes.hxx" |
| #include "ResId.hxx" |
| #include "Bitmaps.hrc" |
| #include "Bitmaps_HC.hrc" |
| #include "HelpIds.hrc" |
| |
| #include <vcl/fixed.hxx> |
| #include <vcl/image.hxx> |
| #include <vcl/msgbox.hxx> |
| #include <rtl/math.hxx> |
| |
| #include <com/sun/star/util/XCloneable.hpp> |
| #include <com/sun/star/chart2/XChartDocument.hpp> |
| #include <com/sun/star/chart2/XChartType.hpp> |
| |
| #include <com/sun/star/container/XIndexReplace.hpp> |
| #include <com/sun/star/util/XNumberFormats.hpp> |
| |
| #include <algorithm> |
| #include <functional> |
| |
| #define SELECT_IMAGE(name,hc) Image( SchResId( hc ? name ## _HC : name )) |
| |
| /* BROWSER_COLUMNSELECTION : single cells may be selected rather than only |
| entire rows |
| BROWSER_(H|V)LINES : show horizontal or vertical grid-lines |
| |
| BROWSER_AUTO_(H|V)SCROLL : scroll automated horizontally or vertically when |
| cursor is moved beyond the edge of the dialog |
| BROWSER_HIGHLIGHT_NONE : Do not mark the current row with selection color |
| (usually blue) |
| |
| */ |
| #define BROWSER_STANDARD_FLAGS \ |
| BROWSER_COLUMNSELECTION | \ |
| BROWSER_HLINES | BROWSER_VLINES | \ |
| BROWSER_AUTO_HSCROLL | BROWSER_AUTO_VSCROLL | \ |
| BROWSER_HIGHLIGHT_NONE |
| |
| // BROWSER_HIDECURSOR would prevent flickering in edit fields, but navigating |
| // with shift up/down, and entering non-editable cells would be problematic, |
| // e.g. the first cell, or when being in read-only mode |
| |
| |
| using namespace ::com::sun::star; |
| using ::com::sun::star::uno::Sequence; |
| using ::com::sun::star::uno::Reference; |
| using ::rtl::OUString; |
| |
| using namespace ::svt; |
| |
| namespace |
| { |
| sal_Int32 lcl_getRowInData( long nRow ) |
| { |
| return static_cast< sal_Int32 >( nRow ); |
| } |
| |
| sal_Int32 lcl_getColumnInData( sal_uInt16 nCol ) |
| { |
| return static_cast< sal_Int32 >( nCol ) - 1; |
| } |
| |
| } // anonymous namespace |
| |
| // -------------------------------------------------------------------------------- |
| |
| namespace chart |
| { |
| |
| // ---------------------------------------- |
| namespace impl |
| { |
| |
| class SeriesHeaderEdit : public Edit |
| { |
| public: |
| SeriesHeaderEdit( Window * pParent ); |
| virtual ~SeriesHeaderEdit(); |
| virtual void MouseButtonDown( const MouseEvent& rMEvt ); |
| |
| void setStartColumn( sal_Int32 nStartColumn ); |
| sal_Int32 getStartColumn() const; |
| void SetShowWarningBox( bool bShowWarning = true ); |
| |
| private: |
| sal_Int32 m_nStartColumn; |
| bool m_bShowWarningBox; |
| }; |
| |
| SeriesHeaderEdit::SeriesHeaderEdit( Window * pParent ) : |
| Edit( pParent ), |
| m_nStartColumn( 0 ), |
| m_bShowWarningBox( false ) |
| {} |
| SeriesHeaderEdit::~SeriesHeaderEdit() |
| {} |
| |
| void SeriesHeaderEdit::setStartColumn( sal_Int32 nStartColumn ) |
| { |
| m_nStartColumn = nStartColumn; |
| } |
| |
| sal_Int32 SeriesHeaderEdit::getStartColumn() const |
| { |
| return m_nStartColumn; |
| } |
| |
| void SeriesHeaderEdit::SetShowWarningBox( bool bShowWarning ) |
| { |
| m_bShowWarningBox = bShowWarning; |
| } |
| |
| void SeriesHeaderEdit::MouseButtonDown( const MouseEvent& rMEvt ) |
| { |
| Edit::MouseButtonDown( rMEvt ); |
| |
| if( m_bShowWarningBox ) |
| WarningBox( this, WinBits( WB_OK ), |
| String( SchResId( STR_INVALID_NUMBER ))).Execute(); |
| } |
| |
| class SeriesHeader |
| { |
| public: |
| explicit SeriesHeader( Window * pParent ); |
| |
| void SetColor( const Color & rCol ); |
| void SetPos( const Point & rPos ); |
| void SetWidth( sal_Int32 nWidth ); |
| void SetChartType( const Reference< chart2::XChartType > & xChartType, |
| bool bSwapXAndYAxis, |
| bool bIsHighContrast ); |
| void SetSeriesName( const String & rName ); |
| void SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol ); |
| |
| void SetPixelPosX( sal_Int32 nPos ); |
| void SetPixelWidth( sal_Int32 nWidth ); |
| |
| sal_Int32 GetStartColumn() const; |
| sal_Int32 GetEndColumn() const; |
| |
| static sal_Int32 GetRelativeAppFontXPosForNameField(); |
| |
| void Show(); |
| |
| /** call this before destroying the class. This notifies the listeners to |
| changes of the edit field for the series name. |
| */ |
| void applyChanges(); |
| |
| void SetGetFocusHdl( const Link& rLink ); |
| |
| void SetEditChangedHdl( const Link & rLink ); |
| |
| bool HasFocus() const; |
| |
| private: |
| ::boost::shared_ptr< FixedImage > m_spSymbol; |
| ::boost::shared_ptr< SeriesHeaderEdit > m_spSeriesName; |
| ::boost::shared_ptr< FixedText > m_spColorBar; |
| OutputDevice * m_pDevice; |
| Link m_aChangeLink; |
| |
| void notifyChanges(); |
| DECL_LINK( SeriesNameChanged, void * ); |
| DECL_LINK( SeriesNameEdited, void * ); |
| |
| /// @param bHC </sal_True> for hight-contrast image |
| static Image GetChartTypeImage( |
| const Reference< chart2::XChartType > & xChartType, |
| bool bSwapXAndYAxis, |
| bool bHC ); |
| |
| sal_Int32 m_nStartCol, m_nEndCol; |
| sal_Int32 m_nWidth; |
| Point m_aPos; |
| bool m_bSeriesNameChangePending; |
| }; |
| |
| SeriesHeader::SeriesHeader( Window * pParent ) : |
| m_spSymbol( new FixedImage( pParent, WB_NOBORDER )), |
| m_spSeriesName( new SeriesHeaderEdit( pParent )), |
| m_spColorBar( new FixedText( pParent, WB_NOBORDER )), |
| m_pDevice( pParent ), |
| m_nStartCol( 0 ), |
| m_nEndCol( 0 ), |
| m_nWidth( 42 ), |
| m_aPos( 0, 22 ), |
| m_bSeriesNameChangePending( false ) |
| { |
| m_spSeriesName->EnableUpdateData( 4 * EDIT_UPDATEDATA_TIMEOUT ); // define is in vcl/edit.hxx |
| m_spSeriesName->SetUpdateDataHdl( LINK( this, SeriesHeader, SeriesNameChanged )); |
| m_spSeriesName->SetModifyHdl( LINK( this, SeriesHeader, SeriesNameEdited )); |
| m_spSeriesName->SetHelpId( HID_SCH_DATA_SERIES_LABEL ); |
| Show(); |
| } |
| |
| void SeriesHeader::notifyChanges() |
| { |
| if( m_aChangeLink.IsSet()) |
| m_aChangeLink.Call( m_spSeriesName.get()); |
| |
| m_bSeriesNameChangePending = false; |
| } |
| |
| void SeriesHeader::applyChanges() |
| { |
| if( m_bSeriesNameChangePending ) |
| { |
| notifyChanges(); |
| } |
| } |
| |
| void SeriesHeader::SetColor( const Color & rCol ) |
| { |
| m_spColorBar->SetControlBackground( rCol ); |
| } |
| |
| const sal_Int32 nSymbolHeight = 10; |
| const sal_Int32 nSymbolDistance = 2; |
| |
| sal_Int32 SeriesHeader::GetRelativeAppFontXPosForNameField() |
| { |
| return nSymbolHeight + nSymbolDistance; |
| } |
| |
| void SeriesHeader::SetPos( const Point & rPos ) |
| { |
| m_aPos = rPos; |
| |
| // chart type symbol |
| Point aPos( rPos ); |
| aPos.setY( aPos.getY() + nSymbolDistance ); |
| Size aSize( nSymbolHeight, nSymbolHeight ); |
| m_spSymbol->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); |
| m_spSymbol->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); |
| aPos.setY( aPos.getY() - nSymbolDistance ); |
| |
| // series name edit field |
| aPos.setX( aPos.getX() + nSymbolHeight + nSymbolDistance ); |
| aSize.setWidth( m_nWidth - nSymbolHeight - nSymbolDistance ); |
| sal_Int32 nHeight = 12; |
| aSize.setHeight( nHeight ); |
| m_spSeriesName->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); |
| m_spSeriesName->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); |
| |
| // color bar |
| aPos.setX( rPos.getX() + 1 ); |
| aPos.setY( aPos.getY() + nHeight + 2 ); |
| nHeight = 3; |
| aSize.setWidth( m_nWidth - 1 ); |
| aSize.setHeight( nHeight ); |
| m_spColorBar->SetPosPixel( m_pDevice->LogicToPixel( aPos, MAP_APPFONT )); |
| m_spColorBar->SetSizePixel( m_pDevice->LogicToPixel( aSize, MAP_APPFONT )); |
| } |
| |
| void SeriesHeader::SetWidth( sal_Int32 nWidth ) |
| { |
| m_nWidth = nWidth; |
| SetPos( m_aPos ); |
| } |
| |
| |
| void SeriesHeader::SetPixelPosX( sal_Int32 nPos ) |
| { |
| Point aPos( m_pDevice->LogicToPixel( m_aPos, MAP_APPFONT )); |
| aPos.setX( nPos ); |
| SetPos( m_pDevice->PixelToLogic( aPos, MAP_APPFONT )); |
| } |
| |
| void SeriesHeader::SetPixelWidth( sal_Int32 nWidth ) |
| { |
| SetWidth( m_pDevice->PixelToLogic( Size( nWidth, 0 ), MAP_APPFONT ).getWidth()); |
| } |
| |
| void SeriesHeader::SetChartType( |
| const Reference< chart2::XChartType > & xChartType, |
| bool bSwapXAndYAxis, |
| bool bIsHighContrast ) |
| { |
| m_spSymbol->SetImage( GetChartTypeImage( xChartType, bSwapXAndYAxis, bIsHighContrast )); |
| } |
| |
| void SeriesHeader::SetSeriesName( const String & rName ) |
| { |
| m_spSeriesName->SetText( rName ); |
| } |
| |
| void SeriesHeader::SetRange( sal_Int32 nStartCol, sal_Int32 nEndCol ) |
| { |
| m_nStartCol = nStartCol; |
| m_nEndCol = (nEndCol > nStartCol) ? nEndCol : nStartCol; |
| m_spSeriesName->setStartColumn( nStartCol ); |
| } |
| |
| sal_Int32 SeriesHeader::GetStartColumn() const |
| { |
| return m_nStartCol; |
| } |
| |
| sal_Int32 SeriesHeader::GetEndColumn() const |
| { |
| return m_nEndCol; |
| } |
| |
| void SeriesHeader::Show() |
| { |
| m_spSymbol->Show(); |
| m_spSeriesName->Show(); |
| m_spColorBar->Show(); |
| } |
| |
| void SeriesHeader::SetEditChangedHdl( const Link & rLink ) |
| { |
| m_aChangeLink = rLink; |
| } |
| |
| IMPL_LINK( SeriesHeader, SeriesNameChanged, void * , EMPTYARG ) |
| { |
| notifyChanges(); |
| return 0; |
| } |
| |
| IMPL_LINK( SeriesHeader, SeriesNameEdited, void * , EMPTYARG ) |
| { |
| m_bSeriesNameChangePending = true; |
| return 0; |
| } |
| |
| void SeriesHeader::SetGetFocusHdl( const Link& rLink ) |
| { |
| m_spSeriesName->SetGetFocusHdl( rLink ); |
| } |
| |
| bool SeriesHeader::HasFocus() const |
| { |
| return m_spSeriesName->HasFocus(); |
| } |
| |
| Image SeriesHeader::GetChartTypeImage( |
| const Reference< chart2::XChartType > & xChartType, |
| bool bSwapXAndYAxis, |
| bool bHC ) |
| { |
| Image aResult; |
| if( !xChartType.is()) |
| return aResult; |
| OUString aChartTypeName( xChartType->getChartType()); |
| |
| if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_AREA )) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_AREA, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_COLUMN )) |
| { |
| if( bSwapXAndYAxis ) |
| aResult = SELECT_IMAGE( IMG_TYPE_BAR, bHC ); |
| else |
| aResult = SELECT_IMAGE( IMG_TYPE_COLUMN, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_LINE )) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_LINE, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_SCATTER )) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_XY, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_PIE )) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_PIE, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_NET ) |
| || aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET ) ) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_NET, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK )) |
| { |
| // @todo: correct image for candle-stick type |
| aResult = SELECT_IMAGE( IMG_TYPE_STOCK, bHC ); |
| } |
| else if( aChartTypeName.equals( CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE )) |
| { |
| aResult = SELECT_IMAGE( IMG_TYPE_BUBBLE, bHC ); |
| } |
| |
| return aResult; |
| } |
| |
| struct applyChangesFunctor : public ::std::unary_function< ::boost::shared_ptr< SeriesHeader >, void > |
| { |
| void operator() ( ::boost::shared_ptr< SeriesHeader > spHeader ) |
| { |
| spHeader->applyChanges(); |
| } |
| }; |
| |
| } // namespace impl |
| // ---------------------------------------- |
| |
| namespace |
| { |
| |
| /** returns false, if no header as the focus. |
| |
| If a header has the focus, true is returned and the index of the header |
| with focus is set at pIndex if pOutIndex is not 0. |
| */ |
| bool lcl_SeriesHeaderHasFocus( |
| const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader, |
| sal_Int32 * pOutIndex = 0 ) |
| { |
| sal_Int32 nIndex = 0; |
| for( ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > >::const_iterator aIt( rSeriesHeader.begin()); |
| aIt != rSeriesHeader.end(); ++aIt, ++nIndex ) |
| { |
| if( (*aIt)->HasFocus()) |
| { |
| if( pOutIndex ) |
| *pOutIndex = nIndex; |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| sal_Int32 lcl_getColumnInDataOrHeader( |
| sal_uInt16 nCol, const ::std::vector< ::boost::shared_ptr< ::chart::impl::SeriesHeader > > & rSeriesHeader ) |
| { |
| sal_Int32 nColIdx = 0; |
| bool bHeaderHasFocus( lcl_SeriesHeaderHasFocus( rSeriesHeader, &nColIdx )); |
| |
| if( bHeaderHasFocus ) |
| nColIdx = lcl_getColumnInData( static_cast< sal_uInt16 >( rSeriesHeader[nColIdx]->GetStartColumn())); |
| else |
| nColIdx = lcl_getColumnInData( nCol ); |
| |
| return nColIdx; |
| } |
| |
| } // anonymous namespace |
| |
| |
| DataBrowser::DataBrowser( Window* pParent, const ResId& rId, bool bLiveUpdate ) : |
| ::svt::EditBrowseBox( pParent, rId, EBBF_SMART_TAB_TRAVEL | EBBF_HANDLE_COLUMN_TEXT, BROWSER_STANDARD_FLAGS ), |
| m_nSeekRow( 0 ), |
| m_bIsReadOnly( false ), |
| m_bIsDirty( false ), |
| m_bLiveUpdate( bLiveUpdate ), |
| m_bDataValid( true ), |
| m_aNumberEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ), |
| m_aTextEditField( & EditBrowseBox::GetDataWindow(), WB_NOBORDER ), |
| m_rNumberEditController( new ::svt::FormattedFieldCellController( & m_aNumberEditField )), |
| m_rTextEditController( new ::svt::EditCellController( & m_aTextEditField )) |
| { |
| double fNan; |
| ::rtl::math::setNan( & fNan ); |
| m_aNumberEditField.SetDefaultValue( fNan ); |
| m_aNumberEditField.TreatAsNumber( sal_True ); |
| RenewTable(); |
| SetClean(); |
| } |
| |
| DataBrowser::~DataBrowser() |
| { |
| } |
| |
| bool DataBrowser::MayInsertRow() const |
| { |
| return ! IsReadOnly() |
| && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )); |
| } |
| |
| bool DataBrowser::MayInsertColumn() const |
| { |
| return ! IsReadOnly(); |
| } |
| |
| bool DataBrowser::MayDeleteRow() const |
| { |
| return ! IsReadOnly() |
| && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) |
| && ( GetCurRow() >= 0 ) |
| && ( GetRowCount() > 1 ); |
| } |
| |
| bool DataBrowser::MayDeleteColumn() const |
| { |
| // if a series header has the focus |
| if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) |
| return true; |
| |
| return ! IsReadOnly() |
| && ( GetCurColumnId() > 1 ) |
| && ( ColCount() > 2 ); |
| } |
| |
| bool DataBrowser::MaySwapRows() const |
| { |
| return ! IsReadOnly() |
| && ( !lcl_SeriesHeaderHasFocus( m_aSeriesHeaders )) |
| && ( GetCurRow() >= 0 ) |
| && ( GetCurRow() < GetRowCount() - 1 ); |
| } |
| |
| bool DataBrowser::MaySwapColumns() const |
| { |
| // if a series header (except the last one) has the focus |
| { |
| sal_Int32 nColIndex(0); |
| if( lcl_SeriesHeaderHasFocus( m_aSeriesHeaders, &nColIndex )) |
| return (static_cast< sal_uInt32 >( nColIndex ) < (m_aSeriesHeaders.size() - 1)); |
| } |
| |
| sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); |
| return ! IsReadOnly() |
| && ( nColIdx > 0 ) |
| && ( nColIdx < ColCount()-2 ) |
| && m_apDataBrowserModel.get() |
| && !m_apDataBrowserModel->isCategoriesColumn( nColIdx ); |
| } |
| |
| void DataBrowser::clearHeaders() |
| { |
| ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor()); |
| m_aSeriesHeaders.clear(); |
| } |
| |
| void DataBrowser::RenewTable() |
| { |
| if( ! m_apDataBrowserModel.get()) |
| return; |
| |
| long nOldRow = GetCurRow(); |
| sal_uInt16 nOldColId = GetCurColumnId(); |
| |
| sal_Bool bLastUpdateMode = GetUpdateMode(); |
| SetUpdateMode( sal_False ); |
| |
| if( IsModified() ) |
| SaveModified(); |
| |
| DeactivateCell(); |
| |
| RemoveColumns(); |
| RowRemoved( 1, GetRowCount() ); |
| |
| // for row numbers |
| InsertHandleColumn( static_cast< sal_uInt16 >( |
| GetDataWindow().LogicToPixel( Size( 42, 0 )).getWidth() )); |
| |
| OUString aDefaultSeriesName( ::chart::SchResId::getResString( STR_COLUMN_LABEL )); |
| replaceParamterInString( aDefaultSeriesName, C2U("%COLUMNNUMBER"), OUString::valueOf( sal_Int32(24) ) ); |
| sal_Int32 nColumnWidth = GetDataWindow().GetTextWidth( aDefaultSeriesName ) |
| + GetDataWindow().LogicToPixel( Point( 4 + impl::SeriesHeader::GetRelativeAppFontXPosForNameField(), 0 ), MAP_APPFONT ).X(); |
| sal_Int32 nColumnCount = m_apDataBrowserModel->getColumnCount(); |
| // nRowCount is a member of a base class |
| sal_Int32 nRowCountLocal = m_apDataBrowserModel->getMaxRowCount(); |
| for( sal_Int32 nColIdx=1; nColIdx<=nColumnCount; ++nColIdx ) |
| { |
| InsertDataColumn( static_cast< sal_uInt16 >( nColIdx ), GetColString( nColIdx ), nColumnWidth ); |
| } |
| |
| RowInserted( 1, nRowCountLocal ); |
| GoToRow( ::std::min( nOldRow, GetRowCount() - 1 )); |
| GoToColumnId( ::std::min( nOldColId, static_cast< sal_uInt16 >( ColCount() - 1 ))); |
| |
| Window * pWin = this->GetParent(); |
| if( !pWin ) |
| pWin = this; |
| |
| // fill series headers |
| clearHeaders(); |
| const DataBrowserModel::tDataHeaderVector& aHeaders( m_apDataBrowserModel->getDataHeaders()); |
| Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus )); |
| Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged )); |
| bool bIsHighContrast = pWin ? (pWin->GetSettings().GetStyleSettings().GetHighContrastMode()) : false; |
| |
| for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin()); |
| aIt != aHeaders.end(); ++aIt ) |
| { |
| ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin )); |
| Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY ); |
| sal_Int32 nColor = 0; |
| // @todo: Set "DraftColor", i.e. interpolated colors for gradients, bitmaps, etc. |
| if( xSeriesProp.is() && |
| ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor )) |
| spHeader->SetColor( Color( nColor )); |
| spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis, bIsHighContrast ); |
| spHeader->SetSeriesName( |
| String( DataSeriesHelper::getDataSeriesLabel( |
| aIt->m_xDataSeries, |
| (aIt->m_xChartType.is() ? |
| aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() : |
| OUString( RTL_CONSTASCII_USTRINGPARAM("values-y")))))); |
| // index is 1-based, as 0 is for the column that contains the row-numbers |
| spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 ); |
| spHeader->SetGetFocusHdl( aFocusLink ); |
| spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink ); |
| m_aSeriesHeaders.push_back( spHeader ); |
| } |
| |
| ImplAdjustHeaderControls(); |
| SetDirty(); |
| SetUpdateMode( bLastUpdateMode ); |
| ActivateCell(); |
| Invalidate(); |
| } |
| |
| String DataBrowser::GetColString( sal_Int32 nColumnId ) const |
| { |
| OSL_ASSERT( m_apDataBrowserModel.get()); |
| if( nColumnId > 0 ) |
| return String( m_apDataBrowserModel->getRoleOfColumn( static_cast< sal_Int32 >( nColumnId ) - 1 )); |
| return String(); |
| } |
| |
| String DataBrowser::GetRowString( sal_Int32 nRow ) const |
| { |
| return String::CreateFromInt32( nRow + 1 ); |
| } |
| |
| String DataBrowser::GetCellText( long nRow, sal_uInt16 nColumnId ) const |
| { |
| String aResult; |
| |
| if( nColumnId == 0 ) |
| { |
| aResult = GetRowString( static_cast< sal_Int32 >( nRow )); |
| } |
| else if( nRow >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| sal_Int32 nColIndex = static_cast< sal_Int32 >( nColumnId ) - 1; |
| |
| if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::NUMBER ) |
| { |
| double fData( m_apDataBrowserModel->getCellNumber( nColIndex, nRow )); |
| sal_Int32 nLabelColor; |
| bool bColorChanged = false; |
| |
| if( ! ::rtl::math::isNan( fData ) && |
| m_spNumberFormatterWrapper.get() ) |
| aResult = String( m_spNumberFormatterWrapper->getFormattedString( |
| GetNumberFormatKey( nRow, nColumnId ), |
| fData, nLabelColor, bColorChanged )); |
| } |
| else if( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXTORDATE ) |
| { |
| uno::Any aAny = m_apDataBrowserModel->getCellAny( nColIndex, nRow ); |
| OUString aText; |
| double fDouble=0.0; |
| if( aAny>>=aText ) |
| aResult = aText; |
| else if( aAny>>=fDouble ) |
| { |
| sal_Int32 nLabelColor; |
| bool bColorChanged = false; |
| sal_Int32 nDateNumberFormat = DiagramHelper::getDateNumberFormat( Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY) ); |
| if( ! ::rtl::math::isNan( fDouble ) && m_spNumberFormatterWrapper.get() ) |
| aResult = String( m_spNumberFormatterWrapper->getFormattedString( |
| nDateNumberFormat, fDouble, nLabelColor, bColorChanged )); |
| } |
| } |
| else |
| { |
| OSL_ASSERT( m_apDataBrowserModel->getCellType( nColIndex, nRow ) == DataBrowserModel::TEXT ); |
| aResult = m_apDataBrowserModel->getCellText( nColIndex, nRow ); |
| } |
| } |
| |
| return aResult; |
| } |
| |
| double DataBrowser::GetCellNumber( long nRow, sal_uInt16 nColumnId ) const |
| { |
| double fResult; |
| ::rtl::math::setNan( & fResult ); |
| |
| if(( nColumnId >= 1 ) && ( nRow >= 0 ) && |
| m_apDataBrowserModel.get()) |
| { |
| fResult = m_apDataBrowserModel->getCellNumber( |
| static_cast< sal_Int32 >( nColumnId ) - 1, nRow ); |
| } |
| |
| return fResult; |
| } |
| |
| void DataBrowser::Resize() |
| { |
| sal_Bool bLastUpdateMode = GetUpdateMode(); |
| SetUpdateMode( sal_False ); |
| |
| ::svt::EditBrowseBox::Resize(); |
| ImplAdjustHeaderControls(); |
| SetUpdateMode( bLastUpdateMode ); |
| } |
| |
| bool DataBrowser::SetReadOnly( bool bNewState ) |
| { |
| bool bResult = m_bIsReadOnly; |
| |
| if( m_bIsReadOnly != bNewState ) |
| { |
| m_bIsReadOnly = bNewState; |
| Invalidate(); |
| DeactivateCell(); |
| } |
| |
| return bResult; |
| } |
| |
| bool DataBrowser::IsReadOnly() const |
| { |
| return m_bIsReadOnly; |
| } |
| |
| |
| void DataBrowser::SetClean() |
| { |
| m_bIsDirty = false; |
| } |
| |
| void DataBrowser::SetDirty() |
| { |
| if( !m_bLiveUpdate ) |
| m_bIsDirty = true; |
| } |
| |
| void DataBrowser::CursorMoved() |
| { |
| EditBrowseBox::CursorMoved(); |
| |
| if( GetUpdateMode() && m_aCursorMovedHdlLink.IsSet()) |
| m_aCursorMovedHdlLink.Call( this ); |
| } |
| |
| void DataBrowser::SetCellModifiedHdl( const Link& rLink ) |
| { |
| m_aCellModifiedLink = rLink; |
| } |
| |
| void DataBrowser::MouseButtonDown( const BrowserMouseEvent& rEvt ) |
| { |
| if( !m_bDataValid ) |
| ShowWarningBox(); |
| else |
| EditBrowseBox::MouseButtonDown( rEvt ); |
| } |
| |
| void DataBrowser::ShowWarningBox() |
| { |
| WarningBox( this, WinBits( WB_OK ), |
| String( SchResId( STR_INVALID_NUMBER ))).Execute(); |
| } |
| |
| bool DataBrowser::ShowQueryBox() |
| { |
| QueryBox* pQueryBox = new QueryBox( this, WB_YES_NO, String( SchResId( STR_DATA_EDITOR_INCORRECT_INPUT ))); |
| |
| return ( pQueryBox->Execute() == RET_YES ); |
| } |
| |
| bool DataBrowser::IsDataValid() |
| { |
| bool bValid = true; |
| const sal_Int32 nRow = lcl_getRowInData( GetCurRow()); |
| const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId()); |
| |
| if( m_apDataBrowserModel->getCellType( nCol, nRow ) == DataBrowserModel::NUMBER ) |
| { |
| sal_uInt32 nDummy = 0; |
| double fDummy = 0.0; |
| String aText( m_aNumberEditField.GetText()); |
| |
| if( aText.Len() > 0 && |
| m_spNumberFormatterWrapper.get() && |
| m_spNumberFormatterWrapper->getSvNumberFormatter() && |
| ! m_spNumberFormatterWrapper->getSvNumberFormatter()->IsNumberFormat( |
| aText, nDummy, fDummy )) |
| { |
| bValid = false; |
| } |
| } |
| |
| return bValid; |
| } |
| |
| bool DataBrowser::IsEnableItem() |
| { |
| return m_bDataValid; |
| } |
| |
| void DataBrowser::CellModified() |
| { |
| m_bDataValid = IsDataValid(); |
| SetDirty(); |
| if( m_aCellModifiedLink.IsSet()) |
| m_aCursorMovedHdlLink.Call( this ); |
| } |
| |
| void DataBrowser::SetDataFromModel( |
| const Reference< chart2::XChartDocument > & xChartDoc, |
| const Reference< uno::XComponentContext > & xContext ) |
| { |
| if( m_bLiveUpdate ) |
| { |
| m_xChartDoc.set( xChartDoc ); |
| } |
| else |
| { |
| Reference< util::XCloneable > xCloneable( xChartDoc, uno::UNO_QUERY ); |
| if( xCloneable.is()) |
| m_xChartDoc.set( xCloneable->createClone(), uno::UNO_QUERY ); |
| } |
| |
| m_apDataBrowserModel.reset( new DataBrowserModel( m_xChartDoc, xContext )); |
| m_spNumberFormatterWrapper.reset( |
| new NumberFormatterWrapper( |
| Reference< util::XNumberFormatsSupplier >( m_xChartDoc, uno::UNO_QUERY ))); |
| |
| if( m_spNumberFormatterWrapper.get() ) |
| m_aNumberEditField.SetFormatter( m_spNumberFormatterWrapper->getSvNumberFormatter() ); |
| |
| RenewTable(); |
| |
| const sal_Int32 nColCnt = m_apDataBrowserModel->getColumnCount(); |
| const sal_Int32 nRowCnt = m_apDataBrowserModel->getMaxRowCount(); |
| if( nRowCnt && nColCnt ) |
| { |
| GoToRow( 0 ); |
| GoToColumnId( 1 ); |
| } |
| SetClean(); |
| } |
| |
| void DataBrowser::InsertColumn() |
| { |
| sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); |
| |
| if( nColIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_apDataBrowserModel->insertDataSeries( nColIdx ); |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::InsertTextColumn() |
| { |
| sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); |
| |
| if( nColIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_apDataBrowserModel->insertComplexCategoryLevel( nColIdx ); |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::RemoveColumn() |
| { |
| sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); |
| |
| if( nColIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_bDataValid = true; |
| m_apDataBrowserModel->removeDataSeriesOrComplexCategoryLevel( nColIdx ); |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::InsertRow() |
| { |
| sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); |
| |
| if( nRowIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_apDataBrowserModel->insertDataPointForAllSeries( nRowIdx ); |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::RemoveRow() |
| { |
| sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); |
| |
| if( nRowIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_bDataValid = true; |
| m_apDataBrowserModel->removeDataPointForAllSeries( nRowIdx ); |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::SwapColumn() |
| { |
| sal_Int32 nColIdx = lcl_getColumnInDataOrHeader( GetCurColumnId(), m_aSeriesHeaders ); |
| |
| if( nColIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_apDataBrowserModel->swapDataSeries( nColIdx ); |
| |
| // keep cursor in swapped column |
| if( GetCurColumnId() < ColCount() - 1 ) |
| { |
| Dispatch( BROWSER_CURSORRIGHT ); |
| } |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::SwapRow() |
| { |
| sal_Int32 nRowIdx = lcl_getRowInData( GetCurRow()); |
| |
| if( nRowIdx >= 0 && |
| m_apDataBrowserModel.get()) |
| { |
| // save changes made to edit-field |
| if( IsModified() ) |
| SaveModified(); |
| |
| m_apDataBrowserModel->swapDataPointForAllSeries( nRowIdx ); |
| |
| // keep cursor in swapped row |
| if( GetCurRow() < GetRowCount() - 1 ) |
| { |
| Dispatch( BROWSER_CURSORDOWN ); |
| } |
| RenewTable(); |
| } |
| } |
| |
| void DataBrowser::SetCursorMovedHdl( const Link& rLink ) |
| { |
| m_aCursorMovedHdlLink = rLink; |
| } |
| |
| // implementations for ::svt::EditBrowseBox (pure virtual methods) |
| void DataBrowser::PaintCell( |
| OutputDevice& rDev, const Rectangle& rRect, sal_uInt16 nColumnId ) const |
| { |
| Point aPos( rRect.TopLeft()); |
| aPos.X() += 1; |
| |
| String aText = GetCellText( m_nSeekRow, nColumnId ); |
| Size TxtSize( GetDataWindow().GetTextWidth( aText ), GetDataWindow().GetTextHeight()); |
| |
| // clipping |
| if( aPos.X() < rRect.Right() || aPos.X() + TxtSize.Width() > rRect.Right() || |
| aPos.Y() < rRect.Top() || aPos.Y() + TxtSize.Height() > rRect.Bottom()) |
| rDev.SetClipRegion( rRect ); |
| |
| // allow for a disabled control ... |
| sal_Bool bEnabled = IsEnabled(); |
| Color aOriginalColor = rDev.GetTextColor(); |
| if( ! bEnabled ) |
| rDev.SetTextColor( GetSettings().GetStyleSettings().GetDisableColor() ); |
| |
| // TEST |
| // if( nColumnId == 1 ) |
| // // categories |
| // rDev.SetFillColor( Color( 0xff, 0xff, 0xff )); |
| // else if( nColumnId == 2 ) |
| // // x-values |
| // rDev.SetFillColor( Color( 0xf0, 0xf0, 0xff )); |
| // else |
| // // y-values |
| // rDev.SetFillColor( Color( 0xff, 0xff, 0xf0 )); |
| |
| // rDev.DrawRect( rRect ); |
| |
| // draw the text |
| rDev.DrawText( aPos, aText ); |
| |
| // reset the color (if necessary) |
| if( ! bEnabled ) |
| rDev.SetTextColor( aOriginalColor ); |
| |
| if( rDev.IsClipRegion()) |
| rDev.SetClipRegion(); |
| } |
| |
| sal_Bool DataBrowser::SeekRow( long nRow ) |
| { |
| if( ! EditBrowseBox::SeekRow( nRow )) |
| return sal_False; |
| |
| if( nRow < 0 ) |
| m_nSeekRow = - 1; |
| else |
| m_nSeekRow = nRow; |
| |
| return sal_True; |
| } |
| |
| sal_Bool DataBrowser::IsTabAllowed( sal_Bool bForward ) const |
| { |
| long nRow = GetCurRow(); |
| long nCol = GetCurColumnId(); |
| |
| // column 0 is header-column |
| long nBadCol = bForward |
| ? GetColumnCount() - 1 |
| : 1; |
| long nBadRow = bForward |
| ? GetRowCount() - 1 |
| : 0; |
| |
| if( !m_bDataValid ) |
| { |
| const_cast< DataBrowser* >( this )->ShowWarningBox(); |
| return sal_False; |
| } |
| |
| return ( nRow != nBadRow || |
| nCol != nBadCol ); |
| } |
| |
| ::svt::CellController* DataBrowser::GetController( long nRow, sal_uInt16 nCol ) |
| { |
| if( m_bIsReadOnly ) |
| return 0; |
| |
| if( CellContainsNumbers( nRow, nCol )) |
| { |
| m_aNumberEditField.UseInputStringForFormatting(); |
| m_aNumberEditField.SetFormatKey( GetNumberFormatKey( nRow, nCol )); |
| return m_rNumberEditController; |
| } |
| |
| return m_rTextEditController; |
| } |
| |
| void DataBrowser::InitController( |
| ::svt::CellControllerRef& rController, long nRow, sal_uInt16 nCol ) |
| { |
| if( rController == m_rTextEditController ) |
| { |
| String aText( GetCellText( nRow, nCol ) ); |
| m_aTextEditField.SetText( aText ); |
| m_aTextEditField.SetSelection( Selection( 0, aText.Len() )); |
| } |
| else if( rController == m_rNumberEditController ) |
| { |
| // treat invalid and empty text as Nan |
| m_aNumberEditField.EnableNotANumber( true ); |
| if( ::rtl::math::isNan( GetCellNumber( nRow, nCol ))) |
| m_aNumberEditField.SetTextValue( String()); |
| else |
| m_aNumberEditField.SetValue( GetCellNumber( nRow, nCol ) ); |
| String aText( m_aNumberEditField.GetText()); |
| m_aNumberEditField.SetSelection( Selection( 0, aText.Len())); |
| } |
| else |
| { |
| DBG_ERROR( "Invalid Controller" ); |
| } |
| } |
| |
| bool DataBrowser::CellContainsNumbers( sal_Int32 nRow, sal_uInt16 nCol ) const |
| { |
| if( ! m_apDataBrowserModel.get()) |
| return false; |
| return (m_apDataBrowserModel->getCellType( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )) == |
| DataBrowserModel::NUMBER); |
| } |
| |
| sal_uInt32 DataBrowser::GetNumberFormatKey( sal_Int32 nRow, sal_uInt16 nCol ) const |
| { |
| if( ! m_apDataBrowserModel.get()) |
| return 0; |
| return m_apDataBrowserModel->getNumberFormatKey( lcl_getColumnInData( nCol ), lcl_getRowInData( nRow )); |
| } |
| |
| bool DataBrowser::isDateString( rtl::OUString aInputString, double& fOutDateValue ) |
| { |
| sal_uInt32 nNumberFormat=0; |
| SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0; |
| if( !aInputString.isEmpty() && pSvNumberFormatter && pSvNumberFormatter->IsNumberFormat( aInputString, nNumberFormat, fOutDateValue ) ) |
| { |
| Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_xChartDoc, uno::UNO_QUERY ); |
| Reference< util::XNumberFormats > xNumberFormats; |
| if( xNumberFormatsSupplier.is() ) |
| xNumberFormats = Reference< util::XNumberFormats >( xNumberFormatsSupplier->getNumberFormats() ); |
| if( DiagramHelper::isDateNumberFormat( nNumberFormat, xNumberFormats ) ) |
| return true; |
| } |
| return false; |
| } |
| |
| sal_Bool DataBrowser::SaveModified() |
| { |
| if( ! IsModified() ) |
| return sal_True; |
| |
| sal_Bool bChangeValid = sal_True; |
| |
| const sal_Int32 nRow = lcl_getRowInData( GetCurRow()); |
| const sal_Int32 nCol = lcl_getColumnInData( GetCurColumnId()); |
| |
| DBG_ASSERT( nRow >= 0 || nCol >= 0, "This cell should not be modified!" ); |
| |
| SvNumberFormatter* pSvNumberFormatter = m_spNumberFormatterWrapper.get() ? m_spNumberFormatterWrapper->getSvNumberFormatter() : 0; |
| switch( m_apDataBrowserModel->getCellType( nCol, nRow )) |
| { |
| case DataBrowserModel::NUMBER: |
| { |
| sal_uInt32 nDummy = 0; |
| double fDummy = 0.0; |
| String aText( m_aNumberEditField.GetText()); |
| // an empty string is valid, if no numberformatter exists, all |
| // values are treated as valid |
| if( aText.Len() > 0 && pSvNumberFormatter && |
| ! pSvNumberFormatter->IsNumberFormat( aText, nDummy, fDummy ) ) |
| { |
| bChangeValid = sal_False; |
| } |
| else |
| { |
| double fData = m_aNumberEditField.GetValue(); |
| bChangeValid = m_apDataBrowserModel->setCellNumber( nCol, nRow, fData ); |
| } |
| } |
| break; |
| case DataBrowserModel::TEXTORDATE: |
| { |
| OUString aText( m_aTextEditField.GetText() ); |
| double fDateValue=0.0; |
| bChangeValid = sal_False; |
| if( isDateString( aText, fDateValue ) ) |
| bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( fDateValue ) ); |
| if(!bChangeValid) |
| bChangeValid = m_apDataBrowserModel->setCellAny( nCol, nRow, uno::makeAny( aText ) ); |
| } |
| break; |
| case DataBrowserModel::TEXT: |
| { |
| OUString aText( m_aTextEditField.GetText()); |
| bChangeValid = m_apDataBrowserModel->setCellText( nCol, nRow, aText ); |
| } |
| break; |
| } |
| |
| // the first valid change changes this to true |
| if( bChangeValid ) |
| { |
| RowModified( GetCurRow(), GetCurColumnId()); |
| ::svt::CellController* pCtrl = GetController( GetCurRow(), GetCurColumnId()); |
| if( pCtrl ) |
| pCtrl->ClearModified(); |
| SetDirty(); |
| } |
| |
| return bChangeValid; |
| } |
| |
| bool DataBrowser::EndEditing() |
| { |
| if( IsModified()) |
| SaveModified(); |
| |
| // apply changes made to series headers |
| ::std::for_each( m_aSeriesHeaders.begin(), m_aSeriesHeaders.end(), impl::applyChangesFunctor()); |
| |
| if( m_bDataValid ) |
| return true; |
| else |
| return ShowQueryBox(); |
| } |
| |
| sal_Int16 DataBrowser::GetFirstVisibleColumNumber() const |
| { |
| return GetFirstVisibleColNumber(); |
| } |
| |
| void DataBrowser::ColumnResized( sal_uInt16 nColId ) |
| { |
| sal_Bool bLastUpdateMode = GetUpdateMode(); |
| SetUpdateMode( sal_False ); |
| |
| EditBrowseBox::ColumnResized( nColId ); |
| ImplAdjustHeaderControls(); |
| SetUpdateMode( bLastUpdateMode ); |
| } |
| |
| // virtual void MouseMove( const MouseEvent& rEvt ); |
| |
| void DataBrowser::EndScroll() |
| { |
| sal_Bool bLastUpdateMode = GetUpdateMode(); |
| SetUpdateMode( sal_False ); |
| |
| EditBrowseBox::EndScroll(); |
| RenewSeriesHeaders(); |
| |
| SetUpdateMode( bLastUpdateMode ); |
| } |
| |
| void DataBrowser::RenewSeriesHeaders() |
| { |
| Window * pWin = this->GetParent(); |
| if( !pWin ) |
| pWin = this; |
| |
| clearHeaders(); |
| DataBrowserModel::tDataHeaderVector aHeaders( m_apDataBrowserModel->getDataHeaders()); |
| Link aFocusLink( LINK( this, DataBrowser, SeriesHeaderGotFocus )); |
| Link aSeriesHeaderChangedLink( LINK( this, DataBrowser, SeriesHeaderChanged )); |
| bool bIsHighContrast = pWin ? (pWin->GetSettings().GetStyleSettings().GetHighContrastMode()) : false; |
| |
| for( DataBrowserModel::tDataHeaderVector::const_iterator aIt( aHeaders.begin()); |
| aIt != aHeaders.end(); ++aIt ) |
| { |
| ::boost::shared_ptr< impl::SeriesHeader > spHeader( new impl::SeriesHeader( pWin )); |
| Reference< beans::XPropertySet > xSeriesProp( aIt->m_xDataSeries, uno::UNO_QUERY ); |
| sal_Int32 nColor = 0; |
| if( xSeriesProp.is() && |
| ( xSeriesProp->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM("Color"))) >>= nColor )) |
| spHeader->SetColor( Color( nColor )); |
| spHeader->SetChartType( aIt->m_xChartType, aIt->m_bSwapXAndYAxis, bIsHighContrast ); |
| spHeader->SetSeriesName( |
| String( DataSeriesHelper::getDataSeriesLabel( |
| aIt->m_xDataSeries, |
| (aIt->m_xChartType.is() ? |
| aIt->m_xChartType->getRoleOfSequenceForSeriesLabel() : |
| OUString( RTL_CONSTASCII_USTRINGPARAM("values-y")))))); |
| spHeader->SetRange( aIt->m_nStartColumn + 1, aIt->m_nEndColumn + 1 ); |
| spHeader->SetGetFocusHdl( aFocusLink ); |
| spHeader->SetEditChangedHdl( aSeriesHeaderChangedLink ); |
| m_aSeriesHeaders.push_back( spHeader ); |
| } |
| |
| ImplAdjustHeaderControls(); |
| } |
| |
| void DataBrowser::ImplAdjustHeaderControls() |
| { |
| sal_uInt16 nColCount = this->GetColumnCount(); |
| sal_uInt32 nCurrentPos = this->GetPosPixel().getX(); |
| sal_uInt32 nMaxPos = nCurrentPos + this->GetOutputSizePixel().getWidth(); |
| sal_uInt32 nStartPos = nCurrentPos; |
| |
| // width of header column |
| nCurrentPos += this->GetColumnWidth( 0 ); |
| tSeriesHeaderContainer::iterator aIt( m_aSeriesHeaders.begin()); |
| sal_uInt16 i = this->GetFirstVisibleColumNumber(); |
| while( (aIt != m_aSeriesHeaders.end()) && ((*aIt)->GetStartColumn() < i) ) |
| ++aIt; |
| for( ; i < nColCount && aIt != m_aSeriesHeaders.end(); ++i ) |
| { |
| if( (*aIt)->GetStartColumn() == i ) |
| nStartPos = nCurrentPos; |
| |
| nCurrentPos += (this->GetColumnWidth( i )); |
| |
| if( (*aIt)->GetEndColumn() == i ) |
| { |
| if( nStartPos < nMaxPos ) |
| { |
| (*aIt)->SetPixelPosX( nStartPos + 2 ); |
| (*aIt)->SetPixelWidth( nCurrentPos - nStartPos - 3 ); |
| } |
| else |
| // do not hide, to get focus events. Move outside the dialog for "hiding" |
| (*aIt)->SetPixelPosX( nMaxPos + 42 ); |
| ++aIt; |
| } |
| } |
| } |
| |
| IMPL_LINK( DataBrowser, SeriesHeaderGotFocus, impl::SeriesHeaderEdit*, pEdit ) |
| { |
| if( pEdit ) |
| { |
| pEdit->SetShowWarningBox( !m_bDataValid ); |
| |
| if( !m_bDataValid ) |
| GoToCell( 0, 0 ); |
| else |
| { |
| //DeactivateCell(); |
| MakeFieldVisible( GetCurRow(), static_cast< sal_uInt16 >( pEdit->getStartColumn()), true /* bComplete */ ); |
| ActivateCell(); |
| m_aCursorMovedHdlLink.Call( this ); |
| } |
| } |
| return 0; |
| } |
| |
| IMPL_LINK( DataBrowser, SeriesHeaderChanged, impl::SeriesHeaderEdit*, pEdit ) |
| { |
| if( pEdit ) |
| { |
| Reference< chart2::XDataSeries > xSeries( |
| m_apDataBrowserModel->getDataSeriesByColumn( pEdit->getStartColumn() - 1 )); |
| Reference< chart2::data::XDataSource > xSource( xSeries, uno::UNO_QUERY ); |
| if( xSource.is()) |
| { |
| Reference< chart2::XChartType > xChartType( |
| m_apDataBrowserModel->getHeaderForSeries( xSeries ).m_xChartType ); |
| if( xChartType.is()) |
| { |
| Reference< chart2::data::XLabeledDataSequence > xLabeledSeq( |
| DataSeriesHelper::getDataSequenceByRole( xSource, xChartType->getRoleOfSequenceForSeriesLabel())); |
| if( xLabeledSeq.is()) |
| { |
| Reference< container::XIndexReplace > xIndexReplace( xLabeledSeq->getLabel(), uno::UNO_QUERY ); |
| if( xIndexReplace.is()) |
| xIndexReplace->replaceByIndex( |
| 0, uno::makeAny( OUString( pEdit->GetText()))); |
| } |
| } |
| } |
| } |
| return 0; |
| } |
| |
| sal_Int32 DataBrowser::GetTotalWidth() const |
| { |
| sal_uLong nWidth = 0; |
| for ( sal_uInt16 nCol = 0; nCol < ColCount(); ++nCol ) |
| nWidth += GetColumnWidth( nCol ); |
| return static_cast< sal_Int32 >( nWidth ); |
| } |
| |
| } // namespace chart |