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

Generated by: LCOV version 1.10