1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: csvgrid.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
35 // ============================================================================
36 #include "csvgrid.hxx"
39 #include <svtools/colorcfg.hxx>
40 #include <svtools/smplhint.hxx>
41 #include <tools/poly.hxx>
43 #include "asciiopt.hxx"
45 #include "AccessibleCsvControl.hxx"
47 // *** edit engine ***
48 #include "scitems.hxx"
49 #include <svx/eeitem.hxx>
52 #include <svx/colritem.hxx>
53 #include <svx/fhgtitem.hxx>
54 #include <svx/fontitem.hxx>
55 #include <svtools/itemset.hxx>
56 #include "editutil.hxx"
57 // *** edit engine ***
60 // ============================================================================
65 inline Func_SetType( sal_Int32 nType
) : mnType( nType
) {}
66 inline void operator()( ScCsvColState
& rState
) { rState
.mnType
= mnType
; }
72 inline Func_Select( bool bSelect
) : mbSelect( bSelect
) {}
73 inline void operator()( ScCsvColState
& rState
) { rState
.Select( mbSelect
); }
77 // ============================================================================
79 ScCsvGrid::ScCsvGrid( ScCsvControl
& rParent
) :
80 ScCsvControl( rParent
),
81 mrColorConfig( SC_MOD()->GetColorConfig() ),
82 mpEditEngine( new ScEditEngineDefaulter( EditEngine::CreatePool(), TRUE
) ),
83 maHeaderFont( GetFont() ),
87 mnRecentSelCol( CSV_COLUMN_INVALID
)
89 mpEditEngine
->SetRefDevice( &maBackgrDev
);
90 mpEditEngine
->SetRefMapMode( MapMode( MAP_PIXEL
) );
91 maEdEngSize
= mpEditEngine
->GetPaperSize();
93 maPopup
.SetMenuFlags( maPopup
.GetMenuFlags() | MENU_FLAG_NOAUTOMNEMONICS
);
95 EnableRTL( false ); // #107812# RTL
99 StartListening( mrColorConfig
);
102 ScCsvGrid::~ScCsvGrid()
104 EndListening( mrColorConfig
);
108 // common grid handling -------------------------------------------------------
110 void ScCsvGrid::UpdateLayoutData()
113 SetFont( maMonoFont
);
114 Execute( CSVCMD_SETCHARWIDTH
, GetTextWidth( String( 'X' ) ) );
115 Execute( CSVCMD_SETLINEHEIGHT
, GetTextHeight() + 1 );
116 SetFont( maHeaderFont
);
117 Execute( CSVCMD_SETHDRHEIGHT
, GetTextHeight() + 1 );
122 void ScCsvGrid::UpdateOffsetX()
124 sal_Int32 nLastLine
= GetLastVisLine() + 1;
125 sal_Int32 nDigits
= 2;
126 while( nLastLine
/= 10 ) ++nDigits
;
127 nDigits
= Max( nDigits
, sal_Int32( 3 ) );
128 Execute( CSVCMD_SETHDRWIDTH
, GetTextWidth( String( '0' ) ) * nDigits
);
131 void ScCsvGrid::ApplyLayout( const ScCsvLayoutData
& rOldData
)
133 ScCsvDiff nDiff
= GetLayoutData().GetDiff( rOldData
);
134 if( nDiff
== CSV_DIFF_EQUAL
) return;
138 if( nDiff
& CSV_DIFF_RULERCURSOR
)
140 ImplInvertCursor( rOldData
.mnPosCursor
);
141 ImplInvertCursor( GetRulerCursorPos() );
144 if( nDiff
& CSV_DIFF_POSCOUNT
)
146 if( GetPosCount() < rOldData
.mnPosCount
)
149 maSplits
.RemoveRange( GetPosCount(), rOldData
.mnPosCount
);
152 maSplits
.Remove( rOldData
.mnPosCount
);
153 maSplits
.Insert( GetPosCount() );
154 maColStates
.resize( maSplits
.Count() - 1 );
157 if( nDiff
& CSV_DIFF_LINEOFFSET
)
159 Execute( CSVCMD_UPDATECELLTEXTS
);
163 ScCsvDiff nHVDiff
= nDiff
& (CSV_DIFF_HORIZONTAL
| CSV_DIFF_VERTICAL
);
164 if( nHVDiff
== CSV_DIFF_POSOFFSET
)
165 ImplDrawHorzScrolled( rOldData
.mnPosOffset
);
166 else if( nHVDiff
!= CSV_DIFF_EQUAL
)
171 if( nDiff
& (CSV_DIFF_POSOFFSET
| CSV_DIFF_LINEOFFSET
) )
172 AccSendVisibleEvent();
175 void ScCsvGrid::SetFirstImportedLine( sal_Int32 nLine
)
177 ImplDrawFirstLineSep( false );
178 mnFirstImpLine
= nLine
;
179 ImplDrawFirstLineSep( true );
184 sal_Int32
ScCsvGrid::GetNoScrollCol( sal_Int32 nPos
) const
186 sal_Int32 nNewPos
= nPos
;
187 if( nNewPos
!= CSV_POS_INVALID
)
189 if( nNewPos
< GetFirstVisPos() + CSV_SCROLL_DIST
)
191 sal_Int32 nScroll
= (GetFirstVisPos() > 0) ? CSV_SCROLL_DIST
: 0;
192 nNewPos
= GetFirstVisPos() + nScroll
;
194 else if( nNewPos
> GetLastVisPos() - CSV_SCROLL_DIST
- 1L )
196 sal_Int32 nScroll
= (GetFirstVisPos() < GetMaxPosOffset()) ? CSV_SCROLL_DIST
: 0;
197 nNewPos
= GetLastVisPos() - nScroll
- 1;
203 void ScCsvGrid::InitColors()
205 maBackColor
.SetColor( static_cast< sal_uInt32
>( mrColorConfig
.GetColorValue( ::svtools::DOCCOLOR
).nColor
) );
206 maGridColor
.SetColor( static_cast< sal_uInt32
>( mrColorConfig
.GetColorValue( ::svtools::CALCGRID
).nColor
) );
207 maGridPBColor
.SetColor( static_cast< sal_uInt32
>( mrColorConfig
.GetColorValue( ::svtools::CALCPAGEBREAK
).nColor
) );
208 maAppBackColor
.SetColor( static_cast< sal_uInt32
>( mrColorConfig
.GetColorValue( ::svtools::APPBACKGROUND
).nColor
) );
209 maTextColor
.SetColor( static_cast< sal_uInt32
>( mrColorConfig
.GetColorValue( ::svtools::FONTCOLOR
).nColor
) );
211 const StyleSettings
& rSett
= GetSettings().GetStyleSettings();
212 maHeaderBackColor
= rSett
.GetFaceColor();
213 maHeaderGridColor
= rSett
.GetDarkShadowColor();
214 maHeaderTextColor
= rSett
.GetButtonTextColor();
215 maSelectColor
= rSett
.GetActiveColor();
220 void ScCsvGrid::InitFonts()
222 maMonoFont
= OutputDevice::GetDefaultFont( DEFAULTFONT_FIXED
, LANGUAGE_ENGLISH_US
, 0 );
223 maMonoFont
.SetSize( Size( maMonoFont
.GetSize().Width(), maHeaderFont
.GetSize().Height() ) );
225 /* *** Set edit engine defaults ***
226 maMonoFont for Latin script, smaller default font for Asian and Complex script. */
229 SvxFontItem
aLatinItem( EE_CHAR_FONTINFO
);
230 SvxFontItem
aAsianItem( EE_CHAR_FONTINFO_CJK
);
231 SvxFontItem
aComplexItem( EE_CHAR_FONTINFO_CTL
);
232 ::GetDefaultFonts( aLatinItem
, aAsianItem
, aComplexItem
);
234 // create item set for defaults
235 SfxItemSet
aDefSet( mpEditEngine
->GetEmptyItemSet() );
236 EditEngine::SetFontInfoInItemSet( aDefSet
, maMonoFont
);
237 aDefSet
.Put( aAsianItem
);
238 aDefSet
.Put( aComplexItem
);
240 // set Asian/Complex font size to height of character in Latin font
241 ULONG nFontHt
= static_cast< ULONG
>( maMonoFont
.GetSize().Height() );
242 aDefSet
.Put( SvxFontHeightItem( nFontHt
, 100, EE_CHAR_FONTHEIGHT_CJK
) );
243 aDefSet
.Put( SvxFontHeightItem( nFontHt
, 100, EE_CHAR_FONTHEIGHT_CTL
) );
245 // copy other items from default font
246 const SfxPoolItem
& rWeightItem
= aDefSet
.Get( EE_CHAR_WEIGHT
);
247 aDefSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CJK
);
248 aDefSet
.Put( rWeightItem
, EE_CHAR_WEIGHT_CTL
);
249 const SfxPoolItem
& rItalicItem
= aDefSet
.Get( EE_CHAR_ITALIC
);
250 aDefSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CJK
);
251 aDefSet
.Put( rItalicItem
, EE_CHAR_ITALIC_CTL
);
252 const SfxPoolItem
& rLangItem
= aDefSet
.Get( EE_CHAR_LANGUAGE
);
253 aDefSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CJK
);
254 aDefSet
.Put( rLangItem
, EE_CHAR_LANGUAGE_CTL
);
256 mpEditEngine
->SetDefaults( aDefSet
);
260 void ScCsvGrid::InitSizeData()
262 maWinSize
= GetSizePixel();
263 maBackgrDev
.SetOutputSizePixel( maWinSize
);
264 maGridDev
.SetOutputSizePixel( maWinSize
);
269 // split handling -------------------------------------------------------------
271 void ScCsvGrid::InsertSplit( sal_Int32 nPos
)
273 if( ImplInsertSplit( nPos
) )
276 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
277 Execute( CSVCMD_UPDATECELLTEXTS
);
278 sal_uInt32 nColIx
= GetColumnFromPos( nPos
);
279 ImplDrawColumn( nColIx
- 1 );
280 ImplDrawColumn( nColIx
);
281 ValidateGfx(); // performance: do not redraw all columns
286 void ScCsvGrid::RemoveSplit( sal_Int32 nPos
)
288 if( ImplRemoveSplit( nPos
) )
291 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
292 Execute( CSVCMD_UPDATECELLTEXTS
);
293 ImplDrawColumn( GetColumnFromPos( nPos
) );
294 ValidateGfx(); // performance: do not redraw all columns
299 void ScCsvGrid::MoveSplit( sal_Int32 nPos
, sal_Int32 nNewPos
)
301 sal_uInt32 nColIx
= GetColumnFromPos( nPos
);
302 if( nColIx
!= CSV_COLUMN_INVALID
)
305 if( (GetColumnPos( nColIx
- 1 ) < nNewPos
) && (nNewPos
< GetColumnPos( nColIx
+ 1 )) )
307 // move a split in the range between 2 others -> keep selection state of both columns
308 maSplits
.Remove( nPos
);
309 maSplits
.Insert( nNewPos
);
310 Execute( CSVCMD_UPDATECELLTEXTS
);
311 ImplDrawColumn( nColIx
- 1 );
312 ImplDrawColumn( nColIx
);
313 ValidateGfx(); // performance: do not redraw all columns
314 AccSendTableUpdateEvent( nColIx
- 1, nColIx
);
318 ImplRemoveSplit( nPos
);
319 ImplInsertSplit( nNewPos
);
320 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
321 Execute( CSVCMD_UPDATECELLTEXTS
);
327 void ScCsvGrid::RemoveAllSplits()
331 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
332 Execute( CSVCMD_UPDATECELLTEXTS
);
336 void ScCsvGrid::SetSplits( const ScCsvSplits
& rSplits
)
340 sal_uInt32 nCount
= rSplits
.Count();
341 for( sal_uInt32 nIx
= 0; nIx
< nCount
; ++nIx
)
342 maSplits
.Insert( rSplits
[ nIx
] );
344 maColStates
.resize( maSplits
.Count() - 1 );
345 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
346 Execute( CSVCMD_UPDATECELLTEXTS
);
350 bool ScCsvGrid::ImplInsertSplit( sal_Int32 nPos
)
352 sal_uInt32 nColIx
= GetColumnFromPos( nPos
);
353 bool bRet
= (nColIx
< GetColumnCount()) && maSplits
.Insert( nPos
);
356 ScCsvColState
aState( GetColumnType( nColIx
) );
357 aState
.Select( IsSelected( nColIx
) && IsSelected( nColIx
+ 1 ) );
358 maColStates
.insert( maColStates
.begin() + nColIx
+ 1, aState
);
359 AccSendInsertColumnEvent( nColIx
+ 1, nColIx
+ 1 );
360 AccSendTableUpdateEvent( nColIx
, nColIx
);
365 bool ScCsvGrid::ImplRemoveSplit( sal_Int32 nPos
)
367 bool bRet
= maSplits
.Remove( nPos
);
370 sal_uInt32 nColIx
= GetColumnFromPos( nPos
);
371 bool bSel
= IsSelected( nColIx
) || IsSelected( nColIx
+ 1 );
372 maColStates
.erase( maColStates
.begin() + nColIx
+ 1 );
373 maColStates
[ nColIx
].Select( bSel
);
374 AccSendRemoveColumnEvent( nColIx
+ 1, nColIx
+ 1 );
375 AccSendTableUpdateEvent( nColIx
, nColIx
);
380 void ScCsvGrid::ImplClearSplits()
382 sal_uInt32 nColumns
= GetColumnCount();
384 maSplits
.Insert( 0 );
385 maSplits
.Insert( GetPosCount() );
386 maColStates
.resize( 1 );
388 AccSendRemoveColumnEvent( 1, nColumns
- 1 );
391 // columns/column types -------------------------------------------------------
393 sal_uInt32
ScCsvGrid::GetFirstVisColumn() const
395 return GetColumnFromPos( GetFirstVisPos() );
398 sal_uInt32
ScCsvGrid::GetLastVisColumn() const
400 return GetColumnFromPos( Min( GetLastVisPos(), GetPosCount() ) - 1 );
403 bool ScCsvGrid::IsValidColumn( sal_uInt32 nColIndex
) const
405 return nColIndex
< GetColumnCount();
408 bool ScCsvGrid::IsVisibleColumn( sal_uInt32 nColIndex
) const
410 return IsValidColumn( nColIndex
) &&
411 (GetColumnPos( nColIndex
) < GetLastVisPos()) &&
412 (GetFirstVisPos() < GetColumnPos( nColIndex
+ 1 ));
415 sal_Int32
ScCsvGrid::GetColumnX( sal_uInt32 nColIndex
) const
417 return GetX( GetColumnPos( nColIndex
) );
420 sal_uInt32
ScCsvGrid::GetColumnFromX( sal_Int32 nX
) const
422 sal_Int32 nPos
= (nX
- GetFirstX()) / GetCharWidth() + GetFirstVisPos();
423 return ((GetFirstVisPos() <= nPos
) && (nPos
<= GetLastVisPos())) ?
424 GetColumnFromPos( nPos
) : CSV_COLUMN_INVALID
;
427 sal_uInt32
ScCsvGrid::GetColumnFromPos( sal_Int32 nPos
) const
429 return maSplits
.UpperBound( nPos
);
432 sal_Int32
ScCsvGrid::GetColumnWidth( sal_uInt32 nColIndex
) const
434 return IsValidColumn( nColIndex
) ? (GetColumnPos( nColIndex
+ 1 ) - GetColumnPos( nColIndex
)) : 0;
437 void ScCsvGrid::SetColumnStates( const ScCsvColStateVec
& rStates
)
439 maColStates
= rStates
;
440 maColStates
.resize( maSplits
.Count() - 1 );
441 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
442 AccSendTableUpdateEvent( 0, GetColumnCount(), false );
443 AccSendSelectionEvent();
446 sal_Int32
ScCsvGrid::GetColumnType( sal_uInt32 nColIndex
) const
448 return IsValidColumn( nColIndex
) ? maColStates
[ nColIndex
].mnType
: CSV_TYPE_NOSELECTION
;
451 void ScCsvGrid::SetColumnType( sal_uInt32 nColIndex
, sal_Int32 nColType
)
453 if( IsValidColumn( nColIndex
) )
455 maColStates
[ nColIndex
].mnType
= nColType
;
456 AccSendTableUpdateEvent( nColIndex
, nColIndex
, false );
460 sal_Int32
ScCsvGrid::GetSelColumnType() const
462 sal_uInt32 nColIx
= GetFirstSelected();
463 if( nColIx
== CSV_COLUMN_INVALID
)
464 return CSV_TYPE_NOSELECTION
;
466 sal_Int32 nType
= GetColumnType( nColIx
);
467 while( (nColIx
!= CSV_COLUMN_INVALID
) && (nType
!= CSV_TYPE_MULTI
) )
469 if( nType
!= GetColumnType( nColIx
) )
470 nType
= CSV_TYPE_MULTI
;
471 nColIx
= GetNextSelected( nColIx
);
476 void ScCsvGrid::SetSelColumnType( sal_Int32 nType
)
478 if( (nType
!= CSV_TYPE_MULTI
) && (nType
!= CSV_TYPE_NOSELECTION
) )
480 for( sal_uInt32 nColIx
= GetFirstSelected(); nColIx
!= CSV_COLUMN_INVALID
; nColIx
= GetNextSelected( nColIx
) )
481 SetColumnType( nColIx
, nType
);
483 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
487 void ScCsvGrid::SetTypeNames( const StringVec
& rTypeNames
)
489 DBG_ASSERT( !rTypeNames
.empty(), "ScCsvGrid::SetTypeNames - vector is empty" );
490 maTypeNames
= rTypeNames
;
494 sal_uInt32 nCount
= maTypeNames
.size();
497 for( nIx
= 0, nItemId
= 1; nIx
< nCount
; ++nIx
, ++nItemId
)
498 maPopup
.InsertItem( nItemId
, maTypeNames
[ nIx
] );
500 ::std::for_each( maColStates
.begin(), maColStates
.end(), Func_SetType( CSV_TYPE_DEFAULT
) );
503 const String
& ScCsvGrid::GetColumnTypeName( sal_uInt32 nColIndex
) const
505 sal_uInt32 nTypeIx
= static_cast< sal_uInt32
>( GetColumnType( nColIndex
) );
506 return (nTypeIx
< maTypeNames
.size()) ? maTypeNames
[ nTypeIx
] : EMPTY_STRING
;
509 sal_uInt8
lcl_GetExtColumnType( sal_Int32 nIntType
)
511 static sal_uInt8 pExtTypes
[] =
512 { SC_COL_STANDARD
, SC_COL_TEXT
, SC_COL_DMY
, SC_COL_MDY
, SC_COL_YMD
, SC_COL_ENGLISH
, SC_COL_SKIP
};
513 static sal_Int32 nExtTypeCount
= sizeof( pExtTypes
) / sizeof( *pExtTypes
);
514 return pExtTypes
[ ((0 <= nIntType
) && (nIntType
< nExtTypeCount
)) ? nIntType
: 0 ];
517 void ScCsvGrid::FillColumnDataSep( ScAsciiOptions
& rOptions
) const
519 sal_uInt32 nCount
= GetColumnCount();
520 ScCsvExpDataVec aDataVec
;
522 for( sal_uInt32 nColIx
= 0; nColIx
< nCount
; ++nColIx
)
524 if( GetColumnType( nColIx
) != CSV_TYPE_DEFAULT
)
525 // 1-based column index
526 aDataVec
.push_back( ScCsvExpData(
527 static_cast< xub_StrLen
>( nColIx
+ 1 ),
528 lcl_GetExtColumnType( GetColumnType( nColIx
) ) ) );
530 rOptions
.SetColumnInfo( aDataVec
);
533 void ScCsvGrid::FillColumnDataFix( ScAsciiOptions
& rOptions
) const
535 sal_uInt32 nCount
= Min( GetColumnCount(), static_cast<sal_uInt32
>(MAXCOLCOUNT
) );
536 ScCsvExpDataVec
aDataVec( nCount
+ 1 );
538 for( sal_uInt32 nColIx
= 0; nColIx
< nCount
; ++nColIx
)
540 ScCsvExpData
& rData
= aDataVec
[ nColIx
];
541 rData
.mnIndex
= static_cast< xub_StrLen
>(
542 Min( static_cast< sal_Int32
>( STRING_MAXLEN
), GetColumnPos( nColIx
) ) );
543 rData
.mnType
= lcl_GetExtColumnType( GetColumnType( nColIx
) );
545 aDataVec
[ nCount
].mnIndex
= STRING_MAXLEN
;
546 aDataVec
[ nCount
].mnType
= SC_COL_SKIP
;
547 rOptions
.SetColumnInfo( aDataVec
);
550 void ScCsvGrid::ScrollVertRel( ScMoveMode eDir
)
552 sal_Int32 nLine
= GetFirstVisLine();
555 case MOVE_PREV
: --nLine
; break;
556 case MOVE_NEXT
: ++nLine
; break;
557 case MOVE_FIRST
: nLine
= 0; break;
558 case MOVE_LAST
: nLine
= GetMaxLineOffset(); break;
559 case MOVE_PREVPAGE
: nLine
-= GetVisLineCount() - 2; break;
560 case MOVE_NEXTPAGE
: nLine
+= GetVisLineCount() - 2; break;
563 // added to avoid warnings
566 Execute( CSVCMD_SETLINEOFFSET
, nLine
);
569 void ScCsvGrid::ExecutePopup( const Point
& rPos
)
571 sal_uInt16 nItemId
= maPopup
.Execute( this, rPos
);
572 if( nItemId
) // 0 = cancelled
573 Execute( CSVCMD_SETCOLUMNTYPE
, maPopup
.GetItemPos( nItemId
) );
577 // selection handling ---------------------------------------------------------
579 bool ScCsvGrid::IsSelected( sal_uInt32 nColIndex
) const
581 return IsValidColumn( nColIndex
) && maColStates
[ nColIndex
].IsSelected();
584 sal_uInt32
ScCsvGrid::GetFirstSelected() const
586 return IsSelected( 0 ) ? 0 : GetNextSelected( 0 );
589 sal_uInt32
ScCsvGrid::GetNextSelected( sal_uInt32 nFromIndex
) const
591 sal_uInt32 nColCount
= GetColumnCount();
592 for( sal_uInt32 nColIx
= nFromIndex
+ 1; nColIx
< nColCount
; ++nColIx
)
593 if( IsSelected( nColIx
) )
595 return CSV_COLUMN_INVALID
;
598 void ScCsvGrid::Select( sal_uInt32 nColIndex
, bool bSelect
)
600 if( IsValidColumn( nColIndex
) )
602 maColStates
[ nColIndex
].Select( bSelect
);
603 ImplDrawColumnSelection( nColIndex
);
605 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
607 mnRecentSelCol
= nColIndex
;
608 AccSendSelectionEvent();
612 void ScCsvGrid::ToggleSelect( sal_uInt32 nColIndex
)
614 Select( nColIndex
, !IsSelected( nColIndex
) );
617 void ScCsvGrid::SelectRange( sal_uInt32 nColIndex1
, sal_uInt32 nColIndex2
, bool bSelect
)
619 if( nColIndex1
== CSV_COLUMN_INVALID
)
620 Select( nColIndex2
);
621 else if( nColIndex2
== CSV_COLUMN_INVALID
)
622 Select( nColIndex1
);
623 else if( nColIndex1
> nColIndex2
)
625 SelectRange( nColIndex2
, nColIndex1
, bSelect
);
627 mnRecentSelCol
= nColIndex1
;
629 else if( IsValidColumn( nColIndex1
) && IsValidColumn( nColIndex2
) )
631 for( sal_uInt32 nColIx
= nColIndex1
; nColIx
<= nColIndex2
; ++nColIx
)
633 maColStates
[ nColIx
].Select( bSelect
);
634 ImplDrawColumnSelection( nColIx
);
637 Execute( CSVCMD_EXPORTCOLUMNTYPE
);
639 mnRecentSelCol
= nColIndex1
;
640 AccSendSelectionEvent();
644 void ScCsvGrid::SelectAll( bool bSelect
)
646 SelectRange( 0, GetColumnCount() - 1, bSelect
);
649 void ScCsvGrid::MoveCursor( sal_uInt32 nColIndex
)
652 if( IsValidColumn( nColIndex
) )
654 sal_Int32 nPosBeg
= GetColumnPos( nColIndex
);
655 sal_Int32 nPosEnd
= GetColumnPos( nColIndex
+ 1 );
656 sal_Int32 nMinPos
= Max( nPosBeg
- CSV_SCROLL_DIST
, sal_Int32( 0 ) );
657 sal_Int32 nMaxPos
= Min( nPosEnd
- GetVisPosCount() + CSV_SCROLL_DIST
+ sal_Int32( 1 ), nMinPos
);
658 if( nPosBeg
- CSV_SCROLL_DIST
+ 1 <= GetFirstVisPos() )
659 Execute( CSVCMD_SETPOSOFFSET
, nMinPos
);
660 else if( nPosEnd
+ CSV_SCROLL_DIST
>= GetLastVisPos() )
661 Execute( CSVCMD_SETPOSOFFSET
, nMaxPos
);
663 Execute( CSVCMD_MOVEGRIDCURSOR
, GetColumnPos( nColIndex
) );
667 void ScCsvGrid::MoveCursorRel( ScMoveMode eDir
)
669 if( GetFocusColumn() != CSV_COLUMN_INVALID
)
677 MoveCursor( GetColumnCount() - 1 );
680 if( GetFocusColumn() > 0 )
681 MoveCursor( GetFocusColumn() - 1 );
684 if( GetFocusColumn() < GetColumnCount() - 1 )
685 MoveCursor( GetFocusColumn() + 1 );
689 // added to avoid warnings
695 void ScCsvGrid::ImplClearSelection()
697 ::std::for_each( maColStates
.begin(), maColStates
.end(), Func_Select( false ) );
701 void ScCsvGrid::DoSelectAction( sal_uInt32 nColIndex
, sal_uInt16 nModifier
)
703 if( !(nModifier
& KEY_MOD1
) )
704 ImplClearSelection();
705 if( nModifier
& KEY_SHIFT
) // SHIFT always expands
706 SelectRange( mnRecentSelCol
, nColIndex
);
707 else if( !(nModifier
& KEY_MOD1
) ) // no SHIFT/CTRL always selects 1 column
709 else if( IsTracking() ) // CTRL in tracking does not toggle
710 Select( nColIndex
, mbMTSelecting
);
711 else // CTRL only toggles
712 ToggleSelect( nColIndex
);
713 Execute( CSVCMD_MOVEGRIDCURSOR
, GetColumnPos( nColIndex
) );
717 // cell contents --------------------------------------------------------------
719 void ScCsvGrid::ImplSetTextLineSep(
720 sal_Int32 nLine
, const String
& rTextLine
,
721 const String
& rSepChars
, sal_Unicode cTextSep
, bool bMergeSep
)
723 if( nLine
< GetFirstVisLine() ) return;
725 sal_uInt32 nLineIx
= nLine
- GetFirstVisLine();
726 while( maTexts
.size() <= nLineIx
)
727 maTexts
.push_back( StringVec() );
728 StringVec
& rStrVec
= maTexts
[ nLineIx
];
731 // scan for separators
733 const sal_Unicode
* pSepChars
= rSepChars
.GetBuffer();
734 const sal_Unicode
* pChar
= rTextLine
.GetBuffer();
735 sal_uInt32 nColIx
= 0;
737 while( *pChar
&& (nColIx
< sal::static_int_cast
<sal_uInt32
>(CSV_MAXCOLCOUNT
)) )
739 // scan for next cell text
740 bool bIsQuoted
= false;
741 pChar
= ScImportExport::ScanNextFieldFromString( pChar
, aCellText
, cTextSep
, pSepChars
, bMergeSep
, bIsQuoted
);
743 // update column width
744 sal_Int32 nWidth
= Max( CSV_MINCOLWIDTH
, aCellText
.Len() + sal_Int32( 1 ) );
745 if( IsValidColumn( nColIx
) )
747 // expand existing column
748 sal_Int32 nDiff
= nWidth
- GetColumnWidth( nColIx
);
751 Execute( CSVCMD_SETPOSCOUNT
, GetPosCount() + nDiff
);
752 for( sal_uInt32 nSplitIx
= GetColumnCount() - 1; nSplitIx
> nColIx
; --nSplitIx
)
754 sal_Int32 nPos
= maSplits
[ nSplitIx
];
755 maSplits
.Remove( nPos
);
756 maSplits
.Insert( nPos
+ nDiff
);
763 sal_Int32 nLastPos
= GetPosCount();
764 Execute( CSVCMD_SETPOSCOUNT
, nLastPos
+ nWidth
);
765 ImplInsertSplit( nLastPos
);
768 if( aCellText
.Len() <= CSV_MAXSTRLEN
)
769 rStrVec
.push_back( aCellText
);
771 rStrVec
.push_back( aCellText
.Copy( 0, CSV_MAXSTRLEN
) );
777 void ScCsvGrid::ImplSetTextLineFix( sal_Int32 nLine
, const String
& rTextLine
)
779 if( nLine
< GetFirstVisLine() ) return;
781 sal_Int32 nChars
= rTextLine
.Len();
782 if( nChars
> GetPosCount() )
783 Execute( CSVCMD_SETPOSCOUNT
, nChars
);
785 sal_uInt32 nLineIx
= nLine
- GetFirstVisLine();
786 while( maTexts
.size() <= nLineIx
)
787 maTexts
.push_back( StringVec() );
789 StringVec
& rStrVec
= maTexts
[ nLineIx
];
791 sal_uInt32 nColCount
= GetColumnCount();
792 xub_StrLen nStrLen
= rTextLine
.Len();
793 xub_StrLen nStrIx
= 0;
794 for( sal_uInt32 nColIx
= 0; (nColIx
< nColCount
) && (nStrIx
< nStrLen
); ++nColIx
)
796 xub_StrLen nColWidth
= static_cast< xub_StrLen
>( GetColumnWidth( nColIx
) );
797 rStrVec
.push_back( rTextLine
.Copy( nStrIx
, Max( nColWidth
, CSV_MAXSTRLEN
) ) );
798 nStrIx
= sal::static_int_cast
<xub_StrLen
>( nStrIx
+ nColWidth
);
803 const String
& ScCsvGrid::GetCellText( sal_uInt32 nColIndex
, sal_Int32 nLine
) const
805 if( nLine
< GetFirstVisLine() ) return EMPTY_STRING
;
807 sal_uInt32 nLineIx
= nLine
- GetFirstVisLine();
808 if( nLineIx
>= maTexts
.size() ) return EMPTY_STRING
;
810 const StringVec
& rStrVec
= maTexts
[ nLineIx
];
811 if( nColIndex
>= rStrVec
.size() ) return EMPTY_STRING
;
813 return rStrVec
[ nColIndex
];
817 // event handling -------------------------------------------------------------
819 void ScCsvGrid::Resize()
821 ScCsvControl::Resize();
823 Execute( CSVCMD_UPDATECELLTEXTS
);
826 void ScCsvGrid::GetFocus()
828 ScCsvControl::GetFocus();
829 Execute( CSVCMD_MOVEGRIDCURSOR
, GetNoScrollCol( GetGridCursorPos() ) );
833 void ScCsvGrid::LoseFocus()
835 ScCsvControl::LoseFocus();
839 void ScCsvGrid::MouseButtonDown( const MouseEvent
& rMEvt
)
845 Point
aPos( rMEvt
.GetPosPixel() );
846 sal_uInt32 nColIx
= GetColumnFromX( aPos
.X() );
850 if( (GetFirstX() > aPos
.X()) || (aPos
.X() > GetLastX()) ) // in header column
852 if( aPos
.Y() <= GetHdrHeight() )
855 else if( IsValidColumn( nColIx
) )
857 DoSelectAction( nColIx
, rMEvt
.GetModifier() );
858 mnMTCurrCol
= nColIx
;
859 mbMTSelecting
= IsSelected( nColIx
);
860 StartTracking( STARTTRACK_BUTTONREPEAT
);
866 void ScCsvGrid::Tracking( const TrackingEvent
& rTEvt
)
868 if( rTEvt
.IsTrackingEnded() || rTEvt
.IsTrackingRepeat() )
871 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
873 sal_Int32 nPos
= (rMEvt
.GetPosPixel().X() - GetFirstX()) / GetCharWidth() + GetFirstVisPos();
874 // on mouse tracking: keep position valid
875 nPos
= Max( Min( nPos
, GetPosCount() - sal_Int32( 1 ) ), sal_Int32( 0 ) );
876 Execute( CSVCMD_MAKEPOSVISIBLE
, nPos
);
878 sal_uInt32 nColIx
= GetColumnFromPos( nPos
);
879 if( mnMTCurrCol
!= nColIx
)
881 DoSelectAction( nColIx
, rMEvt
.GetModifier() );
882 mnMTCurrCol
= nColIx
;
888 void ScCsvGrid::KeyInput( const KeyEvent
& rKEvt
)
890 const KeyCode
& rKCode
= rKEvt
.GetKeyCode();
891 sal_uInt16 nCode
= rKCode
.GetCode();
892 bool bShift
= rKCode
.IsShift() == TRUE
;
893 bool bMod1
= rKCode
.IsMod1() == TRUE
;
895 if( !rKCode
.IsMod2() )
897 ScMoveMode eHDir
= GetHorzDirection( nCode
, !bMod1
);
898 ScMoveMode eVDir
= GetVertDirection( nCode
, bMod1
);
900 if( eHDir
!= MOVE_NONE
)
903 MoveCursorRel( eHDir
);
905 ImplClearSelection();
907 SelectRange( mnRecentSelCol
, GetFocusColumn() );
909 Select( GetFocusColumn() );
912 else if( eVDir
!= MOVE_NONE
)
913 ScrollVertRel( eVDir
);
914 else if( nCode
== KEY_SPACE
)
917 ImplClearSelection();
919 SelectRange( mnRecentSelCol
, GetFocusColumn() );
921 ToggleSelect( GetFocusColumn() );
923 Select( GetFocusColumn() );
925 else if( !bShift
&& bMod1
)
929 else if( (KEY_1
<= nCode
) && (nCode
<= KEY_9
) )
931 sal_uInt32 nType
= nCode
- KEY_1
;
932 if( nType
< maTypeNames
.size() )
933 Execute( CSVCMD_SETCOLUMNTYPE
, nType
);
938 if( rKCode
.GetGroup() != KEYGROUP_CURSOR
)
939 ScCsvControl::KeyInput( rKEvt
);
942 void ScCsvGrid::Command( const CommandEvent
& rCEvt
)
944 switch( rCEvt
.GetCommand() )
946 case COMMAND_CONTEXTMENU
:
948 if( rCEvt
.IsMouseEvent() )
950 Point
aPos( rCEvt
.GetMousePosPixel() );
951 sal_uInt32 nColIx
= GetColumnFromX( aPos
.X() );
952 if( IsValidColumn( nColIx
) && (GetFirstX() <= aPos
.X()) && (aPos
.X() <= GetLastX()) )
954 if( !IsSelected( nColIx
) )
955 DoSelectAction( nColIx
, 0 ); // focus & select
956 ExecutePopup( aPos
);
961 sal_uInt32 nColIx
= GetFocusColumn();
962 if( !IsSelected( nColIx
) )
964 sal_Int32 nX1
= Max( GetColumnX( nColIx
), GetFirstX() );
965 sal_Int32 nX2
= Min( GetColumnX( nColIx
+ 1 ), GetWidth() );
966 ExecutePopup( Point( (nX1
+ nX2
) / 2, GetHeight() / 2 ) );
973 Rectangle
aRect( aPoint
, maWinSize
);
974 if( aRect
.IsInside( rCEvt
.GetMousePosPixel() ) )
976 const CommandWheelData
* pData
= rCEvt
.GetWheelData();
977 if( pData
&& (pData
->GetMode() == COMMAND_WHEEL_SCROLL
) && !pData
->IsHorz() )
978 Execute( CSVCMD_SETLINEOFFSET
, GetFirstVisLine() - pData
->GetNotchDelta() );
983 ScCsvControl::Command( rCEvt
);
987 void ScCsvGrid::DataChanged( const DataChangedEvent
& rDCEvt
)
989 if( (rDCEvt
.GetType() == DATACHANGED_SETTINGS
) && (rDCEvt
.GetFlags() & SETTINGS_STYLE
) )
994 Execute( CSVCMD_UPDATECELLTEXTS
);
996 ScCsvControl::DataChanged( rDCEvt
);
999 void ScCsvGrid::Notify( SfxBroadcaster
&, const SfxHint
& rHint
)
1001 if( rHint
.ISA( SfxSimpleHint
) &&
1002 (static_cast< const SfxSimpleHint
& >( rHint
).GetId() == SFX_HINT_COLORS_CHANGED
) )
1010 // painting -------------------------------------------------------------------
1012 void ScCsvGrid::Paint( const Rectangle
& )
1017 void ScCsvGrid::ImplRedraw()
1024 ImplDrawBackgrDev();
1027 DrawOutDev( Point(), maWinSize
, Point(), maWinSize
, maGridDev
);
1028 ImplDrawTrackingRect( GetFocusColumn() );
1032 EditEngine
* ScCsvGrid::GetEditEngine()
1034 return mpEditEngine
.get();
1037 void ScCsvGrid::ImplSetColumnClipRegion( OutputDevice
& rOutDev
, sal_uInt32 nColIndex
)
1039 rOutDev
.SetClipRegion( Region( Rectangle(
1040 Max( GetColumnX( nColIndex
), GetFirstX() ) + 1, 0,
1041 Min( GetColumnX( nColIndex
+ 1 ), GetLastX() ), GetHeight() - 1 ) ) );
1044 void ScCsvGrid::ImplDrawColumnHeader( OutputDevice
& rOutDev
, sal_uInt32 nColIndex
, Color aFillColor
)
1046 sal_Int32 nX1
= GetColumnX( nColIndex
) + 1;
1047 sal_Int32 nX2
= GetColumnX( nColIndex
+ 1 );
1048 sal_Int32 nHdrHt
= GetHdrHeight();
1050 rOutDev
.SetLineColor();
1051 rOutDev
.SetFillColor( aFillColor
);
1052 rOutDev
.DrawRect( Rectangle( nX1
, 0, nX2
, nHdrHt
) );
1054 rOutDev
.SetFont( maHeaderFont
);
1055 rOutDev
.SetTextColor( maHeaderTextColor
);
1056 rOutDev
.SetTextFillColor();
1057 rOutDev
.DrawText( Point( nX1
+ 1, 0 ), GetColumnTypeName( nColIndex
) );
1059 rOutDev
.SetLineColor( maHeaderGridColor
);
1060 rOutDev
.DrawLine( Point( nX1
, nHdrHt
), Point( nX2
, nHdrHt
) );
1061 rOutDev
.DrawLine( Point( nX2
, 0 ), Point( nX2
, nHdrHt
) );
1064 void ScCsvGrid::ImplDrawCellText( const Point
& rPos
, const String
& rText
)
1066 String
aPlainText( rText
);
1067 aPlainText
.SearchAndReplaceAll( '\t', ' ' );
1068 aPlainText
.SearchAndReplaceAll( '\n', ' ' );
1069 mpEditEngine
->SetPaperSize( maEdEngSize
);
1071 /* #i60296# If string contains mixed script types, the space character
1072 U+0020 may be drawn with a wrong width (from non-fixed-width Asian or
1073 Complex font). Now we draw every non-space portion separately. */
1074 xub_StrLen nTokenCount
= aPlainText
.GetTokenCount( ' ' );
1075 xub_StrLen nCharIx
= 0;
1076 for( xub_StrLen nToken
= 0; nToken
< nTokenCount
; ++nToken
)
1078 xub_StrLen nBeginIx
= nCharIx
;
1079 String aToken
= aPlainText
.GetToken( 0, ' ', nCharIx
);
1080 if( aToken
.Len() > 0 )
1082 sal_Int32 nX
= rPos
.X() + GetCharWidth() * nBeginIx
;
1083 mpEditEngine
->SetText( aToken
);
1084 mpEditEngine
->Draw( &maBackgrDev
, Point( nX
, rPos
.Y() ) );
1089 while( (nCharIx
= rText
.Search( '\t', nCharIx
)) != STRING_NOTFOUND
)
1091 sal_Int32 nX1
= rPos
.X() + GetCharWidth() * nCharIx
;
1092 sal_Int32 nX2
= nX1
+ GetCharWidth() - 2;
1093 sal_Int32 nY
= rPos
.Y() + GetLineHeight() / 2;
1094 Color
aColor( maTextColor
);
1095 maBackgrDev
.SetLineColor( aColor
);
1096 maBackgrDev
.DrawLine( Point( nX1
, nY
), Point( nX2
, nY
) );
1097 maBackgrDev
.DrawLine( Point( nX2
- 2, nY
- 2 ), Point( nX2
, nY
) );
1098 maBackgrDev
.DrawLine( Point( nX2
- 2, nY
+ 2 ), Point( nX2
, nY
) );
1102 while( (nCharIx
= rText
.Search( '\n', nCharIx
)) != STRING_NOTFOUND
)
1104 sal_Int32 nX1
= rPos
.X() + GetCharWidth() * nCharIx
;
1105 sal_Int32 nX2
= nX1
+ GetCharWidth() - 2;
1106 sal_Int32 nY
= rPos
.Y() + GetLineHeight() / 2;
1107 Color
aColor( maTextColor
);
1108 maBackgrDev
.SetLineColor( aColor
);
1109 maBackgrDev
.DrawLine( Point( nX1
, nY
), Point( nX2
, nY
) );
1110 maBackgrDev
.DrawLine( Point( nX1
+ 2, nY
- 2 ), Point( nX1
, nY
) );
1111 maBackgrDev
.DrawLine( Point( nX1
+ 2, nY
+ 2 ), Point( nX1
, nY
) );
1112 maBackgrDev
.DrawLine( Point( nX2
, nY
- 2 ), Point( nX2
, nY
) );
1117 void ScCsvGrid::ImplDrawFirstLineSep( bool bSet
)
1119 if( IsVisibleLine( mnFirstImpLine
) && (mnFirstImpLine
!= GetFirstVisLine() ) )
1121 sal_Int32 nY
= GetY( mnFirstImpLine
);
1122 sal_Int32 nX
= Min( GetColumnX( GetLastVisColumn() + 1 ), GetLastX() );
1123 maBackgrDev
.SetLineColor( bSet
? maGridPBColor
: maGridColor
);
1124 maBackgrDev
.DrawLine( Point( GetFirstX() + 1, nY
), Point( nX
, nY
) );
1128 void ScCsvGrid::ImplDrawColumnBackgr( sal_uInt32 nColIndex
)
1130 if( !IsVisibleColumn( nColIndex
) )
1133 ImplSetColumnClipRegion( maBackgrDev
, nColIndex
);
1136 maBackgrDev
.SetLineColor();
1137 maBackgrDev
.SetFillColor( maBackColor
);
1138 sal_Int32 nX1
= GetColumnX( nColIndex
) + 1;
1139 sal_Int32 nX2
= GetColumnX( nColIndex
+ 1 );
1140 sal_Int32 nY2
= GetY( GetLastVisLine() + 1 );
1141 sal_Int32 nHdrHt
= GetHdrHeight();
1142 Rectangle
aRect( nX1
, nHdrHt
, nX2
, nY2
);
1143 maBackgrDev
.DrawRect( aRect
);
1144 maBackgrDev
.SetLineColor( maGridColor
);
1145 maBackgrDev
.DrawGrid( aRect
, Size( 1, GetLineHeight() ), GRID_HORZLINES
);
1146 maBackgrDev
.DrawLine( Point( nX2
, nHdrHt
), Point( nX2
, nY2
) );
1147 ImplDrawFirstLineSep( true );
1150 mpEditEngine
->SetDefaultItem( SvxColorItem( maTextColor
, EE_CHAR_COLOR
) );
1151 size_t nLineCount
= ::std::min( static_cast< size_t >( GetLastVisLine() - GetFirstVisLine() + 1 ), maTexts
.size() );
1152 // #i67432# cut string to avoid edit engine performance problems with very large strings
1153 sal_Int32 nFirstVisPos
= ::std::max( GetColumnPos( nColIndex
), GetFirstVisPos() );
1154 sal_Int32 nLastVisPos
= ::std::min( GetColumnPos( nColIndex
+ 1 ), GetLastVisPos() );
1155 xub_StrLen nStrPos
= static_cast< xub_StrLen
>( nFirstVisPos
- GetColumnPos( nColIndex
) );
1156 xub_StrLen nStrLen
= static_cast< xub_StrLen
>( nLastVisPos
- nFirstVisPos
+ 1 );
1157 sal_Int32 nStrX
= GetX( nFirstVisPos
);
1158 for( size_t nLine
= 0; nLine
< nLineCount
; ++nLine
)
1160 StringVec
& rStrVec
= maTexts
[ nLine
];
1161 if( (nColIndex
< rStrVec
.size()) && (rStrVec
[ nColIndex
].Len() > nStrPos
) )
1163 String
aText( rStrVec
[ nColIndex
], nStrPos
, nStrLen
);
1164 ImplDrawCellText( Point( nStrX
, GetY( GetFirstVisLine() + nLine
) ), aText
);
1169 ImplDrawColumnHeader( maBackgrDev
, nColIndex
, maHeaderBackColor
);
1171 maBackgrDev
.SetClipRegion();
1174 void ScCsvGrid::ImplDrawRowHeaders()
1176 maBackgrDev
.SetLineColor();
1177 maBackgrDev
.SetFillColor( maAppBackColor
);
1178 Point
aPoint( GetHdrX(), 0 );
1179 Rectangle
aRect( aPoint
, Size( GetHdrWidth() + 1, GetHeight() ) );
1180 maBackgrDev
.DrawRect( aRect
);
1182 maBackgrDev
.SetFillColor( maHeaderBackColor
);
1183 aRect
.Bottom() = GetY( GetLastVisLine() + 1 );
1184 maBackgrDev
.DrawRect( aRect
);
1187 maBackgrDev
.SetFont( maHeaderFont
);
1188 maBackgrDev
.SetTextColor( maHeaderTextColor
);
1189 maBackgrDev
.SetTextFillColor();
1190 sal_Int32 nLastLine
= GetLastVisLine();
1191 for( sal_Int32 nLine
= GetFirstVisLine(); nLine
<= nLastLine
; ++nLine
)
1193 String
aText( String::CreateFromInt32( nLine
+ 1 ) );
1194 sal_Int32 nX
= GetHdrX() + (GetHdrWidth() - maBackgrDev
.GetTextWidth( aText
)) / 2;
1195 maBackgrDev
.DrawText( Point( nX
, GetY( nLine
) ), aText
);
1199 maBackgrDev
.SetLineColor( maHeaderGridColor
);
1202 maBackgrDev
.DrawLine( Point( 0, 0 ), Point( 0, GetHeight() - 1 ) );
1203 maBackgrDev
.DrawLine( aRect
.TopLeft(), aRect
.BottomLeft() );
1206 maBackgrDev
.DrawLine( aRect
.TopRight(), aRect
.BottomRight() );
1207 aRect
.Top() = GetHdrHeight();
1208 maBackgrDev
.DrawGrid( aRect
, Size( 1, GetLineHeight() ), GRID_HORZLINES
);
1211 void ScCsvGrid::ImplDrawBackgrDev()
1213 maBackgrDev
.SetLineColor();
1214 maBackgrDev
.SetFillColor( maAppBackColor
);
1215 maBackgrDev
.DrawRect( Rectangle(
1216 Point( GetFirstX() + 1, 0 ), Size( GetWidth() - GetHdrWidth(), GetHeight() ) ) );
1218 sal_uInt32 nLastCol
= GetLastVisColumn();
1219 for( sal_uInt32 nColIx
= GetFirstVisColumn(); nColIx
<= nLastCol
; ++nColIx
)
1220 ImplDrawColumnBackgr( nColIx
);
1222 ImplDrawRowHeaders();
1225 void ScCsvGrid::ImplDrawColumnSelection( sal_uInt32 nColIndex
)
1227 ImplInvertCursor( GetRulerCursorPos() );
1228 ImplSetColumnClipRegion( maGridDev
, nColIndex
);
1229 maGridDev
.DrawOutDev( Point(), maWinSize
, Point(), maWinSize
, maBackgrDev
);
1231 if( IsSelected( nColIndex
) )
1233 sal_Int32 nX1
= GetColumnX( nColIndex
) + 1;
1234 sal_Int32 nX2
= GetColumnX( nColIndex
+ 1 );
1237 Rectangle
aRect( nX1
, 0, nX2
, GetHdrHeight() );
1238 maGridDev
.SetLineColor();
1239 if( maHeaderBackColor
.IsDark() )
1240 // redraw with light gray background in dark mode
1241 ImplDrawColumnHeader( maGridDev
, nColIndex
, COL_LIGHTGRAY
);
1244 // use transparent active color
1245 maGridDev
.SetFillColor( maSelectColor
);
1246 maGridDev
.DrawTransparent( PolyPolygon( Polygon( aRect
) ), CSV_HDR_TRANSPARENCY
);
1250 aRect
= Rectangle( nX1
, GetHdrHeight() + 1, nX2
, GetY( GetLastVisLine() + 1 ) - 1 );
1251 ImplInvertRect( maGridDev
, aRect
);
1254 maGridDev
.SetClipRegion();
1255 ImplInvertCursor( GetRulerCursorPos() );
1258 void ScCsvGrid::ImplDrawGridDev()
1260 maGridDev
.DrawOutDev( Point(), maWinSize
, Point(), maWinSize
, maBackgrDev
);
1261 sal_uInt32 nLastCol
= GetLastVisColumn();
1262 for( sal_uInt32 nColIx
= GetFirstVisColumn(); nColIx
<= nLastCol
; ++nColIx
)
1263 ImplDrawColumnSelection( nColIx
);
1266 void ScCsvGrid::ImplDrawColumn( sal_uInt32 nColIndex
)
1268 ImplDrawColumnBackgr( nColIndex
);
1269 ImplDrawColumnSelection( nColIndex
);
1272 void ScCsvGrid::ImplDrawHorzScrolled( sal_Int32 nOldPos
)
1274 sal_Int32 nPos
= GetFirstVisPos();
1275 if( !IsValidGfx() || (nPos
== nOldPos
) )
1277 if( Abs( nPos
- nOldPos
) > GetVisPosCount() / 2 )
1279 ImplDrawBackgrDev();
1285 sal_uInt32 nFirstColIx
, nLastColIx
;
1286 if( nPos
< nOldPos
)
1288 aSrc
= Point( GetFirstX() + 1, 0 );
1289 aDest
= Point( GetFirstX() + GetCharWidth() * (nOldPos
- nPos
) + 1, 0 );
1290 nFirstColIx
= GetColumnFromPos( nPos
);
1291 nLastColIx
= GetColumnFromPos( nOldPos
);
1295 aSrc
= Point( GetFirstX() + GetCharWidth() * (nPos
- nOldPos
) + 1, 0 );
1296 aDest
= Point( GetFirstX() + 1, 0 );
1297 nFirstColIx
= GetColumnFromPos( Min( nOldPos
+ GetVisPosCount(), GetPosCount() ) - 1 );
1298 nLastColIx
= GetColumnFromPos( Min( nPos
+ GetVisPosCount(), GetPosCount() ) - 1 );
1301 ImplInvertCursor( GetRulerCursorPos() + (nPos
- nOldPos
) );
1302 Rectangle
aRectangle( GetFirstX(), 0, GetLastX(), GetHeight() - 1 );
1303 Region
aClipReg( aRectangle
);
1304 maBackgrDev
.SetClipRegion( aClipReg
);
1305 maBackgrDev
.CopyArea( aDest
, aSrc
, maWinSize
);
1306 maBackgrDev
.SetClipRegion();
1307 maGridDev
.SetClipRegion( aClipReg
);
1308 maGridDev
.CopyArea( aDest
, aSrc
, maWinSize
);
1309 maGridDev
.SetClipRegion();
1310 ImplInvertCursor( GetRulerCursorPos() );
1312 for( sal_uInt32 nColIx
= nFirstColIx
; nColIx
<= nLastColIx
; ++nColIx
)
1313 ImplDrawColumn( nColIx
);
1315 sal_Int32 nLastX
= GetX( GetPosCount() ) + 1;
1316 if( nLastX
<= GetLastX() )
1318 Rectangle
aRect( nLastX
, 0, GetLastX(), GetHeight() - 1 );
1319 maBackgrDev
.SetLineColor();
1320 maBackgrDev
.SetFillColor( maAppBackColor
);
1321 maBackgrDev
.DrawRect( aRect
);
1322 maGridDev
.SetLineColor();
1323 maGridDev
.SetFillColor( maAppBackColor
);
1324 maGridDev
.DrawRect( aRect
);
1328 void ScCsvGrid::ImplInvertCursor( sal_Int32 nPos
)
1330 if( IsVisibleSplitPos( nPos
) )
1332 sal_Int32 nX
= GetX( nPos
) - 1;
1333 Rectangle
aRect( Point( nX
, 0 ), Size( 3, GetHdrHeight() ) );
1334 ImplInvertRect( maGridDev
, aRect
);
1335 aRect
.Top() = GetHdrHeight() + 1;
1336 aRect
.Bottom() = GetY( GetLastVisLine() + 1 );
1337 ImplInvertRect( maGridDev
, aRect
);
1341 void ScCsvGrid::ImplDrawTrackingRect( sal_uInt32 nColIndex
)
1343 if( HasFocus() && IsVisibleColumn( nColIndex
) )
1345 sal_Int32 nX1
= Max( GetColumnX( nColIndex
), GetFirstX() ) + 1;
1346 sal_Int32 nX2
= Min( GetColumnX( nColIndex
+ 1 ) - sal_Int32( 1 ), GetLastX() );
1347 sal_Int32 nY2
= Min( GetY( GetLastVisLine() + 1 ), GetHeight() ) - 1;
1348 InvertTracking( Rectangle( nX1
, 0, nX2
, nY2
), SHOWTRACK_SMALL
| SHOWTRACK_WINDOW
);
1353 // accessibility ==============================================================
1355 ScAccessibleCsvControl
* ScCsvGrid::ImplCreateAccessible()
1357 return new ScAccessibleCsvGrid( *this );
1361 // ============================================================================