merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / frmedt / fews.cxx
blob4485ba99f6e141dd366017cac5eaf2bef078d0f5
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
415 pThis->GetDoc()->InsertPoolItem( *pThis->GetCrsr(), aDesc, 0 );
418 pThis->EndAllAction();
421 void SwFEShell::SetNewPageOffset( USHORT nOffset )
423 GetLayout()->SetVirtPageNum( TRUE );
424 const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
425 lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
428 void SwFEShell::SetPageOffset( USHORT nOffset )
430 const SwPageFrm *pPage = GetCurrFrm( FALSE )->FindPageFrm();
431 const SwRootFrm* pLayout = GetLayout();
432 while ( pPage )
434 const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
435 if ( pFlow )
437 if ( pFlow->IsInTab() )
438 pFlow = pFlow->FindTabFrm();
439 const SwFmtPageDesc& rPgDesc = pFlow->GetAttrSet()->GetPageDesc();
440 if ( rPgDesc.GetNumOffset() )
442 pLayout->SetVirtPageNum( TRUE );
443 lcl_SetAPageOffset( nOffset, (SwPageFrm*)pPage, this );
444 break;
447 pPage = (SwPageFrm*)pPage->GetPrev();
451 USHORT SwFEShell::GetPageOffset() const
453 const SwPageFrm *pPage = GetCurrFrm()->FindPageFrm();
454 while ( pPage )
456 const SwFrm *pFlow = pPage->FindFirstBodyCntnt();
457 if ( pFlow )
459 if ( pFlow->IsInTab() )
460 pFlow = pFlow->FindTabFrm();
461 const USHORT nOffset = pFlow->GetAttrSet()->GetPageDesc().GetNumOffset();
462 if ( nOffset )
463 return nOffset;
465 pPage = (SwPageFrm*)pPage->GetPrev();
467 return 0;
470 /*************************************************************************
472 |* SwFEShell::InsertLabel()
474 |* Ersterstellung MA 10. Feb. 94
475 |* Letzte Aenderung MA 10. Feb. 94
477 *************************************************************************/
479 void SwFEShell::InsertLabel( const SwLabelType eType, const String &rTxt, const String& rSeparator,
480 const String& rNumberSeparator,
481 const BOOL bBefore, const USHORT nId,
482 const String& rCharacterStyle,
483 const BOOL bCpyBrd )
485 //NodeIndex der CrsrPosition besorgen, den Rest kann das Dokument
486 //selbst erledigen.
487 SwCntntFrm *pCnt = LTYPE_DRAW==eType ? 0 : GetCurrFrm( FALSE );
488 if( LTYPE_DRAW==eType || pCnt )
490 StartAllAction();
492 ULONG nIdx = 0;
493 SwFlyFrmFmt* pFlyFmt = 0;
494 switch( eType )
496 case LTYPE_OBJECT:
497 case LTYPE_FLY:
498 if( pCnt->IsInFly() )
500 //Bei Flys den Index auf den StartNode herunterreichen.
501 nIdx = pCnt->FindFlyFrm()->
502 GetFmt()->GetCntnt().GetCntntIdx()->GetIndex();
503 //warum?? Bug 61913 ParkCrsr( GetCrsr()->GetPoint()->nNode );
505 break;
506 case LTYPE_TABLE:
507 if( pCnt->IsInTab() )
509 //Bei Tabellen den Index auf den TblNode herunterreichen.
510 const SwTable& rTbl = *pCnt->FindTabFrm()->GetTable();
511 nIdx = rTbl.GetTabSortBoxes()[ 0 ]
512 ->GetSttNd()->FindTableNode()->GetIndex();
514 break;
515 case LTYPE_DRAW:
516 if( Imp()->GetDrawView() )
518 SwDrawView *pDView = Imp()->GetDrawView();
519 const SdrMarkList& rMrkList = pDView->GetMarkedObjectList();
520 StartUndo();
522 // OD 27.11.2003 #112045# - copy marked drawing objects to
523 // local list to perform the corresponding action for each object
524 std::vector<SdrObject*> aDrawObjs;
526 for ( USHORT i = 0; i < rMrkList.GetMarkCount(); ++i )
528 SdrObject* pDrawObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
529 aDrawObjs.push_back( pDrawObj );
532 // loop on marked drawing objects
533 while ( !aDrawObjs.empty() )
535 SdrObject* pDrawObj = aDrawObjs.back();
536 if ( !pDrawObj->ISA(SwVirtFlyDrawObj) &&
537 !pDrawObj->ISA(SwFlyDrawObj) )
539 SwFlyFrmFmt *pFmt =
540 GetDoc()->InsertDrawLabel( rTxt, rSeparator, rNumberSeparator, nId, rCharacterStyle, *pDrawObj );
541 if( !pFlyFmt )
542 pFlyFmt = pFmt;
545 aDrawObjs.pop_back();
548 EndUndo();
550 break;
551 default:
552 ASSERT( !this, "Crsr weder in Tabelle noch in Fly." );
555 if( nIdx )
556 pFlyFmt = GetDoc()->InsertLabel( eType, rTxt, rSeparator, rNumberSeparator, bBefore, nId,
557 nIdx, rCharacterStyle, bCpyBrd );
559 SwFlyFrm* pFrm;
560 const Point aPt( GetCrsrDocPos() );
561 if( pFlyFmt && 0 != ( pFrm = pFlyFmt->GetFrm( &aPt )))
562 SelectFlyFrm( *pFrm, TRUE );
564 EndAllActionAndCall();
569 /***********************************************************************
570 #* Class : SwFEShell
571 #* Methoden : Sort
572 #* Datum : ??
573 #* Update : ??
574 #***********************************************************************/
576 BOOL SwFEShell::Sort(const SwSortOptions& rOpt)
578 if( !HasSelection() )
579 return FALSE;
581 SET_CURR_SHELL( this );
582 BOOL bRet;
583 StartAllAction();
584 if(IsTableMode())
586 // Tabelle sortieren
587 // pruefe ob vom aktuellen Crsr der SPoint/Mark in einer Tabelle stehen
588 SwFrm *pFrm = GetCurrFrm( FALSE );
589 ASSERT( pFrm->FindTabFrm(), "Crsr nicht in Tabelle." );
591 // lasse ueber das Layout die Boxen suchen
592 SwSelBoxes aBoxes;
593 GetTblSel(*this, aBoxes);
595 // die Crsr muessen noch aus dem Loesch Bereich entfernt
596 // werden. Setze sie immer hinter/auf die Tabelle; ueber die
597 // Dokument-Position werden sie dann immer an die alte Position gesetzt.
598 while( !pFrm->IsCellFrm() )
599 pFrm = pFrm->GetUpper();
601 /* #107993# ParkCursor->ParkCursorTab */
602 ParkCursorInTab();
605 // Sorting am Dokument aufrufen
606 bRet = pDoc->SortTbl(aBoxes, rOpt);
608 else
610 // Text sortieren und nichts anderes
611 FOREACHPAM_START(this)
613 SwPaM* pPam = PCURCRSR;
615 SwPosition* pStart = pPam->Start();
616 SwPosition* pEnd = pPam->End();
618 SwNodeIndex aPrevIdx( pStart->nNode, -1 );
619 ULONG nOffset = pEnd->nNode.GetIndex() - pStart->nNode.GetIndex();
620 xub_StrLen nCntStt = pStart->nContent.GetIndex();
622 // Das Sortieren
623 bRet = pDoc->SortText(*pPam, rOpt);
625 // Selektion wieder setzen
626 pPam->DeleteMark();
627 pPam->GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
628 SwCntntNode* pCNd = pPam->GetCntntNode();
629 xub_StrLen nLen = pCNd->Len();
630 if( nLen > nCntStt )
631 nLen = nCntStt;
632 pPam->GetPoint()->nContent.Assign(pCNd, nLen );
633 pPam->SetMark();
635 pPam->GetPoint()->nNode += nOffset;
636 pCNd = pPam->GetCntntNode();
637 pPam->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
639 FOREACHPAM_END()
642 EndAllAction();
643 return bRet;
646 /*************************************************************************
648 |* SwFEShell::GetCurColNum(), _GetColNum()
650 |* Ersterstellung MA 03. Feb. 95
651 |* Letzte Aenderung MA 20. Apr. 95
653 |*************************************************************************/
655 USHORT SwFEShell::_GetCurColNum( const SwFrm *pFrm,
656 SwGetCurColNumPara* pPara ) const
658 USHORT nRet = 0;
659 while ( pFrm )
661 pFrm = pFrm->GetUpper();
662 if( pFrm && pFrm->IsColumnFrm() )
664 const SwFrm *pCurFrm = pFrm;
665 do {
666 ++nRet;
667 pFrm = pFrm->GetPrev();
668 } while ( pFrm );
670 if( pPara )
672 // dann suche mal das Format, was diese Spaltigkeit bestimmt
673 pFrm = pCurFrm->GetUpper();
674 while( pFrm )
676 if( ( FRM_PAGE | FRM_FLY | FRM_SECTION ) & pFrm->GetType() )
678 pPara->pFrmFmt = ((SwLayoutFrm*)pFrm)->GetFmt();
679 pPara->pPrtRect = &pFrm->Prt();
680 pPara->pFrmRect = &pFrm->Frm();
681 break;
683 pFrm = pFrm->GetUpper();
685 if( !pFrm )
687 pPara->pFrmFmt = 0;
688 pPara->pPrtRect = 0;
689 pPara->pFrmRect = 0;
692 break;
695 return nRet;
698 USHORT SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
700 ASSERT( GetCurrFrm(), "Crsr geparkt?" );
701 return _GetCurColNum( GetCurrFrm(), pPara );
704 USHORT SwFEShell::GetCurOutColNum( SwGetCurColNumPara* pPara ) const
706 USHORT nRet = 0;
707 SwFrm* pFrm = GetCurrFrm();
708 ASSERT( pFrm, "Crsr geparkt?" );
709 if( pFrm )
711 pFrm = pFrm->IsInTab() ? (SwFrm*)pFrm->FindTabFrm()
712 : (SwFrm*)pFrm->FindSctFrm();
713 ASSERT( pFrm, "No Tab, no Sect" );
714 if( pFrm )
715 nRet = _GetCurColNum( pFrm, pPara );
717 return nRet;
720 SwFEShell::SwFEShell( SwDoc& rDoc, Window *pWindow, const SwViewOption *pOptions )
721 : SwEditShell( rDoc, pWindow, pOptions ),
722 pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
726 SwFEShell::SwFEShell( SwEditShell& rShell, Window *pWindow )
727 : SwEditShell( rShell, pWindow ),
728 pChainFrom( 0 ), pChainTo( 0 ), bCheckForOLEInCaption( FALSE )
732 SwFEShell::~SwFEShell()
734 delete pChainFrom;
735 delete pChainTo;
738 // OD 18.09.2003 #i17567#, #108749#, #110354# - adjustments for allowing
739 // negative vertical positions for fly frames anchored to paragraph/to character.
740 // OD 06.11.2003 #i22305# - adjustments for option 'Follow text flow'
741 // for to frame anchored objects.
742 // OD 12.11.2003 #i22341# - adjustments for vertical alignment at top of line
743 // for to character anchored objects.
744 void SwFEShell::CalcBoundRect( SwRect& _orRect,
745 const RndStdIds _nAnchorId,
746 const sal_Int16 _eHoriRelOrient,
747 const sal_Int16 _eVertRelOrient,
748 const SwPosition* _pToCharCntntPos,
749 const bool _bFollowTextFlow,
750 bool _bMirror,
751 Point* _opRef,
752 Size* _opPercent ) const
754 const SwFrm* pFrm;
755 const SwFlyFrm* pFly;
756 if( _opRef )
758 pFrm = GetCurrFrm();
759 if( 0 != ( pFly = pFrm->FindFlyFrm() ) )
760 pFrm = pFly->GetAnchorFrm();
762 else
764 pFly = FindFlyFrm();
765 pFrm = pFly ? pFly->GetAnchorFrm() : GetCurrFrm();
768 sal_Bool bWrapThrough = sal_False;
769 if ( pFly )
771 SwFlyFrmFmt* pFmt = (SwFlyFrmFmt*)pFly->GetFmt();
772 const SwFmtSurround& rSurround = pFmt->GetSurround();
773 bWrapThrough = rSurround.GetSurround() == SURROUND_THROUGHT;
776 const SwPageFrm* pPage = pFrm->FindPageFrm();
777 _bMirror = _bMirror && !pPage->OnRightPage();
779 Point aPos;
780 BOOL bVertic = FALSE;
781 BOOL bRTL = FALSE;
783 if( FLY_PAGE == _nAnchorId || FLY_AT_FLY == _nAnchorId ) // LAYER_IMPL
785 const SwFrm* pTmp = pFrm;
786 // OD 06.11.2003 #i22305#
787 if ( FLY_PAGE == _nAnchorId ||
788 ( FLY_AT_FLY == _nAnchorId && !_bFollowTextFlow ) )
790 pFrm = pPage;
792 else
794 pFrm = pFrm->FindFlyFrm();
796 if ( !pFrm )
797 pFrm = pTmp;
798 _orRect = pFrm->Frm();
799 SWRECTFN( pFrm )
800 bRTL = pFrm->IsRightToLeft();
801 if ( bRTL )
802 aPos = pFrm->Frm().TopRight();
803 else
804 aPos = (pFrm->Frm().*fnRect->fnGetPos)();
806 if( bVert )
808 bVertic = TRUE;
809 _bMirror = false; // no mirroring in vertical environment
810 switch ( _eHoriRelOrient )
812 case text::RelOrientation::PAGE_RIGHT:
813 case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
814 // no break!
815 case text::RelOrientation::PRINT_AREA:
816 case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() += pFrm->Prt().Top(); break;
817 default: break;
820 else if ( _bMirror )
822 switch ( _eHoriRelOrient )
824 case text::RelOrientation::PRINT_AREA:
825 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
826 // kein break
827 case text::RelOrientation::PAGE_RIGHT:
828 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
829 default: aPos.X() += pFrm->Frm().Width();
832 else if ( bRTL )
834 switch ( _eHoriRelOrient )
836 case text::RelOrientation::PRINT_AREA:
837 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Width();
838 // kein break!
839 case text::RelOrientation::PAGE_LEFT:
840 case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Prt().Left() -
841 pFrm->Frm().Width(); break;
842 default: break;
845 else
847 switch ( _eHoriRelOrient )
849 case text::RelOrientation::PAGE_RIGHT:
850 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
851 // kein break!
852 case text::RelOrientation::PRINT_AREA:
853 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() += pFrm->Prt().Left(); break;
854 default:break;
857 // --> OD 2006-12-12 #i67221# - proposed patch
858 if( bVert )
860 switch ( _eVertRelOrient )
862 case text::RelOrientation::PRINT_AREA:
863 case text::RelOrientation::PAGE_PRINT_AREA:
865 aPos.X() -= pFrm->GetRightMargin();
867 break;
870 else
872 switch ( _eVertRelOrient )
874 case text::RelOrientation::PRINT_AREA:
875 case text::RelOrientation::PAGE_PRINT_AREA:
877 if ( pFrm->IsPageFrm() )
879 aPos.Y() =
880 static_cast<const SwPageFrm*>(pFrm)->PrtWithoutHeaderAndFooter().Top();
882 else
884 aPos.Y() += pFrm->Prt().Top();
887 break;
890 // <--
891 if ( _opPercent )
892 *_opPercent = pFrm->Prt().SSize();
894 else
896 const SwFrm* pUpper = ( pFrm->IsPageFrm() || pFrm->IsFlyFrm() ) ?
897 pFrm : pFrm->GetUpper();
898 SWRECTFN( pUpper );
899 if ( _opPercent )
900 *_opPercent = pUpper->Prt().SSize();
902 bRTL = pFrm->IsRightToLeft();
903 if ( bRTL )
904 aPos = pFrm->Frm().TopRight();
905 else
906 aPos = (pFrm->Frm().*fnRect->fnGetPos)();
907 // OD 08.09.2003 #i17567#, #108749#, #110354# - allow negative positions
908 // for fly frames anchor to paragraph/to character.
909 if ( _nAnchorId == FLY_AT_CNTNT || _nAnchorId == FLY_AUTO_CNTNT )
911 // The rectangle, the fly frame can be positioned in, is determined
912 // horizontally by the frame area of the horizontal environment
913 // and vertically by the printing area of the vertical environment,
914 // if the object follows the text flow, or by the frame area of the
915 // vertical environment, if the object doesn't follow the text flow.
916 // OD 29.10.2003 #113049# - new class <SwEnvironmentOfAnchoredObject>
917 objectpositioning::SwEnvironmentOfAnchoredObject aEnvOfObj(
918 _bFollowTextFlow );
919 const SwLayoutFrm& rHoriEnvironLayFrm =
920 aEnvOfObj.GetHoriEnvironmentLayoutFrm( *pFrm );
921 const SwLayoutFrm& rVertEnvironLayFrm =
922 aEnvOfObj.GetVertEnvironmentLayoutFrm( *pFrm );
923 SwRect aHoriEnvironRect( rHoriEnvironLayFrm.Frm() );
924 SwRect aVertEnvironRect;
925 if ( _bFollowTextFlow )
927 aVertEnvironRect = rVertEnvironLayFrm.Prt();
928 aVertEnvironRect.Pos() += rVertEnvironLayFrm.Frm().Pos();
929 // OD 19.09.2003 #i18732# - adjust vertical 'virtual' anchor position
930 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
931 // to page areas.
932 if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
934 if ( bVert )
936 aPos.X() = aVertEnvironRect.Right();
938 else
940 aPos.Y() = aVertEnvironRect.Top();
944 else
946 ASSERT( rVertEnvironLayFrm.IsPageFrm(),
947 "<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
948 aVertEnvironRect = rVertEnvironLayFrm.Frm();
949 // OD 19.09.2003 #i18732# - adjustment vertical 'virtual' anchor position
950 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
951 // to page areas.
952 if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
954 if ( bVert )
956 aPos.X() = aVertEnvironRect.Right();
957 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
959 aPos.X() -= rVertEnvironLayFrm.GetRightMargin();
962 else
964 aPos.Y() = aVertEnvironRect.Top();
965 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
967 aPos.Y() += rVertEnvironLayFrm.GetTopMargin();
968 // add height of page header
969 const SwFrm* pTmpFrm = rVertEnvironLayFrm.Lower();
970 if ( pTmpFrm->IsHeaderFrm() )
972 aPos.Y() += pTmpFrm->Frm().Height();
979 // OD 12.11.2003 #i22341# - adjust vertical 'virtual' anchor position
980 // (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
981 // character and vertical aligned at character or top of line
982 // --> OD 2005-12-29 #125800#
983 // <pFrm>, which is the anchor frame or the proposed anchor frame,
984 // doesn't have to be a text frame (e.g. edit a to-page anchored
985 // fly frame). Thus, assure this.
986 const SwTxtFrm* pTxtFrm( dynamic_cast<const SwTxtFrm*>(pFrm) );
987 if ( pTxtFrm &&
988 _nAnchorId == FLY_AUTO_CNTNT &&
989 ( _eVertRelOrient == text::RelOrientation::CHAR ||
990 _eVertRelOrient == text::RelOrientation::TEXT_LINE ) )
992 SwTwips nTop = 0L;
993 if ( _eVertRelOrient == text::RelOrientation::CHAR )
995 SwRect aChRect;
996 if ( _pToCharCntntPos )
998 pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
1000 else
1002 // No content position provided. Thus, use a default one.
1003 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1004 pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
1006 nTop = (aChRect.*fnRect->fnGetBottom)();
1008 else
1010 if ( _pToCharCntntPos )
1012 pTxtFrm->GetTopOfLine( nTop, *_pToCharCntntPos );
1014 else
1016 // No content position provided. Thus, use a default one.
1017 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1018 pTxtFrm->GetTopOfLine( nTop, aDefaultCntntPos );
1021 if ( bVert )
1023 aPos.X() = nTop;
1025 else
1027 aPos.Y() = nTop;
1031 // --> OD 2004-10-05 #i26945# - adjust horizontal 'virtual' anchor
1032 // position (<aPos.X()> respectively <aPos.Y()>), if object is
1033 // anchored to character and horizontal aligned at character.
1034 if ( pTxtFrm &&
1035 _nAnchorId == FLY_AUTO_CNTNT &&
1036 _eHoriRelOrient == text::RelOrientation::CHAR )
1038 SwTwips nLeft = 0L;
1039 SwRect aChRect;
1040 if ( _pToCharCntntPos )
1042 pTxtFrm->GetAutoPos( aChRect, *_pToCharCntntPos );
1044 else
1046 // No content position provided. Thus, use a default one.
1047 SwPosition aDefaultCntntPos( *(pTxtFrm->GetTxtNode()) );
1048 pTxtFrm->GetAutoPos( aChRect, aDefaultCntntPos );
1050 nLeft = (aChRect.*fnRect->fnGetLeft)();
1051 if ( bVert )
1053 aPos.Y() = nLeft;
1055 else
1057 aPos.X() = nLeft;
1060 // <--
1062 if ( bVert )
1064 _orRect = SwRect( aVertEnvironRect.Left(),
1065 aHoriEnvironRect.Top(),
1066 aVertEnvironRect.Width(),
1067 aHoriEnvironRect.Height() );
1069 else
1071 _orRect = SwRect( aHoriEnvironRect.Left(),
1072 aVertEnvironRect.Top(),
1073 aHoriEnvironRect.Width(),
1074 aVertEnvironRect.Height() );
1077 else
1079 if( _opRef && pFly && pFly->IsFlyInCntFrm() )
1080 *_opRef = ( (SwFlyInCntFrm*)pFly )->GetRefPoint();
1082 _orRect = pUpper->Frm();
1083 if( !pUpper->IsBodyFrm() )
1085 _orRect += pUpper->Prt().Pos();
1086 _orRect.SSize( pUpper->Prt().SSize() );
1087 if ( pUpper->IsCellFrm() )//MA_FLY_HEIGHT
1089 const SwFrm* pTab = pUpper->FindTabFrm();
1090 long nBottom = (pTab->GetUpper()->*fnRect->fnGetPrtBottom)();
1091 (_orRect.*fnRect->fnSetBottom)( nBottom );
1094 // bei zeichengebundenen lieber nur 90% der Hoehe ausnutzen
1096 if( bVert )
1097 _orRect.Width( (_orRect.Width()*9)/10 );
1098 else
1099 _orRect.Height( (_orRect.Height()*9)/10 );
1103 const SwTwips nBaseOfstForFly = ( pFrm->IsTxtFrm() && pFly ) ?
1104 ((SwTxtFrm*)pFrm)->GetBaseOfstForFly( !bWrapThrough ) :
1106 if( bVert )
1108 bVertic = TRUE;
1109 _bMirror = false;
1111 switch ( _eHoriRelOrient )
1113 case text::RelOrientation::FRAME_RIGHT: aPos.Y() += pFrm->Prt().Height();
1114 aPos += (pFrm->Prt().*fnRect->fnGetPos)();
1115 break;
1116 case text::RelOrientation::PRINT_AREA: aPos += (pFrm->Prt().*fnRect->fnGetPos)();
1117 aPos.Y() += nBaseOfstForFly;
1118 break;
1119 case text::RelOrientation::PAGE_RIGHT: aPos.Y() = pPage->Frm().Top()
1120 + pPage->Prt().Bottom(); break;
1121 case text::RelOrientation::PAGE_PRINT_AREA: aPos.Y() = pPage->Frm().Top()
1122 + pPage->Prt().Top(); break;
1123 case text::RelOrientation::PAGE_LEFT:
1124 case text::RelOrientation::PAGE_FRAME: aPos.Y() = pPage->Frm().Top(); break;
1125 case text::RelOrientation::FRAME: aPos.Y() += nBaseOfstForFly; break;
1126 default: break;
1129 else if( _bMirror )
1131 switch ( _eHoriRelOrient )
1133 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Left(); break;
1134 case text::RelOrientation::FRAME:
1135 case text::RelOrientation::FRAME_LEFT: aPos.X() += pFrm->Frm().Width(); break;
1136 case text::RelOrientation::PRINT_AREA: aPos.X() += pFrm->Prt().Right(); break;
1137 case text::RelOrientation::PAGE_LEFT:
1138 case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Right(); break;
1139 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
1140 + pPage->Prt().Left(); break;
1141 default: break;
1144 else if ( bRTL )
1146 switch ( _eHoriRelOrient )
1148 case text::RelOrientation::FRAME_LEFT:
1149 aPos.X() = pFrm->Frm().Left() +
1150 pFrm->Prt().Left();
1151 break;
1153 case text::RelOrientation::PRINT_AREA:
1154 aPos.X() = pFrm->Frm().Left() + pFrm->Prt().Left() +
1155 pFrm->Prt().Width();
1156 aPos.X() += nBaseOfstForFly;
1157 break;
1159 case text::RelOrientation::PAGE_LEFT:
1160 aPos.X() = pPage->Frm().Left() + pPage->Prt().Left();
1161 break;
1163 case text::RelOrientation::PAGE_PRINT_AREA:
1164 aPos.X() = pPage->Frm().Left() + pPage->Prt().Left() +
1165 pPage->Prt().Width() ;
1166 break;
1168 case text::RelOrientation::PAGE_RIGHT:
1169 case text::RelOrientation::PAGE_FRAME:
1170 aPos.X() = pPage->Frm().Right();
1171 break;
1173 case text::RelOrientation::FRAME:
1174 aPos.X() += nBaseOfstForFly;
1175 break;
1176 default: break;
1179 else
1181 switch ( _eHoriRelOrient )
1183 case text::RelOrientation::FRAME_RIGHT: aPos.X() += pFrm->Prt().Width();
1184 aPos += pFrm->Prt().Pos();
1185 break;
1186 case text::RelOrientation::PRINT_AREA: aPos += pFrm->Prt().Pos();
1187 aPos.X() += nBaseOfstForFly;
1188 break;
1189 case text::RelOrientation::PAGE_RIGHT: aPos.X() = pPage->Frm().Left()
1190 + pPage->Prt().Right(); break;
1191 case text::RelOrientation::PAGE_PRINT_AREA: aPos.X() = pPage->Frm().Left()
1192 + pPage->Prt().Left(); break;
1193 case text::RelOrientation::PAGE_LEFT:
1194 case text::RelOrientation::PAGE_FRAME: aPos.X() = pPage->Frm().Left(); break;
1195 case text::RelOrientation::FRAME: aPos.X() += nBaseOfstForFly; break;
1196 default: break;
1201 if( !_opRef )
1203 if( bVertic )
1204 _orRect.Pos( aPos.X() - _orRect.Width() - _orRect.Left(), _orRect.Top() - aPos.Y() );
1205 else if ( bRTL )
1206 _orRect.Pos( - ( _orRect.Right() - aPos.X() ), _orRect.Top() - aPos.Y() );
1207 else
1208 _orRect.Pos( _orRect.Left() - aPos.X(), _orRect.Top() - aPos.Y() );
1209 if( _bMirror )
1210 _orRect.Pos( -_orRect.Right(), _orRect.Top() );
1214 Size SwFEShell::GetGraphicDefaultSize() const
1216 Size aRet;
1217 SwFlyFrm *pFly = FindFlyFrm();
1218 if ( pFly )
1220 // --> OD 2004-09-24 #i32951# - due to issue #i28701# no format of a
1221 // newly inserted Writer fly frame or its anchor frame is performed
1222 // any more. Thus, it could be possible (e.g. on insert of a horizontal
1223 // line) that the anchor frame isn't formatted and its printing area
1224 // size is (0,0). If this is the case the printing area of the upper
1225 // of the anchor frame is taken.
1226 const SwFrm* pAnchorFrm = pFly->GetAnchorFrm();
1227 aRet = pAnchorFrm->Prt().SSize();
1228 if ( aRet.Width() == 0 && aRet.Height() == 0 &&
1229 pAnchorFrm->GetUpper() )
1231 aRet = pAnchorFrm->GetUpper()->Prt().SSize();
1233 // <--
1235 SwRect aBound;
1236 CalcBoundRect( aBound, pFly->GetFmt()->GetAnchor().GetAnchorId());
1237 if ( pFly->GetAnchorFrm()->IsVertical() )
1238 aRet.Width() = aBound.Width();
1239 else
1240 aRet.Height() = aBound.Height();
1242 return aRet;
1244 /* -----------------------------12.08.2002 12:51------------------------------
1246 ---------------------------------------------------------------------------*/
1247 BOOL SwFEShell::IsFrmVertical(BOOL bEnvironment, BOOL& bRTL) const
1249 BOOL bVert = FALSE;
1250 bRTL = FALSE;
1252 if ( Imp()->HasDrawView() )
1254 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1255 if( rMrkList.GetMarkCount() != 1 )
1256 return bVert;
1258 SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1259 // --> OD 2006-01-06 #123831# - make code robust:
1260 if ( !pObj )
1262 ASSERT( false,
1263 "<SwFEShell::IsFrmVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation, please inform OD" );
1264 return bVert;
1266 // <--
1267 // OD 2004-03-29 #i26791#
1268 SwContact* pContact = static_cast<SwContact*>(GetUserCall( pObj ));
1269 // --> OD 2006-01-06 #123831# - make code robust:
1270 if ( !pContact )
1272 ASSERT( false,
1273 "<SwFEShell::IsFrmVertical(..)> - missing SwContact instance at marked object -> This is a serious situation, please inform OD" );
1274 return bVert;
1276 // <--
1277 const SwFrm* pRef = pContact->GetAnchoredObj( pObj )->GetAnchorFrm();
1278 // --> OD 2006-01-06 #123831# - make code robust:
1279 if ( !pRef )
1281 ASSERT( false,
1282 "<SwFEShell::IsFrmVertical(..)> - missing anchor frame at marked object -> This is a serious situation, please inform OD" );
1283 return bVert;
1285 // <--
1287 if ( pObj->ISA(SwVirtFlyDrawObj) && !bEnvironment )
1288 pRef = static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrm();
1290 bVert = pRef->IsVertical();
1291 bRTL = pRef->IsRightToLeft();
1294 return bVert;
1297 void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef&, const Point& )
1299 // does not do anything, only avoids crash if the method is used for wrong shell