update dev300-m58
[ooovba.git] / sw / source / core / frmedt / fews.cxx
blob2140311c3cd8d2fd0b923ee5541881919c9bec07
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fews.cxx,v $
10 * $Revision: 1.48 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <tools/list.hxx>
36 //#ifndef _SVDVMARK_HXX //autogen
37 //#include <svx/svdvmark.hxx>
38 //#endif
39 #include <svx/svdobj.hxx>
40 #include <init.hxx>
41 #include <fesh.hxx>
42 #include <pagefrm.hxx>
43 #include <rootfrm.hxx>
44 #include <cntfrm.hxx>
45 #include <doc.hxx>
46 #include <frmtool.hxx>
47 #include <swtable.hxx>
48 #include <viewimp.hxx>
49 #include <dview.hxx>
50 #include <flyfrm.hxx>
51 #include <node.hxx>
52 #include <pam.hxx>
53 #include <sectfrm.hxx>
54 #include <fmtpdsc.hxx>
55 #include <fmtsrnd.hxx>
56 #include <fmtcntnt.hxx>
57 #include <tabfrm.hxx>
58 #include <cellfrm.hxx>
59 #include <flyfrms.hxx>
60 #include <txtfrm.hxx> // SwTxtFrm
61 #include <mdiexp.hxx>
62 #include <edimp.hxx>
63 #include <pagedesc.hxx>
64 #include <fmtanchr.hxx>
65 // OD 29.10.2003 #113049#
66 #include <environmentofanchoredobject.hxx>
67 // OD 12.11.2003 #i22341#
68 #include <ndtxt.hxx>
69 // OD 27.11.2003 #112045#
70 #include <dflyobj.hxx>
71 // OD 2004-03-29 #i26791#
72 #include <dcontact.hxx>
74 using namespace com::sun::star;
76 TYPEINIT1(SwFEShell,SwEditShell)
78 /***********************************************************************
79 #* Class : SwFEShell
80 #* Methode : EndAllActionAndCall()
82 #* Datum : MA 03. May. 93
83 #* Update : MA 31. Oct. 95
84 #***********************************************************************/
86 void SwFEShell::EndAllActionAndCall()
88 ViewShell *pTmp = this;
89 do {
90 if( pTmp->IsA( TYPE(SwCrsrShell) ) )
92 ((SwFEShell*)pTmp)->EndAction();
93 ((SwFEShell*)pTmp)->CallChgLnk();
95 else
96 pTmp->EndAction();
97 } while( this != ( pTmp = (ViewShell*)pTmp->GetNext() ));
101 /***********************************************************************
102 #* Class : SwFEShell
103 #* Methode : GetCntntPos
104 #* Beschreibung: Ermitteln des Cntnt's der dem Punkt am naechsten liegt
105 #* Datum : MA 02. Jun. 92
106 #* Update : MA 02. May. 95
107 #***********************************************************************/
109 Point SwFEShell::GetCntntPos( const Point& rPoint, BOOL bNext ) const
111 SET_CURR_SHELL( (ViewShell*)this );
112 return GetLayout()->GetNextPrevCntntPos( rPoint, bNext );
116 const SwRect& SwFEShell::GetAnyCurRect( CurRectType eType, const Point* pPt,
117 const uno::Reference < embed::XEmbeddedObject >& xObj ) const
119 const SwFrm *pFrm = Imp()->HasDrawView()
120 ? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
121 (ViewShell*)this)
122 : 0;
124 if( !pFrm )
126 if( pPt )
128 SwPosition aPos( *GetCrsr()->GetPoint() );
129 Point aPt( *pPt );
130 GetLayout()->GetCrsrOfst( &aPos, aPt );
131 SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
132 pFrm = pNd->GetFrm( pPt );
134 else
135 pFrm = GetCurrFrm();
138 if( !pFrm )
139 return GetLayout()->Frm();
141 BOOL bFrm = TRUE;
142 switch ( eType )
144 case RECT_PAGE_PRT: bFrm = FALSE; /* no break */
145 case RECT_PAGE : pFrm = pFrm->FindPageFrm();
146 break;
148 case RECT_PAGE_CALC: pFrm->Calc();
149 pFrm = pFrm->FindPageFrm();
150 pFrm->Calc();
151 break;
153 case RECT_FLY_PRT_EMBEDDED: bFrm = FALSE; /* no break */
154 case RECT_FLY_EMBEDDED: pFrm = xObj.is() ? FindFlyFrm( xObj )
155 : pFrm->IsFlyFrm()
156 ? pFrm
157 : pFrm->FindFlyFrm();
158 break;
160 case RECT_OUTTABSECTION_PRT:
161 case RECT_OUTTABSECTION : if( pFrm->IsInTab() )
162 pFrm = pFrm->FindTabFrm();
163 else {
164 ASSERT( FALSE, "Missing Table" );
166 /* KEIN BREAK */
167 case RECT_SECTION_PRT:
168 case RECT_SECTION: if( pFrm->IsInSct() )
169 pFrm = pFrm->FindSctFrm();
170 else {
171 ASSERT( FALSE, "Missing section" );
174 if( RECT_OUTTABSECTION_PRT == eType ||
175 RECT_SECTION_PRT == eType )
176 bFrm = FALSE;
177 break;
179 case RECT_HEADERFOOTER_PRT: bFrm = FALSE; /* no break */
180 case RECT_HEADERFOOTER: if( 0 == (pFrm = pFrm->FindFooterOrHeader()) )
181 return GetLayout()->Frm();
182 break;
184 case RECT_PAGES_AREA: return GetLayout()->GetPagesArea();
186 default: break;
188 return bFrm ? pFrm->Frm() : pFrm->Prt();
192 USHORT SwFEShell::GetPageNumber( const Point &rPoint ) const
194 const SwFrm *pPage = GetLayout()->Lower();
195 while ( pPage && !pPage->Frm().IsInside( rPoint ) )
196 pPage = pPage->GetNext();
197 if ( pPage )
198 return ((const SwPageFrm*)pPage)->GetPhyPageNum();
199 else
200 return 0;
204 BOOL SwFEShell::GetPageNumber( long nYPos, BOOL bAtCrsrPos, USHORT& rPhyNum, USHORT& rVirtNum, String &rDisplay) const
206 const SwFrm *pPage;
208 if ( bAtCrsrPos ) //Seite vom Crsr besorgen
210 pPage = GetCurrFrm( FALSE );
211 if ( pPage )
212 pPage = pPage->FindPageFrm();
214 else if ( nYPos > -1 ) //Seite ueber die Positon ermitteln
216 pPage = GetLayout()->Lower();
217 while( pPage && (pPage->Frm().Bottom() < nYPos ||
218 nYPos < pPage->Frm().Top() ) )
219 pPage = pPage->GetNext();
221 else //Die erste sichtbare Seite
223 pPage = Imp()->GetFirstVisPage();
224 if ( pPage && ((SwPageFrm*)pPage)->IsEmptyPage() )
225 pPage = pPage->GetNext();
228 if( pPage )
230 rPhyNum = ((const SwPageFrm*)pPage)->GetPhyPageNum();
231 rVirtNum = ((const SwPageFrm*)pPage)->GetVirtPageNum();
232 const SvxNumberType& rNum = ((const SwPageFrm*)pPage)->GetPageDesc()->GetNumType();
233 rDisplay = rNum.GetNumStr( rVirtNum );
236 return 0 != pPage;
239 /*************************************************************************
241 |* SwFEShell::IsDirectlyInSection()
243 |* Hack for OS:
245 *************************************************************************/
247 bool SwFEShell::IsDirectlyInSection() const
249 SwFrm* pFrm = GetCurrFrm( FALSE );
250 return pFrm && pFrm->GetUpper() && pFrm->GetUpper()->IsSctFrm();
253 /*************************************************************************
255 |* SwFEShell::GetFrmType()
257 |* Ersterstellung MA 12. Jan. 93
258 |* Letzte Aenderung AMA 25. Nov. 98
260 *************************************************************************/
262 USHORT SwFEShell::GetFrmType( const Point *pPt, BOOL bStopAtFly ) const
264 USHORT nReturn = FRMTYPE_NONE;
265 const SwFrm *pFrm;
266 if ( pPt )
268 SwPosition aPos( *GetCrsr()->GetPoint() );
269 Point aPt( *pPt );
270 GetLayout()->GetCrsrOfst( &aPos, aPt );
271 SwCntntNode *pNd = aPos.nNode.GetNode().GetCntntNode();
272 pFrm = pNd->GetFrm( pPt );
274 else
275 pFrm = GetCurrFrm( FALSE );
276 while ( pFrm )
278 switch ( pFrm->GetType() )
280 case FRM_COLUMN: if( pFrm->GetUpper()->IsSctFrm() )
282 // Check, if isn't not only a single column
283 // from a section with footnotes at the end.
284 if( pFrm->GetNext() || pFrm->GetPrev() )
285 // Sectioncolumns
286 nReturn |= ( nReturn & FRMTYPE_TABLE ) ?
287 FRMTYPE_COLSECTOUTTAB : FRMTYPE_COLSECT;
289 else // nur Seiten und Rahmenspalten
290 nReturn |= FRMTYPE_COLUMN;
291 break;
292 case FRM_PAGE: nReturn |= FRMTYPE_PAGE;
293 if( ((SwPageFrm*)pFrm)->IsFtnPage() )
294 nReturn |= FRMTYPE_FTNPAGE;
295 break;
296 case FRM_HEADER: nReturn |= FRMTYPE_HEADER; break;
297 case FRM_FOOTER: nReturn |= FRMTYPE_FOOTER; break;
298 case FRM_BODY: if( pFrm->GetUpper()->IsPageFrm() ) // nicht bei ColumnFrms
299 nReturn |= FRMTYPE_BODY;
300 break;
301 case FRM_FTN: nReturn |= FRMTYPE_FOOTNOTE; break;
302 case FRM_FLY: if( ((SwFlyFrm*)pFrm)->IsFlyLayFrm() )
303 nReturn |= FRMTYPE_FLY_FREE;
304 else if ( ((SwFlyFrm*)pFrm)->IsFlyAtCntFrm() )
305 nReturn |= FRMTYPE_FLY_ATCNT;
306 else
308 ASSERT( ((SwFlyFrm*)pFrm)->IsFlyInCntFrm(),
309 "Neuer Rahmentyp?" );
310 nReturn |= FRMTYPE_FLY_INCNT;
312 nReturn |= FRMTYPE_FLY_ANY;
313 if( bStopAtFly )
314 return nReturn;
315 break;
316 case FRM_TAB:
317 case FRM_ROW:
318 case FRM_CELL: nReturn |= FRMTYPE_TABLE; break;
319 default: /* do nothing */ break;
321 if ( pFrm->IsFlyFrm() )
322 pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
323 else
324 pFrm = pFrm->GetUpper();
326 return nReturn;
329 /*************************************************************************
331 |* SwFEShell::ShLooseFcs(), ShGetFcs()
333 |* Ersterstellung MA 10. May. 93
334 |* Letzte Aenderung MA 09. Sep. 98
336 *************************************************************************/
338 void SwFEShell::ShGetFcs( BOOL bUpdate )
340 ::SetShell( this );
341 SwCrsrShell::ShGetFcs( bUpdate );
343 if ( HasDrawView() )
345 Imp()->GetDrawView()->showMarkHandles();
346 if ( Imp()->GetDrawView()->AreObjectsMarked() )
347 FrameNotify( this, FLY_DRAG_START );
351 void SwFEShell::ShLooseFcs()
353 SwCrsrShell::ShLooseFcs();
355 if ( HasDrawView() && Imp()->GetDrawView()->AreObjectsMarked() )
357 Imp()->GetDrawView()->hideMarkHandles();
358 FrameNotify( this, FLY_DRAG_END );
360 // ::ResetShell();
363 /*************************************************************************
365 |* SwFEShell::GetPhyPageNum()
366 |* SwFEShell::GetVirtPageNum()
368 |* Ersterstellung OK 07.07.93 08:20
369 |* Letzte Aenderung MA 03. Jan. 94
371 *************************************************************************/
373 USHORT SwFEShell::GetPhyPageNum()
375 SwFrm *pFrm = GetCurrFrm();
376 if ( pFrm )
377 return pFrm->GetPhyPageNum();
378 return 0;
381 USHORT SwFEShell::GetVirtPageNum( const BOOL bCalcFrm )
383 SwFrm *pFrm = GetCurrFrm( bCalcFrm );
384 if ( pFrm )
385 return pFrm->GetVirtPageNum();
386 return 0;
389 /*************************************************************************
391 |* void lcl_SetAPageOffset()
392 |* void SwFEShell::SetNewPageOffset()
393 |* void SwFEShell::SetPageOffset()
394 |* USHORT SwFEShell::GetPageOffset() const
396 |* Ersterstellung OK 07.07.93 08:20
397 |* Letzte Aenderung MA 30. Mar. 95
399 *************************************************************************/
401 void lcl_SetAPageOffset( USHORT nOffset, SwPageFrm* pPage, SwFEShell* pThis )
403 pThis->StartAllAction();
404 ASSERT( pPage->FindFirstBodyCntnt(),
405 "SwFEShell _SetAPageOffset() ohne CntntFrm" );
407 SwFmtPageDesc aDesc( pPage->GetPageDesc() );
408 aDesc.SetNumOffset( nOffset );
410 SwFrm *pFrm = pThis->GetCurrFrm( FALSE );
411 if ( pFrm->IsInTab() )
412 pThis->GetDoc()->SetAttr( aDesc, *pFrm->FindTabFrm()->GetFmt() );
413 else
414 pThis->GetDoc()->Insert( *pThis->GetCrsr(), aDesc, 0 );
416 pThis->EndAllAction();
419 void SwFEShell::SetNewPageOffset( USHORT nOffset )
421 GetLayout()->SetVirtPageNum( TRUE );
422 const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
423 lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
426 void SwFEShell::SetPageOffset( USHORT nOffset )
428 const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
429 const SwRootFrm* pLayout = GetLayout();
430 while ( pPage )
432 const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
433 if ( pFlow )
435 if ( pFlow->IsInTab() )
436 pFlow = pFlow->FindTabFrm();
437 const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
438 if ( rPgDesc.GetNumOffset() )
440 pLayout->SetVirtPageNum( TRUE );
441 lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
442 break;
445 pPage = (SwPageFrm*)pPage->GetPrev();
449 USHORT SwFEShell::GetPageOffset() const
451 const SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
452 while ( pPage )
454 const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
455 if ( pFlow )
457 if ( pFlow->IsInTab() )
458 pFlow = pFlow->FindTabFrm();
459 const USHORT nOffset = pFlow->GetAttrSet()->GetPageDesc().GetNumOffset();
460 if ( nOffset )
461 return nOffset;
463 pPage = (SwPageFrm*)pPage->GetPrev();
465 return 0;
468 /*************************************************************************
470 |* SwFEShell::InsertLabel()
472 |* Ersterstellung MA 10. Feb. 94
473 |* Letzte Aenderung MA 10. Feb. 94
475 *************************************************************************/
477 void SwFEShell::InsertLabel( const SwLabelType eType, const String &rTxt, const String& rSeparator,
478 const String& rNumberSeparator,
479 const BOOL bBefore, const USHORT nId,
480 const String& rCharacterStyle,
481 const BOOL bCpyBrd )
483 //NodeIndex der CrsrPosition besorgen, den Rest kann das Dokument
484 //selbst erledigen.
485 SwCntntFrm *pCnt = LTYPE_DRAW==eType ? 0 : GetCurrFrm( FALSE );
486 if( LTYPE_DRAW==eType || pCnt )
488 StartAllAction();
490 ULONG nIdx = 0;
491 SwFlyFrmFmt* pFlyFmt = 0;
492 switch( eType )
494 case LTYPE_OBJECT:
495 case LTYPE_FLY:
496 if( pCnt->IsInFly() )
498 //Bei Flys den Index auf den StartNode herunterreichen.
499 nIdx = pCnt->FindFlyFrm()->
500 GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
501 //warum?? Bug 61913 ParkCrsr( GetCrsr()->GetPoint()->nNode );
503 break;
504 case LTYPE_TABLE:
505 if( pCnt->IsInTab() )
507 //Bei Tabellen den Index auf den TblNode herunterreichen.
508 const SwTable& rTbl = *pCnt->FindTabFrm()->GetTable();
509 nIdx = rTbl.GetTabSortBoxes()[ 0 ]
510 ->GetSttNd()->FindTableNode()->GetIndex();
512 break;
513 case LTYPE_DRAW:
514 if( Imp()->GetDrawView() )
516 SwDrawView *pDView = Imp()->GetDrawView();
517 const SdrMarkList& rMrkList = pDView->GetMarkedObjectList();
518 StartUndo();
520 // OD 27.11.2003 #112045# - copy marked drawing objects to
521 // local list to perform the corresponding action for each object
522 std::vector<SdrObject*> aDrawObjs;
524 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
526 SdrObject* pDrawObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
527 aDrawObjs.push_back( pDrawObj );
530 // loop on marked drawing objects
531 while ( !aDrawObjs.empty() )
533 SdrObject* pDrawObj = aDrawObjs.back();
534 if ( !pDrawObj->ISA(SwVirtFlyDrawObj) &&
535 !pDrawObj->ISA(SwFlyDrawObj) )
537 SwFlyFrmFmt *pFmt =
538 GetDoc()->InsertDrawLabel( rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, *pDrawObj );
539 if( !pFlyFmt )
540 pFlyFmt = pFmt;
543 aDrawObjs.pop_back();
546 EndUndo();
548 break;
549 default:
550 ASSERT( !this, "Crsr weder in Tabelle noch in Fly." );
553 if( nIdx )
554 pFlyFmt = GetDoc()->InsertLabel( eType, rTxt, rSeparator, rNumberSeparator, bBefore, nId,
555 nIdx, rCharacterStyle, bCpyBrd );
557 SwFlyFrm* pFrm;
558 const Point aPt( GetCrsrDocPos() );
559 if( pFlyFmt && 0 != ( pFrm = pFlyFmt->GetFrm( &aPt )))
560 SelectFlyFrm( *pFrm, TRUE );
562 EndAllActionAndCall();
567 /***********************************************************************
568 #* Class : SwFEShell
569 #* Methoden : Sort
570 #* Datum : ??
571 #* Update : ??
572 #***********************************************************************/
574 BOOL SwFEShell::Sort(const SwSortOptions& rOpt)
576 if( !HasSelection() )
577 return FALSE;
579 SET_CURR_SHELL( this );
580 BOOL bRet;
581 StartAllAction();
582 if(IsTableMode())
584 // Tabelle sortieren
585 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
586 SwFrm *pFrm = GetCurrFrm( FALSE );
587 ASSERT( pFrm->FindTabFrm(), "Crsr nicht in Tabelle." );
589 // lasse ueber das Layout die Boxen suchen
590 SwSelBoxes aBoxes;
591 GetTblSel(*this, aBoxes);
593 // die Crsr muessen noch aus dem Loesch Bereich entfernt
594 // werden. Setze sie immer hinter/auf die Tabelle; ueber die
595 // Dokument-Position werden sie dann immer an die alte Position gesetzt.
596 while( !pFrm->IsCellFrm() )
597 pFrm = pFrm->GetUpper();
599 /* #107993# ParkCursor->ParkCursorTab */
600 ParkCursorInTab();
603 // Sorting am Dokument aufrufen
604 bRet = pDoc->SortTbl(aBoxes, rOpt);
606 else
608 // Text sortieren und nichts anderes
609 FOREACHPAM_START(this)
611 SwPaM* pPam = PCURCRSR;
613 SwPosition* pStart = pPam->Start();
614 SwPosition* pEnd = pPam->End();
616 SwNodeIndex aPrevIdx( pStart->nNode, -1 );
617 ULONG nOffset = pEnd->nNode.GetIndex() - pStart->nNode.GetIndex();
618 xub_StrLen nCntStt = pStart->nContent.GetIndex();
620 // Das Sortieren
621 bRet = pDoc->SortText(*pPam, rOpt);
623 // Selektion wieder setzen
624 pPam->DeleteMark();
625 pPam->GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
626 SwCntntNode* pCNd = pPam->GetCntntNode();
627 xub_StrLen nLen = pCNd->Len();
628 if( nLen > nCntStt )
629 nLen = nCntStt;
630 pPam->GetPoint()->nContent.Assign(pCNd, nLen );
631 pPam->SetMark();
633 pPam->GetPoint()->nNode += nOffset;
634 pCNd = pPam->GetCntntNode();
635 pPam->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
637 FOREACHPAM_END()
640 EndAllAction();
641 return bRet;
644 /*************************************************************************
646 |* SwFEShell::GetCurColNum(), _GetColNum()
648 |* Ersterstellung MA 03. Feb. 95
649 |* Letzte Aenderung MA 20. Apr. 95
651 |*************************************************************************/
653 USHORT SwFEShell::_GetCurColNum( const SwFrm *pFrm,
654 SwGetCurColNumPara* pPara ) const
656 USHORT nRet = 0;
657 while ( pFrm )
659 pFrm = pFrm->GetUpper();
660 if( pFrm && pFrm->IsColumnFrm() )
662 const SwFrm *pCurFrm = pFrm;
663 do {
664 ++nRet;
665 pFrm = pFrm->GetPrev();
666 } while ( pFrm );
668 if( pPara )
670 // dann suche mal das Format, was diese Spaltigkeit bestimmt
671 pFrm = pCurFrm->GetUpper();
672 while( pFrm )
674 if( ( FRM_PAGE | FRM_FLY | FRM_SECTION ) & pFrm->GetType() )
676 pPara->pFrmFmt = ((SwLayoutFrm*)pFrm)->GetFmt();
677 pPara->pPrtRect = &pFrm->Prt();
678 pPara->pFrmRect = &pFrm->Frm();
679 break;
681 pFrm = pFrm->GetUpper();
683 if( !pFrm )
685 pPara->pFrmFmt = 0;
686 pPara->pPrtRect = 0;
687 pPara->pFrmRect = 0;
690 break;
693 return nRet;
696 USHORT SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
698 ASSERT( GetCurrFrm(), "Crsr geparkt?" );
699 return _GetCurColNum( GetCurrFrm(), pPara );
702 USHORT SwFEShell::GetCurOutColNum( SwGetCurColNumPara* pPara ) const
704 USHORT nRet = 0;
705 SwFrm* pFrm = GetCurrFrm();
706 ASSERT( pFrm, "Crsr geparkt?" );
707 if( pFrm )
709 pFrm = pFrm->IsInTab() ? (SwFrm*)pFrm->FindTabFrm()
710 : (SwFrm*)pFrm->FindSctFrm();
711 ASSERT( pFrm, "No Tab, no Sect" );
712 if( pFrm )
713 nRet = _GetCurColNum( pFrm, pPara );
715 return nRet;
718 SwFEShell::SwFEShell( SwDoc& rDoc, Window *pWindow, const SwViewOption *pOptions )
719 : SwEditShell( rDoc, pWindow, pOptions ),
720 pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
724 SwFEShell::SwFEShell( SwEditShell& rShell, Window *pWindow )
725 : SwEditShell( rShell, pWindow ),
726 pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
730 SwFEShell::~SwFEShell()
732 delete pChainFrom;
733 delete pChainTo;
736 // OD 18.09.2003 #i17567#, #108749#, #110354# - adjustments for allowing
737 // negative vertical positions for fly frames anchored to paragraph/to character.
738 // OD 06.11.2003 #i22305# - adjustments for option 'Follow text flow'
739 // for to frame anchored objects.
740 // OD 12.11.2003 #i22341# - adjustments for vertical alignment at top of line
741 // for to character anchored objects.
742 void SwFEShell::CalcBoundRect( SwRect& _orRect,
743 const RndStdIds _nAnchorId,
744 const sal_Int16 _eHoriRelOrient,
745 const sal_Int16 _eVertRelOrient,
746 const SwPosition* _pToCharCntntPos,
747 const bool _bFollowTextFlow,
748 bool _bMirror,
749 Point* _opRef,
750 Size* _opPercent ) const
752 const SwFrm* pFrm;
753 const SwFlyFrm* pFly;
754 if( _opRef )
756 pFrm = GetCurrFrm();
757 if( 0 != ( pFly = pFrm->FindFlyFrm() ) )
758 pFrm = pFly->GetAnchorFrm();
760 else
762 pFly = FindFlyFrm();
763 pFrm = pFly ? pFly->GetAnchorFrm() : GetCurrFrm();
766 sal_Bool bWrapThrough = sal_False;
767 if ( pFly )
769 SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
770 const SwFmtSurround& rSurround = pFmt->GetSurround();
771 bWrapThrough = rSurround.GetSurround() == SURROUND_THROUGHT;
774 const SwPageFrm* pPage = pFrm->FindPageFrm();
775 _bMirror = _bMirror && !pPage->OnRightPage();
777 Point aPos;
778 BOOL bVertic = FALSE;
779 BOOL bRTL = FALSE;
781 if( FLY_PAGE == _nAnchorId || FLY_AT_FLY == _nAnchorId ) // LAYER_IMPL
783 const SwFrm* pTmp = pFrm;
784 // OD 06.11.2003 #i22305#
785 if ( FLY_PAGE == _nAnchorId ||
786 ( FLY_AT_FLY == _nAnchorId && !_bFollowTextFlow ) )
788 pFrm = pPage;
790 else
792 pFrm = pFrm->FindFlyFrm();
794 if ( !pFrm )
795 pFrm = pTmp;
796 _orRect = pFrm->Frm();
797 SWRECTFN( pFrm )
798 bRTL = pFrm->IsRightToLeft();
799 if ( bRTL )
800 aPos = pFrm->Frm().TopRight();
801 else
802 aPos = (pFrm->Frm().*fnRect->fnGetPos)();
804 if( bVert )
806 bVertic = TRUE;
807 _bMirror = false; // no mirroring in vertical environment
808 switch ( _eHoriRelOrient )
810 case text::RelOrientation::PAGE_RIGHT:
811 case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
812 // no break!
813 case text::RelOrientation::PRINT_AREA:
814 case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() += pFrm->Prt().Top(); break;
815 default: break;
818 else if ( _bMirror )
820 switch ( _eHoriRelOrient )
822 case text::RelOrientation::PRINT_AREA:
823 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
824 // kein break
825 case text::RelOrientation::PAGE_RIGHT:
826 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
827 default: aPos.X() += pFrm->Frm().Width();
830 else if ( bRTL )
832 switch ( _eHoriRelOrient )
834 case text::RelOrientation::PRINT_AREA:
835 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
836 // kein break!
837 case text::RelOrientation::PAGE_LEFT:
838 case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Prt().Left() -
839 pFrm->Frm().Width(); break;
840 default: break;
843 else
845 switch ( _eHoriRelOrient )
847 case text::RelOrientation::PAGE_RIGHT:
848 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
849 // kein break!
850 case text::RelOrientation::PRINT_AREA:
851 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Left(); break;
852 default:break;
855 // --> OD 2006-12-12 #i67221# - proposed patch
856 if( bVert )
858 switch ( _eVertRelOrient )
860 case text::RelOrientation::PRINT_AREA:
861 case text::RelOrientation::PAGE_PRINT_AREA:
863 aPos.X() -= pFrm->GetRightMargin();
865 break;
868 else
870 switch ( _eVertRelOrient )
872 case text::RelOrientation::PRINT_AREA:
873 case text::RelOrientation::PAGE_PRINT_AREA:
875 if ( pFrm->IsPageFrm() )
877 aPos.Y() =
878 static_cast<const SwPageFrm*>(pFrm)->PrtWithoutHeaderAndFooter().Top();
880 else
882 aPos.Y() += pFrm->Prt().Top();
885 break;
888 // <--
889 if ( _opPercent )
890 *_opPercent = pFrm->Prt().SSize();
892 else
894 const SwFrm* pUpper = ( pFrm->IsPageFrm() || pFrm->IsFlyFrm() ) ?
895 pFrm : pFrm->GetUpper();
896 SWRECTFN( pUpper );
897 if ( _opPercent )
898 *_opPercent = pUpper->Prt().SSize();
900 bRTL = pFrm->IsRightToLeft();
901 if ( bRTL )
902 aPos = pFrm->Frm().TopRight();
903 else
904 aPos = (pFrm->Frm().*fnRect->fnGetPos)();
905 // OD 08.09.2003 #i17567#, #108749#, #110354# - allow negative positions
906 // for fly frames anchor to paragraph/to character.
907 if ( _nAnchorId == FLY_AT_CNTNT || _nAnchorId == FLY_AUTO_CNTNT )
909 // The rectangle, the fly frame can be positioned in, is determined
910 // horizontally by the frame area of the horizontal environment
911 // and vertically by the printing area of the vertical environment,
912 // if the object follows the text flow, or by the frame area of the
913 // vertical environment, if the object doesn't follow the text flow.
914 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject>
915 objectpositioning::SwEnvironmentOfAnchoredObject aEnvOfObj(
916 _bFollowTextFlow );
917 const SwLayoutFrm& rHoriEnvironLayFrm =
918 aEnvOfObj.GetHoriEnvironmentLayoutFrm( *pFrm );
919 const SwLayoutFrm& rVertEnvironLayFrm =
920 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pFrm );
921 SwRect aHoriEnvironRect( rHoriEnvironLayFrm.Frm() );
922 SwRect aVertEnvironRect;
923 if ( _bFollowTextFlow )
925 aVertEnvironRect = rVertEnvironLayFrm.Prt();
926 aVertEnvironRect.Pos() += rVertEnvironLayFrm.Frm().Pos();
927 // OD 19.09.2003 #i18732# - adjust vertical 'virtual' anchor position
928 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
929 // to page areas.
930 if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
932 if ( bVert )
934 aPos.X() = aVertEnvironRect.Right();
936 else
938 aPos.Y() = aVertEnvironRect.Top();
942 else
944 ASSERT( rVertEnvironLayFrm.IsPageFrm(),
945 "<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
946 aVertEnvironRect = rVertEnvironLayFrm.Frm();
947 // OD 19.09.2003 #i18732# - adjustment vertical 'virtual' anchor position
948 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
949 // to page areas.
950 if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
952 if ( bVert )
954 aPos.X() = aVertEnvironRect.Right();
955 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
957 aPos.X() -= rVertEnvironLayFrm.GetRightMargin();
960 else
962 aPos.Y() = aVertEnvironRect.Top();
963 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
965 aPos.Y() += rVertEnvironLayFrm.GetTopMargin();
966 // add height of page header
967 const SwFrm* pTmpFrm = rVertEnvironLayFrm.Lower();
968 if ( pTmpFrm->IsHeaderFrm() )
970 aPos.Y() += pTmpFrm->Frm().Height();
977 // OD 12.11.2003 #i22341# - adjust vertical 'virtual' anchor position
978 // (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
979 // character and vertical aligned at character or top of line
980 // --> OD 2005-12-29 #125800#
981 // <pFrm>, which is the anchor frame or the proposed anchor frame,
982 // doesn't have to be a text frame (e.g. edit a to-page anchored
983 // fly frame). Thus, assure this.
984 const SwTxtFrm* pTxtFrm( dynamic_cast<const SwTxtFrm*>(pFrm) );
985 if ( pTxtFrm &&
986 _nAnchorId == FLY_AUTO_CNTNT &&
987 ( _eVertRelOrient == text::RelOrientation::CHAR ||
988 _eVertRelOrient == text::RelOrientation::TEXT_LINE ) )
990 SwTwips nTop = 0L;
991 if ( _eVertRelOrient == text::RelOrientation::CHAR )
993 SwRect aChRect;
994 if ( _pToCharCntntPos )
996 pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
998 else
1000 // No content position provided. Thus, use a default one.
1001 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1002 pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
1004 nTop = (aChRect.*fnRect->fnGetBottom)();
1006 else
1008 if ( _pToCharCntntPos )
1010 pTxtFrm->GetTopOfLine( nTop, *_pToCharCntntPos );
1012 else
1014 // No content position provided. Thus, use a default one.
1015 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1016 pTxtFrm->GetTopOfLine( nTop, aDefaultCntntPos );
1019 if ( bVert )
1021 aPos.X() = nTop;
1023 else
1025 aPos.Y() = nTop;
1029 // --> OD 2004-10-05 #i26945# - adjust horizontal 'virtual' anchor
1030 // position (<aPos.X()> respectively <aPos.Y()>), if object is
1031 // anchored to character and horizontal aligned at character.
1032 if ( pTxtFrm &&
1033 _nAnchorId == FLY_AUTO_CNTNT &&
1034 _eHoriRelOrient == text::RelOrientation::CHAR )
1036 SwTwips nLeft = 0L;
1037 SwRect aChRect;
1038 if ( _pToCharCntntPos )
1040 pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
1042 else
1044 // No content position provided. Thus, use a default one.
1045 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1046 pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
1048 nLeft = (aChRect.*fnRect->fnGetLeft)();
1049 if ( bVert )
1051 aPos.Y() = nLeft;
1053 else
1055 aPos.X() = nLeft;
1058 // <--
1060 if ( bVert )
1062 _orRect = SwRect( aVertEnvironRect.Left(),
1063 aHoriEnvironRect.Top(),
1064 aVertEnvironRect.Width(),
1065 aHoriEnvironRect.Height() );
1067 else
1069 _orRect = SwRect( aHoriEnvironRect.Left(),
1070 aVertEnvironRect.Top(),
1071 aHoriEnvironRect.Width(),
1072 aVertEnvironRect.Height() );
1075 else
1077 if( _opRef && pFly && pFly->IsFlyInCntFrm() )
1078 *_opRef = ( (SwFlyInCntFrm*)pFly )->GetRefPoint();
1080 _orRect = pUpper->Frm();
1081 if( !pUpper->IsBodyFrm() )
1083 _orRect += pUpper->Prt().Pos();
1084 _orRect.SSize( pUpper->Prt().SSize() );
1085 if ( pUpper->IsCellFrm() )//MA_FLY_HEIGHT
1087 const SwFrm* pTab = pUpper->FindTabFrm();
1088 long nBottom = (pTab->GetUpper()->*fnRect->fnGetPrtBottom)();
1089 (_orRect.*fnRect->fnSetBottom)( nBottom );
1092 // bei zeichengebundenen lieber nur 90% der Hoehe ausnutzen
1094 if( bVert )
1095 _orRect.Width( (_orRect.Width()*9)/10 );
1096 else
1097 _orRect.Height( (_orRect.Height()*9)/10 );
1101 const SwTwips nBaseOfstForFly = ( pFrm->IsTxtFrm() && pFly ) ?
1102 ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( !bWrapThrough ) :
1104 if( bVert )
1106 bVertic = TRUE;
1107 _bMirror = false;
1109 switch ( _eHoriRelOrient )
1111 case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
1112 aPos += (pFrm->Prt().*fnRect->fnGetPos)();
1113 break;
1114 case text::RelOrientation::PRINT_AREA: aPos += (pFrm->Prt().*fnRect->fnGetPos)();
1115 aPos.Y() += nBaseOfstForFly;
1116 break;
1117 case text::RelOrientation::PAGE_RIGHT: aPos.Y() = pPage->Frm().Top()
1118 + pPage->Prt().Bottom(); break;
1119 case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() = pPage->Frm().Top()
1120 + pPage->Prt().Top(); break;
1121 case text::RelOrientation::PAGE_LEFT:
1122 case text::RelOrientation::PAGE_FRAME: aPos.Y() = pPage->Frm().Top(); break;
1123 case text::RelOrientation::FRAME: aPos.Y() += nBaseOfstForFly; break;
1124 default: break;
1127 else if( _bMirror )
1129 switch ( _eHoriRelOrient )
1131 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
1132 case text::RelOrientation::FRAME:
1133 case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Frm().Width(); break;
1134 case text::RelOrientation::PRINT_AREA: aPos.X() += pFrm->Prt().Right(); break;
1135 case text::RelOrientation::PAGE_LEFT:
1136 case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Right(); break;
1137 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
1138 + pPage->Prt().Left(); break;
1139 default: break;
1142 else if ( bRTL )
1144 switch ( _eHoriRelOrient )
1146 case text::RelOrientation::FRAME_LEFT:
1147 aPos.X() = pFrm->Frm().Left() +
1148 pFrm->Prt().Left();
1149 break;
1151 case text::RelOrientation::PRINT_AREA:
1152 aPos.X() = pFrm->Frm().Left() + pFrm->Prt().Left() +
1153 pFrm->Prt().Width();
1154 aPos.X() += nBaseOfstForFly;
1155 break;
1157 case text::RelOrientation::PAGE_LEFT:
1158 aPos.X() = pPage->Frm().Left() + pPage->Prt().Left();
1159 break;
1161 case text::RelOrientation::PAGE_PRINT_AREA:
1162 aPos.X() = pPage->Frm().Left() + pPage->Prt().Left() +
1163 pPage->Prt().Width() ;
1164 break;
1166 case text::RelOrientation::PAGE_RIGHT:
1167 case text::RelOrientation::PAGE_FRAME:
1168 aPos.X() = pPage->Frm().Right();
1169 break;
1171 case text::RelOrientation::FRAME:
1172 aPos.X() += nBaseOfstForFly;
1173 break;
1174 default: break;
1177 else
1179 switch ( _eHoriRelOrient )
1181 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
1182 aPos += pFrm->Prt().Pos();
1183 break;
1184 case text::RelOrientation::PRINT_AREA: aPos += pFrm->Prt().Pos();
1185 aPos.X() += nBaseOfstForFly;
1186 break;
1187 case text::RelOrientation::PAGE_RIGHT: aPos.X() = pPage->Frm().Left()
1188 + pPage->Prt().Right(); break;
1189 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
1190 + pPage->Prt().Left(); break;
1191 case text::RelOrientation::PAGE_LEFT:
1192 case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Left(); break;
1193 case text::RelOrientation::FRAME: aPos.X() += nBaseOfstForFly; break;
1194 default: break;
1199 if( !_opRef )
1201 if( bVertic )
1202 _orRect.Pos( aPos.X() - _orRect.Width() - _orRect.Left(), _orRect.Top() - aPos.Y() );
1203 else if ( bRTL )
1204 _orRect.Pos( - ( _orRect.Right() - aPos.X() ), _orRect.Top() - aPos.Y() );
1205 else
1206 _orRect.Pos( _orRect.Left() - aPos.X(), _orRect.Top() - aPos.Y() );
1207 if( _bMirror )
1208 _orRect.Pos( -_orRect.Right(), _orRect.Top() );
1212 Size SwFEShell::GetGraphicDefaultSize() const
1214 Size aRet;
1215 SwFlyFrm *pFly = FindFlyFrm();
1216 if ( pFly )
1218 // --> OD 2004-09-24 #i32951# - due to issue #i28701# no format of a
1219 // newly inserted Writer fly frame or its anchor frame is performed
1220 // any more. Thus, it could be possible (e.g. on insert of a horizontal
1221 // line) that the anchor frame isn't formatted and its printing area
1222 // size is (0,0). If this is the case the printing area of the upper
1223 // of the anchor frame is taken.
1224 const SwFrm* pAnchorFrm = pFly->GetAnchorFrm();
1225 aRet = pAnchorFrm->Prt().SSize();
1226 if ( aRet.Width() == 0 && aRet.Height() == 0 &&
1227 pAnchorFrm->GetUpper() )
1229 aRet = pAnchorFrm->GetUpper()->Prt().SSize();
1231 // <--
1233 SwRect aBound;
1234 CalcBoundRect( aBound, pFly->GetFmt()->GetAnchor().GetAnchorId());
1235 if ( pFly->GetAnchorFrm()->IsVertical() )
1236 aRet.Width() = aBound.Width();
1237 else
1238 aRet.Height() = aBound.Height();
1240 return aRet;
1242 /* -----------------------------12.08.2002 12:51------------------------------
1244 ---------------------------------------------------------------------------*/
1245 BOOL SwFEShell::IsFrmVertical(BOOL bEnvironment, BOOL& bRTL) const
1247 BOOL bVert = FALSE;
1248 bRTL = FALSE;
1250 if ( Imp()->HasDrawView() )
1252 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1253 if( rMrkList.GetMarkCount() != 1 )
1254 return bVert;
1256 SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1257 // --> OD 2006-01-06 #123831# - make code robust:
1258 if ( !pObj )
1260 ASSERT( false,
1261 "<SwFEShell::IsFrmVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation, please inform OD" );
1262 return bVert;
1264 // <--
1265 // OD 2004-03-29 #i26791#
1266 SwContact* pContact = static_cast<SwContact*>(GetUserCall( pObj ));
1267 // --> OD 2006-01-06 #123831# - make code robust:
1268 if ( !pContact )
1270 ASSERT( false,
1271 "<SwFEShell::IsFrmVertical(..)> - missing SwContact instance at marked object -> This is a serious situation, please inform OD" );
1272 return bVert;
1274 // <--
1275 const SwFrm* pRef = pContact->GetAnchoredObj( pObj )->GetAnchorFrm();
1276 // --> OD 2006-01-06 #123831# - make code robust:
1277 if ( !pRef )
1279 ASSERT( false,
1280 "<SwFEShell::IsFrmVertical(..)> - missing anchor frame at marked object -> This is a serious situation, please inform OD" );
1281 return bVert;
1283 // <--
1285 if ( pObj->ISA(SwVirtFlyDrawObj) && !bEnvironment )
1286 pRef = static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
1288 bVert = pRef->IsVertical();
1289 bRTL = pRef->IsRightToLeft();
1292 return bVert;
1295 void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef&, const Point& )
1297 // does not do anything, only avoids crash if the method is used for wrong shell