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 "csvtablebox.hxx" 30 #include <tools/debug.hxx> 31 #include <vcl/lstbox.hxx> 32 33 // ause 34 #include "editutil.hxx" 35 36 // ============================================================================ 37 38 //UNUSED2009-05 ScCsvTableBox::ScCsvTableBox( Window* pParent ) : 39 //UNUSED2009-05 ScCsvControl( pParent, maData, WB_BORDER | WB_TABSTOP | WB_DIALOGCONTROL ), 40 //UNUSED2009-05 maRuler( *this ), 41 //UNUSED2009-05 maGrid( *this ), 42 //UNUSED2009-05 maHScroll( this, WB_HORZ | WB_DRAG ), 43 //UNUSED2009-05 maVScroll( this, WB_VERT | WB_DRAG ), 44 //UNUSED2009-05 maScrollBox( this ) 45 //UNUSED2009-05 { 46 //UNUSED2009-05 Init(); 47 //UNUSED2009-05 } 48 49 ScCsvTableBox::ScCsvTableBox( Window* pParent, const ResId& rResId ) : 50 ScCsvControl( pParent, maData, rResId ), 51 maRuler( *this ), 52 maGrid( *this ), 53 maHScroll( this, WB_HORZ | WB_DRAG ), 54 maVScroll( this, WB_VERT | WB_DRAG ), 55 maScrollBox( this ) 56 { 57 Init(); 58 } 59 60 61 // common table box handling -------------------------------------------------- 62 63 void ScCsvTableBox::SetSeparatorsMode() 64 { 65 if( mbFixedMode ) 66 { 67 // rescue data for fixed width mode 68 mnFixedWidth = GetPosCount(); 69 maFixColStates = maGrid.GetColumnStates(); 70 // switch to separators mode 71 mbFixedMode = false; 72 // reset and reinitialize controls 73 DisableRepaint(); 74 Execute( CSVCMD_SETLINEOFFSET, 0 ); 75 Execute( CSVCMD_SETPOSCOUNT, 1 ); 76 Execute( CSVCMD_NEWCELLTEXTS ); 77 maGrid.SetColumnStates( maSepColStates ); 78 InitControls(); 79 EnableRepaint(); 80 } 81 } 82 83 void ScCsvTableBox::SetFixedWidthMode() 84 { 85 if( !mbFixedMode ) 86 { 87 // rescue data for separators mode 88 maSepColStates = maGrid.GetColumnStates(); 89 // switch to fixed width mode 90 mbFixedMode = true; 91 // reset and reinitialize controls 92 DisableRepaint(); 93 Execute( CSVCMD_SETLINEOFFSET, 0 ); 94 Execute( CSVCMD_SETPOSCOUNT, mnFixedWidth ); 95 maGrid.SetSplits( maRuler.GetSplits() ); 96 maGrid.SetColumnStates( maFixColStates ); 97 InitControls(); 98 EnableRepaint(); 99 } 100 } 101 102 void ScCsvTableBox::Init() 103 { 104 mbFixedMode = false; 105 mnFixedWidth = 1; 106 107 maHScroll.EnableRTL( false ); // #107812# RTL 108 maHScroll.SetLineSize( 1 ); 109 maVScroll.SetLineSize( 1 ); 110 111 Link aLink = LINK( this, ScCsvTableBox, CsvCmdHdl ); 112 SetCmdHdl( aLink ); 113 maRuler.SetCmdHdl( aLink ); 114 maGrid.SetCmdHdl( aLink ); 115 116 aLink = LINK( this, ScCsvTableBox, ScrollHdl ); 117 maHScroll.SetScrollHdl( aLink ); 118 maVScroll.SetScrollHdl( aLink ); 119 120 aLink = LINK( this, ScCsvTableBox, ScrollEndHdl ); 121 maHScroll.SetEndScrollHdl( aLink ); 122 maVScroll.SetEndScrollHdl( aLink ); 123 124 InitControls(); 125 } 126 127 void ScCsvTableBox::InitControls() 128 { 129 maGrid.UpdateLayoutData(); 130 131 long nScrollBarSize = GetSettings().GetStyleSettings().GetScrollBarSize(); 132 Size aWinSize = CalcOutputSize( GetSizePixel() ); 133 long nDataWidth = aWinSize.Width() - nScrollBarSize; 134 long nDataHeight = aWinSize.Height() - nScrollBarSize; 135 136 maData.mnWinWidth = nDataWidth; 137 maData.mnWinHeight = nDataHeight; 138 139 if( mbFixedMode ) 140 { 141 // ruler sets height internally 142 maRuler.SetPosSizePixel( 0, 0, nDataWidth, 0 ); 143 sal_Int32 nY = maRuler.GetSizePixel().Height(); 144 maData.mnWinHeight -= nY; 145 maGrid.SetPosSizePixel( 0, nY, nDataWidth, maData.mnWinHeight ); 146 } 147 else 148 maGrid.SetPosSizePixel( 0, 0, nDataWidth, nDataHeight ); 149 maGrid.Show(); 150 maRuler.Show( mbFixedMode ); 151 152 // scrollbars always visible 153 maHScroll.SetPosSizePixel( 0, nDataHeight, nDataWidth, nScrollBarSize ); 154 InitHScrollBar(); 155 maHScroll.Show(); 156 157 // scrollbars always visible 158 maVScroll.SetPosSizePixel( nDataWidth, 0, nScrollBarSize, nDataHeight ); 159 InitVScrollBar(); 160 maVScroll.Show(); 161 162 bool bScrBox = maHScroll.IsVisible() && maVScroll.IsVisible(); 163 if( bScrBox ) 164 maScrollBox.SetPosSizePixel( nDataWidth, nDataHeight, nScrollBarSize, nScrollBarSize ); 165 maScrollBox.Show( bScrBox ); 166 167 // let the controls self-adjust to visible area 168 Execute( CSVCMD_SETPOSOFFSET, GetFirstVisPos() ); 169 Execute( CSVCMD_SETLINEOFFSET, GetFirstVisLine() ); 170 } 171 172 void ScCsvTableBox::InitHScrollBar() 173 { 174 maHScroll.SetRange( Range( 0, GetPosCount() + 2 ) ); 175 maHScroll.SetVisibleSize( GetVisPosCount() ); 176 maHScroll.SetPageSize( GetVisPosCount() * 3 / 4 ); 177 maHScroll.SetThumbPos( GetFirstVisPos() ); 178 } 179 180 void ScCsvTableBox::InitVScrollBar() 181 { 182 maVScroll.SetRange( Range( 0, GetLineCount() + 1 ) ); 183 maVScroll.SetVisibleSize( GetVisLineCount() ); 184 maVScroll.SetPageSize( GetVisLineCount() - 2 ); 185 maVScroll.SetThumbPos( GetFirstVisLine() ); 186 } 187 188 void ScCsvTableBox::MakePosVisible( sal_Int32 nPos ) 189 { 190 if( (0 <= nPos) && (nPos < GetPosCount()) ) 191 { 192 if( nPos - CSV_SCROLL_DIST + 1 <= GetFirstVisPos() ) 193 Execute( CSVCMD_SETPOSOFFSET, nPos - CSV_SCROLL_DIST ); 194 else if( nPos + CSV_SCROLL_DIST >= GetLastVisPos() ) 195 Execute( CSVCMD_SETPOSOFFSET, nPos - GetVisPosCount() + CSV_SCROLL_DIST ); 196 } 197 } 198 199 200 // cell contents -------------------------------------------------------------- 201 202 void ScCsvTableBox::SetUniStrings( 203 const String* pTextLines, const String& rSepChars, 204 sal_Unicode cTextSep, bool bMergeSep ) 205 { 206 // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES 207 // -> will be dynamic sometime 208 DisableRepaint(); 209 sal_Int32 nEndLine = GetFirstVisLine() + CSV_PREVIEW_LINES; 210 const String* pString = pTextLines; 211 for( sal_Int32 nLine = GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString ) 212 { 213 if( mbFixedMode ) 214 maGrid.ImplSetTextLineFix( nLine, *pString ); 215 else 216 maGrid.ImplSetTextLineSep( nLine, *pString, rSepChars, cTextSep, bMergeSep ); 217 } 218 EnableRepaint(); 219 } 220 221 //UNUSED2009-05 void ScCsvTableBox::SetByteStrings( 222 //UNUSED2009-05 const ByteString* pTextLines, CharSet eCharSet, 223 //UNUSED2009-05 const String& rSepChars, sal_Unicode cTextSep, bool bMergeSep ) 224 //UNUSED2009-05 { 225 //UNUSED2009-05 // assuming that pTextLines is a string array with size CSV_PREVIEW_LINES 226 //UNUSED2009-05 // -> will be dynamic sometime 227 //UNUSED2009-05 DisableRepaint(); 228 //UNUSED2009-05 sal_Int32 nEndLine = GetFirstVisLine() + CSV_PREVIEW_LINES; 229 //UNUSED2009-05 const ByteString* pString = pTextLines; 230 //UNUSED2009-05 for( sal_Int32 nLine = GetFirstVisLine(); nLine < nEndLine; ++nLine, ++pString ) 231 //UNUSED2009-05 { 232 //UNUSED2009-05 if( mbFixedMode ) 233 //UNUSED2009-05 maGrid.ImplSetTextLineFix( nLine, String( *pString, eCharSet ) ); 234 //UNUSED2009-05 else 235 //UNUSED2009-05 maGrid.ImplSetTextLineSep( nLine, String( *pString, eCharSet ), rSepChars, cTextSep, bMergeSep ); 236 //UNUSED2009-05 } 237 //UNUSED2009-05 EnableRepaint(); 238 //UNUSED2009-05 } 239 240 241 // column settings ------------------------------------------------------------ 242 243 void ScCsvTableBox::InitTypes( const ListBox& rListBox ) 244 { 245 sal_uInt16 nTypeCount = rListBox.GetEntryCount(); 246 StringVec aTypeNames( nTypeCount ); 247 for( sal_uInt16 nIndex = 0; nIndex < nTypeCount; ++nIndex ) 248 aTypeNames[ nIndex ] = rListBox.GetEntry( nIndex ); 249 maGrid.SetTypeNames( aTypeNames ); 250 } 251 252 void ScCsvTableBox::FillColumnData( ScAsciiOptions& rOptions ) const 253 { 254 if( mbFixedMode ) 255 maGrid.FillColumnDataFix( rOptions ); 256 else 257 maGrid.FillColumnDataSep( rOptions ); 258 } 259 260 261 // event handling ------------------------------------------------------------- 262 263 void ScCsvTableBox::Resize() 264 { 265 ScCsvControl::Resize(); 266 InitControls(); 267 } 268 269 void ScCsvTableBox::DataChanged( const DataChangedEvent& rDCEvt ) 270 { 271 if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) 272 InitControls(); 273 ScCsvControl::DataChanged( rDCEvt ); 274 } 275 276 IMPL_LINK( ScCsvTableBox, CsvCmdHdl, ScCsvControl*, pCtrl ) 277 { 278 DBG_ASSERT( pCtrl, "ScCsvTableBox::CsvCmdHdl - missing sender" ); 279 280 const ScCsvCmd& rCmd = pCtrl->GetCmd(); 281 ScCsvCmdType eType = rCmd.GetType(); 282 sal_Int32 nParam1 = rCmd.GetParam1(); 283 sal_Int32 nParam2 = rCmd.GetParam2(); 284 285 bool bFound = true; 286 switch( eType ) 287 { 288 case CSVCMD_REPAINT: 289 if( !IsNoRepaint() ) 290 { 291 maGrid.ImplRedraw(); 292 maRuler.ImplRedraw(); 293 InitHScrollBar(); 294 InitVScrollBar(); 295 } 296 break; 297 case CSVCMD_MAKEPOSVISIBLE: 298 MakePosVisible( nParam1 ); 299 break; 300 301 case CSVCMD_NEWCELLTEXTS: 302 if( mbFixedMode ) 303 Execute( CSVCMD_UPDATECELLTEXTS ); 304 else 305 { 306 DisableRepaint(); 307 ScCsvColStateVec aStates( maGrid.GetColumnStates() ); 308 sal_Int32 nPos = GetFirstVisPos(); 309 Execute( CSVCMD_SETPOSCOUNT, 1 ); 310 Execute( CSVCMD_UPDATECELLTEXTS ); 311 Execute( CSVCMD_SETPOSOFFSET, nPos ); 312 maGrid.SetColumnStates( aStates ); 313 EnableRepaint(); 314 } 315 break; 316 case CSVCMD_UPDATECELLTEXTS: 317 maUpdateTextHdl.Call( this ); 318 break; 319 case CSVCMD_SETCOLUMNTYPE: 320 maGrid.SetSelColumnType( nParam1 ); 321 break; 322 case CSVCMD_EXPORTCOLUMNTYPE: 323 maColTypeHdl.Call( this ); 324 break; 325 case CSVCMD_SETFIRSTIMPORTLINE: 326 maGrid.SetFirstImportedLine( nParam1 ); 327 break; 328 329 case CSVCMD_INSERTSPLIT: 330 DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::InsertSplit - invalid call" ); 331 if( maRuler.GetSplitCount() + 1 < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT) ) 332 { 333 maRuler.InsertSplit( nParam1 ); 334 maGrid.InsertSplit( nParam1 ); 335 } 336 break; 337 case CSVCMD_REMOVESPLIT: 338 DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveSplit - invalid call" ); 339 maRuler.RemoveSplit( nParam1 ); 340 maGrid.RemoveSplit( nParam1 ); 341 break; 342 case CSVCMD_TOGGLESPLIT: 343 Execute( maRuler.HasSplit( nParam1 ) ? CSVCMD_REMOVESPLIT : CSVCMD_INSERTSPLIT, nParam1 ); 344 break; 345 case CSVCMD_MOVESPLIT: 346 DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::MoveSplit - invalid call" ); 347 maRuler.MoveSplit( nParam1, nParam2 ); 348 maGrid.MoveSplit( nParam1, nParam2 ); 349 break; 350 case CSVCMD_REMOVEALLSPLITS: 351 DBG_ASSERT( mbFixedMode, "ScCsvTableBox::CsvCmdHdl::RemoveAllSplits - invalid call" ); 352 maRuler.RemoveAllSplits(); 353 maGrid.RemoveAllSplits(); 354 break; 355 default: 356 bFound = false; 357 } 358 if( bFound ) 359 return 0; 360 361 const ScCsvLayoutData aOldData( maData ); 362 switch( eType ) 363 { 364 case CSVCMD_SETPOSCOUNT: 365 maData.mnPosCount = Max( nParam1, sal_Int32( 1 ) ); 366 ImplSetPosOffset( GetFirstVisPos() ); 367 break; 368 case CSVCMD_SETPOSOFFSET: 369 ImplSetPosOffset( nParam1 ); 370 break; 371 case CSVCMD_SETHDRWIDTH: 372 maData.mnHdrWidth = Max( nParam1, sal_Int32( 0 ) ); 373 ImplSetPosOffset( GetFirstVisPos() ); 374 break; 375 case CSVCMD_SETCHARWIDTH: 376 maData.mnCharWidth = Max( nParam1, sal_Int32( 1 ) ); 377 ImplSetPosOffset( GetFirstVisPos() ); 378 break; 379 case CSVCMD_SETLINECOUNT: 380 maData.mnLineCount = Max( nParam1, sal_Int32( 1 ) ); 381 ImplSetLineOffset( GetFirstVisLine() ); 382 break; 383 case CSVCMD_SETLINEOFFSET: 384 ImplSetLineOffset( nParam1 ); 385 break; 386 case CSVCMD_SETHDRHEIGHT: 387 maData.mnHdrHeight = Max( nParam1, sal_Int32( 0 ) ); 388 ImplSetLineOffset( GetFirstVisLine() ); 389 break; 390 case CSVCMD_SETLINEHEIGHT: 391 maData.mnLineHeight = Max( nParam1, sal_Int32( 1 ) ); 392 ImplSetLineOffset( GetFirstVisLine() ); 393 break; 394 case CSVCMD_MOVERULERCURSOR: 395 maData.mnPosCursor = IsVisibleSplitPos( nParam1 ) ? nParam1 : CSV_POS_INVALID; 396 break; 397 case CSVCMD_MOVEGRIDCURSOR: 398 maData.mnColCursor = ((0 <= nParam1) && (nParam1 < GetPosCount())) ? nParam1 : CSV_POS_INVALID; 399 break; 400 default: 401 { 402 // added to avoid warnings 403 } 404 } 405 406 if( maData != aOldData ) 407 { 408 DisableRepaint(); 409 maRuler.ApplyLayout( aOldData ); 410 maGrid.ApplyLayout( aOldData ); 411 EnableRepaint(); 412 } 413 414 return 0; 415 } 416 417 IMPL_LINK( ScCsvTableBox, ScrollHdl, ScrollBar*, pScrollBar ) 418 { 419 DBG_ASSERT( pScrollBar, "ScCsvTableBox::ScrollHdl - missing sender" ); 420 421 if( pScrollBar == &maHScroll ) 422 Execute( CSVCMD_SETPOSOFFSET, pScrollBar->GetThumbPos() ); 423 else if( pScrollBar == &maVScroll ) 424 Execute( CSVCMD_SETLINEOFFSET, pScrollBar->GetThumbPos() ); 425 426 return 0; 427 } 428 429 IMPL_LINK( ScCsvTableBox, ScrollEndHdl, ScrollBar*, pScrollBar ) 430 { 431 DBG_ASSERT( pScrollBar, "ScCsvTableBox::ScrollEndHdl - missing sender" ); 432 433 if( pScrollBar == &maHScroll ) 434 { 435 if( GetRulerCursorPos() != CSV_POS_INVALID ) 436 Execute( CSVCMD_MOVERULERCURSOR, maRuler.GetNoScrollPos( GetRulerCursorPos() ) ); 437 if( GetGridCursorPos() != CSV_POS_INVALID ) 438 Execute( CSVCMD_MOVEGRIDCURSOR, maGrid.GetNoScrollCol( GetGridCursorPos() ) ); 439 } 440 441 return 0; 442 } 443 444 445 // accessibility -------------------------------------------------------------- 446 447 ScCsvTableBox::XAccessibleRef ScCsvTableBox::CreateAccessible() 448 { 449 // do not use the ScCsvControl mechanism, return default accessible object 450 return Control::CreateAccessible(); 451 } 452 453 ScAccessibleCsvControl* ScCsvTableBox::ImplCreateAccessible() 454 { 455 return NULL; // not used, see CreateAccessible() 456 } 457 458 459 // ============================================================================ 460 461