1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sc.hxx" 30 31 32 // ============================================================================ 33 #include "csvcontrol.hxx" 34 #include <tools/debug.hxx> 35 #include <vcl/svapp.hxx> 36 #include "AccessibleCsvControl.hxx" 37 38 39 // ============================================================================ 40 41 ScCsvLayoutData::ScCsvLayoutData() : 42 mnPosCount( 1 ), 43 mnPosOffset( 0 ), 44 mnWinWidth( 1 ), 45 mnHdrWidth( 0 ), 46 mnCharWidth( 1 ), 47 mnLineCount( 1 ), 48 mnLineOffset( 0 ), 49 mnWinHeight( 1 ), 50 mnHdrHeight( 0 ), 51 mnLineHeight( 1 ), 52 mnPosCursor( CSV_POS_INVALID ), 53 mnColCursor( 0 ), 54 mnNoRepaint( 0 ), 55 mbAppRTL( !!Application::GetSettings().GetLayoutRTL() ) 56 { 57 } 58 59 ScCsvDiff ScCsvLayoutData::GetDiff( const ScCsvLayoutData& rData ) const 60 { 61 ScCsvDiff nRet = CSV_DIFF_EQUAL; 62 if( mnPosCount != rData.mnPosCount ) nRet |= CSV_DIFF_POSCOUNT; 63 if( mnPosOffset != rData.mnPosOffset ) nRet |= CSV_DIFF_POSOFFSET; 64 if( mnHdrWidth != rData.mnHdrWidth ) nRet |= CSV_DIFF_HDRWIDTH; 65 if( mnCharWidth != rData.mnCharWidth ) nRet |= CSV_DIFF_CHARWIDTH; 66 if( mnLineCount != rData.mnLineCount ) nRet |= CSV_DIFF_LINECOUNT; 67 if( mnLineOffset != rData.mnLineOffset ) nRet |= CSV_DIFF_LINEOFFSET; 68 if( mnHdrHeight != rData.mnHdrHeight ) nRet |= CSV_DIFF_HDRHEIGHT; 69 if( mnLineHeight != rData.mnLineHeight ) nRet |= CSV_DIFF_LINEHEIGHT; 70 if( mnPosCursor != rData.mnPosCursor ) nRet |= CSV_DIFF_RULERCURSOR; 71 if( mnColCursor != rData.mnColCursor ) nRet |= CSV_DIFF_GRIDCURSOR; 72 return nRet; 73 } 74 75 76 // ============================================================================ 77 78 ScCsvControl::ScCsvControl( ScCsvControl& rParent ) : 79 Control( &rParent, WB_TABSTOP | WB_NODIALOGCONTROL ), 80 mrData( rParent.GetLayoutData() ), 81 mpAccessible( NULL ), 82 mbValidGfx( false ) 83 { 84 } 85 86 ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, WinBits nStyle ) : 87 Control( pParent, nStyle ), 88 mrData( rData ), 89 mpAccessible( NULL ), 90 mbValidGfx( false ) 91 { 92 } 93 94 ScCsvControl::ScCsvControl( Window* pParent, const ScCsvLayoutData& rData, const ResId& rResId ) : 95 Control( pParent, rResId ), 96 mrData( rData ), 97 mpAccessible( NULL ), 98 mbValidGfx( false ) 99 { 100 } 101 102 ScCsvControl::~ScCsvControl() 103 { 104 if( mpAccessible ) 105 mpAccessible->dispose(); 106 } 107 108 109 // event handling ------------------------------------------------------------- 110 111 void ScCsvControl::GetFocus() 112 { 113 Control::GetFocus(); 114 AccSendFocusEvent( true ); 115 } 116 117 void ScCsvControl::LoseFocus() 118 { 119 Control::LoseFocus(); 120 AccSendFocusEvent( false ); 121 } 122 123 void ScCsvControl::AccSendFocusEvent( bool bFocused ) 124 { 125 if( mpAccessible ) 126 mpAccessible->SendFocusEvent( bFocused ); 127 } 128 129 void ScCsvControl::AccSendCaretEvent() 130 { 131 if( mpAccessible ) 132 mpAccessible->SendCaretEvent(); 133 } 134 135 void ScCsvControl::AccSendVisibleEvent() 136 { 137 if( mpAccessible ) 138 mpAccessible->SendVisibleEvent(); 139 } 140 141 void ScCsvControl::AccSendSelectionEvent() 142 { 143 if( mpAccessible ) 144 mpAccessible->SendSelectionEvent(); 145 } 146 147 void ScCsvControl::AccSendTableUpdateEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn, bool bAllRows ) 148 { 149 if( mpAccessible ) 150 mpAccessible->SendTableUpdateEvent( nFirstColumn, nLastColumn, bAllRows ); 151 } 152 153 void ScCsvControl::AccSendInsertColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ) 154 { 155 if( mpAccessible ) 156 mpAccessible->SendInsertColumnEvent( nFirstColumn, nLastColumn ); 157 } 158 159 void ScCsvControl::AccSendRemoveColumnEvent( sal_uInt32 nFirstColumn, sal_uInt32 nLastColumn ) 160 { 161 if( mpAccessible ) 162 mpAccessible->SendRemoveColumnEvent( nFirstColumn, nLastColumn ); 163 } 164 165 166 // repaint helpers ------------------------------------------------------------ 167 168 void ScCsvControl::Repaint( bool bInvalidate ) 169 { 170 if( bInvalidate ) 171 InvalidateGfx(); 172 if( !IsNoRepaint() ) 173 Execute( CSVCMD_REPAINT ); 174 } 175 176 void ScCsvControl::DisableRepaint() 177 { 178 ++mrData.mnNoRepaint; 179 } 180 181 void ScCsvControl::EnableRepaint( bool bInvalidate ) 182 { 183 DBG_ASSERT( IsNoRepaint(), "ScCsvControl::EnableRepaint - invalid call" ); 184 --mrData.mnNoRepaint; 185 Repaint( bInvalidate ); 186 } 187 188 189 // command handling ----------------------------------------------------------- 190 191 void ScCsvControl::Execute( ScCsvCmdType eType, sal_Int32 nParam1, sal_Int32 nParam2 ) 192 { 193 maCmd.Set( eType, nParam1, nParam2 ); 194 maCmdHdl.Call( this ); 195 } 196 197 198 // layout helpers ------------------------------------------------------------- 199 200 sal_Int32 ScCsvControl::GetVisPosCount() const 201 { 202 return (mrData.mnWinWidth - GetHdrWidth()) / GetCharWidth(); 203 } 204 205 sal_Int32 ScCsvControl::GetMaxPosOffset() const 206 { 207 return Max( GetPosCount() - GetVisPosCount() + 2L, 0L ); 208 } 209 210 bool ScCsvControl::IsValidSplitPos( sal_Int32 nPos ) const 211 { 212 return (0 < nPos) && (nPos < GetPosCount() ); 213 } 214 215 bool ScCsvControl::IsVisibleSplitPos( sal_Int32 nPos ) const 216 { 217 return IsValidSplitPos( nPos ) && (GetFirstVisPos() <= nPos) && (nPos <= GetLastVisPos()); 218 } 219 220 sal_Int32 ScCsvControl::GetHdrX() const 221 { 222 return IsRTL() ? (mrData.mnWinWidth - GetHdrWidth()) : 0; 223 } 224 225 sal_Int32 ScCsvControl::GetFirstX() const 226 { 227 return IsRTL() ? 0 : GetHdrWidth(); 228 } 229 230 sal_Int32 ScCsvControl::GetLastX() const 231 { 232 return mrData.mnWinWidth - (IsRTL() ? GetHdrWidth() : 0) - 1; 233 } 234 235 sal_Int32 ScCsvControl::GetX( sal_Int32 nPos ) const 236 { 237 return GetFirstX() + (nPos - GetFirstVisPos()) * GetCharWidth(); 238 } 239 240 sal_Int32 ScCsvControl::GetPosFromX( sal_Int32 nX ) const 241 { 242 return (nX - GetFirstX() + GetCharWidth() / 2) / GetCharWidth() + GetFirstVisPos(); 243 } 244 245 sal_Int32 ScCsvControl::GetVisLineCount() const 246 { 247 return (mrData.mnWinHeight - GetHdrHeight() - 2) / GetLineHeight() + 1; 248 } 249 250 sal_Int32 ScCsvControl::GetLastVisLine() const 251 { 252 return Min( GetFirstVisLine() + GetVisLineCount(), GetLineCount() ) - 1; 253 } 254 255 sal_Int32 ScCsvControl::GetMaxLineOffset() const 256 { 257 return Max( GetLineCount() - GetVisLineCount() + 1L, 0L ); 258 } 259 260 bool ScCsvControl::IsValidLine( sal_Int32 nLine ) const 261 { 262 return (0 <= nLine) && (nLine < GetLineCount()); 263 } 264 265 bool ScCsvControl::IsVisibleLine( sal_Int32 nLine ) const 266 { 267 return IsValidLine( nLine ) && (GetFirstVisLine() <= nLine) && (nLine <= GetLastVisLine()); 268 } 269 270 sal_Int32 ScCsvControl::GetY( sal_Int32 nLine ) const 271 { 272 return GetHdrHeight() + (nLine - GetFirstVisLine()) * GetLineHeight(); 273 } 274 275 sal_Int32 ScCsvControl::GetLineFromY( sal_Int32 nY ) const 276 { 277 return (nY - GetHdrHeight()) / GetLineHeight() + GetFirstVisLine(); 278 } 279 280 281 // static helpers ------------------------------------------------------------- 282 283 void ScCsvControl::ImplInvertRect( OutputDevice& rOutDev, const Rectangle& rRect ) 284 { 285 rOutDev.Push( PUSH_LINECOLOR | PUSH_FILLCOLOR | PUSH_RASTEROP ); 286 rOutDev.SetLineColor( Color( COL_BLACK ) ); 287 rOutDev.SetFillColor( Color( COL_BLACK ) ); 288 rOutDev.SetRasterOp( ROP_INVERT ); 289 rOutDev.DrawRect( rRect ); 290 rOutDev.Pop(); 291 } 292 293 ScMoveMode ScCsvControl::GetHorzDirection( sal_uInt16 nCode, bool bHomeEnd ) 294 { 295 switch( nCode ) 296 { 297 case KEY_LEFT: return MOVE_PREV; 298 case KEY_RIGHT: return MOVE_NEXT; 299 } 300 if( bHomeEnd ) switch( nCode ) 301 { 302 case KEY_HOME: return MOVE_FIRST; 303 case KEY_END: return MOVE_LAST; 304 } 305 return MOVE_NONE; 306 } 307 308 ScMoveMode ScCsvControl::GetVertDirection( sal_uInt16 nCode, bool bHomeEnd ) 309 { 310 switch( nCode ) 311 { 312 case KEY_UP: return MOVE_PREV; 313 case KEY_DOWN: return MOVE_NEXT; 314 case KEY_PAGEUP: return MOVE_PREVPAGE; 315 case KEY_PAGEDOWN: return MOVE_NEXTPAGE; 316 } 317 if( bHomeEnd ) switch( nCode ) 318 { 319 case KEY_HOME: return MOVE_FIRST; 320 case KEY_END: return MOVE_LAST; 321 } 322 return MOVE_NONE; 323 } 324 325 326 // accessibility -------------------------------------------------------------- 327 328 ScCsvControl::XAccessibleRef ScCsvControl::CreateAccessible() 329 { 330 mpAccessible = ImplCreateAccessible(); 331 mxAccessible = mpAccessible; 332 return mxAccessible; 333 } 334 335 336 // ============================================================================ 337 338