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_sw.hxx" 30 31 32 #include <hintids.hxx> 33 34 #include <tools/errinf.hxx> 35 #include <vcl/svapp.hxx> 36 #include <basegfx/vector/b2dvector.hxx> 37 #ifndef _SVX_SVXIDS_HRC 38 #include <svx/svxids.hrc> 39 #endif 40 #include <editeng/protitem.hxx> 41 #include <editeng/brshitem.hxx> 42 #include <editeng/frmdiritem.hxx> 43 #include <svtools/ruler.hxx> 44 #include <swwait.hxx> 45 #include <fmtfsize.hxx> 46 #include <fmtornt.hxx> 47 #include <frmatr.hxx> 48 #include <docary.hxx> 49 #include <fesh.hxx> 50 #include <doc.hxx> 51 #include <cntfrm.hxx> 52 #include <rootfrm.hxx> 53 #include <pagefrm.hxx> 54 #include <tabfrm.hxx> 55 #include <rowfrm.hxx> 56 #include <cellfrm.hxx> 57 #include <flyfrm.hxx> 58 #include <dflyobj.hxx> 59 #include <swtable.hxx> 60 #include <swddetbl.hxx> 61 #include <ndtxt.hxx> 62 #include <calc.hxx> 63 #include <tabcol.hxx> 64 #include <cellatr.hxx> 65 #include <pam.hxx> 66 #include <viscrs.hxx> 67 #include <tblsel.hxx> 68 #include <swtblfmt.hxx> 69 #include <swerror.h> 70 #include <swundo.hxx> 71 #include <frmtool.hxx> 72 73 #include <node.hxx> // #i23726# 74 // OD 2004-05-24 #i28701# 75 #include <sortedobjs.hxx> 76 77 using namespace ::com::sun::star; 78 79 80 //siehe auch swtable.cxx 81 #define COLFUZZY 20L 82 83 inline sal_Bool IsSame( long nA, long nB ) { return Abs(nA-nB) <= COLFUZZY; } 84 inline sal_Bool IsNear( long nA, long nB, long nTolerance ) { return Abs( nA - nB ) <= nTolerance; } 85 86 // table column cache 87 SwTabCols *pLastCols = 0; 88 const SwTable *pColumnCacheLastTable = 0; 89 const SwTabFrm *pColumnCacheLastTabFrm = 0; 90 const SwFrm *pColumnCacheLastCellFrm = 0; 91 92 // table row cache 93 SwTabCols *pLastRows = 0; 94 const SwTable *pRowCacheLastTable = 0; 95 const SwTabFrm *pRowCacheLastTabFrm = 0; 96 const SwFrm *pRowCacheLastCellFrm = 0; 97 98 99 class TblWait 100 { 101 SwWait *pWait; 102 public: 103 TblWait( sal_uInt16 nCnt, SwFrm *pFrm, SwDocShell &rDocShell, sal_uInt16 nCnt2 = 0); 104 ~TblWait() { delete pWait; } 105 }; 106 107 TblWait::TblWait( sal_uInt16 nCnt, SwFrm *pFrm, SwDocShell &rDocShell, sal_uInt16 nCnt2): 108 pWait( 0 ) 109 { 110 sal_Bool bWait = 20 < nCnt || 20 < nCnt2 || (pFrm && 111 20 < pFrm->ImplFindTabFrm()->GetTable()->GetTabLines().Count()); 112 if( bWait ) 113 pWait = new SwWait( rDocShell, sal_True ); 114 } 115 116 117 void SwFEShell::ParkCursorInTab() 118 { 119 SwCursor * pSwCrsr = GetSwCrsr(); 120 121 ASSERT(pSwCrsr, "no SwCursor"); 122 123 SwPosition aStartPos = *pSwCrsr->GetPoint(), aEndPos = aStartPos; 124 125 SwCursor * pTmpCrsr = (SwCursor *) pSwCrsr; 126 127 /* Search least and greatest position in current cursor ring. 128 */ 129 do 130 { 131 const SwPosition * pPt = pTmpCrsr->GetPoint(), 132 * pMk = pTmpCrsr->GetMark(); 133 134 if (*pPt < aStartPos) 135 aStartPos = *pPt; 136 137 if (*pPt > aEndPos) 138 aEndPos = *pPt; 139 140 if (*pMk < aStartPos) 141 aStartPos = *pMk; 142 143 if (*pMk > aEndPos) 144 aEndPos = *pMk; 145 146 pTmpCrsr = (SwCursor *) pTmpCrsr->GetNext(); 147 } 148 while (pTmpCrsr != pSwCrsr); 149 150 KillPams(); 151 152 /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */ 153 154 /* Set cursor to end of selection to ensure IsLastCellInRow works 155 properly. */ 156 { 157 SwCursor aTmpCrsr( aEndPos, 0, false ); 158 *pSwCrsr = aTmpCrsr; 159 } 160 161 /* Move the cursor out of the columns to delete and stay in the 162 same row. If the table has only one column the cursor will 163 stay in the row and the shell will take care of it. */ 164 if (IsLastCellInRow()) 165 { 166 /* If the cursor is in the last row of the table, first 167 try to move it to the previous cell. If that fails move 168 it to the next cell. */ 169 170 { 171 SwCursor aTmpCrsr( aStartPos, 0, false ); 172 *pSwCrsr = aTmpCrsr; 173 } 174 175 if (! pSwCrsr->GoPrevCell()) 176 { 177 SwCursor aTmpCrsr( aEndPos, 0, false ); 178 *pSwCrsr = aTmpCrsr; 179 pSwCrsr->GoNextCell(); 180 } 181 } 182 else 183 { 184 /* If the cursor is not in the last row of the table, first 185 try to move it to the next cell. If that fails move it 186 to the previous cell. */ 187 188 { 189 SwCursor aTmpCrsr( aEndPos, 0, false ); 190 *pSwCrsr = aTmpCrsr; 191 } 192 193 if (! pSwCrsr->GoNextCell()) 194 { 195 SwCursor aTmpCrsr( aStartPos, 0, false ); 196 *pSwCrsr = aTmpCrsr; 197 pSwCrsr->GoPrevCell(); 198 } 199 } 200 } 201 202 /*********************************************************************** 203 #* Class : SwFEShell 204 #* Methoden : InsertRow(), InsertCol 205 #* Datum : MA 03. May. 93 206 #* Update : MA 19. Apr. 95 207 #***********************************************************************/ 208 sal_Bool SwFEShell::InsertRow( sal_uInt16 nCnt, sal_Bool bBehind ) 209 { 210 // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen 211 SwFrm *pFrm = GetCurrFrm(); 212 if( !pFrm || !pFrm->IsInTab() ) 213 return sal_False; 214 215 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 216 { 217 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 218 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 219 return sal_False; 220 } 221 222 SET_CURR_SHELL( this ); 223 StartAllAction(); 224 225 // lasse ueber das Layout die Boxen suchen 226 SwSelBoxes aBoxes; 227 GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW ); 228 229 TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() ); 230 231 sal_Bool bRet = sal_False; 232 if ( aBoxes.Count() ) 233 bRet = GetDoc()->InsertRow( aBoxes, nCnt, bBehind ); 234 235 EndAllActionAndCall(); 236 return bRet; 237 } 238 239 sal_Bool SwFEShell::InsertCol( sal_uInt16 nCnt, sal_Bool bBehind ) 240 { 241 // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen 242 SwFrm *pFrm = GetCurrFrm(); 243 if( !pFrm || !pFrm->IsInTab() ) 244 return sal_False; 245 246 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 247 { 248 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 249 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 250 return sal_False; 251 } 252 253 SET_CURR_SHELL( this ); 254 255 if( !CheckSplitCells( *this, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) ) 256 { 257 ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR, 258 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 259 return sal_False; 260 } 261 262 StartAllAction(); 263 // lasse ueber das Layout die Boxen suchen 264 SwSelBoxes aBoxes; 265 GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL ); 266 267 TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() ); 268 269 sal_Bool bRet = sal_False; 270 if( aBoxes.Count() ) 271 bRet = GetDoc()->InsertCol( aBoxes, nCnt, bBehind ); 272 273 EndAllActionAndCall(); 274 return bRet; 275 } 276 277 /*********************************************************************** 278 #* Class : SwFEShell 279 #* Methoden : DeleteRow(), DeleteCol() 280 #* Datum : MA 03. May. 93 281 #* Update : MA 19. Apr. 95 282 #***********************************************************************/ 283 284 /** 285 Determines if the current cursor is in the last row of the table. 286 */ 287 sal_Bool SwFEShell::IsLastCellInRow() const 288 { 289 SwTabCols aTabCols; 290 GetTabCols( aTabCols ); 291 sal_Bool bResult = sal_False; 292 293 if (IsTableRightToLeft()) 294 /* If the table is right-to-left the last row is the most left one. */ 295 bResult = 0 == GetCurTabColNum(); 296 else 297 /* If the table is left-to-right the last row is the most right one. */ 298 bResult = aTabCols.Count() == GetCurTabColNum(); 299 300 return bResult; 301 } 302 303 sal_Bool SwFEShell::DeleteCol() 304 { 305 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 306 SwFrm *pFrm = GetCurrFrm(); 307 if( !pFrm || !pFrm->IsInTab() ) 308 return sal_False; 309 310 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 311 { 312 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 313 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 314 return sal_False; 315 } 316 317 SET_CURR_SHELL( this ); 318 StartAllAction(); 319 320 // lasse ueber das Layout die Boxen suchen 321 sal_Bool bRet; 322 SwSelBoxes aBoxes; 323 GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL ); 324 if ( aBoxes.Count() ) 325 { 326 TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() ); 327 328 // die Crsr muessen noch aus dem Loesch Bereich entfernt 329 // werden. Setze sie immer hinter/auf die Tabelle; ueber die 330 // Dokument-Position werden sie dann immer an die alte Position gesetzt. 331 while( !pFrm->IsCellFrm() ) 332 pFrm = pFrm->GetUpper(); 333 334 ParkCursorInTab(); 335 336 // dann loesche doch die Spalten 337 StartUndo(UNDO_COL_DELETE); 338 bRet = GetDoc()->DeleteRowCol( aBoxes, true ); 339 EndUndo(UNDO_COL_DELETE); 340 341 } 342 else 343 bRet = sal_False; 344 345 EndAllActionAndCall(); 346 return bRet; 347 } 348 349 sal_Bool SwFEShell::DeleteRow() 350 { 351 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 352 SwFrm *pFrm = GetCurrFrm(); 353 if( !pFrm || !pFrm->IsInTab() ) 354 return sal_False; 355 356 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 357 { 358 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 359 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 360 return sal_False; 361 } 362 363 SET_CURR_SHELL( this ); 364 StartAllAction(); 365 366 // lasse ueber das Layout die Boxen suchen 367 sal_Bool bRet; 368 SwSelBoxes aBoxes; 369 GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW ); 370 371 if( aBoxes.Count() ) 372 { 373 TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() ); 374 375 // die Crsr aus dem Loeschbereich entfernen. 376 // Der Cursor steht danach: 377 // - es folgt noch eine Zeile, in dieser 378 // - vorher steht noch eine Zeile, in dieser 379 // - sonst immer dahinter 380 { 381 SwTableNode* pTblNd = ((SwCntntFrm*)pFrm)->GetNode()->FindTableNode(); 382 383 // suche alle Boxen / Lines 384 _FndBox aFndBox( 0, 0 ); 385 { 386 _FndPara aPara( aBoxes, &aFndBox ); 387 pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara ); 388 } 389 390 if( !aFndBox.GetLines().Count() ) 391 { 392 EndAllActionAndCall(); 393 return sal_False; 394 } 395 396 KillPams(); 397 398 _FndBox* pFndBox = &aFndBox; 399 while( 1 == pFndBox->GetLines().Count() && 400 1 == pFndBox->GetLines()[0]->GetBoxes().Count() ) 401 { 402 _FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0]; 403 if( pTmp->GetBox()->GetSttNd() ) 404 break; // das ist sonst zu weit 405 pFndBox = pTmp; 406 } 407 408 SwTableLine* pDelLine = pFndBox->GetLines()[ 409 pFndBox->GetLines().Count()-1 ]->GetLine(); 410 SwTableBox* pDelBox = pDelLine->GetTabBoxes()[ 411 pDelLine->GetTabBoxes().Count() - 1 ]; 412 while( !pDelBox->GetSttNd() ) 413 { 414 SwTableLine* pLn = pDelBox->GetTabLines()[ 415 pDelBox->GetTabLines().Count()-1 ]; 416 pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ]; 417 } 418 SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(), 419 pDelBox, sal_True ); 420 while( pNextBox && 421 pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) 422 pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox ); 423 424 if( !pNextBox ) // keine nachfolgende? dann die vorhergehende 425 { 426 pDelLine = pFndBox->GetLines()[ 0 ]->GetLine(); 427 pDelBox = pDelLine->GetTabBoxes()[ 0 ]; 428 while( !pDelBox->GetSttNd() ) 429 pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0]; 430 pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(), 431 pDelBox, sal_True ); 432 while( pNextBox && 433 pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() ) 434 pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox ); 435 } 436 437 sal_uLong nIdx; 438 if( pNextBox ) // dann den Cursor hier hinein 439 nIdx = pNextBox->GetSttIdx() + 1; 440 else // ansonsten hinter die Tabelle 441 nIdx = pTblNd->EndOfSectionIndex() + 1; 442 443 SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx ); 444 SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); 445 if( !pCNd ) 446 pCNd = GetDoc()->GetNodes().GoNext( &aIdx ); 447 448 if( pCNd ) 449 { 450 SwPaM* pPam = GetCrsr(); 451 pPam->GetPoint()->nNode = aIdx; 452 pPam->GetPoint()->nContent.Assign( pCNd, 0 ); 453 pPam->SetMark(); // beide wollen etwas davon haben 454 pPam->DeleteMark(); 455 } 456 } 457 458 // dann loesche doch die Zeilen 459 StartUndo(UNDO_ROW_DELETE); 460 bRet = GetDoc()->DeleteRowCol( aBoxes ); 461 EndUndo(UNDO_ROW_DELETE); 462 } 463 else 464 bRet = sal_False; 465 466 EndAllActionAndCall(); 467 return bRet; 468 } 469 470 /*********************************************************************** 471 #* Class : SwFEShell 472 #* Methoden : MergeTab(), SplitTab() 473 #* Datum : MA 03. May. 93 474 #* Update : MA 19. Apr. 95 475 #***********************************************************************/ 476 477 sal_uInt16 SwFEShell::MergeTab() 478 { 479 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 480 sal_uInt16 nRet = TBLMERGE_NOSELECTION; 481 if( IsTableMode() ) 482 { 483 SwShellTableCrsr* pTableCrsr = GetTableCrsr(); 484 const SwTableNode* pTblNd = pTableCrsr->GetNode()->FindTableNode(); 485 if( pTblNd->GetTable().ISA( SwDDETable )) 486 { 487 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 488 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 489 } 490 else 491 { 492 SET_CURR_SHELL( this ); 493 StartAllAction(); 494 495 TblWait( pTableCrsr->GetBoxesCount(), 0, *GetDoc()->GetDocShell(), 496 pTblNd->GetTable().GetTabLines().Count() ); 497 498 nRet = GetDoc()->MergeTbl( *pTableCrsr ); 499 500 KillPams(); 501 502 EndAllActionAndCall(); 503 } 504 } 505 return nRet; 506 } 507 508 sal_Bool SwFEShell::SplitTab( sal_Bool bVert, sal_uInt16 nCnt, sal_Bool bSameHeight ) 509 { 510 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 511 SwFrm *pFrm = GetCurrFrm(); 512 if( !pFrm || !pFrm->IsInTab() ) 513 return sal_False; 514 515 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 516 { 517 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 518 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 519 return sal_False; 520 } 521 522 SET_CURR_SHELL( this ); 523 524 if( bVert && !CheckSplitCells( *this, nCnt + 1 ) ) 525 { 526 ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR, 527 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 528 return sal_False; 529 } 530 StartAllAction(); 531 // lasse ueber das Layout die Boxen suchen 532 sal_Bool bRet; 533 SwSelBoxes aBoxes; 534 GetTblSel( *this, aBoxes ); 535 if( aBoxes.Count() ) 536 { 537 TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() ); 538 539 // dann loesche doch die Spalten 540 bRet = GetDoc()->SplitTbl( aBoxes, bVert, nCnt, bSameHeight ); 541 542 DELETEZ( pLastCols ); 543 DELETEZ( pLastRows ); 544 } 545 else 546 bRet = sal_False; 547 EndAllActionAndCall(); 548 return bRet; 549 } 550 551 552 /*********************************************************************** 553 #* Class : SwFEShell 554 #* Methoden : _GetTabCols 555 #* Datum : MA 30. Nov. 95 556 #* Update : MA 08. Jan. 97 557 #***********************************************************************/ 558 void SwFEShell::_GetTabCols( SwTabCols &rToFill, const SwFrm *pBox ) const 559 { 560 const SwTabFrm *pTab = pBox->FindTabFrm(); 561 if ( pLastCols ) 562 { 563 //Paar Kleinigkeiten muessen wir schon noch sicherstellen 564 sal_Bool bDel = sal_True; 565 if ( pColumnCacheLastTable == pTab->GetTable() ) 566 { 567 bDel = sal_False; 568 SWRECTFN( pTab ) 569 570 const SwPageFrm* pPage = pTab->FindPageFrm(); 571 const sal_uLong nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() - 572 (pPage->Frm().*fnRect->fnGetLeft)(); 573 const sal_uLong nRightMax = (pTab->Frm().*fnRect->fnGetRight)() - 574 (pPage->Frm().*fnRect->fnGetLeft)(); 575 576 if ( pColumnCacheLastTabFrm != pTab ) 577 { 578 //Wenn der TabFrm gewechselt hat, brauchen wir bei gleicher 579 //Breite nur ein wenig shiften. 580 SWRECTFNX( pColumnCacheLastTabFrm ) 581 if( (pColumnCacheLastTabFrm->Frm().*fnRectX->fnGetWidth)() == 582 (pTab->Frm().*fnRect->fnGetWidth)() ) 583 { 584 pLastCols->SetLeftMin( nLeftMin ); 585 586 //ASSERT( bVert || 587 // pLastCols->GetLeftMin() == (pTab->Frm().*fnRect->fnGetLeft)(), 588 // "GetTabCols: wrong result" ) 589 590 pColumnCacheLastTabFrm = pTab; 591 } 592 else 593 bDel = sal_True; 594 } 595 596 if ( !bDel && 597 pLastCols->GetLeftMin () == (sal_uInt16)nLeftMin && 598 pLastCols->GetLeft () == (sal_uInt16)(pTab->Prt().*fnRect->fnGetLeft)() && 599 pLastCols->GetRight () == (sal_uInt16)(pTab->Prt().*fnRect->fnGetRight)()&& 600 pLastCols->GetRightMax() == (sal_uInt16)nRightMax - pLastCols->GetLeftMin() ) 601 { 602 if ( pColumnCacheLastCellFrm != pBox ) 603 { 604 pTab->GetTable()->GetTabCols( *pLastCols, 605 ((SwCellFrm*)pBox)->GetTabBox(), sal_True); 606 pColumnCacheLastCellFrm = pBox; 607 } 608 rToFill = *pLastCols; 609 } 610 else 611 bDel = sal_True; 612 } 613 if ( bDel ) 614 DELETEZ(pLastCols); 615 } 616 if ( !pLastCols ) 617 { 618 GetDoc()->GetTabCols( rToFill, 0, (SwCellFrm*)pBox ); 619 620 pLastCols = new SwTabCols( rToFill ); 621 pColumnCacheLastTable = pTab->GetTable(); 622 pColumnCacheLastTabFrm = pTab; 623 pColumnCacheLastCellFrm= pBox; 624 } 625 626 #if OSL_DEBUG_LEVEL > 1 627 SwTabColsEntry aEntry; 628 for ( sal_uInt16 i = 0; i < rToFill.Count(); ++i ) 629 { 630 aEntry = rToFill.GetEntry( i ); 631 (void)aEntry; 632 } 633 #endif 634 } 635 636 /*********************************************************************** 637 #* Class : SwFEShell 638 #* Methoden : _GetTabRows 639 #* Datum : FME 2004-01-14 640 #* Update : 641 #***********************************************************************/ 642 void SwFEShell::_GetTabRows( SwTabCols &rToFill, const SwFrm *pBox ) const 643 { 644 const SwTabFrm *pTab = pBox->FindTabFrm(); 645 if ( pLastRows ) 646 { 647 //Paar Kleinigkeiten muessen wir schon noch sicherstellen 648 sal_Bool bDel = sal_True; 649 if ( pRowCacheLastTable == pTab->GetTable() ) 650 { 651 bDel = sal_False; 652 SWRECTFN( pTab ) 653 const SwPageFrm* pPage = pTab->FindPageFrm(); 654 const long nLeftMin = ( bVert ? 655 pTab->GetPrtLeft() - pPage->Frm().Left() : 656 pTab->GetPrtTop() - pPage->Frm().Top() ); 657 const long nLeft = bVert ? LONG_MAX : 0; 658 const long nRight = (pTab->Prt().*fnRect->fnGetHeight)(); 659 const long nRightMax = bVert ? nRight : LONG_MAX; 660 661 if ( pRowCacheLastTabFrm != pTab || 662 pRowCacheLastCellFrm != pBox ) 663 bDel = sal_True; 664 665 if ( !bDel && 666 pLastRows->GetLeftMin () == nLeftMin && 667 pLastRows->GetLeft () == nLeft && 668 pLastRows->GetRight () == nRight && 669 pLastRows->GetRightMax() == nRightMax ) 670 { 671 rToFill = *pLastRows; 672 } 673 else 674 bDel = sal_True; 675 } 676 if ( bDel ) 677 DELETEZ(pLastRows); 678 } 679 if ( !pLastRows ) 680 { 681 GetDoc()->GetTabRows( rToFill, 0, (SwCellFrm*)pBox ); 682 683 pLastRows = new SwTabCols( rToFill ); 684 pRowCacheLastTable = pTab->GetTable(); 685 pRowCacheLastTabFrm = pTab; 686 pRowCacheLastCellFrm= pBox; 687 } 688 } 689 690 /*********************************************************************** 691 #* Class : SwFEShell 692 #* Methoden : SetTabCols(), GetTabCols() 693 #* Datum : MA 03. May. 93 694 #* Update : MA 18. May. 93 695 #***********************************************************************/ 696 void SwFEShell::SetTabCols( const SwTabCols &rNew, sal_Bool bCurRowOnly ) 697 { 698 SwFrm *pBox = GetCurrFrm(); 699 if( !pBox || !pBox->IsInTab() ) 700 return; 701 702 SET_CURR_SHELL( this ); 703 StartAllAction(); 704 705 do { 706 pBox = pBox->GetUpper(); 707 } while ( !pBox->IsCellFrm() ); 708 709 GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox ); 710 EndAllActionAndCall(); 711 } 712 713 void SwFEShell::GetTabCols( SwTabCols &rToFill ) const 714 { 715 const SwFrm *pFrm = GetCurrFrm(); 716 if( !pFrm || !pFrm->IsInTab() ) 717 return; 718 do 719 { pFrm = pFrm->GetUpper(); 720 } while ( !pFrm->IsCellFrm() ); 721 722 _GetTabCols( rToFill, pFrm ); 723 } 724 725 /*-- 19.01.2004 08:56:42--------------------------------------------------- 726 727 -----------------------------------------------------------------------*/ 728 void SwFEShell::GetTabRows( SwTabCols &rToFill ) const 729 { 730 const SwFrm *pFrm = GetCurrFrm(); 731 if( !pFrm || !pFrm->IsInTab() ) 732 return; 733 do 734 { pFrm = pFrm->GetUpper(); 735 } while ( !pFrm->IsCellFrm() ); 736 737 _GetTabRows( rToFill, pFrm ); 738 } 739 /*-- 19.01.2004 08:56:44--------------------------------------------------- 740 741 -----------------------------------------------------------------------*/ 742 void SwFEShell::SetTabRows( const SwTabCols &rNew, sal_Bool bCurColOnly ) 743 { 744 SwFrm *pBox = GetCurrFrm(); 745 if( !pBox || !pBox->IsInTab() ) 746 return; 747 748 SET_CURR_SHELL( this ); 749 StartAllAction(); 750 751 do { 752 pBox = pBox->GetUpper(); 753 } while ( !pBox->IsCellFrm() ); 754 755 GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox ); 756 EndAllActionAndCall(); 757 } 758 /*-- 19.01.2004 08:59:45--------------------------------------------------- 759 760 -----------------------------------------------------------------------*/ 761 void SwFEShell::GetMouseTabRows( SwTabCols &rToFill, const Point &rPt ) const 762 { 763 const SwFrm *pBox = GetBox( rPt ); 764 if ( pBox ) 765 _GetTabRows( rToFill, pBox ); 766 } 767 /*-- 19.01.2004 08:59:45--------------------------------------------------- 768 769 -----------------------------------------------------------------------*/ 770 void SwFEShell::SetMouseTabRows( const SwTabCols &rNew, sal_Bool bCurColOnly, const Point &rPt ) 771 { 772 const SwFrm *pBox = GetBox( rPt ); 773 if( pBox ) 774 { 775 SET_CURR_SHELL( this ); 776 StartAllAction(); 777 GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox ); 778 EndAllActionAndCall(); 779 } 780 } 781 782 /*********************************************************************** 783 * Class : SwFEShell 784 * Methoden : SetRowSplit(), GetRowSplit() 785 * Datum : FME 13.11.2003 786 ***********************************************************************/ 787 788 void SwFEShell::SetRowSplit( const SwFmtRowSplit& rNew ) 789 { 790 SET_CURR_SHELL( this ); 791 StartAllAction(); 792 GetDoc()->SetRowSplit( *getShellCrsr( false ), rNew ); 793 EndAllActionAndCall(); 794 } 795 796 void SwFEShell::GetRowSplit( SwFmtRowSplit*& rpSz ) const 797 { 798 GetDoc()->GetRowSplit( *getShellCrsr( false ), rpSz ); 799 } 800 801 802 /*********************************************************************** 803 #* Class : SwFEShell 804 #* Methoden : SetRowHeight(), GetRowHeight() 805 #* Datum : MA 17. May. 93 806 #* Update : JP 29.04.98 807 #***********************************************************************/ 808 809 void SwFEShell::SetRowHeight( const SwFmtFrmSize &rNew ) 810 { 811 SET_CURR_SHELL( this ); 812 StartAllAction(); 813 GetDoc()->SetRowHeight( *getShellCrsr( false ), rNew ); 814 EndAllActionAndCall(); 815 } 816 817 /****************************************************************************** 818 * SwTwips SwFEShell::GetRowHeight() const 819 ******************************************************************************/ 820 void SwFEShell::GetRowHeight( SwFmtFrmSize *& rpSz ) const 821 { 822 GetDoc()->GetRowHeight( *getShellCrsr( false ), rpSz ); 823 } 824 825 sal_Bool SwFEShell::BalanceRowHeight( sal_Bool bTstOnly ) 826 { 827 SET_CURR_SHELL( this ); 828 if( !bTstOnly ) 829 StartAllAction(); 830 sal_Bool bRet = GetDoc()->BalanceRowHeight( *getShellCrsr( false ), bTstOnly ); 831 if( !bTstOnly ) 832 EndAllActionAndCall(); 833 return bRet; 834 } 835 836 /****************************************************************************** 837 * void SwFEShell::SetRowBackground() 838 ******************************************************************************/ 839 void SwFEShell::SetRowBackground( const SvxBrushItem &rNew ) 840 { 841 SET_CURR_SHELL( this ); 842 StartAllAction(); 843 GetDoc()->SetRowBackground( *getShellCrsr( false ), rNew ); 844 EndAllActionAndCall(); 845 } 846 847 /****************************************************************************** 848 * SwTwips SwFEShell::GetRowBackground() const 849 ******************************************************************************/ 850 sal_Bool SwFEShell::GetRowBackground( SvxBrushItem &rToFill ) const 851 { 852 return GetDoc()->GetRowBackground( *getShellCrsr( false ), rToFill ); 853 } 854 855 /*********************************************************************** 856 #* Class : SwFEShell 857 #* Methoden : SetTabBorders(), GetTabBorders() 858 #* Datum : MA 18. May. 93 859 #* Update : JP 29.04.98 860 #***********************************************************************/ 861 862 void SwFEShell::SetTabBorders( const SfxItemSet& rSet ) 863 { 864 SET_CURR_SHELL( this ); 865 StartAllAction(); 866 GetDoc()->SetTabBorders( *getShellCrsr( false ), rSet ); 867 EndAllActionAndCall(); 868 } 869 870 void SwFEShell::SetTabLineStyle( const Color* pColor, sal_Bool bSetLine, 871 const SvxBorderLine* pBorderLine ) 872 { 873 SET_CURR_SHELL( this ); 874 StartAllAction(); 875 GetDoc()->SetTabLineStyle( *getShellCrsr( false ), 876 pColor, bSetLine, pBorderLine ); 877 EndAllActionAndCall(); 878 } 879 880 void SwFEShell::GetTabBorders( SfxItemSet& rSet ) const 881 { 882 GetDoc()->GetTabBorders( *getShellCrsr( false ), rSet ); 883 } 884 885 886 /*********************************************************************** 887 #* Class : SwFEShell 888 #* Methoden : SetBoxBackground(), GetBoxBackground() 889 #* Datum : MA 01. Jun. 93 890 #* Update : MA 03. Jul. 96 891 #***********************************************************************/ 892 void SwFEShell::SetBoxBackground( const SvxBrushItem &rNew ) 893 { 894 SET_CURR_SHELL( this ); 895 StartAllAction(); 896 GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew ); 897 EndAllActionAndCall(); 898 } 899 900 sal_Bool SwFEShell::GetBoxBackground( SvxBrushItem &rToFill ) const 901 { 902 return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill ); 903 } 904 905 /*********************************************************************** 906 #* Class : SwFEShell 907 #* Methoden : SetBoxDirection(), GetBoxDirection() 908 #* Datum : FME 2004-02-03 909 #* Update : FME 2004-02-03 910 #***********************************************************************/ 911 void SwFEShell::SetBoxDirection( const SvxFrameDirectionItem& rNew ) 912 { 913 SET_CURR_SHELL( this ); 914 StartAllAction(); 915 GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew ); 916 EndAllActionAndCall(); 917 } 918 919 sal_Bool SwFEShell::GetBoxDirection( SvxFrameDirectionItem& rToFill ) const 920 { 921 return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill ); 922 } 923 924 /*********************************************************************** 925 #* Class : SwFEShell 926 #* Methoden : SetBoxAlign, SetBoxAlign 927 #* Datum : MA 18. Dec. 96 928 #* Update : JP 29.04.98 929 #***********************************************************************/ 930 void SwFEShell::SetBoxAlign( sal_uInt16 nAlign ) 931 { 932 SET_CURR_SHELL( this ); 933 StartAllAction(); 934 GetDoc()->SetBoxAlign( *getShellCrsr( false ), nAlign ); 935 EndAllActionAndCall(); 936 } 937 938 sal_uInt16 SwFEShell::GetBoxAlign() const 939 { 940 return GetDoc()->GetBoxAlign( *getShellCrsr( false ) ); 941 } 942 943 /*********************************************************************** 944 #* Class : SwFEShell 945 #* Methoden : SetTabBackground(), GetTabBackground() 946 #* Datum : MA 08. Jul. 96 947 #* Update : MA 08. Jul. 96 948 #***********************************************************************/ 949 void SwFEShell::SetTabBackground( const SvxBrushItem &rNew ) 950 { 951 SwFrm *pFrm = GetCurrFrm(); 952 if( !pFrm || !pFrm->IsInTab() ) 953 return; 954 955 SET_CURR_SHELL( this ); 956 StartAllAction(); 957 GetDoc()->SetAttr( rNew, *pFrm->ImplFindTabFrm()->GetFmt() ); 958 EndAllAction(); //Kein Call, denn es veraendert sich nichts! 959 GetDoc()->SetModified(); 960 } 961 962 void SwFEShell::GetTabBackground( SvxBrushItem &rToFill ) const 963 { 964 SwFrm *pFrm = GetCurrFrm(); 965 if( pFrm && pFrm->IsInTab() ) 966 rToFill = pFrm->ImplFindTabFrm()->GetFmt()->GetBackground(); 967 } 968 969 970 /*********************************************************************** 971 #* Class : SwFEShell 972 #* Methoden : HasWholeTabSelection() 973 #* Datum : MA 18. May. 93 974 #* Update : MA 20. Jul. 93 975 #***********************************************************************/ 976 sal_Bool SwFEShell::HasWholeTabSelection() const 977 { 978 //Ist die ganze Tabelle Selektiert? 979 if ( IsTableMode() ) 980 { 981 SwSelBoxes aBoxes; 982 ::GetTblSelCrs( *this, aBoxes ); 983 if( aBoxes.Count() ) 984 { 985 const SwTableNode *pTblNd = IsCrsrInTbl(); 986 return ( pTblNd && aBoxes[0]->GetSttIdx()-1 == pTblNd-> 987 EndOfSectionNode()->StartOfSectionIndex() && 988 aBoxes[aBoxes.Count()-1]->GetSttNd()->EndOfSectionIndex()+1 989 == pTblNd->EndOfSectionIndex() ); 990 } 991 } 992 return sal_False; 993 } 994 995 sal_Bool SwFEShell::HasBoxSelection() const 996 { 997 if(!IsCrsrInTbl()) 998 return sal_False; 999 //Ist die ganze Tabelle Selektiert? 1000 if( IsTableMode() ) 1001 return sal_True; 1002 SwPaM* pPam = GetCrsr(); 1003 // leere Boxen gelten auch ohne Selektion als selektiert 1004 // if( !pPam->HasMark() ) 1005 // return sal_False; 1006 sal_Bool bChg = sal_False; 1007 if( pPam->GetPoint() == pPam->End()) 1008 { 1009 bChg = sal_True; 1010 pPam->Exchange(); 1011 } 1012 SwNode* pNd; 1013 if( pPam->GetPoint()->nNode.GetIndex() -1 == 1014 ( pNd = pPam->GetNode())->StartOfSectionIndex() && 1015 !pPam->GetPoint()->nContent.GetIndex() && 1016 pPam->GetMark()->nNode.GetIndex() + 1 == 1017 pNd->EndOfSectionIndex()) 1018 { 1019 SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 ); 1020 SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode(); 1021 if( !pCNd ) 1022 { 1023 pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx ); 1024 ASSERT( pCNd, "kein ContentNode in der Box ??" ); 1025 } 1026 if( pPam->GetMark()->nContent == pCNd->Len() ) 1027 { 1028 if( bChg ) 1029 pPam->Exchange(); 1030 return sal_True; 1031 } 1032 } 1033 if( bChg ) 1034 pPam->Exchange(); 1035 return sal_False; 1036 } 1037 1038 /*********************************************************************** 1039 #* Class : SwFEShell 1040 #* Methoden : ProtectCells(), UnProtectCells() 1041 #* Datum : MA 20. Jul. 93 1042 #* Update : JP 25. Sep. 93 1043 #***********************************************************************/ 1044 void SwFEShell::ProtectCells() 1045 { 1046 SvxProtectItem aProt( RES_PROTECT ); 1047 aProt.SetCntntProtect( sal_True ); 1048 1049 SET_CURR_SHELL( this ); 1050 StartAllAction(); 1051 1052 GetDoc()->SetBoxAttr( *getShellCrsr( false ), aProt ); 1053 1054 if( !IsCrsrReadonly() ) 1055 { 1056 if( IsTableMode() ) 1057 ClearMark(); 1058 ParkCursorInTab(); 1059 } 1060 EndAllActionAndCall(); 1061 } 1062 1063 // die Tabellenselektion aufheben 1064 void SwFEShell::UnProtectCells() 1065 { 1066 SET_CURR_SHELL( this ); 1067 StartAllAction(); 1068 1069 SwSelBoxes aBoxes; 1070 if( IsTableMode() ) 1071 ::GetTblSelCrs( *this, aBoxes ); 1072 else 1073 { 1074 SwFrm *pFrm = GetCurrFrm(); 1075 do { 1076 pFrm = pFrm->GetUpper(); 1077 } while ( pFrm && !pFrm->IsCellFrm() ); 1078 if( pFrm ) 1079 { 1080 SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(); 1081 aBoxes.Insert( pBox ); 1082 } 1083 } 1084 1085 if( aBoxes.Count() ) 1086 GetDoc()->UnProtectCells( aBoxes ); 1087 1088 EndAllActionAndCall(); 1089 } 1090 1091 void SwFEShell::UnProtectTbls() 1092 { 1093 SET_CURR_SHELL( this ); 1094 StartAllAction(); 1095 GetDoc()->UnProtectTbls( *GetCrsr() ); 1096 EndAllActionAndCall(); 1097 } 1098 1099 sal_Bool SwFEShell::HasTblAnyProtection( const String* pTblName, 1100 sal_Bool* pFullTblProtection ) 1101 { 1102 return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName, 1103 pFullTblProtection ); 1104 } 1105 1106 sal_Bool SwFEShell::CanUnProtectCells() const 1107 { 1108 sal_Bool bUnProtectAvailable = sal_False; 1109 const SwTableNode *pTblNd = IsCrsrInTbl(); 1110 if( pTblNd && !pTblNd->IsProtect() ) 1111 { 1112 SwSelBoxes aBoxes; 1113 if( IsTableMode() ) 1114 ::GetTblSelCrs( *this, aBoxes ); 1115 else 1116 { 1117 SwFrm *pFrm = GetCurrFrm(); 1118 do { 1119 pFrm = pFrm->GetUpper(); 1120 } while ( pFrm && !pFrm->IsCellFrm() ); 1121 if( pFrm ) 1122 { 1123 SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(); 1124 aBoxes.Insert( pBox ); 1125 } 1126 } 1127 if( aBoxes.Count() ) 1128 bUnProtectAvailable = ::HasProtectedCells( aBoxes ); 1129 } 1130 return bUnProtectAvailable; 1131 } 1132 1133 /*********************************************************************** 1134 #* Class : SwFEShell 1135 #* Methoden : GetRowsToRepeat(), SetRowsToRepeat() 1136 #***********************************************************************/ 1137 sal_uInt16 SwFEShell::GetRowsToRepeat() const 1138 { 1139 const SwFrm *pFrm = GetCurrFrm(); 1140 const SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0; 1141 if( pTab ) 1142 return pTab->GetTable()->GetRowsToRepeat(); 1143 return 0; 1144 } 1145 1146 void SwFEShell::SetRowsToRepeat( sal_uInt16 nSet ) 1147 { 1148 SwFrm *pFrm = GetCurrFrm(); 1149 SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0; 1150 if( pTab && pTab->GetTable()->GetRowsToRepeat() != nSet ) 1151 { 1152 SwWait aWait( *GetDoc()->GetDocShell(), sal_True ); 1153 SET_CURR_SHELL( this ); 1154 StartAllAction(); 1155 GetDoc()->SetRowsToRepeat( *pTab->GetTable(), nSet ); 1156 EndAllActionAndCall(); 1157 } 1158 } 1159 /*-- 30.06.2004 08:46:35--------------------------------------------------- 1160 returns the number of rows consecutively selected from top 1161 -----------------------------------------------------------------------*/ 1162 sal_uInt16 lcl_GetRowNumber( const SwPosition& rPos ) 1163 { 1164 sal_uInt16 nRet = USHRT_MAX; 1165 Point aTmpPt; 1166 const SwCntntNode *pNd; 1167 const SwCntntFrm *pFrm; 1168 1169 if( 0 != ( pNd = rPos.nNode.GetNode().GetCntntNode() )) 1170 pFrm = pNd->getLayoutFrm( pNd->GetDoc()->GetCurrentLayout(), &aTmpPt, &rPos, sal_False ); 1171 else 1172 pFrm = 0; 1173 1174 if ( pFrm && pFrm->IsInTab() ) 1175 { 1176 const SwFrm* pRow = pFrm->GetUpper(); 1177 while ( !pRow->GetUpper()->IsTabFrm() ) 1178 pRow = pRow->GetUpper(); 1179 1180 const SwTabFrm* pTabFrm = (const SwTabFrm*)pRow->GetUpper(); 1181 const SwTableLine* pTabLine = static_cast<const SwRowFrm*>(pRow)->GetTabLine(); 1182 1183 sal_uInt16 nI = 0; 1184 while ( nI < pTabFrm->GetTable()->GetTabLines().Count() ) 1185 { 1186 if ( pTabFrm->GetTable()->GetTabLines()[ nI ] == pTabLine ) 1187 { 1188 nRet = nI; 1189 break; 1190 } 1191 ++nI; 1192 } 1193 } 1194 1195 return nRet; 1196 } 1197 sal_uInt16 SwFEShell::GetRowSelectionFromTop() const 1198 { 1199 sal_uInt16 nRet = 0; 1200 const SwPaM* pPaM = IsTableMode() ? GetTableCrsr() : _GetCrsr(); 1201 const sal_uInt16 nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() ); 1202 1203 if ( !IsTableMode() ) 1204 { 1205 nRet = 0 == nPtLine ? 1 : 0; 1206 } 1207 else 1208 { 1209 const sal_uInt16 nMkLine = lcl_GetRowNumber( *pPaM->GetMark() ); 1210 1211 if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) || 1212 ( nMkLine == 0 && nPtLine != USHRT_MAX ) ) 1213 { 1214 nRet = Max( nPtLine, nMkLine ) + 1; 1215 } 1216 } 1217 1218 return nRet; 1219 } 1220 1221 /* 1222 * 1. case: bRepeat = true 1223 * returns true if the current frame is located inside a table headline in 1224 * a follow frame 1225 * 1226 * 2. case: bRepeat = false 1227 * returns true if the current frame is localed inside a table headline OR 1228 * inside the first line of a table!!! 1229 */ 1230 sal_Bool SwFEShell::CheckHeadline( bool bRepeat ) const 1231 { 1232 sal_Bool bRet = sal_False; 1233 if ( !IsTableMode() ) 1234 { 1235 SwFrm *pFrm = GetCurrFrm(); // DONE MULTIIHEADER 1236 if ( pFrm && pFrm->IsInTab() ) 1237 { 1238 SwTabFrm* pTab = pFrm->FindTabFrm(); 1239 if ( bRepeat ) 1240 { 1241 bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrm ); 1242 } 1243 else 1244 { 1245 bRet = ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm ) || 1246 pTab->IsInHeadline( *pFrm ); 1247 } 1248 } 1249 } 1250 return bRet; 1251 } 1252 1253 /*********************************************************************** 1254 #* Class : SwFEShell 1255 #* Methoden : AdjustCellWidth() 1256 #* Datum : MA 20. Feb. 95 1257 #* Update : MA 27. Jul. 95 1258 #***********************************************************************/ 1259 1260 void SwFEShell::AdjustCellWidth( sal_Bool bBalance ) 1261 { 1262 SET_CURR_SHELL( this ); 1263 StartAllAction(); 1264 1265 //WarteCrsr immer einschalten, weil sich im vorraus nicht so recht 1266 //ermitteln laesst wieviel Inhalt betroffen ist. 1267 TblWait aWait( USHRT_MAX, 0, *GetDoc()->GetDocShell() ); 1268 1269 GetDoc()->AdjustCellWidth( *getShellCrsr( false ), bBalance ); 1270 EndAllActionAndCall(); 1271 } 1272 1273 sal_Bool SwFEShell::IsAdjustCellWidthAllowed( sal_Bool bBalance ) const 1274 { 1275 //Es muss mindestens eine Zelle mit Inhalt in der Selektion enthalten 1276 //sein. 1277 1278 SwFrm *pFrm = GetCurrFrm(); 1279 if( !pFrm || !pFrm->IsInTab() ) 1280 return sal_False; 1281 1282 SwSelBoxes aBoxes; 1283 ::GetTblSelCrs( *this, aBoxes ); 1284 1285 if ( bBalance ) 1286 return aBoxes.Count() > 1; 1287 1288 if ( !aBoxes.Count() ) 1289 { 1290 do 1291 { pFrm = pFrm->GetUpper(); 1292 } while ( !pFrm->IsCellFrm() ); 1293 SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(); 1294 aBoxes.Insert( pBox ); 1295 } 1296 1297 for ( sal_uInt16 i = 0; i < aBoxes.Count(); ++i ) 1298 { 1299 SwTableBox *pBox = aBoxes[i]; 1300 if ( pBox->GetSttNd() ) 1301 { 1302 SwNodeIndex aIdx( *pBox->GetSttNd(), 1 ); 1303 SwTxtNode* pCNd = aIdx.GetNode().GetTxtNode(); 1304 if( !pCNd ) 1305 pCNd = (SwTxtNode*)GetDoc()->GetNodes().GoNext( &aIdx ); 1306 1307 while ( pCNd ) 1308 { 1309 if ( pCNd->GetTxt().Len() ) 1310 return sal_True; 1311 ++aIdx; 1312 pCNd = aIdx.GetNode().GetTxtNode(); 1313 } 1314 } 1315 } 1316 return sal_False; 1317 } 1318 1319 // AutoFormat fuer die Tabelle/TabellenSelection 1320 sal_Bool SwFEShell::SetTableAutoFmt( const SwTableAutoFmt& rNew ) 1321 { 1322 SwTableNode *pTblNd = (SwTableNode*)IsCrsrInTbl(); 1323 if( !pTblNd || pTblNd->GetTable().IsTblComplex() ) 1324 return sal_False; 1325 1326 SwSelBoxes aBoxes; 1327 1328 if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind 1329 GetCrsr(); 1330 1331 // gesamte Tabelle oder nur auf die akt. Selektion 1332 if( IsTableMode() ) 1333 ::GetTblSelCrs( *this, aBoxes ); 1334 else 1335 { 1336 const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes(); 1337 for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n ) 1338 { 1339 SwTableBox* pBox = rTBoxes[ n ]; 1340 aBoxes.Insert( pBox ); 1341 } 1342 } 1343 1344 sal_Bool bRet; 1345 if( aBoxes.Count() ) 1346 { 1347 SET_CURR_SHELL( this ); 1348 StartAllAction(); 1349 bRet = GetDoc()->SetTableAutoFmt( aBoxes, rNew ); 1350 DELETEZ( pLastCols ); 1351 DELETEZ( pLastRows ); 1352 EndAllActionAndCall(); 1353 } 1354 else 1355 bRet = sal_False; 1356 return bRet; 1357 } 1358 1359 sal_Bool SwFEShell::GetTableAutoFmt( SwTableAutoFmt& rGet ) 1360 { 1361 const SwTableNode *pTblNd = IsCrsrInTbl(); 1362 if( !pTblNd || pTblNd->GetTable().IsTblComplex() ) 1363 return sal_False; 1364 1365 SwSelBoxes aBoxes; 1366 1367 if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind 1368 GetCrsr(); 1369 1370 // gesamte Tabelle oder nur auf die akt. Selektion 1371 if( IsTableMode() ) 1372 ::GetTblSelCrs( *this, aBoxes ); 1373 else 1374 { 1375 const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes(); 1376 for( sal_uInt16 n = 0; n < rTBoxes.Count(); ++n ) 1377 { 1378 SwTableBox* pBox = rTBoxes[ n ]; 1379 aBoxes.Insert( pBox ); 1380 } 1381 } 1382 1383 return GetDoc()->GetTableAutoFmt( aBoxes, rGet ); 1384 } 1385 1386 /*********************************************************************** 1387 #* Class : SwFEShell 1388 #* Methoden : DeleteTblSel() 1389 #* Datum : MA 03. May. 93 1390 #* Update : MA 19. Apr. 95 1391 #***********************************************************************/ 1392 sal_Bool SwFEShell::DeleteTblSel() 1393 { 1394 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 1395 SwFrm *pFrm = GetCurrFrm(); 1396 if( !pFrm || !pFrm->IsInTab() ) 1397 return sal_False; 1398 1399 if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 1400 { 1401 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 1402 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 1403 return sal_False; 1404 } 1405 1406 SET_CURR_SHELL( this ); 1407 StartAllAction(); 1408 1409 // lasse ueber das Layout die Boxen suchen 1410 sal_Bool bRet; 1411 SwSelBoxes aBoxes; 1412 GetTblSelCrs( *this, aBoxes ); 1413 if( aBoxes.Count() ) 1414 { 1415 TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() ); 1416 1417 // die Crsr muessen noch aus dem Loesch Bereich entfernt 1418 // werden. Setze sie immer hinter/auf die Tabelle; ueber die 1419 // Dokument-Position werden sie dann immer an die alte Position gesetzt. 1420 while( !pFrm->IsCellFrm() ) 1421 pFrm = pFrm->GetUpper(); 1422 ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() )); 1423 1424 bRet = GetDoc()->DeleteRowCol( aBoxes ); 1425 1426 DELETEZ( pLastCols ); 1427 DELETEZ( pLastRows ); 1428 } 1429 else 1430 bRet = sal_False; 1431 EndAllActionAndCall(); 1432 return bRet; 1433 } 1434 1435 /************************************************************************* 1436 |* 1437 |* SwFEShell::GetCurTabColNum() 1438 |* 1439 |* Ersterstellung MA 03. Feb. 95 1440 |* Letzte Aenderung MA 21. May. 95 1441 | 1442 |*************************************************************************/ 1443 sal_uInt16 SwFEShell::GetCurTabColNum() const 1444 { 1445 //!!!GetCurMouseTabColNum() mitpflegen!!!! 1446 sal_uInt16 nRet = 0; 1447 1448 SwFrm *pFrm = GetCurrFrm(); 1449 ASSERT( pFrm, "Crsr geparkt?" ); 1450 1451 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen 1452 if( pFrm && pFrm->IsInTab() ) 1453 { 1454 do { // JP 26.09.95: warum mit dem CntntFrame und nicht mit 1455 // dem CellFrame vergleichen???? 1456 pFrm = pFrm->GetUpper(); 1457 } while ( !pFrm->IsCellFrm() ); 1458 SWRECTFN( pFrm ) 1459 1460 const SwPageFrm* pPage = pFrm->FindPageFrm(); 1461 1462 //TabCols besorgen, den nur ueber diese erreichen wir die Position. 1463 SwTabCols aTabCols; 1464 GetTabCols( aTabCols ); 1465 1466 if( pFrm->FindTabFrm()->IsRightToLeft() ) 1467 { 1468 long nX = (pFrm->Frm().*fnRect->fnGetRight)() - (pPage->Frm().*fnRect->fnGetLeft)(); 1469 1470 const long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();; 1471 1472 if ( !::IsSame( nX, nRight ) ) 1473 { 1474 nX = nRight - nX + aTabCols.GetLeft(); 1475 for ( sal_uInt16 i = 0; i < aTabCols.Count(); ++i ) 1476 if ( ::IsSame( nX, aTabCols[i] ) ) 1477 { 1478 nRet = i + 1; 1479 break; 1480 } 1481 } 1482 } 1483 else 1484 { 1485 const long nX = (pFrm->Frm().*fnRect->fnGetLeft)() - 1486 (pPage->Frm().*fnRect->fnGetLeft)(); 1487 1488 const long nLeft = aTabCols.GetLeftMin(); 1489 1490 if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) ) 1491 { 1492 for ( sal_uInt16 i = 0; i < aTabCols.Count(); ++i ) 1493 if ( ::IsSame( nX, nLeft + aTabCols[i] ) ) 1494 { 1495 nRet = i + 1; 1496 break; 1497 } 1498 } 1499 } 1500 } 1501 return nRet; 1502 } 1503 1504 /************************************************************************* 1505 |* 1506 |* SwFEShell::GetBox() 1507 |* 1508 |* Ersterstellung MA 22. Jun. 95 1509 |* Letzte Aenderung MA 21. Nov. 96 1510 |* 1511 |*************************************************************************/ 1512 1513 const SwFrm *lcl_FindFrmInTab( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy ) 1514 { 1515 const SwFrm *pFrm = pLay->Lower(); 1516 1517 while( pFrm && pLay->IsAnLower( pFrm ) ) 1518 { 1519 if ( pFrm->Frm().IsNear( rPt, nFuzzy ) ) 1520 { 1521 if ( pFrm->IsLayoutFrm() ) 1522 { 1523 const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy ); 1524 if ( pTmp ) 1525 return pTmp; 1526 } 1527 1528 return pFrm; 1529 } 1530 1531 pFrm = pFrm->FindNext(); 1532 } 1533 1534 return 0; 1535 } 1536 1537 const SwCellFrm *lcl_FindFrm( const SwLayoutFrm *pLay, const Point &rPt, 1538 SwTwips nFuzzy, bool* pbRow, bool* pbCol ) 1539 { 1540 // bMouseMoveRowCols : 1541 // Method is called for 1542 // - Moving columns/rows with the mouse or 1543 // - Enhanced table selection 1544 const bool bMouseMoveRowCols = 0 == pbCol; 1545 1546 bool bCloseToRow = false; 1547 bool bCloseToCol = false; 1548 1549 const SwFrm *pFrm = pLay->ContainsCntnt(); 1550 const SwFrm* pRet = 0; 1551 1552 if ( pFrm ) 1553 { 1554 do 1555 { 1556 if ( pFrm->IsInTab() ) 1557 pFrm = ((SwFrm*)pFrm)->ImplFindTabFrm(); 1558 1559 if ( pFrm->IsTabFrm() ) 1560 { 1561 Point aPt( rPt ); 1562 bool bSearchForFrmInTab = true; 1563 SwTwips nTmpFuzzy = nFuzzy; 1564 1565 if ( !bMouseMoveRowCols ) 1566 { 1567 // We ignore nested tables for the enhanced table selection: 1568 while ( pFrm->GetUpper()->IsInTab() ) 1569 pFrm = pFrm->GetUpper()->FindTabFrm(); 1570 1571 // We first check if the given point is 'close' to the left or top 1572 // border of the table frame: 1573 ASSERT( pFrm, "Nested table frame without outer table" ) 1574 SWRECTFN( pFrm ) 1575 const bool bRTL = pFrm->IsRightToLeft(); 1576 1577 SwRect aTabRect = pFrm->Prt(); 1578 aTabRect.Pos() += pFrm->Frm().Pos(); 1579 1580 const SwTwips nLeft = bRTL ? 1581 (aTabRect.*fnRect->fnGetRight)() : 1582 (aTabRect.*fnRect->fnGetLeft)(); 1583 const SwTwips nTop = (aTabRect.*fnRect->fnGetTop)(); 1584 1585 SwTwips& rPointX = bVert ? aPt.Y() : aPt.X(); 1586 SwTwips& rPointY = bVert ? aPt.X() : aPt.Y(); 1587 1588 const SwTwips nXDiff = (*fnRect->fnXDiff)( nLeft, rPointX ) * ( bRTL ? (-1) : 1 ); 1589 const SwTwips nYDiff = (*fnRect->fnYDiff)( nTop, rPointY ); 1590 1591 bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy; 1592 bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy; 1593 1594 if ( bCloseToCol && 2 * nYDiff > nFuzzy ) 1595 { 1596 const SwFrm* pPrev = pFrm->GetPrev(); 1597 if ( pPrev ) 1598 { 1599 SwRect aPrevRect = pPrev->Prt(); 1600 aPrevRect.Pos() += pPrev->Frm().Pos(); 1601 1602 if( aPrevRect.IsInside( rPt ) ) 1603 { 1604 bCloseToCol = false; 1605 } 1606 } 1607 1608 } 1609 1610 // If we found the point to be 'close' to the left or top border 1611 // of the table frame, we adjust the point to be on that border: 1612 if ( bCloseToRow && bCloseToCol ) 1613 aPt = bRTL ? aTabRect.TopRight() : (aTabRect.*fnRect->fnGetPos)(); 1614 else if ( bCloseToRow ) 1615 rPointX = nLeft; 1616 else if ( bCloseToCol ) 1617 rPointY = nTop; 1618 1619 if ( !bCloseToRow && !bCloseToCol ) 1620 bSearchForFrmInTab = false; 1621 1622 // Since the point has been adjusted, we call lcl_FindFrmInTab() 1623 // with a fuzzy value of 1: 1624 nTmpFuzzy = 1; 1625 } 1626 1627 const SwFrm* pTmp = bSearchForFrmInTab ? 1628 ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, aPt, nTmpFuzzy ) : 1629 0; 1630 1631 if ( pTmp ) 1632 { 1633 pFrm = pTmp; 1634 break; 1635 } 1636 } 1637 pFrm = pFrm->FindNextCnt(); 1638 1639 } while ( pFrm && pLay->IsAnLower( pFrm ) ); 1640 } 1641 1642 if ( pFrm && pFrm->IsInTab() && pLay->IsAnLower( pFrm ) ) 1643 { 1644 do 1645 { 1646 // We allow mouse drag of table borders within nested tables, 1647 // but disallow hotspot selection of nested tables. 1648 if ( bMouseMoveRowCols ) 1649 { 1650 // find the next cell frame 1651 while ( pFrm && !pFrm->IsCellFrm() ) 1652 pFrm = pFrm->GetUpper(); 1653 } 1654 else 1655 { 1656 // find the most upper cell frame: 1657 while ( pFrm && 1658 ( !pFrm->IsCellFrm() || 1659 !pFrm->GetUpper()->GetUpper()->IsTabFrm() || 1660 pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) ) 1661 pFrm = pFrm->GetUpper(); 1662 } 1663 1664 if ( pFrm ) // Note: this condition should be the same like the while condition!!! 1665 { 1666 // --> FME 2004-07-30 #i32329# Enhanced table selection 1667 // used for hotspot selection of tab/cols/rows 1668 if ( !bMouseMoveRowCols ) 1669 { 1670 1671 ASSERT( pbCol && pbRow, "pbCol or pbRow missing" ) 1672 1673 if ( bCloseToRow || bCloseToCol ) 1674 { 1675 *pbRow = bCloseToRow; 1676 *pbCol = bCloseToCol; 1677 pRet = pFrm; 1678 break; 1679 } 1680 } 1681 // <-- 1682 else 1683 { 1684 // used for mouse move of columns/rows 1685 const SwTabFrm* pTabFrm = pFrm->FindTabFrm(); 1686 SwRect aTabRect = pTabFrm->Prt(); 1687 aTabRect.Pos() += pTabFrm->Frm().Pos(); 1688 1689 SWRECTFN( pTabFrm ) 1690 1691 const SwTwips nTabTop = (aTabRect.*fnRect->fnGetTop)(); 1692 const SwTwips nMouseTop = bVert ? rPt.X() : rPt.Y(); 1693 1694 // Do not allow to drag upper table border: 1695 if ( !::IsSame( nTabTop, nMouseTop ) ) 1696 { 1697 if ( ::IsSame( pFrm->Frm().Left(), rPt.X() ) || 1698 ::IsSame( pFrm->Frm().Right(),rPt.X() ) ) 1699 { 1700 if ( pbRow ) *pbRow = false; 1701 pRet = pFrm; 1702 break; 1703 } 1704 if ( ::IsSame( pFrm->Frm().Top(), rPt.Y() ) || 1705 ::IsSame( pFrm->Frm().Bottom(),rPt.Y() ) ) 1706 { 1707 if ( pbRow ) *pbRow = true; 1708 pRet = pFrm; 1709 break; 1710 } 1711 } 1712 } 1713 1714 pFrm = pFrm->GetUpper(); 1715 } 1716 } while ( pFrm ); 1717 } 1718 1719 // robust: 1720 ASSERT( !pRet || pRet->IsCellFrm(), "lcl_FindFrm() is supposed to find a cell frame!" ) 1721 return pRet && pRet->IsCellFrm() ? static_cast<const SwCellFrm*>(pRet) : 0; 1722 } 1723 1724 // 1725 // pbCol = 0 => Used for moving table rows/cols with mouse 1726 // pbCol != 0 => Used for selecting table/rows/cols 1727 // 1728 #define ENHANCED_TABLE_SELECTION_FUZZY 10 1729 1730 const SwFrm* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const 1731 { 1732 const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower(); 1733 Window* pOutWin = GetWin(); 1734 SwTwips nFuzzy = COLFUZZY; 1735 if( pOutWin ) 1736 { 1737 // --> FME 2004-07-30 #i32329# Enhanced table selection 1738 SwTwips nSize = pbCol ? ENHANCED_TABLE_SELECTION_FUZZY : RULER_MOUSE_MARGINWIDTH; 1739 // <-- 1740 Size aTmp( nSize, nSize ); 1741 aTmp = pOutWin->PixelToLogic( aTmp ); 1742 nFuzzy = aTmp.Width(); 1743 } 1744 1745 while ( pPage && !pPage->Frm().IsNear( rPt, nFuzzy ) ) 1746 pPage = (SwPageFrm*)pPage->GetNext(); 1747 1748 const SwCellFrm *pFrm = 0; 1749 if ( pPage ) 1750 { 1751 //Per GetCrsrOfst oder GetCntntPos koennen wir hier die Box leider 1752 //nicht suchen. Das wuerde zu einem Performance-Zusammenbruch bei 1753 //Dokumenten mit vielen Absaetzen/Tabellen auf einer Seite fuehren 1754 //(BrowseMode!) 1755 1756 //Erst die Flys checken. 1757 if ( pPage->GetSortedObjs() ) 1758 { 1759 for ( sal_uInt16 i = 0; !pFrm && i < pPage->GetSortedObjs()->Count(); ++i ) 1760 { 1761 SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i]; 1762 if ( pObj->ISA(SwFlyFrm) ) 1763 { 1764 pFrm = lcl_FindFrm( static_cast<SwFlyFrm*>(pObj), 1765 rPt, nFuzzy, pbRow, pbCol ); 1766 } 1767 } 1768 } 1769 const SwLayoutFrm *pLay = (SwLayoutFrm*)pPage->Lower(); 1770 while ( pLay && !pFrm ) 1771 { 1772 pFrm = lcl_FindFrm( pLay, rPt, nFuzzy, pbRow, pbCol ); 1773 pLay = (SwLayoutFrm*)pLay->GetNext(); 1774 } 1775 } 1776 return pFrm; 1777 } 1778 1779 /* Helper function*/ 1780 /* calculated the distance between Point rC and Line Segment (rA, rB) */ 1781 double lcl_DistancePoint2Segment( const Point& rA, const Point& rB, const Point& rC ) 1782 { 1783 double nRet = 0; 1784 1785 const basegfx::B2DVector aBC( rC.X() - rB.X(), rC.Y() - rB.Y() ); 1786 const basegfx::B2DVector aAB( rB.X() - rA.X(), rB.Y() - rA.Y() ); 1787 const double nDot1 = aBC.scalar( aAB ); 1788 1789 if ( nDot1 > 0 ) // check outside case 1 1790 nRet = aBC.getLength(); 1791 else 1792 { 1793 const basegfx::B2DVector aAC( rC.X() - rA.X(), rC.Y() - rA.Y() ); 1794 const basegfx::B2DVector aBA( rA.X() - rB.X(), rA.Y() - rB.Y() ); 1795 const double nDot2 = aAC.scalar( aBA ); 1796 1797 if ( nDot2 > 0 ) // check outside case 2 1798 nRet = aAC.getLength(); 1799 else 1800 { 1801 const double nDiv = aAB.getLength(); 1802 nRet = nDiv ? aAB.cross( aAC ) / nDiv : 0; 1803 } 1804 } 1805 1806 return Abs(nRet); 1807 } 1808 1809 /* Helper function*/ 1810 Point lcl_ProjectOntoClosestTableFrm( const SwTabFrm& rTab, const Point& rPoint, bool bRowDrag ) 1811 { 1812 Point aRet( rPoint ); 1813 const SwTabFrm* pCurrentTab = &rTab; 1814 const bool bVert = pCurrentTab->IsVertical(); 1815 const bool bRTL = pCurrentTab->IsRightToLeft(); 1816 1817 // Western Layout: 1818 // bRowDrag = true => compare to left border of table 1819 // bRowDrag = false => compare to top border of table 1820 1821 // Asian Layout: 1822 // bRowDrag = true => compare to right border of table 1823 // bRowDrag = false => compare to top border of table 1824 1825 // RTL Layout: 1826 // bRowDrag = true => compare to right border of table 1827 // bRowDrag = false => compare to top border of table 1828 bool bLeft = false; 1829 bool bRight = false; 1830 1831 if ( bRowDrag ) 1832 { 1833 if ( bVert || bRTL ) 1834 bRight = true; 1835 else 1836 bLeft = true; 1837 } 1838 1839 // used to find the minimal distance 1840 double nMin = -1; 1841 Point aMin1; 1842 Point aMin2; 1843 1844 Point aS1; 1845 Point aS2; 1846 1847 while ( pCurrentTab ) 1848 { 1849 SwRect aTabRect( pCurrentTab->Prt() ); 1850 aTabRect += pCurrentTab->Frm().Pos(); 1851 1852 if ( bLeft ) 1853 { 1854 // distance to left table border 1855 aS1 = aTabRect.TopLeft(); 1856 aS2 = aTabRect.BottomLeft(); 1857 } 1858 else if ( bRight ) 1859 { 1860 // distance to right table border 1861 aS1 = aTabRect.TopRight(); 1862 aS2 = aTabRect.BottomRight(); 1863 } 1864 else //if ( bTop ) 1865 { 1866 // distance to top table border 1867 aS1 = aTabRect.TopLeft(); 1868 aS2 = aTabRect.TopRight(); 1869 } 1870 1871 const double nDist = lcl_DistancePoint2Segment( aS1, aS2, rPoint ); 1872 1873 if ( nDist < nMin || -1 == nMin ) 1874 { 1875 aMin1 = aS1; 1876 aMin2 = aS2; 1877 nMin = nDist; 1878 } 1879 1880 pCurrentTab = pCurrentTab->GetFollow(); 1881 } 1882 1883 // project onto closest line: 1884 if ( bLeft || bRight ) 1885 { 1886 aRet.X() = aMin1.X(); 1887 if ( aRet.Y() > aMin2.Y() ) 1888 aRet.Y() = aMin2.Y(); 1889 else if ( aRet.Y() < aMin1.Y() ) 1890 aRet.Y() = aMin1.Y(); 1891 } 1892 else //if ( bTop ) 1893 { 1894 aRet.Y() = aMin1.Y(); 1895 if ( aRet.X() > aMin2.X() ) 1896 aRet.X() = aMin2.X(); 1897 else if ( aRet.X() < aMin1.X() ) 1898 aRet.X() = aMin1.X(); 1899 } 1900 1901 return aRet; 1902 } 1903 1904 // --> FME 2004-07-30 #i32329# Enhanced table selection 1905 bool SwFEShell::SelTblRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag ) 1906 { 1907 bool bRet = false; 1908 Point aEndPt; 1909 if ( pEnd ) 1910 aEndPt = *pEnd; 1911 1912 SwPosition* ppPos[2] = { 0, 0 }; 1913 Point paPt [2] = { rPt, aEndPt }; 1914 bool pbRow[2] = { 0, 0 }; 1915 bool pbCol[2] = { 0, 0 }; 1916 1917 // pEnd is set during dragging. 1918 for ( sal_uInt16 i = 0; i < ( pEnd ? 2 : 1 ); ++i ) 1919 { 1920 const SwCellFrm* pFrm = 1921 static_cast<const SwCellFrm*>(GetBox( paPt[i], &pbRow[i], &pbCol[i] ) ); 1922 1923 if( pFrm ) 1924 { 1925 while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() ) 1926 pFrm = static_cast<const SwCellFrm*>( static_cast<const SwLayoutFrm*>( pFrm->Lower() )->Lower() ); 1927 if( pFrm && pFrm->GetTabBox()->GetSttNd() && 1928 pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() ) 1929 pFrm = 0; 1930 } 1931 1932 if ( pFrm ) 1933 { 1934 const SwCntntFrm* pCntnt = ::GetCellCntnt( *pFrm ); 1935 1936 if ( pCntnt && pCntnt->IsTxtFrm() ) 1937 { 1938 ppPos[i] = new SwPosition( *pCntnt->GetNode() ); 1939 ppPos[i]->nContent.Assign( const_cast<SwCntntNode*>(pCntnt->GetNode()), 0 ); 1940 1941 // paPt[i] will not be used any longer, now we use it to store 1942 // a position inside the content frame 1943 paPt[i] = pCntnt->Frm().Center(); 1944 } 1945 } 1946 1947 // no calculation of end frame if start frame has not been found. 1948 if ( 1 == i || !ppPos[0] || !pEnd ) 1949 break; 1950 1951 // find 'closest' table frame to pEnd: 1952 const SwTabFrm* pCurrentTab = pFrm->FindTabFrm(); 1953 if ( pCurrentTab->IsFollow() ) 1954 pCurrentTab = pCurrentTab->FindMaster( true ); 1955 1956 const Point aProjection = lcl_ProjectOntoClosestTableFrm( *pCurrentTab, *pEnd, bRowDrag ); 1957 paPt[1] = aProjection; 1958 } 1959 1960 if ( ppPos[0] ) 1961 { 1962 SwShellCrsr* pCrsr = _GetCrsr(); 1963 SwCrsrSaveState aSaveState( *pCrsr ); 1964 SwPosition aOldPos( *pCrsr->GetPoint() ); 1965 1966 pCrsr->DeleteMark(); 1967 *pCrsr->GetPoint() = *ppPos[0]; 1968 pCrsr->GetPtPos() = paPt[0]; 1969 1970 if ( !pCrsr->IsInProtectTable( sal_False, sal_True ) ) 1971 { 1972 bool bNewSelection = true; 1973 1974 if ( ppPos[1] ) 1975 { 1976 if ( ppPos[1]->nNode.GetNode().StartOfSectionNode() != 1977 aOldPos.nNode.GetNode().StartOfSectionNode() ) 1978 { 1979 pCrsr->SetMark(); 1980 SwCrsrSaveState aSaveState2( *pCrsr ); 1981 *pCrsr->GetPoint() = *ppPos[1]; 1982 pCrsr->GetPtPos() = paPt[1]; 1983 1984 if ( pCrsr->IsInProtectTable( sal_False, sal_False ) ) 1985 { 1986 pCrsr->RestoreSavePos(); 1987 bNewSelection = false; 1988 } 1989 } 1990 else 1991 { 1992 pCrsr->RestoreSavePos(); 1993 bNewSelection = false; 1994 } 1995 } 1996 1997 if ( bNewSelection ) 1998 { 1999 // --> FME 2004-10-20 #i35543# SelTblRowCol should remove any existing 2000 // table cursor: 2001 if ( IsTableMode() ) 2002 TblCrsrToCursor(); 2003 // <-- 2004 2005 if ( pbRow[0] && pbCol[0] ) 2006 bRet = SwCrsrShell::SelTbl(); 2007 else if ( pbRow[0] ) 2008 bRet = SwCrsrShell::_SelTblRowOrCol( true, true ); 2009 else if ( pbCol[0] ) 2010 bRet = SwCrsrShell::_SelTblRowOrCol( false, true ); 2011 } 2012 else 2013 bRet = true; 2014 } 2015 2016 delete ppPos[0]; 2017 delete ppPos[1]; 2018 } 2019 2020 return bRet; 2021 } 2022 // <-- 2023 2024 2025 /************************************************************************* 2026 |* 2027 |* SwFEShell::WhichMouseTabCol() 2028 |* 2029 |* Ersterstellung MA 22. Jun. 95 2030 |* Last change AMA 12. Jun. 02 2031 | 2032 |*************************************************************************/ 2033 sal_uInt8 SwFEShell::WhichMouseTabCol( const Point &rPt ) const 2034 { 2035 sal_uInt8 nRet = SW_TABCOL_NONE; 2036 bool bRow = false; 2037 bool bCol = false; 2038 bool bSelect = false; 2039 2040 // First try: Do we get the row/col move cursor? 2041 SwCellFrm* pFrm = (SwCellFrm*)GetBox( rPt, &bRow, 0 ); 2042 2043 if ( !pFrm ) 2044 { 2045 // Second try: Do we get the row/col/tab selection cursor? 2046 pFrm = (SwCellFrm*)GetBox( rPt, &bRow, &bCol ); 2047 bSelect = true; 2048 } 2049 2050 if( pFrm ) 2051 { 2052 while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() ) 2053 pFrm = (SwCellFrm*)((SwLayoutFrm*)pFrm->Lower())->Lower(); 2054 if( pFrm && pFrm->GetTabBox()->GetSttNd() && 2055 pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() ) 2056 pFrm = 0; 2057 } 2058 2059 if( pFrm ) 2060 { 2061 if ( !bSelect ) 2062 { 2063 if ( pFrm->IsVertical() ) 2064 nRet = bRow ? SW_TABCOL_VERT : SW_TABROW_VERT; 2065 else 2066 nRet = bRow ? SW_TABROW_HORI : SW_TABCOL_HORI; 2067 } 2068 else 2069 { 2070 const SwTabFrm* pTabFrm = pFrm->FindTabFrm(); 2071 if ( pTabFrm->IsVertical() ) 2072 { 2073 if ( bRow && bCol ) 2074 { 2075 nRet = SW_TABSEL_VERT; 2076 } 2077 else if ( bRow ) 2078 { 2079 nRet = SW_TABROWSEL_VERT; 2080 } 2081 else if ( bCol ) 2082 { 2083 nRet = SW_TABCOLSEL_VERT; 2084 } 2085 } 2086 else 2087 { 2088 if ( bRow && bCol ) 2089 { 2090 nRet = pTabFrm->IsRightToLeft() ? 2091 SW_TABSEL_HORI_RTL : 2092 SW_TABSEL_HORI; 2093 } 2094 else if ( bRow ) 2095 { 2096 nRet = pTabFrm->IsRightToLeft() ? 2097 SW_TABROWSEL_HORI_RTL : 2098 SW_TABROWSEL_HORI; 2099 } 2100 else if ( bCol ) 2101 { 2102 nRet = SW_TABCOLSEL_HORI; 2103 } 2104 } 2105 } 2106 } 2107 2108 return nRet; 2109 } 2110 2111 // -> #i23726# 2112 SwTxtNode * SwFEShell::GetNumRuleNodeAtPos( const Point &rPt) 2113 { 2114 SwTxtNode * pResult = NULL; 2115 2116 SwContentAtPos aCntntAtPos 2117 (SwContentAtPos::SW_NUMLABEL); 2118 2119 if( GetContentAtPos(rPt, aCntntAtPos) && aCntntAtPos.aFnd.pNode) 2120 pResult = aCntntAtPos.aFnd.pNode->GetTxtNode(); 2121 2122 return pResult; 2123 } 2124 2125 sal_Bool SwFEShell::IsNumLabel( const Point &rPt, int nMaxOffset ) 2126 { 2127 sal_Bool bResult = sal_False; 2128 2129 SwContentAtPos aCntntAtPos 2130 (SwContentAtPos::SW_NUMLABEL); 2131 2132 if( GetContentAtPos(rPt, aCntntAtPos)) 2133 { 2134 if ((nMaxOffset >= 0 && aCntntAtPos.nDist <= nMaxOffset) || 2135 (nMaxOffset < 0)) 2136 bResult = sal_True; 2137 } 2138 2139 return bResult; 2140 } 2141 // <- #i23726# 2142 2143 // --> OD 2005-02-21 #i42921# 2144 bool SwFEShell::IsVerticalModeAtNdAndPos( const SwTxtNode& _rTxtNode, 2145 const Point& _rDocPos ) const 2146 { 2147 bool bRet( false ); 2148 2149 const short nTextDir = 2150 _rTxtNode.GetTextDirection( SwPosition(_rTxtNode), &_rDocPos ); 2151 switch ( nTextDir ) 2152 { 2153 case -1: 2154 case FRMDIR_HORI_RIGHT_TOP: 2155 case FRMDIR_HORI_LEFT_TOP: 2156 { 2157 bRet = false; 2158 } 2159 break; 2160 case FRMDIR_VERT_TOP_LEFT: 2161 case FRMDIR_VERT_TOP_RIGHT: 2162 { 2163 bRet = true; 2164 } 2165 break; 2166 } 2167 2168 return bRet; 2169 } 2170 // <-- 2171 2172 /************************************************************************* 2173 |* 2174 |* SwFEShell::GetMouseTabCols() 2175 |* 2176 |* Ersterstellung MA 22. Jun. 95 2177 |* Letzte Aenderung MA 27. Aug. 96 2178 | 2179 |*************************************************************************/ 2180 void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const 2181 { 2182 const SwFrm *pBox = GetBox( rPt ); 2183 if ( pBox ) 2184 _GetTabCols( rToFill, pBox ); 2185 } 2186 2187 void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, sal_Bool bCurRowOnly, 2188 const Point &rPt ) 2189 { 2190 const SwFrm *pBox = GetBox( rPt ); 2191 if( pBox ) 2192 { 2193 SET_CURR_SHELL( this ); 2194 StartAllAction(); 2195 GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox ); 2196 EndAllActionAndCall(); 2197 } 2198 } 2199 2200 /************************************************************************* 2201 |* 2202 |* SwFEShell::GetMouseColNum(), GetMouseTabColNum() 2203 |* 2204 |* Ersterstellung MA 04. Jul. 95 2205 |* Letzte Aenderung MA 04. Jul. 95 2206 | 2207 |*************************************************************************/ 2208 sal_uInt16 SwFEShell::GetCurMouseColNum( const Point &rPt, 2209 SwGetCurColNumPara* pPara ) const 2210 { 2211 return _GetCurColNum( GetBox( rPt ), pPara ); 2212 } 2213 2214 sal_uInt16 SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const 2215 { 2216 //!!!GetCurTabColNum() mitpflegen!!!! 2217 sal_uInt16 nRet = 0; 2218 2219 const SwFrm *pFrm = GetBox( rPt ); 2220 ASSERT( pFrm, "Table not found" ); 2221 if( pFrm ) 2222 { 2223 const long nX = pFrm->Frm().Left(); 2224 2225 //TabCols besorgen, den nur ueber diese erreichen wir die Position. 2226 SwTabCols aTabCols; 2227 GetMouseTabCols( aTabCols, rPt ); 2228 2229 const long nLeft = aTabCols.GetLeftMin(); 2230 2231 if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) ) 2232 { 2233 for ( sal_uInt16 i = 0; i < aTabCols.Count(); ++i ) 2234 if ( ::IsSame( nX, nLeft + aTabCols[i] ) ) 2235 { 2236 nRet = i + 1; 2237 break; 2238 } 2239 } 2240 } 2241 return nRet; 2242 } 2243 2244 void ClearFEShellTabCols() 2245 { 2246 DELETEZ( pLastCols ); 2247 DELETEZ( pLastRows ); 2248 } 2249 2250 /************************************************************************* 2251 |* 2252 |* SwFEShell::GetTblAttr(), SetTblAttr() 2253 |* 2254 |* Ersterstellung MA 09. Dec. 96 2255 |* Letzte Aenderung MA 09. Dec. 96 2256 | 2257 |*************************************************************************/ 2258 void SwFEShell::GetTblAttr( SfxItemSet &rSet ) const 2259 { 2260 SwFrm *pFrm = GetCurrFrm(); 2261 if( pFrm && pFrm->IsInTab() ) 2262 rSet.Put( pFrm->ImplFindTabFrm()->GetFmt()->GetAttrSet() ); 2263 } 2264 2265 void SwFEShell::SetTblAttr( const SfxItemSet &rNew ) 2266 { 2267 SwFrm *pFrm = GetCurrFrm(); 2268 if( pFrm && pFrm->IsInTab() ) 2269 { 2270 SET_CURR_SHELL( this ); 2271 StartAllAction(); 2272 SwTabFrm *pTab = pFrm->FindTabFrm(); 2273 pTab->GetTable()->SetHTMLTableLayout( 0 ); 2274 GetDoc()->SetAttr( rNew, *pTab->GetFmt() ); 2275 GetDoc()->SetModified(); 2276 EndAllActionAndCall(); 2277 } 2278 } 2279 2280 /** move cursor within a table into previous/next row (same column) 2281 * @param pShell cursor shell whose cursor is to be moved 2282 * @param bUp true: move up, false: move down 2283 * @returns true if successful 2284 */ 2285 bool lcl_GoTableRow( SwCrsrShell* pShell, bool bUp ) 2286 { 2287 ASSERT( pShell != NULL, "need shell" ); 2288 2289 bool bRet = false; 2290 2291 SwPaM* pPam = pShell->GetCrsr(); 2292 const SwStartNode* pTableBox = pPam->GetNode()->FindTableBoxStartNode(); 2293 ASSERT( pTableBox != NULL, "I'm living in a box... NOT!" ); 2294 2295 // move cursor to start node of table box 2296 pPam->GetPoint()->nNode = pTableBox->GetIndex(); 2297 pPam->GetPoint()->nContent.Assign( NULL, 0 ); 2298 GoInCntnt( *pPam, fnMoveForward ); 2299 2300 // go to beginning end of table box 2301 SwPosSection fnPosSect = bUp ? fnSectionStart : fnSectionEnd; 2302 pShell->MoveSection( fnSectionCurr, fnPosSect ); 2303 2304 // and go up/down into next content 2305 bRet = bUp ? pShell->Up() : pShell->Down(); 2306 2307 return bRet; 2308 } 2309 2310 // aender eine Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe 2311 sal_Bool SwFEShell::SetColRowWidthHeight( sal_uInt16 eType, sal_uInt16 nDiff ) 2312 { 2313 SwFrm *pFrm = GetCurrFrm(); 2314 if( !pFrm || !pFrm->IsInTab() ) 2315 return sal_False; 2316 2317 if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType && 2318 pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable )) 2319 { 2320 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR, 2321 ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK ); 2322 return sal_False; 2323 } 2324 2325 SET_CURR_SHELL( this ); 2326 StartAllAction(); 2327 2328 do { 2329 pFrm = pFrm->GetUpper(); 2330 } while( !pFrm->IsCellFrm() ); 2331 2332 SwTabFrm *pTab = pFrm->ImplFindTabFrm(); 2333 2334 // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen 2335 // dann muss es jetzt auf absolute umgerechnet werden. 2336 const SwFmtFrmSize& rTblFrmSz = pTab->GetFmt()->GetFrmSize(); 2337 SWRECTFN( pTab ) 2338 long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)(); 2339 if( TBLVAR_CHGABS == pTab->GetTable()->GetTblChgMode() && 2340 ( eType & nsTblChgWidthHeightType::WH_COL_LEFT || eType & nsTblChgWidthHeightType::WH_COL_RIGHT ) && 2341 text::HoriOrientation::NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() && 2342 nPrtWidth != rTblFrmSz.GetWidth() ) 2343 { 2344 SwFmtFrmSize aSz( rTblFrmSz ); 2345 aSz.SetWidth( pTab->Prt().Width() ); 2346 pTab->GetFmt()->SetFmtAttr( aSz ); 2347 } 2348 2349 if( (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) == 2350 (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL) ) 2351 { 2352 nDiff = sal_uInt16((pFrm->Frm().*fnRect->fnGetWidth)()); 2353 2354 // we must move the cursor outside the current cell before 2355 // deleting the cells. 2356 TblChgWidthHeightType eTmp = 2357 static_cast<TblChgWidthHeightType>( eType & 0xfff ); 2358 switch( eTmp ) 2359 { 2360 case nsTblChgWidthHeightType::WH_ROW_TOP: 2361 lcl_GoTableRow( this, true ); 2362 break; 2363 case nsTblChgWidthHeightType::WH_ROW_BOTTOM: 2364 lcl_GoTableRow( this, false ); 2365 break; 2366 case nsTblChgWidthHeightType::WH_COL_LEFT: 2367 GoPrevCell(); 2368 break; 2369 case nsTblChgWidthHeightType::WH_COL_RIGHT: 2370 GoNextCell(); 2371 break; 2372 default: 2373 break; 2374 } 2375 } 2376 2377 SwTwips nLogDiff = nDiff; 2378 nLogDiff *= pTab->GetFmt()->GetFrmSize().GetWidth(); 2379 nLogDiff /= nPrtWidth; 2380 2381 /** The cells are destroyed in here */ 2382 sal_Bool bRet = GetDoc()->SetColRowWidthHeight( 2383 *(SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(), 2384 eType, nDiff, nLogDiff ); 2385 2386 delete pLastCols, pLastCols = 0; 2387 EndAllActionAndCall(); 2388 2389 if( bRet && (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) == nsTblChgWidthHeightType::WH_FLAG_INSDEL ) 2390 { 2391 switch(eType & ~(nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) 2392 { 2393 case nsTblChgWidthHeightType::WH_CELL_LEFT: 2394 case nsTblChgWidthHeightType::WH_COL_LEFT: 2395 GoPrevCell(); 2396 break; 2397 2398 case nsTblChgWidthHeightType::WH_CELL_RIGHT: 2399 case nsTblChgWidthHeightType::WH_COL_RIGHT: 2400 GoNextCell(); 2401 break; 2402 2403 case nsTblChgWidthHeightType::WH_CELL_TOP: 2404 case nsTblChgWidthHeightType::WH_ROW_TOP: 2405 lcl_GoTableRow( this, true ); 2406 break; 2407 2408 case nsTblChgWidthHeightType::WH_CELL_BOTTOM: 2409 case nsTblChgWidthHeightType::WH_ROW_BOTTOM: 2410 lcl_GoTableRow( this, false ); 2411 break; 2412 } 2413 } 2414 2415 return bRet; 2416 } 2417 2418 sal_Bool lcl_IsFormulaSelBoxes( const SwTable& rTbl, const SwTblBoxFormula& rFml, 2419 SwCellFrms& rCells ) 2420 { 2421 SwTblBoxFormula aTmp( rFml ); 2422 SwSelBoxes aBoxes; 2423 for( sal_uInt16 nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes ); nSelBoxes; ) 2424 { 2425 SwTableBox* pBox = aBoxes[ --nSelBoxes ]; 2426 sal_uInt16 i; 2427 for( i = 0; i < rCells.Count(); ++i ) 2428 if( rCells[ i ]->GetTabBox() == pBox ) 2429 break; // gefunden 2430 2431 if( i == rCells.Count() ) 2432 return sal_False; 2433 } 2434 2435 return sal_True; 2436 } 2437 2438 // erfrage die Formel fuer die Autosumme 2439 sal_Bool SwFEShell::GetAutoSum( String& rFml ) const 2440 { 2441 SwFrm *pFrm = GetCurrFrm(); 2442 SwTabFrm *pTab = pFrm ? pFrm->ImplFindTabFrm() : 0; 2443 if( !pTab ) 2444 return sal_False; 2445 2446 rFml = String::CreateFromAscii( sCalc_Sum ); 2447 2448 SwCellFrms aCells; 2449 if( ::GetAutoSumSel( *this, aCells )) 2450 { 2451 sal_uInt16 nW = 0, nInsPos = 0; 2452 for( sal_uInt16 n = aCells.Count(); n; ) 2453 { 2454 SwCellFrm* pCFrm = aCells[ --n ]; 2455 sal_uInt16 nBoxW = pCFrm->GetTabBox()->IsFormulaOrValueBox(); 2456 if( !nBoxW ) 2457 break; 2458 2459 if( !nW ) 2460 { 2461 if( USHRT_MAX == nBoxW ) 2462 continue; // leere am Anfang ueberspringen 2463 2464 rFml += '('; 2465 nInsPos = rFml.Len(); 2466 2467 // Formeln nur wenn diese Boxen enthalten 2468 if( RES_BOXATR_FORMULA == nBoxW && 2469 !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm-> 2470 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells)) 2471 { 2472 nW = RES_BOXATR_VALUE; 2473 // alle vorhierigen Leere wieder mit aufnehmen ! 2474 for( sal_uInt16 i = aCells.Count(); n+1 < i; ) 2475 { 2476 String sTmp( String::CreateFromAscii( 2477 RTL_CONSTASCII_STRINGPARAM( "|<" )) ); 2478 sTmp += aCells[ --i ]->GetTabBox()->GetName(); 2479 sTmp += '>'; 2480 rFml.Insert( sTmp, nInsPos ); 2481 } 2482 } 2483 else 2484 nW = nBoxW; 2485 } 2486 else if( RES_BOXATR_VALUE == nW ) 2487 { 2488 // values werden gesucht, Value/Formel/Text gefunden -> aufn. 2489 if( RES_BOXATR_FORMULA == nBoxW && 2490 ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm-> 2491 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells )) 2492 break; 2493 else if( USHRT_MAX != nBoxW ) 2494 rFml.Insert( cListDelim, nInsPos ); 2495 else 2496 break; 2497 } 2498 else if( RES_BOXATR_FORMULA == nW ) 2499 { 2500 // bei Formeln nur weiter suchen, wenn die akt. Formel auf 2501 // alle Boxen verweist, die sich in der Selektion befinden 2502 if( RES_BOXATR_FORMULA == nBoxW ) 2503 { 2504 if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm-> 2505 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells )) 2506 { 2507 // dann noch mal von vorne und nur die Values! 2508 2509 nW = RES_BOXATR_VALUE; 2510 rFml.Erase( nInsPos ); 2511 // alle vorhierigen Leere wieder mit aufnehmen ! 2512 for( sal_uInt16 i = aCells.Count(); n+1 < i; ) 2513 { 2514 String sTmp( String::CreateFromAscii( 2515 RTL_CONSTASCII_STRINGPARAM( "|<" )) ); 2516 sTmp += aCells[ --i ]->GetTabBox()->GetName(); 2517 sTmp += '>'; 2518 rFml.Insert( sTmp, nInsPos ); 2519 } 2520 } 2521 else 2522 rFml.Insert( cListDelim, nInsPos ); 2523 } 2524 else if( USHRT_MAX == nBoxW ) 2525 break; 2526 else 2527 continue; // diese Boxen ignorieren 2528 } 2529 else 2530 // alles andere beendet die Schleife 2531 // evt. Texte noch zu lassen?? 2532 break; 2533 2534 String sTmp( '<' ); 2535 sTmp += pCFrm->GetTabBox()->GetName(); 2536 sTmp += '>'; 2537 rFml.Insert( sTmp, nInsPos ); 2538 } 2539 if( nW ) 2540 { 2541 rFml += ')'; 2542 2543 /* 2544 // TabellenSelektion erzeugen?? 2545 SwTblBoxFormula aTmp( rFml ); 2546 SwSelBoxes aBoxes; 2547 for( sal_uInt16 nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes ); 2548 nSelBoxes; ) 2549 { 2550 } 2551 */ 2552 } 2553 } 2554 2555 return sal_True; 2556 } 2557 /* -----------------------------22.08.2002 12:50------------------------------ 2558 2559 ---------------------------------------------------------------------------*/ 2560 sal_Bool SwFEShell::IsTableRightToLeft() const 2561 { 2562 SwFrm *pFrm = GetCurrFrm(); 2563 if( !pFrm || !pFrm->IsInTab() ) 2564 return sal_False; 2565 2566 return pFrm->ImplFindTabFrm()->IsRightToLeft(); 2567 } 2568 2569 /* -----------------------------22.08.2002 12:50------------------------------ 2570 2571 ---------------------------------------------------------------------------*/ 2572 sal_Bool SwFEShell::IsMouseTableRightToLeft(const Point &rPt) const 2573 { 2574 SwFrm *pFrm = (SwFrm *)GetBox( rPt ); 2575 const SwTabFrm* pTabFrm = pFrm ? pFrm->ImplFindTabFrm() : 0; 2576 ASSERT( pTabFrm, "Table not found" ); 2577 return pTabFrm ? pTabFrm->IsRightToLeft() : sal_False; 2578 } 2579 2580 /* -----------------------------11.02.2004 12:50------------------------------ 2581 2582 ---------------------------------------------------------------------------*/ 2583 sal_Bool SwFEShell::IsTableVertical() const 2584 { 2585 SwFrm *pFrm = GetCurrFrm(); 2586 if( !pFrm || !pFrm->IsInTab() ) 2587 return sal_False; 2588 2589 return pFrm->ImplFindTabFrm()->IsVertical(); 2590 } 2591 2592 2593 2594