1356 lines
49 KiB
C++
1356 lines
49 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
#include <svx/svdobj.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <comphelper/lok.hxx>
|
|
#include <init.hxx>
|
|
#include <fesh.hxx>
|
|
#include <tabcol.hxx>
|
|
#include <pagefrm.hxx>
|
|
#include <rootfrm.hxx>
|
|
#include <cntfrm.hxx>
|
|
#include <doc.hxx>
|
|
#include <frmtool.hxx>
|
|
#include <swtable.hxx>
|
|
#include <viewimp.hxx>
|
|
#include <dview.hxx>
|
|
#include <flyfrm.hxx>
|
|
#include <node.hxx>
|
|
#include <pam.hxx>
|
|
#include <sectfrm.hxx>
|
|
#include <fmtpdsc.hxx>
|
|
#include <fmtsrnd.hxx>
|
|
#include <fmtcntnt.hxx>
|
|
#include <fmtfsize.hxx>
|
|
#include <tabfrm.hxx>
|
|
#include <flyfrms.hxx>
|
|
#include <txtfrm.hxx>
|
|
#include <mdiexp.hxx>
|
|
#include <pagedesc.hxx>
|
|
#include <fmtanchr.hxx>
|
|
#include <environmentofanchoredobject.hxx>
|
|
#include <ndtxt.hxx>
|
|
#include <dflyobj.hxx>
|
|
#include <dcontact.hxx>
|
|
#include <UndoInsert.hxx>
|
|
#include <formatflysplit.hxx>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
namespace
|
|
{
|
|
/**
|
|
* This mutex is only used for the paste listeners, where the solar mutex can't
|
|
* be used.
|
|
*/
|
|
osl::Mutex& GetPasteMutex()
|
|
{
|
|
static osl::Mutex aMutex;
|
|
return aMutex;
|
|
}
|
|
}
|
|
|
|
void SwFEShell::EndAllActionAndCall()
|
|
{
|
|
for(SwViewShell& rCurrentShell : GetRingContainer())
|
|
{
|
|
if( dynamic_cast<const SwCursorShell*>( &rCurrentShell) != nullptr )
|
|
{
|
|
static_cast<SwFEShell*>(&rCurrentShell)->EndAction();
|
|
static_cast<SwFEShell*>(&rCurrentShell)->CallChgLnk();
|
|
}
|
|
else
|
|
rCurrentShell.EndAction();
|
|
}
|
|
}
|
|
|
|
// Determine the Content's nearest to the point
|
|
Point SwFEShell::GetContentPos( const Point& rPoint, bool bNext ) const
|
|
{
|
|
CurrShell aCurr( const_cast<SwFEShell*>(this) );
|
|
return GetLayout()->GetNextPrevContentPos( rPoint, bNext );
|
|
}
|
|
|
|
const SwRect& SwFEShell::GetAnyCurRect( CurRectType eType, const Point* pPt,
|
|
const uno::Reference < embed::XEmbeddedObject >& xObj ) const
|
|
{
|
|
const SwFrame *pFrame = Imp()->HasDrawView()
|
|
? ::GetFlyFromMarked( &Imp()->GetDrawView()->GetMarkedObjectList(),
|
|
const_cast<SwFEShell*>(this))
|
|
: nullptr;
|
|
|
|
if( !pFrame )
|
|
{
|
|
if( pPt )
|
|
{
|
|
SwPosition aPos( *GetCursor()->GetPoint() );
|
|
Point aPt( *pPt );
|
|
GetLayout()->GetModelPositionForViewPoint( &aPos, aPt );
|
|
SwContentNode *pNd = aPos.GetNode().GetContentNode();
|
|
std::pair<Point, bool> const tmp(*pPt, true);
|
|
pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
|
|
}
|
|
else
|
|
{
|
|
const bool bOldCallbackActionEnabled = GetLayout()->IsCallbackActionEnabled();
|
|
if( bOldCallbackActionEnabled )
|
|
GetLayout()->SetCallbackActionEnabled( false );
|
|
pFrame = GetCurrFrame();
|
|
if( bOldCallbackActionEnabled )
|
|
GetLayout()->SetCallbackActionEnabled( true );
|
|
}
|
|
}
|
|
|
|
if( !pFrame )
|
|
return GetLayout()->getFrameArea();
|
|
|
|
bool bFrame = true;
|
|
switch ( eType )
|
|
{
|
|
case CurRectType::PagePrt:
|
|
bFrame = false;
|
|
[[fallthrough]];
|
|
case CurRectType::Page :
|
|
pFrame = pFrame->FindPageFrame();
|
|
break;
|
|
case CurRectType::PageCalc:
|
|
{
|
|
DisableCallbackAction a(const_cast<SwRootFrame&>(*pFrame->getRootFrame()));
|
|
pFrame->Calc(Imp()->GetShell()->GetOut());
|
|
pFrame = pFrame->FindPageFrame();
|
|
pFrame->Calc(Imp()->GetShell()->GetOut());
|
|
}
|
|
break;
|
|
case CurRectType::FlyEmbeddedPrt:
|
|
bFrame = false;
|
|
[[fallthrough]];
|
|
case CurRectType::FlyEmbedded:
|
|
{
|
|
const SwFrame *pFlyFrame = xObj.is() ? FindFlyFrame(xObj) : nullptr;
|
|
pFrame = pFlyFrame ? pFlyFrame
|
|
: pFrame->IsFlyFrame()
|
|
? pFrame
|
|
: pFrame->FindFlyFrame();
|
|
break;
|
|
}
|
|
case CurRectType::SectionOutsideTable :
|
|
if( pFrame->IsInTab() )
|
|
pFrame = pFrame->FindTabFrame();
|
|
else {
|
|
OSL_FAIL( "Missing Table" );
|
|
}
|
|
[[fallthrough]];
|
|
case CurRectType::SectionPrt:
|
|
case CurRectType::Section:
|
|
if( pFrame->IsInSct() )
|
|
pFrame = pFrame->FindSctFrame();
|
|
else {
|
|
OSL_FAIL( "Missing section" );
|
|
}
|
|
|
|
if( CurRectType::SectionPrt == eType )
|
|
bFrame = false;
|
|
break;
|
|
case CurRectType::HeaderFooter:
|
|
pFrame = pFrame->FindFooterOrHeader();
|
|
if( nullptr == pFrame )
|
|
return GetLayout()->getFrameArea();
|
|
break;
|
|
case CurRectType::PagesArea:
|
|
return GetLayout()->GetPagesArea();
|
|
default:
|
|
break;
|
|
}
|
|
return bFrame ? pFrame->getFrameArea() : pFrame->getFramePrintArea();
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetPageNumber( const Point &rPoint ) const
|
|
{
|
|
const SwFrame *pPage = GetLayout()->Lower();
|
|
while ( pPage && !pPage->getFrameArea().Contains( rPoint ) )
|
|
pPage = pPage->GetNext();
|
|
if ( pPage )
|
|
return static_cast<const SwPageFrame*>(pPage)->GetPhyPageNum();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
bool SwFEShell::GetPageNumber( tools::Long nYPos, bool bAtCursorPos, sal_uInt16& rPhyNum, sal_uInt16& rVirtNum, OUString &rDisplay) const
|
|
{
|
|
const SwFrame *pPage;
|
|
|
|
if ( bAtCursorPos ) // get page of Cursor
|
|
{
|
|
pPage = GetCurrFrame( false );
|
|
if ( pPage )
|
|
pPage = pPage->FindPageFrame();
|
|
}
|
|
else if ( nYPos > -1 ) // determine page via the position
|
|
{
|
|
pPage = GetLayout()->Lower();
|
|
while( pPage && (pPage->getFrameArea().Bottom() < nYPos ||
|
|
nYPos < pPage->getFrameArea().Top() ) )
|
|
pPage = pPage->GetNext();
|
|
}
|
|
else // first visible page
|
|
{
|
|
pPage = Imp()->GetFirstVisPage(GetOut());
|
|
if ( pPage && static_cast<const SwPageFrame*>(pPage)->IsEmptyPage() )
|
|
pPage = pPage->GetNext();
|
|
}
|
|
|
|
if( pPage )
|
|
{
|
|
rPhyNum = static_cast<const SwPageFrame*>(pPage)->GetPhyPageNum();
|
|
rVirtNum = static_cast<const SwPageFrame*>(pPage)->GetVirtPageNum();
|
|
const SvxNumberType& rNum = static_cast<const SwPageFrame*>(pPage)->GetPageDesc()->GetNumType();
|
|
rDisplay = rNum.GetNumStr( rVirtNum );
|
|
}
|
|
|
|
return nullptr != pPage;
|
|
}
|
|
|
|
bool SwFEShell::IsDirectlyInSection() const
|
|
{
|
|
SwFrame* pFrame = GetCurrFrame( false );
|
|
return pFrame && pFrame->GetUpper() && pFrame->GetUpper()->IsSctFrame();
|
|
}
|
|
|
|
FrameTypeFlags SwFEShell::GetFrameType( const Point *pPt, bool bStopAtFly ) const
|
|
{
|
|
FrameTypeFlags nReturn = FrameTypeFlags::NONE;
|
|
const SwFrame *pFrame;
|
|
if ( pPt )
|
|
{
|
|
SwPosition aPos( *GetCursor()->GetPoint() );
|
|
Point aPt( *pPt );
|
|
GetLayout()->GetModelPositionForViewPoint( &aPos, aPt );
|
|
SwContentNode *pNd = aPos.GetNode().GetContentNode();
|
|
std::pair<Point, bool> const tmp(*pPt, true);
|
|
pFrame = pNd->getLayoutFrame(GetLayout(), nullptr, &tmp);
|
|
}
|
|
else
|
|
pFrame = GetCurrFrame( false );
|
|
while ( pFrame )
|
|
{
|
|
switch ( pFrame->GetType() )
|
|
{
|
|
case SwFrameType::Column:
|
|
if( pFrame->GetUpper()->IsSctFrame() )
|
|
{
|
|
// Check, if isn't not only a single column
|
|
// from a section with footnotes at the end.
|
|
if( pFrame->GetNext() || pFrame->GetPrev() )
|
|
// Sectioncolumns
|
|
nReturn |= ( nReturn & FrameTypeFlags::TABLE ) ?
|
|
FrameTypeFlags::COLSECTOUTTAB : FrameTypeFlags::COLSECT;
|
|
}
|
|
else // only pages and frame columns
|
|
nReturn |= FrameTypeFlags::COLUMN;
|
|
break;
|
|
case SwFrameType::Page:
|
|
nReturn |= FrameTypeFlags::PAGE;
|
|
if( static_cast<const SwPageFrame*>(pFrame)->IsFootnotePage() )
|
|
nReturn |= FrameTypeFlags::FTNPAGE;
|
|
break;
|
|
case SwFrameType::Header:
|
|
nReturn |= FrameTypeFlags::HEADER;
|
|
break;
|
|
case SwFrameType::Footer:
|
|
nReturn |= FrameTypeFlags::FOOTER;
|
|
break;
|
|
case SwFrameType::Body:
|
|
if( pFrame->GetUpper()->IsPageFrame() ) // not for ColumnFrames
|
|
nReturn |= FrameTypeFlags::BODY;
|
|
break;
|
|
case SwFrameType::Ftn:
|
|
nReturn |= FrameTypeFlags::FOOTNOTE;
|
|
break;
|
|
case SwFrameType::Fly:
|
|
if( static_cast<const SwFlyFrame*>(pFrame)->IsFlyLayFrame() )
|
|
nReturn |= FrameTypeFlags::FLY_FREE;
|
|
else if ( static_cast<const SwFlyFrame*>(pFrame)->IsFlyAtContentFrame() )
|
|
nReturn |= FrameTypeFlags::FLY_ATCNT;
|
|
else
|
|
{
|
|
OSL_ENSURE( static_cast<const SwFlyFrame*>(pFrame)->IsFlyInContentFrame(),
|
|
"New frametype?" );
|
|
nReturn |= FrameTypeFlags::FLY_INCNT;
|
|
}
|
|
nReturn |= FrameTypeFlags::FLY_ANY;
|
|
if( bStopAtFly )
|
|
return nReturn;
|
|
break;
|
|
case SwFrameType::Tab:
|
|
case SwFrameType::Row:
|
|
case SwFrameType::Cell:
|
|
nReturn |= FrameTypeFlags::TABLE;
|
|
break;
|
|
default:
|
|
/* do nothing */
|
|
break;
|
|
}
|
|
if ( pFrame->IsFlyFrame() )
|
|
pFrame = static_cast<const SwFlyFrame*>(pFrame)->GetAnchorFrame();
|
|
else
|
|
pFrame = pFrame->GetUpper();
|
|
}
|
|
return nReturn;
|
|
}
|
|
|
|
void SwFEShell::ShellGetFocus()
|
|
{
|
|
::SetShell( this );
|
|
SwCursorShell::ShellGetFocus();
|
|
|
|
if ( HasDrawView() )
|
|
{
|
|
if (!comphelper::LibreOfficeKit::isActive())
|
|
Imp()->GetDrawView()->showMarkHandles();
|
|
if ( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0 )
|
|
FrameNotify( this, FLY_DRAG_START );
|
|
}
|
|
}
|
|
|
|
void SwFEShell::ShellLoseFocus()
|
|
{
|
|
SwCursorShell::ShellLoseFocus();
|
|
|
|
if ( HasDrawView() && Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0 )
|
|
{
|
|
if (!comphelper::LibreOfficeKit::isActive())
|
|
Imp()->GetDrawView()->hideMarkHandles();
|
|
FrameNotify( this, FLY_DRAG_END );
|
|
}
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetPhyPageNum() const
|
|
{
|
|
SwFrame *pFrame = GetCurrFrame();
|
|
if ( pFrame )
|
|
return pFrame->GetPhyPageNum();
|
|
return 0;
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetVirtPageNum() const
|
|
{
|
|
SwFrame *pFrame = GetCurrFrame();
|
|
if ( pFrame )
|
|
return pFrame->GetVirtPageNum();
|
|
return 0;
|
|
}
|
|
|
|
static void lcl_SetAPageOffset( sal_uInt16 nOffset, SwPageFrame* pPage, SwFEShell* pThis )
|
|
{
|
|
pThis->StartAllAction();
|
|
OSL_ENSURE( pPage->FindFirstBodyContent(),
|
|
"SwFEShell _SetAPageOffset() without ContentFrame" );
|
|
|
|
SwFormatPageDesc aDesc( pPage->GetPageDesc() );
|
|
aDesc.SetNumOffset( nOffset );
|
|
|
|
SwFrame *pFrame = pThis->GetCurrFrame( false );
|
|
if ( pFrame->IsInTab() )
|
|
pThis->GetDoc()->SetAttr( aDesc, *pFrame->FindTabFrame()->GetFormat() );
|
|
else
|
|
{
|
|
pThis->GetDoc()->getIDocumentContentOperations().InsertPoolItem(
|
|
*pThis->GetCursor(), aDesc, SetAttrMode::DEFAULT, pThis->GetLayout());
|
|
}
|
|
|
|
pThis->EndAllAction();
|
|
}
|
|
|
|
void SwFEShell::SetNewPageOffset( sal_uInt16 nOffset )
|
|
{
|
|
GetLayout()->SetVirtPageNum( true );
|
|
const SwPageFrame *pPage = GetCurrFrame( false )->FindPageFrame();
|
|
lcl_SetAPageOffset( nOffset, const_cast<SwPageFrame*>(pPage), this );
|
|
}
|
|
|
|
void SwFEShell::SetPageOffset( sal_uInt16 nOffset )
|
|
{
|
|
const SwPageFrame *pPage = GetCurrFrame( false )->FindPageFrame();
|
|
const SwRootFrame* pDocLayout = GetLayout();
|
|
while ( pPage )
|
|
{
|
|
const SwFrame *pFlow = pPage->FindFirstBodyContent();
|
|
if ( pFlow )
|
|
{
|
|
if ( pFlow->IsInTab() )
|
|
pFlow = pFlow->FindTabFrame();
|
|
const SwFormatPageDesc& rPgDesc = pFlow->GetPageDescItem();
|
|
if ( rPgDesc.GetNumOffset() )
|
|
{
|
|
pDocLayout->SetVirtPageNum( true );
|
|
lcl_SetAPageOffset( nOffset, const_cast<SwPageFrame*>(pPage), this );
|
|
break;
|
|
}
|
|
}
|
|
pPage = static_cast<const SwPageFrame*>(pPage->GetPrev());
|
|
}
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetPageOffset() const
|
|
{
|
|
const SwPageFrame *pPage = GetCurrFrame()->FindPageFrame();
|
|
while ( pPage )
|
|
{
|
|
const SwFrame *pFlow = pPage->FindFirstBodyContent();
|
|
if ( pFlow )
|
|
{
|
|
if ( pFlow->IsInTab() )
|
|
pFlow = pFlow->FindTabFrame();
|
|
::std::optional<sal_uInt16> oNumOffset = pFlow->GetPageDescItem().GetNumOffset();
|
|
if ( oNumOffset )
|
|
return *oNumOffset;
|
|
}
|
|
pPage = static_cast<const SwPageFrame*>(pPage->GetPrev());
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void SwFEShell::InsertLabel( const SwLabelType eType, const OUString &rText, const OUString& rSeparator,
|
|
const OUString& rNumberSeparator,
|
|
const bool bBefore, const sal_uInt16 nId,
|
|
const OUString& rCharacterStyle,
|
|
const bool bCpyBrd )
|
|
{
|
|
// get node index of cursor position, SwDoc can do everything else itself
|
|
SwContentFrame *pCnt = SwLabelType::Draw==eType ? nullptr : GetCurrFrame( false );
|
|
if( SwLabelType::Draw!=eType && !pCnt )
|
|
return;
|
|
|
|
StartAllAction();
|
|
SwRewriter aRewriter(SwUndoInsertLabel::CreateRewriter(rText));
|
|
StartUndo(SwUndoId::INSERTLABEL, &aRewriter);
|
|
|
|
SwNodeOffset nIdx(0);
|
|
bool bInnerCntIsFly = false;
|
|
SwFlyFrameFormat* pFlyFormat = nullptr;
|
|
switch( eType )
|
|
{
|
|
case SwLabelType::Object:
|
|
case SwLabelType::Fly:
|
|
bInnerCntIsFly = pCnt->IsInFly();
|
|
if (bInnerCntIsFly)
|
|
{
|
|
// pass down index to the startnode for flys
|
|
nIdx = pCnt->FindFlyFrame()->
|
|
GetFormat()->GetContent().GetContentIdx()->GetIndex();
|
|
}
|
|
break;
|
|
case SwLabelType::Table:
|
|
if( pCnt->IsInTab() )
|
|
{
|
|
// pass down index to the TableNode for tables
|
|
SwTabFrame* pTabFrame = pCnt->FindTabFrame();
|
|
const SwTable& rTable = *pTabFrame->GetTable();
|
|
nIdx = rTable.GetTabSortBoxes()[ 0 ]
|
|
->GetSttNd()->FindTableNode()->GetIndex();
|
|
|
|
SwFlyFrame* pFly = pTabFrame->FindFlyFrame();
|
|
if (pFly && pFly->IsFlySplitAllowed())
|
|
{
|
|
// This table is in a split fly, but we will insert a label, which means this is not
|
|
// a floating table anymore, disable the "can split" bit, it'll be hidden on the UI
|
|
// anyway.
|
|
SwFrameFormat* pFormat = pFly->GetFrameFormat();
|
|
SfxItemSetFixed<RES_FLY_SPLIT, RES_FLY_SPLIT> aSet(GetDoc()->GetAttrPool());
|
|
SwFormatFlySplit aSplit(false);
|
|
aSet.Put(aSplit);
|
|
// SwUndoFormatAttr is created for us.
|
|
GetDoc()->SetFlyFrameAttr(*pFormat, aSet);
|
|
}
|
|
}
|
|
break;
|
|
case SwLabelType::Draw:
|
|
if( Imp()->GetDrawView() )
|
|
{
|
|
SwDrawView *pDView = Imp()->GetDrawView();
|
|
const SdrMarkList& rMrkList = pDView->GetMarkedObjectList();
|
|
|
|
// copy marked drawing objects to
|
|
// local list to perform the corresponding action for each object
|
|
std::vector<SdrObject*> aDrawObjs;
|
|
{
|
|
for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
|
|
{
|
|
SdrObject* pDrawObj = rMrkList.GetMark(i)->GetMarkedSdrObj();
|
|
if( pDrawObj )
|
|
aDrawObjs.push_back( pDrawObj );
|
|
}
|
|
}
|
|
// loop on marked drawing objects
|
|
while ( !aDrawObjs.empty() )
|
|
{
|
|
SdrObject* pDrawObj = aDrawObjs.back();
|
|
assert(pDrawObj);
|
|
if ( dynamic_cast<const SwVirtFlyDrawObj*>( pDrawObj) == nullptr &&
|
|
dynamic_cast<const SwFlyDrawObj*>( pDrawObj) == nullptr )
|
|
{
|
|
SwFlyFrameFormat *pFormat =
|
|
GetDoc()->InsertDrawLabel( rText, rSeparator, rNumberSeparator, nId, rCharacterStyle, *pDrawObj );
|
|
if( !pFlyFormat )
|
|
pFlyFormat = pFormat;
|
|
}
|
|
|
|
aDrawObjs.pop_back();
|
|
}
|
|
|
|
}
|
|
break;
|
|
default:
|
|
OSL_ENSURE( false, "Cursor neither in table nor in fly." );
|
|
}
|
|
|
|
if( nIdx )
|
|
{
|
|
pFlyFormat = GetDoc()->InsertLabel(eType, rText, rSeparator,
|
|
rNumberSeparator, bBefore, nId,
|
|
nIdx, rCharacterStyle, bCpyBrd);
|
|
}
|
|
|
|
if (pFlyFormat)
|
|
{
|
|
const Point aPt(GetCursorDocPos());
|
|
if (SwFlyFrame* pFrame = pFlyFormat->GetFrame(&aPt))
|
|
SelectFlyFrame(*pFrame);
|
|
}
|
|
EndUndo();
|
|
EndAllActionAndCall();
|
|
|
|
}
|
|
|
|
bool SwFEShell::Sort(const SwSortOptions& rOpt)
|
|
{
|
|
if( !HasSelection() )
|
|
return false;
|
|
|
|
CurrShell aCurr( this );
|
|
bool bRet = false;
|
|
StartAllAction();
|
|
if(IsTableMode())
|
|
{
|
|
// Sort table
|
|
// check if Point/Mark of current Cursor are in one table
|
|
SwFrame *pFrame = GetCurrFrame( false );
|
|
OSL_ENSURE( pFrame->FindTabFrame(), "Cursor not in table." );
|
|
|
|
// search boxes via the layout
|
|
SwSelBoxes aBoxes;
|
|
GetTableSel(*this, aBoxes);
|
|
|
|
// The Cursor should be removed from the deletion area.
|
|
// Always put them behind/on the table; via the
|
|
// document position they will always be set to the old position
|
|
while( !pFrame->IsCellFrame() )
|
|
pFrame = pFrame->GetUpper();
|
|
{
|
|
/* ParkCursor->ParkCursorTab */
|
|
ParkCursorInTab();
|
|
}
|
|
|
|
// call sorting on document
|
|
bRet = mxDoc->SortTable(aBoxes, rOpt);
|
|
}
|
|
else
|
|
{
|
|
// Sort text nothing else
|
|
for(SwPaM& rPaM : GetCursor()->GetRingContainer())
|
|
{
|
|
SwPaM* pPam = &rPaM;
|
|
|
|
auto [pStart, pEnd] = pPam->StartEnd(); // SwPosition*
|
|
|
|
SwNodeIndex aPrevIdx( pStart->GetNode(), -1 );
|
|
SwNodeOffset nOffset = pEnd->GetNodeIndex() - pStart->GetNodeIndex();
|
|
const sal_Int32 nCntStt = pStart->GetContentIndex();
|
|
|
|
// Sorting
|
|
bRet = mxDoc->SortText(*pPam, rOpt);
|
|
|
|
// put selection again
|
|
pPam->DeleteMark();
|
|
pPam->GetPoint()->Assign( aPrevIdx.GetNode(), SwNodeOffset(+1) );
|
|
SwContentNode* pCNd = pPam->GetPointContentNode();
|
|
sal_Int32 nLen = pCNd->Len();
|
|
if( nLen > nCntStt )
|
|
nLen = nCntStt;
|
|
pPam->GetPoint()->SetContent(nLen );
|
|
pPam->SetMark();
|
|
|
|
pPam->GetPoint()->Adjust(nOffset);
|
|
pCNd = pPam->GetPointContentNode();
|
|
pPam->GetPoint()->SetContent( pCNd->Len() );
|
|
}
|
|
}
|
|
|
|
EndAllAction();
|
|
return bRet;
|
|
}
|
|
|
|
bool SwFEShell::IsColRightToLeft() const
|
|
{
|
|
SwFrame* pFrame = GetCurrFrame();
|
|
while (pFrame)
|
|
{
|
|
pFrame = pFrame->GetUpper();
|
|
if (pFrame && pFrame->IsColumnFrame())
|
|
{
|
|
return pFrame->IsRightToLeft();
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetCurColNum_( const SwFrame *pFrame,
|
|
SwGetCurColNumPara* pPara )
|
|
{
|
|
sal_uInt16 nRet = 0;
|
|
while ( pFrame )
|
|
{
|
|
pFrame = pFrame->GetUpper();
|
|
if( pFrame && pFrame->IsColumnFrame() )
|
|
{
|
|
const SwFrame *pCurFrame = pFrame;
|
|
do {
|
|
++nRet;
|
|
pFrame = pFrame->GetPrev();
|
|
} while ( pFrame );
|
|
|
|
if( pPara )
|
|
{
|
|
// now search the format, determining the columness
|
|
pFrame = pCurFrame->GetUpper();
|
|
while( pFrame )
|
|
{
|
|
if( ( SwFrameType::Page | SwFrameType::Fly | SwFrameType::Section ) & pFrame->GetType() )
|
|
{
|
|
pPara->pFrameFormat = static_cast<const SwLayoutFrame*>(pFrame)->GetFormat();
|
|
pPara->pPrtRect = &pFrame->getFramePrintArea();
|
|
break;
|
|
}
|
|
pFrame = pFrame->GetUpper();
|
|
}
|
|
if( !pFrame )
|
|
{
|
|
pPara->pFrameFormat = nullptr;
|
|
pPara->pPrtRect = nullptr;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetCurColNum( SwGetCurColNumPara* pPara ) const
|
|
{
|
|
OSL_ENSURE( GetCurrFrame(), "Cursor parked?" );
|
|
return GetCurColNum_( GetCurrFrame(), pPara );
|
|
}
|
|
|
|
sal_uInt16 SwFEShell::GetCurOutColNum() const
|
|
{
|
|
sal_uInt16 nRet = 0;
|
|
SwFrame* pFrame = GetCurrFrame();
|
|
OSL_ENSURE( pFrame, "Cursor parked?" );
|
|
if( pFrame )
|
|
{
|
|
pFrame = pFrame->IsInTab() ? static_cast<SwFrame*>(pFrame->FindTabFrame())
|
|
: static_cast<SwFrame*>(pFrame->FindSctFrame());
|
|
OSL_ENSURE( pFrame, "No Tab, no Sect" );
|
|
if( pFrame )
|
|
nRet = GetCurColNum_( pFrame, nullptr );
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
SwFEShell::SwFEShell( SwDoc& rDoc, vcl::Window *pWindow, const SwViewOption *pOptions )
|
|
: SwEditShell( rDoc, pWindow, pOptions )
|
|
, m_bCheckForOLEInCaption(false)
|
|
, m_aPasteListeners(GetPasteMutex())
|
|
, m_eTableInsertMode(SwTable::SEARCH_NONE)
|
|
, m_bTableCopied(false)
|
|
{
|
|
}
|
|
|
|
SwFEShell::SwFEShell( SwEditShell& rShell, vcl::Window *pWindow )
|
|
: SwEditShell( rShell, pWindow )
|
|
, m_bCheckForOLEInCaption(false)
|
|
, m_aPasteListeners(GetPasteMutex())
|
|
, m_eTableInsertMode(SwTable::SEARCH_NONE)
|
|
, m_bTableCopied(false)
|
|
{
|
|
}
|
|
|
|
SwFEShell::~SwFEShell()
|
|
{
|
|
}
|
|
|
|
// #i17567# - adjustments for allowing
|
|
// negative vertical positions for fly frames anchored to paragraph/to character.
|
|
// #i22305# - adjustments for option 'Follow text flow'
|
|
// for to frame anchored objects.
|
|
// #i22341# - adjustments for vertical alignment at top of line
|
|
// for to character anchored objects.
|
|
void SwFEShell::CalcBoundRect( SwRect& _orRect,
|
|
const RndStdIds _nAnchorId,
|
|
const sal_Int16 _eHoriRelOrient,
|
|
const sal_Int16 _eVertRelOrient,
|
|
const SwFormatAnchor* _pToCharContentPos,
|
|
const bool _bFollowTextFlow,
|
|
bool _bMirror,
|
|
Point* _opRef,
|
|
Size* _opPercent,
|
|
const SwFormatFrameSize* pFormatFrameSize) const
|
|
{
|
|
const SwFrame* pFrame;
|
|
const SwFlyFrame* pFly;
|
|
if( _opRef )
|
|
{
|
|
pFrame = GetCurrFrame();
|
|
pFly = pFrame->FindFlyFrame();
|
|
if( nullptr != pFly )
|
|
pFrame = pFly->GetAnchorFrame();
|
|
}
|
|
else
|
|
{
|
|
pFly = GetSelectedOrCurrFlyFrame();
|
|
pFrame = pFly ? pFly->GetAnchorFrame() : GetCurrFrame();
|
|
}
|
|
|
|
bool bWrapThrough = false;
|
|
if ( pFly )
|
|
{
|
|
SwFlyFrameFormat* pFormat = const_cast<SwFlyFrameFormat*>(pFly->GetFormat());
|
|
const SwFormatSurround& rSurround = pFormat->GetSurround();
|
|
bWrapThrough = rSurround.GetSurround() == css::text::WrapTextMode_THROUGH;
|
|
}
|
|
|
|
const SwPageFrame* pPage = pFrame->FindPageFrame();
|
|
_bMirror = _bMirror && !pPage->OnRightPage();
|
|
|
|
Point aPos;
|
|
bool bVertic = false;
|
|
bool bRTL = false;
|
|
bool bVerticalL2R = false;
|
|
|
|
if ((RndStdIds::FLY_AT_PAGE == _nAnchorId) || (RndStdIds::FLY_AT_FLY == _nAnchorId)) // LAYER_IMPL
|
|
{
|
|
const SwFrame* pTmp = pFrame;
|
|
// #i22305#
|
|
if ((RndStdIds::FLY_AT_PAGE == _nAnchorId) ||
|
|
((RndStdIds::FLY_AT_FLY == _nAnchorId) && !_bFollowTextFlow))
|
|
{
|
|
pFrame = pPage;
|
|
}
|
|
else
|
|
{
|
|
pFrame = pFrame->FindFlyFrame();
|
|
}
|
|
if ( !pFrame )
|
|
pFrame = pTmp;
|
|
_orRect = pFrame->getFrameArea();
|
|
SwRectFnSet aRectFnSet(pFrame);
|
|
bRTL = pFrame->IsRightToLeft();
|
|
if ( bRTL )
|
|
aPos = pFrame->getFrameArea().TopRight();
|
|
else
|
|
aPos = aRectFnSet.GetPos(pFrame->getFrameArea());
|
|
|
|
if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
{
|
|
bVertic = aRectFnSet.IsVert();
|
|
bVerticalL2R = aRectFnSet.IsVertL2R();
|
|
_bMirror = false; // no mirroring in vertical environment
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
case text::RelOrientation::FRAME_RIGHT: aPos.AdjustY(pFrame->getFramePrintArea().Height() );
|
|
[[fallthrough]];
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustY(pFrame->getFramePrintArea().Top() ); break;
|
|
default: break;
|
|
}
|
|
}
|
|
else if ( _bMirror )
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
|
|
[[fallthrough]];
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
case text::RelOrientation::FRAME_RIGHT: aPos.AdjustX(pFrame->getFramePrintArea().Left() ); break;
|
|
default: aPos.AdjustX(pFrame->getFrameArea().Width() );
|
|
}
|
|
}
|
|
else if ( bRTL )
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
|
|
[[fallthrough]];
|
|
case text::RelOrientation::PAGE_LEFT:
|
|
case text::RelOrientation::FRAME_LEFT: aPos.AdjustX(pFrame->getFramePrintArea().Left() -
|
|
pFrame->getFrameArea().Width() ); break;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
case text::RelOrientation::FRAME_RIGHT: aPos.AdjustX(pFrame->getFramePrintArea().Width() );
|
|
[[fallthrough]];
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA: aPos.AdjustX(pFrame->getFramePrintArea().Left() ); break;
|
|
default:break;
|
|
}
|
|
}
|
|
|
|
if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
|
|
{
|
|
switch ( _eVertRelOrient )
|
|
{
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
{
|
|
aPos.AdjustX( -(pFrame->GetRightMargin()) );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else if ( aRectFnSet.IsVertL2R() )
|
|
{
|
|
switch ( _eVertRelOrient )
|
|
{
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
{
|
|
aPos.AdjustX(pFrame->GetLeftMargin() );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( _eVertRelOrient )
|
|
{
|
|
case text::RelOrientation::PRINT_AREA:
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
{
|
|
if ( pFrame->IsPageFrame() )
|
|
{
|
|
aPos.setY(
|
|
static_cast<const SwPageFrame*>(pFrame)->PrtWithoutHeaderAndFooter().Top() );
|
|
}
|
|
else
|
|
{
|
|
aPos.AdjustY(pFrame->getFramePrintArea().Top() );
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if ( _opPercent )
|
|
*_opPercent = pFrame->getFramePrintArea().SSize();
|
|
}
|
|
else
|
|
{
|
|
const SwFrame* pUpper = ( pFrame->IsPageFrame() || pFrame->IsFlyFrame() ) ?
|
|
pFrame : pFrame->GetUpper();
|
|
SwRectFnSet aRectFnSet(pUpper);
|
|
if ( _opPercent )
|
|
{
|
|
// If the size is relative from page, then full size should be counted from the page frame.
|
|
if (pFormatFrameSize && pFormatFrameSize->GetWidthPercentRelation() == text::RelOrientation::PAGE_FRAME)
|
|
_opPercent->setWidth(pPage->getFrameArea().Width());
|
|
else
|
|
_opPercent->setWidth(pUpper->getFramePrintArea().Width());
|
|
|
|
if (pFormatFrameSize && pFormatFrameSize->GetHeightPercentRelation() == text::RelOrientation::PAGE_FRAME)
|
|
// If the size is relative from page, then full size should be counted from the page frame.
|
|
_opPercent->setHeight(pPage->getFrameArea().Height());
|
|
else
|
|
_opPercent->setHeight(pUpper->getFramePrintArea().Height());
|
|
}
|
|
|
|
bRTL = pFrame->IsRightToLeft();
|
|
if ( bRTL )
|
|
aPos = pFrame->getFrameArea().TopRight();
|
|
else
|
|
aPos = aRectFnSet.GetPos(pFrame->getFrameArea());
|
|
// #i17567# - allow negative positions
|
|
// for fly frames anchor to paragraph/to character.
|
|
if ((_nAnchorId == RndStdIds::FLY_AT_PARA) || (_nAnchorId == RndStdIds::FLY_AT_CHAR))
|
|
{
|
|
// The rectangle, the fly frame can be positioned in, is determined
|
|
// horizontally by the frame area of the horizontal environment
|
|
// and vertically by the printing area of the vertical environment,
|
|
// if the object follows the text flow, or by the frame area of the
|
|
// vertical environment, if the object doesn't follow the text flow.
|
|
// new class <SwEnvironmentOfAnchoredObject>
|
|
objectpositioning::SwEnvironmentOfAnchoredObject aEnvOfObj(
|
|
_bFollowTextFlow );
|
|
const SwLayoutFrame& rHoriEnvironLayFrame =
|
|
aEnvOfObj.GetHoriEnvironmentLayoutFrame( *pFrame );
|
|
const SwLayoutFrame& rVertEnvironLayFrame =
|
|
aEnvOfObj.GetVertEnvironmentLayoutFrame( *pFrame );
|
|
const SwRect& aHoriEnvironRect( rHoriEnvironLayFrame.getFrameArea() );
|
|
SwRect aVertEnvironRect;
|
|
if ( _bFollowTextFlow )
|
|
{
|
|
aVertEnvironRect = rVertEnvironLayFrame.getFramePrintArea();
|
|
aVertEnvironRect.Pos() += rVertEnvironLayFrame.getFrameArea().Pos();
|
|
// #i18732# - adjust vertical 'virtual' anchor position
|
|
// (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
|
|
// to page areas.
|
|
if ( _eVertRelOrient == text::RelOrientation::PAGE_FRAME || _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
|
|
{
|
|
if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setX( aVertEnvironRect.Right() );
|
|
}
|
|
else if ( aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setX( aVertEnvironRect.Left() );
|
|
}
|
|
else
|
|
{
|
|
aPos.setY( aVertEnvironRect.Top() );
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
OSL_ENSURE( rVertEnvironLayFrame.IsPageFrame(),
|
|
"<SwFEShell::CalcBoundRect(..)> - not following text flow, but vertical environment *not* page!" );
|
|
aVertEnvironRect = rVertEnvironLayFrame.getFrameArea();
|
|
// #i18732# - adjustment vertical 'virtual' anchor position
|
|
// (<aPos.Y()> respectively <aPos.X()>), if object is vertical aligned
|
|
// to page areas.
|
|
if (_eVertRelOrient == text::RelOrientation::PAGE_FRAME
|
|
|| _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA
|
|
|| _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
|
|
{
|
|
if ( aRectFnSet.IsVert() && !aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setX( aVertEnvironRect.Right() );
|
|
if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
|
|
{
|
|
aPos.setX(aPos.getX() - rVertEnvironLayFrame.GetRightMargin());
|
|
}
|
|
}
|
|
else if ( aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setX( aVertEnvironRect.Left() );
|
|
if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
|
|
{
|
|
aPos.setX(aPos.getX() + rVertEnvironLayFrame.GetLeftMargin());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
aPos.setY( aVertEnvironRect.Top() );
|
|
if ( _eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA )
|
|
{
|
|
aPos.setY(aPos.getY() + rVertEnvironLayFrame.GetTopMargin());
|
|
// add height of page header
|
|
const SwFrame* pTmpFrame = rVertEnvironLayFrame.Lower();
|
|
if ( pTmpFrame->IsHeaderFrame() )
|
|
{
|
|
aPos.setY(aPos.getY() + pTmpFrame->getFrameArea().Height());
|
|
}
|
|
}
|
|
else if (_eVertRelOrient == text::RelOrientation::PAGE_PRINT_AREA_BOTTOM)
|
|
{
|
|
if (rVertEnvironLayFrame.IsPageFrame())
|
|
{
|
|
auto& rPageFrame = static_cast<const SwPageFrame&>(rVertEnvironLayFrame);
|
|
aPos.setY(rPageFrame.PrtWithoutHeaderAndFooter().Bottom());
|
|
}
|
|
else
|
|
{
|
|
aPos.AdjustY(rVertEnvironLayFrame.getFramePrintArea().Bottom());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// #i22341# - adjust vertical 'virtual' anchor position
|
|
// (<aPos.Y()> respectively <aPos.X()>), if object is anchored to
|
|
// character and vertical aligned at character or top of line
|
|
// <pFrame>, which is the anchor frame or the proposed anchor frame,
|
|
// doesn't have to be a text frame (e.g. edit a to-page anchored
|
|
// fly frame). Thus, assure this.
|
|
const SwTextFrame* pTextFrame = pFrame->DynCastTextFrame();
|
|
if ( pTextFrame &&
|
|
(_nAnchorId == RndStdIds::FLY_AT_CHAR) &&
|
|
( _eVertRelOrient == text::RelOrientation::CHAR ||
|
|
_eVertRelOrient == text::RelOrientation::TEXT_LINE ) )
|
|
{
|
|
SwTwips nTop = 0;
|
|
if ( _eVertRelOrient == text::RelOrientation::CHAR )
|
|
{
|
|
SwRect aChRect;
|
|
if ( _pToCharContentPos )
|
|
{
|
|
pTextFrame->GetAutoPos( aChRect, *_pToCharContentPos->GetContentAnchor() );
|
|
}
|
|
else
|
|
{
|
|
// No content position provided. Thus, use a default one.
|
|
SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
|
|
pTextFrame->GetAutoPos( aChRect, aDefaultContentPos );
|
|
}
|
|
nTop = aRectFnSet.GetBottom(aChRect);
|
|
}
|
|
else
|
|
{
|
|
if ( _pToCharContentPos )
|
|
{
|
|
pTextFrame->GetTopOfLine( nTop, *_pToCharContentPos->GetContentAnchor() );
|
|
}
|
|
else
|
|
{
|
|
// No content position provided. Thus, use a default one.
|
|
SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
|
|
pTextFrame->GetTopOfLine( nTop, aDefaultContentPos );
|
|
}
|
|
}
|
|
if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setX(nTop);
|
|
}
|
|
else
|
|
{
|
|
aPos.setY(nTop);
|
|
}
|
|
}
|
|
|
|
// #i26945# - adjust horizontal 'virtual' anchor
|
|
// position (<aPos.X()> respectively <aPos.Y()>), if object is
|
|
// anchored to character and horizontal aligned at character.
|
|
if ( pTextFrame &&
|
|
(_nAnchorId == RndStdIds::FLY_AT_CHAR) &&
|
|
_eHoriRelOrient == text::RelOrientation::CHAR )
|
|
{
|
|
SwTwips nLeft = 0;
|
|
SwRect aChRect;
|
|
if ( _pToCharContentPos )
|
|
{
|
|
pTextFrame->GetAutoPos( aChRect, *_pToCharContentPos->GetContentAnchor() );
|
|
}
|
|
else
|
|
{
|
|
// No content position provided. Thus, use a default one.
|
|
SwPosition aDefaultContentPos(*(pTextFrame->GetTextNodeFirst()));
|
|
pTextFrame->GetAutoPos( aChRect, aDefaultContentPos );
|
|
}
|
|
nLeft = aRectFnSet.GetLeft(aChRect);
|
|
if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
{
|
|
aPos.setY(nLeft);
|
|
}
|
|
else
|
|
{
|
|
aPos.setX(nLeft);
|
|
}
|
|
}
|
|
if ( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
{
|
|
_orRect = SwRect( aVertEnvironRect.Left(),
|
|
aHoriEnvironRect.Top(),
|
|
aVertEnvironRect.Width(),
|
|
aHoriEnvironRect.Height() );
|
|
}
|
|
else
|
|
{
|
|
_orRect = SwRect( aHoriEnvironRect.Left(),
|
|
aVertEnvironRect.Top(),
|
|
aHoriEnvironRect.Width(),
|
|
aVertEnvironRect.Height() );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( _opRef && pFly && pFly->IsFlyInContentFrame() )
|
|
*_opRef = static_cast<const SwFlyInContentFrame*>( pFly )->GetRefPoint();
|
|
|
|
_orRect = pUpper->getFrameArea();
|
|
if( !pUpper->IsBodyFrame() )
|
|
{
|
|
_orRect += pUpper->getFramePrintArea().Pos();
|
|
_orRect.SSize( pUpper->getFramePrintArea().SSize() );
|
|
if ( pUpper->IsCellFrame() )//MA_FLY_HEIGHT
|
|
{
|
|
const SwFrame* pTab = pUpper->FindTabFrame();
|
|
tools::Long nBottom = aRectFnSet.GetPrtBottom(*pTab->GetUpper());
|
|
aRectFnSet.SetBottom( _orRect, nBottom );
|
|
}
|
|
}
|
|
// only use 90% of height for character bound
|
|
{
|
|
if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
_orRect.Width( (_orRect.Width()*9)/10 );
|
|
else
|
|
_orRect.Height( (_orRect.Height()*9)/10 );
|
|
}
|
|
}
|
|
|
|
const SwTwips nBaseOfstForFly = ( pFrame->IsTextFrame() && pFly ) ?
|
|
static_cast<const SwTextFrame*>(pFrame)->GetBaseOffsetForFly( !bWrapThrough ) :
|
|
0;
|
|
if( aRectFnSet.IsVert() || aRectFnSet.IsVertL2R() )
|
|
{
|
|
bVertic = aRectFnSet.IsVert();
|
|
bVerticalL2R = aRectFnSet.IsVertL2R();
|
|
_bMirror = false;
|
|
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::FRAME_RIGHT:
|
|
{
|
|
aPos.setY(aPos.getY() + pFrame->getFramePrintArea().Height());
|
|
aPos += aRectFnSet.GetPos(pFrame->getFramePrintArea());
|
|
break;
|
|
}
|
|
case text::RelOrientation::PRINT_AREA:
|
|
{
|
|
aPos += aRectFnSet.GetPos(pFrame->getFramePrintArea());
|
|
aPos.setY(aPos.getY() + nBaseOfstForFly);
|
|
break;
|
|
}
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
{
|
|
aPos.setY(pPage->getFrameArea().Top() + pPage->getFramePrintArea().Bottom());
|
|
break;
|
|
}
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
{
|
|
aPos.setY(pPage->getFrameArea().Top() + pPage->getFramePrintArea().Top());
|
|
break;
|
|
}
|
|
case text::RelOrientation::PAGE_LEFT:
|
|
case text::RelOrientation::PAGE_FRAME:
|
|
{
|
|
aPos.setY(pPage->getFrameArea().Top());
|
|
break;
|
|
}
|
|
case text::RelOrientation::FRAME:
|
|
{
|
|
aPos.setY(aPos.getY() + nBaseOfstForFly);
|
|
break;
|
|
}
|
|
default: break;
|
|
}
|
|
}
|
|
else if( _bMirror )
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::FRAME_RIGHT: aPos.setX(aPos.getX() + pFrame->getFramePrintArea().Left()); break;
|
|
case text::RelOrientation::FRAME:
|
|
case text::RelOrientation::FRAME_LEFT: aPos.setX(aPos.getX() + pFrame->getFrameArea().Width()); break;
|
|
case text::RelOrientation::PRINT_AREA: aPos.setX(aPos.getX() + pFrame->getFramePrintArea().Right()); break;
|
|
case text::RelOrientation::PAGE_LEFT:
|
|
case text::RelOrientation::PAGE_FRAME: aPos.setX(pPage->getFrameArea().Right()); break;
|
|
case text::RelOrientation::PAGE_PRINT_AREA: aPos.setX(pPage->getFrameArea().Left()
|
|
+ pPage->getFramePrintArea().Left()); break;
|
|
default: break;
|
|
}
|
|
}
|
|
else if ( bRTL )
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::FRAME_LEFT:
|
|
aPos.setX(pFrame->getFrameArea().Left() +
|
|
pFrame->getFramePrintArea().Left());
|
|
break;
|
|
|
|
case text::RelOrientation::PRINT_AREA:
|
|
aPos.setX(pFrame->getFrameArea().Left() + pFrame->getFramePrintArea().Left() +
|
|
pFrame->getFramePrintArea().Width());
|
|
aPos.setX(aPos.getX() + nBaseOfstForFly);
|
|
break;
|
|
|
|
case text::RelOrientation::PAGE_LEFT:
|
|
aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left());
|
|
break;
|
|
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left() +
|
|
pPage->getFramePrintArea().Width());
|
|
break;
|
|
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
case text::RelOrientation::PAGE_FRAME:
|
|
aPos.setX(pPage->getFrameArea().Right());
|
|
break;
|
|
|
|
case text::RelOrientation::FRAME:
|
|
aPos.setX(aPos.getX() + nBaseOfstForFly);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch ( _eHoriRelOrient )
|
|
{
|
|
case text::RelOrientation::FRAME_RIGHT:
|
|
aPos.AdjustX(pFrame->getFramePrintArea().Width() );
|
|
aPos += pFrame->getFramePrintArea().Pos();
|
|
break;
|
|
case text::RelOrientation::PRINT_AREA:
|
|
aPos += pFrame->getFramePrintArea().Pos();
|
|
aPos.setX(aPos.getX() + nBaseOfstForFly);
|
|
break;
|
|
case text::RelOrientation::PAGE_RIGHT:
|
|
aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Right());
|
|
break;
|
|
case text::RelOrientation::PAGE_PRINT_AREA:
|
|
aPos.setX(pPage->getFrameArea().Left() + pPage->getFramePrintArea().Left());
|
|
break;
|
|
case text::RelOrientation::PAGE_LEFT:
|
|
case text::RelOrientation::PAGE_FRAME:
|
|
aPos.setX(pPage->getFrameArea().Left());
|
|
break;
|
|
case text::RelOrientation::FRAME:
|
|
aPos.setX(aPos.getX() + nBaseOfstForFly);
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
}
|
|
if( _opRef )
|
|
return;
|
|
|
|
if( bVertic && !bVerticalL2R )
|
|
_orRect.Pos( aPos.getX() - _orRect.Width() - _orRect.Left(), _orRect.Top() - aPos.getY() );
|
|
else if( bVerticalL2R )
|
|
_orRect.Pos( _orRect.Left() - aPos.getX(), _orRect.Top() - aPos.getY() );
|
|
else if ( bRTL )
|
|
_orRect.Pos( - ( _orRect.Right() - aPos.getX() ), _orRect.Top() - aPos.getY() );
|
|
else
|
|
_orRect.Pos( _orRect.Left() - aPos.getX(), _orRect.Top() - aPos.getY() );
|
|
if( _bMirror )
|
|
_orRect.Pos( -_orRect.Right(), _orRect.Top() );
|
|
}
|
|
|
|
Size SwFEShell::GetGraphicDefaultSize() const
|
|
{
|
|
Size aRet;
|
|
SwFlyFrame *pFly = GetSelectedFlyFrame();
|
|
if ( pFly )
|
|
{
|
|
// #i32951# - due to issue #i28701# no format of a
|
|
// newly inserted Writer fly frame or its anchor frame is performed
|
|
// any more. Thus, it could be possible (e.g. on insert of a horizontal
|
|
// line) that the anchor frame isn't formatted and its printing area
|
|
// size is (0,0). If this is the case the printing area of the upper
|
|
// of the anchor frame is taken.
|
|
const SwFrame* pAnchorFrame = pFly->GetAnchorFrame();
|
|
aRet = pAnchorFrame->getFramePrintArea().SSize();
|
|
if ( aRet.IsEmpty() && pAnchorFrame->GetUpper() )
|
|
{
|
|
aRet = pAnchorFrame->GetUpper()->getFramePrintArea().SSize();
|
|
}
|
|
|
|
SwRect aBound;
|
|
CalcBoundRect( aBound, pFly->GetFormat()->GetAnchor().GetAnchorId());
|
|
if ( pFly->GetAnchorFrame()->IsVertical() )
|
|
aRet.setWidth( aBound.Width() );
|
|
else
|
|
aRet.setHeight( aBound.Height() );
|
|
}
|
|
return aRet;
|
|
}
|
|
|
|
bool SwFEShell::IsFrameVertical(const bool bEnvironment, bool& bRTL, bool& bVertL2R) const
|
|
{
|
|
bool bVert = false;
|
|
bRTL = false;
|
|
bVertL2R = false;
|
|
|
|
if ( Imp()->HasDrawView() )
|
|
{
|
|
const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
|
|
if( rMrkList.GetMarkCount() != 1 )
|
|
return bVert;
|
|
|
|
SdrObject* pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if ( !pObj )
|
|
{
|
|
OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SdrObject instance in marked object list -> This is a serious situation" );
|
|
return bVert;
|
|
}
|
|
// #i26791#
|
|
SwContact* pContact = GetUserCall( pObj );
|
|
if ( !pContact )
|
|
{
|
|
OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing SwContact instance at marked object -> This is a serious situation" );
|
|
return bVert;
|
|
}
|
|
const SwFrame* pRef = pContact->GetAnchoredObj( pObj )->GetAnchorFrame();
|
|
if ( !pRef )
|
|
{
|
|
OSL_FAIL( "<SwFEShell::IsFrameVertical(..)> - missing anchor frame at marked object -> This is a serious situation" );
|
|
return bVert;
|
|
}
|
|
|
|
if ( !bEnvironment )
|
|
if ( auto pVirtFly = dynamic_cast<const SwVirtFlyDrawObj*>( pObj) )
|
|
pRef = pVirtFly->GetFlyFrame();
|
|
|
|
bVert = pRef->IsVertical();
|
|
bRTL = pRef->IsRightToLeft();
|
|
bVertL2R = pRef->IsVertLR();
|
|
}
|
|
|
|
return bVert;
|
|
}
|
|
|
|
void SwFEShell::MoveObjectIfActive( svt::EmbeddedObjectRef&, const Point& )
|
|
{
|
|
// does not do anything, only avoids crash if the method is used for wrong shell
|
|
}
|
|
|
|
void SwFEShell::ToggleHeaderFooterEdit()
|
|
{
|
|
// Clear objects selection
|
|
if ( Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() != 0 )
|
|
{
|
|
Imp()->GetDrawView()->UnmarkAll();
|
|
ClearMark();
|
|
}
|
|
|
|
SwCursorShell::ToggleHeaderFooterEdit();
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|