LCOV - code coverage report
Current view: top level - chart2/source/controller/dialogs - DataBrowser.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 682 0.1 %
Date: 2015-06-13 12:38:46 Functions: 2 93 2.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11