/* -*- 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 .
*/
staticvoid lcl_GrabCursor( SwFEShell* pSh, SwFlyFrame* pOldSelFly, const SwFrameFormat* pNewDrawFormat = nullptr)
{ const SwFrameFormat *pFlyFormat = pSh->SelFlyGrabCursor(); if( pFlyFormat && !pSh->ActionPend() &&
(!pOldSelFly || pOldSelFly->GetFormat() != pFlyFormat) )
{ // now call set macro if applicable
pSh->GetFlyMacroLnk().Call( static_cast<const SwFlyFrameFormat*>(pFlyFormat) ); // if a dialog was started inside a macro, then // MouseButtonUp arrives at macro and not to us. Therefore // flag is always set here and will never be switched to // respective Shell !!!!!!!
g_bNoInterrupt = false;
} elseif( !pFlyFormat || RES_DRAWFRMFMT == pFlyFormat->Which() )
{ // --> assure consistent cursor
pSh->KillPams();
pSh->ClearMark(); if (pNewDrawFormat)
{ // If we selected a draw shape format, move the cursor to its anchor position. // SetCursor() may pick something inside, which is not wanted: code later assumes that // the cursor is at the anchor point if a shape is selected. const SwPosition* pContentAnchor = pNewDrawFormat->GetAnchor().GetContentAnchor(); if (pContentAnchor)
{
pSh->SetSelection(SwPaM(*pContentAnchor));
}
} else
{
pSh->SetCursor( pSh->Imp()->GetDrawView()->GetAllMarkedRect().TopLeft(), true);
}
}
}
bool SwFEShell::SelectObj( const Point& rPt, sal_uInt8 nFlag, SdrObject *pObj )
{
SwDrawView *pDView = Imp()->GetDrawView(); if(!pDView) returnfalse;
CurrShell aCurr( this );
StartAction(); // action is necessary to assure only one AttrChgdNotify // (e.g. due to Unmark->MarkListHasChgd) arrives
if( bHadSelection )
{ // call Unmark when !bAddSelect or if fly was selected bool bUnmark = !bAddSelect;
if ( rMrkList.GetMarkCount() == 1 )
{ // if fly was selected, deselect it first
pOldSelFly = ::GetFlyFromMarked( &rMrkList, this ); if ( pOldSelFly )
{ const sal_uInt16 nType = GetCntType(); if( nType != CNT_TXT || (SW_LEAVE_FRAME & nFlag) ||
( pOldSelFly->GetFormat()->GetProtect().IsContentProtected()
&& !IsReadOnlyAvailable() ))
{
SdrObject *pOldObj = rMrkList.GetMark(0)->GetMarkedSdrObj(); // If a fly is deselected, which contains graphic, OLE or // otherwise, the cursor should be removed from it. // Similar if a fly with protected content is deselected. // For simplicity we put the cursor next to the upper-left // corner.
Point aPt( pOldSelFly->getFrameArea().Pos() );
aPt.setX(aPt.getX() - 1); bool bUnLockView = !IsViewLocked();
LockView( true );
SetCursor( aPt, true );
// in tables, fix lost position, when the selected image was // anchored as character at beginning of the table row: // in this case, the text cursor was positionated after the // floating table, and not before the image, as in other positions // in the table row (and if the table wasn't a floating one, // the text cursor lost completely) if ( SW_LEAVE_FRAME & nFlag )
{ const SwContact* pContact = GetUserCall(pOldObj); if ( pContact && pContact->ObjAnchoredAsChar() &&
pOldSelFly->GetAnchorFrame() &&
pOldSelFly->GetAnchorFrame()->GetUpper() )
{ const SwNode * pOldNd = pContact->GetAnchorNode().FindTableNode(); const SwNode * pNewNd = GetCursor()->GetPointNode().FindTableNode(); // the original image was in a table, but the cursor is not in that if ( pOldNd && pOldNd != pNewNd )
{ const SwRect& rCellFrame =
pOldSelFly->GetAnchorFrame()->GetUpper()->getFrameArea();
Point aPtCellTopRight( rCellFrame.Pos() );
aPtCellTopRight.setX( aPtCellTopRight.X() + rCellFrame.Width() ); if ( SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(this) ) // put the text cursor in the same cell
pWrtShell->SelectTableRowCol( aPtCellTopRight );
} // same table, but not in the same cell elseif ( pOldNd && pOldNd == pNewNd &&
GetCursor()->GetPointNode().GetTextNode() &&
pContact->GetAnchorNode().GetTableBox() !=
GetCursor()->GetPointNode().GetTextNode()->GetTableBox() )
{
aPt.setX( aPt.getX() + 2 + pOldSelFly->getFrameArea().Width() ); // put the text cursor after the object
SetCursor( aPt, true );
}
}
}
if ( rMrkList.GetMarkCount() > 1 )
{ // It sucks if Drawing objects were selected and now // additionally a fly is selected. for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
SdrObject *pTmpObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); bool bForget = dynamic_cast<const SwVirtFlyDrawObj*>( pTmpObj) != nullptr; if( bForget )
{
pDView->UnmarkAll();
pDView->MarkObj( pTmpObj, Imp()->GetPageView(), bAddSelect, bEnterGroup ); break;
}
}
}
if (rMrkList.GetMarkCount() == 1)
{
SwFlyFrame* pSelFly = ::GetFlyFromMarked(&rMrkList, this); if (pSelFly && pSelFly->IsFlySplitAllowed())
{ auto pMaster = static_cast<SwFlyAtContentFrame*>(pSelFly); while (pMaster->IsFollow())
{
pMaster = pMaster->GetPrecede();
} if (pMaster != pSelFly)
{ // A follow fly frame is selected, select the master instead. Selection of a follow // would not be ideal, since one can't customize its vertical position (always // starts at the top of the page).
pDView->UnmarkAll();
pDView->MarkObj(pMaster->DrawObj(), Imp()->GetPageView(), bAddSelect, bEnterGroup);
}
}
}
if ( rMrkList.GetMarkCount() == 1 )
{
SwFlyFrame *pSelFly = ::GetFlyFromMarked( &rMrkList, this ); if (pSelFly)
pSelFly->SelectionHasChanged(this);
}
SwFrameFormat* pNewDrawFormat = nullptr; if (!(nFlag & SW_ALLOW_TEXTBOX))
{ // If the fly frame is a textbox of a shape, then select the shape instead. for (size_t i = 0; i < rMrkList.GetMarkCount(); ++i)
{
SdrObject* pObject = rMrkList.GetMark(i)->GetMarkedSdrObj();
SwContact* pContact = GetUserCall(pObject); if (!pContact)
{ continue;
}
SwFrameFormat* pFormat = pContact->GetFormat(); if (SwFrameFormat* pShapeFormat = SwTextBoxHelper::getOtherTextBoxFormat(pFormat, RES_FLYFRMFMT))
{
SdrObject* pShape = pShapeFormat->FindSdrObject();
pDView->UnmarkAll();
pDView->MarkObj(pShape, Imp()->GetPageView(), bAddSelect, bEnterGroup); // Remember that this frame format was marked for selection.
pNewDrawFormat = pShapeFormat; break;
}
}
}
// update status line
::FrameNotify( this, bRet ? FLY_DRAG_START : FLY_DRAG_END );
EndAction(); return bRet;
}
/* * Description: MoveAnchor( nDir ) looked for an another Anchor for * the selected drawing object (or fly frame) in the given direction. * An object "as character" doesn't moves anyway. * A page bounded object could move to the previous/next page with up/down, * an object bounded "at paragraph" moves to the previous/next paragraph, too. * An object bounded "at character" moves to the previous/next paragraph * with up/down and to the previous/next character with left/right. * If the anchor for at paragraph/character bounded objects has vertical or * right_to_left text direction, the directions for up/down/left/right will * interpreted accordingly. * An object bounded "at fly" takes the center of the actual anchor and looks * for the nearest fly frame in the given direction.
*/
if( pNewFly )
{
SwPosition aPos( *pNewFly->GetFormat()->
GetContent().GetContentIdx());
aAnch.SetAnchor( &aPos );
bRet = true;
} break;
} default: break;
} if( bRet )
{
StartAllAction(); // --> handle change of anchor node: // if count of the anchor frame also change, the fly frames have to be // re-created. Thus, delete all fly frames except the <this> before the // anchor attribute is change and re-create them afterwards.
{
std::unique_ptr<SwHandleAnchorNodeChg> pHandleAnchorNodeChg;
SwFlyFrameFormat* pFlyFrameFormat( dynamic_cast<SwFlyFrameFormat*>(pFormat) ); if ( pFlyFrameFormat )
{
pHandleAnchorNodeChg.reset( new SwHandleAnchorNodeChg( *pFlyFrameFormat, aAnch ));
}
pFormat->GetDoc().SetAttr( aAnch, *pFormat );
} // #i28701# - no call of method // <CheckCharRectAndTopOfLine()> for to-character anchored // Writer fly frame needed. This method call can cause a // format of the anchor frame, which is no longer intended. // Instead clear the anchor character rectangle and // the top of line values for all to-character anchored objects.
pAnchoredObj->ClearCharRectAndTopOfLine();
EndAllAction();
}
} return bRet;
}
// get marked frame list, and check if anything is selected const SdrMarkList* pMarkList = GetMarkList_(); if( pMarkList == nullptr || pMarkList->GetMarkCount() == 0 )
eType = FrameTypeFlags::NONE; else
{ // obtain marked item as fly frame; if no fly frame, it must // be a draw object const SwFlyFrame* pFly = ::GetFlyFromMarked(pMarkList, const_cast<SwFEShell*>(this)); if ( pFly != nullptr )
{ if( pFly->IsFlyLayFrame() )
eType = FrameTypeFlags::FLY_FREE; elseif( pFly->IsFlyAtContentFrame() )
eType = FrameTypeFlags::FLY_ATCNT; else
{
OSL_ENSURE( pFly->IsFlyInContentFrame(), "New frametype?" );
eType = FrameTypeFlags::FLY_INCNT;
}
} else
eType = FrameTypeFlags::DRAWOBJ;
}
return eType;
}
// does the draw selection contain a control? bool SwFEShell::IsSelContainsControl() const
{ bool bRet = false;
// basically, copy the mechanism from GetSelFrameType(), but call // CheckControl... if you get a drawing object const SdrMarkList* pMarkList = GetMarkList_(); if( pMarkList != nullptr && pMarkList->GetMarkCount() == 1 )
{ // if we have one marked object, get the SdrObject and check // whether it contains a control const SdrObject* pSdrObject = pMarkList->GetMark( 0 )->GetMarkedSdrObj();
bRet = pSdrObject && ::CheckControlLayer( pSdrObject );
} return bRet;
}
// If more than a single SwVirtFlyDrawObj is selected, select only the first SwVirtFlyDrawObj if ( rMarkList.GetMarkCount() > 1 )
{ for ( size_t i = 0; i < rMarkList.GetMarkCount(); ++i )
{
SdrObject *pTmpObj = rMarkList.GetMark( i )->GetMarkedSdrObj(); bool bForget = dynamic_cast<const SwVirtFlyDrawObj*>( pTmpObj) != nullptr; if( bForget )
{
pView->UnmarkAll();
pView->MarkObj( pTmpObj, Imp()->GetPageView() ); break;
}
}
}
// #50778# Bug during dragging: In StartAction a HideShowXor is called. // In EndDragObj() this is reversed, for no reason and even wrong. // To restore consistency we should bring up the Xor again.
// Reanimation from the hack #50778 to fix bug #97057 // May be not the best solution, but the one with lowest risc at the moment. // pView->ShowShownXor( GetOut() );
pView->EndDragObj();
// DrawUndo on to flyframes are not stored // The flys change the flag.
GetDoc()->GetIDocumentUndoRedo().DoDrawUndo(true);
ChgAnchor( RndStdIds::FLY_AT_PARA, true );
// If a fly is selected, pulls the crsr in the first ContentFrame const SwFrameFormat* SwFEShell::SelFlyGrabCursor()
{ if ( Imp()->HasDrawView() )
{ const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList();
SwFlyFrame *pFly = ::GetFlyFromMarked( &rMrkList, this );
if( pFly )
{
SwContentFrame *pCFrame = pFly->ContainsContent(); if ( pCFrame )
{ // --> assure, that the cursor is consistent.
KillPams();
ClearMark();
SwPaM *pCursor = GetCursor();
// Selection to above/below (Z-Order) staticvoid lcl_NotifyNeighbours( const SdrMarkList *pLst )
{ // Rules for evasion have changed. // 1. The environment of the fly and everything inside should be notified // 2. The content of the frame itself has to be notified // 3. Frames displaced by the frame have to be notified // 4. Also Drawing objects can displace frames for( size_t j = 0; j < pLst->GetMarkCount(); ++j )
{
SwPageFrame *pPage; bool bCheckNeighbours = false;
sal_Int16 aHori = text::HoriOrientation::NONE;
SwRect aRect;
SdrObject *pO = pLst->GetMark( j )->GetMarkedSdrObj(); if (SwVirtFlyDrawObj* pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pO))
{
SwFlyFrame *pFly = pVirtO->GetFlyFrame();
// Does the selection contain a textbox? for (size_t i = 0; i < rMrkList.GetMarkCount(); i++) if (auto pObj = rMrkList.GetMark(i)->GetMarkedSdrObj()) // Get the textbox-shape if (auto pFormat = FindFrameFormat(pObj))
{ // If it has not textframe skip... if (!SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj)) continue; // If it has a textframe so it is a textbox, get its page if (auto pDrwModel
= pFormat->GetDoc().getIDocumentDrawModelAccess().GetDrawModel()) // Not really understood why everything is on page 0... // but it is easier to handle sdrobjects, that's true if (auto pPage = pDrwModel->GetPage(0))
{ // nShift: it means how many layers the pObj have to be shifted up, // in order not to interfere with other shapes and textboxes. // Situations: // - The next shape has textframe: This shape have to shifted with // two layers. // - The next shape has not got textframe: This shape have to be // shifted only one layer up. // - The next shape is null: // - This shape is already at heaven: Only the textframe have // to be adjusted.
sal_uInt32 nShift = 0; // Get the one level higher object (note: can be nullptr!) constauto pNextObj = pPage->SetObjectOrdNum(pObj->GetOrdNum() + 1, pObj->GetOrdNum() + 1); // If there is a higher object (not null)... if (pNextObj)
{ // One level shift is necessary
nShift++; // If this object is a textbox, two level increasing needed // (one for the shape and one for the frame) if (auto pNextFormat = FindFrameFormat(pNextObj)) if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT, pNextObj)
|| SwTextBoxHelper::isTextBox(pNextFormat, RES_FLYFRMFMT))
nShift++;
} // Set the new z-order.
pPage->SetObjectOrdNum(pObj->GetOrdNum(), pObj->GetOrdNum() + nShift);
} // The shape is on the right level, correct the layer of the frame
SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat, pObj);
}
// If the selection has textbox for(size_t i = 0; i < rMrkList.GetMarkCount(); i++) if (auto pObj = rMrkList.GetMark(i)->GetMarkedSdrObj()) // Get the shape of the textbox if (auto pFormat = FindFrameFormat(pObj))
{ // If the shape has not textframes skip. if (!SwTextBoxHelper::isTextBox(pFormat, RES_DRAWFRMFMT, pObj)) continue; // If has, move the shape to correct level with... if (auto pDrwModel
= pFormat->GetDoc().getIDocumentDrawModelAccess().GetDrawModel()) if (auto pPage = pDrwModel->GetPage(0))
{
sal_uInt32 nOrdNum = pObj->GetOrdNum();
assert(nOrdNum > 0); constauto pNextObj = pPage->SetObjectOrdNum(nOrdNum - 1, nOrdNum - 1); // If there is a lower object (not null)... if (pNextObj)
{ // If the lower has no textframe, just do nothing, else move by one lower if (auto pNextFormat = FindFrameFormat(pNextObj)) if (SwTextBoxHelper::isTextBox(pNextFormat, RES_DRAWFRMFMT, pNextObj)
|| SwTextBoxHelper::isTextBox(pNextFormat, RES_FLYFRMFMT))
pPage->SetObjectOrdNum(pObj->GetOrdNum(), pObj->GetOrdNum() - 1);
}
} // And set correct layer for the selected textbox.
SwTextBoxHelper::DoTextBoxZOrderCorrection(pFormat, pObj);
}
// Object above/below the document // Note: only visible objects can be marked. Thus, objects with invisible // layer IDs have not to be considered. // If <SwFEShell> exists, layout exists!! void SwFEShell::ChangeOpaque( SdrLayerID nLayerId )
{ if ( !Imp()->HasDrawView() ) return;
const SdrMarkList &rMrkList = Imp()->GetDrawView()->GetMarkedObjectList(); const IDocumentDrawModelAccess& rIDDMA = getIDocumentDrawModelAccess(); // correct type of <nControls> for ( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
{
SdrObject* pObj = rMrkList.GetMark( i )->GetMarkedSdrObj(); if( !pObj ) continue; // or group objects containing controls. // --> #i113730# // consider that a member of a drawing group has been selected. const SwContact* pContact = ::GetUserCall( pObj );
OSL_ENSURE( pContact && pContact->GetMaster(), " - missing contact or missing master object at contact!" ); constbool bControlObj = ( pContact && pContact->GetMaster() )
? ::CheckControlLayer( pContact->GetMaster() )
: ::CheckControlLayer( pObj ); if ( !bControlObj && pObj->GetLayer() != nLayerId )
{
pObj->SetLayer( nLayerId );
InvalidateWindows( SwRect( pObj->GetCurrentBoundRect() ) ); if (SwVirtFlyDrawObj* pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pObj))
{
SwFormat *pFormat = pVirtO->GetFlyFrame()->GetFormat();
SvxOpaqueItem aOpa( pFormat->GetOpaque() );
aOpa.SetValue( nLayerId == rIDDMA.GetHellId() );
pFormat->SetFormatAttr( aOpa ); // If pObj has textframe, put its textframe to the right level if (auto pTextBx = FindFrameFormat(pObj))
SwTextBoxHelper::DoTextBoxZOrderCorrection(pTextBx, pObj);
}
}
}
GetDoc()->getIDocumentState().SetModified();
}
void SwFEShell::EndTextEdit()
{ // Terminate the TextEditMode. If required (default if the object // does not contain any more text and does not carry attributes) the object // is deleted. All other objects marked are preserved.
OSL_ENSURE( Imp()->HasDrawView() && Imp()->GetDrawView()->IsTextEdit(), "EndTextEdit a no Object" );
// Test if there is an object at that position and if it should be selected. bool SwFEShell::ShouldObjectBeSelected(const Point& rPt, bool *pSelectFrameInsteadOfCroppedImage)
{
CurrShell aCurr(this);
SwDrawView *pDrawView = Imp()->GetDrawView(); bool bRet(false);
// within table row, where image cropped by the fixed table row height, // click position must be in the cell frame, where the image anchored as character if ( bRet && pContact && pContact->ObjAnchoredAsChar() )
{ if ( const SwTableBox *pBox = pContact->GetAnchorNode().GetTableBox() )
{
SwIterator<SwCellFrame, SwFormat> aIter( *pBox->GetFrameFormat() ); bool bContainsClickPosition = false; for (SwCellFrame* pFrame = aIter.First(); pFrame; pFrame = aIter.Next())
{ const SwRect& rRect = pFrame->getFrameArea(); // click inside the cell frame which contains the cropped image if ( rRect.Contains( rPt ) )
{ // click next to the right cell border if ( pSelectFrameInsteadOfCroppedImage &&
!rRect.Contains( Point(rPt.X() + 2 * nHitTol, rPt.Y()) ) )
{
*pSelectFrameInsteadOfCroppedImage = true;
}
bContainsClickPosition = true; break;
} // or click on the right table border of the same table frame elseif ( pSelectFrameInsteadOfCroppedImage &&
( pFrame->GetUpper() && pFrame->GetUpper()->GetUpper() &&
pFrame->GetUpper()->GetUpper()->getFrameArea().Contains(
Point(rPt.X() - 2 * nHitTol, rPt.Y()) ) &&
!pFrame->GetUpper()->GetUpper()->getFrameArea().Contains(
Point(rPt.X() + 2 * nHitTol, rPt.Y()) ) ) )
{
*pSelectFrameInsteadOfCroppedImage = true;
bContainsClickPosition = true;
}
} if ( !bContainsClickPosition )
bRet = false;
}
}
}
}
return bRet;
}
/* * If an object was selected, we assume its upper-left corner * otherwise the middle of the current CharRects. * Does the object include a control or groups, * which comprise only controls
*/ staticbool lcl_IsControlGroup( const SdrObject *pObj )
{ bool bRet = false; if(dynamic_cast<const SdrUnoObj*>( pObj) != nullptr)
bRet = true; elseif( auto pObjGroup = dynamic_cast<const SdrObjGroup*>( pObj) )
{
bRet = true; const SdrObjList *pLst = pObjGroup->GetSubList(); for (const rtl::Reference<SdrObject>& pChildObj : *pLst) if( !::lcl_IsControlGroup( pChildObj.get() ) ) returnfalse;
} return bRet;
}
namespace
{ class MarkableObjectsOnly : public svx::ISdrObjectFilter
{ public: explicit MarkableObjectsOnly( SdrPageView* i_pPV )
:m_pPV( i_pPV )
{
}
// If an object inside a group is selected, we want to // iterate over the group members. if ( ! pStartObj->GetUserCall() )
pList = pStartObj->getParentSdrObjListFromSdrObject();
} else
{ // If no object is selected, we check if we just entered a group. // In this case we want to iterate over the group members.
aPos = GetCharRect().Center(); const SdrObject* pStartObj = pPV ? pPV->GetCurrentGroup() : nullptr; if ( dynamic_cast<const SdrObjGroup*>( pStartObj) )
pList = pStartObj->GetSubList();
}
if ( ! pList )
{ // Here we are if // A No object has been selected and no group has been entered or // B An object has been selected and it is not inside a group
pList = getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 );
}
OSL_ENSURE( pList, "No object list to iterate" );
SdrObjListIter aObjIter( pList, bFlat ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups ); while ( aObjIter.IsMore() )
{
SdrObject* pObj = aObjIter.Next();
SwVirtFlyDrawObj *pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pObj); if( ( bNoFly && pVirtO ) ||
( bNoDraw && !pVirtO ) || // Ignore TextBoxes of draw shapes here, so that // SwFEShell::SelectObj() won't jump back on this list, meaning // we never jump to the next draw shape.
(pVirtO && pVirtO->IsTextBox()) ||
( eType == GotoObjFlags::DrawSimple && lcl_IsControlGroup( pObj ) ) ||
( eType == GotoObjFlags::DrawControl && !lcl_IsControlGroup( pObj ) ) ||
!pFilter->includeObject( *pObj ) ) continue; if (pVirtO)
{
SwFlyFrame *pFly = pVirtO->GetFlyFrame(); if( GotoObjFlags::FlyAny != ( GotoObjFlags::FlyAny & eType ) )
{ switch ( eType )
{ case GotoObjFlags::FlyFrame: if ( pFly->Lower() && pFly->Lower()->IsNoTextFrame() ) continue; break; case GotoObjFlags::FlyGrf: if ( pFly->Lower() &&
(!pFly->Lower()->IsNoTextFrame() ||
!static_cast<SwNoTextFrame*>(pFly->Lower())->GetNode()->GetGrfNode())) continue; break; case GotoObjFlags::FlyOLE: if ( pFly->Lower() &&
(!pFly->Lower()->IsNoTextFrame() ||
!static_cast<SwNoTextFrame*>(pFly->Lower())->GetNode()->GetOLENode())) continue; break; default: break;
}
}
aCurPos = pFly->getFrameArea().Pos();
} else
aCurPos = pObj->GetSnapRect().TopLeft();
// Special case if another object is on same Y. if( aCurPos != aPos && // only when it is not me
aCurPos.getY() == aPos.getY() && // Y positions equal
(bNext? (aCurPos.getX() > aPos.getX()) : // lies next to me
(aCurPos.getX() < aPos.getX())) ) // " reverse
{
aBestPos = Point( nTmp, nTmp );
SdrObjListIter aTmpIter( pList, bFlat ? SdrIterMode::Flat : SdrIterMode::DeepNoGroups ); while ( aTmpIter.IsMore() )
{
SdrObject* pTmpObj = aTmpIter.Next();
pVirtO = dynamic_cast<SwVirtFlyDrawObj*>(pTmpObj); if( ( bNoFly && pVirtO ) || ( bNoDraw && !pVirtO ) ) continue; if (pVirtO)
{
aCurPos = pVirtO->GetFlyFrame()->getFrameArea().Pos();
} else
aCurPos = pTmpObj->GetCurrentBoundRect().TopLeft();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.