1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fetab.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <hintids.hxx>
37 #include <tools/errinf.hxx>
38 #include <vcl/svapp.hxx>
39 #include <basegfx/vector/b2dvector.hxx>
40 #ifndef _SVX_SVXIDS_HRC
41 #include <svx/svxids.hrc>
43 #include <svx/protitem.hxx>
44 #include <svx/brshitem.hxx>
45 #include <svx/frmdiritem.hxx>
46 #include <svtools/ruler.hxx>
48 #include <fmtfsize.hxx>
49 #include <fmtornt.hxx>
55 #include <rootfrm.hxx>
56 #include <pagefrm.hxx>
59 #include <cellfrm.hxx>
61 #include <dflyobj.hxx>
62 #include <swtable.hxx>
63 #include <swddetbl.hxx>
67 #include <cellatr.hxx>
71 #include <swtblfmt.hxx>
74 #include <frmtool.hxx>
76 #include <node.hxx> // #i23726#
77 // OD 2004-05-24 #i28701#
78 #include <sortedobjs.hxx>
80 using namespace ::com::sun::star
;
83 //siehe auch swtable.cxx
86 inline BOOL
IsSame( long nA
, long nB
) { return Abs(nA
-nB
) <= COLFUZZY
; }
87 inline BOOL
IsNear( long nA
, long nB
, long nTolerance
) { return Abs( nA
- nB
) <= nTolerance
; }
90 SwTabCols
*pLastCols
= 0;
91 const SwTable
*pColumnCacheLastTable
= 0;
92 const SwTabFrm
*pColumnCacheLastTabFrm
= 0;
93 const SwFrm
*pColumnCacheLastCellFrm
= 0;
96 SwTabCols
*pLastRows
= 0;
97 const SwTable
*pRowCacheLastTable
= 0;
98 const SwTabFrm
*pRowCacheLastTabFrm
= 0;
99 const SwFrm
*pRowCacheLastCellFrm
= 0;
106 TblWait( USHORT nCnt
, SwFrm
*pFrm
, SwDocShell
&rDocShell
, USHORT nCnt2
= 0);
107 ~TblWait() { delete pWait
; }
110 TblWait::TblWait( USHORT nCnt
, SwFrm
*pFrm
, SwDocShell
&rDocShell
, USHORT nCnt2
):
113 BOOL bWait
= 20 < nCnt
|| 20 < nCnt2
|| (pFrm
&&
114 20 < pFrm
->ImplFindTabFrm()->GetTable()->GetTabLines().Count());
116 pWait
= new SwWait( rDocShell
, TRUE
);
120 void SwFEShell::ParkCursorInTab()
122 SwCursor
* pSwCrsr
= GetSwCrsr();
124 ASSERT(pSwCrsr
, "no SwCursor");
126 SwPosition aStartPos
= *pSwCrsr
->GetPoint(), aEndPos
= aStartPos
;
128 SwCursor
* pTmpCrsr
= (SwCursor
*) pSwCrsr
;
130 /* Search least and greatest position in current cursor ring.
134 const SwPosition
* pPt
= pTmpCrsr
->GetPoint(),
135 * pMk
= pTmpCrsr
->GetMark();
137 if (*pPt
< aStartPos
)
143 if (*pMk
< aStartPos
)
149 pTmpCrsr
= (SwCursor
*) pTmpCrsr
->GetNext();
151 while (pTmpCrsr
!= pSwCrsr
);
155 /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */
157 /* Set cursor to end of selection to ensure IsLastCellInRow works
160 SwCursor
aTmpCrsr( aEndPos
, 0, false );
164 /* Move the cursor out of the columns to delete and stay in the
165 same row. If the table has only one column the cursor will
166 stay in the row and the shell will take care of it. */
167 if (IsLastCellInRow())
169 /* If the cursor is in the last row of the table, first
170 try to move it to the previous cell. If that fails move
171 it to the next cell. */
174 SwCursor
aTmpCrsr( aStartPos
, 0, false );
178 if (! pSwCrsr
->GoPrevCell())
180 SwCursor
aTmpCrsr( aEndPos
, 0, false );
182 pSwCrsr
->GoNextCell();
187 /* If the cursor is not in the last row of the table, first
188 try to move it to the next cell. If that fails move it
189 to the previous cell. */
192 SwCursor
aTmpCrsr( aEndPos
, 0, false );
196 if (! pSwCrsr
->GoNextCell())
198 SwCursor
aTmpCrsr( aStartPos
, 0, false );
200 pSwCrsr
->GoPrevCell();
205 /***********************************************************************
207 #* Methoden : InsertRow(), InsertCol
208 #* Datum : MA 03. May. 93
209 #* Update : MA 19. Apr. 95
210 #***********************************************************************/
211 BOOL
SwFEShell::InsertRow( USHORT nCnt
, BOOL bBehind
)
213 // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
214 SwFrm
*pFrm
= GetCurrFrm();
215 if( !pFrm
|| !pFrm
->IsInTab() )
218 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
220 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
221 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
225 SET_CURR_SHELL( this );
228 // lasse ueber das Layout die Boxen suchen
230 GetTblSel( *this, aBoxes
, nsSwTblSearchType::TBLSEARCH_ROW
);
232 TblWait( nCnt
, pFrm
, *GetDoc()->GetDocShell(), aBoxes
.Count() );
235 if ( aBoxes
.Count() )
236 bRet
= GetDoc()->InsertRow( aBoxes
, nCnt
, bBehind
);
238 EndAllActionAndCall();
242 BOOL
SwFEShell::InsertCol( USHORT nCnt
, BOOL bBehind
)
244 // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
245 SwFrm
*pFrm
= GetCurrFrm();
246 if( !pFrm
|| !pFrm
->IsInTab() )
249 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
251 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
252 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
256 SET_CURR_SHELL( this );
258 if( !CheckSplitCells( *this, nCnt
+ 1, nsSwTblSearchType::TBLSEARCH_COL
) )
260 ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR
,
261 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
266 // lasse ueber das Layout die Boxen suchen
268 GetTblSel( *this, aBoxes
, nsSwTblSearchType::TBLSEARCH_COL
);
270 TblWait( nCnt
, pFrm
, *GetDoc()->GetDocShell(), aBoxes
.Count() );
274 bRet
= GetDoc()->InsertCol( aBoxes
, nCnt
, bBehind
);
276 EndAllActionAndCall();
280 /***********************************************************************
282 #* Methoden : DeleteRow(), DeleteCol()
283 #* Datum : MA 03. May. 93
284 #* Update : MA 19. Apr. 95
285 #***********************************************************************/
288 Determines if the current cursor is in the last row of the table.
290 BOOL
SwFEShell::IsLastCellInRow() const
293 GetTabCols( aTabCols
);
294 BOOL bResult
= FALSE
;
296 if (IsTableRightToLeft())
297 /* If the table is right-to-left the last row is the most left one. */
298 bResult
= 0 == GetCurTabColNum();
300 /* If the table is left-to-right the last row is the most right one. */
301 bResult
= aTabCols
.Count() == GetCurTabColNum();
306 BOOL
SwFEShell::DeleteCol()
308 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
309 SwFrm
*pFrm
= GetCurrFrm();
310 if( !pFrm
|| !pFrm
->IsInTab() )
313 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
315 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
316 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
320 SET_CURR_SHELL( this );
323 // lasse ueber das Layout die Boxen suchen
326 GetTblSel( *this, aBoxes
, nsSwTblSearchType::TBLSEARCH_COL
);
327 if ( aBoxes
.Count() )
329 TblWait( aBoxes
.Count(), pFrm
, *GetDoc()->GetDocShell() );
331 // die Crsr muessen noch aus dem Loesch Bereich entfernt
332 // werden. Setze sie immer hinter/auf die Tabelle; ueber die
333 // Dokument-Position werden sie dann immer an die alte Position gesetzt.
334 while( !pFrm
->IsCellFrm() )
335 pFrm
= pFrm
->GetUpper();
339 // dann loesche doch die Spalten
340 StartUndo(UNDO_COL_DELETE
);
341 bRet
= GetDoc()->DeleteRowCol( aBoxes
, true );
342 EndUndo(UNDO_COL_DELETE
);
348 EndAllActionAndCall();
352 BOOL
SwFEShell::DeleteRow()
354 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
355 SwFrm
*pFrm
= GetCurrFrm();
356 if( !pFrm
|| !pFrm
->IsInTab() )
359 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
361 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
362 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
366 SET_CURR_SHELL( this );
369 // lasse ueber das Layout die Boxen suchen
372 GetTblSel( *this, aBoxes
, nsSwTblSearchType::TBLSEARCH_ROW
);
376 TblWait( aBoxes
.Count(), pFrm
, *GetDoc()->GetDocShell() );
378 // die Crsr aus dem Loeschbereich entfernen.
379 // Der Cursor steht danach:
380 // - es folgt noch eine Zeile, in dieser
381 // - vorher steht noch eine Zeile, in dieser
382 // - sonst immer dahinter
384 SwTableNode
* pTblNd
= ((SwCntntFrm
*)pFrm
)->GetNode()->FindTableNode();
386 // suche alle Boxen / Lines
387 _FndBox
aFndBox( 0, 0 );
389 _FndPara
aPara( aBoxes
, &aFndBox
);
390 pTblNd
->GetTable().GetTabLines().ForEach( &_FndLineCopyCol
, &aPara
);
393 if( !aFndBox
.GetLines().Count() )
395 EndAllActionAndCall();
401 _FndBox
* pFndBox
= &aFndBox
;
402 while( 1 == pFndBox
->GetLines().Count() &&
403 1 == pFndBox
->GetLines()[0]->GetBoxes().Count() )
405 _FndBox
* pTmp
= pFndBox
->GetLines()[0]->GetBoxes()[0];
406 if( pTmp
->GetBox()->GetSttNd() )
407 break; // das ist sonst zu weit
411 SwTableLine
* pDelLine
= pFndBox
->GetLines()[
412 pFndBox
->GetLines().Count()-1 ]->GetLine();
413 SwTableBox
* pDelBox
= pDelLine
->GetTabBoxes()[
414 pDelLine
->GetTabBoxes().Count() - 1 ];
415 while( !pDelBox
->GetSttNd() )
417 SwTableLine
* pLn
= pDelBox
->GetTabLines()[
418 pDelBox
->GetTabLines().Count()-1 ];
419 pDelBox
= pLn
->GetTabBoxes()[ pLn
->GetTabBoxes().Count() - 1 ];
421 SwTableBox
* pNextBox
= pDelLine
->FindNextBox( pTblNd
->GetTable(),
424 pNextBox
->GetFrmFmt()->GetProtect().IsCntntProtected() )
425 pNextBox
= pNextBox
->FindNextBox( pTblNd
->GetTable(), pNextBox
);
427 if( !pNextBox
) // keine nachfolgende? dann die vorhergehende
429 pDelLine
= pFndBox
->GetLines()[ 0 ]->GetLine();
430 pDelBox
= pDelLine
->GetTabBoxes()[ 0 ];
431 while( !pDelBox
->GetSttNd() )
432 pDelBox
= pDelBox
->GetTabLines()[0]->GetTabBoxes()[0];
433 pNextBox
= pDelLine
->FindPreviousBox( pTblNd
->GetTable(),
436 pNextBox
->GetFrmFmt()->GetProtect().IsCntntProtected() )
437 pNextBox
= pNextBox
->FindPreviousBox( pTblNd
->GetTable(), pNextBox
);
441 if( pNextBox
) // dann den Cursor hier hinein
442 nIdx
= pNextBox
->GetSttIdx() + 1;
443 else // ansonsten hinter die Tabelle
444 nIdx
= pTblNd
->EndOfSectionIndex() + 1;
446 SwNodeIndex
aIdx( GetDoc()->GetNodes(), nIdx
);
447 SwCntntNode
* pCNd
= aIdx
.GetNode().GetCntntNode();
449 pCNd
= GetDoc()->GetNodes().GoNext( &aIdx
);
453 SwPaM
* pPam
= GetCrsr();
454 pPam
->GetPoint()->nNode
= aIdx
;
455 pPam
->GetPoint()->nContent
.Assign( pCNd
, 0 );
456 pPam
->SetMark(); // beide wollen etwas davon haben
461 // dann loesche doch die Zeilen
462 StartUndo(UNDO_ROW_DELETE
);
463 bRet
= GetDoc()->DeleteRowCol( aBoxes
);
464 EndUndo(UNDO_ROW_DELETE
);
469 EndAllActionAndCall();
473 /***********************************************************************
475 #* Methoden : MergeTab(), SplitTab()
476 #* Datum : MA 03. May. 93
477 #* Update : MA 19. Apr. 95
478 #***********************************************************************/
480 USHORT
SwFEShell::MergeTab()
482 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
483 USHORT nRet
= TBLMERGE_NOSELECTION
;
486 SwShellTableCrsr
* pTableCrsr
= GetTableCrsr();
487 const SwTableNode
* pTblNd
= pTableCrsr
->GetNode()->FindTableNode();
488 if( pTblNd
->GetTable().ISA( SwDDETable
))
490 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
491 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
495 SET_CURR_SHELL( this );
498 TblWait( pTableCrsr
->GetBoxesCount(), 0, *GetDoc()->GetDocShell(),
499 pTblNd
->GetTable().GetTabLines().Count() );
501 nRet
= GetDoc()->MergeTbl( *pTableCrsr
);
505 EndAllActionAndCall();
511 BOOL
SwFEShell::SplitTab( BOOL bVert
, USHORT nCnt
, BOOL bSameHeight
)
513 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
514 SwFrm
*pFrm
= GetCurrFrm();
515 if( !pFrm
|| !pFrm
->IsInTab() )
518 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
520 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
521 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
525 SET_CURR_SHELL( this );
527 if( bVert
&& !CheckSplitCells( *this, nCnt
+ 1 ) )
529 ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR
,
530 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
534 // lasse ueber das Layout die Boxen suchen
537 GetTblSel( *this, aBoxes
);
540 TblWait( nCnt
, pFrm
, *GetDoc()->GetDocShell(), aBoxes
.Count() );
542 // dann loesche doch die Spalten
543 bRet
= GetDoc()->SplitTbl( aBoxes
, bVert
, nCnt
, bSameHeight
);
545 DELETEZ( pLastCols
);
546 DELETEZ( pLastRows
);
550 EndAllActionAndCall();
555 /***********************************************************************
557 #* Methoden : _GetTabCols
558 #* Datum : MA 30. Nov. 95
559 #* Update : MA 08. Jan. 97
560 #***********************************************************************/
561 void SwFEShell::_GetTabCols( SwTabCols
&rToFill
, const SwFrm
*pBox
) const
563 const SwTabFrm
*pTab
= pBox
->FindTabFrm();
566 //Paar Kleinigkeiten muessen wir schon noch sicherstellen
568 if ( pColumnCacheLastTable
== pTab
->GetTable() )
573 const SwPageFrm
* pPage
= pTab
->FindPageFrm();
574 const ULONG nLeftMin
= (pTab
->Frm().*fnRect
->fnGetLeft
)() -
575 (pPage
->Frm().*fnRect
->fnGetLeft
)();
576 const ULONG nRightMax
= (pTab
->Frm().*fnRect
->fnGetRight
)() -
577 (pPage
->Frm().*fnRect
->fnGetLeft
)();
579 if ( pColumnCacheLastTabFrm
!= pTab
)
581 //Wenn der TabFrm gewechselt hat, brauchen wir bei gleicher
582 //Breite nur ein wenig shiften.
583 SWRECTFNX( pColumnCacheLastTabFrm
)
584 if( (pColumnCacheLastTabFrm
->Frm().*fnRectX
->fnGetWidth
)() ==
585 (pTab
->Frm().*fnRect
->fnGetWidth
)() )
587 pLastCols
->SetLeftMin( nLeftMin
);
590 // pLastCols->GetLeftMin() == (pTab->Frm().*fnRect->fnGetLeft)(),
591 // "GetTabCols: wrong result" )
593 pColumnCacheLastTabFrm
= pTab
;
600 pLastCols
->GetLeftMin () == (USHORT
)nLeftMin
&&
601 pLastCols
->GetLeft () == (USHORT
)(pTab
->Prt().*fnRect
->fnGetLeft
)() &&
602 pLastCols
->GetRight () == (USHORT
)(pTab
->Prt().*fnRect
->fnGetRight
)()&&
603 pLastCols
->GetRightMax() == (USHORT
)nRightMax
- pLastCols
->GetLeftMin() )
605 if ( pColumnCacheLastCellFrm
!= pBox
)
607 pTab
->GetTable()->GetTabCols( *pLastCols
,
608 ((SwCellFrm
*)pBox
)->GetTabBox(), TRUE
);
609 pColumnCacheLastCellFrm
= pBox
;
611 rToFill
= *pLastCols
;
621 GetDoc()->GetTabCols( rToFill
, 0, (SwCellFrm
*)pBox
);
623 pLastCols
= new SwTabCols( rToFill
);
624 pColumnCacheLastTable
= pTab
->GetTable();
625 pColumnCacheLastTabFrm
= pTab
;
626 pColumnCacheLastCellFrm
= pBox
;
629 #if OSL_DEBUG_LEVEL > 1
630 SwTabColsEntry aEntry
;
631 for ( USHORT i
= 0; i
< rToFill
.Count(); ++i
)
633 aEntry
= rToFill
.GetEntry( i
);
639 /***********************************************************************
641 #* Methoden : _GetTabRows
642 #* Datum : FME 2004-01-14
644 #***********************************************************************/
645 void SwFEShell::_GetTabRows( SwTabCols
&rToFill
, const SwFrm
*pBox
) const
647 const SwTabFrm
*pTab
= pBox
->FindTabFrm();
650 //Paar Kleinigkeiten muessen wir schon noch sicherstellen
652 if ( pRowCacheLastTable
== pTab
->GetTable() )
656 const SwPageFrm
* pPage
= pTab
->FindPageFrm();
657 const long nLeftMin
= ( bVert
?
658 pTab
->GetPrtLeft() - pPage
->Frm().Left() :
659 pTab
->GetPrtTop() - pPage
->Frm().Top() );
660 const long nLeft
= bVert
? LONG_MAX
: 0;
661 const long nRight
= (pTab
->Prt().*fnRect
->fnGetHeight
)();
662 const long nRightMax
= bVert
? nRight
: LONG_MAX
;
664 if ( pRowCacheLastTabFrm
!= pTab
||
665 pRowCacheLastCellFrm
!= pBox
)
669 pLastRows
->GetLeftMin () == nLeftMin
&&
670 pLastRows
->GetLeft () == nLeft
&&
671 pLastRows
->GetRight () == nRight
&&
672 pLastRows
->GetRightMax() == nRightMax
)
674 rToFill
= *pLastRows
;
684 GetDoc()->GetTabRows( rToFill
, 0, (SwCellFrm
*)pBox
);
686 pLastRows
= new SwTabCols( rToFill
);
687 pRowCacheLastTable
= pTab
->GetTable();
688 pRowCacheLastTabFrm
= pTab
;
689 pRowCacheLastCellFrm
= pBox
;
693 /***********************************************************************
695 #* Methoden : SetTabCols(), GetTabCols()
696 #* Datum : MA 03. May. 93
697 #* Update : MA 18. May. 93
698 #***********************************************************************/
699 void SwFEShell::SetTabCols( const SwTabCols
&rNew
, BOOL bCurRowOnly
)
701 SwFrm
*pBox
= GetCurrFrm();
702 if( !pBox
|| !pBox
->IsInTab() )
705 SET_CURR_SHELL( this );
709 pBox
= pBox
->GetUpper();
710 } while ( !pBox
->IsCellFrm() );
712 GetDoc()->SetTabCols( rNew
, bCurRowOnly
, 0, (SwCellFrm
*)pBox
);
713 EndAllActionAndCall();
716 void SwFEShell::GetTabCols( SwTabCols
&rToFill
) const
718 const SwFrm
*pFrm
= GetCurrFrm();
719 if( !pFrm
|| !pFrm
->IsInTab() )
722 { pFrm
= pFrm
->GetUpper();
723 } while ( !pFrm
->IsCellFrm() );
725 _GetTabCols( rToFill
, pFrm
);
728 /*-- 19.01.2004 08:56:42---------------------------------------------------
730 -----------------------------------------------------------------------*/
731 void SwFEShell::GetTabRows( SwTabCols
&rToFill
) const
733 const SwFrm
*pFrm
= GetCurrFrm();
734 if( !pFrm
|| !pFrm
->IsInTab() )
737 { pFrm
= pFrm
->GetUpper();
738 } while ( !pFrm
->IsCellFrm() );
740 _GetTabRows( rToFill
, pFrm
);
742 /*-- 19.01.2004 08:56:44---------------------------------------------------
744 -----------------------------------------------------------------------*/
745 void SwFEShell::SetTabRows( const SwTabCols
&rNew
, BOOL bCurColOnly
)
747 SwFrm
*pBox
= GetCurrFrm();
748 if( !pBox
|| !pBox
->IsInTab() )
751 SET_CURR_SHELL( this );
755 pBox
= pBox
->GetUpper();
756 } while ( !pBox
->IsCellFrm() );
758 GetDoc()->SetTabRows( rNew
, bCurColOnly
, 0, (SwCellFrm
*)pBox
);
759 EndAllActionAndCall();
761 /*-- 19.01.2004 08:59:45---------------------------------------------------
763 -----------------------------------------------------------------------*/
764 void SwFEShell::GetMouseTabRows( SwTabCols
&rToFill
, const Point
&rPt
) const
766 const SwFrm
*pBox
= GetBox( rPt
);
768 _GetTabRows( rToFill
, pBox
);
770 /*-- 19.01.2004 08:59:45---------------------------------------------------
772 -----------------------------------------------------------------------*/
773 void SwFEShell::SetMouseTabRows( const SwTabCols
&rNew
, BOOL bCurColOnly
, const Point
&rPt
)
775 const SwFrm
*pBox
= GetBox( rPt
);
778 SET_CURR_SHELL( this );
780 GetDoc()->SetTabRows( rNew
, bCurColOnly
, 0, (SwCellFrm
*)pBox
);
781 EndAllActionAndCall();
785 /***********************************************************************
787 * Methoden : SetRowSplit(), GetRowSplit()
788 * Datum : FME 13.11.2003
789 ***********************************************************************/
791 void SwFEShell::SetRowSplit( const SwFmtRowSplit
& rNew
)
793 SET_CURR_SHELL( this );
795 GetDoc()->SetRowSplit( *getShellCrsr( false ), rNew
);
796 EndAllActionAndCall();
799 void SwFEShell::GetRowSplit( SwFmtRowSplit
*& rpSz
) const
801 GetDoc()->GetRowSplit( *getShellCrsr( false ), rpSz
);
805 /***********************************************************************
807 #* Methoden : SetRowHeight(), GetRowHeight()
808 #* Datum : MA 17. May. 93
809 #* Update : JP 29.04.98
810 #***********************************************************************/
812 void SwFEShell::SetRowHeight( const SwFmtFrmSize
&rNew
)
814 SET_CURR_SHELL( this );
816 GetDoc()->SetRowHeight( *getShellCrsr( false ), rNew
);
817 EndAllActionAndCall();
820 /******************************************************************************
821 * SwTwips SwFEShell::GetRowHeight() const
822 ******************************************************************************/
823 void SwFEShell::GetRowHeight( SwFmtFrmSize
*& rpSz
) const
825 GetDoc()->GetRowHeight( *getShellCrsr( false ), rpSz
);
828 BOOL
SwFEShell::BalanceRowHeight( BOOL bTstOnly
)
830 SET_CURR_SHELL( this );
833 BOOL bRet
= GetDoc()->BalanceRowHeight( *getShellCrsr( false ), bTstOnly
);
835 EndAllActionAndCall();
839 /******************************************************************************
840 * void SwFEShell::SetRowBackground()
841 ******************************************************************************/
842 void SwFEShell::SetRowBackground( const SvxBrushItem
&rNew
)
844 SET_CURR_SHELL( this );
846 GetDoc()->SetRowBackground( *getShellCrsr( false ), rNew
);
847 EndAllActionAndCall();
850 /******************************************************************************
851 * SwTwips SwFEShell::GetRowBackground() const
852 ******************************************************************************/
853 BOOL
SwFEShell::GetRowBackground( SvxBrushItem
&rToFill
) const
855 return GetDoc()->GetRowBackground( *getShellCrsr( false ), rToFill
);
858 /***********************************************************************
860 #* Methoden : SetTabBorders(), GetTabBorders()
861 #* Datum : MA 18. May. 93
862 #* Update : JP 29.04.98
863 #***********************************************************************/
865 void SwFEShell::SetTabBorders( const SfxItemSet
& rSet
)
867 SET_CURR_SHELL( this );
869 GetDoc()->SetTabBorders( *getShellCrsr( false ), rSet
);
870 EndAllActionAndCall();
873 void SwFEShell::SetTabLineStyle( const Color
* pColor
, BOOL bSetLine
,
874 const SvxBorderLine
* pBorderLine
)
876 SET_CURR_SHELL( this );
878 GetDoc()->SetTabLineStyle( *getShellCrsr( false ),
879 pColor
, bSetLine
, pBorderLine
);
880 EndAllActionAndCall();
883 void SwFEShell::GetTabBorders( SfxItemSet
& rSet
) const
885 GetDoc()->GetTabBorders( *getShellCrsr( false ), rSet
);
889 /***********************************************************************
891 #* Methoden : SetBoxBackground(), GetBoxBackground()
892 #* Datum : MA 01. Jun. 93
893 #* Update : MA 03. Jul. 96
894 #***********************************************************************/
895 void SwFEShell::SetBoxBackground( const SvxBrushItem
&rNew
)
897 SET_CURR_SHELL( this );
899 GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew
);
900 EndAllActionAndCall();
903 BOOL
SwFEShell::GetBoxBackground( SvxBrushItem
&rToFill
) const
905 return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill
);
908 /***********************************************************************
910 #* Methoden : SetBoxDirection(), GetBoxDirection()
911 #* Datum : FME 2004-02-03
912 #* Update : FME 2004-02-03
913 #***********************************************************************/
914 void SwFEShell::SetBoxDirection( const SvxFrameDirectionItem
& rNew
)
916 SET_CURR_SHELL( this );
918 GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew
);
919 EndAllActionAndCall();
922 BOOL
SwFEShell::GetBoxDirection( SvxFrameDirectionItem
& rToFill
) const
924 return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill
);
927 /***********************************************************************
929 #* Methoden : SetBoxAlign, SetBoxAlign
930 #* Datum : MA 18. Dec. 96
931 #* Update : JP 29.04.98
932 #***********************************************************************/
933 void SwFEShell::SetBoxAlign( USHORT nAlign
)
935 SET_CURR_SHELL( this );
937 GetDoc()->SetBoxAlign( *getShellCrsr( false ), nAlign
);
938 EndAllActionAndCall();
941 USHORT
SwFEShell::GetBoxAlign() const
943 return GetDoc()->GetBoxAlign( *getShellCrsr( false ) );
946 /***********************************************************************
948 #* Methoden : SetTabBackground(), GetTabBackground()
949 #* Datum : MA 08. Jul. 96
950 #* Update : MA 08. Jul. 96
951 #***********************************************************************/
952 void SwFEShell::SetTabBackground( const SvxBrushItem
&rNew
)
954 SwFrm
*pFrm
= GetCurrFrm();
955 if( !pFrm
|| !pFrm
->IsInTab() )
958 SET_CURR_SHELL( this );
960 GetDoc()->SetAttr( rNew
, *pFrm
->ImplFindTabFrm()->GetFmt() );
961 EndAllAction(); //Kein Call, denn es veraendert sich nichts!
962 GetDoc()->SetModified();
965 void SwFEShell::GetTabBackground( SvxBrushItem
&rToFill
) const
967 SwFrm
*pFrm
= GetCurrFrm();
968 if( pFrm
&& pFrm
->IsInTab() )
969 rToFill
= pFrm
->ImplFindTabFrm()->GetFmt()->GetBackground();
973 /***********************************************************************
975 #* Methoden : HasWholeTabSelection()
976 #* Datum : MA 18. May. 93
977 #* Update : MA 20. Jul. 93
978 #***********************************************************************/
979 BOOL
SwFEShell::HasWholeTabSelection() const
981 //Ist die ganze Tabelle Selektiert?
985 ::GetTblSelCrs( *this, aBoxes
);
988 const SwTableNode
*pTblNd
= IsCrsrInTbl();
989 return ( pTblNd
&& aBoxes
[0]->GetSttIdx()-1 == pTblNd
->
990 EndOfSectionNode()->StartOfSectionIndex() &&
991 aBoxes
[aBoxes
.Count()-1]->GetSttNd()->EndOfSectionIndex()+1
992 == pTblNd
->EndOfSectionIndex() );
998 BOOL
SwFEShell::HasBoxSelection() const
1002 //Ist die ganze Tabelle Selektiert?
1005 SwPaM
* pPam
= GetCrsr();
1006 // leere Boxen gelten auch ohne Selektion als selektiert
1007 // if( !pPam->HasMark() )
1010 if( pPam
->GetPoint() == pPam
->End())
1016 if( pPam
->GetPoint()->nNode
.GetIndex() -1 ==
1017 ( pNd
= pPam
->GetNode())->StartOfSectionIndex() &&
1018 !pPam
->GetPoint()->nContent
.GetIndex() &&
1019 pPam
->GetMark()->nNode
.GetIndex() + 1 ==
1020 pNd
->EndOfSectionIndex())
1022 SwNodeIndex
aIdx( *pNd
->EndOfSectionNode(), -1 );
1023 SwCntntNode
* pCNd
= GetDoc()->GetNodes()[ aIdx
]->GetCntntNode();
1026 pCNd
= GetDoc()->GetNodes().GoPrevious( &aIdx
);
1027 ASSERT( pCNd
, "kein ContentNode in der Box ??" );
1029 if( pPam
->GetMark()->nContent
== pCNd
->Len() )
1041 /***********************************************************************
1042 #* Class : SwFEShell
1043 #* Methoden : ProtectCells(), UnProtectCells()
1044 #* Datum : MA 20. Jul. 93
1045 #* Update : JP 25. Sep. 93
1046 #***********************************************************************/
1047 void SwFEShell::ProtectCells()
1049 SvxProtectItem
aProt( RES_PROTECT
);
1050 aProt
.SetCntntProtect( TRUE
);
1052 SET_CURR_SHELL( this );
1055 GetDoc()->SetBoxAttr( *getShellCrsr( false ), aProt
);
1057 if( !IsCrsrReadonly() )
1063 EndAllActionAndCall();
1066 // die Tabellenselektion aufheben
1067 void SwFEShell::UnProtectCells()
1069 SET_CURR_SHELL( this );
1074 ::GetTblSelCrs( *this, aBoxes
);
1077 SwFrm
*pFrm
= GetCurrFrm();
1079 pFrm
= pFrm
->GetUpper();
1080 } while ( pFrm
&& !pFrm
->IsCellFrm() );
1083 SwTableBox
*pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
1084 aBoxes
.Insert( pBox
);
1088 if( aBoxes
.Count() )
1089 GetDoc()->UnProtectCells( aBoxes
);
1091 EndAllActionAndCall();
1094 void SwFEShell::UnProtectTbls()
1096 SET_CURR_SHELL( this );
1098 GetDoc()->UnProtectTbls( *GetCrsr() );
1099 EndAllActionAndCall();
1102 BOOL
SwFEShell::HasTblAnyProtection( const String
* pTblName
,
1103 BOOL
* pFullTblProtection
)
1105 return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName
,
1106 pFullTblProtection
);
1109 BOOL
SwFEShell::CanUnProtectCells() const
1111 BOOL bUnProtectAvailable
= FALSE
;
1112 const SwTableNode
*pTblNd
= IsCrsrInTbl();
1113 if( pTblNd
&& !pTblNd
->IsProtect() )
1117 ::GetTblSelCrs( *this, aBoxes
);
1120 SwFrm
*pFrm
= GetCurrFrm();
1122 pFrm
= pFrm
->GetUpper();
1123 } while ( pFrm
&& !pFrm
->IsCellFrm() );
1126 SwTableBox
*pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
1127 aBoxes
.Insert( pBox
);
1130 if( aBoxes
.Count() )
1131 bUnProtectAvailable
= ::HasProtectedCells( aBoxes
);
1133 return bUnProtectAvailable
;
1136 /***********************************************************************
1137 #* Class : SwFEShell
1138 #* Methoden : GetRowsToRepeat(), SetRowsToRepeat()
1139 #***********************************************************************/
1140 USHORT
SwFEShell::GetRowsToRepeat() const
1142 const SwFrm
*pFrm
= GetCurrFrm();
1143 const SwTabFrm
*pTab
= pFrm
? pFrm
->FindTabFrm() : 0;
1145 return pTab
->GetTable()->GetRowsToRepeat();
1149 void SwFEShell::SetRowsToRepeat( USHORT nSet
)
1151 SwFrm
*pFrm
= GetCurrFrm();
1152 SwTabFrm
*pTab
= pFrm
? pFrm
->FindTabFrm() : 0;
1153 if( pTab
&& pTab
->GetTable()->GetRowsToRepeat() != nSet
)
1155 SwWait
aWait( *GetDoc()->GetDocShell(), TRUE
);
1156 SET_CURR_SHELL( this );
1158 GetDoc()->SetRowsToRepeat( *pTab
->GetTable(), nSet
);
1159 EndAllActionAndCall();
1162 /*-- 30.06.2004 08:46:35---------------------------------------------------
1163 returns the number of rows consecutively selected from top
1164 -----------------------------------------------------------------------*/
1165 USHORT
lcl_GetRowNumber( const SwPosition
& rPos
)
1167 USHORT nRet
= USHRT_MAX
;
1169 const SwCntntNode
*pNd
;
1170 const SwCntntFrm
*pFrm
;
1172 if( 0 != ( pNd
= rPos
.nNode
.GetNode().GetCntntNode() ))
1173 pFrm
= pNd
->GetFrm( &aTmpPt
, &rPos
, FALSE
);
1177 if ( pFrm
&& pFrm
->IsInTab() )
1179 const SwFrm
* pRow
= pFrm
->GetUpper();
1180 while ( !pRow
->GetUpper()->IsTabFrm() )
1181 pRow
= pRow
->GetUpper();
1183 const SwTabFrm
* pTabFrm
= (const SwTabFrm
*)pRow
->GetUpper();
1184 const SwTableLine
* pTabLine
= static_cast<const SwRowFrm
*>(pRow
)->GetTabLine();
1187 while ( nI
< pTabFrm
->GetTable()->GetTabLines().Count() )
1189 if ( pTabFrm
->GetTable()->GetTabLines()[ nI
] == pTabLine
)
1200 USHORT
SwFEShell::GetRowSelectionFromTop() const
1203 const SwPaM
* pPaM
= IsTableMode() ? GetTableCrsr() : _GetCrsr();
1204 const USHORT nPtLine
= lcl_GetRowNumber( *pPaM
->GetPoint() );
1206 if ( !IsTableMode() )
1208 nRet
= 0 == nPtLine
? 1 : 0;
1212 const USHORT nMkLine
= lcl_GetRowNumber( *pPaM
->GetMark() );
1214 if ( ( nPtLine
== 0 && nMkLine
!= USHRT_MAX
) ||
1215 ( nMkLine
== 0 && nPtLine
!= USHRT_MAX
) )
1217 nRet
= Max( nPtLine
, nMkLine
) + 1;
1225 * 1. case: bRepeat = true
1226 * returns true if the current frame is located inside a table headline in
1229 * 2. case: bRepeat = false
1230 * returns true if the current frame is localed inside a table headline OR
1231 * inside the first line of a table!!!
1233 BOOL
SwFEShell::CheckHeadline( bool bRepeat
) const
1236 if ( !IsTableMode() )
1238 SwFrm
*pFrm
= GetCurrFrm(); // DONE MULTIIHEADER
1239 if ( pFrm
&& pFrm
->IsInTab() )
1241 SwTabFrm
* pTab
= pFrm
->FindTabFrm();
1244 bRet
= pTab
->IsFollow() && pTab
->IsInHeadline( *pFrm
);
1248 bRet
= ((SwLayoutFrm
*)pTab
->Lower())->IsAnLower( pFrm
) ||
1249 pTab
->IsInHeadline( *pFrm
);
1256 /***********************************************************************
1257 #* Class : SwFEShell
1258 #* Methoden : AdjustCellWidth()
1259 #* Datum : MA 20. Feb. 95
1260 #* Update : MA 27. Jul. 95
1261 #***********************************************************************/
1263 void SwFEShell::AdjustCellWidth( BOOL bBalance
)
1265 SET_CURR_SHELL( this );
1268 //WarteCrsr immer einschalten, weil sich im vorraus nicht so recht
1269 //ermitteln laesst wieviel Inhalt betroffen ist.
1270 TblWait
aWait( USHRT_MAX
, 0, *GetDoc()->GetDocShell() );
1272 GetDoc()->AdjustCellWidth( *getShellCrsr( false ), bBalance
);
1273 EndAllActionAndCall();
1276 BOOL
SwFEShell::IsAdjustCellWidthAllowed( BOOL bBalance
) const
1278 //Es muss mindestens eine Zelle mit Inhalt in der Selektion enthalten
1281 SwFrm
*pFrm
= GetCurrFrm();
1282 if( !pFrm
|| !pFrm
->IsInTab() )
1286 ::GetTblSelCrs( *this, aBoxes
);
1289 return aBoxes
.Count() > 1;
1291 if ( !aBoxes
.Count() )
1294 { pFrm
= pFrm
->GetUpper();
1295 } while ( !pFrm
->IsCellFrm() );
1296 SwTableBox
*pBox
= (SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox();
1297 aBoxes
.Insert( pBox
);
1300 for ( USHORT i
= 0; i
< aBoxes
.Count(); ++i
)
1302 SwTableBox
*pBox
= aBoxes
[i
];
1303 if ( pBox
->GetSttNd() )
1305 SwNodeIndex
aIdx( *pBox
->GetSttNd(), 1 );
1306 SwTxtNode
* pCNd
= aIdx
.GetNode().GetTxtNode();
1308 pCNd
= (SwTxtNode
*)GetDoc()->GetNodes().GoNext( &aIdx
);
1312 if ( pCNd
->GetTxt().Len() )
1315 pCNd
= GetDoc()->GetNodes()[ aIdx
]->GetTxtNode();
1322 // AutoFormat fuer die Tabelle/TabellenSelection
1323 BOOL
SwFEShell::SetTableAutoFmt( const SwTableAutoFmt
& rNew
)
1325 SwTableNode
*pTblNd
= (SwTableNode
*)IsCrsrInTbl();
1326 if( !pTblNd
|| pTblNd
->GetTable().IsTblComplex() )
1331 if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
1334 // gesamte Tabelle oder nur auf die akt. Selektion
1336 ::GetTblSelCrs( *this, aBoxes
);
1339 const SwTableSortBoxes
& rTBoxes
= pTblNd
->GetTable().GetTabSortBoxes();
1340 for( USHORT n
= 0; n
< rTBoxes
.Count(); ++n
)
1342 SwTableBox
* pBox
= rTBoxes
[ n
];
1343 aBoxes
.Insert( pBox
);
1348 if( aBoxes
.Count() )
1350 SET_CURR_SHELL( this );
1352 bRet
= GetDoc()->SetTableAutoFmt( aBoxes
, rNew
);
1353 DELETEZ( pLastCols
);
1354 DELETEZ( pLastRows
);
1355 EndAllActionAndCall();
1362 BOOL
SwFEShell::GetTableAutoFmt( SwTableAutoFmt
& rGet
)
1364 const SwTableNode
*pTblNd
= IsCrsrInTbl();
1365 if( !pTblNd
|| pTblNd
->GetTable().IsTblComplex() )
1370 if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
1373 // gesamte Tabelle oder nur auf die akt. Selektion
1375 ::GetTblSelCrs( *this, aBoxes
);
1378 const SwTableSortBoxes
& rTBoxes
= pTblNd
->GetTable().GetTabSortBoxes();
1379 for( USHORT n
= 0; n
< rTBoxes
.Count(); ++n
)
1381 SwTableBox
* pBox
= rTBoxes
[ n
];
1382 aBoxes
.Insert( pBox
);
1386 return GetDoc()->GetTableAutoFmt( aBoxes
, rGet
);
1389 /***********************************************************************
1390 #* Class : SwFEShell
1391 #* Methoden : DeleteTblSel()
1392 #* Datum : MA 03. May. 93
1393 #* Update : MA 19. Apr. 95
1394 #***********************************************************************/
1395 BOOL
SwFEShell::DeleteTblSel()
1397 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
1398 SwFrm
*pFrm
= GetCurrFrm();
1399 if( !pFrm
|| !pFrm
->IsInTab() )
1402 if( pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
1404 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
1405 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
1409 SET_CURR_SHELL( this );
1412 // lasse ueber das Layout die Boxen suchen
1415 GetTblSelCrs( *this, aBoxes
);
1416 if( aBoxes
.Count() )
1418 TblWait( aBoxes
.Count(), pFrm
, *GetDoc()->GetDocShell() );
1420 // die Crsr muessen noch aus dem Loesch Bereich entfernt
1421 // werden. Setze sie immer hinter/auf die Tabelle; ueber die
1422 // Dokument-Position werden sie dann immer an die alte Position gesetzt.
1423 while( !pFrm
->IsCellFrm() )
1424 pFrm
= pFrm
->GetUpper();
1425 ParkCrsr( SwNodeIndex( *((SwCellFrm
*)pFrm
)->GetTabBox()->GetSttNd() ));
1427 bRet
= GetDoc()->DeleteRowCol( aBoxes
);
1429 DELETEZ( pLastCols
);
1430 DELETEZ( pLastRows
);
1434 EndAllActionAndCall();
1438 /*************************************************************************
1440 |* SwFEShell::GetCurTabColNum()
1442 |* Ersterstellung MA 03. Feb. 95
1443 |* Letzte Aenderung MA 21. May. 95
1445 |*************************************************************************/
1446 USHORT
SwFEShell::GetCurTabColNum() const
1448 //!!!GetCurMouseTabColNum() mitpflegen!!!!
1451 SwFrm
*pFrm
= GetCurrFrm();
1452 ASSERT( pFrm
, "Crsr geparkt?" );
1454 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
1455 if( pFrm
&& pFrm
->IsInTab() )
1457 do { // JP 26.09.95: warum mit dem CntntFrame und nicht mit
1458 // dem CellFrame vergleichen????
1459 pFrm
= pFrm
->GetUpper();
1460 } while ( !pFrm
->IsCellFrm() );
1463 const SwPageFrm
* pPage
= pFrm
->FindPageFrm();
1465 //TabCols besorgen, den nur ueber diese erreichen wir die Position.
1467 GetTabCols( aTabCols
);
1469 if( pFrm
->FindTabFrm()->IsRightToLeft() )
1471 long nX
= (pFrm
->Frm().*fnRect
->fnGetRight
)() - (pPage
->Frm().*fnRect
->fnGetLeft
)();
1473 const long nRight
= aTabCols
.GetLeftMin() + aTabCols
.GetRight();;
1475 if ( !::IsSame( nX
, nRight
) )
1477 nX
= nRight
- nX
+ aTabCols
.GetLeft();
1478 for ( USHORT i
= 0; i
< aTabCols
.Count(); ++i
)
1479 if ( ::IsSame( nX
, aTabCols
[i
] ) )
1488 const long nX
= (pFrm
->Frm().*fnRect
->fnGetLeft
)() -
1489 (pPage
->Frm().*fnRect
->fnGetLeft
)();
1491 const long nLeft
= aTabCols
.GetLeftMin();
1493 if ( !::IsSame( nX
, nLeft
+ aTabCols
.GetLeft() ) )
1495 for ( USHORT i
= 0; i
< aTabCols
.Count(); ++i
)
1496 if ( ::IsSame( nX
, nLeft
+ aTabCols
[i
] ) )
1507 /*************************************************************************
1509 |* SwFEShell::GetBox()
1511 |* Ersterstellung MA 22. Jun. 95
1512 |* Letzte Aenderung MA 21. Nov. 96
1514 |*************************************************************************/
1516 const SwFrm
*lcl_FindFrmInTab( const SwLayoutFrm
*pLay
, const Point
&rPt
, SwTwips nFuzzy
)
1518 const SwFrm
*pFrm
= pLay
->Lower();
1520 while( pFrm
&& pLay
->IsAnLower( pFrm
) )
1522 if ( pFrm
->Frm().IsNear( rPt
, nFuzzy
) )
1524 if ( pFrm
->IsLayoutFrm() )
1526 const SwFrm
*pTmp
= ::lcl_FindFrmInTab( (SwLayoutFrm
*)pFrm
, rPt
, nFuzzy
);
1534 pFrm
= pFrm
->FindNext();
1540 const SwCellFrm
*lcl_FindFrm( const SwLayoutFrm
*pLay
, const Point
&rPt
,
1541 SwTwips nFuzzy
, bool* pbRow
, bool* pbCol
)
1543 // bMouseMoveRowCols :
1544 // Method is called for
1545 // - Moving columns/rows with the mouse or
1546 // - Enhanced table selection
1547 const bool bMouseMoveRowCols
= 0 == pbCol
;
1549 bool bCloseToRow
= false;
1550 bool bCloseToCol
= false;
1552 const SwFrm
*pFrm
= pLay
->ContainsCntnt();
1553 const SwFrm
* pRet
= 0;
1559 if ( pFrm
->IsInTab() )
1560 pFrm
= ((SwFrm
*)pFrm
)->ImplFindTabFrm();
1562 if ( pFrm
->IsTabFrm() )
1565 bool bSearchForFrmInTab
= true;
1566 SwTwips nTmpFuzzy
= nFuzzy
;
1568 if ( !bMouseMoveRowCols
)
1570 // We ignore nested tables for the enhanced table selection:
1571 while ( pFrm
->GetUpper()->IsInTab() )
1572 pFrm
= pFrm
->GetUpper()->FindTabFrm();
1574 // We first check if the given point is 'close' to the left or top
1575 // border of the table frame:
1576 ASSERT( pFrm
, "Nested table frame without outer table" )
1578 const bool bRTL
= pFrm
->IsRightToLeft();
1580 SwRect aTabRect
= pFrm
->Prt();
1581 aTabRect
.Pos() += pFrm
->Frm().Pos();
1583 const SwTwips nLeft
= bRTL
?
1584 (aTabRect
.*fnRect
->fnGetRight
)() :
1585 (aTabRect
.*fnRect
->fnGetLeft
)();
1586 const SwTwips nTop
= (aTabRect
.*fnRect
->fnGetTop
)();
1588 SwTwips
& rPointX
= bVert
? aPt
.Y() : aPt
.X();
1589 SwTwips
& rPointY
= bVert
? aPt
.X() : aPt
.Y();
1591 const SwTwips nXDiff
= (*fnRect
->fnXDiff
)( nLeft
, rPointX
) * ( bRTL
? (-1) : 1 );
1592 const SwTwips nYDiff
= (*fnRect
->fnYDiff
)( nTop
, rPointY
);
1594 bCloseToRow
= nXDiff
>= 0 && nXDiff
< nFuzzy
;
1595 bCloseToCol
= nYDiff
>= 0 && nYDiff
< nFuzzy
;
1597 if ( bCloseToCol
&& 2 * nYDiff
> nFuzzy
)
1599 const SwFrm
* pPrev
= pFrm
->GetPrev();
1602 SwRect aPrevRect
= pPrev
->Prt();
1603 aPrevRect
.Pos() += pPrev
->Frm().Pos();
1605 if( aPrevRect
.IsInside( rPt
) )
1607 bCloseToCol
= false;
1613 // If we found the point to be 'close' to the left or top border
1614 // of the table frame, we adjust the point to be on that border:
1615 if ( bCloseToRow
&& bCloseToCol
)
1616 aPt
= bRTL
? aTabRect
.TopRight() : (aTabRect
.*fnRect
->fnGetPos
)();
1617 else if ( bCloseToRow
)
1619 else if ( bCloseToCol
)
1622 if ( !bCloseToRow
&& !bCloseToCol
)
1623 bSearchForFrmInTab
= false;
1625 // Since the point has been adjusted, we call lcl_FindFrmInTab()
1626 // with a fuzzy value of 1:
1630 const SwFrm
* pTmp
= bSearchForFrmInTab
?
1631 ::lcl_FindFrmInTab( (SwLayoutFrm
*)pFrm
, aPt
, nTmpFuzzy
) :
1640 pFrm
= pFrm
->FindNextCnt();
1642 } while ( pFrm
&& pLay
->IsAnLower( pFrm
) );
1645 if ( pFrm
&& pFrm
->IsInTab() && pLay
->IsAnLower( pFrm
) )
1649 // We allow mouse drag of table borders within nested tables,
1650 // but disallow hotspot selection of nested tables.
1651 if ( bMouseMoveRowCols
)
1653 // find the next cell frame
1654 while ( pFrm
&& !pFrm
->IsCellFrm() )
1655 pFrm
= pFrm
->GetUpper();
1659 // find the most upper cell frame:
1661 ( !pFrm
->IsCellFrm() ||
1662 !pFrm
->GetUpper()->GetUpper()->IsTabFrm() ||
1663 pFrm
->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
1664 pFrm
= pFrm
->GetUpper();
1667 if ( pFrm
) // Note: this condition should be the same like the while condition!!!
1669 // --> FME 2004-07-30 #i32329# Enhanced table selection
1670 // used for hotspot selection of tab/cols/rows
1671 if ( !bMouseMoveRowCols
)
1674 ASSERT( pbCol
&& pbRow
, "pbCol or pbRow missing" )
1676 if ( bCloseToRow
|| bCloseToCol
)
1678 *pbRow
= bCloseToRow
;
1679 *pbCol
= bCloseToCol
;
1687 // used for mouse move of columns/rows
1688 const SwTabFrm
* pTabFrm
= pFrm
->FindTabFrm();
1689 SwRect aTabRect
= pTabFrm
->Prt();
1690 aTabRect
.Pos() += pTabFrm
->Frm().Pos();
1694 const SwTwips nTabTop
= (aTabRect
.*fnRect
->fnGetTop
)();
1695 const SwTwips nMouseTop
= bVert
? rPt
.X() : rPt
.Y();
1697 // Do not allow to drag upper table border:
1698 if ( !::IsSame( nTabTop
, nMouseTop
) )
1700 if ( ::IsSame( pFrm
->Frm().Left(), rPt
.X() ) ||
1701 ::IsSame( pFrm
->Frm().Right(),rPt
.X() ) )
1703 if ( pbRow
) *pbRow
= false;
1707 if ( ::IsSame( pFrm
->Frm().Top(), rPt
.Y() ) ||
1708 ::IsSame( pFrm
->Frm().Bottom(),rPt
.Y() ) )
1710 if ( pbRow
) *pbRow
= true;
1717 pFrm
= pFrm
->GetUpper();
1723 ASSERT( !pRet
|| pRet
->IsCellFrm(), "lcl_FindFrm() is supposed to find a cell frame!" )
1724 return pRet
&& pRet
->IsCellFrm() ? static_cast<const SwCellFrm
*>(pRet
) : 0;
1728 // pbCol = 0 => Used for moving table rows/cols with mouse
1729 // pbCol != 0 => Used for selecting table/rows/cols
1731 #define ENHANCED_TABLE_SELECTION_FUZZY 10
1733 const SwFrm
* SwFEShell::GetBox( const Point
&rPt
, bool* pbRow
, bool* pbCol
) const
1735 const SwPageFrm
*pPage
= (SwPageFrm
*)GetLayout()->Lower();
1736 Window
* pOutWin
= GetWin();
1737 SwTwips nFuzzy
= COLFUZZY
;
1740 // --> FME 2004-07-30 #i32329# Enhanced table selection
1741 SwTwips nSize
= pbCol
? ENHANCED_TABLE_SELECTION_FUZZY
: RULER_MOUSE_MARGINWIDTH
;
1743 Size
aTmp( nSize
, nSize
);
1744 aTmp
= pOutWin
->PixelToLogic( aTmp
);
1745 nFuzzy
= aTmp
.Width();
1748 while ( pPage
&& !pPage
->Frm().IsNear( rPt
, nFuzzy
) )
1749 pPage
= (SwPageFrm
*)pPage
->GetNext();
1751 const SwCellFrm
*pFrm
= 0;
1754 //Per GetCrsrOfst oder GetCntntPos koennen wir hier die Box leider
1755 //nicht suchen. Das wuerde zu einem Performance-Zusammenbruch bei
1756 //Dokumenten mit vielen Absaetzen/Tabellen auf einer Seite fuehren
1759 //Erst die Flys checken.
1760 if ( pPage
->GetSortedObjs() )
1762 for ( USHORT i
= 0; !pFrm
&& i
< pPage
->GetSortedObjs()->Count(); ++i
)
1764 SwAnchoredObject
* pObj
= (*pPage
->GetSortedObjs())[i
];
1765 if ( pObj
->ISA(SwFlyFrm
) )
1767 pFrm
= lcl_FindFrm( static_cast<SwFlyFrm
*>(pObj
),
1768 rPt
, nFuzzy
, pbRow
, pbCol
);
1772 const SwLayoutFrm
*pLay
= (SwLayoutFrm
*)pPage
->Lower();
1773 while ( pLay
&& !pFrm
)
1775 pFrm
= lcl_FindFrm( pLay
, rPt
, nFuzzy
, pbRow
, pbCol
);
1776 pLay
= (SwLayoutFrm
*)pLay
->GetNext();
1782 /* Helper function*/
1783 /* calculated the distance between Point rC and Line Segment (rA, rB) */
1784 double lcl_DistancePoint2Segment( const Point
& rA
, const Point
& rB
, const Point
& rC
)
1788 const basegfx::B2DVector
aBC( rC
.X() - rB
.X(), rC
.Y() - rB
.Y() );
1789 const basegfx::B2DVector
aAB( rB
.X() - rA
.X(), rB
.Y() - rA
.Y() );
1790 const double nDot1
= aBC
.scalar( aAB
);
1792 if ( nDot1
> 0 ) // check outside case 1
1793 nRet
= aBC
.getLength();
1796 const basegfx::B2DVector
aAC( rC
.X() - rA
.X(), rC
.Y() - rA
.Y() );
1797 const basegfx::B2DVector
aBA( rA
.X() - rB
.X(), rA
.Y() - rB
.Y() );
1798 const double nDot2
= aAC
.scalar( aBA
);
1800 if ( nDot2
> 0 ) // check outside case 2
1801 nRet
= aAC
.getLength();
1804 const double nDiv
= aAB
.getLength();
1805 nRet
= nDiv
? aAB
.cross( aAC
) / nDiv
: 0;
1812 /* Helper function*/
1813 Point
lcl_ProjectOntoClosestTableFrm( const SwTabFrm
& rTab
, const Point
& rPoint
, bool bRowDrag
)
1815 Point
aRet( rPoint
);
1816 const SwTabFrm
* pCurrentTab
= &rTab
;
1817 const bool bVert
= pCurrentTab
->IsVertical();
1818 const bool bRTL
= pCurrentTab
->IsRightToLeft();
1821 // bRowDrag = true => compare to left border of table
1822 // bRowDrag = false => compare to top border of table
1825 // bRowDrag = true => compare to right border of table
1826 // bRowDrag = false => compare to top border of table
1829 // bRowDrag = true => compare to right border of table
1830 // bRowDrag = false => compare to top border of table
1832 bool bRight
= false;
1836 if ( bVert
|| bRTL
)
1842 // used to find the minimal distance
1850 while ( pCurrentTab
)
1852 SwRect
aTabRect( pCurrentTab
->Prt() );
1853 aTabRect
+= pCurrentTab
->Frm().Pos();
1857 // distance to left table border
1858 aS1
= aTabRect
.TopLeft();
1859 aS2
= aTabRect
.BottomLeft();
1863 // distance to right table border
1864 aS1
= aTabRect
.TopRight();
1865 aS2
= aTabRect
.BottomRight();
1869 // distance to top table border
1870 aS1
= aTabRect
.TopLeft();
1871 aS2
= aTabRect
.TopRight();
1874 const double nDist
= lcl_DistancePoint2Segment( aS1
, aS2
, rPoint
);
1876 if ( nDist
< nMin
|| -1 == nMin
)
1883 pCurrentTab
= pCurrentTab
->GetFollow();
1886 // project onto closest line:
1887 if ( bLeft
|| bRight
)
1889 aRet
.X() = aMin1
.X();
1890 if ( aRet
.Y() > aMin2
.Y() )
1891 aRet
.Y() = aMin2
.Y();
1892 else if ( aRet
.Y() < aMin1
.Y() )
1893 aRet
.Y() = aMin1
.Y();
1897 aRet
.Y() = aMin1
.Y();
1898 if ( aRet
.X() > aMin2
.X() )
1899 aRet
.X() = aMin2
.X();
1900 else if ( aRet
.X() < aMin1
.X() )
1901 aRet
.X() = aMin1
.X();
1907 // --> FME 2004-07-30 #i32329# Enhanced table selection
1908 bool SwFEShell::SelTblRowCol( const Point
& rPt
, const Point
* pEnd
, bool bRowDrag
)
1915 SwPosition
* ppPos
[2] = { 0, 0 };
1916 Point paPt
[2] = { rPt
, aEndPt
};
1917 bool pbRow
[2] = { 0, 0 };
1918 bool pbCol
[2] = { 0, 0 };
1920 // pEnd is set during dragging.
1921 for ( USHORT i
= 0; i
< ( pEnd
? 2 : 1 ); ++i
)
1923 const SwCellFrm
* pFrm
=
1924 static_cast<const SwCellFrm
*>(GetBox( paPt
[i
], &pbRow
[i
], &pbCol
[i
] ) );
1928 while( pFrm
->Lower() && pFrm
->Lower()->IsRowFrm() )
1929 pFrm
= static_cast<const SwCellFrm
*>( static_cast<const SwLayoutFrm
*>( pFrm
->Lower() )->Lower() );
1930 if( pFrm
&& pFrm
->GetTabBox()->GetSttNd() &&
1931 pFrm
->GetTabBox()->GetSttNd()->IsInProtectSect() )
1937 const SwCntntFrm
* pCntnt
= ::GetCellCntnt( *pFrm
);
1939 if ( pCntnt
&& pCntnt
->IsTxtFrm() )
1941 ppPos
[i
] = new SwPosition( *pCntnt
->GetNode() );
1942 ppPos
[i
]->nContent
.Assign( const_cast<SwCntntNode
*>(pCntnt
->GetNode()), 0 );
1944 // paPt[i] will not be used any longer, now we use it to store
1945 // a position inside the content frame
1946 paPt
[i
] = pCntnt
->Frm().Center();
1950 // no calculation of end frame if start frame has not been found.
1951 if ( 1 == i
|| !ppPos
[0] || !pEnd
)
1954 // find 'closest' table frame to pEnd:
1955 const SwTabFrm
* pCurrentTab
= pFrm
->FindTabFrm();
1956 if ( pCurrentTab
->IsFollow() )
1957 pCurrentTab
= pCurrentTab
->FindMaster( true );
1959 const Point aProjection
= lcl_ProjectOntoClosestTableFrm( *pCurrentTab
, *pEnd
, bRowDrag
);
1960 paPt
[1] = aProjection
;
1965 SwShellCrsr
* pCrsr
= _GetCrsr();
1966 SwCrsrSaveState
aSaveState( *pCrsr
);
1967 SwPosition
aOldPos( *pCrsr
->GetPoint() );
1969 pCrsr
->DeleteMark();
1970 *pCrsr
->GetPoint() = *ppPos
[0];
1971 pCrsr
->GetPtPos() = paPt
[0];
1973 if ( !pCrsr
->IsInProtectTable( FALSE
, TRUE
) )
1975 bool bNewSelection
= true;
1979 if ( ppPos
[1]->nNode
.GetNode().StartOfSectionNode() !=
1980 aOldPos
.nNode
.GetNode().StartOfSectionNode() )
1983 SwCrsrSaveState
aSaveState2( *pCrsr
);
1984 *pCrsr
->GetPoint() = *ppPos
[1];
1985 pCrsr
->GetPtPos() = paPt
[1];
1987 if ( pCrsr
->IsInProtectTable( FALSE
, FALSE
) )
1989 pCrsr
->RestoreSavePos();
1990 bNewSelection
= false;
1995 pCrsr
->RestoreSavePos();
1996 bNewSelection
= false;
2000 if ( bNewSelection
)
2002 // --> FME 2004-10-20 #i35543# SelTblRowCol should remove any existing
2004 if ( IsTableMode() )
2008 if ( pbRow
[0] && pbCol
[0] )
2009 bRet
= SwCrsrShell::SelTbl();
2010 else if ( pbRow
[0] )
2011 bRet
= SwCrsrShell::_SelTblRowOrCol( true, true );
2012 else if ( pbCol
[0] )
2013 bRet
= SwCrsrShell::_SelTblRowOrCol( false, true );
2028 /*************************************************************************
2030 |* SwFEShell::WhichMouseTabCol()
2032 |* Ersterstellung MA 22. Jun. 95
2033 |* Last change AMA 12. Jun. 02
2035 |*************************************************************************/
2036 BYTE
SwFEShell::WhichMouseTabCol( const Point
&rPt
) const
2038 BYTE nRet
= SW_TABCOL_NONE
;
2041 bool bSelect
= false;
2043 // First try: Do we get the row/col move cursor?
2044 SwCellFrm
* pFrm
= (SwCellFrm
*)GetBox( rPt
, &bRow
, 0 );
2048 // Second try: Do we get the row/col/tab selection cursor?
2049 pFrm
= (SwCellFrm
*)GetBox( rPt
, &bRow
, &bCol
);
2055 while( pFrm
->Lower() && pFrm
->Lower()->IsRowFrm() )
2056 pFrm
= (SwCellFrm
*)((SwLayoutFrm
*)pFrm
->Lower())->Lower();
2057 if( pFrm
&& pFrm
->GetTabBox()->GetSttNd() &&
2058 pFrm
->GetTabBox()->GetSttNd()->IsInProtectSect() )
2066 if ( pFrm
->IsVertical() )
2067 nRet
= bRow
? SW_TABCOL_VERT
: SW_TABROW_VERT
;
2069 nRet
= bRow
? SW_TABROW_HORI
: SW_TABCOL_HORI
;
2073 const SwTabFrm
* pTabFrm
= pFrm
->FindTabFrm();
2074 if ( pTabFrm
->IsVertical() )
2078 nRet
= SW_TABSEL_VERT
;
2082 nRet
= SW_TABROWSEL_VERT
;
2086 nRet
= SW_TABCOLSEL_VERT
;
2093 nRet
= pTabFrm
->IsRightToLeft() ?
2094 SW_TABSEL_HORI_RTL
:
2099 nRet
= pTabFrm
->IsRightToLeft() ?
2100 SW_TABROWSEL_HORI_RTL
:
2105 nRet
= SW_TABCOLSEL_HORI
;
2115 SwTxtNode
* SwFEShell::GetNumRuleNodeAtPos( const Point
&rPt
)
2117 SwTxtNode
* pResult
= NULL
;
2119 SwContentAtPos aCntntAtPos
2120 (SwContentAtPos::SW_NUMLABEL
);
2122 if( GetContentAtPos(rPt
, aCntntAtPos
) && aCntntAtPos
.aFnd
.pNode
)
2123 pResult
= aCntntAtPos
.aFnd
.pNode
->GetTxtNode();
2128 BOOL
SwFEShell::IsNumLabel( const Point
&rPt
, int nMaxOffset
)
2130 BOOL bResult
= FALSE
;
2132 SwContentAtPos aCntntAtPos
2133 (SwContentAtPos::SW_NUMLABEL
);
2135 if( GetContentAtPos(rPt
, aCntntAtPos
))
2137 if ((nMaxOffset
>= 0 && aCntntAtPos
.nDist
<= nMaxOffset
) ||
2146 // --> OD 2005-02-21 #i42921#
2147 bool SwFEShell::IsVerticalModeAtNdAndPos( const SwTxtNode
& _rTxtNode
,
2148 const Point
& _rDocPos
) const
2152 const short nTextDir
=
2153 _rTxtNode
.GetTextDirection( SwPosition(_rTxtNode
), &_rDocPos
);
2157 case FRMDIR_HORI_RIGHT_TOP
:
2158 case FRMDIR_HORI_LEFT_TOP
:
2163 case FRMDIR_VERT_TOP_LEFT
:
2164 case FRMDIR_VERT_TOP_RIGHT
:
2175 /*************************************************************************
2177 |* SwFEShell::GetMouseTabCols()
2179 |* Ersterstellung MA 22. Jun. 95
2180 |* Letzte Aenderung MA 27. Aug. 96
2182 |*************************************************************************/
2183 void SwFEShell::GetMouseTabCols( SwTabCols
&rToFill
, const Point
&rPt
) const
2185 const SwFrm
*pBox
= GetBox( rPt
);
2187 _GetTabCols( rToFill
, pBox
);
2190 void SwFEShell::SetMouseTabCols( const SwTabCols
&rNew
, BOOL bCurRowOnly
,
2193 const SwFrm
*pBox
= GetBox( rPt
);
2196 SET_CURR_SHELL( this );
2198 GetDoc()->SetTabCols( rNew
, bCurRowOnly
, 0, (SwCellFrm
*)pBox
);
2199 EndAllActionAndCall();
2203 /*************************************************************************
2205 |* SwFEShell::GetMouseColNum(), GetMouseTabColNum()
2207 |* Ersterstellung MA 04. Jul. 95
2208 |* Letzte Aenderung MA 04. Jul. 95
2210 |*************************************************************************/
2211 USHORT
SwFEShell::GetCurMouseColNum( const Point
&rPt
,
2212 SwGetCurColNumPara
* pPara
) const
2214 return _GetCurColNum( GetBox( rPt
), pPara
);
2217 USHORT
SwFEShell::GetCurMouseTabColNum( const Point
&rPt
) const
2219 //!!!GetCurTabColNum() mitpflegen!!!!
2222 const SwFrm
*pFrm
= GetBox( rPt
);
2223 ASSERT( pFrm
, "Table not found" );
2226 const long nX
= pFrm
->Frm().Left();
2228 //TabCols besorgen, den nur ueber diese erreichen wir die Position.
2230 GetMouseTabCols( aTabCols
, rPt
);
2232 const long nLeft
= aTabCols
.GetLeftMin();
2234 if ( !::IsSame( nX
, nLeft
+ aTabCols
.GetLeft() ) )
2236 for ( USHORT i
= 0; i
< aTabCols
.Count(); ++i
)
2237 if ( ::IsSame( nX
, nLeft
+ aTabCols
[i
] ) )
2247 void ClearFEShellTabCols()
2249 DELETEZ( pLastCols
);
2250 DELETEZ( pLastRows
);
2253 /*************************************************************************
2255 |* SwFEShell::GetTblAttr(), SetTblAttr()
2257 |* Ersterstellung MA 09. Dec. 96
2258 |* Letzte Aenderung MA 09. Dec. 96
2260 |*************************************************************************/
2261 void SwFEShell::GetTblAttr( SfxItemSet
&rSet
) const
2263 SwFrm
*pFrm
= GetCurrFrm();
2264 if( pFrm
&& pFrm
->IsInTab() )
2265 rSet
.Put( pFrm
->ImplFindTabFrm()->GetFmt()->GetAttrSet() );
2268 void SwFEShell::SetTblAttr( const SfxItemSet
&rNew
)
2270 SwFrm
*pFrm
= GetCurrFrm();
2271 if( pFrm
&& pFrm
->IsInTab() )
2273 SET_CURR_SHELL( this );
2275 SwTabFrm
*pTab
= pFrm
->FindTabFrm();
2276 pTab
->GetTable()->SetHTMLTableLayout( 0 );
2277 GetDoc()->SetAttr( rNew
, *pTab
->GetFmt() );
2278 GetDoc()->SetModified();
2279 EndAllActionAndCall();
2283 /** move cursor within a table into previous/next row (same column)
2284 * @param pShell cursor shell whose cursor is to be moved
2285 * @param bUp true: move up, false: move down
2286 * @returns true if successful
2288 bool lcl_GoTableRow( SwCrsrShell
* pShell
, bool bUp
)
2290 ASSERT( pShell
!= NULL
, "need shell" );
2294 SwPaM
* pPam
= pShell
->GetCrsr();
2295 const SwStartNode
* pTableBox
= pPam
->GetNode()->FindTableBoxStartNode();
2296 ASSERT( pTableBox
!= NULL
, "I'm living in a box... NOT!" );
2298 // move cursor to start node of table box
2299 pPam
->GetPoint()->nNode
= pTableBox
->GetIndex();
2300 pPam
->GetPoint()->nContent
.Assign( NULL
, 0 );
2301 GoInCntnt( *pPam
, fnMoveForward
);
2303 // go to beginning end of table box
2304 SwPosSection fnPosSect
= bUp
? fnSectionStart
: fnSectionEnd
;
2305 pShell
->MoveSection( fnSectionCurr
, fnPosSect
);
2307 // and go up/down into next content
2308 bRet
= bUp
? pShell
->Up() : pShell
->Down();
2313 // aender eine Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe
2314 BOOL
SwFEShell::SetColRowWidthHeight( USHORT eType
, USHORT nDiff
)
2316 SwFrm
*pFrm
= GetCurrFrm();
2317 if( !pFrm
|| !pFrm
->IsInTab() )
2320 if( nsTblChgWidthHeightType::WH_FLAG_INSDEL
& eType
&&
2321 pFrm
->ImplFindTabFrm()->GetTable()->ISA( SwDDETable
))
2323 ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR
,
2324 ERRCODE_MSG_INFO
| ERRCODE_BUTTON_DEF_OK
);
2328 SET_CURR_SHELL( this );
2332 pFrm
= pFrm
->GetUpper();
2333 } while( !pFrm
->IsCellFrm() );
2335 SwTabFrm
*pTab
= pFrm
->ImplFindTabFrm();
2337 // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
2338 // dann muss es jetzt auf absolute umgerechnet werden.
2339 const SwFmtFrmSize
& rTblFrmSz
= pTab
->GetFmt()->GetFrmSize();
2341 long nPrtWidth
= (pTab
->Prt().*fnRect
->fnGetWidth
)();
2342 if( TBLVAR_CHGABS
== pTab
->GetTable()->GetTblChgMode() &&
2343 ( eType
& nsTblChgWidthHeightType::WH_COL_LEFT
|| eType
& nsTblChgWidthHeightType::WH_COL_RIGHT
) &&
2344 text::HoriOrientation::NONE
== pTab
->GetFmt()->GetHoriOrient().GetHoriOrient() &&
2345 nPrtWidth
!= rTblFrmSz
.GetWidth() )
2347 SwFmtFrmSize
aSz( rTblFrmSz
);
2348 aSz
.SetWidth( pTab
->Prt().Width() );
2349 pTab
->GetFmt()->SetFmtAttr( aSz
);
2352 if( (eType
& (nsTblChgWidthHeightType::WH_FLAG_BIGGER
| nsTblChgWidthHeightType::WH_FLAG_INSDEL
)) ==
2353 (nsTblChgWidthHeightType::WH_FLAG_BIGGER
| nsTblChgWidthHeightType::WH_FLAG_INSDEL
) )
2355 nDiff
= USHORT((pFrm
->Frm().*fnRect
->fnGetWidth
)());
2357 // we must move the cursor outside the current cell before
2358 // deleting the cells.
2359 TblChgWidthHeightType eTmp
=
2360 static_cast<TblChgWidthHeightType
>( eType
& 0xfff );
2363 case nsTblChgWidthHeightType::WH_ROW_TOP
:
2364 lcl_GoTableRow( this, true );
2366 case nsTblChgWidthHeightType::WH_ROW_BOTTOM
:
2367 lcl_GoTableRow( this, false );
2369 case nsTblChgWidthHeightType::WH_COL_LEFT
:
2372 case nsTblChgWidthHeightType::WH_COL_RIGHT
:
2380 SwTwips nLogDiff
= nDiff
;
2381 nLogDiff
*= pTab
->GetFmt()->GetFrmSize().GetWidth();
2382 nLogDiff
/= nPrtWidth
;
2384 /** The cells are destroyed in here */
2385 BOOL bRet
= GetDoc()->SetColRowWidthHeight(
2386 *(SwTableBox
*)((SwCellFrm
*)pFrm
)->GetTabBox(),
2387 eType
, nDiff
, nLogDiff
);
2389 delete pLastCols
, pLastCols
= 0;
2390 EndAllActionAndCall();
2392 if( bRet
&& (eType
& (nsTblChgWidthHeightType::WH_FLAG_BIGGER
| nsTblChgWidthHeightType::WH_FLAG_INSDEL
)) == nsTblChgWidthHeightType::WH_FLAG_INSDEL
)
2394 switch(eType
& ~(nsTblChgWidthHeightType::WH_FLAG_BIGGER
| nsTblChgWidthHeightType::WH_FLAG_INSDEL
))
2396 case nsTblChgWidthHeightType::WH_CELL_LEFT
:
2397 case nsTblChgWidthHeightType::WH_COL_LEFT
:
2401 case nsTblChgWidthHeightType::WH_CELL_RIGHT
:
2402 case nsTblChgWidthHeightType::WH_COL_RIGHT
:
2406 case nsTblChgWidthHeightType::WH_CELL_TOP
:
2407 case nsTblChgWidthHeightType::WH_ROW_TOP
:
2408 lcl_GoTableRow( this, true );
2411 case nsTblChgWidthHeightType::WH_CELL_BOTTOM
:
2412 case nsTblChgWidthHeightType::WH_ROW_BOTTOM
:
2413 lcl_GoTableRow( this, false );
2421 BOOL
lcl_IsFormulaSelBoxes( const SwTable
& rTbl
, const SwTblBoxFormula
& rFml
,
2422 SwCellFrms
& rCells
)
2424 SwTblBoxFormula
aTmp( rFml
);
2426 for( USHORT nSelBoxes
= aTmp
.GetBoxesOfFormula( rTbl
,aBoxes
); nSelBoxes
; )
2428 SwTableBox
* pBox
= aBoxes
[ --nSelBoxes
];
2430 for( i
= 0; i
< rCells
.Count(); ++i
)
2431 if( rCells
[ i
]->GetTabBox() == pBox
)
2434 if( i
== rCells
.Count() )
2441 // erfrage die Formel fuer die Autosumme
2442 BOOL
SwFEShell::GetAutoSum( String
& rFml
) const
2444 SwFrm
*pFrm
= GetCurrFrm();
2445 SwTabFrm
*pTab
= pFrm
? pFrm
->ImplFindTabFrm() : 0;
2449 rFml
= String::CreateFromAscii( sCalc_Sum
);
2452 if( ::GetAutoSumSel( *this, aCells
))
2454 USHORT nW
= 0, nInsPos
= 0;
2455 for( USHORT n
= aCells
.Count(); n
; )
2457 SwCellFrm
* pCFrm
= aCells
[ --n
];
2458 USHORT nBoxW
= pCFrm
->GetTabBox()->IsFormulaOrValueBox();
2464 if( USHRT_MAX
== nBoxW
)
2465 continue; // leere am Anfang ueberspringen
2468 nInsPos
= rFml
.Len();
2470 // Formeln nur wenn diese Boxen enthalten
2471 if( RES_BOXATR_FORMULA
== nBoxW
&&
2472 !::lcl_IsFormulaSelBoxes( *pTab
->GetTable(), pCFrm
->
2473 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells
))
2475 nW
= RES_BOXATR_VALUE
;
2476 // alle vorhierigen Leere wieder mit aufnehmen !
2477 for( USHORT i
= aCells
.Count(); n
+1 < i
; )
2479 String
sTmp( String::CreateFromAscii(
2480 RTL_CONSTASCII_STRINGPARAM( "|<" )) );
2481 sTmp
+= aCells
[ --i
]->GetTabBox()->GetName();
2483 rFml
.Insert( sTmp
, nInsPos
);
2489 else if( RES_BOXATR_VALUE
== nW
)
2491 // values werden gesucht, Value/Formel/Text gefunden -> aufn.
2492 if( RES_BOXATR_FORMULA
== nBoxW
&&
2493 ::lcl_IsFormulaSelBoxes( *pTab
->GetTable(), pCFrm
->
2494 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells
))
2496 else if( USHRT_MAX
!= nBoxW
)
2497 rFml
.Insert( cListDelim
, nInsPos
);
2501 else if( RES_BOXATR_FORMULA
== nW
)
2503 // bei Formeln nur weiter suchen, wenn die akt. Formel auf
2504 // alle Boxen verweist, die sich in der Selektion befinden
2505 if( RES_BOXATR_FORMULA
== nBoxW
)
2507 if( !::lcl_IsFormulaSelBoxes( *pTab
->GetTable(), pCFrm
->
2508 GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells
))
2510 // dann noch mal von vorne und nur die Values!
2512 nW
= RES_BOXATR_VALUE
;
2513 rFml
.Erase( nInsPos
);
2514 // alle vorhierigen Leere wieder mit aufnehmen !
2515 for( USHORT i
= aCells
.Count(); n
+1 < i
; )
2517 String
sTmp( String::CreateFromAscii(
2518 RTL_CONSTASCII_STRINGPARAM( "|<" )) );
2519 sTmp
+= aCells
[ --i
]->GetTabBox()->GetName();
2521 rFml
.Insert( sTmp
, nInsPos
);
2525 rFml
.Insert( cListDelim
, nInsPos
);
2527 else if( USHRT_MAX
== nBoxW
)
2530 continue; // diese Boxen ignorieren
2533 // alles andere beendet die Schleife
2534 // evt. Texte noch zu lassen??
2538 sTmp
+= pCFrm
->GetTabBox()->GetName();
2540 rFml
.Insert( sTmp
, nInsPos
);
2547 // TabellenSelektion erzeugen??
2548 SwTblBoxFormula aTmp( rFml );
2550 for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes );
2560 /* -----------------------------22.08.2002 12:50------------------------------
2562 ---------------------------------------------------------------------------*/
2563 BOOL
SwFEShell::IsTableRightToLeft() const
2565 SwFrm
*pFrm
= GetCurrFrm();
2566 if( !pFrm
|| !pFrm
->IsInTab() )
2569 return pFrm
->ImplFindTabFrm()->IsRightToLeft();
2572 /* -----------------------------22.08.2002 12:50------------------------------
2574 ---------------------------------------------------------------------------*/
2575 BOOL
SwFEShell::IsMouseTableRightToLeft(const Point
&rPt
) const
2577 SwFrm
*pFrm
= (SwFrm
*)GetBox( rPt
);
2578 const SwTabFrm
* pTabFrm
= pFrm
? pFrm
->ImplFindTabFrm() : 0;
2579 ASSERT( pTabFrm
, "Table not found" );
2580 return pTabFrm
? pTabFrm
->IsRightToLeft() : FALSE
;
2583 /* -----------------------------11.02.2004 12:50------------------------------
2585 ---------------------------------------------------------------------------*/
2586 BOOL
SwFEShell::IsTableVertical() const
2588 SwFrm
*pFrm
= GetCurrFrm();
2589 if( !pFrm
|| !pFrm
->IsInTab() )
2592 return pFrm
->ImplFindTabFrm()->IsVertical();