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