LCOV - code coverage report
Current view: top level - sc/source/ui/dbgui - csvgrid.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 822 0.1 %
Date: 2014-11-03 Functions: 2 86 2.3 %
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 "csvgrid.hxx"
      21             : 
      22             : #include <algorithm>
      23             : #include <memory>
      24             : 
      25             : #include <comphelper/string.hxx>
      26             : #include <svtools/colorcfg.hxx>
      27             : #include <svl/smplhint.hxx>
      28             : #include <sal/macros.h>
      29             : #include <tools/poly.hxx>
      30             : #include "scmod.hxx"
      31             : #include "asciiopt.hxx"
      32             : #include "impex.hxx"
      33             : #include "AccessibleCsvControl.hxx"
      34             : 
      35             : // *** edit engine ***
      36             : #include "scitems.hxx"
      37             : #include <editeng/eeitem.hxx>
      38             : #include <vcl/settings.hxx>
      39             : 
      40             : #include <editeng/colritem.hxx>
      41             : #include <editeng/fhgtitem.hxx>
      42             : #include <editeng/fontitem.hxx>
      43             : #include <svl/itemset.hxx>
      44             : #include "editutil.hxx"
      45             : // *** edit engine ***
      46             : 
      47             : struct Func_SetType
      48             : {
      49             :     sal_Int32                   mnType;
      50           0 :     inline                      Func_SetType( sal_Int32 nType ) : mnType( nType ) {}
      51           0 :     inline void                 operator()( ScCsvColState& rState ) const
      52           0 :         { rState.mnType = mnType; }
      53             : };
      54             : 
      55             : struct Func_Select
      56             : {
      57             :     bool                        mbSelect;
      58           0 :     inline                      Func_Select( bool bSelect ) : mbSelect( bSelect ) {}
      59           0 :     inline void                 operator()( ScCsvColState& rState ) const
      60           0 :         { rState.Select( mbSelect ); }
      61             : };
      62             : 
      63           0 : ScCsvGrid::ScCsvGrid( ScCsvControl& rParent ) :
      64             :     ScCsvControl( rParent ),
      65             :     mpColorConfig( 0 ),
      66           0 :     mpEditEngine( new ScEditEngineDefaulter( EditEngine::CreatePool(), true ) ),
      67           0 :     maHeaderFont( GetFont() ),
      68             :     maColStates( 1 ),
      69             :     maTypeNames( 1 ),
      70             :     mnFirstImpLine( 0 ),
      71             :     mnRecentSelCol( CSV_COLUMN_INVALID ),
      72             :     mnMTCurrCol( SAL_MAX_UINT32 ),
      73           0 :     mbMTSelecting( false )
      74             : {
      75           0 :     mpEditEngine->SetRefDevice( &maBackgrDev );
      76           0 :     mpEditEngine->SetRefMapMode( MapMode( MAP_PIXEL ) );
      77           0 :     maEdEngSize = mpEditEngine->GetPaperSize();
      78             : 
      79           0 :     maPopup.SetMenuFlags( maPopup.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS );
      80             : 
      81           0 :     EnableRTL( false ); // RTL
      82           0 :     InitFonts();
      83           0 :     ImplClearSplits();
      84           0 : }
      85             : 
      86           0 : ScCsvGrid::~ScCsvGrid()
      87             : {
      88             :     OSL_ENSURE(mpColorConfig, "the object hasn't been initialized properly");
      89           0 :     if (mpColorConfig)
      90           0 :         mpColorConfig->RemoveListener(this);
      91           0 : }
      92             : 
      93             : void
      94           0 : ScCsvGrid::Init()
      95             : {
      96             :     OSL_PRECOND(!mpColorConfig, "the object has already been initialized");
      97           0 :     mpColorConfig = &SC_MOD()->GetColorConfig();
      98           0 :     InitColors();
      99           0 :     mpColorConfig->AddListener(this);
     100           0 : }
     101             : 
     102             : // common grid handling -------------------------------------------------------
     103             : 
     104           0 : void ScCsvGrid::UpdateLayoutData()
     105             : {
     106           0 :     DisableRepaint();
     107           0 :     SetFont( maMonoFont );
     108           0 :     Execute( CSVCMD_SETCHARWIDTH, GetTextWidth( OUString( 'X' ) ) );
     109           0 :     Execute( CSVCMD_SETLINEHEIGHT, GetTextHeight() + 1 );
     110           0 :     SetFont( maHeaderFont );
     111           0 :     Execute( CSVCMD_SETHDRHEIGHT, GetTextHeight() + 1 );
     112           0 :     UpdateOffsetX();
     113           0 :     EnableRepaint();
     114           0 : }
     115             : 
     116           0 : void ScCsvGrid::UpdateOffsetX()
     117             : {
     118           0 :     sal_Int32 nLastLine = GetLastVisLine() + 1;
     119           0 :     sal_Int32 nDigits = 2;
     120           0 :     while( nLastLine /= 10 ) ++nDigits;
     121           0 :     nDigits = std::max( nDigits, sal_Int32( 3 ) );
     122           0 :     Execute( CSVCMD_SETHDRWIDTH, GetTextWidth( OUString( '0' ) ) * nDigits );
     123           0 : }
     124             : 
     125           0 : void ScCsvGrid::ApplyLayout( const ScCsvLayoutData& rOldData )
     126             : {
     127           0 :     ScCsvDiff nDiff = GetLayoutData().GetDiff( rOldData );
     128           0 :     if( nDiff == CSV_DIFF_EQUAL ) return;
     129             : 
     130           0 :     DisableRepaint();
     131             : 
     132           0 :     if( nDiff & CSV_DIFF_RULERCURSOR )
     133             :     {
     134           0 :         ImplInvertCursor( rOldData.mnPosCursor );
     135           0 :         ImplInvertCursor( GetRulerCursorPos() );
     136             :     }
     137             : 
     138           0 :     if( nDiff & CSV_DIFF_POSCOUNT )
     139             :     {
     140           0 :         if( GetPosCount() < rOldData.mnPosCount )
     141             :         {
     142           0 :             SelectAll( false );
     143           0 :             maSplits.RemoveRange( GetPosCount(), rOldData.mnPosCount );
     144             :         }
     145             :         else
     146           0 :             maSplits.Remove( rOldData.mnPosCount );
     147           0 :         maSplits.Insert( GetPosCount() );
     148           0 :         maColStates.resize( maSplits.Count() - 1 );
     149             :     }
     150             : 
     151           0 :     if( nDiff & CSV_DIFF_LINEOFFSET )
     152             :     {
     153           0 :         Execute( CSVCMD_UPDATECELLTEXTS );
     154           0 :         UpdateOffsetX();
     155             :     }
     156             : 
     157           0 :     ScCsvDiff nHVDiff = nDiff & (CSV_DIFF_HORIZONTAL | CSV_DIFF_VERTICAL);
     158           0 :     if( nHVDiff == CSV_DIFF_POSOFFSET )
     159           0 :         ImplDrawHorzScrolled( rOldData.mnPosOffset );
     160           0 :     else if( nHVDiff != CSV_DIFF_EQUAL )
     161           0 :         InvalidateGfx();
     162             : 
     163           0 :     EnableRepaint();
     164             : 
     165           0 :     if( nDiff & (CSV_DIFF_POSOFFSET | CSV_DIFF_LINEOFFSET) )
     166           0 :         AccSendVisibleEvent();
     167             : }
     168             : 
     169           0 : void ScCsvGrid::SetFirstImportedLine( sal_Int32 nLine )
     170             : {
     171           0 :     ImplDrawFirstLineSep( false );
     172           0 :     mnFirstImpLine = nLine;
     173           0 :     ImplDrawFirstLineSep( true );
     174           0 :     ImplDrawGridDev();
     175           0 :     Repaint();
     176           0 : }
     177             : 
     178           0 : sal_Int32 ScCsvGrid::GetNoScrollCol( sal_Int32 nPos ) const
     179             : {
     180           0 :     sal_Int32 nNewPos = nPos;
     181           0 :     if( nNewPos != CSV_POS_INVALID )
     182             :     {
     183           0 :         if( nNewPos < GetFirstVisPos() + CSV_SCROLL_DIST )
     184             :         {
     185           0 :             sal_Int32 nScroll = (GetFirstVisPos() > 0) ? CSV_SCROLL_DIST : 0;
     186           0 :             nNewPos = GetFirstVisPos() + nScroll;
     187             :         }
     188           0 :         else if( nNewPos > GetLastVisPos() - CSV_SCROLL_DIST - 1L )
     189             :         {
     190           0 :             sal_Int32 nScroll = (GetFirstVisPos() < GetMaxPosOffset()) ? CSV_SCROLL_DIST : 0;
     191           0 :             nNewPos = GetLastVisPos() - nScroll - 1;
     192             :         }
     193             :     }
     194           0 :     return nNewPos;
     195             : }
     196             : 
     197           0 : void ScCsvGrid::InitColors()
     198             : {
     199             :     OSL_PRECOND(mpColorConfig, "the object hasn't been initialized properly");
     200           0 :     if ( !mpColorConfig )
     201           0 :         return;
     202           0 :     maBackColor.SetColor( static_cast< sal_uInt32 >( mpColorConfig->GetColorValue( ::svtools::DOCCOLOR ).nColor ) );
     203           0 :     maGridColor.SetColor( static_cast< sal_uInt32 >( mpColorConfig->GetColorValue( ::svtools::CALCGRID ).nColor ) );
     204           0 :     maGridPBColor.SetColor( static_cast< sal_uInt32 >( mpColorConfig->GetColorValue( ::svtools::CALCPAGEBREAK ).nColor ) );
     205           0 :     maAppBackColor.SetColor( static_cast< sal_uInt32 >( mpColorConfig->GetColorValue( ::svtools::APPBACKGROUND ).nColor ) );
     206           0 :     maTextColor.SetColor( static_cast< sal_uInt32 >( mpColorConfig->GetColorValue( ::svtools::FONTCOLOR ).nColor ) );
     207             : 
     208           0 :     const StyleSettings& rSett = GetSettings().GetStyleSettings();
     209           0 :     maHeaderBackColor = rSett.GetFaceColor();
     210           0 :     maHeaderGridColor = rSett.GetDarkShadowColor();
     211           0 :     maHeaderTextColor = rSett.GetButtonTextColor();
     212           0 :     maSelectColor = rSett.GetActiveColor();
     213             : 
     214           0 :     InvalidateGfx();
     215             : }
     216             : 
     217           0 : void ScCsvGrid::InitFonts()
     218             : {
     219           0 :     maMonoFont = OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED, LANGUAGE_ENGLISH_US, 0 );
     220           0 :     maMonoFont.SetSize( Size( maMonoFont.GetSize().Width(), maHeaderFont.GetSize().Height() ) );
     221             : 
     222             :     /* *** Set edit engine defaults ***
     223             :         maMonoFont for Latin script, smaller default font for Asian and Complex script. */
     224             : 
     225             :     // get default fonts
     226           0 :     SvxFontItem aLatinItem( EE_CHAR_FONTINFO );
     227           0 :     SvxFontItem aAsianItem( EE_CHAR_FONTINFO_CJK );
     228           0 :     SvxFontItem aComplexItem( EE_CHAR_FONTINFO_CTL );
     229           0 :     ::GetDefaultFonts( aLatinItem, aAsianItem, aComplexItem );
     230             : 
     231             :     // create item set for defaults
     232           0 :     SfxItemSet aDefSet( mpEditEngine->GetEmptyItemSet() );
     233           0 :     EditEngine::SetFontInfoInItemSet( aDefSet, maMonoFont );
     234           0 :     aDefSet.Put( aAsianItem );
     235           0 :     aDefSet.Put( aComplexItem );
     236             : 
     237             :     // set Asian/Complex font size to height of character in Latin font
     238           0 :     sal_uLong nFontHt = static_cast< sal_uLong >( maMonoFont.GetSize().Height() );
     239           0 :     aDefSet.Put( SvxFontHeightItem( nFontHt, 100, EE_CHAR_FONTHEIGHT_CJK ) );
     240           0 :     aDefSet.Put( SvxFontHeightItem( nFontHt, 100, EE_CHAR_FONTHEIGHT_CTL ) );
     241             : 
     242             :     // copy other items from default font
     243           0 :     const SfxPoolItem& rWeightItem = aDefSet.Get( EE_CHAR_WEIGHT );
     244           0 :     aDefSet.Put( rWeightItem, EE_CHAR_WEIGHT_CJK );
     245           0 :     aDefSet.Put( rWeightItem, EE_CHAR_WEIGHT_CTL );
     246           0 :     const SfxPoolItem& rItalicItem = aDefSet.Get( EE_CHAR_ITALIC );
     247           0 :     aDefSet.Put( rItalicItem, EE_CHAR_ITALIC_CJK );
     248           0 :     aDefSet.Put( rItalicItem, EE_CHAR_ITALIC_CTL );
     249           0 :     const SfxPoolItem& rLangItem = aDefSet.Get( EE_CHAR_LANGUAGE );
     250           0 :     aDefSet.Put( rLangItem, EE_CHAR_LANGUAGE_CJK );
     251           0 :     aDefSet.Put( rLangItem, EE_CHAR_LANGUAGE_CTL );
     252             : 
     253           0 :     mpEditEngine->SetDefaults( aDefSet );
     254           0 :     InvalidateGfx();
     255           0 : }
     256             : 
     257           0 : void ScCsvGrid::InitSizeData()
     258             : {
     259           0 :     maWinSize = GetSizePixel();
     260           0 :     maBackgrDev.SetOutputSizePixel( maWinSize );
     261           0 :     maGridDev.SetOutputSizePixel( maWinSize );
     262           0 :     InvalidateGfx();
     263           0 : }
     264             : 
     265             : // split handling -------------------------------------------------------------
     266             : 
     267           0 : void ScCsvGrid::InsertSplit( sal_Int32 nPos )
     268             : {
     269           0 :     if( ImplInsertSplit( nPos ) )
     270             :     {
     271           0 :         DisableRepaint();
     272           0 :         Execute( CSVCMD_EXPORTCOLUMNTYPE );
     273           0 :         Execute( CSVCMD_UPDATECELLTEXTS );
     274           0 :         sal_uInt32 nColIx = GetColumnFromPos( nPos );
     275           0 :         ImplDrawColumn( nColIx - 1 );
     276           0 :         ImplDrawColumn( nColIx );
     277           0 :         ValidateGfx();  // performance: do not redraw all columns
     278           0 :         EnableRepaint();
     279             :     }
     280           0 : }
     281             : 
     282           0 : void ScCsvGrid::RemoveSplit( sal_Int32 nPos )
     283             : {
     284           0 :     if( ImplRemoveSplit( nPos ) )
     285             :     {
     286           0 :         DisableRepaint();
     287           0 :         Execute( CSVCMD_EXPORTCOLUMNTYPE );
     288           0 :         Execute( CSVCMD_UPDATECELLTEXTS );
     289           0 :         ImplDrawColumn( GetColumnFromPos( nPos ) );
     290           0 :         ValidateGfx();  // performance: do not redraw all columns
     291           0 :         EnableRepaint();
     292             :     }
     293           0 : }
     294             : 
     295           0 : void ScCsvGrid::MoveSplit( sal_Int32 nPos, sal_Int32 nNewPos )
     296             : {
     297           0 :     sal_uInt32 nColIx = GetColumnFromPos( nPos );
     298           0 :     if( nColIx != CSV_COLUMN_INVALID )
     299             :     {
     300           0 :         DisableRepaint();
     301           0 :         if( (GetColumnPos( nColIx - 1 ) < nNewPos) && (nNewPos < GetColumnPos( nColIx + 1 )) )
     302             :         {
     303             :             // move a split in the range between 2 others -> keep selection state of both columns
     304           0 :             maSplits.Remove( nPos );
     305           0 :             maSplits.Insert( nNewPos );
     306           0 :             Execute( CSVCMD_UPDATECELLTEXTS );
     307           0 :             ImplDrawColumn( nColIx - 1 );
     308           0 :             ImplDrawColumn( nColIx );
     309           0 :             ValidateGfx();  // performance: do not redraw all columns
     310           0 :             AccSendTableUpdateEvent( nColIx - 1, nColIx );
     311             :         }
     312             :         else
     313             :         {
     314           0 :             ImplRemoveSplit( nPos );
     315           0 :             ImplInsertSplit( nNewPos );
     316           0 :             Execute( CSVCMD_EXPORTCOLUMNTYPE );
     317           0 :             Execute( CSVCMD_UPDATECELLTEXTS );
     318             :         }
     319           0 :         EnableRepaint();
     320             :     }
     321           0 : }
     322             : 
     323           0 : void ScCsvGrid::RemoveAllSplits()
     324             : {
     325           0 :     DisableRepaint();
     326           0 :     ImplClearSplits();
     327           0 :     Execute( CSVCMD_EXPORTCOLUMNTYPE );
     328           0 :     Execute( CSVCMD_UPDATECELLTEXTS );
     329           0 :     EnableRepaint();
     330           0 : }
     331             : 
     332           0 : void ScCsvGrid::SetSplits( const ScCsvSplits& rSplits )
     333             : {
     334           0 :     DisableRepaint();
     335           0 :     ImplClearSplits();
     336           0 :     sal_uInt32 nCount = rSplits.Count();
     337           0 :     for( sal_uInt32 nIx = 0; nIx < nCount; ++nIx )
     338           0 :         maSplits.Insert( rSplits[ nIx ] );
     339           0 :     maColStates.clear();
     340           0 :     maColStates.resize( maSplits.Count() - 1 );
     341           0 :     Execute( CSVCMD_EXPORTCOLUMNTYPE );
     342           0 :     Execute( CSVCMD_UPDATECELLTEXTS );
     343           0 :     EnableRepaint();
     344           0 : }
     345             : 
     346           0 : bool ScCsvGrid::ImplInsertSplit( sal_Int32 nPos )
     347             : {
     348           0 :     sal_uInt32 nColIx = GetColumnFromPos( nPos );
     349           0 :     bool bRet = (nColIx < GetColumnCount()) && maSplits.Insert( nPos );
     350           0 :     if( bRet )
     351             :     {
     352           0 :         ScCsvColState aState( GetColumnType( nColIx ) );
     353           0 :         aState.Select( IsSelected( nColIx ) && IsSelected( nColIx + 1 ) );
     354           0 :         maColStates.insert( maColStates.begin() + nColIx + 1, aState );
     355           0 :         AccSendInsertColumnEvent( nColIx + 1, nColIx + 1 );
     356           0 :         AccSendTableUpdateEvent( nColIx, nColIx );
     357             :     }
     358           0 :     return bRet;
     359             : }
     360             : 
     361           0 : bool ScCsvGrid::ImplRemoveSplit( sal_Int32 nPos )
     362             : {
     363           0 :     bool bRet = maSplits.Remove( nPos );
     364           0 :     if( bRet )
     365             :     {
     366           0 :         sal_uInt32 nColIx = GetColumnFromPos( nPos );
     367           0 :         bool bSel = IsSelected( nColIx ) || IsSelected( nColIx + 1 );
     368           0 :         maColStates.erase( maColStates.begin() + nColIx + 1 );
     369           0 :         maColStates[ nColIx ].Select( bSel );
     370           0 :         AccSendRemoveColumnEvent( nColIx + 1, nColIx + 1 );
     371           0 :         AccSendTableUpdateEvent( nColIx, nColIx );
     372             :     }
     373           0 :     return bRet;
     374             : }
     375             : 
     376           0 : void ScCsvGrid::ImplClearSplits()
     377             : {
     378           0 :     sal_uInt32 nColumns = GetColumnCount();
     379           0 :     maSplits.Clear();
     380           0 :     maSplits.Insert( 0 );
     381           0 :     maSplits.Insert( GetPosCount() );
     382           0 :     maColStates.resize( 1 );
     383           0 :     InvalidateGfx();
     384           0 :     AccSendRemoveColumnEvent( 1, nColumns - 1 );
     385           0 : }
     386             : 
     387             : // columns/column types -------------------------------------------------------
     388             : 
     389           0 : sal_uInt32 ScCsvGrid::GetFirstVisColumn() const
     390             : {
     391           0 :     return GetColumnFromPos( GetFirstVisPos() );
     392             : }
     393             : 
     394           0 : sal_uInt32 ScCsvGrid::GetLastVisColumn() const
     395             : {
     396           0 :     return GetColumnFromPos( std::min( GetLastVisPos(), GetPosCount() ) - 1 );
     397             : }
     398             : 
     399           0 : bool ScCsvGrid::IsValidColumn( sal_uInt32 nColIndex ) const
     400             : {
     401           0 :     return nColIndex < GetColumnCount();
     402             : }
     403             : 
     404           0 : bool ScCsvGrid::IsVisibleColumn( sal_uInt32 nColIndex ) const
     405             : {
     406           0 :     return  IsValidColumn( nColIndex ) &&
     407           0 :             (GetColumnPos( nColIndex ) < GetLastVisPos()) &&
     408           0 :             (GetFirstVisPos() < GetColumnPos( nColIndex + 1 ));
     409             : }
     410             : 
     411           0 : sal_Int32 ScCsvGrid::GetColumnX( sal_uInt32 nColIndex ) const
     412             : {
     413           0 :     return GetX( GetColumnPos( nColIndex ) );
     414             : }
     415             : 
     416           0 : sal_uInt32 ScCsvGrid::GetColumnFromX( sal_Int32 nX ) const
     417             : {
     418           0 :     sal_Int32 nPos = (nX - GetFirstX()) / GetCharWidth() + GetFirstVisPos();
     419           0 :     return ((GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos())) ?
     420           0 :         GetColumnFromPos( nPos ) : CSV_COLUMN_INVALID;
     421             : }
     422             : 
     423           0 : sal_uInt32 ScCsvGrid::GetColumnFromPos( sal_Int32 nPos ) const
     424             : {
     425           0 :     return maSplits.UpperBound( nPos );
     426             : }
     427             : 
     428           0 : sal_Int32 ScCsvGrid::GetColumnWidth( sal_uInt32 nColIndex ) const
     429             : {
     430           0 :     return IsValidColumn( nColIndex ) ? (GetColumnPos( nColIndex + 1 ) - GetColumnPos( nColIndex )) : 0;
     431             : }
     432             : 
     433           0 : void ScCsvGrid::SetColumnStates( const ScCsvColStateVec& rStates )
     434             : {
     435           0 :     maColStates = rStates;
     436           0 :     maColStates.resize( maSplits.Count() - 1 );
     437           0 :     Execute( CSVCMD_EXPORTCOLUMNTYPE );
     438           0 :     AccSendTableUpdateEvent( 0, GetColumnCount(), false );
     439           0 :     AccSendSelectionEvent();
     440           0 : }
     441             : 
     442           0 : sal_Int32 ScCsvGrid::GetColumnType( sal_uInt32 nColIndex ) const
     443             : {
     444           0 :     return IsValidColumn( nColIndex ) ? maColStates[ nColIndex ].mnType : CSV_TYPE_NOSELECTION;
     445             : }
     446             : 
     447           0 : void ScCsvGrid::SetColumnType( sal_uInt32 nColIndex, sal_Int32 nColType )
     448             : {
     449           0 :     if( IsValidColumn( nColIndex ) )
     450             :     {
     451           0 :         maColStates[ nColIndex ].mnType = nColType;
     452           0 :         AccSendTableUpdateEvent( nColIndex, nColIndex, false );
     453             :     }
     454           0 : }
     455             : 
     456           0 : sal_Int32 ScCsvGrid::GetSelColumnType() const
     457             : {
     458           0 :     sal_uInt32 nColIx = GetFirstSelected();
     459           0 :     if( nColIx == CSV_COLUMN_INVALID )
     460           0 :         return CSV_TYPE_NOSELECTION;
     461             : 
     462           0 :     sal_Int32 nType = GetColumnType( nColIx );
     463           0 :     while( (nColIx != CSV_COLUMN_INVALID) && (nType != CSV_TYPE_MULTI) )
     464             :     {
     465           0 :         if( nType != GetColumnType( nColIx ) )
     466           0 :             nType = CSV_TYPE_MULTI;
     467           0 :         nColIx = GetNextSelected( nColIx );
     468             :     }
     469           0 :     return nType;
     470             : }
     471             : 
     472           0 : void ScCsvGrid::SetSelColumnType( sal_Int32 nType )
     473             : {
     474           0 :     if( (nType != CSV_TYPE_MULTI) && (nType != CSV_TYPE_NOSELECTION) )
     475             :     {
     476           0 :         for( sal_uInt32 nColIx = GetFirstSelected(); nColIx != CSV_COLUMN_INVALID; nColIx = GetNextSelected( nColIx ) )
     477           0 :             SetColumnType( nColIx, nType );
     478           0 :         Repaint( true );
     479           0 :         Execute( CSVCMD_EXPORTCOLUMNTYPE );
     480             :     }
     481           0 : }
     482             : 
     483           0 : void ScCsvGrid::SetTypeNames( const StringVec& rTypeNames )
     484             : {
     485             :     OSL_ENSURE( !rTypeNames.empty(), "ScCsvGrid::SetTypeNames - vector is empty" );
     486           0 :     maTypeNames = rTypeNames;
     487           0 :     Repaint( true );
     488             : 
     489           0 :     maPopup.Clear();
     490           0 :     sal_uInt32 nCount = maTypeNames.size();
     491             :     sal_uInt32 nIx;
     492             :     sal_uInt16 nItemId;
     493           0 :     for( nIx = 0, nItemId = 1; nIx < nCount; ++nIx, ++nItemId )
     494           0 :         maPopup.InsertItem( nItemId, maTypeNames[ nIx ] );
     495             : 
     496           0 :     ::std::for_each( maColStates.begin(), maColStates.end(), Func_SetType( CSV_TYPE_DEFAULT ) );
     497           0 : }
     498             : 
     499           0 : const OUString& ScCsvGrid::GetColumnTypeName( sal_uInt32 nColIndex ) const
     500             : {
     501           0 :     sal_uInt32 nTypeIx = static_cast< sal_uInt32 >( GetColumnType( nColIndex ) );
     502           0 :     return (nTypeIx < maTypeNames.size()) ? maTypeNames[ nTypeIx ] : EMPTY_OUSTRING;
     503             : }
     504             : 
     505           0 : static sal_uInt8 lcl_GetExtColumnType( sal_Int32 nIntType )
     506             : {
     507             :     static const sal_uInt8 pExtTypes[] =
     508             :         { SC_COL_STANDARD, SC_COL_TEXT, SC_COL_DMY, SC_COL_MDY, SC_COL_YMD, SC_COL_ENGLISH, SC_COL_SKIP };
     509             :     static const sal_Int32 nExtTypeCount = SAL_N_ELEMENTS(pExtTypes);
     510           0 :     return pExtTypes[ ((0 <= nIntType) && (nIntType < nExtTypeCount)) ? nIntType : 0 ];
     511             : }
     512             : 
     513           0 : void ScCsvGrid::FillColumnDataSep( ScAsciiOptions& rOptions ) const
     514             : {
     515           0 :     sal_uInt32 nCount = GetColumnCount();
     516           0 :     ScCsvExpDataVec aDataVec;
     517             : 
     518           0 :     for( sal_uInt32 nColIx = 0; nColIx < nCount; ++nColIx )
     519             :     {
     520           0 :         if( GetColumnType( nColIx ) != CSV_TYPE_DEFAULT )
     521             :             // 1-based column index
     522             :             aDataVec.push_back( ScCsvExpData(
     523           0 :                 static_cast< sal_Int32 >( nColIx + 1 ),
     524           0 :                 lcl_GetExtColumnType( GetColumnType( nColIx ) ) ) );
     525             :     }
     526           0 :     rOptions.SetColumnInfo( aDataVec );
     527           0 : }
     528             : 
     529           0 : void ScCsvGrid::FillColumnDataFix( ScAsciiOptions& rOptions ) const
     530             : {
     531           0 :     sal_uInt32 nCount = std::min( GetColumnCount(), static_cast<sal_uInt32>(MAXCOLCOUNT) );
     532           0 :     ScCsvExpDataVec aDataVec( nCount + 1 );
     533             : 
     534           0 :     for( sal_uInt32 nColIx = 0; nColIx < nCount; ++nColIx )
     535             :     {
     536           0 :         ScCsvExpData& rData = aDataVec[ nColIx ];
     537           0 :         rData.mnIndex = static_cast< sal_Int32 >( GetColumnPos( nColIx ) );
     538           0 :         rData.mnType = lcl_GetExtColumnType( GetColumnType( nColIx ) );
     539             :     }
     540           0 :     aDataVec[ nCount ].mnIndex = SAL_MAX_INT32;
     541           0 :     aDataVec[ nCount ].mnType = SC_COL_SKIP;
     542           0 :     rOptions.SetColumnInfo( aDataVec );
     543           0 : }
     544             : 
     545           0 : void ScCsvGrid::ScrollVertRel( ScMoveMode eDir )
     546             : {
     547           0 :     sal_Int32 nLine = GetFirstVisLine();
     548           0 :     switch( eDir )
     549             :     {
     550           0 :         case MOVE_PREV:     --nLine;                        break;
     551           0 :         case MOVE_NEXT:     ++nLine;                        break;
     552           0 :         case MOVE_FIRST:    nLine = 0;                      break;
     553           0 :         case MOVE_LAST:     nLine = GetMaxLineOffset();     break;
     554           0 :         case MOVE_PREVPAGE: nLine -= GetVisLineCount() - 2; break;
     555           0 :         case MOVE_NEXTPAGE: nLine += GetVisLineCount() - 2; break;
     556             :         default:
     557             :         {
     558             :             // added to avoid warnings
     559             :         }
     560             :     }
     561           0 :     Execute( CSVCMD_SETLINEOFFSET, nLine );
     562           0 : }
     563             : 
     564           0 : void ScCsvGrid::ExecutePopup( const Point& rPos )
     565             : {
     566           0 :     sal_uInt16 nItemId = maPopup.Execute( this, rPos );
     567           0 :     if( nItemId )   // 0 = cancelled
     568           0 :         Execute( CSVCMD_SETCOLUMNTYPE, maPopup.GetItemPos( nItemId ) );
     569           0 : }
     570             : 
     571             : // selection handling ---------------------------------------------------------
     572             : 
     573           0 : bool ScCsvGrid::IsSelected( sal_uInt32 nColIndex ) const
     574             : {
     575           0 :     return IsValidColumn( nColIndex ) && maColStates[ nColIndex ].IsSelected();
     576             : }
     577             : 
     578           0 : sal_uInt32 ScCsvGrid::GetFirstSelected() const
     579             : {
     580           0 :     return IsSelected( 0 ) ? 0 : GetNextSelected( 0 );
     581             : }
     582             : 
     583           0 : sal_uInt32 ScCsvGrid::GetNextSelected( sal_uInt32 nFromIndex ) const
     584             : {
     585           0 :     sal_uInt32 nColCount = GetColumnCount();
     586           0 :     for( sal_uInt32 nColIx = nFromIndex + 1; nColIx < nColCount; ++nColIx )
     587           0 :         if( IsSelected( nColIx ) )
     588           0 :             return nColIx;
     589           0 :     return CSV_COLUMN_INVALID;
     590             : }
     591             : 
     592           0 : void ScCsvGrid::Select( sal_uInt32 nColIndex, bool bSelect )
     593             : {
     594           0 :     if( IsValidColumn( nColIndex ) )
     595             :     {
     596           0 :         maColStates[ nColIndex ].Select( bSelect );
     597           0 :         ImplDrawColumnSelection( nColIndex );
     598           0 :         Repaint();
     599           0 :         Execute( CSVCMD_EXPORTCOLUMNTYPE );
     600           0 :         if( bSelect )
     601           0 :             mnRecentSelCol = nColIndex;
     602           0 :         AccSendSelectionEvent();
     603             :     }
     604           0 : }
     605             : 
     606           0 : void ScCsvGrid::ToggleSelect( sal_uInt32 nColIndex )
     607             : {
     608           0 :     Select( nColIndex, !IsSelected( nColIndex ) );
     609           0 : }
     610             : 
     611           0 : void ScCsvGrid::SelectRange( sal_uInt32 nColIndex1, sal_uInt32 nColIndex2, bool bSelect )
     612             : {
     613           0 :     if( nColIndex1 == CSV_COLUMN_INVALID )
     614           0 :         Select( nColIndex2 );
     615           0 :     else if( nColIndex2 == CSV_COLUMN_INVALID )
     616           0 :         Select( nColIndex1 );
     617           0 :     else if( nColIndex1 > nColIndex2 )
     618             :     {
     619           0 :         SelectRange( nColIndex2, nColIndex1, bSelect );
     620           0 :         if( bSelect )
     621           0 :             mnRecentSelCol = nColIndex1;
     622             :     }
     623           0 :     else if( IsValidColumn( nColIndex1 ) && IsValidColumn( nColIndex2 ) )
     624             :     {
     625           0 :         for( sal_uInt32 nColIx = nColIndex1; nColIx <= nColIndex2; ++nColIx )
     626             :         {
     627           0 :             maColStates[ nColIx ].Select( bSelect );
     628           0 :             ImplDrawColumnSelection( nColIx );
     629             :         }
     630           0 :         Repaint();
     631           0 :         Execute( CSVCMD_EXPORTCOLUMNTYPE );
     632           0 :         if( bSelect )
     633           0 :             mnRecentSelCol = nColIndex1;
     634           0 :         AccSendSelectionEvent();
     635             :     }
     636           0 : }
     637             : 
     638           0 : void ScCsvGrid::SelectAll( bool bSelect )
     639             : {
     640           0 :     SelectRange( 0, GetColumnCount() - 1, bSelect );
     641           0 : }
     642             : 
     643           0 : void ScCsvGrid::MoveCursor( sal_uInt32 nColIndex )
     644             : {
     645           0 :     DisableRepaint();
     646           0 :     if( IsValidColumn( nColIndex ) )
     647             :     {
     648           0 :         sal_Int32 nPosBeg = GetColumnPos( nColIndex );
     649           0 :         sal_Int32 nPosEnd = GetColumnPos( nColIndex + 1 );
     650           0 :         sal_Int32 nMinPos = std::max( nPosBeg - CSV_SCROLL_DIST, sal_Int32( 0 ) );
     651           0 :         sal_Int32 nMaxPos = std::min( nPosEnd - GetVisPosCount() + CSV_SCROLL_DIST + sal_Int32( 1 ), nMinPos );
     652           0 :         if( nPosBeg - CSV_SCROLL_DIST + 1 <= GetFirstVisPos() )
     653           0 :             Execute( CSVCMD_SETPOSOFFSET, nMinPos );
     654           0 :         else if( nPosEnd + CSV_SCROLL_DIST >= GetLastVisPos() )
     655           0 :             Execute( CSVCMD_SETPOSOFFSET, nMaxPos );
     656             :     }
     657           0 :     Execute( CSVCMD_MOVEGRIDCURSOR, GetColumnPos( nColIndex ) );
     658           0 :     EnableRepaint();
     659           0 : }
     660             : 
     661           0 : void ScCsvGrid::MoveCursorRel( ScMoveMode eDir )
     662             : {
     663           0 :     if( GetFocusColumn() != CSV_COLUMN_INVALID )
     664             :     {
     665           0 :         switch( eDir )
     666             :         {
     667             :             case MOVE_FIRST:
     668           0 :                 MoveCursor( 0 );
     669           0 :             break;
     670             :             case MOVE_LAST:
     671           0 :                 MoveCursor( GetColumnCount() - 1 );
     672           0 :             break;
     673             :             case MOVE_PREV:
     674           0 :                 if( GetFocusColumn() > 0 )
     675           0 :                     MoveCursor( GetFocusColumn() - 1 );
     676           0 :             break;
     677             :             case MOVE_NEXT:
     678           0 :                 if( GetFocusColumn() < GetColumnCount() - 1 )
     679           0 :                     MoveCursor( GetFocusColumn() + 1 );
     680           0 :             break;
     681             :             default:
     682             :             {
     683             :                 // added to avoid warnings
     684             :             }
     685             :         }
     686             :     }
     687           0 : }
     688             : 
     689           0 : void ScCsvGrid::ImplClearSelection()
     690             : {
     691           0 :     ::std::for_each( maColStates.begin(), maColStates.end(), Func_Select( false ) );
     692           0 :     ImplDrawGridDev();
     693           0 : }
     694             : 
     695           0 : void ScCsvGrid::DoSelectAction( sal_uInt32 nColIndex, sal_uInt16 nModifier )
     696             : {
     697           0 :     if( !(nModifier & KEY_MOD1) )
     698           0 :         ImplClearSelection();
     699           0 :     if( nModifier & KEY_SHIFT )             // SHIFT always expands
     700           0 :         SelectRange( mnRecentSelCol, nColIndex );
     701           0 :     else if( !(nModifier & KEY_MOD1) )      // no SHIFT/CTRL always selects 1 column
     702           0 :         Select( nColIndex );
     703           0 :     else if( IsTracking() )                 // CTRL in tracking does not toggle
     704           0 :         Select( nColIndex, mbMTSelecting );
     705             :     else                                    // CTRL only toggles
     706           0 :         ToggleSelect( nColIndex );
     707           0 :     Execute( CSVCMD_MOVEGRIDCURSOR, GetColumnPos( nColIndex ) );
     708           0 : }
     709             : 
     710             : // cell contents --------------------------------------------------------------
     711             : 
     712           0 : void ScCsvGrid::ImplSetTextLineSep(
     713             :         sal_Int32 nLine, const OUString& rTextLine,
     714             :         const OUString& rSepChars, sal_Unicode cTextSep, bool bMergeSep )
     715             : {
     716           0 :     if( nLine < GetFirstVisLine() ) return;
     717             : 
     718           0 :     sal_uInt32 nLineIx = nLine - GetFirstVisLine();
     719           0 :     while( maTexts.size() <= nLineIx )
     720           0 :         maTexts.push_back( StringVec() );
     721           0 :     StringVec& rStrVec = maTexts[ nLineIx ];
     722           0 :     rStrVec.clear();
     723             : 
     724             :     // scan for separators
     725           0 :     OUString aCellText;
     726           0 :     const sal_Unicode* pSepChars = rSepChars.getStr();
     727           0 :     const sal_Unicode* pChar = rTextLine.getStr();
     728           0 :     sal_uInt32 nColIx = 0;
     729             : 
     730           0 :     while( *pChar && (nColIx < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT)) )
     731             :     {
     732             :         // scan for next cell text
     733           0 :         bool bIsQuoted = false;
     734           0 :         bool bOverflowCell = false;
     735             :         pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText,
     736           0 :                 cTextSep, pSepChars, bMergeSep, bIsQuoted, bOverflowCell );
     737             :         /* TODO: signal overflow somewhere in UI */
     738             : 
     739             :         // update column width
     740           0 :         sal_Int32 nWidth = std::max( CSV_MINCOLWIDTH, aCellText.getLength() + 1 );
     741           0 :         if( IsValidColumn( nColIx ) )
     742             :         {
     743             :             // expand existing column
     744           0 :             sal_Int32 nDiff = nWidth - GetColumnWidth( nColIx );
     745           0 :             if( nDiff > 0 )
     746             :             {
     747           0 :                 Execute( CSVCMD_SETPOSCOUNT, GetPosCount() + nDiff );
     748           0 :                 for( sal_uInt32 nSplitIx = GetColumnCount() - 1; nSplitIx > nColIx; --nSplitIx )
     749             :                 {
     750           0 :                     sal_Int32 nPos = maSplits[ nSplitIx ];
     751           0 :                     maSplits.Remove( nPos );
     752           0 :                     maSplits.Insert( nPos + nDiff );
     753             :                 }
     754             :             }
     755             :         }
     756             :         else
     757             :         {
     758             :             // append new column
     759           0 :             sal_Int32 nLastPos = GetPosCount();
     760           0 :             Execute( CSVCMD_SETPOSCOUNT, nLastPos + nWidth );
     761           0 :             ImplInsertSplit( nLastPos );
     762             :         }
     763             : 
     764           0 :         if( aCellText.getLength() <= CSV_MAXSTRLEN )
     765           0 :             rStrVec.push_back( aCellText );
     766             :         else
     767           0 :             rStrVec.push_back( aCellText.copy( 0, CSV_MAXSTRLEN ) );
     768           0 :         ++nColIx;
     769             :     }
     770           0 :     InvalidateGfx();
     771             : }
     772             : 
     773           0 : void ScCsvGrid::ImplSetTextLineFix( sal_Int32 nLine, const OUString& rTextLine )
     774             : {
     775           0 :     if( nLine < GetFirstVisLine() ) return;
     776             : 
     777           0 :     sal_Int32 nChars = rTextLine.getLength();
     778           0 :     if( nChars > GetPosCount() )
     779           0 :         Execute( CSVCMD_SETPOSCOUNT, nChars );
     780             : 
     781           0 :     sal_uInt32 nLineIx = nLine - GetFirstVisLine();
     782           0 :     while( maTexts.size() <= nLineIx )
     783           0 :         maTexts.push_back( StringVec() );
     784             : 
     785           0 :     StringVec& rStrVec = maTexts[ nLineIx ];
     786           0 :     rStrVec.clear();
     787           0 :     sal_uInt32 nColCount = GetColumnCount();
     788           0 :     sal_Int32 nStrLen = rTextLine.getLength();
     789           0 :     sal_Int32 nStrIx = 0;
     790           0 :     for( sal_uInt32 nColIx = 0; (nColIx < nColCount) && (nStrIx < nStrLen); ++nColIx )
     791             :     {
     792           0 :         sal_Int32 nColWidth = GetColumnWidth( nColIx );
     793           0 :         sal_Int32 nLen = std::min( std::min( nColWidth, static_cast<sal_Int32>(CSV_MAXSTRLEN) ), nStrLen - nStrIx);
     794           0 :         rStrVec.push_back( rTextLine.copy( nStrIx, nLen ) );
     795           0 :         nStrIx = nStrIx + nColWidth;
     796             :     }
     797           0 :     InvalidateGfx();
     798             : }
     799             : 
     800           0 : const OUString& ScCsvGrid::GetCellText( sal_uInt32 nColIndex, sal_Int32 nLine ) const
     801             : {
     802           0 :     if( nLine < GetFirstVisLine() ) return EMPTY_OUSTRING;
     803             : 
     804           0 :     sal_uInt32 nLineIx = nLine - GetFirstVisLine();
     805           0 :     if( nLineIx >= maTexts.size() ) return EMPTY_OUSTRING;
     806             : 
     807           0 :     const StringVec& rStrVec = maTexts[ nLineIx ];
     808           0 :     if( nColIndex >= rStrVec.size() ) return EMPTY_OUSTRING;
     809             : 
     810           0 :     return rStrVec[ nColIndex ];
     811             : }
     812             : 
     813             : // event handling -------------------------------------------------------------
     814             : 
     815           0 : void ScCsvGrid::Resize()
     816             : {
     817           0 :     ScCsvControl::Resize();
     818           0 :     InitSizeData();
     819           0 :     Execute( CSVCMD_UPDATECELLTEXTS );
     820           0 : }
     821             : 
     822           0 : void ScCsvGrid::GetFocus()
     823             : {
     824           0 :     ScCsvControl::GetFocus();
     825           0 :     Execute( CSVCMD_MOVEGRIDCURSOR, GetNoScrollCol( GetGridCursorPos() ) );
     826           0 :     Repaint();
     827           0 : }
     828             : 
     829           0 : void ScCsvGrid::LoseFocus()
     830             : {
     831           0 :     ScCsvControl::LoseFocus();
     832           0 :     Repaint();
     833           0 : }
     834             : 
     835           0 : void ScCsvGrid::MouseButtonDown( const MouseEvent& rMEvt )
     836             : {
     837           0 :     DisableRepaint();
     838           0 :     if( !HasFocus() )
     839           0 :         GrabFocus();
     840             : 
     841           0 :     Point aPos( rMEvt.GetPosPixel() );
     842           0 :     sal_uInt32 nColIx = GetColumnFromX( aPos.X() );
     843             : 
     844           0 :     if( rMEvt.IsLeft() )
     845             :     {
     846           0 :         if( (GetFirstX() > aPos.X()) || (aPos.X() > GetLastX()) )   // in header column
     847             :         {
     848           0 :             if( aPos.Y() <= GetHdrHeight() )
     849           0 :                 SelectAll();
     850             :         }
     851           0 :         else if( IsValidColumn( nColIx ) )
     852             :         {
     853           0 :             DoSelectAction( nColIx, rMEvt.GetModifier() );
     854           0 :             mnMTCurrCol = nColIx;
     855           0 :             mbMTSelecting = IsSelected( nColIx );
     856           0 :             StartTracking( STARTTRACK_BUTTONREPEAT );
     857             :         }
     858             :     }
     859           0 :     EnableRepaint();
     860           0 : }
     861             : 
     862           0 : void ScCsvGrid::Tracking( const TrackingEvent& rTEvt )
     863             : {
     864           0 :     if( rTEvt.IsTrackingEnded() || rTEvt.IsTrackingRepeat() )
     865             :     {
     866           0 :         DisableRepaint();
     867           0 :         const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
     868             : 
     869           0 :         sal_Int32 nPos = (rMEvt.GetPosPixel().X() - GetFirstX()) / GetCharWidth() + GetFirstVisPos();
     870             :         // on mouse tracking: keep position valid
     871           0 :         nPos = std::max( std::min( nPos, GetPosCount() - sal_Int32( 1 ) ), sal_Int32( 0 ) );
     872           0 :         Execute( CSVCMD_MAKEPOSVISIBLE, nPos );
     873             : 
     874           0 :         sal_uInt32 nColIx = GetColumnFromPos( nPos );
     875           0 :         if( mnMTCurrCol != nColIx )
     876             :         {
     877           0 :             DoSelectAction( nColIx, rMEvt.GetModifier() );
     878           0 :             mnMTCurrCol = nColIx;
     879             :         }
     880           0 :         EnableRepaint();
     881             :     }
     882           0 : }
     883             : 
     884           0 : void ScCsvGrid::KeyInput( const KeyEvent& rKEvt )
     885             : {
     886           0 :     const vcl::KeyCode& rKCode = rKEvt.GetKeyCode();
     887           0 :     sal_uInt16 nCode = rKCode.GetCode();
     888           0 :     bool bShift = rKCode.IsShift();
     889           0 :     bool bMod1 = rKCode.IsMod1();
     890             : 
     891           0 :     if( !rKCode.IsMod2() )
     892             :     {
     893           0 :         ScMoveMode eHDir = GetHorzDirection( nCode, !bMod1 );
     894           0 :         ScMoveMode eVDir = GetVertDirection( nCode, bMod1 );
     895             : 
     896           0 :         if( eHDir != MOVE_NONE )
     897             :         {
     898           0 :             DisableRepaint();
     899           0 :             MoveCursorRel( eHDir );
     900           0 :             if( !bMod1 )
     901           0 :                 ImplClearSelection();
     902           0 :             if( bShift )
     903           0 :                 SelectRange( mnRecentSelCol, GetFocusColumn() );
     904           0 :             else if( !bMod1 )
     905           0 :                 Select( GetFocusColumn() );
     906           0 :             EnableRepaint();
     907             :         }
     908           0 :         else if( eVDir != MOVE_NONE )
     909           0 :             ScrollVertRel( eVDir );
     910           0 :         else if( nCode == KEY_SPACE )
     911             :         {
     912           0 :             if( !bMod1 )
     913           0 :                 ImplClearSelection();
     914           0 :             if( bShift )
     915           0 :                 SelectRange( mnRecentSelCol, GetFocusColumn() );
     916           0 :             else if( bMod1 )
     917           0 :                 ToggleSelect( GetFocusColumn() );
     918             :             else
     919           0 :                 Select( GetFocusColumn() );
     920             :         }
     921           0 :         else if( !bShift && bMod1 )
     922             :         {
     923           0 :             if( nCode == KEY_A )
     924           0 :                 SelectAll();
     925           0 :             else if( (KEY_1 <= nCode) && (nCode <= KEY_9) )
     926             :             {
     927           0 :                 sal_uInt32 nType = nCode - KEY_1;
     928           0 :                 if( nType < maTypeNames.size() )
     929           0 :                     Execute( CSVCMD_SETCOLUMNTYPE, nType );
     930             :             }
     931             :         }
     932             :     }
     933             : 
     934           0 :     if( rKCode.GetGroup() != KEYGROUP_CURSOR )
     935           0 :         ScCsvControl::KeyInput( rKEvt );
     936           0 : }
     937             : 
     938           0 : void ScCsvGrid::Command( const CommandEvent& rCEvt )
     939             : {
     940           0 :     switch( rCEvt.GetCommand() )
     941             :     {
     942             :         case COMMAND_CONTEXTMENU:
     943             :         {
     944           0 :             if( rCEvt.IsMouseEvent() )
     945             :             {
     946           0 :                 Point aPos( rCEvt.GetMousePosPixel() );
     947           0 :                 sal_uInt32 nColIx = GetColumnFromX( aPos.X() );
     948           0 :                 if( IsValidColumn( nColIx ) && (GetFirstX() <= aPos.X()) && (aPos.X() <= GetLastX()) )
     949             :                 {
     950           0 :                     if( !IsSelected( nColIx ) )
     951           0 :                         DoSelectAction( nColIx, 0 );    // focus & select
     952           0 :                     ExecutePopup( aPos );
     953             :                 }
     954             :             }
     955             :             else
     956             :             {
     957           0 :                 sal_uInt32 nColIx = GetFocusColumn();
     958           0 :                 if( !IsSelected( nColIx ) )
     959           0 :                     Select( nColIx );
     960           0 :                 sal_Int32 nX1 = std::max( GetColumnX( nColIx ), GetFirstX() );
     961           0 :                 sal_Int32 nX2 = std::min( GetColumnX( nColIx + 1 ), GetWidth() );
     962           0 :                 ExecutePopup( Point( (nX1 + nX2) / 2, GetHeight() / 2 ) );
     963             :             }
     964             :         }
     965           0 :         break;
     966             :         case COMMAND_WHEEL:
     967             :         {
     968           0 :             Point aPoint;
     969           0 :             Rectangle aRect( aPoint, maWinSize );
     970           0 :             if( aRect.IsInside( rCEvt.GetMousePosPixel() ) )
     971             :             {
     972           0 :                 const CommandWheelData* pData = rCEvt.GetWheelData();
     973           0 :                 if( pData && (pData->GetMode() == CommandWheelMode::SCROLL) && !pData->IsHorz() )
     974           0 :                     Execute( CSVCMD_SETLINEOFFSET, GetFirstVisLine() - pData->GetNotchDelta() );
     975             :             }
     976             :         }
     977           0 :         break;
     978             :         default:
     979           0 :             ScCsvControl::Command( rCEvt );
     980             :     }
     981           0 : }
     982             : 
     983           0 : void ScCsvGrid::DataChanged( const DataChangedEvent& rDCEvt )
     984             : {
     985           0 :     if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
     986             :     {
     987           0 :         InitColors();
     988           0 :         InitFonts();
     989           0 :         UpdateLayoutData();
     990           0 :         Execute( CSVCMD_UPDATECELLTEXTS );
     991             :     }
     992           0 :     ScCsvControl::DataChanged( rDCEvt );
     993           0 : }
     994             : 
     995           0 : void ScCsvGrid::ConfigurationChanged( utl::ConfigurationBroadcaster*, sal_uInt32 )
     996             : {
     997           0 :     InitColors();
     998           0 :     Repaint();
     999           0 : }
    1000             : 
    1001             : // painting -------------------------------------------------------------------
    1002             : 
    1003           0 : void ScCsvGrid::Paint( const Rectangle& )
    1004             : {
    1005           0 :     Repaint();
    1006           0 : }
    1007             : 
    1008           0 : void ScCsvGrid::ImplRedraw()
    1009             : {
    1010           0 :     if( IsVisible() )
    1011             :     {
    1012           0 :         if( !IsValidGfx() )
    1013             :         {
    1014           0 :             ValidateGfx();
    1015           0 :             ImplDrawBackgrDev();
    1016           0 :             ImplDrawGridDev();
    1017             :         }
    1018           0 :         DrawOutDev( Point(), maWinSize, Point(), maWinSize, maGridDev );
    1019           0 :         ImplDrawTrackingRect( GetFocusColumn() );
    1020             :     }
    1021           0 : }
    1022             : 
    1023           0 : EditEngine* ScCsvGrid::GetEditEngine()
    1024             : {
    1025           0 :     return mpEditEngine.get();
    1026             : }
    1027             : 
    1028           0 : void ScCsvGrid::ImplSetColumnClipRegion( OutputDevice& rOutDev, sal_uInt32 nColIndex )
    1029             : {
    1030             :     rOutDev.SetClipRegion( vcl::Region( Rectangle(
    1031           0 :         std::max( GetColumnX( nColIndex ), GetFirstX() ) + 1, 0,
    1032           0 :         std::min( GetColumnX( nColIndex + 1 ), GetLastX() ), GetHeight() - 1 ) ) );
    1033           0 : }
    1034             : 
    1035           0 : void ScCsvGrid::ImplDrawColumnHeader( OutputDevice& rOutDev, sal_uInt32 nColIndex, Color aFillColor )
    1036             : {
    1037           0 :     sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
    1038           0 :     sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
    1039           0 :     sal_Int32 nHdrHt = GetHdrHeight();
    1040             : 
    1041           0 :     rOutDev.SetLineColor();
    1042           0 :     rOutDev.SetFillColor( aFillColor );
    1043           0 :     rOutDev.DrawRect( Rectangle( nX1, 0, nX2, nHdrHt ) );
    1044             : 
    1045           0 :     rOutDev.SetFont( maHeaderFont );
    1046           0 :     rOutDev.SetTextColor( maHeaderTextColor );
    1047           0 :     rOutDev.SetTextFillColor();
    1048           0 :     rOutDev.DrawText( Point( nX1 + 1, 0 ), GetColumnTypeName( nColIndex ) );
    1049             : 
    1050           0 :     rOutDev.SetLineColor( maHeaderGridColor );
    1051           0 :     rOutDev.DrawLine( Point( nX1, nHdrHt ), Point( nX2, nHdrHt ) );
    1052           0 :     rOutDev.DrawLine( Point( nX2, 0 ), Point( nX2, nHdrHt ) );
    1053           0 : }
    1054             : 
    1055           0 : void ScCsvGrid::ImplDrawCellText( const Point& rPos, const OUString& rText )
    1056             : {
    1057           0 :     OUString aPlainText( rText );
    1058           0 :     aPlainText = aPlainText.replaceAll( "\t", " " );
    1059           0 :     aPlainText = aPlainText.replaceAll( "\n", " " );
    1060           0 :     mpEditEngine->SetPaperSize( maEdEngSize );
    1061             : 
    1062             :     /*  #i60296# If string contains mixed script types, the space character
    1063             :         U+0020 may be drawn with a wrong width (from non-fixed-width Asian or
    1064             :         Complex font). Now we draw every non-space portion separately. */
    1065           0 :     sal_Int32 nTokenCount = comphelper::string::getTokenCount(aPlainText, ' ');
    1066           0 :     sal_Int32 nCharIxInt = 0;
    1067           0 :     for( sal_Int32 nToken = 0; nToken < nTokenCount; ++nToken )
    1068             :     {
    1069           0 :         sal_Int32 nBeginIx = nCharIxInt;
    1070           0 :         OUString aToken = aPlainText.getToken( 0, ' ', nCharIxInt );
    1071           0 :         if( !aToken.isEmpty() )
    1072             :         {
    1073           0 :             sal_Int32 nX = rPos.X() + GetCharWidth() * nBeginIx;
    1074           0 :             mpEditEngine->SetText( aToken );
    1075           0 :             mpEditEngine->Draw( &maBackgrDev, Point( nX, rPos.Y() ) );
    1076             :         }
    1077           0 :     }
    1078             : 
    1079           0 :     sal_Int32 nCharIx = 0;
    1080           0 :     while( (nCharIx = rText.indexOf( '\t', nCharIx )) != -1 )
    1081             :     {
    1082           0 :         sal_Int32 nX1 = rPos.X() + GetCharWidth() * nCharIx;
    1083           0 :         sal_Int32 nX2 = nX1 + GetCharWidth() - 2;
    1084           0 :         sal_Int32 nY = rPos.Y() + GetLineHeight() / 2;
    1085           0 :         Color aColor( maTextColor );
    1086           0 :         maBackgrDev.SetLineColor( aColor );
    1087           0 :         maBackgrDev.DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
    1088           0 :         maBackgrDev.DrawLine( Point( nX2 - 2, nY - 2 ), Point( nX2, nY ) );
    1089           0 :         maBackgrDev.DrawLine( Point( nX2 - 2, nY + 2 ), Point( nX2, nY ) );
    1090           0 :         ++nCharIx;
    1091             :     }
    1092           0 :     nCharIx = 0;
    1093           0 :     while( (nCharIx = rText.indexOf( '\n', nCharIx )) != -1 )
    1094             :     {
    1095           0 :         sal_Int32 nX1 = rPos.X() + GetCharWidth() * nCharIx;
    1096           0 :         sal_Int32 nX2 = nX1 + GetCharWidth() - 2;
    1097           0 :         sal_Int32 nY = rPos.Y() + GetLineHeight() / 2;
    1098           0 :         Color aColor( maTextColor );
    1099           0 :         maBackgrDev.SetLineColor( aColor );
    1100           0 :         maBackgrDev.DrawLine( Point( nX1, nY ), Point( nX2, nY ) );
    1101           0 :         maBackgrDev.DrawLine( Point( nX1 + 2, nY - 2 ), Point( nX1, nY ) );
    1102           0 :         maBackgrDev.DrawLine( Point( nX1 + 2, nY + 2 ), Point( nX1, nY ) );
    1103           0 :         maBackgrDev.DrawLine( Point( nX2, nY - 2 ), Point( nX2, nY ) );
    1104           0 :         ++nCharIx;
    1105           0 :     }
    1106           0 : }
    1107             : 
    1108           0 : void ScCsvGrid::ImplDrawFirstLineSep( bool bSet )
    1109             : {
    1110           0 :     if( IsVisibleLine( mnFirstImpLine ) && (mnFirstImpLine != GetFirstVisLine() ) )
    1111             :     {
    1112           0 :         sal_Int32 nY = GetY( mnFirstImpLine );
    1113           0 :         sal_Int32 nX = std::min( GetColumnX( GetLastVisColumn() + 1 ), GetLastX() );
    1114           0 :         maBackgrDev.SetLineColor( bSet ? maGridPBColor : maGridColor );
    1115           0 :         maBackgrDev.DrawLine( Point( GetFirstX() + 1, nY ), Point( nX, nY ) );
    1116             :     }
    1117           0 : }
    1118             : 
    1119           0 : void ScCsvGrid::ImplDrawColumnBackgr( sal_uInt32 nColIndex )
    1120             : {
    1121           0 :     if( !IsVisibleColumn( nColIndex ) )
    1122           0 :         return;
    1123             : 
    1124           0 :     ImplSetColumnClipRegion( maBackgrDev, nColIndex );
    1125             : 
    1126             :     // grid
    1127           0 :     maBackgrDev.SetLineColor();
    1128           0 :     maBackgrDev.SetFillColor( maBackColor );
    1129           0 :     sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
    1130           0 :     sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
    1131           0 :     sal_Int32 nY2 = GetY( GetLastVisLine() + 1 );
    1132           0 :     sal_Int32 nHdrHt = GetHdrHeight();
    1133           0 :     Rectangle aRect( nX1, nHdrHt, nX2, nY2 );
    1134           0 :     maBackgrDev.DrawRect( aRect );
    1135           0 :     maBackgrDev.SetLineColor( maGridColor );
    1136           0 :     maBackgrDev.DrawGrid( aRect, Size( 1, GetLineHeight() ), GRID_HORZLINES );
    1137           0 :     maBackgrDev.DrawLine( Point( nX2, nHdrHt ), Point( nX2, nY2 ) );
    1138           0 :     ImplDrawFirstLineSep( true );
    1139             : 
    1140             :     // cell texts
    1141           0 :     mpEditEngine->SetDefaultItem( SvxColorItem( maTextColor, EE_CHAR_COLOR ) );
    1142           0 :     size_t nLineCount = ::std::min( static_cast< size_t >( GetLastVisLine() - GetFirstVisLine() + 1 ), maTexts.size() );
    1143             :     // #i67432# cut string to avoid edit engine performance problems with very large strings
    1144           0 :     sal_Int32 nFirstVisPos = ::std::max( GetColumnPos( nColIndex ), GetFirstVisPos() );
    1145           0 :     sal_Int32 nLastVisPos = ::std::min( GetColumnPos( nColIndex + 1 ), GetLastVisPos() );
    1146           0 :     sal_Int32 nStrPos = nFirstVisPos - GetColumnPos( nColIndex );
    1147           0 :     sal_Int32 nStrLen = nLastVisPos - nFirstVisPos + 1;
    1148           0 :     sal_Int32 nStrX = GetX( nFirstVisPos );
    1149           0 :     for( size_t nLine = 0; nLine < nLineCount; ++nLine )
    1150             :     {
    1151           0 :         StringVec& rStrVec = maTexts[ nLine ];
    1152           0 :         if( (nColIndex < rStrVec.size()) && (rStrVec[ nColIndex ].getLength() > nStrPos) )
    1153             :         {
    1154           0 :             const OUString& rStr = rStrVec[ nColIndex ];
    1155           0 :             OUString aText = rStr.copy( nStrPos, ::std::min( nStrLen, rStr.getLength() - nStrPos) );
    1156           0 :             ImplDrawCellText( Point( nStrX, GetY( GetFirstVisLine() + nLine ) ), aText );
    1157             :         }
    1158             :     }
    1159             : 
    1160             :     // header
    1161           0 :     ImplDrawColumnHeader( maBackgrDev, nColIndex, maHeaderBackColor );
    1162             : 
    1163           0 :     maBackgrDev.SetClipRegion();
    1164             : }
    1165             : 
    1166           0 : void ScCsvGrid::ImplDrawRowHeaders()
    1167             : {
    1168           0 :     maBackgrDev.SetLineColor();
    1169           0 :     maBackgrDev.SetFillColor( maAppBackColor );
    1170           0 :     Point aPoint( GetHdrX(), 0 );
    1171           0 :     Rectangle aRect( aPoint, Size( GetHdrWidth() + 1, GetHeight() ) );
    1172           0 :     maBackgrDev.DrawRect( aRect );
    1173             : 
    1174           0 :     maBackgrDev.SetFillColor( maHeaderBackColor );
    1175           0 :     aRect.Bottom() = GetY( GetLastVisLine() + 1 );
    1176           0 :     maBackgrDev.DrawRect( aRect );
    1177             : 
    1178             :     // line numbers
    1179           0 :     maBackgrDev.SetFont( maHeaderFont );
    1180           0 :     maBackgrDev.SetTextColor( maHeaderTextColor );
    1181           0 :     maBackgrDev.SetTextFillColor();
    1182           0 :     sal_Int32 nLastLine = GetLastVisLine();
    1183           0 :     for( sal_Int32 nLine = GetFirstVisLine(); nLine <= nLastLine; ++nLine )
    1184             :     {
    1185           0 :         OUString aText( OUString::number( nLine + 1 ) );
    1186           0 :         sal_Int32 nX = GetHdrX() + (GetHdrWidth() - maBackgrDev.GetTextWidth( aText )) / 2;
    1187           0 :         maBackgrDev.DrawText( Point( nX, GetY( nLine ) ), aText );
    1188           0 :     }
    1189             : 
    1190             :     // grid
    1191           0 :     maBackgrDev.SetLineColor( maHeaderGridColor );
    1192           0 :     if( IsRTL() )
    1193             :     {
    1194           0 :         maBackgrDev.DrawLine( Point( 0, 0 ), Point( 0, GetHeight() - 1 ) );
    1195           0 :         maBackgrDev.DrawLine( aRect.TopLeft(), aRect.BottomLeft() );
    1196             :     }
    1197             :     else
    1198           0 :         maBackgrDev.DrawLine( aRect.TopRight(), aRect.BottomRight() );
    1199           0 :     aRect.Top() = GetHdrHeight();
    1200           0 :     maBackgrDev.DrawGrid( aRect, Size( 1, GetLineHeight() ), GRID_HORZLINES );
    1201           0 : }
    1202             : 
    1203           0 : void ScCsvGrid::ImplDrawBackgrDev()
    1204             : {
    1205           0 :     maBackgrDev.SetLineColor();
    1206           0 :     maBackgrDev.SetFillColor( maAppBackColor );
    1207             :     maBackgrDev.DrawRect( Rectangle(
    1208           0 :         Point( GetFirstX() + 1, 0 ), Size( GetWidth() - GetHdrWidth(), GetHeight() ) ) );
    1209             : 
    1210           0 :     sal_uInt32 nLastCol = GetLastVisColumn();
    1211           0 :     if (nLastCol == CSV_COLUMN_INVALID)
    1212           0 :         return;
    1213           0 :     for( sal_uInt32 nColIx = GetFirstVisColumn(); nColIx <= nLastCol; ++nColIx )
    1214           0 :         ImplDrawColumnBackgr( nColIx );
    1215             : 
    1216           0 :     ImplDrawRowHeaders();
    1217             : }
    1218             : 
    1219           0 : void ScCsvGrid::ImplDrawColumnSelection( sal_uInt32 nColIndex )
    1220             : {
    1221           0 :     ImplInvertCursor( GetRulerCursorPos() );
    1222           0 :     ImplSetColumnClipRegion( maGridDev, nColIndex );
    1223           0 :     maGridDev.DrawOutDev( Point(), maWinSize, Point(), maWinSize, maBackgrDev );
    1224             : 
    1225           0 :     if( IsSelected( nColIndex ) )
    1226             :     {
    1227           0 :         sal_Int32 nX1 = GetColumnX( nColIndex ) + 1;
    1228           0 :         sal_Int32 nX2 = GetColumnX( nColIndex + 1 );
    1229             : 
    1230             :         // header
    1231           0 :         Rectangle aRect( nX1, 0, nX2, GetHdrHeight() );
    1232           0 :         maGridDev.SetLineColor();
    1233           0 :         if( maHeaderBackColor.IsDark() )
    1234             :             // redraw with light gray background in dark mode
    1235           0 :             ImplDrawColumnHeader( maGridDev, nColIndex, COL_LIGHTGRAY );
    1236             :         else
    1237             :         {
    1238             :             // use transparent active color
    1239           0 :             maGridDev.SetFillColor( maSelectColor );
    1240           0 :             maGridDev.DrawTransparent( tools::PolyPolygon( Polygon( aRect ) ), CSV_HDR_TRANSPARENCY );
    1241             :         }
    1242             : 
    1243             :         // column selection
    1244           0 :         aRect = Rectangle( nX1, GetHdrHeight() + 1, nX2, GetY( GetLastVisLine() + 1 ) - 1 );
    1245           0 :         ImplInvertRect( maGridDev, aRect );
    1246             :     }
    1247             : 
    1248           0 :     maGridDev.SetClipRegion();
    1249           0 :     ImplInvertCursor( GetRulerCursorPos() );
    1250           0 : }
    1251             : 
    1252           0 : void ScCsvGrid::ImplDrawGridDev()
    1253             : {
    1254           0 :     maGridDev.DrawOutDev( Point(), maWinSize, Point(), maWinSize, maBackgrDev );
    1255           0 :     sal_uInt32 nLastCol = GetLastVisColumn();
    1256           0 :     if (nLastCol == CSV_COLUMN_INVALID)
    1257           0 :         return;
    1258           0 :     for( sal_uInt32 nColIx = GetFirstVisColumn(); nColIx <= nLastCol; ++nColIx )
    1259           0 :         ImplDrawColumnSelection( nColIx );
    1260             : }
    1261             : 
    1262           0 : void ScCsvGrid::ImplDrawColumn( sal_uInt32 nColIndex )
    1263             : {
    1264           0 :     ImplDrawColumnBackgr( nColIndex );
    1265           0 :     ImplDrawColumnSelection( nColIndex );
    1266           0 : }
    1267             : 
    1268           0 : void ScCsvGrid::ImplDrawHorzScrolled( sal_Int32 nOldPos )
    1269             : {
    1270           0 :     sal_Int32 nPos = GetFirstVisPos();
    1271           0 :     if( !IsValidGfx() || (nPos == nOldPos) )
    1272           0 :         return;
    1273           0 :     if( std::abs( nPos - nOldPos ) > GetVisPosCount() / 2 )
    1274             :     {
    1275           0 :         ImplDrawBackgrDev();
    1276           0 :         ImplDrawGridDev();
    1277           0 :         return;
    1278             :     }
    1279             : 
    1280           0 :     Point aSrc, aDest;
    1281             :     sal_uInt32 nFirstColIx, nLastColIx;
    1282           0 :     if( nPos < nOldPos )
    1283             :     {
    1284           0 :         aSrc = Point( GetFirstX() + 1, 0 );
    1285           0 :         aDest = Point( GetFirstX() + GetCharWidth() * (nOldPos - nPos) + 1, 0 );
    1286           0 :         nFirstColIx = GetColumnFromPos( nPos );
    1287           0 :         nLastColIx = GetColumnFromPos( nOldPos );
    1288             :     }
    1289             :     else
    1290             :     {
    1291           0 :         aSrc = Point( GetFirstX() + GetCharWidth() * (nPos - nOldPos) + 1, 0 );
    1292           0 :         aDest = Point( GetFirstX() + 1, 0 );
    1293           0 :         nFirstColIx = GetColumnFromPos( std::min( nOldPos + GetVisPosCount(), GetPosCount() ) - 1 );
    1294           0 :         nLastColIx = GetColumnFromPos( std::min( nPos + GetVisPosCount(), GetPosCount() ) - 1 );
    1295             :     }
    1296             : 
    1297           0 :     ImplInvertCursor( GetRulerCursorPos() + (nPos - nOldPos) );
    1298           0 :     Rectangle aRectangle( GetFirstX(), 0, GetLastX(), GetHeight() - 1 );
    1299           0 :     vcl::Region aClipReg( aRectangle );
    1300           0 :     maBackgrDev.SetClipRegion( aClipReg );
    1301           0 :     maBackgrDev.CopyArea( aDest, aSrc, maWinSize );
    1302           0 :     maBackgrDev.SetClipRegion();
    1303           0 :     maGridDev.SetClipRegion( aClipReg );
    1304           0 :     maGridDev.CopyArea( aDest, aSrc, maWinSize );
    1305           0 :     maGridDev.SetClipRegion();
    1306           0 :     ImplInvertCursor( GetRulerCursorPos() );
    1307             : 
    1308           0 :     for( sal_uInt32 nColIx = nFirstColIx; nColIx <= nLastColIx; ++nColIx )
    1309           0 :         ImplDrawColumn( nColIx );
    1310             : 
    1311           0 :     sal_Int32 nLastX = GetX( GetPosCount() ) + 1;
    1312           0 :     if( nLastX <= GetLastX() )
    1313             :     {
    1314           0 :         Rectangle aRect( nLastX, 0, GetLastX(), GetHeight() - 1 );
    1315           0 :         maBackgrDev.SetLineColor();
    1316           0 :         maBackgrDev.SetFillColor( maAppBackColor );
    1317           0 :         maBackgrDev.DrawRect( aRect );
    1318           0 :         maGridDev.SetLineColor();
    1319           0 :         maGridDev.SetFillColor( maAppBackColor );
    1320           0 :         maGridDev.DrawRect( aRect );
    1321           0 :     }
    1322             : }
    1323             : 
    1324           0 : void ScCsvGrid::ImplInvertCursor( sal_Int32 nPos )
    1325             : {
    1326           0 :     if( IsVisibleSplitPos( nPos ) )
    1327             :     {
    1328           0 :         sal_Int32 nX = GetX( nPos ) - 1;
    1329           0 :         Rectangle aRect( Point( nX, 0 ), Size( 3, GetHdrHeight() ) );
    1330           0 :         ImplInvertRect( maGridDev, aRect );
    1331           0 :         aRect.Top() = GetHdrHeight() + 1;
    1332           0 :         aRect.Bottom() = GetY( GetLastVisLine() + 1 );
    1333           0 :         ImplInvertRect( maGridDev, aRect );
    1334             :     }
    1335           0 : }
    1336             : 
    1337           0 : void ScCsvGrid::ImplDrawTrackingRect( sal_uInt32 nColIndex )
    1338             : {
    1339           0 :     if( HasFocus() && IsVisibleColumn( nColIndex ) )
    1340             :     {
    1341           0 :         sal_Int32 nX1 = std::max( GetColumnX( nColIndex ), GetFirstX() ) + 1;
    1342           0 :         sal_Int32 nX2 = std::min( GetColumnX( nColIndex + 1 ) - sal_Int32( 1 ), GetLastX() );
    1343           0 :         sal_Int32 nY2 = std::min( GetY( GetLastVisLine() + 1 ), GetHeight() ) - 1;
    1344           0 :         InvertTracking( Rectangle( nX1, 0, nX2, nY2 ), SHOWTRACK_SMALL | SHOWTRACK_WINDOW );
    1345             :     }
    1346           0 : }
    1347             : 
    1348             : // accessibility ==============================================================
    1349             : 
    1350           0 : ScAccessibleCsvControl* ScCsvGrid::ImplCreateAccessible()
    1351             : {
    1352           0 :     std::unique_ptr<ScAccessibleCsvControl> pControl(new ScAccessibleCsvGrid( *this ));
    1353           0 :     pControl->Init();
    1354           0 :     return pControl.release();
    1355         228 : }
    1356             : 
    1357             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10