summaryrefslogtreecommitdiff
path: root/binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx')
-rw-r--r--binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx1571
1 files changed, 1571 insertions, 0 deletions
diff --git a/binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx b/binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx
new file mode 100644
index 000000000000..9dc8c963209c
--- /dev/null
+++ b/binfilter/bf_sw/source/core/frmedt/sw_tblsel.cxx
@@ -0,0 +1,1571 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * 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.
+ *
+ ************************************************************************/
+
+
+#ifdef _MSC_VER
+#pragma hdrstop
+#endif
+
+#define ITEMID_BOXINFO SID_ATTR_BORDER_INNER
+#include <hintids.hxx>
+
+#include <bf_svx/protitem.hxx>
+#include <bf_sch/schdll.hxx>
+#include <bf_sch/memchrt.hxx>
+
+#include <fmtfsize.hxx>
+#include <frmatr.hxx>
+
+#include <horiornt.hxx>
+
+#include <crsrsh.hxx>
+#include <doc.hxx>
+#include <ndole.hxx>
+#include <cntfrm.hxx>
+#include <tabfrm.hxx>
+#include <rowfrm.hxx>
+#include <cellfrm.hxx>
+#include <viscrs.hxx>
+#include <swtblfmt.hxx>
+namespace binfilter {
+
+//siehe auch swtable.cxx
+#define COLFUZZY 20L
+
+// defines, die bestimmen, wie Tabellen Boxen gemergt werden:
+// - 1. alle leeren Zeilen entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+// - 2. alle leeren Zeilen und alle leeren Boxen am Anfang und Ende
+// entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+// - 3. alle leeren Boxen entfernen, alle Boxen werden mit Blank,
+// alle Lines mit ParaBreak getrennt
+
+#undef DEL_ONLY_EMPTY_LINES
+#undef DEL_EMPTY_BOXES_AT_START_AND_END
+#define DEL_ALL_EMPTY_BOXES
+
+
+/*N*/ _SV_IMPL_SORTAR_ALG( SwSelBoxes, SwTableBoxPtr )
+/*N*/ BOOL SwSelBoxes::Seek_Entry( const SwTableBoxPtr rSrch, USHORT* pFndPos ) const
+/*N*/ {
+/*N*/ ULONG nIdx = rSrch->GetSttIdx();
+/*N*/
+/*N*/ register USHORT nO = Count(), nM, nU = 0;
+/*N*/ if( nO > 0 )
+/*N*/ {
+/*N*/ nO--;
+/*N*/ while( nU <= nO )
+/*N*/ {
+/*N*/ nM = nU + ( nO - nU ) / 2;
+/*N*/ if( (*this)[ nM ]->GetSttNd() == rSrch->GetSttNd() )
+/*N*/ {
+/*N*/ if( pFndPos )
+/*N*/ *pFndPos = nM;
+/*N*/ return TRUE;
+/*N*/ }
+/*N*/ else if( (*this)[ nM ]->GetSttIdx() < nIdx )
+/*N*/ nU = nM + 1;
+/*N*/ else if( nM == 0 )
+/*N*/ {
+/*N*/ if( pFndPos )
+/*N*/ *pFndPos = nU;
+/*N*/ return FALSE;
+/*N*/ }
+/*N*/ else
+/*N*/ nO = nM - 1;
+/*N*/ }
+/*N*/ }
+/*N*/ if( pFndPos )
+/*N*/ *pFndPos = nU;
+/*N*/ return FALSE;
+/*N*/ }
+
+
+
+
+
+
+/*N*/ SV_IMPL_PTRARR( _FndBoxes, _FndBox* )
+/*N*/ SV_IMPL_PTRARR( _FndLines, _FndLine* )
+
+
+/*N*/ struct _Sort_CellFrm
+/*N*/ {
+/*N*/ const SwCellFrm* pFrm;
+/*N*/
+/*N*/ _Sort_CellFrm( const SwCellFrm& rCFrm )
+/*N*/ : pFrm( &rCFrm ) {}
+/*N*/ };
+
+/*N*/ SV_DECL_VARARR( _Sort_CellFrms, _Sort_CellFrm, 16, 16 )
+/*N*/ SV_IMPL_VARARR( _Sort_CellFrms, _Sort_CellFrm )
+
+/*N*/ SV_IMPL_PTRARR( SwChartBoxes, SwTableBoxPtr );
+/*N*/ SV_IMPL_PTRARR( SwChartLines, SwChartBoxes* );
+
+/*N*/ const SwLayoutFrm *lcl_FindCellFrm( const SwLayoutFrm *pLay )
+/*N*/ {
+/*N*/ while ( pLay && !pLay->IsCellFrm() )
+/*?*/ pLay = pLay->GetUpper();
+/*N*/ return pLay;
+/*N*/ }
+
+/*N*/ const SwLayoutFrm *lcl_FindNextCellFrm( const SwLayoutFrm *pLay )
+/*N*/ {
+/*N*/ //Dafuer sorgen, dass die Zelle auch verlassen wird (Bereiche)
+/*N*/ const SwLayoutFrm *pTmp = pLay;
+/*N*/ do {
+/*N*/ pTmp = pTmp->GetNextLayoutLeaf();
+/*N*/ } while( pLay->IsAnLower( pTmp ) );
+/*N*/
+/*N*/ while( pTmp && !pTmp->IsCellFrm() )
+/*N*/ pTmp = pTmp->GetUpper();
+/*N*/ return pTmp;
+/*N*/ }
+
+/*N*/ void GetTblSel( const SwLayoutFrm* pStart, const SwLayoutFrm* pEnd,
+/*N*/ SwSelBoxes& rBoxes, const SwTblSearchType eSearchType )
+/*N*/ {
+/*N*/ //Muss ein HeadlineRepeat beachtet werden?
+/*N*/ const BOOL bRepeat = pStart->FindTabFrm()->GetTable()->IsHeadlineRepeat();
+/*N*/ int bChkProtected = TBLSEARCH_PROTECT & eSearchType;
+/*N*/
+/*N*/ BOOL bTblIsValid;
+/*N*/ int nLoopMax = 100; //JP 28.06.99: max 100 loops - Bug 67292
+/*N*/ do {
+/*N*/ bTblIsValid = TRUE;
+/*N*/
+/*N*/ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+/*N*/ SwSelUnions aUnions;
+/*N*/ ::binfilter::MakeSelUnions( aUnions, pStart, pEnd, eSearchType );
+/*N*/
+/*N*/ //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+ USHORT i=0;
+/*N*/ for( i = 0; i < aUnions.Count() && bTblIsValid; ++i )
+/*N*/ {
+/*N*/ SwSelUnion *pUnion = aUnions[i];
+/*N*/ const SwTabFrm *pTable = pUnion->GetTable();
+/*N*/ if( !pTable->IsValid() && nLoopMax )
+/*N*/ {
+/*?*/ bTblIsValid = FALSE;
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+/*N*/ //Wenn die Row eine wiederholte Headline ist wird sie nicht
+/*N*/ //beachtet.
+/*N*/ if( bRepeat && pTable->IsFollow() )
+/*?*/ pRow = (const SwLayoutFrm*)pRow->GetNext();
+/*N*/
+/*N*/ while( pRow && bTblIsValid )
+/*N*/ {
+/*N*/ if( !pRow->IsValid() && nLoopMax )
+/*N*/ {
+/*?*/ bTblIsValid = FALSE;
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if ( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+/*N*/ {
+/*N*/ const SwLayoutFrm *pCell = pRow->FirstCell();
+/*N*/
+/*N*/ while( bTblIsValid && pCell && pRow->IsAnLower( pCell ) )
+/*N*/ {
+/*N*/ if( !pCell->IsValid() && nLoopMax )
+/*N*/ {
+/*?*/ bTblIsValid = FALSE;
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+/*N*/ if( ::binfilter::IsFrmInTblSel( pUnion->GetUnion(), pCell ) )
+/*N*/ {
+/*N*/ SwTableBox* pBox = (SwTableBox*)
+/*N*/ ((SwCellFrm*)pCell)->GetTabBox();
+/*N*/ // Zellenschutzt beachten ??
+/*N*/ if( !bChkProtected ||
+/*N*/ !pBox->GetFrmFmt()->GetProtect().IsCntntProtected() )
+/*N*/ rBoxes.Insert( pBox );
+/*N*/ }
+/*N*/ if ( pCell->GetNext() )
+/*N*/ {
+/*N*/ pCell = (const SwLayoutFrm*)pCell->GetNext();
+/*N*/ if ( pCell->Lower()->IsRowFrm() )
+/*?*/ pCell = pCell->FirstCell();
+/*N*/ }
+/*N*/ else
+/*N*/ pCell = ::binfilter::lcl_FindNextCellFrm( pCell );
+/*N*/ }
+/*N*/ }
+/*N*/ pRow = (const SwLayoutFrm*)pRow->GetNext();
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( bTblIsValid )
+/*N*/ break;
+/*N*/
+/*N*/ // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+/*N*/ // und nochmals neu aufsetzen
+/*?*/ SwTabFrm *pTable = aUnions[0]->GetTable();
+/*?*/ for( i = 0; i < aUnions.Count(); ++i )
+/*?*/ {
+/*?*/ if( pTable->IsValid() )
+/*?*/ pTable->InvalidatePos();
+/*?*/ pTable->SetONECalcLowers();
+/*?*/ pTable->Calc();
+/*?*/ pTable->SetCompletePaint();
+/*?*/ if( 0 == (pTable = pTable->GetFollow()) )
+/*?*/ break;
+/*?*/ }
+/*?*/ i = 0;
+/*?*/ rBoxes.Remove( i, rBoxes.Count() );
+/*?*/ --nLoopMax;
+/*?*/
+/*?*/ } while( TRUE );
+/*N*/ ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+/*N*/ }
+
+
+
+/*N*/ BOOL ChkChartSel( const SwNode& rSttNd, const SwNode& rEndNd,
+/*N*/ SwChartLines* pGetCLines )
+/*N*/ {
+/*N*/ const SwTableNode* pTNd = rSttNd.FindTableNode();
+/*N*/ if( !pTNd )
+/*N*/ return FALSE;
+/*N*/
+/*N*/ Point aNullPos;
+/*N*/ SwNodeIndex aIdx( rSttNd );
+/*N*/ const SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+/*N*/ if( !pCNd )
+/*N*/ pCNd = aIdx.GetNodes().GoNextSection( &aIdx, FALSE, FALSE );
+/*N*/
+/*N*/ // #109394# if table is invisible, return
+/*N*/ // (layout needed for forming table selection further down, so we can't
+/*N*/ // continue with invisible tables)
+/*N*/ if( pCNd->GetFrm() == NULL )
+/*N*/ return FALSE;
+/*N*/
+/*N*/ const SwLayoutFrm *pStart = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+/*N*/ ASSERT( pStart, "ohne Frame geht gar nichts" );
+/*N*/
+/*N*/ aIdx = rEndNd;
+/*N*/ pCNd = aIdx.GetNode().GetCntntNode();
+/*N*/ if( !pCNd )
+/*N*/ pCNd = aIdx.GetNodes().GoNextSection( &aIdx, FALSE, FALSE );
+/*N*/
+/*N*/ const SwLayoutFrm *pEnd = pCNd ? pCNd->GetFrm( &aNullPos )->GetUpper() : 0;
+/*N*/ ASSERT( pEnd, "ohne Frame geht gar nichts" );
+/*N*/
+/*N*/
+/*N*/ //Muss ein HeadlineRepeat beachtet werden?
+/*N*/ const BOOL bRepeat = pTNd->GetTable().IsHeadlineRepeat();
+/*N*/
+/*N*/ BOOL bTblIsValid, bValidChartSel;
+/*N*/ int nLoopMax = 100; //JP 28.06.99: max 100 loops - Bug 67292
+/*N*/ do {
+/*N*/ bTblIsValid = TRUE;
+/*N*/ bValidChartSel = TRUE;
+/*N*/
+/*N*/ USHORT nRowCells = USHRT_MAX;
+/*N*/
+/*N*/ //Zuerst lassen wir uns die Tabellen und die Rechtecke heraussuchen.
+/*N*/ SwSelUnions aUnions;
+/*N*/ ::binfilter::MakeSelUnions( aUnions, pStart, pEnd, TBLSEARCH_NO_UNION_CORRECT );
+/*N*/
+/*N*/ //Jetzt zu jedem Eintrag die Boxen herausfischen und uebertragen.
+ USHORT i=0;
+/*N*/ for( i = 0; i < aUnions.Count() && bTblIsValid &&
+/*N*/ bValidChartSel; ++i )
+/*N*/ {
+/*N*/ SwSelUnion *pUnion = aUnions[i];
+/*N*/ const SwTabFrm *pTable = pUnion->GetTable();
+/*N*/
+/*N*/ SWRECTFN( pTable )
+/*N*/ #ifdef BIDI
+/*N*/ sal_Bool bRTL = pTable->IsRightToLeft();
+/*N*/ #endif
+/*N*/
+/*N*/ if( !pTable->IsValid() && nLoopMax )
+/*N*/ {
+/*N*/ bTblIsValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/
+/*N*/ _Sort_CellFrms aCellFrms;
+/*N*/
+/*N*/ const SwLayoutFrm *pRow = (const SwLayoutFrm*)pTable->Lower();
+/*N*/ //Wenn die Row eine wiederholte Headline ist wird sie nicht
+/*N*/ //beachtet.
+/*N*/ if( bRepeat && pTable->IsFollow() )
+/*N*/ pRow = (const SwLayoutFrm*)pRow->GetNext();
+/*N*/
+/*N*/ while( pRow && bTblIsValid && bValidChartSel )
+/*N*/ {
+/*N*/ if( !pRow->IsValid() && nLoopMax )
+/*N*/ {
+/*N*/ bTblIsValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if( pRow->Frm().IsOver( pUnion->GetUnion() ) )
+/*N*/ {
+/*N*/ const SwLayoutFrm *pCell = pRow->FirstCell();
+/*N*/
+/*N*/ while( bValidChartSel && bTblIsValid && pCell &&
+/*N*/ pRow->IsAnLower( pCell ) )
+/*N*/ {
+/*N*/ if( !pCell->IsValid() && nLoopMax )
+/*N*/ {
+/*N*/ bTblIsValid = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/
+/*N*/ ASSERT( pCell->IsCellFrm(), "Frame ohne Celle" );
+/*N*/ const SwRect& rUnion = pUnion->GetUnion(),
+/*N*/ & rFrmRect = pCell->Frm();
+/*N*/
+/*N*/ const long nUnionRight = rUnion.Right();
+/*N*/ const long nUnionBottom = rUnion.Bottom();
+/*N*/ const long nFrmRight = rFrmRect.Right();
+/*N*/ const long nFrmBottom = rFrmRect.Bottom();
+/*N*/
+/*N*/ // liegt das FrmRect ausserhalb der Union, kann es
+/*N*/ // ignoriert werden.
+/*N*/
+/*N*/ const long nXFuzzy = bVert ? 0 : 20;
+/*N*/ const long nYFuzzy = bVert ? 20 : 0;
+/*N*/
+/*N*/ if( !( rUnion.Top() + nYFuzzy > nFrmBottom ||
+/*N*/ nUnionBottom < rFrmRect.Top() + nYFuzzy ||
+/*N*/ rUnion.Left() + nXFuzzy > nFrmRight ||
+/*N*/ nUnionRight < rFrmRect.Left() + nXFuzzy ))
+/*N*/ {
+/*N*/ // ok, rUnion is _not_ completely outside of rFrmRect
+/*N*/
+/*N*/ // wenn es aber nicht komplett in der Union liegt,
+/*N*/ // dann ist es fuers Chart eine ungueltige
+/*N*/ // Selektion.
+/*N*/ if( rUnion.Left() <= rFrmRect.Left() + nXFuzzy &&
+/*N*/ rFrmRect.Left() <= nUnionRight &&
+/*N*/ rUnion.Left() <= nFrmRight &&
+/*N*/ nFrmRight <= nUnionRight + nXFuzzy &&
+/*N*/ rUnion.Top() <= rFrmRect.Top() + nYFuzzy &&
+/*N*/ rFrmRect.Top() <= nUnionBottom &&
+/*N*/ rUnion.Top() <= nFrmBottom &&
+/*N*/ nFrmBottom <= nUnionBottom+ nYFuzzy )
+/*N*/
+/*N*/ aCellFrms.Insert(
+/*N*/ _Sort_CellFrm( *(SwCellFrm*)pCell ),
+/*N*/ aCellFrms.Count() );
+/*N*/ else
+/*N*/ {
+/*N*/ bValidChartSel = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ if ( pCell->GetNext() )
+/*N*/ {
+/*N*/ pCell = (const SwLayoutFrm*)pCell->GetNext();
+/*N*/ if ( pCell->Lower()->IsRowFrm() )
+/*N*/ pCell = pCell->FirstCell();
+/*N*/ }
+/*N*/ else
+/*N*/ pCell = ::binfilter::lcl_FindNextCellFrm( pCell );
+/*N*/ }
+/*N*/ }
+/*N*/ pRow = (const SwLayoutFrm*)pRow->GetNext();
+/*N*/ }
+/*N*/
+/*N*/ if( !bValidChartSel )
+/*N*/ break;
+/*N*/
+/*N*/ // alle Zellen der (Teil-)Tabelle zusammen. Dann teste mal ob
+/*N*/ // all huebsch nebeneinander liegen.
+/*N*/ USHORT n, nEnd, nCellCnt = 0;
+/*N*/ long nYPos = LONG_MAX, nXPos, nHeight;
+/*N*/
+/*N*/ for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+/*N*/ {
+/*N*/ const _Sort_CellFrm& rCF = aCellFrms[ n ];
+/*N*/ if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
+/*N*/ {
+/*N*/ // neue Zeile
+/*N*/ if( n )
+/*N*/ {
+/*N*/ if( USHRT_MAX == nRowCells ) // 1. Zeilenwechsel
+/*N*/ nRowCells = nCellCnt;
+/*N*/ else if( nRowCells != nCellCnt )
+/*N*/ {
+/*N*/ bValidChartSel = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ nCellCnt = 1;
+/*N*/ nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
+/*N*/ nHeight = (rCF.pFrm->Frm().*fnRect->fnGetHeight)();
+/*N*/
+/*N*/ #ifdef BIDI
+/*N*/ nXPos = bRTL ?
+/*N*/ (rCF.pFrm->Frm().*fnRect->fnGetLeft)() :
+/*N*/ (rCF.pFrm->Frm().*fnRect->fnGetRight)();
+/*N*/ }
+/*N*/ else if( nXPos == ( bRTL ?
+/*N*/ (rCF.pFrm->Frm().*fnRect->fnGetRight)() :
+/*N*/ (rCF.pFrm->Frm().*fnRect->fnGetLeft)() ) &&
+/*N*/ nHeight == (rCF.pFrm->Frm().*fnRect->fnGetHeight)() )
+/*N*/ {
+/*N*/ nXPos += ( bRTL ? (-1) : 1 ) *
+/*N*/ (rCF.pFrm->Frm().*fnRect->fnGetWidth)();
+/*N*/ ++nCellCnt;
+/*N*/ }
+/*N*/
+/*N*/ #else
+/*N*/ nXPos = (rCF.pFrm->Frm().*fnRect->fnGetRight)();
+/*N*/ }
+/*N*/ else if( nXPos == (rCF.pFrm->Frm().*fnRect->fnGetLeft)() &&
+/*N*/ nHeight == (rCF.pFrm->Frm().*fnRect->fnGetHeight)() )
+/*N*/ {
+/*N*/ nXPos += (rCF.pFrm->Frm().*fnRect->fnGetWidth)();
+/*N*/ ++nCellCnt;
+/*N*/ }
+/*N*/ #endif
+/*N*/ else
+/*N*/ {
+/*N*/ bValidChartSel = FALSE;
+/*N*/ break;
+/*N*/ }
+/*N*/ }
+/*N*/ if( bValidChartSel )
+/*N*/ {
+/*N*/ if( USHRT_MAX == nRowCells )
+/*N*/ nRowCells = nCellCnt;
+/*N*/ else if( nRowCells != nCellCnt )
+/*N*/ bValidChartSel = FALSE;
+/*N*/ }
+/*N*/
+/*N*/ if( bValidChartSel && pGetCLines )
+/*N*/ {
+/*N*/ nYPos = LONG_MAX;
+/*N*/ SwChartBoxes* pBoxes;
+/*N*/ for( n = 0, nEnd = aCellFrms.Count(); n < nEnd; ++n )
+/*N*/ {
+/*N*/ const _Sort_CellFrm& rCF = aCellFrms[ n ];
+/*N*/ if( (rCF.pFrm->Frm().*fnRect->fnGetTop)() != nYPos )
+/*N*/ {
+/*N*/ pBoxes = new SwChartBoxes( 255 < nRowCells
+/*N*/ ? 255 : (BYTE)nRowCells);
+/*N*/ pGetCLines->C40_INSERT( SwChartBoxes, pBoxes, pGetCLines->Count() );
+/*N*/ nYPos = (rCF.pFrm->Frm().*fnRect->fnGetTop)();
+/*N*/ }
+/*N*/ SwTableBoxPtr pBox = (SwTableBox*)rCF.pFrm->GetTabBox();
+/*N*/ pBoxes->Insert( pBox, pBoxes->Count() );
+/*N*/ }
+/*N*/ }
+/*N*/ }
+/*N*/
+/*N*/ if( bTblIsValid )
+/*N*/ break;
+/*N*/
+/*N*/ // ansonsten das Layout der Tabelle kurz "kalkulieren" lassen
+/*N*/ // und nochmals neu aufsetzen
+/*N*/ SwTabFrm *pTable = aUnions[0]->GetTable();
+/*N*/ for( i = 0; i < aUnions.Count(); ++i )
+/*N*/ {
+/*N*/ if( pTable->IsValid() )
+/*N*/ pTable->InvalidatePos();
+/*N*/ pTable->SetONECalcLowers();
+/*N*/ pTable->Calc();
+/*N*/ pTable->SetCompletePaint();
+/*N*/ if( 0 == (pTable = pTable->GetFollow()) )
+/*N*/ break;
+/*N*/ }
+/*N*/ --nLoopMax;
+/*N*/ if( pGetCLines )
+/*N*/ pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+/*N*/ } while( TRUE );
+/*N*/
+/*N*/ ASSERT( nLoopMax, "das Layout der Tabelle wurde nicht valide!" );
+/*N*/
+/*N*/ if( !bValidChartSel && pGetCLines )
+/*N*/ pGetCLines->DeleteAndDestroy( 0, pGetCLines->Count() );
+/*N*/
+/*N*/ return bValidChartSel;
+/*N*/ }
+
+
+/*N*/ BOOL IsFrmInTblSel( const SwRect& rUnion, const SwFrm* pCell )
+/*N*/ {
+/*N*/ #ifdef VERTICAL_LAYOUT
+/*N*/ if( pCell->IsVertical() )
+/*?*/ return ( rUnion.Right() >= pCell->Frm().Right() &&
+/*?*/ rUnion.Left() <= pCell->Frm().Left() &&
+/*?*/ (( rUnion.Top() <= pCell->Frm().Top()+20 &&
+/*?*/ rUnion.Bottom() > pCell->Frm().Top() ) ||
+/*?*/ ( rUnion.Top() >= pCell->Frm().Top() &&
+/*?*/ rUnion.Bottom() < pCell->Frm().Bottom() )) ? TRUE : FALSE );
+/*N*/ #endif
+/*N*/ return (
+/*N*/ rUnion.Top() <= pCell->Frm().Top() &&
+/*N*/ rUnion.Bottom() >= pCell->Frm().Bottom() &&
+/*N*/
+/*N*/ (( rUnion.Left() <= pCell->Frm().Left()+20 &&
+/*N*/ rUnion.Right() > pCell->Frm().Left() ) ||
+/*N*/
+/*N*/ ( rUnion.Left() >= pCell->Frm().Left() &&
+/*N*/ rUnion.Right() < pCell->Frm().Right() )) ? TRUE : FALSE );
+/*N*/ }
+
+
+BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara );
+
+BOOL lcl_CheckRow( const _FndLine*& rpFndLine, void* pPara )
+{
+ ((_FndLine*)rpFndLine)->GetBoxes().ForEach( &::binfilter::lcl_CheckCol, pPara );
+ return *(BOOL*)pPara;
+}
+
+BOOL lcl_CheckCol( const _FndBox*& rpFndBox, void* pPara )
+{
+ if( !rpFndBox->GetBox()->GetSttNd() )
+ {
+ if( rpFndBox->GetLines().Count() !=
+ rpFndBox->GetBox()->GetTabLines().Count() )
+ *((BOOL*)pPara) = FALSE;
+ else
+ ((_FndBox*)rpFndBox)->GetLines().ForEach( &lcl_CheckRow, pPara );
+ }
+ // Box geschuetzt ??
+ else if( rpFndBox->GetBox()->GetFrmFmt()->GetProtect().IsCntntProtected() )
+ *((BOOL*)pPara) = FALSE;
+ return *(BOOL*)pPara;
+}
+
+USHORT CheckMergeSel( const SwSelBoxes& rBoxes )
+{
+ USHORT eRet = TBLMERGE_NOSELECTION;
+ if( rBoxes.Count() )
+ {
+ eRet = TBLMERGE_OK;
+
+ _FndBox aFndBox( 0, 0 );
+ _FndPara aPara( rBoxes, &aFndBox );
+ const SwTableNode* pTblNd = aPara.rBoxes[0]->GetSttNd()->FindTableNode();
+ ((SwTable&)pTblNd->GetTable()).GetTabLines().ForEach(
+ &_FndLineCopyCol, &aPara );
+ if( aFndBox.GetLines().Count() )
+ {
+ BOOL bMergeSelOk = TRUE;
+ _FndBox* pFndBox = &aFndBox;
+ _FndLine* pFndLine = 0;
+ while( pFndBox && 1 == pFndBox->GetLines().Count() )
+ {
+ pFndLine = pFndBox->GetLines()[0];
+ if( 1 == pFndLine->GetBoxes().Count() )
+ pFndBox = pFndLine->GetBoxes()[0];
+ else
+ pFndBox = 0;
+ }
+ if( pFndBox )
+ pFndBox->GetLines().ForEach( &::binfilter::lcl_CheckRow, &bMergeSelOk );
+ else if( pFndLine )
+ pFndLine->GetBoxes().ForEach( &::binfilter::lcl_CheckCol, &bMergeSelOk );
+ if( !bMergeSelOk )
+ eRet = TBLMERGE_TOOCOMPLEX;
+ }
+ else
+ eRet = TBLMERGE_NOSELECTION;
+ }
+ return eRet;
+}
+
+//Ermittelt die von einer Tabellenselektion betroffenen Tabellen und die
+//Union-Rechteckte der Selektionen - auch fuer aufgespaltene Tabellen.
+/*N*/ SV_IMPL_PTRARR( SwSelUnions, SwSelUnion* );
+
+/*M*/ SwTwips lcl_CalcWish( const SwLayoutFrm *pCell, long nWish,
+/*M*/ const long nAct )
+/*M*/ {
+/*M*/ const SwLayoutFrm *pTmp = pCell;
+/*M*/ if ( !nWish )
+/*M*/ nWish = 1;
+/*M*/
+/*M*/ #ifdef BIDI
+/*M*/ const sal_Bool bRTL = pCell->IsRightToLeft();
+/*M*/ SwTwips nRet = bRTL ?
+/*M*/ nAct - pCell->Frm().Width() :
+/*M*/ 0;
+/*M*/ #else
+/*M*/ SwTwips nRet = 0;
+/*M*/ #endif
+/*M*/
+/*M*/
+/*M*/ while ( pTmp )
+/*M*/ {
+/*M*/ while ( pTmp->GetPrev() )
+/*M*/ {
+/*M*/ pTmp = (SwLayoutFrm*)pTmp->GetPrev();
+/*M*/ long nTmp = pTmp->GetFmt()->GetFrmSize().GetWidth();
+/*M*/ #ifdef BIDI
+/*M*/ nRet += ( bRTL ? ( -1 ) : 1 ) * nTmp * nAct / nWish;
+/*M*/ #else
+/*M*/ nRet += nTmp * nAct / nWish;
+/*M*/ #endif
+/*M*/ }
+/*M*/ pTmp = pTmp->GetUpper()->GetUpper();
+/*M*/ if ( pTmp && !pTmp->IsCellFrm() )
+/*M*/ pTmp = 0;
+/*M*/ }
+/*M*/ return nRet;
+/*M*/ }
+
+/* MA: 20. Sep. 93 wird nicht mehr gebraucht.
+static const SwLayoutFrm *GetPrevCell( const SwLayoutFrm *pCell )
+{
+ const SwLayoutFrm *pLay = pCell->GetPrevLayoutLeaf();
+ if ( pLay && pLay->IsLayoutFrm() && !pLay->IsTab() )
+ {
+ //GetPrevLayoutLeaf() liefert ggf. auch die Umgebung einer Tab zurueck
+ //(naehmlich genau dann, wenn die Zelle noch Vorgaenger hat).
+ const SwFrm *pFrm = pLay->Lower();
+ while ( pFrm->GetNext() )
+ pFrm = pFrm->GetNext();
+ pLay = pFrm->IsTabFrm() ? (SwLayoutFrm*)pFrm : 0;
+ }
+ if ( pLay && pLay->IsTabFrm() )
+ {
+ //GetPrevLayoutLeaf() liefert ggf. auch Tabellen zurueck die letzte
+ //Zelle dieser Tabelle ist das das gesuchte Blatt.
+ pLay = ((SwTabFrm*)pLay)->FindLastCntnt()->GetUpper();
+ while ( !pLay->IsCellFrm() )
+ pLay = pLay->GetUpper();
+ }
+ return pLay;
+}
+*/
+
+/*N*/ void lcl_FindStartEndRow( const SwLayoutFrm *&rpStart,
+/*N*/ const SwLayoutFrm *&rpEnd,
+/*N*/ const int bChkProtected )
+/*N*/ {
+/*N*/ //Start an den Anfang seiner Zeile setzen.
+/*N*/ //End an das Ende seiner Zeile setzen.
+/*N*/ rpStart = (SwLayoutFrm*)rpStart->GetUpper()->Lower();
+/*N*/ while ( rpEnd->GetNext() )
+/*?*/ rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+/*N*/
+/*N*/ SvPtrarr aSttArr( 8, 8 ), aEndArr( 8, 8 );
+/*N*/ const SwLayoutFrm *pTmp;
+/*N*/ for( pTmp = rpStart; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+/*N*/ pTmp = pTmp->GetUpper() )
+/*N*/ {
+/*N*/ void* p = (void*)pTmp;
+/*N*/ aSttArr.Insert( p, 0 );
+/*N*/ }
+/*N*/ for( pTmp = rpEnd; (FRM_CELL|FRM_ROW) & pTmp->GetType();
+/*N*/ pTmp = pTmp->GetUpper() )
+/*N*/ {
+/*N*/ void* p = (void*)pTmp;
+/*N*/ aEndArr.Insert( p, 0 );
+/*N*/ }
+/*N*/
+/*N*/ for( USHORT n = 0; n < aEndArr.Count() && n < aSttArr.Count(); ++n )
+/*N*/ if( aSttArr[ n ] != aEndArr[ n ] )
+/*N*/ {
+/*?*/ // first unequal line or box - all odds are
+/*?*/ if( n & 1 ) // 1, 3, 5, ... are boxes
+/*?*/ {
+/*?*/ rpStart = (SwLayoutFrm*)aSttArr[ n ];
+/*?*/ rpEnd = (SwLayoutFrm*)aEndArr[ n ];
+/*?*/ }
+/*?*/ else // 0, 2, 4, ... are lines
+/*?*/ {
+/*?*/ // check if start & end line are the first & last Line of the
+/*?*/ // box. If not return these cells.
+/*?*/ // Else the hole line with all Boxes has to be deleted.
+/*?*/ rpStart = (SwLayoutFrm*)aSttArr[ n+1 ];
+/*?*/ rpEnd = (SwLayoutFrm*)aEndArr[ n+1 ];
+/*?*/ if( n )
+/*?*/ {
+/*?*/ const SwCellFrm* pCellFrm = (SwCellFrm*)aSttArr[ n-1 ];
+/*?*/ const SwTableLines& rLns = pCellFrm->
+/*?*/ GetTabBox()->GetTabLines();
+/*?*/ if( rLns[ 0 ] == ((SwRowFrm*)aSttArr[ n ])->GetTabLine() &&
+/*?*/ rLns[ rLns.Count() - 1 ] ==
+/*?*/ ((SwRowFrm*)aEndArr[ n ])->GetTabLine() )
+/*?*/ {
+/*?*/ rpStart = rpEnd = pCellFrm;
+/*?*/ while ( rpStart->GetPrev() )
+/*?*/ rpStart = (SwLayoutFrm*)rpStart->GetPrev();
+/*?*/ while ( rpEnd->GetNext() )
+/*?*/ rpEnd = (SwLayoutFrm*)rpEnd->GetNext();
+/*?*/ }
+/*?*/ }
+/*?*/ }
+/*?*/ break;
+/*N*/ }
+/*N*/
+/*N*/ if( !bChkProtected ) // geschuetzte Zellen beachten ?
+/*N*/ return;
+/*N*/
+/*N*/
+/*?*/ //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+/*?*/ while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+/*?*/ rpStart = (SwLayoutFrm*)rpStart->GetNext();
+/*?*/ while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+/*?*/ rpEnd = (SwLayoutFrm*)rpEnd->GetPrev();
+/*N*/ }
+
+
+/*M*/ void lcl_FindStartEndCol( const SwLayoutFrm *&rpStart,
+/*M*/ const SwLayoutFrm *&rpEnd,
+/*M*/ const int bChkProtected )
+/*M*/ {
+/*M*/ //Start und End senkrecht bis an den Rand der Tabelle denken; es muss
+/*M*/ //die Gesamttabelle betrachtet werden, also inklusive Masters und
+/*M*/ //Follows.
+/*M*/ //Fuer den Start brauchen wir den Mutter-TabellenFrm.
+/*M*/ if( !rpStart )
+/*M*/ return;
+/*M*/ const SwTabFrm *pOrg = rpStart->FindTabFrm();
+/*M*/ const SwTabFrm *pTab = pOrg;
+/*M*/
+/*M*/ SWRECTFN( pTab )
+/*M*/
+/*M*/ #ifdef BIDI
+/*M*/ sal_Bool bRTL = pTab->IsRightToLeft();
+/*M*/ #endif
+/*M*/
+/*M*/ const long nWish = pOrg->GetFmt()->GetFrmSize().GetWidth();
+/*M*/ while ( pTab->IsFollow() )
+/*M*/ {
+/*M*/ const SwFrm *pTmp = pTab->FindPrev();
+/*M*/ ASSERT( pTmp->IsTabFrm(), "Vorgaenger vom Follow nicht der Master." );
+/*M*/ pTab = (const SwTabFrm*)pTmp;
+/*M*/ }
+/*M*/
+/*M*/ SwTwips nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+/*M*/ const SwTwips nSX = ::binfilter::lcl_CalcWish( rpStart, nWish, nPrtWidth ) +
+/*M*/ (pTab->*fnRect->fnGetPrtLeft)();
+/*M*/
+/*M*/ const SwTwips nSX2= nSX + (rpStart->GetFmt()->GetFrmSize().GetWidth() *
+/*M*/ nPrtWidth / nWish);
+/*M*/
+/*M*/ const SwLayoutFrm *pTmp = pTab->FirstCell();
+/*M*/
+/*M*/ #ifdef BIDI
+/*M*/ while ( pTmp &&
+/*M*/ (!pTmp->IsCellFrm() ||
+/*M*/ ( ( ! bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
+/*M*/ (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 ) ||
+/*M*/ bRTL && (pTmp->Frm().*fnRect->fnGetLeft)() > nSX &&
+/*M*/ (pTmp->Frm().*fnRect->fnGetRight)()> nSX2 ) ) )
+/*M*/ #else
+/*M*/ while ( pTmp &&
+/*M*/ (!pTmp->IsCellFrm() ||
+/*M*/ ( (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
+/*M*/ (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 ) ) )
+/*M*/ #endif
+/*M*/ pTmp = pTmp->GetNextLayoutLeaf();
+/*M*/
+/*M*/ if ( pTmp )
+/*M*/ rpStart = pTmp;
+/*M*/
+/*M*/ pTab = pOrg;
+/*M*/ while ( pTab->GetFollow() )
+/*M*/ pTab = pTab->GetFollow();
+/*M*/
+/*M*/ nPrtWidth = (pTab->Prt().*fnRect->fnGetWidth)();
+/*M*/ const SwTwips nEX = ::binfilter::lcl_CalcWish( rpEnd, nWish, nPrtWidth ) +
+/*M*/ (pTab->*fnRect->fnGetPrtLeft)();
+/*M*/ rpEnd = pTab->FindLastCntnt()->GetUpper();
+/*M*/ while( !rpEnd->IsCellFrm() )
+/*M*/ rpEnd = rpEnd->GetUpper();
+/*M*/
+/*M*/ #ifdef BIDI
+/*M*/ while ( ( bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() < nEX ) ||
+/*M*/ ( ! bRTL && (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX ) )
+/*M*/ #else
+/*M*/ while ( (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX ) )
+/*M*/ #endif
+/*M*/ {
+/*M*/ const SwLayoutFrm* pTmp = rpEnd->GetPrevLayoutLeaf();
+/*M*/ if( !pTmp || !pTab->IsAnLower( pTmp ) )
+/*M*/ break;
+/*M*/ rpEnd = pTmp;
+/*M*/ }
+/*M*/
+/*M*/ if( !bChkProtected ) // geschuetzte Zellen beachten ?
+/*M*/ return;
+/*M*/
+/*M*/ //Anfang und Ende duerfen nicht auf geschuetzten Zellen liegen.
+/*M*/ //Also muss ggf. nocheinmal rueckwaerts gesucht werden.
+/*M*/ while ( rpStart->GetFmt()->GetProtect().IsCntntProtected() )
+/*M*/ {
+/*M*/ const SwLayoutFrm *pTmp = rpStart;
+/*M*/ pTmp = pTmp->GetNextLayoutLeaf();
+/*M*/ while ( pTmp && (pTmp->Frm().*fnRect->fnGetLeft)() > nEX )//erstmal die Zeile ueberspr.
+/*M*/ pTmp = pTmp->GetNextLayoutLeaf();
+/*M*/ while ( pTmp && (pTmp->Frm().*fnRect->fnGetLeft)() < nSX &&
+/*M*/ (pTmp->Frm().*fnRect->fnGetRight)()< nSX2 )
+/*M*/ pTmp = pTmp->GetNextLayoutLeaf();
+/*M*/ const SwTabFrm *pTab = rpStart->FindTabFrm();
+/*M*/ if ( !pTab->IsAnLower( pTmp ) )
+/*M*/ {
+/*M*/ pTab = pTab->GetFollow();
+/*M*/ rpStart = pTab->FirstCell();
+/*M*/ while ( (rpStart->Frm().*fnRect->fnGetLeft)() < nSX &&
+/*M*/ (rpStart->Frm().*fnRect->fnGetRight)()< nSX2 )
+/*M*/ rpStart = rpStart->GetNextLayoutLeaf();
+/*M*/ }
+/*M*/ else
+/*M*/ rpStart = pTmp;
+/*M*/ }
+/*M*/ while ( rpEnd->GetFmt()->GetProtect().IsCntntProtected() )
+/*M*/ {
+/*M*/ const SwLayoutFrm *pTmp = rpEnd;
+/*M*/ pTmp = pTmp->GetPrevLayoutLeaf();
+/*M*/ while ( pTmp && (pTmp->Frm().*fnRect->fnGetLeft)() < nEX )//erstmal die Zeile ueberspr.
+/*M*/ pTmp = pTmp->GetPrevLayoutLeaf();
+/*M*/ while ( pTmp && (pTmp->Frm().*fnRect->fnGetLeft)() > nEX )
+/*M*/ pTmp = pTmp->GetPrevLayoutLeaf();
+/*M*/ const SwTabFrm *pTab = rpEnd->FindTabFrm();
+/*M*/ if ( !pTmp || !pTab->IsAnLower( pTmp ) )
+/*M*/ {
+/*M*/ pTab = (const SwTabFrm*)pTab->FindPrev();
+/*M*/ ASSERT( pTab->IsTabFrm(), "Vorgaenger vom Follow nicht der Master.");
+/*M*/ rpEnd = pTab->FindLastCntnt()->GetUpper();
+/*M*/ while( !rpEnd->IsCellFrm() )
+/*M*/ rpEnd = rpEnd->GetUpper();
+/*M*/ while ( (rpEnd->Frm().*fnRect->fnGetLeft)() > nEX )
+/*M*/ rpEnd = rpEnd->GetPrevLayoutLeaf();
+/*M*/ }
+/*M*/ else
+/*M*/ rpEnd = pTmp;
+/*M*/ }
+/*M*/ }
+
+
+/*M*/ void MakeSelUnions( SwSelUnions& rUnions, const SwLayoutFrm *pStart,
+/*M*/ const SwLayoutFrm *pEnd, const SwTblSearchType eSearchType )
+/*M*/ {
+/*M*/ while ( !pStart->IsCellFrm() )
+/*M*/ pStart = pStart->GetUpper();
+/*M*/ while ( !pEnd->IsCellFrm() )
+/*M*/ pEnd = pEnd->GetUpper();
+/*M*/
+/*M*/ const SwTabFrm *pTable = pStart->FindTabFrm();
+/*M*/ const SwTabFrm *pEndTable = pEnd->FindTabFrm();
+/*M*/ if( !pTable || !pEndTable )
+/*M*/ return;
+/*M*/ BOOL bExchange = FALSE;
+/*M*/
+/*M*/ if ( pTable != pEndTable )
+/*M*/ {
+/*M*/ if ( !pTable->IsAnFollow( pEndTable ) )
+/*M*/ {
+/*M*/ ASSERT( pEndTable->IsAnFollow( pTable ), "Tabkette verknotet." );
+/*M*/ bExchange = TRUE;
+/*M*/ }
+/*M*/ }
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ else
+/*M*/ {
+/*M*/ SWRECTFN( pStart )
+/*M*/ long nSttTop = (pStart->Frm().*fnRect->fnGetTop)();
+/*M*/ long nEndTop = (pEnd->Frm().*fnRect->fnGetTop)();
+/*M*/ if( nSttTop == nEndTop )
+/*M*/ {
+/*M*/ if( (pStart->Frm().*fnRect->fnGetLeft)() >
+/*M*/ (pEnd->Frm().*fnRect->fnGetLeft)() )
+/*M*/ bExchange = TRUE;
+/*M*/ }
+/*M*/ else if( bVert == ( nSttTop < nEndTop ) )
+/*M*/ bExchange = TRUE;
+/*M*/ }
+/*M*/ #else
+/*M*/ else if ( pStart->Frm().Top() > pEnd->Frm().Top() ||
+/*M*/ (pStart->Frm().Top() == pEnd->Frm().Top() &&
+/*M*/ pStart->Frm().Left() > pEnd->Frm().Left()) )
+/*M*/ bExchange = TRUE;
+/*M*/ #endif
+/*M*/ if ( bExchange )
+/*M*/ {
+/*M*/ const SwLayoutFrm *pTmp = pStart;
+/*M*/ pStart = pEnd;
+/*M*/ pEnd = pTmp;
+/*M*/ //pTable und pEndTable nicht umsortieren, werden unten neu gesetzt.
+/*M*/ //MA: 28. Dec. 93 Bug: 5190
+/*M*/ }
+/*M*/
+/*M*/ //Start und End sind jetzt huebsch sortiert, jetzt muessen sie falls
+/*M*/ //erwuenscht noch versetzt werden.
+/*M*/ if( TBLSEARCH_ROW == ((~TBLSEARCH_PROTECT ) & eSearchType ) )
+/*M*/ ::binfilter::lcl_FindStartEndRow( pStart, pEnd, TBLSEARCH_PROTECT & eSearchType );
+/*M*/ else if( TBLSEARCH_COL == ((~TBLSEARCH_PROTECT ) & eSearchType ) )
+/*M*/ ::binfilter::lcl_FindStartEndCol( pStart, pEnd, TBLSEARCH_PROTECT & eSearchType );
+/*M*/
+/*M*/ //neu besorgen, da sie jetzt verschoben sind. MA: 28. Dec. 93 Bug 5190
+/*M*/ pTable = pStart->FindTabFrm();
+/*M*/ pEndTable = pEnd->FindTabFrm();
+/*M*/
+/*M*/ const FASTBOOL bRepeat = pTable->GetTable()->IsHeadlineRepeat();
+/*M*/
+/*M*/ const long nStSz = pStart->GetFmt()->GetFrmSize().GetWidth();
+/*M*/ const long nEdSz = pEnd->GetFmt()->GetFrmSize().GetWidth();
+/*M*/ const long nWish = Max( 1L, pTable->GetFmt()->GetFrmSize().GetWidth() );
+/*M*/ while ( pTable )
+/*M*/ {
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ SWRECTFN( pTable )
+/*M*/ const long nOfst = (pTable->*fnRect->fnGetPrtLeft)();
+/*M*/ const long nPrtWidth = (pTable->Prt().*fnRect->fnGetWidth)();
+/*M*/ long nSt1 = ::binfilter::lcl_CalcWish( pStart, nWish, nPrtWidth ) + nOfst;
+/*M*/ long nEd1 = ::binfilter::lcl_CalcWish( pEnd, nWish, nPrtWidth ) + nOfst;
+/*M*/
+/*M*/ if ( nSt1 <= nEd1 )
+/*M*/ nEd1 += (long)((nEdSz * nPrtWidth) / nWish) - 1;
+/*M*/ else
+/*M*/ nSt1 += (long)((nStSz * nPrtWidth) / nWish) - 1;
+/*M*/
+/*M*/ long nSt2;
+/*M*/ long nEd2;
+/*M*/ if( pTable->IsAnLower( pStart ) )
+/*M*/ nSt2 = (pStart->Frm().*fnRect->fnGetTop)();
+/*M*/ else
+/*M*/ nSt2 = (pTable->Frm().*fnRect->fnGetTop)();
+/*M*/ if( pTable->IsAnLower( pEnd ) )
+/*M*/ nEd2 = (pEnd->Frm().*fnRect->fnGetBottom)();
+/*M*/ else
+/*M*/ nEd2 = (pTable->Frm().*fnRect->fnGetBottom)();
+/*M*/ Point aSt, aEd;
+/*M*/ if( nSt1 > nEd1 )
+/*M*/ {
+/*M*/ long nTmp = nSt1;
+/*M*/ nSt1 = nEd1;
+/*M*/ nEd1 = nTmp;
+/*M*/ }
+/*M*/ if( nSt2 > nEd2 )
+/*M*/ {
+/*M*/ long nTmp = nSt2;
+/*M*/ nSt2 = nEd2;
+/*M*/ nEd2 = nTmp;
+/*M*/ }
+/*M*/ if( bVert )
+/*M*/ {
+/*M*/ aSt = Point( nSt2, nSt1 );
+/*M*/ aEd = Point( nEd2, nEd1 );
+/*M*/ }
+/*M*/ else
+/*M*/ {
+/*M*/ aSt = Point( nSt1, nSt2 );
+/*M*/ aEd = Point( nEd1, nEd2 );
+/*M*/ }
+/*M*/ #else
+/*M*/ const long nOfst = pTable->Frm().Left() + pTable->Prt().Left();
+/*M*/ long nSt = ::binfilter::lcl_CalcWish( pStart, nWish, pTable->Prt().Width() ) + nOfst;
+/*M*/ long nEd = ::binfilter::lcl_CalcWish( pEnd, nWish, pTable->Prt().Width() ) + nOfst;
+/*M*/
+/*M*/ if ( nSt <= nEd )
+/*M*/ nEd += (long)((nEdSz * pTable->Prt().Width()) / nWish) - 1;
+/*M*/ else
+/*M*/ nSt += (long)((nStSz * pTable->Prt().Width()) / nWish) - 1;
+/*M*/
+/*M*/ Point aSt( nSt, pStart->Frm().Top() ),
+/*M*/ aEd( nEd, pEnd->Frm().Bottom() );
+/*M*/
+/*M*/ if ( !pTable->IsAnLower( pStart ) )
+/*M*/ aSt.Y() = pTable->Frm().Top();
+/*M*/ if ( !pTable->IsAnLower( pEnd ) )
+/*M*/ aEd.Y() = pTable->Frm().Bottom();
+/*M*/ #endif
+/*M*/
+/*M*/ SwRect aUnion( aSt, aEd );
+/*M*/ aUnion.Justify();
+/*M*/
+/*M*/ // fuers
+/*M*/ if( !(TBLSEARCH_NO_UNION_CORRECT & eSearchType ))
+/*M*/ {
+/*M*/ //Leider ist die Union jetzt mit Rundungsfehlern behaftet und dadurch
+/*M*/ //wuerden beim Split/Merge fehlertraechtige Umstaende entstehen.
+/*M*/ //Um dies zu vermeiden werden jetzt fuer die Table die erste und
+/*M*/ //letzte Zelle innerhalb der Union ermittelt und aus genau deren
+/*M*/ //Werten wird die Union neu gebildet.
+/*M*/ const SwLayoutFrm *pRow = (SwLayoutFrm*)pTable->Lower();
+/*M*/ if ( bRepeat && pRow && pTable->IsFollow() )
+/*M*/ pRow = (SwLayoutFrm*)pRow->GetNext();
+/*M*/ while ( pRow && !pRow->Frm().IsOver( aUnion ) )
+/*M*/ pRow = (SwLayoutFrm*)pRow->GetNext();
+/*M*/ const SwLayoutFrm *pFirst = pRow ? pRow->FirstCell() : 0;
+/*M*/ while ( pFirst && !::binfilter::IsFrmInTblSel( aUnion, pFirst ) )
+/*M*/ {
+/*M*/ if ( pFirst->GetNext() )
+/*M*/ {
+/*M*/ pFirst = (const SwLayoutFrm*)pFirst->GetNext();
+/*M*/ if ( pFirst->Lower()->IsRowFrm() )
+/*M*/ pFirst = pFirst->FirstCell();
+/*M*/ }
+/*M*/ else
+/*M*/ pFirst = ::binfilter::lcl_FindNextCellFrm( pFirst );
+/*M*/ }
+/*M*/ const SwLayoutFrm *pLast = ::binfilter::lcl_FindCellFrm( pTable->FindLastCntnt()->GetUpper());
+/*M*/ while ( pLast && !::binfilter::IsFrmInTblSel( aUnion, pLast ) )
+/*M*/ pLast = ::binfilter::lcl_FindCellFrm( pLast->GetPrevLayoutLeaf() );
+/*M*/
+/*M*/ if ( pFirst && pLast ) //Robust
+/*M*/ #ifdef VERTICAL_LAYOUT
+/*M*/ {
+/*M*/ aUnion = pFirst->Frm();
+/*M*/ aUnion.Union( pLast->Frm() );
+/*M*/ }
+/*M*/ #else
+/*M*/ aUnion = SwRect( pFirst->Frm().Pos(),
+/*M*/ Point( pLast->Frm().Right(),
+/*M*/ pLast->Frm().Bottom() ) );
+/*M*/ #endif
+/*M*/ else
+/*M*/ aUnion.Width( 0 );
+/*M*/ }
+/*M*/
+/*M*/ if( (aUnion.*fnRect->fnGetWidth)() )
+/*M*/ {
+/*M*/ SwSelUnion *pTmp = new SwSelUnion( aUnion, (SwTabFrm*)pTable );
+/*M*/ rUnions.C40_INSERT( SwSelUnion, pTmp, rUnions.Count() );
+/*M*/ }
+/*M*/
+/*M*/ pTable = pTable->GetFollow();
+/*M*/ if ( pTable != pEndTable && pEndTable->IsAnFollow( pTable ) )
+/*M*/ pTable = 0;
+/*M*/ }
+/*M*/ }
+
+
+
+// -------------------------------------------------------------------
+// Diese Klassen kopieren die aktuelle Tabellen-Selektion (rBoxes)
+// unter Beibehaltung der Tabellen-Struktur in eine eigene Struktur
+// neu: SS zum gezielten Loeschen/Retaurieren des Layouts.
+
+ void lcl_InsertRow( SwTableLine &rLine, SwLayoutFrm *pUpper, SwFrm *pSibling )
+ {
+ SwRowFrm *pRow = new SwRowFrm( rLine );
+ if ( pUpper->IsTabFrm() && ((SwTabFrm*)pUpper)->IsFollow() )
+ {
+ ((SwTabFrm*)pUpper)->FindMaster()->InvalidatePos(); //kann die Zeile vielleicht aufnehmen
+ if ( ((SwTabFrm*)pUpper)->GetTable()->IsHeadlineRepeat() &&
+ pSibling && !pSibling->GetPrev() )
+ {
+ //Nicht vor die Headline-Wiederholung pasten.
+ pSibling = pSibling->GetNext();
+ }
+ }
+ pRow->Paste( pUpper, pSibling );
+ pRow->RegistFlys();
+ }
+
+
+ BOOL _FndBoxCopyCol( const SwTableBox*& rpBox, void* pPara )
+ {
+ _FndPara* pFndPara = (_FndPara*)pPara;
+ _FndBox* pFndBox = new _FndBox( (SwTableBox*)rpBox, pFndPara->pFndLine );
+ if( rpBox->GetTabLines().Count() )
+ {
+ _FndPara aPara( *pFndPara, pFndBox );
+ pFndBox->GetBox()->GetTabLines().ForEach( &_FndLineCopyCol, &aPara );
+ if( !pFndBox->GetLines().Count() )
+ {
+ delete pFndBox;
+ return TRUE;
+ }
+ }
+ else
+ {
+ SwTableBoxPtr pSrch = (SwTableBoxPtr)rpBox;
+ USHORT nFndPos;
+ if( !pFndPara->rBoxes.Seek_Entry( pSrch, &nFndPos ))
+ {
+ delete pFndBox;
+ return TRUE;
+ }
+ }
+ pFndPara->pFndLine->GetBoxes().C40_INSERT( _FndBox, pFndBox,
+ pFndPara->pFndLine->GetBoxes().Count() );
+ return TRUE;
+ }
+
+/*N*/ BOOL _FndLineCopyCol( const SwTableLine*& rpLine, void* pPara )
+/*N*/ {
+ _FndPara* pFndPara = (_FndPara*)pPara;
+ _FndLine* pFndLine = new _FndLine( (SwTableLine*)rpLine, pFndPara->pFndBox );
+ _FndPara aPara( *pFndPara, pFndLine );
+ pFndLine->GetLine()->GetTabBoxes().ForEach( &_FndBoxCopyCol, &aPara );
+ if( pFndLine->GetBoxes().Count() )
+ {
+ pFndPara->pFndBox->GetLines().C40_INSERT( _FndLine, pFndLine,
+ pFndPara->pFndBox->GetLines().Count() );
+ }
+ else
+ delete pFndLine;
+/*N*/ return TRUE;
+/*N*/ }
+
+void _FndBox::SetTableLines( const SwSelBoxes &rBoxes, const SwTable &rTable )
+{
+ //Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+ //setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+ //sind, so bleiben die Pointer eben einfach 0.
+ //Gesucht werden zunachst die Positionen der ersten/letzten betroffenen
+ //Line im Array der SwTable. Damit die 0 fuer 'keine Line' verwand werden
+ //kann werden die Positionen um 1 nach oben versetzt!
+
+ USHORT nStPos = USHRT_MAX;
+ USHORT nEndPos= 0;
+
+ for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+ {
+ SwTableLine *pLine = rBoxes[i]->GetUpper();
+ while ( pLine->GetUpper() )
+ pLine = pLine->GetUpper()->GetUpper();
+ const USHORT nPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLine ) + 1;
+
+ ASSERT( nPos != USHRT_MAX, "TableLine not found." );
+
+ if( nStPos > nPos )
+ nStPos = nPos;
+
+ if( nEndPos < nPos )
+ nEndPos = nPos;
+ }
+ if ( nStPos > 1 )
+ pLineBefore = rTable.GetTabLines()[nStPos - 2];
+ if ( nEndPos < rTable.GetTabLines().Count() )
+ pLineBehind = rTable.GetTabLines()[nEndPos];
+}
+
+void _FndBox::SetTableLines( const SwTable &rTable )
+{
+ // Pointer auf die Lines vor und hinter den zu verarbeitenden Bereich
+ // setzen. Wenn die erste/letzte Zeile in den Bereich eingeschlossen
+ // sind, so bleiben die Pointer eben einfach 0.
+ // Die Positionen der ersten/letzten betroffenen Line im Array der
+ // SwTable steht in der FndBox. Damit die 0 fuer 'keine Line' verwand
+ // werdenkann werden die Positionen um 1 nach oben versetzt!
+
+ if( !GetLines().Count() )
+ return;
+
+ SwTableLine* pTmpLine = GetLines()[0]->GetLine();
+ USHORT nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+ ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+ if( nPos )
+ pLineBefore = rTable.GetTabLines()[ nPos - 1 ];
+
+ pTmpLine = GetLines()[GetLines().Count()-1]->GetLine();
+ nPos = rTable.GetTabLines().C40_GETPOS( SwTableLine, pTmpLine );
+ ASSERT( USHRT_MAX != nPos, "Line steht nicht in der Tabelle" );
+ if( ++nPos < rTable.GetTabLines().Count() )
+ pLineBehind = rTable.GetTabLines()[nPos];
+}
+
+inline void UnsetFollow( SwFlowFrm *pTab )
+{
+ pTab->bIsFollow = FALSE;
+}
+
+void _FndBox::DelFrms( SwTable &rTable )
+{
+ //Alle Lines zwischen pLineBefore und pLineBehind muessen aus dem
+ //Layout ausgeschnitten und geloescht werden.
+ //Entstehen dabei leere Follows so muessen diese vernichtet werden.
+ //Wird ein Master vernichtet, so muss der Follow Master werden.
+ //Ein TabFrm muss immer uebrigbleiben.
+
+ USHORT nStPos = 0;
+ USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+ if ( pLineBefore )
+ {
+ nStPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBefore );
+ ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ ++nStPos;
+ }
+ if ( pLineBehind )
+ {
+ nEndPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBehind );
+ ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ --nEndPos;
+ }
+ for ( USHORT i = nStPos; i <= nEndPos; ++i)
+ {
+ SwFrmFmt *pFmt = rTable.GetTabLines()[i]->GetFrmFmt();
+ SwClientIter aIter( *pFmt );
+ SwClient* pLast = aIter.GoStart();
+ if( pLast )
+ {
+ do {
+ SwFrm *pFrm = PTR_CAST( SwFrm, pLast );
+ if ( pFrm &&
+ ((SwRowFrm*)pFrm)->GetTabLine() == rTable.GetTabLines()[i] )
+ {
+ BOOL bDel = TRUE;
+ SwTabFrm *pUp = !pFrm->GetPrev() && !pFrm->GetNext() ?
+ (SwTabFrm*)pFrm->GetUpper() : 0;
+ if ( !pUp )
+ {
+ if ( ((SwTabFrm*)pFrm->GetUpper())->GetTable()->IsHeadlineRepeat() &&
+ ((SwTabFrm*)pFrm->GetUpper())->IsFollow() )
+ {
+ if ( !pFrm->GetNext() && pFrm->GetPrev() &&
+ !pFrm->GetPrev()->GetPrev() )
+ {
+ pUp = (SwTabFrm*)pFrm->GetUpper();
+ }
+ }
+ }
+ if ( pUp )
+ {
+ SwTabFrm *pFollow = pUp->GetFollow();
+ SwTabFrm *pPrev = pUp->IsFollow() ? pUp : 0;
+ if ( pPrev )
+ {
+ SwFrm *pTmp = pPrev->FindPrev();
+ ASSERT( pTmp->IsTabFrm(),
+ "Vorgaenger vom Follow kein Master.");
+ pPrev = (SwTabFrm*)pTmp;
+ }
+ if ( pPrev )
+ pPrev->SetFollow( pFollow );
+ else if ( pFollow )
+ ::binfilter::UnsetFollow( pFollow );
+
+ //Ein TabellenFrm muss immer stehenbleiben!
+ if ( pPrev || pFollow )
+ {
+ pUp->Cut();
+ delete pUp;
+ bDel = FALSE;//Die Row wird mit in den Abgrund
+ //gerissen.
+ }
+ }
+ if ( bDel )
+ {
+ pFrm->Cut();
+ delete pFrm;
+ }
+ }
+ } while( 0 != ( pLast = aIter++ ));
+ }
+ }
+}
+
+BOOL lcl_IsLineOfTblFrm( const SwTabFrm& rTable, const SwFrm& rChk )
+{
+ const SwTabFrm* pTblFrm = rChk.FindTabFrm();
+ while( pTblFrm->IsFollow() )
+ pTblFrm = pTblFrm->FindMaster();
+ return &rTable == pTblFrm;
+}
+
+ void _FndBox::MakeFrms( SwTable &rTable )
+ {
+ //Alle Lines zwischen pLineBefore und pLineBehind muessen im Layout
+ //wieder neu erzeugt werden.
+ //Und Zwar fuer alle Auspraegungen der Tabelle (mehrere z.B. im Kopf/Fuss).
+
+ USHORT nStPos = 0;
+ USHORT nEndPos= rTable.GetTabLines().Count() - 1;
+ if ( pLineBefore )
+ {
+ nStPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBefore );
+ ASSERT( nStPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ ++nStPos;
+
+ }
+ if ( pLineBehind )
+ {
+ nEndPos = rTable.GetTabLines().GetPos(
+ (const SwTableLine*&)pLineBehind );
+ ASSERT( nEndPos != USHRT_MAX, "Fuchs Du hast die Line gestohlen!" );
+ --nEndPos;
+ }
+ //Jetzt die grosse Einfuegeoperation fuer alle Tabllen.
+ SwClientIter aTabIter( *rTable.GetFrmFmt() );
+ for ( SwTabFrm *pTable = (SwTabFrm*)aTabIter.First( TYPE(SwFrm) ); pTable;
+ pTable = (SwTabFrm*)aTabIter.Next() )
+ {
+ if ( !pTable->IsFollow() )
+ {
+ SwFrm *pSibling = 0;
+ SwFrm *pUpper = 0;
+ int i;
+ for ( i = rTable.GetTabLines().Count()-1;
+ i >= 0 && !pSibling; --i )
+ {
+ SwTableLine *pLine = pLineBehind ? pLineBehind :
+ rTable.GetTabLines()[i];
+ SwClientIter aIter( *pLine->GetFrmFmt() );
+ for ( pSibling = (SwFrm*)aIter.First( TYPE(SwFrm) );
+ pSibling && (
+ ((SwRowFrm*)pSibling)->GetTabLine() != pLine ||
+ !lcl_IsLineOfTblFrm( *pTable, *pSibling ) );
+ pSibling = (SwFrm*)aIter.Next() )
+ /* do nothing */;
+ }
+ if ( pSibling )
+ {
+ pUpper = pSibling->GetUpper();
+ if ( !pLineBehind )
+ pSibling = 0;
+ }
+ else
+ // ???? oder das der Letzte Follow der Tabelle ????
+ pUpper = pTable;
+
+ for ( i = nStPos; (USHORT)i <= nEndPos; ++i )
+ lcl_InsertRow( *rTable.GetTabLines()[i],
+ (SwLayoutFrm*)pUpper, pSibling );
+ if ( pUpper->IsTabFrm() )
+ ((SwTabFrm*)pUpper)->SetCalcLowers();
+ }
+ else if ( nStPos == 0 && rTable.IsHeadlineRepeat() )
+ {
+ //Headline in den Follow einsetzen
+ SwRowFrm *pRow = new SwRowFrm( *rTable.GetTabLines()[0] );
+ pRow->Paste( pTable, pTable->Lower() );
+ pRow->RegistFlys();
+ pTable->SetCalcLowers();
+ }
+ }
+ }
+
+ BOOL _FndBox::AreLinesToRestore( const SwTable &rTable ) const
+ {
+ //Lohnt es sich MakeFrms zu rufen?
+
+ if ( !pLineBefore && !pLineBehind && rTable.GetTabLines().Count() )
+ return TRUE;
+
+ USHORT nBfPos;
+ if(pLineBefore)
+ {
+ const SwTableLine* rLBefore = (const SwTableLine*)pLineBefore;
+ nBfPos = rTable.GetTabLines().GetPos( rLBefore );
+ }
+ else
+ nBfPos = USHRT_MAX;
+
+ USHORT nBhPos;
+ if(pLineBehind)
+ {
+ const SwTableLine* rLBehind = (const SwTableLine*)pLineBehind;
+ nBhPos = rTable.GetTabLines().GetPos( rLBehind );
+ }
+ else
+ nBhPos = USHRT_MAX;
+
+ if ( nBfPos == nBhPos ) //Duerfte eigentlich nie vorkommen.
+ {
+ ASSERT( FALSE, "Table, Loeschen auf keinem Bereich !?!" );
+ return FALSE;
+ }
+
+ if ( nBfPos == USHRT_MAX && nBhPos == 0 )
+ {
+ // ups. sollte unsere zu wiederholende Kopfzeile geloescht worden
+ // sein??
+ if( rTable.IsHeadlineRepeat() )
+ {
+ SwClientIter aIter( *rTable.GetFrmFmt() );
+ for( SwTabFrm* pTable = (SwTabFrm*)aIter.First( TYPE( SwFrm ));
+ pTable; pTable = (SwTabFrm*)aIter.Next() )
+ if( pTable->IsFollow() )
+ {
+ //Headline in den Follow einsetzen
+ SwRowFrm *pRow = new SwRowFrm( *rTable.GetTabLines()[0] );
+ pRow->Paste( pTable, pTable->Lower() );
+ pRow->RegistFlys();
+ }
+ }
+ return FALSE;
+ }
+
+ if ( nBhPos == USHRT_MAX && nBfPos == (rTable.GetTabLines().Count() - 1) )
+ return FALSE;
+
+ if ( nBfPos != USHRT_MAX && nBhPos != USHRT_MAX && (nBfPos + 1) == nBhPos )
+ return FALSE;
+
+ return TRUE;
+ }
+
+//Save- und RestoreChartData:
+//Zu der Tabelle werden alle Charts gesucht. Die Namentliche Addressierung der
+//Boxen in der Tabelle (etwa: <A1:C3>) wird ausgelesen. Die Addressen der
+//Boxen werden im Chart festgehalten. Im Restore wird versucht zu den Pointern
+//die Boxen wiederzufinden. Wenn dies gelingt, wird die neue Addressierung
+//wieder in das Chart geschrieben. Wenn sie nicht gefunden werden gibt es
+//einen FallBack auf die erste/letzte Box.
+
+ const SwTableBox *lcl_FindFirstBox( const SwTable &rTable )
+ {
+ const SwTableLines *pLines = &rTable.GetTabLines();
+ const SwTableBox *pBox;
+ do
+ { pBox = (*pLines)[0]->GetTabBoxes()[0];
+ if ( pBox->GetSttNd() )
+ pLines = 0;
+ else
+ pLines = &pBox->GetTabLines();
+
+ } while ( pLines );
+ return pBox;
+ }
+
+ const SwTableBox *lcl_FindLastBox( const SwTable &rTable )
+ {
+ const SwTableLines *pLines = &rTable.GetTabLines();
+ const SwTableBox *pBox;
+ do
+ { const SwTableBoxes &rBoxes = (*pLines)[pLines->Count()-1]->GetTabBoxes();
+ pBox = rBoxes[rBoxes.Count()-1];
+ if ( pBox->GetSttNd() )
+ pLines = 0;
+ else
+ pLines = &pBox->GetTabLines();
+
+ } while ( pLines );
+
+ return pBox;
+ }
+
+
+//GPF bei Tab in letzer Zelle mit MSC4
+
+void _FndBox::SaveChartData( const SwTable &rTable )
+{
+ SwDoc *pDoc = rTable.GetFrmFmt()->GetDoc();
+ SwClientIter aIter( *(SwModify*)pDoc->GetDfltGrfFmtColl() );
+ SwClient *pCli;
+ if ( 0 != (pCli = aIter.First( TYPE(SwCntntNode) )) )
+ do
+ { if ( !((SwCntntNode*)pCli)->GetOLENode() )
+ continue;
+ SwOLENode *pONd = (SwOLENode*)pCli;
+ if ( rTable.GetFrmFmt()->GetName() == pONd->GetChartTblName() )
+ {
+ SwOLEObj& rOObj = pONd->GetOLEObj();
+ SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
+ if ( pData )
+ {
+ String &rStr = pData->SomeData1();
+ xub_StrLen nTmp = rStr.Search( ':' );
+ String aBox( rStr.Copy( 1, nTmp - 1 ) );
+ //const this, weil Borland so dumm ist!
+ const SwTableBox *pSttBox = rTable.GetTblBox( aBox );
+ if ( !pSttBox )
+ pSttBox = rTable.GetTabLines()[0]->GetTabBoxes()[0];
+ aBox = rStr.Copy( nTmp + 1, rStr.Len()-2 - nTmp);
+ const SwTableBox *pEndBox = rTable.GetTblBox( aBox );
+ if ( !pEndBox )
+ {
+ SwTableLine *pLine =
+ rTable.GetTabLines()[rTable.GetTabLines().Count()-1];
+ pEndBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+ }
+ pData->SomeData3() = String::CreateFromInt32(
+ pSttBox != ::binfilter::lcl_FindFirstBox(rTable)
+ ? long(pSttBox)
+ : LONG_MAX );
+ pData->SomeData4() = String::CreateFromInt32(
+ pEndBox != ::binfilter::lcl_FindLastBox(rTable)
+ ? long(pEndBox)
+ : LONG_MAX );
+ }
+ }
+ } while ( 0 != (pCli = aIter.Next()) );
+}
+
+ void _FndBox::RestoreChartData( const SwTable &rTable )
+ {
+ SwDoc *pDoc = rTable.GetFrmFmt()->GetDoc();
+ SwClientIter aIter( *(SwModify*)pDoc->GetDfltGrfFmtColl() );
+ SwClient *pCli;
+ if ( 0 != (pCli = aIter.First( TYPE(SwCntntNode) )) )
+ do
+ { if ( !((SwCntntNode*)pCli)->GetOLENode() )
+ continue;
+ SwOLENode *pONd = (SwOLENode*)pCli;
+ if ( rTable.GetFrmFmt()->GetName() == pONd->GetChartTblName() )
+ {
+ SwOLEObj& rOObj = pONd->GetOLEObj();
+ SchMemChart *pData = SchDLL::GetChartData( rOObj.GetOleRef() );
+ if ( pData )
+ {
+ const SwTableBox *pSttBox = (SwTableBox*)
+ pData->SomeData3().ToInt32();
+ if ( long(pSttBox) == LONG_MAX )
+ pSttBox = ::binfilter::lcl_FindFirstBox( rTable );
+ const SwTableBox *pEndBox = (SwTableBox*)
+ pData->SomeData4().ToInt32();
+ if ( long(pEndBox) == LONG_MAX )
+ pEndBox = ::binfilter::lcl_FindLastBox( rTable );
+ FASTBOOL bSttFound = FALSE, bEndFound = FALSE;
+ const SwTableSortBoxes &rBoxes = rTable.GetTabSortBoxes();
+ for ( USHORT i = 0; i < rBoxes.Count(); ++i )
+ {
+ const SwTableBox *pTmp = rBoxes[i];
+ if ( pTmp == pSttBox )
+ bSttFound = TRUE;
+ if ( pTmp == pEndBox )
+ bEndFound = TRUE;
+ }
+ if ( !bSttFound )
+ pSttBox = rTable.GetTabLines()[0]->GetTabBoxes()[0];
+ if ( !bEndFound )
+ {
+ SwTableLine *pLine =
+ rTable.GetTabLines()[rTable.GetTabLines().Count()-1];
+ pEndBox = pLine->GetTabBoxes()[pLine->GetTabBoxes().Count()-1];
+ }
+ String &rStr = pData->SomeData1();
+ rStr = '<'; rStr += pSttBox->GetName(); rStr += ':';
+ rStr += pEndBox->GetName(); rStr += '>';
+ pData->SomeData3().Erase(); pData->SomeData4().Erase();
+ SchDLL::Update( rOObj.GetOleRef(), pData );
+ }
+ }
+ } while ( 0 != (pCli = aIter.Next()) );
+ }
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */