nss: upgrade to release 3.73
[LibreOffice.git] / sw / source / core / frmedt / fews.cxx
blobfd1d137b15f46d7318b8aec1ac0c680bb84a9616
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/svdobj.hxx>
21 #include <comphelper/lok.hxx>
22 #include <init.hxx>
23 #include <fesh.hxx>
24 #include <tabcol.hxx>
25 #include <pagefrm.hxx>
26 #include <rootfrm.hxx>
27 #include <cntfrm.hxx>
28 #include <doc.hxx>
29 #include <frmtool.hxx>
30 #include <swtable.hxx>
31 #include <viewimp.hxx>
32 #include <dview.hxx>
33 #include <flyfrm.hxx>
34 #include <node.hxx>
35 #include <pam.hxx>
36 #include <sectfrm.hxx>
37 #include <fmtpdsc.hxx>
38 #include <fmtsrnd.hxx>
39 #include <fmtcntnt.hxx>
40 #include <fmtfsize.hxx>
41 #include <tabfrm.hxx>
42 #include <flyfrms.hxx>
43 #include <txtfrm.hxx>
44 #include <mdiexp.hxx>
45 #include <pagedesc.hxx>
46 #include <fmtanchr.hxx>
47 #include <environmentofanchoredobject.hxx>
48 #include <ndtxt.hxx>
49 #include <dflyobj.hxx>
50 #include <dcontact.hxx>
51 #include <UndoInsert.hxx>
53 using namespace com::sun::star;
55 namespace
57 /**
58 * This mutex is only used for the paste listeners, where the solar mutex can't
59 * be used.
61 osl::Mutex& GetPasteMutex()
63 static osl::Mutex aMutex;
64 return aMutex;
68 void SwFEShell::EndAllActionAndCall()
70 for(SwViewShell& rCurrentShell : GetRingContainer())
72 if( dynamic_cast<const SwCursorShell*>( &rCurrentShell) != nullptr )
74 static_cast<SwFEShell*>(&rCurrentShell)->EndAction();
75 static_cast<SwFEShell*>(&rCurrentShell)->CallChgLnk();
77 else
78 rCurrentShell.EndAction();
82 // Determine the Content's nearest to the point
83 Point SwFEShell::GetContentPos( const Point& rPoint, bool bNext ) const
85 CurrShell aCurr( const_cast<SwFEShell*>(this) );
86 return GetLayout()->GetNextPrevContentPos( rPoint, bNext );
89 const SwRect& SwFEShell::GetAnyCurRect( CurRectType eType, const Point* pPt,
90 const uno::Reference < embed::XEmbeddedObject >& xObj ) const
92 const SwFrame *pFrame = Imp()->HasDrawView()
93 ? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
94 const_cast<SwFEShell*>(this))
95 : nullptr;
97 if( !pFrame )
99 if( pPt )
101 SwPosition aPos( *GetCursor()->GetPoint() );
102 Point aPt( *pPt );
103 GetLayout()->GetModelPositionForViewPoint( &aPos, aPt );
104 SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
105 std::pair<Point, bool> const tmp(*pPt, true);
106 pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
108 else
110 const bool bOldCallbackActionEnabled = GetLayout()->IsCallbackActionEnabled();
111 if( bOldCallbackActionEnabled )
112 GetLayout()->SetCallbackActionEnabled( false );
113 pFrame = GetCurrFrame();
114 if( bOldCallbackActionEnabled )
115 GetLayout()->SetCallbackActionEnabled( true );
119 if( !pFrame )
120 return GetLayout()->getFrameArea();
122 bool bFrame = true;
123 switch ( eType )
125 case CurRectType::PagePrt: bFrame = false;
126 [[fallthrough]];
127 case CurRectType::Page : pFrame = pFrame->FindPageFrame();
128 break;
130 case CurRectType::PageCalc:
132 DisableCallbackAction a(const_cast<SwRootFrame&>(*pFrame->getRootFrame()));
133 pFrame->Calc(Imp()->GetShell()->GetOut());
134 pFrame = pFrame->FindPageFrame();
135 pFrame->Calc(Imp()->GetShell()->GetOut());
137 break;
139 case CurRectType::FlyEmbeddedPrt:
140 bFrame = false;
141 [[fallthrough]];
142 case CurRectType::FlyEmbedded:
144 const SwFrame *pFlyFrame = xObj.is() ? FindFlyFrame(xObj) : nullptr;
145 pFrame = pFlyFrame ? pFlyFrame
146 : pFrame->IsFlyFrame()
147 ? pFrame
148 : pFrame->FindFlyFrame();
149 break;
151 case CurRectType::SectionOutsideTable :
152 if( pFrame->IsInTab() )
153 pFrame = pFrame->FindTabFrame();
154 else {
155 OSL_FAIL( "Missing Table" );
157 [[fallthrough]];
158 case CurRectType::SectionPrt:
159 case CurRectType::Section:
160 if( pFrame->IsInSct() )
161 pFrame = pFrame->FindSctFrame();
162 else {
163 OSL_FAIL( "Missing section" );
166 if( CurRectType::SectionPrt == eType )
167 bFrame = false;
168 break;
170 case CurRectType::HeaderFooter:
171 pFrame = pFrame->FindFooterOrHeader();
172 if( nullptr == pFrame )
173 return GetLayout()->getFrameArea();
174 break;
176 case CurRectType::PagesArea:
177 return GetLayout()->GetPagesArea();
179 default: break;
181 return bFrame ? pFrame->getFrameArea() : pFrame->getFramePrintArea();
184 sal_uInt16 SwFEShell::GetPageNumber( const Point &rPoint ) const
186 const SwFrame *pPage = GetLayout()->Lower();
187 while ( pPage && !pPage->getFrameArea().IsInside( rPoint ) )
188 pPage = pPage->GetNext();
189 if ( pPage )
190 return static_cast<const SwPageFrame*>(pPage)->GetPhyPageNum();
191 else
192 return 0;
195 bool SwFEShell::GetPageNumber( tools::Long nYPos, bool bAtCursorPos, sal_uInt16& rPhyNum, sal_uInt16& rVirtNum, OUString &rDisplay) const
197 const SwFrame *pPage;
199 if ( bAtCursorPos ) // get page of Cursor
201 pPage = GetCurrFrame( false );
202 if ( pPage )
203 pPage = pPage->FindPageFrame();
205 else if ( nYPos > -1 ) // determine page via the position
207 pPage = GetLayout()->Lower();
208 while( pPage && (pPage->getFrameArea().Bottom() < nYPos ||
209 nYPos < pPage->getFrameArea().Top() ) )
210 pPage = pPage->GetNext();
212 else // first visible page
214 pPage = Imp()->GetFirstVisPage(GetOut());
215 if ( pPage && static_cast<const SwPageFrame*>(pPage)->IsEmptyPage() )
216 pPage = pPage->GetNext();
219 if( pPage )
221 rPhyNum = static_cast<const SwPageFrame*>(pPage)->GetPhyPageNum();
222 rVirtNum = static_cast<const SwPageFrame*>(pPage)->GetVirtPageNum();
223 const SvxNumberType& rNum = static_cast<const SwPageFrame*>(pPage)->GetPageDesc()->GetNumType();
224 rDisplay = rNum.GetNumStr( rVirtNum );
227 return nullptr != pPage;
230 bool SwFEShell::IsDirectlyInSection() const
232 SwFrame* pFrame = GetCurrFrame( false );
233 return pFrame && pFrame->GetUpper() && pFrame->GetUpper()->IsSctFrame();
236 FrameTypeFlags SwFEShell::GetFrameType( const Point *pPt, bool bStopAtFly ) const
238 FrameTypeFlags nReturn = FrameTypeFlags::NONE;
239 const SwFrame *pFrame;
240 if ( pPt )
242 SwPosition aPos( *GetCursor()->GetPoint() );
243 Point aPt( *pPt );
244 GetLayout()->GetModelPositionForViewPoint( &aPos, aPt );
245 SwContentNode *pNd = aPos.nNode.GetNode().GetContentNode();
246 std::pair<Point, bool> const tmp(*pPt, true);
247 pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
249 else
250 pFrame = GetCurrFrame( false );
251 while ( pFrame )
253 switch ( pFrame->GetType() )
255 case SwFrameType::Column:
256 if( pFrame->GetUpper()->IsSctFrame() )
258 // Check, if isn't not only a single column
259 // from a section with footnotes at the end.
260 if( pFrame->GetNext() || pFrame->GetPrev() )
261 // Sectioncolumns
262 nReturn |= ( nReturn & FrameTypeFlags::TABLE ) ?
263 FrameTypeFlags::COLSECTOUTTAB : FrameTypeFlags::COLSECT;
265 else // only pages and frame columns
266 nReturn |= FrameTypeFlags::COLUMN;
267 break;
268 case SwFrameType::Page:
269 nReturn |= FrameTypeFlags::PAGE;
270 if( static_cast<const SwPageFrame*>(pFrame)->IsFootnotePage() )
271 nReturn |= FrameTypeFlags::FTNPAGE;
272 break;
273 case SwFrameType::Header: nReturn |= FrameTypeFlags::HEADER; break;
274 case SwFrameType::Footer: nReturn |= FrameTypeFlags::FOOTER; break;
275 case SwFrameType::Body:
276 if( pFrame->GetUpper()->IsPageFrame() ) // not for ColumnFrames
277 nReturn |= FrameTypeFlags::BODY;
278 break;
279 case SwFrameType::Ftn: nReturn |= FrameTypeFlags::FOOTNOTE; break;
280 case SwFrameType::Fly:
281 if( static_cast<const SwFlyFrame*>(pFrame)->IsFlyLayFrame() )
282 nReturn |= FrameTypeFlags::FLY_FREE;
283 else if ( static_cast<const SwFlyFrame*>(pFrame)->IsFlyAtContentFrame() )
284 nReturn |= FrameTypeFlags::FLY_ATCNT;
285 else
287 OSL_ENSURE( static_cast<const SwFlyFrame*>(pFrame)->IsFlyInContentFrame(),
288 "New frametype?" );
289 nReturn |= FrameTypeFlags::FLY_INCNT;
291 nReturn |= FrameTypeFlags::FLY_ANY;
292 if( bStopAtFly )
293 return nReturn;
294 break;
295 case SwFrameType::Tab:
296 case SwFrameType::Row:
297 case SwFrameType::Cell: nReturn |= FrameTypeFlags::TABLE; break;
298 default: /* do nothing */ break;
300 if ( pFrame->IsFlyFrame() )
301 pFrame = static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame();
302 else
303 pFrame = pFrame->GetUpper();
305 return nReturn;
308 void SwFEShell::ShellGetFocus()
310 ::SetShell( this );
311 SwCursorShell::ShellGetFocus();
313 if ( HasDrawView() )
315 if (!comphelper::LibreOfficeKit::isActive())
316 Imp()->GetDrawView()->showMarkHandles();
317 if ( Imp()->GetDrawView()->AreObjectsMarked() )
318 FrameNotify( this, FLY_DRAG_START );
322 void SwFEShell::ShellLoseFocus()
324 SwCursorShell::ShellLoseFocus();
326 if ( HasDrawView() && Imp()->GetDrawView()->AreObjectsMarked() )
328 if (!comphelper::LibreOfficeKit::isActive())
329 Imp()->GetDrawView()->hideMarkHandles();
330 FrameNotify( this, FLY_DRAG_END );
334 sal_uInt16 SwFEShell::GetPhyPageNum() const
336 SwFrame *pFrame = GetCurrFrame();
337 if ( pFrame )
338 return pFrame->GetPhyPageNum();
339 return 0;
342 sal_uInt16 SwFEShell::GetVirtPageNum() const
344 SwFrame *pFrame = GetCurrFrame();
345 if ( pFrame )
346 return pFrame->GetVirtPageNum();
347 return 0;
350 static void lcl_SetAPageOffset( sal_uInt16 nOffset, SwPageFrame* pPage, SwFEShell* pThis )
352 pThis->StartAllAction();
353 OSL_ENSURE( pPage->FindFirstBodyContent(),
354 "SwFEShell _SetAPageOffset() without ContentFrame" );
356 SwFormatPageDesc aDesc( pPage->GetPageDesc() );
357 aDesc.SetNumOffset( nOffset );
359 SwFrame *pFrame = pThis->GetCurrFrame( false );
360 if ( pFrame->IsInTab() )
361 pThis->GetDoc()->SetAttr( aDesc, *pFrame->FindTabFrame()->GetFormat() );
362 else
364 pThis->GetDoc()->getIDocumentContentOperations().InsertPoolItem(
365 *pThis->GetCursor(), aDesc, SetAttrMode::DEFAULT, pThis->GetLayout());
368 pThis->EndAllAction();
371 void SwFEShell::SetNewPageOffset( sal_uInt16 nOffset )
373 GetLayout()->SetVirtPageNum( true );
374 const SwPageFrame *pPage = GetCurrFrame( false )->FindPageFrame();
375 lcl_SetAPageOffset( nOffset, const_cast<SwPageFrame*>(pPage), this );
378 void SwFEShell::SetPageOffset( sal_uInt16 nOffset )
380 const SwPageFrame *pPage = GetCurrFrame( false )->FindPageFrame();
381 const SwRootFrame* pDocLayout = GetLayout();
382 while ( pPage )
384 const SwFrame *pFlow = pPage->FindFirstBodyContent();
385 if ( pFlow )
387 if ( pFlow->IsInTab() )
388 pFlow = pFlow->FindTabFrame();
389 const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
390 if ( rPgDesc.GetNumOffset() )
392 pDocLayout->SetVirtPageNum( true );
393 lcl_SetAPageOffset( nOffset, const_cast<SwPageFrame*>(pPage), this );
394 break;
397 pPage = static_cast<const SwPageFrame*>(pPage->GetPrev());
401 sal_uInt16 SwFEShell::GetPageOffset() const
403 const SwPageFrame *pPage = GetCurrFrame()->FindPageFrame();
404 while ( pPage )
406 const SwFrame *pFlow = pPage->FindFirstBodyContent();
407 if ( pFlow )
409 if ( pFlow->IsInTab() )
410 pFlow = pFlow->FindTabFrame();
411 ::std::optional<sal_uInt16> oNumOffset = pFlow->GetPageDescItem().GetNumOffset();
412 if ( oNumOffset )
413 return *oNumOffset;
415 pPage = static_cast<const SwPageFrame*>(pPage->GetPrev());
417 return 0;
420 void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, const OUString& rSeparator,
421 const OUString& rNumberSeparator,
422 const bool bBefore, const sal_uInt16 nId,
423 const OUString& rCharacterStyle,
424 const bool bCpyBrd )
426 // get node index of cursor position, SwDoc can do everything else itself
427 SwContentFrame *pCnt = SwLabelType::Draw==eType ? nullptr : GetCurrFrame( false );
428 if( SwLabelType::Draw!=eType && !pCnt )
429 return;
431 StartAllAction();
432 SwRewriter aRewriter(SwUndoInsertLabel::CreateRewriter(rText));
433 StartUndo(SwUndoId::INSERTLABEL, &aRewriter);
435 sal_uLong nIdx = 0;
436 bool bInnerCntIsFly = false;
437 SwFlyFrameFormat* pFlyFormat = nullptr;
438 switch( eType )
440 case SwLabelType::Object:
441 case SwLabelType::Fly:
442 bInnerCntIsFly = pCnt->IsInFly();
443 if (bInnerCntIsFly)
445 // pass down index to the startnode for flys
446 nIdx = pCnt->FindFlyFrame()->
447 GetFormat()->GetContent().GetContentIdx()->GetIndex();
449 break;
450 case SwLabelType::Table:
451 if( pCnt->IsInTab() )
453 // pass down index to the TableNode for tables
454 const SwTable& rTable = *pCnt->FindTabFrame()->GetTable();
455 nIdx = rTable.GetTabSortBoxes()[ 0 ]
456 ->GetSttNd()->FindTableNode()->GetIndex();
458 break;
459 case SwLabelType::Draw:
460 if( Imp()->GetDrawView() )
462 SwDrawView *pDView = Imp()->GetDrawView();
463 const SdrMarkList& rMrkList = pDView->GetMarkedObjectList();
465 // copy marked drawing objects to
466 // local list to perform the corresponding action for each object
467 std::vector<SdrObject*> aDrawObjs;
469 for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
471 SdrObject* pDrawObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
472 if( pDrawObj )
473 aDrawObjs.push_back( pDrawObj );
476 // loop on marked drawing objects
477 while ( !aDrawObjs.empty() )
479 SdrObject* pDrawObj = aDrawObjs.back();
480 if ( dynamic_cast<const SwVirtFlyDrawObj*>( pDrawObj) == nullptr &&
481 dynamic_cast<const SwFlyDrawObj*>( pDrawObj) == nullptr )
483 SwFlyFrameFormat *pFormat =
484 GetDoc()->InsertDrawLabel( rText, rSeparator, rNumberSeparator, nId, rCharacterStyle, *pDrawObj );
485 if( !pFlyFormat )
486 pFlyFormat = pFormat;
489 aDrawObjs.pop_back();
493 break;
494 default:
495 OSL_ENSURE( false, "Cursor neither in table nor in fly." );
498 if( nIdx )
500 pFlyFormat = GetDoc()->InsertLabel(eType, rText, rSeparator,
501 rNumberSeparator, bBefore, nId,
502 nIdx, rCharacterStyle, bCpyBrd);
505 if (pFlyFormat)
507 const Point aPt(GetCursorDocPos());
508 if (SwFlyFrame* pFrame = pFlyFormat->GetFrame(&aPt))
509 SelectFlyFrame(*pFrame);
511 EndUndo();
512 EndAllActionAndCall();
516 bool SwFEShell::Sort(const SwSortOptions& rOpt)
518 if( !HasSelection() )
519 return false;
521 CurrShell aCurr( this );
522 bool bRet = false;
523 StartAllAction();
524 if(IsTableMode())
526 // Sort table
527 // check if Point/Mark of current Cursor are in one table
528 SwFrame *pFrame = GetCurrFrame( false );
529 OSL_ENSURE( pFrame->FindTabFrame(), "Cursor not in table." );
531 // search boxes via the layout
532 SwSelBoxes aBoxes;
533 GetTableSel(*this, aBoxes);
535 // The Cursor should be removed from the deletion area.
536 // Always put them behind/on the table; via the
537 // document position they will always be set to the old position
538 while( !pFrame->IsCellFrame() )
539 pFrame = pFrame->GetUpper();
541 /* ParkCursor->ParkCursorTab */
542 ParkCursorInTab();
545 // call sorting on document
546 bRet = mxDoc->SortTable(aBoxes, rOpt);
548 else
550 // Sort text nothing else
551 for(SwPaM& rPaM : GetCursor()->GetRingContainer())
553 SwPaM* pPam = &rPaM;
555 SwPosition* pStart = pPam->Start();
556 SwPosition* pEnd = pPam->End();
558 SwNodeIndex aPrevIdx( pStart->nNode, -1 );
559 sal_uLong nOffset = pEnd->nNode.GetIndex() - pStart->nNode.GetIndex();
560 const sal_Int32 nCntStt = pStart->nContent.GetIndex();
562 // Sorting
563 bRet = mxDoc->SortText(*pPam, rOpt);
565 // put selection again
566 pPam->DeleteMark();
567 pPam->GetPoint()->nNode.Assign( aPrevIdx.GetNode(), +1 );
568 SwContentNode* pCNd = pPam->GetContentNode();
569 sal_Int32 nLen = pCNd->Len();
570 if( nLen > nCntStt )
571 nLen = nCntStt;
572 pPam->GetPoint()->nContent.Assign(pCNd, nLen );
573 pPam->SetMark();
575 pPam->GetPoint()->nNode += nOffset;
576 pCNd = pPam->GetContentNode();
577 pPam->GetPoint()->nContent.Assign( pCNd, pCNd->Len() );
581 EndAllAction();
582 return bRet;
585 bool SwFEShell::IsColRightToLeft() const
587 SwFrame* pFrame = GetCurrFrame();
588 while (pFrame)
590 pFrame = pFrame->GetUpper();
591 if (pFrame && pFrame->IsColumnFrame())
593 return pFrame->IsRightToLeft();
596 return false;
599 sal_uInt16 SwFEShell::GetCurColNum_( const SwFrame *pFrame,
600 SwGetCurColNumPara* pPara )
602 sal_uInt16 nRet = 0;
603 while ( pFrame )
605 pFrame = pFrame->GetUpper();
606 if( pFrame && pFrame->IsColumnFrame() )
608 const SwFrame *pCurFrame = pFrame;
609 do {
610 ++nRet;
611 pFrame = pFrame->GetPrev();
612 } while ( pFrame );
614 if( pPara )
616 // now search the format, determining the columness
617 pFrame = pCurFrame->GetUpper();
618 while( pFrame )
620 if( ( SwFrameType::Page | SwFrameType::Fly | SwFrameType::Section ) & pFrame->GetType() )
622 pPara->pFrameFormat = static_cast<const SwLayoutFrame*>(pFrame)->GetFormat();
623 pPara->pPrtRect = &pFrame->getFramePrintArea();
624 break;
626 pFrame = pFrame->GetUpper();
628 if( !pFrame )
630 pPara->pFrameFormat = nullptr;
631 pPara->pPrtRect = nullptr;
634 break;
637 return nRet;
640 sal_uInt16 SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
642 OSL_ENSURE( GetCurrFrame(), "Cursor parked?" );
643 return GetCurColNum_( GetCurrFrame(), pPara );
646 sal_uInt16 SwFEShell::GetCurOutColNum() const
648 sal_uInt16 nRet = 0;
649 SwFrame* pFrame = GetCurrFrame();
650 OSL_ENSURE( pFrame, "Cursor parked?" );
651 if( pFrame )
653 pFrame = pFrame->IsInTab() ? static_cast<SwFrame*>(pFrame->FindTabFrame())
654 : static_cast<SwFrame*>(pFrame->FindSctFrame());
655 OSL_ENSURE( pFrame, "No Tab, no Sect" );
656 if( pFrame )
657 nRet = GetCurColNum_( pFrame, nullptr );
659 return nRet;
662 SwFEShell::SwFEShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOptions )
663 : SwEditShell( rDoc, pWindow, pOptions )
664 , m_bCheckForOLEInCaption(false)
665 , m_aPasteListeners(GetPasteMutex())
666 , m_eTableInsertMode(SwTable::SEARCH_NONE)
667 , m_bTableCopied(false)
671 SwFEShell::SwFEShell( SwEditShell& rShell, vcl::Window *pWindow )
672 : SwEditShell( rShell, pWindow )
673 , m_bCheckForOLEInCaption(false)
674 , m_aPasteListeners(GetPasteMutex())
675 , m_eTableInsertMode(SwTable::SEARCH_NONE)
676 , m_bTableCopied(false)
680 SwFEShell::~SwFEShell()
684 // #i17567# - adjustments for allowing
685 // negative vertical positions for fly frames anchored to paragraph/to character.
686 // #i22305# - adjustments for option 'Follow text flow'
687 // for to frame anchored objects.
688 // #i22341# - adjustments for vertical alignment at top of line
689 // for to character anchored objects.
690 void SwFEShell::CalcBoundRect( SwRect& _orRect,
691 const RndStdIds _nAnchorId,
692 const sal_Int16 _eHoriRelOrient,
693 const sal_Int16 _eVertRelOrient,
694 const SwPosition* _pToCharContentPos,
695 const bool _bFollowTextFlow,
696 bool _bMirror,
697 Point* _opRef,
698 Size* _opPercent,
699 const SwFormatFrameSize* pFormatFrameSize) const
701 const SwFrame* pFrame;
702 const SwFlyFrame* pFly;
703 if( _opRef )
705 pFrame = GetCurrFrame();
706 pFly = pFrame->FindFlyFrame();
707 if( nullptr != pFly )
708 pFrame = pFly->GetAnchorFrame();
710 else
712 pFly = GetSelectedFlyFrame();
713 pFrame = pFly ? pFly->GetAnchorFrame() : GetCurrFrame();
716 bool bWrapThrough = false;
717 if ( pFly )
719 SwFlyFrameFormat* pFormat = const_cast<SwFlyFrameFormat*>(pFly->GetFormat());
720 const SwFormatSurround& rSurround = pFormat->GetSurround();
721 bWrapThrough = rSurround.GetSurround() == css::text::WrapTextMode_THROUGH;
724 const SwPageFrame* pPage = pFrame->FindPageFrame();
725 _bMirror = _bMirror && !pPage->OnRightPage();
727 Point aPos;
728 bool bVertic = false;
729 bool bRTL = false;
730 bool bVerticalL2R = false;
732 if ((RndStdIds::FLY_AT_PAGE == _nAnchorId) || (RndStdIds::FLY_AT_FLY == _nAnchorId)) // LAYER_IMPL
734 const SwFrame* pTmp = pFrame;
735 // #i22305#
736 if ((RndStdIds::FLY_AT_PAGE == _nAnchorId) ||
737 ((RndStdIds::FLY_AT_FLY == _nAnchorId) && !_bFollowTextFlow))
739 pFrame = pPage;
741 else
743 pFrame = pFrame->FindFlyFrame();
745 if ( !pFrame )
746 pFrame = pTmp;
747 _orRect = pFrame->getFrameArea();
748 SwRectFnSet aRectFnSet(pFrame);
749 bRTL = pFrame->IsRightToLeft();
750 if ( bRTL )
751 aPos = pFrame->getFrameArea().TopRight();
752 else
753 aPos = aRectFnSet.GetPos(pFrame->getFrameArea());
755 if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
757 bVertic = aRectFnSet.IsVert();
758 bVerticalL2R = aRectFnSet.IsVertL2R();
759 _bMirror = false; // no mirroring in vertical environment
760 switch ( _eHoriRelOrient )
762 case text::RelOrientation::PAGE_RIGHT:
763 case text::RelOrientation::FRAME_RIGHT: aPos.AdjustY(pFrame->getFramePrintArea().Height() );
764 [[fallthrough]];
765 case text::RelOrientation::PRINT_AREA:
766 case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustY(pFrame->getFramePrintArea().Top() ); break;
767 default: break;
770 else if ( _bMirror )
772 switch ( _eHoriRelOrient )
774 case text::RelOrientation::PRINT_AREA:
775 case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
776 [[fallthrough]];
777 case text::RelOrientation::PAGE_RIGHT:
778 case text::RelOrientation::FRAME_RIGHT: aPos.AdjustX(pFrame->getFramePrintArea().Left() ); break;
779 default: aPos.AdjustX(pFrame->getFrameArea().Width() );
782 else if ( bRTL )
784 switch ( _eHoriRelOrient )
786 case text::RelOrientation::PRINT_AREA:
787 case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
788 [[fallthrough]];
789 case text::RelOrientation::PAGE_LEFT:
790 case text::RelOrientation::FRAME_LEFT: aPos.AdjustX(pFrame->getFramePrintArea().Left() -
791 pFrame->getFrameArea().Width() ); break;
792 default: break;
795 else
797 switch ( _eHoriRelOrient )
799 case text::RelOrientation::PAGE_RIGHT:
800 case text::RelOrientation::FRAME_RIGHT: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
801 [[fallthrough]];
802 case text::RelOrientation::PRINT_AREA:
803 case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Left() ); break;
804 default:break;
808 if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
810 switch ( _eVertRelOrient )
812 case text::RelOrientation::PRINT_AREA:
813 case text::RelOrientation::PAGE_PRINT_AREA:
815 aPos.AdjustX( -(pFrame->GetRightMargin()) );
817 break;
820 else if ( aRectFnSet.IsVertL2R() )
822 switch ( _eVertRelOrient )
824 case text::RelOrientation::PRINT_AREA:
825 case text::RelOrientation::PAGE_PRINT_AREA:
827 aPos.AdjustX(pFrame->GetLeftMargin() );
829 break;
832 else
834 switch ( _eVertRelOrient )
836 case text::RelOrientation::PRINT_AREA:
837 case text::RelOrientation::PAGE_PRINT_AREA:
839 if ( pFrame->IsPageFrame() )
841 aPos.setY(
842 static_cast<const SwPageFrame*>(pFrame)->PrtWithoutHeaderAndFooter().Top() );
844 else
846 aPos.AdjustY(pFrame->getFramePrintArea().Top() );
849 break;
852 if ( _opPercent )
853 *_opPercent = pFrame->getFramePrintArea().SSize();
855 else
857 const SwFrame* pUpper = ( pFrame->IsPageFrame() || pFrame->IsFlyFrame() ) ?
858 pFrame : pFrame->GetUpper();
859 SwRectFnSet aRectFnSet(pUpper);
860 if ( _opPercent )
862 // If the size is relative from page, then full size should be counted from the page frame.
863 if (pFormatFrameSize && pFormatFrameSize->GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
864 _opPercent->setWidth(pPage->getFrameArea().Width());
865 else
866 _opPercent->setWidth(pUpper->getFramePrintArea().Width());
868 if (pFormatFrameSize && pFormatFrameSize->GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
869 // If the size is relative from page, then full size should be counted from the page frame.
870 _opPercent->setHeight(pPage->getFrameArea().Height());
871 else
872 _opPercent->setHeight(pUpper->getFramePrintArea().Height());
875 bRTL = pFrame->IsRightToLeft();
876 if ( bRTL )
877 aPos = pFrame->getFrameArea().TopRight();
878 else
879 aPos = aRectFnSet.GetPos(pFrame->getFrameArea());
880 // #i17567# - allow negative positions
881 // for fly frames anchor to paragraph/to character.
882 if ((_nAnchorId == RndStdIds::FLY_AT_PARA) || (_nAnchorId == RndStdIds::FLY_AT_CHAR))
884 // The rectangle, the fly frame can be positioned in, is determined
885 // horizontally by the frame area of the horizontal environment
886 // and vertically by the printing area of the vertical environment,
887 // if the object follows the text flow, or by the frame area of the
888 // vertical environment, if the object doesn't follow the text flow.
889 // new class <SwEnvironmentOfAnchoredObject>
890 objectpositioning::SwEnvironmentOfAnchoredObject aEnvOfObj(
891 _bFollowTextFlow );
892 const SwLayoutFrame& rHoriEnvironLayFrame =
893 aEnvOfObj.GetHoriEnvironmentLayoutFrame( *pFrame );
894 const SwLayoutFrame& rVertEnvironLayFrame =
895 aEnvOfObj.GetVertEnvironmentLayoutFrame( *pFrame );
896 const SwRect& aHoriEnvironRect( rHoriEnvironLayFrame.getFrameArea() );
897 SwRect aVertEnvironRect;
898 if ( _bFollowTextFlow )
900 aVertEnvironRect = rVertEnvironLayFrame.getFramePrintArea();
901 aVertEnvironRect.Pos() += rVertEnvironLayFrame.getFrameArea().Pos();
902 // #i18732# - adjust vertical 'virtual' anchor position
903 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
904 // to page areas.
905 if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
907 if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
909 aPos.setX( aVertEnvironRect.Right() );
911 else if ( aRectFnSet.IsVertL2R() )
913 aPos.setX( aVertEnvironRect.Left() );
915 else
917 aPos.setY( aVertEnvironRect.Top() );
921 else
923 OSL_ENSURE( rVertEnvironLayFrame.IsPageFrame(),
924 "<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
925 aVertEnvironRect = rVertEnvironLayFrame.getFrameArea();
926 // #i18732# - adjustment vertical 'virtual' anchor position
927 // (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
928 // to page areas.
929 if (_eVertRelOrient == text::RelOrientation::PAGE_FRAME
930 || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA
931 || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
933 if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
935 aPos.setX( aVertEnvironRect.Right() );
936 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
938 aPos.setX(aPos.getX() - rVertEnvironLayFrame.GetRightMargin());
941 else if ( aRectFnSet.IsVertL2R() )
943 aPos.setX( aVertEnvironRect.Left() );
944 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
946 aPos.setX(aPos.getX() + rVertEnvironLayFrame.GetLeftMargin());
949 else
951 aPos.setY( aVertEnvironRect.Top() );
952 if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
954 aPos.setY(aPos.getY() + rVertEnvironLayFrame.GetTopMargin());
955 // add height of page header
956 const SwFrame* pTmpFrame = rVertEnvironLayFrame.Lower();
957 if ( pTmpFrame->IsHeaderFrame() )
959 aPos.setY(aPos.getY() + pTmpFrame->getFrameArea().Height());
962 else if (_eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
964 if (rVertEnvironLayFrame.IsPageFrame())
966 auto& rPageFrame = static_cast<const SwPageFrame&>(rVertEnvironLayFrame);
967 aPos.setY(rPageFrame.PrtWithoutHeaderAndFooter().Bottom());
969 else
971 aPos.AdjustY(rVertEnvironLayFrame.getFramePrintArea().Bottom());
978 // #i22341# - adjust vertical 'virtual' anchor position
979 // (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
980 // character and vertical aligned at character or top of line
981 // <pFrame>, 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 SwTextFrame* pTextFrame( dynamic_cast<const SwTextFrame*>(pFrame) );
985 if ( pTextFrame &&
986 (_nAnchorId == RndStdIds::FLY_AT_CHAR) &&
987 ( _eVertRelOrient == text::RelOrientation::CHAR ||
988 _eVertRelOrient == text::RelOrientation::TEXT_LINE ) )
990 SwTwips nTop = 0;
991 if ( _eVertRelOrient == text::RelOrientation::CHAR )
993 SwRect aChRect;
994 if ( _pToCharContentPos )
996 pTextFrame->GetAutoPos( aChRect, *_pToCharContentPos );
998 else
1000 // No content position provided. Thus, use a default one.
1001 SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
1002 pTextFrame->GetAutoPos( aChRect, aDefaultContentPos );
1004 nTop = aRectFnSet.GetBottom(aChRect);
1006 else
1008 if ( _pToCharContentPos )
1010 pTextFrame->GetTopOfLine( nTop, *_pToCharContentPos );
1012 else
1014 // No content position provided. Thus, use a default one.
1015 SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
1016 pTextFrame->GetTopOfLine( nTop, aDefaultContentPos );
1019 if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
1021 aPos.setX(nTop);
1023 else
1025 aPos.setY(nTop);
1029 // #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 ( pTextFrame &&
1033 (_nAnchorId == RndStdIds::FLY_AT_CHAR) &&
1034 _eHoriRelOrient == text::RelOrientation::CHAR )
1036 SwTwips nLeft = 0;
1037 SwRect aChRect;
1038 if ( _pToCharContentPos )
1040 pTextFrame->GetAutoPos( aChRect, *_pToCharContentPos );
1042 else
1044 // No content position provided. Thus, use a default one.
1045 SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
1046 pTextFrame->GetAutoPos( aChRect, aDefaultContentPos );
1048 nLeft = aRectFnSet.GetLeft(aChRect);
1049 if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
1051 aPos.setY(nLeft);
1053 else
1055 aPos.setX(nLeft);
1058 if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
1060 _orRect = SwRect( aVertEnvironRect.Left(),
1061 aHoriEnvironRect.Top(),
1062 aVertEnvironRect.Width(),
1063 aHoriEnvironRect.Height() );
1065 else
1067 _orRect = SwRect( aHoriEnvironRect.Left(),
1068 aVertEnvironRect.Top(),
1069 aHoriEnvironRect.Width(),
1070 aVertEnvironRect.Height() );
1073 else
1075 if( _opRef && pFly && pFly->IsFlyInContentFrame() )
1076 *_opRef = static_cast<const SwFlyInContentFrame*>( pFly )->GetRefPoint();
1078 _orRect = pUpper->getFrameArea();
1079 if( !pUpper->IsBodyFrame() )
1081 _orRect += pUpper->getFramePrintArea().Pos();
1082 _orRect.SSize( pUpper->getFramePrintArea().SSize() );
1083 if ( pUpper->IsCellFrame() )//MA_FLY_HEIGHT
1085 const SwFrame* pTab = pUpper->FindTabFrame();
1086 tools::Long nBottom = aRectFnSet.GetPrtBottom(*pTab->GetUpper());
1087 aRectFnSet.SetBottom( _orRect, nBottom );
1090 // only use 90% of height for character bound
1092 if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
1093 _orRect.Width( (_orRect.Width()*9)/10 );
1094 else
1095 _orRect.Height( (_orRect.Height()*9)/10 );
1099 const SwTwips nBaseOfstForFly = ( pFrame->IsTextFrame() && pFly ) ?
1100 static_cast<const SwTextFrame*>(pFrame)->GetBaseOffsetForFly( !bWrapThrough ) :
1102 if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
1104 bVertic = aRectFnSet.IsVert();
1105 bVerticalL2R = aRectFnSet.IsVertL2R();
1106 _bMirror = false;
1108 switch ( _eHoriRelOrient )
1110 case text::RelOrientation::FRAME_RIGHT:
1112 aPos.setY(aPos.getY() + pFrame->getFramePrintArea().Height());
1113 aPos += aRectFnSet.GetPos(pFrame->getFramePrintArea());
1114 break;
1116 case text::RelOrientation::PRINT_AREA:
1118 aPos += aRectFnSet.GetPos(pFrame->getFramePrintArea());
1119 aPos.setY(aPos.getY() + nBaseOfstForFly);
1120 break;
1122 case text::RelOrientation::PAGE_RIGHT:
1124 aPos.setY(pPage->getFrameArea().Top() + pPage->getFramePrintArea().Bottom());
1125 break;
1127 case text::RelOrientation::PAGE_PRINT_AREA:
1129 aPos.setY(pPage->getFrameArea().Top() + pPage->getFramePrintArea().Top());
1130 break;
1132 case text::RelOrientation::PAGE_LEFT:
1133 case text::RelOrientation::PAGE_FRAME:
1135 aPos.setY(pPage->getFrameArea().Top());
1136 break;
1138 case text::RelOrientation::FRAME:
1140 aPos.setY(aPos.getY() + nBaseOfstForFly);
1141 break;
1143 default: break;
1146 else if( _bMirror )
1148 switch ( _eHoriRelOrient )
1150 case text::RelOrientation::FRAME_RIGHT: aPos.setX(aPos.getX() + pFrame->getFramePrintArea().Left()); break;
1151 case text::RelOrientation::FRAME:
1152 case text::RelOrientation::FRAME_LEFT: aPos.setX(aPos.getX() + pFrame->getFrameArea().Width()); break;
1153 case text::RelOrientation::PRINT_AREA: aPos.setX(aPos.getX() + pFrame->getFramePrintArea().Right()); break;
1154 case text::RelOrientation::PAGE_LEFT:
1155 case text::RelOrientation::PAGE_FRAME: aPos.setX(pPage->getFrameArea().Right()); break;
1156 case text::RelOrientation::PAGE_PRINT_AREA: aPos.setX(pPage->getFrameArea().Left()
1157 + pPage->getFramePrintArea().Left()); break;
1158 default: break;
1161 else if ( bRTL )
1163 switch ( _eHoriRelOrient )
1165 case text::RelOrientation::FRAME_LEFT:
1166 aPos.setX(pFrame->getFrameArea().Left() +
1167 pFrame->getFramePrintArea().Left());
1168 break;
1170 case text::RelOrientation::PRINT_AREA:
1171 aPos.setX(pFrame->getFrameArea().Left() + pFrame->getFramePrintArea().Left() +
1172 pFrame->getFramePrintArea().Width());
1173 aPos.setX(aPos.getX() + nBaseOfstForFly);
1174 break;
1176 case text::RelOrientation::PAGE_LEFT:
1177 aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left());
1178 break;
1180 case text::RelOrientation::PAGE_PRINT_AREA:
1181 aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left() +
1182 pPage->getFramePrintArea().Width());
1183 break;
1185 case text::RelOrientation::PAGE_RIGHT:
1186 case text::RelOrientation::PAGE_FRAME:
1187 aPos.setX(pPage->getFrameArea().Right());
1188 break;
1190 case text::RelOrientation::FRAME:
1191 aPos.setX(aPos.getX() + nBaseOfstForFly);
1192 break;
1193 default: break;
1196 else
1198 switch ( _eHoriRelOrient )
1200 case text::RelOrientation::FRAME_RIGHT:
1201 aPos.AdjustX(pFrame->getFramePrintArea().Width() );
1202 aPos += pFrame->getFramePrintArea().Pos();
1203 break;
1204 case text::RelOrientation::PRINT_AREA:
1205 aPos += pFrame->getFramePrintArea().Pos();
1206 aPos.setX(aPos.getX() + nBaseOfstForFly);
1207 break;
1208 case text::RelOrientation::PAGE_RIGHT:
1209 aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Right());
1210 break;
1211 case text::RelOrientation::PAGE_PRINT_AREA:
1212 aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left());
1213 break;
1214 case text::RelOrientation::PAGE_LEFT:
1215 case text::RelOrientation::PAGE_FRAME:
1216 aPos.setX(pPage->getFrameArea().Left());
1217 break;
1218 case text::RelOrientation::FRAME:
1219 aPos.setX(aPos.getX() + nBaseOfstForFly);
1220 break;
1221 default: break;
1226 if( _opRef )
1227 return;
1229 if( bVertic && !bVerticalL2R )
1230 _orRect.Pos( aPos.getX() - _orRect.Width() - _orRect.Left(), _orRect.Top() - aPos.getY() );
1231 else if( bVerticalL2R )
1232 _orRect.Pos( _orRect.Left() - aPos.getX(), _orRect.Top() - aPos.getY() );
1233 else if ( bRTL )
1234 _orRect.Pos( - ( _orRect.Right() - aPos.getX() ), _orRect.Top() - aPos.getY() );
1235 else
1236 _orRect.Pos( _orRect.Left() - aPos.getX(), _orRect.Top() - aPos.getY() );
1237 if( _bMirror )
1238 _orRect.Pos( -_orRect.Right(), _orRect.Top() );
1241 Size SwFEShell::GetGraphicDefaultSize() const
1243 Size aRet;
1244 SwFlyFrame *pFly = GetSelectedFlyFrame();
1245 if ( pFly )
1247 // #i32951# - due to issue #i28701# no format of a
1248 // newly inserted Writer fly frame or its anchor frame is performed
1249 // any more. Thus, it could be possible (e.g. on insert of a horizontal
1250 // line) that the anchor frame isn't formatted and its printing area
1251 // size is (0,0). If this is the case the printing area of the upper
1252 // of the anchor frame is taken.
1253 const SwFrame* pAnchorFrame = pFly->GetAnchorFrame();
1254 aRet = pAnchorFrame->getFramePrintArea().SSize();
1255 if ( aRet.IsEmpty() && pAnchorFrame->GetUpper() )
1257 aRet = pAnchorFrame->GetUpper()->getFramePrintArea().SSize();
1260 SwRect aBound;
1261 CalcBoundRect( aBound, pFly->GetFormat()->GetAnchor().GetAnchorId());
1262 if ( pFly->GetAnchorFrame()->IsVertical() )
1263 aRet.setWidth( aBound.Width() );
1264 else
1265 aRet.setHeight( aBound.Height() );
1267 return aRet;
1270 bool SwFEShell::IsFrameVertical(const bool bEnvironment, bool& bRTL, bool& bVertL2R) const
1272 bool bVert = false;
1273 bRTL = false;
1274 bVertL2R = false;
1276 if ( Imp()->HasDrawView() )
1278 const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
1279 if( rMrkList.GetMarkCount() != 1 )
1280 return bVert;
1282 SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
1283 if ( !pObj )
1285 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation" );
1286 return bVert;
1288 // #i26791#
1289 SwContact* pContact = GetUserCall( pObj );
1290 if ( !pContact )
1292 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SwContact instance at marked object -> This is a serious situation" );
1293 return bVert;
1295 const SwFrame* pRef = pContact->GetAnchoredObj( pObj )->GetAnchorFrame();
1296 if ( !pRef )
1298 OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing anchor frame at marked object -> This is a serious situation" );
1299 return bVert;
1302 if ( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) != nullptr && !bEnvironment )
1303 pRef = static_cast<const SwVirtFlyDrawObj*>(pObj)->GetFlyFrame();
1305 bVert = pRef->IsVertical();
1306 bRTL = pRef->IsRightToLeft();
1307 bVertL2R = pRef->IsVertLR();
1310 return bVert;
1313 void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef&, const Point& )
1315 // does not do anything, only avoids crash if the method is used for wrong shell
1318 void SwFEShell::ToggleHeaderFooterEdit()
1320 // Clear objects selection
1321 if ( Imp()->GetDrawView()->AreObjectsMarked() )
1323 Imp()->GetDrawView()->UnmarkAll();
1324 ClearMark();
1327 SwCursorShell::ToggleHeaderFooterEdit();
1330 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */