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