/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include #include #include //EndAllAction gibts nur an der EditShell #include #include #include #include #include #include #include #include #include #include #include #include #include // setze Crsr in die naechsten/vorherigen Celle BOOL SwCrsrShell::GoNextCell( BOOL bAppendLine ) { BOOL bRet = FALSE; const SwTableNode* pTblNd = 0; if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() )) { SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, bRet = TRUE; // Check if we have to move the cursor to a covered cell before // proceeding: const SwNode* pTableBoxStartNode = pCrsr->GetNode()->FindTableBoxStartNode(); const SwTableBox* pTableBox = 0; if ( pCrsr->GetCrsrRowSpanOffset() ) { pTableBox = pTableBoxStartNode->GetTblBox(); if ( pTableBox->getRowSpan() > 1 ) { if ( !pTblNd ) pTblNd = IsCrsrInTbl(); pTableBox = & pTableBox->FindEndOfRowSpan( pTblNd->GetTable(), (USHORT)(pTableBox->getRowSpan() + pCrsr->GetCrsrRowSpanOffset() ) ); pTableBoxStartNode = pTableBox->GetSttNd(); } } SwNodeIndex aCellStt( *pTableBoxStartNode->EndOfSectionNode(), 1 ); // folgt nach dem EndNode der Cell ein weiterer StartNode, dann // gibt es auch eine naechste Celle if( !aCellStt.GetNode().IsStartNode() ) { if( pCrsr->HasMark() || !bAppendLine ) bRet = FALSE; else { // auf besonderen Wunsch: keine Line mehr vorhanden, dann // mache doch eine neue: if ( !pTableBox ) pTableBox = pTblNd->GetTable().GetTblBox( pCrsr->GetPoint()->nNode.GetNode(). StartOfSectionIndex() ); ASSERT( pTableBox, "Box steht nicht in dieser Tabelle" ); SwSelBoxes aBoxes; //Das Dokument veraendert sich evtl. ohne Action wuerden die Sichten //nichts mitbekommen. ((SwEditShell*)this)->StartAllAction(); bRet = pDoc->InsertRow( pTblNd->GetTable(). SelLineFromBox( pTableBox, aBoxes, FALSE )); ((SwEditShell*)this)->EndAllAction(); } } if( bRet && 0 != ( bRet = pCrsr->GoNextCell() )) UpdateCrsr(); // und den akt. Updaten } return bRet; } BOOL SwCrsrShell::GoPrevCell() { BOOL bRet = FALSE; const SwTableNode* pTblNd; if( IsTableMode() || 0 != ( pTblNd = IsCrsrInTbl() )) { SwCursor* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, bRet = pCrsr->GoPrevCell(); if( bRet ) UpdateCrsr(); // und den akt. Updaten } return bRet; } const SwFrm* lcl_FindMostUpperCellFrm( const SwFrm* pFrm ) { while ( pFrm && ( !pFrm->IsCellFrm() || !pFrm->GetUpper()->GetUpper()->IsTabFrm() || pFrm->GetUpper()->GetUpper()->GetUpper()->IsInTab() ) ) { pFrm = pFrm->GetUpper(); } return pFrm; } BOOL SwCrsrShell::_SelTblRowOrCol( bool bRow, bool bRowSimple ) { // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen SwFrm *pFrm = GetCurrFrm(); if( !pFrm->IsInTab() ) return FALSE; const SwTabFrm* pTabFrm = pFrm->FindTabFrm(); const SwTabFrm* pMasterTabFrm = pTabFrm->IsFollow() ? pTabFrm->FindMaster( true ) : pTabFrm; const SwTable* pTable = pTabFrm->GetTable(); SET_CURR_SHELL( this ); const SwTableBox* pStt = 0; const SwTableBox* pEnd = 0; // lasse ueber das Layout die Boxen suchen SwSelBoxes aBoxes; SwTblSearchType eType = bRow ? nsSwTblSearchType::TBLSEARCH_ROW : nsSwTblSearchType::TBLSEARCH_COL; const bool bCheckProtected = !IsReadOnlyAvailable(); if( bCheckProtected ) eType = (SwTblSearchType)(eType | nsSwTblSearchType::TBLSEARCH_PROTECT); if ( !bRowSimple ) { GetTblSel( *this, aBoxes, eType ); if( !aBoxes.Count() ) return FALSE; pStt = aBoxes[0]; pEnd = aBoxes[aBoxes.Count() - 1]; } // --> FME 2004-07-30 #i32329# Enhanced table selection else if ( pTable->IsNewModel() ) { const SwShellCrsr *pCrsr = _GetCrsr(); SwTable::SearchType eSearchType = bRow ? SwTable::SEARCH_ROW : SwTable::SEARCH_COL; pTable->CreateSelection( *pCrsr, aBoxes, eSearchType, bCheckProtected ); if( !aBoxes.Count() ) return FALSE; pStt = aBoxes[0]; pEnd = aBoxes[aBoxes.Count() - 1]; } else { const SwShellCrsr *pCrsr = _GetCrsr(); const SwFrm* pStartFrm = pFrm; const SwCntntNode *pCNd = pCrsr->GetCntntNode( FALSE ); const SwFrm* pEndFrm = pCNd ? pCNd->GetFrm( &pCrsr->GetMkPos() ) : 0; if ( bRow ) { pStartFrm = lcl_FindMostUpperCellFrm( pStartFrm ); pEndFrm = lcl_FindMostUpperCellFrm( pEndFrm ); } if ( !pStartFrm || !pEndFrm ) return FALSE; const bool bVert = pFrm->ImplFindTabFrm()->IsVertical(); // If we select upwards it is sufficient to set pStt and pEnd // to the first resp. last box of the selection obtained from // GetTblSel. However, selecting downwards requires the frames // located at the corners of the selection. This does not work // for column selections in vertical tables: const bool bSelectUp = ( bVert && !bRow ) || *pCrsr->GetPoint() <= *pCrsr->GetMark(); SwCellFrms aCells; GetTblSel( static_cast(pStartFrm), static_cast(pEndFrm), aBoxes, bSelectUp ? 0 : &aCells, eType ); if( !aBoxes.Count() || ( !bSelectUp && 4 != aCells.Count() ) ) return FALSE; if ( bSelectUp ) { pStt = aBoxes[0]; pEnd = aBoxes[aBoxes.Count() - 1]; } else { pStt = aCells[ bVert ? (bRow ? 0 : 3) : (bRow ? 2 : 1) ]->GetTabBox(); // will become point of table cursor pEnd = aCells[ bVert ? (bRow ? 3 : 0) : (bRow ? 1 : 2) ]->GetTabBox(); // will become mark of table cursor } } // <-- // noch kein Tabellen-Cursor vorhanden, dann erzeuge einen if( !pTblCrsr ) { pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); pCurCrsr->DeleteMark(); pCurCrsr->SwSelPaintRects::Hide(); } pTblCrsr->DeleteMark(); // dann setze mal Anfang und Ende der Spalte pTblCrsr->GetPoint()->nNode = *pEnd->GetSttNd(); pTblCrsr->Move( fnMoveForward, fnGoCntnt ); pTblCrsr->SetMark(); pTblCrsr->GetPoint()->nNode = *pStt->GetSttNd()->EndOfSectionNode(); pTblCrsr->Move( fnMoveBackward, fnGoCntnt ); // set PtPos 'close' to the reference table, otherwise we might get problems with the // repeated headlines check in UpdateCrsr(): if ( !bRow ) pTblCrsr->GetPtPos() = pMasterTabFrm->IsVertical() ? pMasterTabFrm->Frm().TopRight() : pMasterTabFrm->Frm().TopLeft(); UpdateCrsr(); // und den akt. Updaten return TRUE; } BOOL SwCrsrShell::SelTbl() { // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen SwFrm *pFrm = GetCurrFrm(); if( !pFrm->IsInTab() ) return FALSE; const SwTabFrm *pTblFrm = pFrm->ImplFindTabFrm(); const SwTabFrm* pMasterTabFrm = pTblFrm->IsFollow() ? pTblFrm->FindMaster( true ) : pTblFrm; const SwTableNode* pTblNd = pTblFrm->GetTable()->GetTableNode(); SET_CURR_SHELL( this ); if( !pTblCrsr ) { pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); pCurCrsr->DeleteMark(); pCurCrsr->SwSelPaintRects::Hide(); } pTblCrsr->DeleteMark(); pTblCrsr->GetPoint()->nNode = *pTblNd; pTblCrsr->Move( fnMoveForward, fnGoCntnt ); pTblCrsr->SetMark(); // set MkPos 'close' to the master table, otherwise we might get problems with the // repeated headlines check in UpdateCrsr(): pTblCrsr->GetMkPos() = pMasterTabFrm->IsVertical() ? pMasterTabFrm->Frm().TopRight() : pMasterTabFrm->Frm().TopLeft(); pTblCrsr->GetPoint()->nNode = *pTblNd->EndOfSectionNode(); pTblCrsr->Move( fnMoveBackward, fnGoCntnt ); UpdateCrsr(); // und den akt. Updaten return TRUE; } BOOL SwCrsrShell::SelTblBox() { // if we're in a table, create a table cursor, and select the cell // that the current cursor's point resides in // search for start node of our table box. If not found, exit realy const SwStartNode* pStartNode = pCurCrsr->GetPoint()->nNode.GetNode().FindTableBoxStartNode(); #ifdef DBG_UTIL // the old code checks whether we're in a table by asking the // frame. This should yield the same result as searching for the // table box start node, right? SwFrm *pFrm = GetCurrFrm(); DBG_ASSERT( !pFrm->IsInTab() == !(pStartNode != NULL), "Schroedinger's table: We're in a box, and also we aren't." ); #endif if( pStartNode == NULL ) return FALSE; SET_CURR_SHELL( this ); // create a table cursor, if there isn't one already if( !pTblCrsr ) { pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); pCurCrsr->DeleteMark(); pCurCrsr->SwSelPaintRects::Hide(); } // select the complete box with our shiny new pTblCrsr // 1. delete mark, and move point to first content node in box // 2. set mark, and move point to last content node in box // 3. exchange pTblCrsr->DeleteMark(); *(pTblCrsr->GetPoint()) = SwPosition( *pStartNode ); pTblCrsr->Move( fnMoveForward, fnGoNode ); pTblCrsr->SetMark(); *(pTblCrsr->GetPoint()) = SwPosition( *(pStartNode->EndOfSectionNode()) ); pTblCrsr->Move( fnMoveBackward, fnGoNode ); pTblCrsr->Exchange(); // with some luck, UpdateCrsr() will now update everything that // needs updateing UpdateCrsr(); return TRUE; } // return the next non-protected cell inside a table // rIdx - is on a table node // return: // true - Idx points to content in a suitable cell // false - could not find a suitable cell bool lcl_FindNextCell( SwNodeIndex& rIdx, BOOL bInReadOnly ) { // ueberpruefe geschuetzte Zellen SwNodeIndex aTmp( rIdx, 2 ); // TableNode + StartNode // the resulting cell should be in that table: const SwTableNode* pTblNd = rIdx.GetNode().GetTableNode(); if ( !pTblNd ) { ASSERT( false, "lcl_FindNextCell not celled with table start node!" ) return false; } const SwNode* pTableEndNode = pTblNd->EndOfSectionNode(); SwNodes& rNds = aTmp.GetNode().GetNodes(); SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode(); // no content node => go to next content node if( !pCNd ) pCNd = rNds.GoNext( &aTmp ); // robust if ( !pCNd ) return false; SwCntntFrm* pFrm = pCNd->GetFrm(); if ( 0 == pFrm || pCNd->FindTableNode() != pTblNd || (!bInReadOnly && pFrm->IsProtected() ) ) { // we are not located inside a 'valid' cell. We have to continue searching... // skip behind current section. This might be the end of the table cell // or behind a inner section or or or... aTmp.Assign( *pCNd->EndOfSectionNode(), 1 ); // loop to find a suitable cell... for( ;; ) { SwNode* pNd = &aTmp.GetNode(); // we break this loop if we reached the end of the table. // to make this code even more robust, we also break if we are // already behind the table end node: if( pNd == pTableEndNode || /*robust: */ pNd->GetIndex() > pTableEndNode->GetIndex() ) return false; // ok, get the next content node: pCNd = aTmp.GetNode().GetCntntNode(); if( 0 == pCNd ) pCNd = rNds.GoNext( &aTmp ); // robust: if ( !pCNd ) return false; // check if we have found a suitable table cell: pFrm = pCNd->GetFrm(); if ( 0 != pFrm && pCNd->FindTableNode() == pTblNd && (bInReadOnly || !pFrm->IsProtected() ) ) { // finally, we have found a suitable table cell => set index and return rIdx = *pCNd; return true; } // continue behind the current section: aTmp.Assign( *pCNd->EndOfSectionNode(), +1 ); } } rIdx = *pCNd; return true; } // comments see lcl_FindNextCell bool lcl_FindPrevCell( SwNodeIndex& rIdx, BOOL bInReadOnly ) { SwNodeIndex aTmp( rIdx, -2 ); // TableNode + EndNode const SwNode* pTableEndNode = &rIdx.GetNode(); const SwTableNode* pTblNd = pTableEndNode->StartOfSectionNode()->GetTableNode(); if ( !pTblNd ) { ASSERT( false, "lcl_FindPrevCell not celled with table start node!" ) return false; } SwNodes& rNds = aTmp.GetNode().GetNodes(); SwCntntNode* pCNd = aTmp.GetNode().GetCntntNode(); if( !pCNd ) pCNd = rNds.GoPrevious( &aTmp ); if ( !pCNd ) return false; SwCntntFrm* pFrm = pCNd->GetFrm(); if( 0 == pFrm || pCNd->FindTableNode() != pTblNd || (!bInReadOnly && pFrm->IsProtected() )) { // skip before current section aTmp.Assign( *pCNd->StartOfSectionNode(), -1 ); for( ;; ) { SwNode* pNd = &aTmp.GetNode(); if( pNd == pTblNd || pNd->GetIndex() < pTblNd->GetIndex() ) return false; pCNd = aTmp.GetNode().GetCntntNode(); if( 0 == pCNd ) pCNd = rNds.GoPrevious( &aTmp ); if ( !pCNd ) return false; pFrm = pCNd->GetFrm(); if( 0 != pFrm && pCNd->FindTableNode() == pTblNd && (bInReadOnly || !pFrm->IsProtected() ) ) { rIdx = *pCNd; return true; // Ok, nicht geschuetzt } aTmp.Assign( *pCNd->StartOfSectionNode(), - 1 ); } } rIdx = *pCNd; return true; } BOOL GotoPrevTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, BOOL bInReadOnly ) { SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); SwTableNode* pTblNd = aIdx.GetNode().FindTableNode(); if( pTblNd ) { // #i26532#: If we are inside a table, we may not go backward // to the table start node, because we would miss any tables // inside this table. SwTableNode* pInnerTblNd = 0; SwNodeIndex aTmpIdx( aIdx ); while( aTmpIdx.GetIndex() && 0 == ( pInnerTblNd = aTmpIdx.GetNode().StartOfSectionNode()->GetTableNode()) ) aTmpIdx--; if( pInnerTblNd == pTblNd ) aIdx.Assign( *pTblNd, - 1 ); } do { while( aIdx.GetIndex() && 0 == ( pTblNd = aIdx.GetNode().StartOfSectionNode()->GetTableNode()) ) aIdx--; if( pTblNd ) // gibt einen weiteren TableNode ? { if( fnPosTbl == fnMoveForward ) // an Anfang ? { aIdx = *aIdx.GetNode().StartOfSectionNode(); if( !lcl_FindNextCell( aIdx, bInReadOnly )) { // Tabelle ueberspringen aIdx.Assign( *pTblNd, -1 ); continue; } } else { // ueberpruefe geschuetzte Zellen if( !lcl_FindNextCell( aIdx, bInReadOnly )) { // Tabelle ueberspringen aIdx.Assign( *pTblNd, -1 ); continue; } } SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode(); if ( pTxtNode ) { rCurCrsr.GetPoint()->nNode = *pTxtNode; rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ? pTxtNode->Len() : 0 ); } return TRUE; } } while( pTblNd ); return FALSE; } BOOL GotoNextTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, BOOL bInReadOnly ) { SwNodeIndex aIdx( rCurCrsr.GetPoint()->nNode ); SwTableNode* pTblNd = aIdx.GetNode().FindTableNode(); if( pTblNd ) aIdx.Assign( *pTblNd->EndOfSectionNode(), 1 ); ULONG nLastNd = rCurCrsr.GetDoc()->GetNodes().Count() - 1; do { while( aIdx.GetIndex() < nLastNd && 0 == ( pTblNd = aIdx.GetNode().GetTableNode()) ) aIdx++; if( pTblNd ) // gibt einen weiteren TableNode ? { if( fnPosTbl == fnMoveForward ) // an Anfang ? { if( !lcl_FindNextCell( aIdx, bInReadOnly )) { // Tabelle ueberspringen aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 ); continue; } } else { aIdx = *aIdx.GetNode().EndOfSectionNode(); // ueberpruefe geschuetzte Zellen if( !lcl_FindNextCell( aIdx, bInReadOnly )) { // Tabelle ueberspringen aIdx.Assign( *pTblNd->EndOfSectionNode(), + 1 ); continue; } } SwTxtNode* pTxtNode = aIdx.GetNode().GetTxtNode(); if ( pTxtNode ) { rCurCrsr.GetPoint()->nNode = *pTxtNode; rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ? pTxtNode->Len() : 0 ); } return TRUE; } } while( pTblNd ); return FALSE; } BOOL GotoCurrTable( SwPaM& rCurCrsr, SwPosTable fnPosTbl, BOOL bInReadOnly ) { SwTableNode* pTblNd = rCurCrsr.GetPoint()->nNode.GetNode().FindTableNode(); if( !pTblNd ) return FALSE; SwTxtNode* pTxtNode = 0; if( fnPosTbl == fnMoveBackward ) // ans Ende der Tabelle { SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() ); if( !lcl_FindPrevCell( aIdx, bInReadOnly )) return FALSE; pTxtNode = aIdx.GetNode().GetTxtNode(); } else { SwNodeIndex aIdx( *pTblNd ); if( !lcl_FindNextCell( aIdx, bInReadOnly )) return FALSE; pTxtNode = aIdx.GetNode().GetTxtNode(); } if ( pTxtNode ) { rCurCrsr.GetPoint()->nNode = *pTxtNode; rCurCrsr.GetPoint()->nContent.Assign( pTxtNode, fnPosTbl == fnMoveBackward ? pTxtNode->Len() : 0 ); } return TRUE; } BOOL SwCursor::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl ) { BOOL bRet = FALSE; SwTableCursor* pTblCrsr = dynamic_cast(this); if( pTblCrsr || !HasMark() ) // nur wenn kein Mark oder ein TblCrsr { SwCrsrSaveState aSaveState( *this ); bRet = (*fnWhichTbl)( *this, fnPosTbl, IsReadOnlyAvailable() ) && !IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE ); } return bRet; } BOOL SwCrsrShell::MoveTable( SwWhichTable fnWhichTbl, SwPosTable fnPosTbl ) { SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, evt. Link callen SwShellCrsr* pCrsr = pTblCrsr ? pTblCrsr : pCurCrsr; BOOL bCheckPos, bRet; ULONG nPtNd = 0; xub_StrLen nPtCnt = 0; if( !pTblCrsr && pCurCrsr->HasMark() ) // wenn Mark und kein TblCrsr, { // dann auf jedenfall in den Tabellen-Modus schalten pTblCrsr = new SwShellTableCrsr( *this, *pCurCrsr->GetPoint() ); pCurCrsr->DeleteMark(); pCurCrsr->SwSelPaintRects::Hide(); pTblCrsr->SetMark(); pCrsr = pTblCrsr; bCheckPos = FALSE; } else { bCheckPos = TRUE; nPtNd = pCrsr->GetPoint()->nNode.GetIndex(); nPtCnt = pCrsr->GetPoint()->nContent.GetIndex(); } bRet = pCrsr->MoveTable( fnWhichTbl, fnPosTbl ); if( bRet ) { //JP 28.10.97: Bug 45028 - die "oberste" Position setzen fuer // wiederholte Kopfzeilen pCrsr->GetPtPos() = Point(); UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY); if( bCheckPos && pCrsr->GetPoint()->nNode.GetIndex() == nPtNd && pCrsr->GetPoint()->nContent.GetIndex() == nPtCnt ) bRet = FALSE; } return bRet; } BOOL SwCrsrShell::IsTblComplex() const { SwFrm *pFrm = GetCurrFrm( FALSE ); if ( pFrm && pFrm->IsInTab() ) return pFrm->FindTabFrm()->GetTable()->IsTblComplex(); return FALSE; } BOOL SwCrsrShell::IsTblComplexForChart() { BOOL bRet = FALSE; StartAction(); // IsTblComplexForChart() may trigger table formatting // we better do that inside an action const SwTableNode* pTNd = pCurCrsr->GetPoint()->nNode.GetNode().FindTableNode(); if( pTNd ) { // wir stehen in der Tabelle, dann teste mal, ob die Tabelle oder die // Selektion ausgeglichen ist. String sSel; if( pTblCrsr ) sSel = GetBoxNms(); bRet = pTNd->GetTable().IsTblComplexForChart( sSel ); } EndAction(); return bRet; } String SwCrsrShell::GetBoxNms() const { String sNm; const SwPosition* pPos; SwFrm* pFrm; if( IsTableMode() ) { SwCntntNode *pCNd = pTblCrsr->Start()->nNode.GetNode().GetCntntNode(); pFrm = pCNd ? pCNd->GetFrm() : 0; if( !pFrm ) return sNm; do { pFrm = pFrm->GetUpper(); } while ( pFrm && !pFrm->IsCellFrm() ); ASSERT( pFrm, "kein Frame zur Box" ); sNm = ((SwCellFrm*)pFrm)->GetTabBox()->GetName(); sNm += ':'; pPos = pTblCrsr->End(); } else { const SwTableNode* pTblNd = IsCrsrInTbl(); if( !pTblNd ) return sNm; pPos = GetCrsr()->GetPoint(); } SwCntntNode* pCNd = pPos->nNode.GetNode().GetCntntNode(); pFrm = pCNd ? pCNd->GetFrm() : 0; if( pFrm ) { do { pFrm = pFrm->GetUpper(); } while ( pFrm && !pFrm->IsCellFrm() ); if( pFrm ) sNm += ((SwCellFrm*)pFrm)->GetTabBox()->GetName(); } return sNm; } BOOL SwCrsrShell::GotoTable( const String& rName ) { SwCallLink aLk( *this ); // Crsr-Moves ueberwachen, BOOL bRet = !pTblCrsr && pCurCrsr->GotoTable( rName ); if( bRet ) { pCurCrsr->GetPtPos() = Point(); UpdateCrsr( SwCrsrShell::SCROLLWIN | SwCrsrShell::CHKRANGE | SwCrsrShell::READONLY ); // und den akt. Updaten } return bRet; } BOOL SwCrsrShell::CheckTblBoxCntnt( const SwPosition* pPos ) { if( !pBoxIdx || !pBoxPtr || IsSelTblCells() || !IsAutoUpdateCells() ) return FALSE; // ueberpruefe, ob der Box Inhalt mit dem angegebenen Format der Box // ueber einstimmt. Wenn nicht, setze neu SwTableBox* pChkBox = 0; SwStartNode* pSttNd = 0; if( !pPos ) { // gesicherte Position heraus holen. if( pBoxIdx && pBoxPtr && 0 != ( pSttNd = pBoxIdx->GetNode().GetStartNode() ) && SwTableBoxStartNode == pSttNd->GetStartNodeType() && pBoxPtr == pSttNd->FindTableNode()->GetTable(). GetTblBox( pBoxIdx->GetIndex() ) ) pChkBox = pBoxPtr; } else if( 0 != ( pSttNd = pPos->nNode.GetNode(). FindSttNodeByType( SwTableBoxStartNode )) ) { pChkBox = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() ); } // Box mehr als 1 Absatz? if( pChkBox && pSttNd->GetIndex() + 2 != pSttNd->EndOfSectionIndex() ) pChkBox = 0; // jetzt sollten wir mal die Pointer zerstoeren, bevor eine erneute // Actionklammerung kommt. if( !pPos && !pChkBox ) ClearTblBoxCntnt(); // liegt der Cursor nicht mehr in dem Bereich ? if( pChkBox && !pPos && ( pCurCrsr->HasMark() || pCurCrsr->GetNext() != pCurCrsr || pSttNd->GetIndex() + 1 == pCurCrsr->GetPoint()->nNode.GetIndex() )) pChkBox = 0; //JP 12.01.99: hat sich der Inhalt der Box ueberhaupt veraendert? // Ist wichtig, wenn z.B. Undo nicht den richtigen Inhalt wieder // herstellen konnte. if( pChkBox ) { const SwTxtNode* pNd = GetDoc()->GetNodes()[ pSttNd->GetIndex() + 1 ]->GetTxtNode(); if( !pNd || ( pNd->GetTxt() == ViewShell::GetShellRes()->aCalc_Error && SFX_ITEM_SET == pChkBox->GetFrmFmt()-> GetItemState( RES_BOXATR_FORMULA )) ) pChkBox = 0; } if( pChkBox ) { // jetzt sollten wir mal die Pointer zerstoeren, bevor ein weiterer // aufruf kommt. ClearTblBoxCntnt(); StartAction(); GetDoc()->ChkBoxNumFmt( *pChkBox, TRUE ); EndAction(); } return 0 != pChkBox; } void SwCrsrShell::SaveTblBoxCntnt( const SwPosition* pPos ) { if( IsSelTblCells() || !IsAutoUpdateCells() ) return ; if( !pPos ) pPos = pCurCrsr->GetPoint(); SwStartNode* pSttNd = pPos->nNode.GetNode().FindSttNodeByType( SwTableBoxStartNode ); BOOL bCheckBox = FALSE; if( pSttNd && pBoxIdx ) { if( pSttNd == &pBoxIdx->GetNode() ) pSttNd = 0; // die haben wir schon else bCheckBox = TRUE; } else bCheckBox = 0 != pBoxIdx; if( bCheckBox ) { // pBoxIdx Checken SwPosition aPos( *pBoxIdx ); CheckTblBoxCntnt( &aPos ); } if( pSttNd ) { pBoxPtr = pSttNd->FindTableNode()->GetTable().GetTblBox( pSttNd->GetIndex() ); if( pBoxIdx ) *pBoxIdx = *pSttNd; else pBoxIdx = new SwNodeIndex( *pSttNd ); } } void SwCrsrShell::ClearTblBoxCntnt() { delete pBoxIdx, pBoxIdx = 0; pBoxPtr = 0; } BOOL SwCrsrShell::EndAllTblBoxEdit() { BOOL bRet = FALSE; ViewShell *pSh = this; do { if( pSh->IsA( TYPE( SwCrsrShell ) ) ) bRet |= ((SwCrsrShell*)pSh)->CheckTblBoxCntnt( ((SwCrsrShell*)pSh)->pCurCrsr->GetPoint() ); } while( this != (pSh = (ViewShell *)pSh->GetNext()) ); return bRet; }