summaryrefslogtreecommitdiff
path: root/sw/source/core/frmedt/fetab.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/frmedt/fetab.cxx')
-rw-r--r--sw/source/core/frmedt/fetab.cxx2593
1 files changed, 2593 insertions, 0 deletions
diff --git a/sw/source/core/frmedt/fetab.cxx b/sw/source/core/frmedt/fetab.cxx
new file mode 100644
index 000000000000..ad2e077e5d7c
--- /dev/null
+++ b/sw/source/core/frmedt/fetab.cxx
@@ -0,0 +1,2593 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+#include <hintids.hxx>
+
+#include <tools/errinf.hxx>
+#include <vcl/svapp.hxx>
+#include <basegfx/vector/b2dvector.hxx>
+#ifndef _SVX_SVXIDS_HRC
+#include <svx/svxids.hrc>
+#endif
+#include <editeng/protitem.hxx>
+#include <editeng/brshitem.hxx>
+#include <editeng/frmdiritem.hxx>
+#include <svtools/ruler.hxx>
+#include <swwait.hxx>
+#include <fmtfsize.hxx>
+#include <fmtornt.hxx>
+#include <frmatr.hxx>
+#include <docary.hxx>
+#include <fesh.hxx>
+#include <doc.hxx>
+#include <cntfrm.hxx>
+#include <rootfrm.hxx>
+#include <pagefrm.hxx>
+#include <tabfrm.hxx>
+#include <rowfrm.hxx>
+#include <cellfrm.hxx>
+#include <flyfrm.hxx>
+#include <dflyobj.hxx>
+#include <swtable.hxx>
+#include <swddetbl.hxx>
+#include <ndtxt.hxx>
+#include <calc.hxx>
+#include <tabcol.hxx>
+#include <cellatr.hxx>
+#include <pam.hxx>
+#include <viscrs.hxx>
+#include <tblsel.hxx>
+#include <swtblfmt.hxx>
+#include <swerror.h>
+#include <swundo.hxx>
+#include <frmtool.hxx>
+
+#include <node.hxx> // #i23726#
+// OD 2004-05-24 #i28701#
+#include <sortedobjs.hxx>
+
+using namespace ::com::sun::star;
+
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+inline BOOL IsSame( long nA, long nB ) { return Abs(nA-nB) <= COLFUZZY; }
+inline BOOL IsNear( long nA, long nB, long nTolerance ) { return Abs( nA - nB ) <= nTolerance; }
+
+// table column cache
+SwTabCols *pLastCols = 0;
+const SwTable *pColumnCacheLastTable = 0;
+const SwTabFrm *pColumnCacheLastTabFrm = 0;
+const SwFrm *pColumnCacheLastCellFrm = 0;
+
+// table row cache
+SwTabCols *pLastRows = 0;
+const SwTable *pRowCacheLastTable = 0;
+const SwTabFrm *pRowCacheLastTabFrm = 0;
+const SwFrm *pRowCacheLastCellFrm = 0;
+
+
+class TblWait
+{
+ SwWait *pWait;
+public:
+ TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2 = 0);
+ ~TblWait() { delete pWait; }
+};
+
+TblWait::TblWait( USHORT nCnt, SwFrm *pFrm, SwDocShell &rDocShell, USHORT nCnt2):
+ pWait( 0 )
+{
+ BOOL bWait = 20 < nCnt || 20 < nCnt2 || (pFrm &&
+ 20 < pFrm->ImplFindTabFrm()->GetTable()->GetTabLines().Count());
+ if( bWait )
+ pWait = new SwWait( rDocShell, TRUE );
+}
+
+
+void SwFEShell::ParkCursorInTab()
+{
+ SwCursor * pSwCrsr = GetSwCrsr();
+
+ ASSERT(pSwCrsr, "no SwCursor");
+
+ SwPosition aStartPos = *pSwCrsr->GetPoint(), aEndPos = aStartPos;
+
+ SwCursor * pTmpCrsr = (SwCursor *) pSwCrsr;
+
+ /* Search least and greatest position in current cursor ring.
+ */
+ do
+ {
+ const SwPosition * pPt = pTmpCrsr->GetPoint(),
+ * pMk = pTmpCrsr->GetMark();
+
+ if (*pPt < aStartPos)
+ aStartPos = *pPt;
+
+ if (*pPt > aEndPos)
+ aEndPos = *pPt;
+
+ if (*pMk < aStartPos)
+ aStartPos = *pMk;
+
+ if (*pMk > aEndPos)
+ aEndPos = *pMk;
+
+ pTmpCrsr = (SwCursor *) pTmpCrsr->GetNext();
+ }
+ while (pTmpCrsr != pSwCrsr);
+
+ KillPams();
+
+ /* @@@ semantic: SwCursor::operator=() is not implemented @@@ */
+
+ /* Set cursor to end of selection to ensure IsLastCellInRow works
+ properly. */
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ /* Move the cursor out of the columns to delete and stay in the
+ same row. If the table has only one column the cursor will
+ stay in the row and the shell will take care of it. */
+ if (IsLastCellInRow())
+ {
+ /* If the cursor is in the last row of the table, first
+ try to move it to the previous cell. If that fails move
+ it to the next cell. */
+
+ {
+ SwCursor aTmpCrsr( aStartPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ if (! pSwCrsr->GoPrevCell())
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ pSwCrsr->GoNextCell();
+ }
+ }
+ else
+ {
+ /* If the cursor is not in the last row of the table, first
+ try to move it to the next cell. If that fails move it
+ to the previous cell. */
+
+ {
+ SwCursor aTmpCrsr( aEndPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ }
+
+ if (! pSwCrsr->GoNextCell())
+ {
+ SwCursor aTmpCrsr( aStartPos, 0, false );
+ *pSwCrsr = aTmpCrsr;
+ pSwCrsr->GoPrevCell();
+ }
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : InsertRow(), InsertCol
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::InsertRow( USHORT nCnt, BOOL bBehind )
+{
+ // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
+
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ BOOL bRet = FALSE;
+ if ( aBoxes.Count() )
+ bRet = GetDoc()->InsertRow( aBoxes, nCnt, bBehind );
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+BOOL SwFEShell::InsertCol( USHORT nCnt, BOOL bBehind )
+{
+ // pruefe ob vom aktuellen Crsr der Point/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+
+ if( !CheckSplitCells( *this, nCnt + 1, nsSwTblSearchType::TBLSEARCH_COL ) )
+ {
+ ErrorHandler::HandleError( ERR_TBLINSCOL_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ StartAllAction();
+ // lasse ueber das Layout die Boxen suchen
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
+
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ BOOL bRet = FALSE;
+ if( aBoxes.Count() )
+ bRet = GetDoc()->InsertCol( aBoxes, nCnt, bBehind );
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : DeleteRow(), DeleteCol()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+
+/**
+ Determines if the current cursor is in the last row of the table.
+*/
+BOOL SwFEShell::IsLastCellInRow() const
+{
+ SwTabCols aTabCols;
+ GetTabCols( aTabCols );
+ BOOL bResult = FALSE;
+
+ if (IsTableRightToLeft())
+ /* If the table is right-to-left the last row is the most left one. */
+ bResult = 0 == GetCurTabColNum();
+ else
+ /* If the table is left-to-right the last row is the most right one. */
+ bResult = aTabCols.Count() == GetCurTabColNum();
+
+ return bResult;
+}
+
+BOOL SwFEShell::DeleteCol()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_COL );
+ if ( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr muessen noch aus dem Loesch Bereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+ while( !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+
+ ParkCursorInTab();
+
+ // dann loesche doch die Spalten
+ StartUndo(UNDO_COL_DELETE);
+ bRet = GetDoc()->DeleteRowCol( aBoxes, true );
+ EndUndo(UNDO_COL_DELETE);
+
+ }
+ else
+ bRet = FALSE;
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+BOOL SwFEShell::DeleteRow()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes, nsSwTblSearchType::TBLSEARCH_ROW );
+
+ if( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr aus dem Loeschbereich entfernen.
+ // Der Cursor steht danach:
+ // - es folgt noch eine Zeile, in dieser
+ // - vorher steht noch eine Zeile, in dieser
+ // - sonst immer dahinter
+ {
+ SwTableNode* pTblNd = ((SwCntntFrm*)pFrm)->GetNode()->FindTableNode();
+
+ // suche alle Boxen / Lines
+ _FndBox aFndBox( 0, 0 );
+ {
+ _FndPara aPara( aBoxes, &aFndBox );
+ pTblNd->GetTable().GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+ }
+
+ if( !aFndBox.GetLines().Count() )
+ {
+ EndAllActionAndCall();
+ return FALSE;
+ }
+
+ KillPams();
+
+ _FndBox* pFndBox = &aFndBox;
+ while( 1 == pFndBox->GetLines().Count() &&
+ 1 == pFndBox->GetLines()[0]->GetBoxes().Count() )
+ {
+ _FndBox* pTmp = pFndBox->GetLines()[0]->GetBoxes()[0];
+ if( pTmp->GetBox()->GetSttNd() )
+ break; // das ist sonst zu weit
+ pFndBox = pTmp;
+ }
+
+ SwTableLine* pDelLine = pFndBox->GetLines()[
+ pFndBox->GetLines().Count()-1 ]->GetLine();
+ SwTableBox* pDelBox = pDelLine->GetTabBoxes()[
+ pDelLine->GetTabBoxes().Count() - 1 ];
+ while( !pDelBox->GetSttNd() )
+ {
+ SwTableLine* pLn = pDelBox->GetTabLines()[
+ pDelBox->GetTabLines().Count()-1 ];
+ pDelBox = pLn->GetTabBoxes()[ pLn->GetTabBoxes().Count() - 1 ];
+ }
+ SwTableBox* pNextBox = pDelLine->FindNextBox( pTblNd->GetTable(),
+ pDelBox, TRUE );
+ while( pNextBox &&
+ pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ pNextBox = pNextBox->FindNextBox( pTblNd->GetTable(), pNextBox );
+
+ if( !pNextBox ) // keine nachfolgende? dann die vorhergehende
+ {
+ pDelLine = pFndBox->GetLines()[ 0 ]->GetLine();
+ pDelBox = pDelLine->GetTabBoxes()[ 0 ];
+ while( !pDelBox->GetSttNd() )
+ pDelBox = pDelBox->GetTabLines()[0]->GetTabBoxes()[0];
+ pNextBox = pDelLine->FindPreviousBox( pTblNd->GetTable(),
+ pDelBox, TRUE );
+ while( pNextBox &&
+ pNextBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ pNextBox = pNextBox->FindPreviousBox( pTblNd->GetTable(), pNextBox );
+ }
+
+ ULONG nIdx;
+ if( pNextBox ) // dann den Cursor hier hinein
+ nIdx = pNextBox->GetSttIdx() + 1;
+ else // ansonsten hinter die Tabelle
+ nIdx = pTblNd->EndOfSectionIndex() + 1;
+
+ SwNodeIndex aIdx( GetDoc()->GetNodes(), nIdx );
+ SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+ if( !pCNd )
+ pCNd = GetDoc()->GetNodes().GoNext( &aIdx );
+
+ if( pCNd )
+ {
+ SwPaM* pPam = GetCrsr();
+ pPam->GetPoint()->nNode = aIdx;
+ pPam->GetPoint()->nContent.Assign( pCNd, 0 );
+ pPam->SetMark(); // beide wollen etwas davon haben
+ pPam->DeleteMark();
+ }
+ }
+
+ // dann loesche doch die Zeilen
+ StartUndo(UNDO_ROW_DELETE);
+ bRet = GetDoc()->DeleteRowCol( aBoxes );
+ EndUndo(UNDO_ROW_DELETE);
+ }
+ else
+ bRet = FALSE;
+
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : MergeTab(), SplitTab()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+
+USHORT SwFEShell::MergeTab()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ USHORT nRet = TBLMERGE_NOSELECTION;
+ if( IsTableMode() )
+ {
+ SwShellTableCrsr* pTableCrsr = GetTableCrsr();
+ const SwTableNode* pTblNd = pTableCrsr->GetNode()->FindTableNode();
+ if( pTblNd->GetTable().ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ }
+ else
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ TblWait( pTableCrsr->GetBoxesCount(), 0, *GetDoc()->GetDocShell(),
+ pTblNd->GetTable().GetTabLines().Count() );
+
+ nRet = GetDoc()->MergeTbl( *pTableCrsr );
+
+ KillPams();
+
+ EndAllActionAndCall();
+ }
+ }
+ return nRet;
+}
+
+BOOL SwFEShell::SplitTab( BOOL bVert, USHORT nCnt, BOOL bSameHeight )
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+
+ if( bVert && !CheckSplitCells( *this, nCnt + 1 ) )
+ {
+ ErrorHandler::HandleError( ERR_TBLSPLIT_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+ StartAllAction();
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSel( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ TblWait( nCnt, pFrm, *GetDoc()->GetDocShell(), aBoxes.Count() );
+
+ // dann loesche doch die Spalten
+ bRet = GetDoc()->SplitTbl( aBoxes, bVert, nCnt, bSameHeight );
+
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ }
+ else
+ bRet = FALSE;
+ EndAllActionAndCall();
+ return bRet;
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : _GetTabCols
+#* Datum : MA 30. Nov. 95
+#* Update : MA 08. Jan. 97
+#***********************************************************************/
+void SwFEShell::_GetTabCols( SwTabCols &rToFill, const SwFrm *pBox ) const
+{
+ const SwTabFrm *pTab = pBox->FindTabFrm();
+ if ( pLastCols )
+ {
+ //Paar Kleinigkeiten muessen wir schon noch sicherstellen
+ BOOL bDel = TRUE;
+ if ( pColumnCacheLastTable == pTab->GetTable() )
+ {
+ bDel = FALSE;
+ SWRECTFN( pTab )
+
+ const SwPageFrm* pPage = pTab->FindPageFrm();
+ const ULONG nLeftMin = (pTab->Frm().*fnRect->fnGetLeft)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+ const ULONG nRightMax = (pTab->Frm().*fnRect->fnGetRight)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+
+ if ( pColumnCacheLastTabFrm != pTab )
+ {
+ //Wenn der TabFrm gewechselt hat, brauchen wir bei gleicher
+ //Breite nur ein wenig shiften.
+ SWRECTFNX( pColumnCacheLastTabFrm )
+ if( (pColumnCacheLastTabFrm->Frm().*fnRectX->fnGetWidth)() ==
+ (pTab->Frm().*fnRect->fnGetWidth)() )
+ {
+ pLastCols->SetLeftMin( nLeftMin );
+
+ //ASSERT( bVert ||
+ // pLastCols->GetLeftMin() == (pTab->Frm().*fnRect->fnGetLeft)(),
+ // "GetTabCols: wrong result" )
+
+ pColumnCacheLastTabFrm = pTab;
+ }
+ else
+ bDel = TRUE;
+ }
+
+ if ( !bDel &&
+ pLastCols->GetLeftMin () == (USHORT)nLeftMin &&
+ pLastCols->GetLeft () == (USHORT)(pTab->Prt().*fnRect->fnGetLeft)() &&
+ pLastCols->GetRight () == (USHORT)(pTab->Prt().*fnRect->fnGetRight)()&&
+ pLastCols->GetRightMax() == (USHORT)nRightMax - pLastCols->GetLeftMin() )
+ {
+ if ( pColumnCacheLastCellFrm != pBox )
+ {
+ pTab->GetTable()->GetTabCols( *pLastCols,
+ ((SwCellFrm*)pBox)->GetTabBox(), TRUE);
+ pColumnCacheLastCellFrm = pBox;
+ }
+ rToFill = *pLastCols;
+ }
+ else
+ bDel = TRUE;
+ }
+ if ( bDel )
+ DELETEZ(pLastCols);
+ }
+ if ( !pLastCols )
+ {
+ GetDoc()->GetTabCols( rToFill, 0, (SwCellFrm*)pBox );
+
+ pLastCols = new SwTabCols( rToFill );
+ pColumnCacheLastTable = pTab->GetTable();
+ pColumnCacheLastTabFrm = pTab;
+ pColumnCacheLastCellFrm= pBox;
+ }
+
+#if OSL_DEBUG_LEVEL > 1
+ SwTabColsEntry aEntry;
+ for ( USHORT i = 0; i < rToFill.Count(); ++i )
+ {
+ aEntry = rToFill.GetEntry( i );
+ (void)aEntry;
+ }
+#endif
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : _GetTabRows
+#* Datum : FME 2004-01-14
+#* Update :
+#***********************************************************************/
+void SwFEShell::_GetTabRows( SwTabCols &rToFill, const SwFrm *pBox ) const
+{
+ const SwTabFrm *pTab = pBox->FindTabFrm();
+ if ( pLastRows )
+ {
+ //Paar Kleinigkeiten muessen wir schon noch sicherstellen
+ BOOL bDel = TRUE;
+ if ( pRowCacheLastTable == pTab->GetTable() )
+ {
+ bDel = FALSE;
+ SWRECTFN( pTab )
+ const SwPageFrm* pPage = pTab->FindPageFrm();
+ const long nLeftMin = ( bVert ?
+ pTab->GetPrtLeft() - pPage->Frm().Left() :
+ pTab->GetPrtTop() - pPage->Frm().Top() );
+ const long nLeft = bVert ? LONG_MAX : 0;
+ const long nRight = (pTab->Prt().*fnRect->fnGetHeight)();
+ const long nRightMax = bVert ? nRight : LONG_MAX;
+
+ if ( pRowCacheLastTabFrm != pTab ||
+ pRowCacheLastCellFrm != pBox )
+ bDel = TRUE;
+
+ if ( !bDel &&
+ pLastRows->GetLeftMin () == nLeftMin &&
+ pLastRows->GetLeft () == nLeft &&
+ pLastRows->GetRight () == nRight &&
+ pLastRows->GetRightMax() == nRightMax )
+ {
+ rToFill = *pLastRows;
+ }
+ else
+ bDel = TRUE;
+ }
+ if ( bDel )
+ DELETEZ(pLastRows);
+ }
+ if ( !pLastRows )
+ {
+ GetDoc()->GetTabRows( rToFill, 0, (SwCellFrm*)pBox );
+
+ pLastRows = new SwTabCols( rToFill );
+ pRowCacheLastTable = pTab->GetTable();
+ pRowCacheLastTabFrm = pTab;
+ pRowCacheLastCellFrm= pBox;
+ }
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabCols(), GetTabCols()
+#* Datum : MA 03. May. 93
+#* Update : MA 18. May. 93
+#***********************************************************************/
+void SwFEShell::SetTabCols( const SwTabCols &rNew, BOOL bCurRowOnly )
+{
+ SwFrm *pBox = GetCurrFrm();
+ if( !pBox || !pBox->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pBox = pBox->GetUpper();
+ } while ( !pBox->IsCellFrm() );
+
+ GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabCols( SwTabCols &rToFill ) const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+
+ _GetTabCols( rToFill, pFrm );
+}
+
+/*-- 19.01.2004 08:56:42---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::GetTabRows( SwTabCols &rToFill ) const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+
+ _GetTabRows( rToFill, pFrm );
+}
+/*-- 19.01.2004 08:56:44---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::SetTabRows( const SwTabCols &rNew, BOOL bCurColOnly )
+{
+ SwFrm *pBox = GetCurrFrm();
+ if( !pBox || !pBox->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pBox = pBox->GetUpper();
+ } while ( !pBox->IsCellFrm() );
+
+ GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+}
+/*-- 19.01.2004 08:59:45---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::GetMouseTabRows( SwTabCols &rToFill, const Point &rPt ) const
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if ( pBox )
+ _GetTabRows( rToFill, pBox );
+}
+/*-- 19.01.2004 08:59:45---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwFEShell::SetMouseTabRows( const SwTabCols &rNew, BOOL bCurColOnly, const Point &rPt )
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if( pBox )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabRows( rNew, bCurColOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+ }
+}
+
+/***********************************************************************
+ * Class : SwFEShell
+ * Methoden : SetRowSplit(), GetRowSplit()
+ * Datum : FME 13.11.2003
+ ***********************************************************************/
+
+void SwFEShell::SetRowSplit( const SwFmtRowSplit& rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowSplit( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetRowSplit( SwFmtRowSplit*& rpSz ) const
+{
+ GetDoc()->GetRowSplit( *getShellCrsr( false ), rpSz );
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetRowHeight(), GetRowHeight()
+#* Datum : MA 17. May. 93
+#* Update : JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetRowHeight( const SwFmtFrmSize &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowHeight( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+/******************************************************************************
+ * SwTwips SwFEShell::GetRowHeight() const
+ ******************************************************************************/
+void SwFEShell::GetRowHeight( SwFmtFrmSize *& rpSz ) const
+{
+ GetDoc()->GetRowHeight( *getShellCrsr( false ), rpSz );
+}
+
+BOOL SwFEShell::BalanceRowHeight( BOOL bTstOnly )
+{
+ SET_CURR_SHELL( this );
+ if( !bTstOnly )
+ StartAllAction();
+ BOOL bRet = GetDoc()->BalanceRowHeight( *getShellCrsr( false ), bTstOnly );
+ if( !bTstOnly )
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/******************************************************************************
+ * void SwFEShell::SetRowBackground()
+ ******************************************************************************/
+void SwFEShell::SetRowBackground( const SvxBrushItem &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowBackground( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+/******************************************************************************
+ * SwTwips SwFEShell::GetRowBackground() const
+ ******************************************************************************/
+BOOL SwFEShell::GetRowBackground( SvxBrushItem &rToFill ) const
+{
+ return GetDoc()->GetRowBackground( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabBorders(), GetTabBorders()
+#* Datum : MA 18. May. 93
+#* Update : JP 29.04.98
+#***********************************************************************/
+
+void SwFEShell::SetTabBorders( const SfxItemSet& rSet )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabBorders( *getShellCrsr( false ), rSet );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::SetTabLineStyle( const Color* pColor, BOOL bSetLine,
+ const SvxBorderLine* pBorderLine )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabLineStyle( *getShellCrsr( false ),
+ pColor, bSetLine, pBorderLine );
+ EndAllActionAndCall();
+}
+
+void SwFEShell::GetTabBorders( SfxItemSet& rSet ) const
+{
+ GetDoc()->GetTabBorders( *getShellCrsr( false ), rSet );
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxBackground(), GetBoxBackground()
+#* Datum : MA 01. Jun. 93
+#* Update : MA 03. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetBoxBackground( const SvxBrushItem &rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::GetBoxBackground( SvxBrushItem &rToFill ) const
+{
+ return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxDirection(), GetBoxDirection()
+#* Datum : FME 2004-02-03
+#* Update : FME 2004-02-03
+#***********************************************************************/
+void SwFEShell::SetBoxDirection( const SvxFrameDirectionItem& rNew )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), rNew );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::GetBoxDirection( SvxFrameDirectionItem& rToFill ) const
+{
+ return GetDoc()->GetBoxAttr( *getShellCrsr( false ), rToFill );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetBoxAlign, SetBoxAlign
+#* Datum : MA 18. Dec. 96
+#* Update : JP 29.04.98
+#***********************************************************************/
+void SwFEShell::SetBoxAlign( USHORT nAlign )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetBoxAlign( *getShellCrsr( false ), nAlign );
+ EndAllActionAndCall();
+}
+
+USHORT SwFEShell::GetBoxAlign() const
+{
+ return GetDoc()->GetBoxAlign( *getShellCrsr( false ) );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : SetTabBackground(), GetTabBackground()
+#* Datum : MA 08. Jul. 96
+#* Update : MA 08. Jul. 96
+#***********************************************************************/
+void SwFEShell::SetTabBackground( const SvxBrushItem &rNew )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return;
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetAttr( rNew, *pFrm->ImplFindTabFrm()->GetFmt() );
+ EndAllAction(); //Kein Call, denn es veraendert sich nichts!
+ GetDoc()->SetModified();
+}
+
+void SwFEShell::GetTabBackground( SvxBrushItem &rToFill ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ rToFill = pFrm->ImplFindTabFrm()->GetFmt()->GetBackground();
+}
+
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : HasWholeTabSelection()
+#* Datum : MA 18. May. 93
+#* Update : MA 20. Jul. 93
+#***********************************************************************/
+BOOL SwFEShell::HasWholeTabSelection() const
+{
+ //Ist die ganze Tabelle Selektiert?
+ if ( IsTableMode() )
+ {
+ SwSelBoxes aBoxes;
+ ::GetTblSelCrs( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ return ( pTblNd && aBoxes[0]->GetSttIdx()-1 == pTblNd->
+ EndOfSectionNode()->StartOfSectionIndex() &&
+ aBoxes[aBoxes.Count()-1]->GetSttNd()->EndOfSectionIndex()+1
+ == pTblNd->EndOfSectionIndex() );
+ }
+ }
+ return FALSE;
+}
+
+BOOL SwFEShell::HasBoxSelection() const
+{
+ if(!IsCrsrInTbl())
+ return FALSE;
+ //Ist die ganze Tabelle Selektiert?
+ if( IsTableMode() )
+ return TRUE;
+ SwPaM* pPam = GetCrsr();
+ // leere Boxen gelten auch ohne Selektion als selektiert
+// if( !pPam->HasMark() )
+// return FALSE;
+ BOOL bChg = FALSE;
+ if( pPam->GetPoint() == pPam->End())
+ {
+ bChg = TRUE;
+ pPam->Exchange();
+ }
+ SwNode* pNd;
+ if( pPam->GetPoint()->nNode.GetIndex() -1 ==
+ ( pNd = pPam->GetNode())->StartOfSectionIndex() &&
+ !pPam->GetPoint()->nContent.GetIndex() &&
+ pPam->GetMark()->nNode.GetIndex() + 1 ==
+ pNd->EndOfSectionIndex())
+ {
+ SwNodeIndex aIdx( *pNd->EndOfSectionNode(), -1 );
+ SwCntntNode* pCNd = GetDoc()->GetNodes()[ aIdx ]->GetCntntNode();
+ if( !pCNd )
+ {
+ pCNd = GetDoc()->GetNodes().GoPrevious( &aIdx );
+ ASSERT( pCNd, "kein ContentNode in der Box ??" );
+ }
+ if( pPam->GetMark()->nContent == pCNd->Len() )
+ {
+ if( bChg )
+ pPam->Exchange();
+ return TRUE;
+ }
+ }
+ if( bChg )
+ pPam->Exchange();
+ return FALSE;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : ProtectCells(), UnProtectCells()
+#* Datum : MA 20. Jul. 93
+#* Update : JP 25. Sep. 93
+#***********************************************************************/
+void SwFEShell::ProtectCells()
+{
+ SvxProtectItem aProt( RES_PROTECT );
+ aProt.SetCntntProtect( TRUE );
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ GetDoc()->SetBoxAttr( *getShellCrsr( false ), aProt );
+
+ if( !IsCrsrReadonly() )
+ {
+ if( IsTableMode() )
+ ClearMark();
+ ParkCursorInTab();
+ }
+ EndAllActionAndCall();
+}
+
+// die Tabellenselektion aufheben
+void SwFEShell::UnProtectCells()
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ if( aBoxes.Count() )
+ GetDoc()->UnProtectCells( aBoxes );
+
+ EndAllActionAndCall();
+}
+
+void SwFEShell::UnProtectTbls()
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->UnProtectTbls( *GetCrsr() );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::HasTblAnyProtection( const String* pTblName,
+ BOOL* pFullTblProtection )
+{
+ return GetDoc()->HasTblAnyProtection( GetCrsr()->GetPoint(), pTblName,
+ pFullTblProtection );
+}
+
+BOOL SwFEShell::CanUnProtectCells() const
+{
+ BOOL bUnProtectAvailable = FALSE;
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ if( pTblNd && !pTblNd->IsProtect() )
+ {
+ SwSelBoxes aBoxes;
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ SwFrm *pFrm = GetCurrFrm();
+ do {
+ pFrm = pFrm->GetUpper();
+ } while ( pFrm && !pFrm->IsCellFrm() );
+ if( pFrm )
+ {
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+ }
+ if( aBoxes.Count() )
+ bUnProtectAvailable = ::HasProtectedCells( aBoxes );
+ }
+ return bUnProtectAvailable;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : GetRowsToRepeat(), SetRowsToRepeat()
+#***********************************************************************/
+USHORT SwFEShell::GetRowsToRepeat() const
+{
+ const SwFrm *pFrm = GetCurrFrm();
+ const SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
+ if( pTab )
+ return pTab->GetTable()->GetRowsToRepeat();
+ return 0;
+}
+
+void SwFEShell::SetRowsToRepeat( USHORT nSet )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ SwTabFrm *pTab = pFrm ? pFrm->FindTabFrm() : 0;
+ if( pTab && pTab->GetTable()->GetRowsToRepeat() != nSet )
+ {
+ SwWait aWait( *GetDoc()->GetDocShell(), TRUE );
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetRowsToRepeat( *pTab->GetTable(), nSet );
+ EndAllActionAndCall();
+ }
+}
+/*-- 30.06.2004 08:46:35---------------------------------------------------
+ returns the number of rows consecutively selected from top
+ -----------------------------------------------------------------------*/
+USHORT lcl_GetRowNumber( const SwPosition& rPos )
+{
+ USHORT nRet = USHRT_MAX;
+ Point aTmpPt;
+ const SwCntntNode *pNd;
+ const SwCntntFrm *pFrm;
+
+ if( 0 != ( pNd = rPos.nNode.GetNode().GetCntntNode() ))
+ pFrm = pNd->GetFrm( &aTmpPt, &rPos, FALSE );
+ else
+ pFrm = 0;
+
+ if ( pFrm && pFrm->IsInTab() )
+ {
+ const SwFrm* pRow = pFrm->GetUpper();
+ while ( !pRow->GetUpper()->IsTabFrm() )
+ pRow = pRow->GetUpper();
+
+ const SwTabFrm* pTabFrm = (const SwTabFrm*)pRow->GetUpper();
+ const SwTableLine* pTabLine = static_cast<const SwRowFrm*>(pRow)->GetTabLine();
+
+ USHORT nI = 0;
+ while ( nI < pTabFrm->GetTable()->GetTabLines().Count() )
+ {
+ if ( pTabFrm->GetTable()->GetTabLines()[ nI ] == pTabLine )
+ {
+ nRet = nI;
+ break;
+ }
+ ++nI;
+ }
+ }
+
+ return nRet;
+}
+USHORT SwFEShell::GetRowSelectionFromTop() const
+{
+ USHORT nRet = 0;
+ const SwPaM* pPaM = IsTableMode() ? GetTableCrsr() : _GetCrsr();
+ const USHORT nPtLine = lcl_GetRowNumber( *pPaM->GetPoint() );
+
+ if ( !IsTableMode() )
+ {
+ nRet = 0 == nPtLine ? 1 : 0;
+ }
+ else
+ {
+ const USHORT nMkLine = lcl_GetRowNumber( *pPaM->GetMark() );
+
+ if ( ( nPtLine == 0 && nMkLine != USHRT_MAX ) ||
+ ( nMkLine == 0 && nPtLine != USHRT_MAX ) )
+ {
+ nRet = Max( nPtLine, nMkLine ) + 1;
+ }
+ }
+
+ return nRet;
+}
+
+/*
+ * 1. case: bRepeat = true
+ * returns true if the current frame is located inside a table headline in
+ * a follow frame
+ *
+ * 2. case: bRepeat = false
+ * returns true if the current frame is localed inside a table headline OR
+ * inside the first line of a table!!!
+ */
+BOOL SwFEShell::CheckHeadline( bool bRepeat ) const
+{
+ BOOL bRet = FALSE;
+ if ( !IsTableMode() )
+ {
+ SwFrm *pFrm = GetCurrFrm(); // DONE MULTIIHEADER
+ if ( pFrm && pFrm->IsInTab() )
+ {
+ SwTabFrm* pTab = pFrm->FindTabFrm();
+ if ( bRepeat )
+ {
+ bRet = pTab->IsFollow() && pTab->IsInHeadline( *pFrm );
+ }
+ else
+ {
+ bRet = ((SwLayoutFrm*)pTab->Lower())->IsAnLower( pFrm ) ||
+ pTab->IsInHeadline( *pFrm );
+ }
+ }
+ }
+ return bRet;
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : AdjustCellWidth()
+#* Datum : MA 20. Feb. 95
+#* Update : MA 27. Jul. 95
+#***********************************************************************/
+
+void SwFEShell::AdjustCellWidth( BOOL bBalance )
+{
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ //WarteCrsr immer einschalten, weil sich im vorraus nicht so recht
+ //ermitteln laesst wieviel Inhalt betroffen ist.
+ TblWait aWait( USHRT_MAX, 0, *GetDoc()->GetDocShell() );
+
+ GetDoc()->AdjustCellWidth( *getShellCrsr( false ), bBalance );
+ EndAllActionAndCall();
+}
+
+BOOL SwFEShell::IsAdjustCellWidthAllowed( BOOL bBalance ) const
+{
+ //Es muss mindestens eine Zelle mit Inhalt in der Selektion enthalten
+ //sein.
+
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+ ::GetTblSelCrs( *this, aBoxes );
+
+ if ( bBalance )
+ return aBoxes.Count() > 1;
+
+ if ( !aBoxes.Count() )
+ {
+ do
+ { pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+ SwTableBox *pBox = (SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox();
+ aBoxes.Insert( pBox );
+ }
+
+ for ( USHORT i = 0; i < aBoxes.Count(); ++i )
+ {
+ SwTableBox *pBox = aBoxes[i];
+ if ( pBox->GetSttNd() )
+ {
+ SwNodeIndex aIdx( *pBox->GetSttNd(), 1 );
+ SwTxtNode* pCNd = aIdx.GetNode().GetTxtNode();
+ if( !pCNd )
+ pCNd = (SwTxtNode*)GetDoc()->GetNodes().GoNext( &aIdx );
+
+ while ( pCNd )
+ {
+ if ( pCNd->GetTxt().Len() )
+ return TRUE;
+ ++aIdx;
+ pCNd = GetDoc()->GetNodes()[ aIdx ]->GetTxtNode();
+ }
+ }
+ }
+ return FALSE;
+}
+
+ // AutoFormat fuer die Tabelle/TabellenSelection
+BOOL SwFEShell::SetTableAutoFmt( const SwTableAutoFmt& rNew )
+{
+ SwTableNode *pTblNd = (SwTableNode*)IsCrsrInTbl();
+ if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+
+ if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
+ GetCrsr();
+
+ // gesamte Tabelle oder nur auf die akt. Selektion
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+ for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ BOOL bRet;
+ if( aBoxes.Count() )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ bRet = GetDoc()->SetTableAutoFmt( aBoxes, rNew );
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ EndAllActionAndCall();
+ }
+ else
+ bRet = FALSE;
+ return bRet;
+}
+
+BOOL SwFEShell::GetTableAutoFmt( SwTableAutoFmt& rGet )
+{
+ const SwTableNode *pTblNd = IsCrsrInTbl();
+ if( !pTblNd || pTblNd->GetTable().IsTblComplex() )
+ return FALSE;
+
+ SwSelBoxes aBoxes;
+
+ if ( !IsTableMode() ) // falls Crsr noch nicht akt. sind
+ GetCrsr();
+
+ // gesamte Tabelle oder nur auf die akt. Selektion
+ if( IsTableMode() )
+ ::GetTblSelCrs( *this, aBoxes );
+ else
+ {
+ const SwTableSortBoxes& rTBoxes = pTblNd->GetTable().GetTabSortBoxes();
+ for( USHORT n = 0; n < rTBoxes.Count(); ++n )
+ {
+ SwTableBox* pBox = rTBoxes[ n ];
+ aBoxes.Insert( pBox );
+ }
+ }
+
+ return GetDoc()->GetTableAutoFmt( aBoxes, rGet );
+}
+
+/***********************************************************************
+#* Class : SwFEShell
+#* Methoden : DeleteTblSel()
+#* Datum : MA 03. May. 93
+#* Update : MA 19. Apr. 95
+#***********************************************************************/
+BOOL SwFEShell::DeleteTblSel()
+{
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ // lasse ueber das Layout die Boxen suchen
+ BOOL bRet;
+ SwSelBoxes aBoxes;
+ GetTblSelCrs( *this, aBoxes );
+ if( aBoxes.Count() )
+ {
+ TblWait( aBoxes.Count(), pFrm, *GetDoc()->GetDocShell() );
+
+ // die Crsr muessen noch aus dem Loesch Bereich entfernt
+ // werden. Setze sie immer hinter/auf die Tabelle; ueber die
+ // Dokument-Position werden sie dann immer an die alte Position gesetzt.
+ while( !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+ ParkCrsr( SwNodeIndex( *((SwCellFrm*)pFrm)->GetTabBox()->GetSttNd() ));
+
+ bRet = GetDoc()->DeleteRowCol( aBoxes );
+
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+ }
+ else
+ bRet = FALSE;
+ EndAllActionAndCall();
+ return bRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetCurTabColNum()
+|*
+|* Ersterstellung MA 03. Feb. 95
+|* Letzte Aenderung MA 21. May. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurTabColNum() const
+{
+ //!!!GetCurMouseTabColNum() mitpflegen!!!!
+ USHORT nRet = 0;
+
+ SwFrm *pFrm = GetCurrFrm();
+ ASSERT( pFrm, "Crsr geparkt?" );
+
+ // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
+ if( pFrm && pFrm->IsInTab() )
+ {
+ do { // JP 26.09.95: warum mit dem CntntFrame und nicht mit
+ // dem CellFrame vergleichen????
+ pFrm = pFrm->GetUpper();
+ } while ( !pFrm->IsCellFrm() );
+ SWRECTFN( pFrm )
+
+ const SwPageFrm* pPage = pFrm->FindPageFrm();
+
+ //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+ SwTabCols aTabCols;
+ GetTabCols( aTabCols );
+
+ if( pFrm->FindTabFrm()->IsRightToLeft() )
+ {
+ long nX = (pFrm->Frm().*fnRect->fnGetRight)() - (pPage->Frm().*fnRect->fnGetLeft)();
+
+ const long nRight = aTabCols.GetLeftMin() + aTabCols.GetRight();;
+
+ if ( !::IsSame( nX, nRight ) )
+ {
+ nX = nRight - nX + aTabCols.GetLeft();
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ else
+ {
+ const long nX = (pFrm->Frm().*fnRect->fnGetLeft)() -
+ (pPage->Frm().*fnRect->fnGetLeft)();
+
+ const long nLeft = aTabCols.GetLeftMin();
+
+ if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+ {
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ }
+ return nRet;
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetBox()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Letzte Aenderung MA 21. Nov. 96
+|*
+|*************************************************************************/
+
+const SwFrm *lcl_FindFrmInTab( const SwLayoutFrm *pLay, const Point &rPt, SwTwips nFuzzy )
+{
+ const SwFrm *pFrm = pLay->Lower();
+
+ while( pFrm && pLay->IsAnLower( pFrm ) )
+ {
+ if ( pFrm->Frm().IsNear( rPt, nFuzzy ) )
+ {
+ if ( pFrm->IsLayoutFrm() )
+ {
+ const SwFrm *pTmp = ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, rPt, nFuzzy );
+ if ( pTmp )
+ return pTmp;
+ }
+
+ return pFrm;
+ }
+
+ pFrm = pFrm->FindNext();
+ }
+
+ return 0;
+}
+
+const SwCellFrm *lcl_FindFrm( const SwLayoutFrm *pLay, const Point &rPt,
+ SwTwips nFuzzy, bool* pbRow, bool* pbCol )
+{
+ // bMouseMoveRowCols :
+ // Method is called for
+ // - Moving columns/rows with the mouse or
+ // - Enhanced table selection
+ const bool bMouseMoveRowCols = 0 == pbCol;
+
+ bool bCloseToRow = false;
+ bool bCloseToCol = false;
+
+ const SwFrm *pFrm = pLay->ContainsCntnt();
+ const SwFrm* pRet = 0;
+
+ if ( pFrm )
+ {
+ do
+ {
+ if ( pFrm->IsInTab() )
+ pFrm = ((SwFrm*)pFrm)->ImplFindTabFrm();
+
+ if ( pFrm->IsTabFrm() )
+ {
+ Point aPt( rPt );
+ bool bSearchForFrmInTab = true;
+ SwTwips nTmpFuzzy = nFuzzy;
+
+ if ( !bMouseMoveRowCols )
+ {
+ // We ignore nested tables for the enhanced table selection:
+ while ( pFrm->GetUpper()->IsInTab() )
+ pFrm = pFrm->GetUpper()->FindTabFrm();
+
+ // We first check if the given point is 'close' to the left or top
+ // border of the table frame:
+ ASSERT( pFrm, "Nested table frame without outer table" )
+ SWRECTFN( pFrm )
+ const bool bRTL = pFrm->IsRightToLeft();
+
+ SwRect aTabRect = pFrm->Prt();
+ aTabRect.Pos() += pFrm->Frm().Pos();
+
+ const SwTwips nLeft = bRTL ?
+ (aTabRect.*fnRect->fnGetRight)() :
+ (aTabRect.*fnRect->fnGetLeft)();
+ const SwTwips nTop = (aTabRect.*fnRect->fnGetTop)();
+
+ SwTwips& rPointX = bVert ? aPt.Y() : aPt.X();
+ SwTwips& rPointY = bVert ? aPt.X() : aPt.Y();
+
+ const SwTwips nXDiff = (*fnRect->fnXDiff)( nLeft, rPointX ) * ( bRTL ? (-1) : 1 );
+ const SwTwips nYDiff = (*fnRect->fnYDiff)( nTop, rPointY );
+
+ bCloseToRow = nXDiff >= 0 && nXDiff < nFuzzy;
+ bCloseToCol = nYDiff >= 0 && nYDiff < nFuzzy;
+
+ if ( bCloseToCol && 2 * nYDiff > nFuzzy )
+ {
+ const SwFrm* pPrev = pFrm->GetPrev();
+ if ( pPrev )
+ {
+ SwRect aPrevRect = pPrev->Prt();
+ aPrevRect.Pos() += pPrev->Frm().Pos();
+
+ if( aPrevRect.IsInside( rPt ) )
+ {
+ bCloseToCol = false;
+ }
+ }
+
+ }
+
+ // If we found the point to be 'close' to the left or top border
+ // of the table frame, we adjust the point to be on that border:
+ if ( bCloseToRow && bCloseToCol )
+ aPt = bRTL ? aTabRect.TopRight() : (aTabRect.*fnRect->fnGetPos)();
+ else if ( bCloseToRow )
+ rPointX = nLeft;
+ else if ( bCloseToCol )
+ rPointY = nTop;
+
+ if ( !bCloseToRow && !bCloseToCol )
+ bSearchForFrmInTab = false;
+
+ // Since the point has been adjusted, we call lcl_FindFrmInTab()
+ // with a fuzzy value of 1:
+ nTmpFuzzy = 1;
+ }
+
+ const SwFrm* pTmp = bSearchForFrmInTab ?
+ ::lcl_FindFrmInTab( (SwLayoutFrm*)pFrm, aPt, nTmpFuzzy ) :
+ 0;
+
+ if ( pTmp )
+ {
+ pFrm = pTmp;
+ break;
+ }
+ }
+ pFrm = pFrm->FindNextCnt();
+
+ } while ( pFrm && pLay->IsAnLower( pFrm ) );
+ }
+
+ if ( pFrm && pFrm->IsInTab() && pLay->IsAnLower( pFrm ) )
+ {
+ do
+ {
+ // We allow mouse drag of table borders within nested tables,
+ // but disallow hotspot selection of nested tables.
+ if ( bMouseMoveRowCols )
+ {
+ // find the next cell frame
+ while ( pFrm && !pFrm->IsCellFrm() )
+ pFrm = pFrm->GetUpper();
+ }
+ else
+ {
+ // find the most upper cell frame:
+ while ( pFrm &&
+ ( !pFrm->IsCellFrm() ||
+ !pFrm->GetUpper()->GetUpper()->IsTabFrm() ||
+ pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) )
+ pFrm = pFrm->GetUpper();
+ }
+
+ if ( pFrm ) // Note: this condition should be the same like the while condition!!!
+ {
+ // --> FME 2004-07-30 #i32329# Enhanced table selection
+ // used for hotspot selection of tab/cols/rows
+ if ( !bMouseMoveRowCols )
+ {
+
+ ASSERT( pbCol && pbRow, "pbCol or pbRow missing" )
+
+ if ( bCloseToRow || bCloseToCol )
+ {
+ *pbRow = bCloseToRow;
+ *pbCol = bCloseToCol;
+ pRet = pFrm;
+ break;
+ }
+ }
+ // <--
+ else
+ {
+ // used for mouse move of columns/rows
+ const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
+ SwRect aTabRect = pTabFrm->Prt();
+ aTabRect.Pos() += pTabFrm->Frm().Pos();
+
+ SWRECTFN( pTabFrm )
+
+ const SwTwips nTabTop = (aTabRect.*fnRect->fnGetTop)();
+ const SwTwips nMouseTop = bVert ? rPt.X() : rPt.Y();
+
+ // Do not allow to drag upper table border:
+ if ( !::IsSame( nTabTop, nMouseTop ) )
+ {
+ if ( ::IsSame( pFrm->Frm().Left(), rPt.X() ) ||
+ ::IsSame( pFrm->Frm().Right(),rPt.X() ) )
+ {
+ if ( pbRow ) *pbRow = false;
+ pRet = pFrm;
+ break;
+ }
+ if ( ::IsSame( pFrm->Frm().Top(), rPt.Y() ) ||
+ ::IsSame( pFrm->Frm().Bottom(),rPt.Y() ) )
+ {
+ if ( pbRow ) *pbRow = true;
+ pRet = pFrm;
+ break;
+ }
+ }
+ }
+
+ pFrm = pFrm->GetUpper();
+ }
+ } while ( pFrm );
+ }
+
+ // robust:
+ ASSERT( !pRet || pRet->IsCellFrm(), "lcl_FindFrm() is supposed to find a cell frame!" )
+ return pRet && pRet->IsCellFrm() ? static_cast<const SwCellFrm*>(pRet) : 0;
+}
+
+//
+// pbCol = 0 => Used for moving table rows/cols with mouse
+// pbCol != 0 => Used for selecting table/rows/cols
+//
+#define ENHANCED_TABLE_SELECTION_FUZZY 10
+
+const SwFrm* SwFEShell::GetBox( const Point &rPt, bool* pbRow, bool* pbCol ) const
+{
+ const SwPageFrm *pPage = (SwPageFrm*)GetLayout()->Lower();
+ Window* pOutWin = GetWin();
+ SwTwips nFuzzy = COLFUZZY;
+ if( pOutWin )
+ {
+ // --> FME 2004-07-30 #i32329# Enhanced table selection
+ SwTwips nSize = pbCol ? ENHANCED_TABLE_SELECTION_FUZZY : RULER_MOUSE_MARGINWIDTH;
+ // <--
+ Size aTmp( nSize, nSize );
+ aTmp = pOutWin->PixelToLogic( aTmp );
+ nFuzzy = aTmp.Width();
+ }
+
+ while ( pPage && !pPage->Frm().IsNear( rPt, nFuzzy ) )
+ pPage = (SwPageFrm*)pPage->GetNext();
+
+ const SwCellFrm *pFrm = 0;
+ if ( pPage )
+ {
+ //Per GetCrsrOfst oder GetCntntPos koennen wir hier die Box leider
+ //nicht suchen. Das wuerde zu einem Performance-Zusammenbruch bei
+ //Dokumenten mit vielen Absaetzen/Tabellen auf einer Seite fuehren
+ //(BrowseMode!)
+
+ //Erst die Flys checken.
+ if ( pPage->GetSortedObjs() )
+ {
+ for ( USHORT i = 0; !pFrm && i < pPage->GetSortedObjs()->Count(); ++i )
+ {
+ SwAnchoredObject* pObj = (*pPage->GetSortedObjs())[i];
+ if ( pObj->ISA(SwFlyFrm) )
+ {
+ pFrm = lcl_FindFrm( static_cast<SwFlyFrm*>(pObj),
+ rPt, nFuzzy, pbRow, pbCol );
+ }
+ }
+ }
+ const SwLayoutFrm *pLay = (SwLayoutFrm*)pPage->Lower();
+ while ( pLay && !pFrm )
+ {
+ pFrm = lcl_FindFrm( pLay, rPt, nFuzzy, pbRow, pbCol );
+ pLay = (SwLayoutFrm*)pLay->GetNext();
+ }
+ }
+ return pFrm;
+}
+
+/* Helper function*/
+/* calculated the distance between Point rC and Line Segment (rA, rB) */
+double lcl_DistancePoint2Segment( const Point& rA, const Point& rB, const Point& rC )
+{
+ double nRet = 0;
+
+ const basegfx::B2DVector aBC( rC.X() - rB.X(), rC.Y() - rB.Y() );
+ const basegfx::B2DVector aAB( rB.X() - rA.X(), rB.Y() - rA.Y() );
+ const double nDot1 = aBC.scalar( aAB );
+
+ if ( nDot1 > 0 ) // check outside case 1
+ nRet = aBC.getLength();
+ else
+ {
+ const basegfx::B2DVector aAC( rC.X() - rA.X(), rC.Y() - rA.Y() );
+ const basegfx::B2DVector aBA( rA.X() - rB.X(), rA.Y() - rB.Y() );
+ const double nDot2 = aAC.scalar( aBA );
+
+ if ( nDot2 > 0 ) // check outside case 2
+ nRet = aAC.getLength();
+ else
+ {
+ const double nDiv = aAB.getLength();
+ nRet = nDiv ? aAB.cross( aAC ) / nDiv : 0;
+ }
+ }
+
+ return Abs(nRet);
+}
+
+/* Helper function*/
+Point lcl_ProjectOntoClosestTableFrm( const SwTabFrm& rTab, const Point& rPoint, bool bRowDrag )
+{
+ Point aRet( rPoint );
+ const SwTabFrm* pCurrentTab = &rTab;
+ const bool bVert = pCurrentTab->IsVertical();
+ const bool bRTL = pCurrentTab->IsRightToLeft();
+
+ // Western Layout:
+ // bRowDrag = true => compare to left border of table
+ // bRowDrag = false => compare to top border of table
+
+ // Asian Layout:
+ // bRowDrag = true => compare to right border of table
+ // bRowDrag = false => compare to top border of table
+
+ // RTL Layout:
+ // bRowDrag = true => compare to right border of table
+ // bRowDrag = false => compare to top border of table
+ bool bLeft = false;
+ bool bRight = false;
+
+ if ( bRowDrag )
+ {
+ if ( bVert || bRTL )
+ bRight = true;
+ else
+ bLeft = true;
+ }
+
+ // used to find the minimal distance
+ double nMin = -1;
+ Point aMin1;
+ Point aMin2;
+
+ Point aS1;
+ Point aS2;
+
+ while ( pCurrentTab )
+ {
+ SwRect aTabRect( pCurrentTab->Prt() );
+ aTabRect += pCurrentTab->Frm().Pos();
+
+ if ( bLeft )
+ {
+ // distance to left table border
+ aS1 = aTabRect.TopLeft();
+ aS2 = aTabRect.BottomLeft();
+ }
+ else if ( bRight )
+ {
+ // distance to right table border
+ aS1 = aTabRect.TopRight();
+ aS2 = aTabRect.BottomRight();
+ }
+ else //if ( bTop )
+ {
+ // distance to top table border
+ aS1 = aTabRect.TopLeft();
+ aS2 = aTabRect.TopRight();
+ }
+
+ const double nDist = lcl_DistancePoint2Segment( aS1, aS2, rPoint );
+
+ if ( nDist < nMin || -1 == nMin )
+ {
+ aMin1 = aS1;
+ aMin2 = aS2;
+ nMin = nDist;
+ }
+
+ pCurrentTab = pCurrentTab->GetFollow();
+ }
+
+ // project onto closest line:
+ if ( bLeft || bRight )
+ {
+ aRet.X() = aMin1.X();
+ if ( aRet.Y() > aMin2.Y() )
+ aRet.Y() = aMin2.Y();
+ else if ( aRet.Y() < aMin1.Y() )
+ aRet.Y() = aMin1.Y();
+ }
+ else //if ( bTop )
+ {
+ aRet.Y() = aMin1.Y();
+ if ( aRet.X() > aMin2.X() )
+ aRet.X() = aMin2.X();
+ else if ( aRet.X() < aMin1.X() )
+ aRet.X() = aMin1.X();
+ }
+
+ return aRet;
+}
+
+// --> FME 2004-07-30 #i32329# Enhanced table selection
+bool SwFEShell::SelTblRowCol( const Point& rPt, const Point* pEnd, bool bRowDrag )
+{
+ bool bRet = false;
+ Point aEndPt;
+ if ( pEnd )
+ aEndPt = *pEnd;
+
+ SwPosition* ppPos[2] = { 0, 0 };
+ Point paPt [2] = { rPt, aEndPt };
+ bool pbRow[2] = { 0, 0 };
+ bool pbCol[2] = { 0, 0 };
+
+ // pEnd is set during dragging.
+ for ( USHORT i = 0; i < ( pEnd ? 2 : 1 ); ++i )
+ {
+ const SwCellFrm* pFrm =
+ static_cast<const SwCellFrm*>(GetBox( paPt[i], &pbRow[i], &pbCol[i] ) );
+
+ if( pFrm )
+ {
+ while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
+ pFrm = static_cast<const SwCellFrm*>( static_cast<const SwLayoutFrm*>( pFrm->Lower() )->Lower() );
+ if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
+ pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
+ pFrm = 0;
+ }
+
+ if ( pFrm )
+ {
+ const SwCntntFrm* pCntnt = ::GetCellCntnt( *pFrm );
+
+ if ( pCntnt && pCntnt->IsTxtFrm() )
+ {
+ ppPos[i] = new SwPosition( *pCntnt->GetNode() );
+ ppPos[i]->nContent.Assign( const_cast<SwCntntNode*>(pCntnt->GetNode()), 0 );
+
+ // paPt[i] will not be used any longer, now we use it to store
+ // a position inside the content frame
+ paPt[i] = pCntnt->Frm().Center();
+ }
+ }
+
+ // no calculation of end frame if start frame has not been found.
+ if ( 1 == i || !ppPos[0] || !pEnd )
+ break;
+
+ // find 'closest' table frame to pEnd:
+ const SwTabFrm* pCurrentTab = pFrm->FindTabFrm();
+ if ( pCurrentTab->IsFollow() )
+ pCurrentTab = pCurrentTab->FindMaster( true );
+
+ const Point aProjection = lcl_ProjectOntoClosestTableFrm( *pCurrentTab, *pEnd, bRowDrag );
+ paPt[1] = aProjection;
+ }
+
+ if ( ppPos[0] )
+ {
+ SwShellCrsr* pCrsr = _GetCrsr();
+ SwCrsrSaveState aSaveState( *pCrsr );
+ SwPosition aOldPos( *pCrsr->GetPoint() );
+
+ pCrsr->DeleteMark();
+ *pCrsr->GetPoint() = *ppPos[0];
+ pCrsr->GetPtPos() = paPt[0];
+
+ if ( !pCrsr->IsInProtectTable( FALSE, TRUE ) )
+ {
+ bool bNewSelection = true;
+
+ if ( ppPos[1] )
+ {
+ if ( ppPos[1]->nNode.GetNode().StartOfSectionNode() !=
+ aOldPos.nNode.GetNode().StartOfSectionNode() )
+ {
+ pCrsr->SetMark();
+ SwCrsrSaveState aSaveState2( *pCrsr );
+ *pCrsr->GetPoint() = *ppPos[1];
+ pCrsr->GetPtPos() = paPt[1];
+
+ if ( pCrsr->IsInProtectTable( FALSE, FALSE ) )
+ {
+ pCrsr->RestoreSavePos();
+ bNewSelection = false;
+ }
+ }
+ else
+ {
+ pCrsr->RestoreSavePos();
+ bNewSelection = false;
+ }
+ }
+
+ if ( bNewSelection )
+ {
+ // --> FME 2004-10-20 #i35543# SelTblRowCol should remove any existing
+ // table cursor:
+ if ( IsTableMode() )
+ TblCrsrToCursor();
+ // <--
+
+ if ( pbRow[0] && pbCol[0] )
+ bRet = SwCrsrShell::SelTbl();
+ else if ( pbRow[0] )
+ bRet = SwCrsrShell::_SelTblRowOrCol( true, true );
+ else if ( pbCol[0] )
+ bRet = SwCrsrShell::_SelTblRowOrCol( false, true );
+ }
+ else
+ bRet = true;
+ }
+
+ delete ppPos[0];
+ delete ppPos[1];
+ }
+
+ return bRet;
+}
+// <--
+
+
+/*************************************************************************
+|*
+|* SwFEShell::WhichMouseTabCol()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Last change AMA 12. Jun. 02
+|
+|*************************************************************************/
+BYTE SwFEShell::WhichMouseTabCol( const Point &rPt ) const
+{
+ BYTE nRet = SW_TABCOL_NONE;
+ bool bRow = false;
+ bool bCol = false;
+ bool bSelect = false;
+
+ // First try: Do we get the row/col move cursor?
+ SwCellFrm* pFrm = (SwCellFrm*)GetBox( rPt, &bRow, 0 );
+
+ if ( !pFrm )
+ {
+ // Second try: Do we get the row/col/tab selection cursor?
+ pFrm = (SwCellFrm*)GetBox( rPt, &bRow, &bCol );
+ bSelect = true;
+ }
+
+ if( pFrm )
+ {
+ while( pFrm->Lower() && pFrm->Lower()->IsRowFrm() )
+ pFrm = (SwCellFrm*)((SwLayoutFrm*)pFrm->Lower())->Lower();
+ if( pFrm && pFrm->GetTabBox()->GetSttNd() &&
+ pFrm->GetTabBox()->GetSttNd()->IsInProtectSect() )
+ pFrm = 0;
+ }
+
+ if( pFrm )
+ {
+ if ( !bSelect )
+ {
+ if ( pFrm->IsVertical() )
+ nRet = bRow ? SW_TABCOL_VERT : SW_TABROW_VERT;
+ else
+ nRet = bRow ? SW_TABROW_HORI : SW_TABCOL_HORI;
+ }
+ else
+ {
+ const SwTabFrm* pTabFrm = pFrm->FindTabFrm();
+ if ( pTabFrm->IsVertical() )
+ {
+ if ( bRow && bCol )
+ {
+ nRet = SW_TABSEL_VERT;
+ }
+ else if ( bRow )
+ {
+ nRet = SW_TABROWSEL_VERT;
+ }
+ else if ( bCol )
+ {
+ nRet = SW_TABCOLSEL_VERT;
+ }
+ }
+ else
+ {
+ if ( bRow && bCol )
+ {
+ nRet = pTabFrm->IsRightToLeft() ?
+ SW_TABSEL_HORI_RTL :
+ SW_TABSEL_HORI;
+ }
+ else if ( bRow )
+ {
+ nRet = pTabFrm->IsRightToLeft() ?
+ SW_TABROWSEL_HORI_RTL :
+ SW_TABROWSEL_HORI;
+ }
+ else if ( bCol )
+ {
+ nRet = SW_TABCOLSEL_HORI;
+ }
+ }
+ }
+ }
+
+ return nRet;
+}
+
+// -> #i23726#
+SwTxtNode * SwFEShell::GetNumRuleNodeAtPos( const Point &rPt)
+{
+ SwTxtNode * pResult = NULL;
+
+ SwContentAtPos aCntntAtPos
+ (SwContentAtPos::SW_NUMLABEL);
+
+ if( GetContentAtPos(rPt, aCntntAtPos) && aCntntAtPos.aFnd.pNode)
+ pResult = aCntntAtPos.aFnd.pNode->GetTxtNode();
+
+ return pResult;
+}
+
+BOOL SwFEShell::IsNumLabel( const Point &rPt, int nMaxOffset )
+{
+ BOOL bResult = FALSE;
+
+ SwContentAtPos aCntntAtPos
+ (SwContentAtPos::SW_NUMLABEL);
+
+ if( GetContentAtPos(rPt, aCntntAtPos))
+ {
+ if ((nMaxOffset >= 0 && aCntntAtPos.nDist <= nMaxOffset) ||
+ (nMaxOffset < 0))
+ bResult = TRUE;
+ }
+
+ return bResult;
+}
+// <- #i23726#
+
+// --> OD 2005-02-21 #i42921#
+bool SwFEShell::IsVerticalModeAtNdAndPos( const SwTxtNode& _rTxtNode,
+ const Point& _rDocPos ) const
+{
+ bool bRet( false );
+
+ const short nTextDir =
+ _rTxtNode.GetTextDirection( SwPosition(_rTxtNode), &_rDocPos );
+ switch ( nTextDir )
+ {
+ case -1:
+ case FRMDIR_HORI_RIGHT_TOP:
+ case FRMDIR_HORI_LEFT_TOP:
+ {
+ bRet = false;
+ }
+ break;
+ case FRMDIR_VERT_TOP_LEFT:
+ case FRMDIR_VERT_TOP_RIGHT:
+ {
+ bRet = true;
+ }
+ break;
+ }
+
+ return bRet;
+}
+// <--
+
+/*************************************************************************
+|*
+|* SwFEShell::GetMouseTabCols()
+|*
+|* Ersterstellung MA 22. Jun. 95
+|* Letzte Aenderung MA 27. Aug. 96
+|
+|*************************************************************************/
+void SwFEShell::GetMouseTabCols( SwTabCols &rToFill, const Point &rPt ) const
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if ( pBox )
+ _GetTabCols( rToFill, pBox );
+}
+
+void SwFEShell::SetMouseTabCols( const SwTabCols &rNew, BOOL bCurRowOnly,
+ const Point &rPt )
+{
+ const SwFrm *pBox = GetBox( rPt );
+ if( pBox )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ GetDoc()->SetTabCols( rNew, bCurRowOnly, 0, (SwCellFrm*)pBox );
+ EndAllActionAndCall();
+ }
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetMouseColNum(), GetMouseTabColNum()
+|*
+|* Ersterstellung MA 04. Jul. 95
+|* Letzte Aenderung MA 04. Jul. 95
+|
+|*************************************************************************/
+USHORT SwFEShell::GetCurMouseColNum( const Point &rPt,
+ SwGetCurColNumPara* pPara ) const
+{
+ return _GetCurColNum( GetBox( rPt ), pPara );
+}
+
+USHORT SwFEShell::GetCurMouseTabColNum( const Point &rPt ) const
+{
+ //!!!GetCurTabColNum() mitpflegen!!!!
+ USHORT nRet = 0;
+
+ const SwFrm *pFrm = GetBox( rPt );
+ ASSERT( pFrm, "Table not found" );
+ if( pFrm )
+ {
+ const long nX = pFrm->Frm().Left();
+
+ //TabCols besorgen, den nur ueber diese erreichen wir die Position.
+ SwTabCols aTabCols;
+ GetMouseTabCols( aTabCols, rPt );
+
+ const long nLeft = aTabCols.GetLeftMin();
+
+ if ( !::IsSame( nX, nLeft + aTabCols.GetLeft() ) )
+ {
+ for ( USHORT i = 0; i < aTabCols.Count(); ++i )
+ if ( ::IsSame( nX, nLeft + aTabCols[i] ) )
+ {
+ nRet = i + 1;
+ break;
+ }
+ }
+ }
+ return nRet;
+}
+
+void ClearFEShellTabCols()
+{
+ DELETEZ( pLastCols );
+ DELETEZ( pLastRows );
+}
+
+/*************************************************************************
+|*
+|* SwFEShell::GetTblAttr(), SetTblAttr()
+|*
+|* Ersterstellung MA 09. Dec. 96
+|* Letzte Aenderung MA 09. Dec. 96
+|
+|*************************************************************************/
+void SwFEShell::GetTblAttr( SfxItemSet &rSet ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ rSet.Put( pFrm->ImplFindTabFrm()->GetFmt()->GetAttrSet() );
+}
+
+void SwFEShell::SetTblAttr( const SfxItemSet &rNew )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( pFrm && pFrm->IsInTab() )
+ {
+ SET_CURR_SHELL( this );
+ StartAllAction();
+ SwTabFrm *pTab = pFrm->FindTabFrm();
+ pTab->GetTable()->SetHTMLTableLayout( 0 );
+ GetDoc()->SetAttr( rNew, *pTab->GetFmt() );
+ GetDoc()->SetModified();
+ EndAllActionAndCall();
+ }
+}
+
+/** move cursor within a table into previous/next row (same column)
+ * @param pShell cursor shell whose cursor is to be moved
+ * @param bUp true: move up, false: move down
+ * @returns true if successful
+ */
+bool lcl_GoTableRow( SwCrsrShell* pShell, bool bUp )
+{
+ ASSERT( pShell != NULL, "need shell" );
+
+ bool bRet = false;
+
+ SwPaM* pPam = pShell->GetCrsr();
+ const SwStartNode* pTableBox = pPam->GetNode()->FindTableBoxStartNode();
+ ASSERT( pTableBox != NULL, "I'm living in a box... NOT!" );
+
+ // move cursor to start node of table box
+ pPam->GetPoint()->nNode = pTableBox->GetIndex();
+ pPam->GetPoint()->nContent.Assign( NULL, 0 );
+ GoInCntnt( *pPam, fnMoveForward );
+
+ // go to beginning end of table box
+ SwPosSection fnPosSect = bUp ? fnSectionStart : fnSectionEnd;
+ pShell->MoveSection( fnSectionCurr, fnPosSect );
+
+ // and go up/down into next content
+ bRet = bUp ? pShell->Up() : pShell->Down();
+
+ return bRet;
+}
+
+ // aender eine Zellenbreite/-Hoehe/Spaltenbreite/Zeilenhoehe
+BOOL SwFEShell::SetColRowWidthHeight( USHORT eType, USHORT nDiff )
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ if( nsTblChgWidthHeightType::WH_FLAG_INSDEL & eType &&
+ pFrm->ImplFindTabFrm()->GetTable()->ISA( SwDDETable ))
+ {
+ ErrorHandler::HandleError( ERR_TBLDDECHG_ERROR,
+ ERRCODE_MSG_INFO | ERRCODE_BUTTON_DEF_OK );
+ return FALSE;
+ }
+
+ SET_CURR_SHELL( this );
+ StartAllAction();
+
+ do {
+ pFrm = pFrm->GetUpper();
+ } while( !pFrm->IsCellFrm() );
+
+ SwTabFrm *pTab = pFrm->ImplFindTabFrm();
+
+ // sollte die Tabelle noch auf relativen Werten (USHRT_MAX) stehen
+ // dann muss es jetzt auf absolute umgerechnet werden.
+ const SwFmtFrmSize& rTblFrmSz = pTab->GetFmt()->GetFrmSize();
+ SWRECTFN( pTab )
+ long nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+ if( TBLVAR_CHGABS == pTab->GetTable()->GetTblChgMode() &&
+ ( eType & nsTblChgWidthHeightType::WH_COL_LEFT || eType & nsTblChgWidthHeightType::WH_COL_RIGHT ) &&
+ text::HoriOrientation::NONE == pTab->GetFmt()->GetHoriOrient().GetHoriOrient() &&
+ nPrtWidth != rTblFrmSz.GetWidth() )
+ {
+ SwFmtFrmSize aSz( rTblFrmSz );
+ aSz.SetWidth( pTab->Prt().Width() );
+ pTab->GetFmt()->SetFmtAttr( aSz );
+ }
+
+ if( (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) ==
+ (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL) )
+ {
+ nDiff = USHORT((pFrm->Frm().*fnRect->fnGetWidth)());
+
+ // we must move the cursor outside the current cell before
+ // deleting the cells.
+ TblChgWidthHeightType eTmp =
+ static_cast<TblChgWidthHeightType>( eType & 0xfff );
+ switch( eTmp )
+ {
+ case nsTblChgWidthHeightType::WH_ROW_TOP:
+ lcl_GoTableRow( this, true );
+ break;
+ case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
+ lcl_GoTableRow( this, false );
+ break;
+ case nsTblChgWidthHeightType::WH_COL_LEFT:
+ GoPrevCell();
+ break;
+ case nsTblChgWidthHeightType::WH_COL_RIGHT:
+ GoNextCell();
+ break;
+ default:
+ break;
+ }
+ }
+
+ SwTwips nLogDiff = nDiff;
+ nLogDiff *= pTab->GetFmt()->GetFrmSize().GetWidth();
+ nLogDiff /= nPrtWidth;
+
+ /** The cells are destroyed in here */
+ BOOL bRet = GetDoc()->SetColRowWidthHeight(
+ *(SwTableBox*)((SwCellFrm*)pFrm)->GetTabBox(),
+ eType, nDiff, nLogDiff );
+
+ delete pLastCols, pLastCols = 0;
+ EndAllActionAndCall();
+
+ if( bRet && (eType & (nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL)) == nsTblChgWidthHeightType::WH_FLAG_INSDEL )
+ {
+ switch(eType & ~(nsTblChgWidthHeightType::WH_FLAG_BIGGER | nsTblChgWidthHeightType::WH_FLAG_INSDEL))
+ {
+ case nsTblChgWidthHeightType::WH_CELL_LEFT:
+ case nsTblChgWidthHeightType::WH_COL_LEFT:
+ GoPrevCell();
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_RIGHT:
+ case nsTblChgWidthHeightType::WH_COL_RIGHT:
+ GoNextCell();
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_TOP:
+ case nsTblChgWidthHeightType::WH_ROW_TOP:
+ lcl_GoTableRow( this, true );
+ break;
+
+ case nsTblChgWidthHeightType::WH_CELL_BOTTOM:
+ case nsTblChgWidthHeightType::WH_ROW_BOTTOM:
+ lcl_GoTableRow( this, false );
+ break;
+ }
+ }
+
+ return bRet;
+}
+
+BOOL lcl_IsFormulaSelBoxes( const SwTable& rTbl, const SwTblBoxFormula& rFml,
+ SwCellFrms& rCells )
+{
+ SwTblBoxFormula aTmp( rFml );
+ SwSelBoxes aBoxes;
+ for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes ); nSelBoxes; )
+ {
+ SwTableBox* pBox = aBoxes[ --nSelBoxes ];
+ USHORT i;
+ for( i = 0; i < rCells.Count(); ++i )
+ if( rCells[ i ]->GetTabBox() == pBox )
+ break; // gefunden
+
+ if( i == rCells.Count() )
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+ // erfrage die Formel fuer die Autosumme
+BOOL SwFEShell::GetAutoSum( String& rFml ) const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ SwTabFrm *pTab = pFrm ? pFrm->ImplFindTabFrm() : 0;
+ if( !pTab )
+ return FALSE;
+
+ rFml = String::CreateFromAscii( sCalc_Sum );
+
+ SwCellFrms aCells;
+ if( ::GetAutoSumSel( *this, aCells ))
+ {
+ USHORT nW = 0, nInsPos = 0;
+ for( USHORT n = aCells.Count(); n; )
+ {
+ SwCellFrm* pCFrm = aCells[ --n ];
+ USHORT nBoxW = pCFrm->GetTabBox()->IsFormulaOrValueBox();
+ if( !nBoxW )
+ break;
+
+ if( !nW )
+ {
+ if( USHRT_MAX == nBoxW )
+ continue; // leere am Anfang ueberspringen
+
+ rFml += '(';
+ nInsPos = rFml.Len();
+
+ // Formeln nur wenn diese Boxen enthalten
+ if( RES_BOXATR_FORMULA == nBoxW &&
+ !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells))
+ {
+ nW = RES_BOXATR_VALUE;
+ // alle vorhierigen Leere wieder mit aufnehmen !
+ for( USHORT i = aCells.Count(); n+1 < i; )
+ {
+ String sTmp( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+ sTmp += aCells[ --i ]->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ }
+ else
+ nW = nBoxW;
+ }
+ else if( RES_BOXATR_VALUE == nW )
+ {
+ // values werden gesucht, Value/Formel/Text gefunden -> aufn.
+ if( RES_BOXATR_FORMULA == nBoxW &&
+ ::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+ break;
+ else if( USHRT_MAX != nBoxW )
+ rFml.Insert( cListDelim, nInsPos );
+ else
+ break;
+ }
+ else if( RES_BOXATR_FORMULA == nW )
+ {
+ // bei Formeln nur weiter suchen, wenn die akt. Formel auf
+ // alle Boxen verweist, die sich in der Selektion befinden
+ if( RES_BOXATR_FORMULA == nBoxW )
+ {
+ if( !::lcl_IsFormulaSelBoxes( *pTab->GetTable(), pCFrm->
+ GetTabBox()->GetFrmFmt()->GetTblBoxFormula(), aCells ))
+ {
+ // dann noch mal von vorne und nur die Values!
+
+ nW = RES_BOXATR_VALUE;
+ rFml.Erase( nInsPos );
+ // alle vorhierigen Leere wieder mit aufnehmen !
+ for( USHORT i = aCells.Count(); n+1 < i; )
+ {
+ String sTmp( String::CreateFromAscii(
+ RTL_CONSTASCII_STRINGPARAM( "|<" )) );
+ sTmp += aCells[ --i ]->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ }
+ else
+ rFml.Insert( cListDelim, nInsPos );
+ }
+ else if( USHRT_MAX == nBoxW )
+ break;
+ else
+ continue; // diese Boxen ignorieren
+ }
+ else
+ // alles andere beendet die Schleife
+// evt. Texte noch zu lassen??
+ break;
+
+ String sTmp( '<' );
+ sTmp += pCFrm->GetTabBox()->GetName();
+ sTmp += '>';
+ rFml.Insert( sTmp, nInsPos );
+ }
+ if( nW )
+ {
+ rFml += ')';
+
+/*
+ // TabellenSelektion erzeugen??
+ SwTblBoxFormula aTmp( rFml );
+ SwSelBoxes aBoxes;
+ for( USHORT nSelBoxes = aTmp.GetBoxesOfFormula( rTbl,aBoxes );
+ nSelBoxes; )
+ {
+ }
+*/
+ }
+ }
+
+ return TRUE;
+}
+/* -----------------------------22.08.2002 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsTableRightToLeft() const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ return pFrm->ImplFindTabFrm()->IsRightToLeft();
+}
+
+/* -----------------------------22.08.2002 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsMouseTableRightToLeft(const Point &rPt) const
+{
+ SwFrm *pFrm = (SwFrm *)GetBox( rPt );
+ const SwTabFrm* pTabFrm = pFrm ? pFrm->ImplFindTabFrm() : 0;
+ ASSERT( pTabFrm, "Table not found" );
+ return pTabFrm ? pTabFrm->IsRightToLeft() : FALSE;
+}
+
+/* -----------------------------11.02.2004 12:50------------------------------
+
+ ---------------------------------------------------------------------------*/
+BOOL SwFEShell::IsTableVertical() const
+{
+ SwFrm *pFrm = GetCurrFrm();
+ if( !pFrm || !pFrm->IsInTab() )
+ return FALSE;
+
+ return pFrm->ImplFindTabFrm()->IsVertical();
+}
+
+
+