e164e61f46
this
commit 43be09b29c
Author: Noel Grandin <noel.grandin@collabora.co.uk>
Date: Fri Sep 6 15:27:43 2024 +0200
return SwDrawFrameFormat from SwContact::GetFrameFormat
since we can also have SwFlyFrameFormat* being returned there
Change-Id: Ide064ec39ccb99f3a166b869c552f54f482b9bcd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173108
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
715 lines
28 KiB
C++
715 lines
28 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 <hintids.hxx>
|
|
#include <editeng/flditem.hxx>
|
|
#include <editeng/editeng.hxx>
|
|
#include <editeng/colritem.hxx>
|
|
#include <svx/svdpage.hxx>
|
|
#include <svx/svdogrp.hxx>
|
|
#include <editeng/measfld.hxx>
|
|
#include <sal/log.hxx>
|
|
#include <osl/diagnose.h>
|
|
#include <fmtanchr.hxx>
|
|
#include <charatr.hxx>
|
|
#include <frmfmt.hxx>
|
|
#include <charfmt.hxx>
|
|
#include <viewimp.hxx>
|
|
#include <doc.hxx>
|
|
#include <docfunc.hxx>
|
|
#include <IDocumentUndoRedo.hxx>
|
|
#include <IDocumentDrawModelAccess.hxx>
|
|
#include <IDocumentState.hxx>
|
|
#include <IDocumentLayoutAccess.hxx>
|
|
#include <IDocumentStylePoolAccess.hxx>
|
|
#include <poolfmt.hxx>
|
|
#include <drawdoc.hxx>
|
|
#include <UndoDraw.hxx>
|
|
#include <swundo.hxx>
|
|
#include <dcontact.hxx>
|
|
#include <dview.hxx>
|
|
#include <mvsave.hxx>
|
|
#include <flyfrm.hxx>
|
|
#include <dflyobj.hxx>
|
|
#include <txtfrm.hxx>
|
|
#include <editeng/frmdiritem.hxx>
|
|
#include <fmtornt.hxx>
|
|
#include <svx/svditer.hxx>
|
|
|
|
#include <vector>
|
|
|
|
using namespace ::com::sun::star;
|
|
|
|
/** local method to determine positioning and alignment attributes for a drawing
|
|
* object, which is newly connected to the layout.
|
|
*
|
|
* Used for a newly formed group object <SwDoc::GroupSelection(..)>
|
|
* and the members of a destroyed group <SwDoc::UnGroupSelection(..)>
|
|
*/
|
|
static void lcl_AdjustPositioningAttr( SwDrawFrameFormat* _pFrameFormat,
|
|
const SdrObject& _rSdrObj )
|
|
{
|
|
const SwContact* pContact = GetUserCall( &_rSdrObj );
|
|
OSL_ENSURE( pContact, "<lcl_AdjustPositioningAttr(..)> - missing contact object." );
|
|
|
|
if (!pContact)
|
|
return;
|
|
|
|
// determine position of new group object relative to its anchor frame position
|
|
SwTwips nHoriRelPos = 0;
|
|
SwTwips nVertRelPos = 0;
|
|
{
|
|
const SwFrame* pAnchorFrame = pContact->GetAnchoredObj( &_rSdrObj )->GetAnchorFrame();
|
|
OSL_ENSURE( !pAnchorFrame ||
|
|
!pAnchorFrame->IsTextFrame() ||
|
|
!static_cast<const SwTextFrame*>(pAnchorFrame)->IsFollow(),
|
|
"<lcl_AdjustPositioningAttr(..)> - anchor frame is a follow." );
|
|
bool bVert = false;
|
|
bool bR2L = false;
|
|
// #i45952# - use anchor position of anchor frame, if it exist.
|
|
Point aAnchorPos;
|
|
if ( pAnchorFrame )
|
|
{
|
|
// #i45952#
|
|
aAnchorPos = pAnchorFrame->GetFrameAnchorPos( ::HasWrap( &_rSdrObj ) );
|
|
bVert = pAnchorFrame->IsVertical();
|
|
bR2L = pAnchorFrame->IsRightToLeft();
|
|
}
|
|
else
|
|
{
|
|
// #i45952#
|
|
aAnchorPos = _rSdrObj.GetAnchorPos();
|
|
// If no anchor frame exist - e.g. because no layout exists - the
|
|
// default layout direction is taken.
|
|
const SvxFrameDirectionItem& rDirItem =
|
|
_pFrameFormat->GetAttrSet().GetPool()->GetUserOrPoolDefaultItem( RES_FRAMEDIR );
|
|
switch ( rDirItem.GetValue() )
|
|
{
|
|
case SvxFrameDirection::Vertical_LR_TB:
|
|
{
|
|
// vertical from left-to-right
|
|
bVert = true;
|
|
bR2L = true;
|
|
OSL_FAIL( "<lcl_AdjustPositioningAttr(..)> - vertical from left-to-right not supported." );
|
|
}
|
|
break;
|
|
case SvxFrameDirection::Vertical_RL_TB:
|
|
{
|
|
// vertical from right-to-left
|
|
bVert = true;
|
|
bR2L = false;
|
|
}
|
|
break;
|
|
case SvxFrameDirection::Horizontal_RL_TB:
|
|
{
|
|
// horizontal from right-to-left
|
|
bVert = false;
|
|
bR2L = true;
|
|
}
|
|
break;
|
|
case SvxFrameDirection::Horizontal_LR_TB:
|
|
{
|
|
// horizontal from left-to-right
|
|
bVert = false;
|
|
bR2L = false;
|
|
}
|
|
break;
|
|
case SvxFrameDirection::Environment:
|
|
SAL_WARN("sw.core", "lcl_AdjustPositioningAttr(..) SvxFrameDirection::Environment not supported");
|
|
break;
|
|
default: break;
|
|
}
|
|
|
|
}
|
|
// use geometry of drawing object
|
|
const tools::Rectangle aObjRect = _rSdrObj.GetSnapRect();
|
|
|
|
if ( bVert )
|
|
{
|
|
if ( bR2L ) {
|
|
//SvxFrameDirection::Vertical_LR_TB
|
|
nHoriRelPos = aObjRect.Left() - aAnchorPos.getX();
|
|
nVertRelPos = aObjRect.Top() - aAnchorPos.getY();
|
|
} else {
|
|
//SvxFrameDirection::Vertical_RL_TB
|
|
nHoriRelPos = aObjRect.Top() - aAnchorPos.getY();
|
|
nVertRelPos = aAnchorPos.getX() - aObjRect.Right();
|
|
}
|
|
}
|
|
else if ( bR2L )
|
|
{
|
|
nHoriRelPos = aAnchorPos.getX() - aObjRect.Right();
|
|
nVertRelPos = aObjRect.Top() - aAnchorPos.getY();
|
|
}
|
|
else
|
|
{
|
|
nHoriRelPos = aObjRect.Left() - aAnchorPos.getX();
|
|
nVertRelPos = aObjRect.Top() - aAnchorPos.getY();
|
|
}
|
|
}
|
|
|
|
_pFrameFormat->SetFormatAttr( SwFormatHoriOrient( nHoriRelPos, text::HoriOrientation::NONE, text::RelOrientation::FRAME ) );
|
|
_pFrameFormat->SetFormatAttr( SwFormatVertOrient( nVertRelPos, text::VertOrientation::NONE, text::RelOrientation::FRAME ) );
|
|
// #i44334#, #i44681# - positioning attributes already set
|
|
_pFrameFormat->PosAttrSet();
|
|
// #i34750# - keep current object rectangle for drawing
|
|
// objects. The object rectangle is used on events from the drawing layer
|
|
// to adjust the positioning attributes - see <SwDrawContact::Changed_(..)>.
|
|
{
|
|
const SwAnchoredObject* pAnchoredObj = pContact->GetAnchoredObj( &_rSdrObj );
|
|
if ( auto pAnchoredDrawObj = dynamic_cast<const SwAnchoredDrawObject*>( pAnchoredObj) )
|
|
{
|
|
const tools::Rectangle aObjRect = _rSdrObj.GetSnapRect();
|
|
const_cast<SwAnchoredDrawObject*>(pAnchoredDrawObj)
|
|
->SetLastObjRect( aObjRect );
|
|
}
|
|
}
|
|
}
|
|
|
|
SwDrawContact* SwDoc::GroupSelection( SdrView& rDrawView )
|
|
{
|
|
// replace marked 'virtual' drawing objects by the corresponding 'master'
|
|
// drawing objects.
|
|
SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
|
|
|
|
const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
|
|
SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
bool bNoGroup = ( nullptr == pObj->getParentSdrObjectFromSdrObject() );
|
|
SwDrawContact* pNewContact = nullptr;
|
|
if( bNoGroup )
|
|
{
|
|
SwDrawFrameFormat *pFormat = nullptr;
|
|
|
|
// Revoke anchor attribute.
|
|
SwDrawContact *pMyContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
|
|
if (!pMyContact)
|
|
return pNewContact;
|
|
|
|
const SwFormatAnchor aAnch( pMyContact->GetFormat()->GetAnchor() );
|
|
|
|
std::unique_ptr<SwUndoDrawGroup> pUndo;
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
pUndo.reset(new SwUndoDrawGroup( o3tl::narrowing<sal_uInt16>(rMrkList.GetMarkCount()), *this));
|
|
|
|
// #i53320#
|
|
bool bGroupMembersNotPositioned( false );
|
|
{
|
|
SwAnchoredDrawObject* pAnchoredDrawObj =
|
|
static_cast<SwAnchoredDrawObject*>(pMyContact->GetAnchoredObj( pObj ));
|
|
bGroupMembersNotPositioned = pAnchoredDrawObj->NotYetPositioned();
|
|
}
|
|
|
|
std::map<const SdrObject*, SwFrameFormat*> vSavedTextBoxes;
|
|
// Destroy ContactObjects and formats.
|
|
for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
|
|
{
|
|
pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
|
|
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
|
|
|
|
if (!pContact)
|
|
continue;
|
|
|
|
assert(pObj);
|
|
|
|
// #i53320#
|
|
#if OSL_DEBUG_LEVEL > 0
|
|
SwAnchoredDrawObject* pAnchoredDrawObj =
|
|
static_cast<SwAnchoredDrawObject*>(pContact->GetAnchoredObj( pObj ));
|
|
OSL_ENSURE( bGroupMembersNotPositioned == pAnchoredDrawObj->NotYetPositioned(),
|
|
"<SwDoc::GroupSelection(..)> - group members have different positioning status!" );
|
|
#endif
|
|
// Before the format will be killed, save its textbox for later use.
|
|
if (auto pShapeFormat = pContact->GetFormat())
|
|
if (auto pTextBoxNode = pShapeFormat->GetOtherTextBoxFormats())
|
|
for (const auto& rTextBoxElement : pTextBoxNode->GetAllTextBoxes())
|
|
vSavedTextBoxes.emplace(rTextBoxElement);
|
|
|
|
pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
|
|
// Deletes itself!
|
|
pContact->Changed(*pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
|
|
pObj->SetUserCall( nullptr );
|
|
|
|
if( pUndo )
|
|
pUndo->AddObj( i, pFormat, pObj );
|
|
else
|
|
DelFrameFormat( pFormat );
|
|
|
|
// #i45952# - re-introduce position normalization of group member
|
|
// objects, because its anchor position is cleared, when they are
|
|
// grouped.
|
|
Point aAnchorPos( pObj->GetAnchorPos() );
|
|
pObj->NbcSetAnchorPos( Point( 0, 0 ) );
|
|
pObj->NbcMove( Size( aAnchorPos.getX(), aAnchorPos.getY() ) );
|
|
}
|
|
|
|
pFormat = MakeDrawFrameFormat( GetUniqueDrawObjectName(),
|
|
GetDfltFrameFormat() );
|
|
pFormat->SetFormatAttr( aAnch );
|
|
// #i36010# - set layout direction of the position
|
|
pFormat->SetPositionLayoutDir(
|
|
text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
|
|
|
|
// Add the saved textboxes to the new format.
|
|
auto pTextBoxNode = std::make_shared<SwTextBoxNode>(
|
|
SwTextBoxNode(static_cast<SwFrameFormat*>(pFormat)));
|
|
for (const auto& pTextBoxEntry : vSavedTextBoxes)
|
|
{
|
|
pTextBoxNode->AddTextBox(const_cast<SdrObject*>(pTextBoxEntry.first),
|
|
pTextBoxEntry.second);
|
|
pTextBoxEntry.second->SetOtherTextBoxFormats(pTextBoxNode);
|
|
}
|
|
pFormat->SetOtherTextBoxFormats(pTextBoxNode);
|
|
vSavedTextBoxes.clear();
|
|
|
|
rDrawView.GroupMarked();
|
|
OSL_ENSURE( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
|
|
|
|
SdrObject* pNewGroupObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
pNewGroupObj->SetName(pFormat->GetName());
|
|
pNewContact = new SwDrawContact( pFormat, pNewGroupObj );
|
|
// #i35635#
|
|
pNewContact->MoveObjToVisibleLayer( pNewGroupObj );
|
|
pNewContact->ConnectToLayout();
|
|
// #i53320# - No adjustment of the positioning and alignment
|
|
// attributes, if group members aren't positioned yet.
|
|
if ( !bGroupMembersNotPositioned )
|
|
{
|
|
// #i26791# - Adjust positioning and alignment attributes.
|
|
lcl_AdjustPositioningAttr( pFormat, *pNewGroupObj );
|
|
}
|
|
|
|
if( pUndo )
|
|
{
|
|
pUndo->SetGroupFormat( pFormat );
|
|
GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
{
|
|
GetIDocumentUndoRedo().ClearRedo();
|
|
}
|
|
|
|
rDrawView.GroupMarked();
|
|
OSL_ENSURE( rMrkList.GetMarkCount() == 1, "GroupMarked more or none groups." );
|
|
}
|
|
|
|
return pNewContact;
|
|
}
|
|
|
|
static void lcl_CollectTextBoxesForSubGroupObj(SwFrameFormat* pTargetFormat, std::shared_ptr<SwTextBoxNode> pTextBoxNode,
|
|
SdrObject* pSourceObjs)
|
|
{
|
|
if (auto pChildrenObjs = pSourceObjs->getChildrenOfSdrObject())
|
|
for (const rtl::Reference<SdrObject>& pSubObj : *pChildrenObjs)
|
|
lcl_CollectTextBoxesForSubGroupObj(pTargetFormat, pTextBoxNode, pSubObj.get());
|
|
else
|
|
{
|
|
if (auto pTextBox = pTextBoxNode->GetTextBox(pSourceObjs))
|
|
{
|
|
if (!pTargetFormat->GetOtherTextBoxFormats())
|
|
{
|
|
pTargetFormat->SetOtherTextBoxFormats(std::make_shared<SwTextBoxNode>(SwTextBoxNode(pTargetFormat)));
|
|
}
|
|
pTargetFormat->GetOtherTextBoxFormats()->AddTextBox(pSourceObjs, pTextBox);
|
|
pTextBox->SetOtherTextBoxFormats(pTargetFormat->GetOtherTextBoxFormats());
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void SwDoc::UnGroupSelection( SdrView& rDrawView )
|
|
{
|
|
bool const bUndo = GetIDocumentUndoRedo().DoesUndo();
|
|
if( bUndo )
|
|
{
|
|
GetIDocumentUndoRedo().ClearRedo();
|
|
}
|
|
|
|
// replace marked 'virtual' drawing objects by the corresponding 'master'
|
|
// drawing objects.
|
|
SwDrawView::ReplaceMarkedDrawVirtObjs( rDrawView );
|
|
|
|
const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
|
|
std::unique_ptr<std::vector< std::pair< SwDrawFrameFormat*, SdrObject* > >[]> pFormatsAndObjs;
|
|
const size_t nMarkCount( rMrkList.GetMarkCount() );
|
|
if ( nMarkCount )
|
|
{
|
|
pFormatsAndObjs.reset( new std::vector< std::pair< SwDrawFrameFormat*, SdrObject* > >[nMarkCount] );
|
|
SdrObject *pMyObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if( !pMyObj->getParentSdrObjectFromSdrObject() )
|
|
{
|
|
for ( size_t i = 0; i < nMarkCount; ++i )
|
|
{
|
|
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
|
|
if ( auto pObjGroup = dynamic_cast<SdrObjGroup*>(pObj) )
|
|
{
|
|
SwDrawContact *pContact = static_cast<SwDrawContact*>(GetUserCall(pObj));
|
|
|
|
if (!pContact)
|
|
continue;
|
|
|
|
std::shared_ptr<SwTextBoxNode> pTextBoxNode;
|
|
if (auto pGroupFormat = pContact->GetFormat())
|
|
pTextBoxNode = pGroupFormat->GetOtherTextBoxFormats();
|
|
|
|
SwFormatAnchor aAnch( pContact->GetFormat()->GetAnchor() );
|
|
SdrObjList *pLst = pObjGroup->GetSubList();
|
|
|
|
SwUndoDrawUnGroup* pUndo = nullptr;
|
|
if( bUndo )
|
|
{
|
|
pUndo = new SwUndoDrawUnGroup( pObjGroup, *this );
|
|
GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
|
|
}
|
|
|
|
for ( size_t i2 = 0; i2 < pLst->GetObjCount(); ++i2 )
|
|
{
|
|
SdrObject* pSubObj = pLst->GetObj( i2 );
|
|
SwDrawFrameFormat *pFormat = MakeDrawFrameFormat( GetUniqueShapeName(),
|
|
GetDfltFrameFormat() );
|
|
pFormat->SetFormatAttr( aAnch );
|
|
|
|
if (pTextBoxNode)
|
|
{
|
|
if (!pObj->getChildrenOfSdrObject())
|
|
{
|
|
if (auto pTextBoxFormat = pTextBoxNode->GetTextBox(pSubObj))
|
|
{
|
|
auto pNewTextBoxNode =std::make_shared<SwTextBoxNode>(SwTextBoxNode(pFormat));
|
|
pNewTextBoxNode->AddTextBox(pSubObj, pTextBoxFormat);
|
|
pFormat->SetOtherTextBoxFormats(pNewTextBoxNode);
|
|
pTextBoxFormat->SetOtherTextBoxFormats(pNewTextBoxNode);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
lcl_CollectTextBoxesForSubGroupObj(pFormat, pTextBoxNode, pSubObj);
|
|
}
|
|
}
|
|
// #i36010# - set layout direction of the position
|
|
pFormat->SetPositionLayoutDir(
|
|
text::PositionLayoutDir::PositionInLayoutDirOfAnchor );
|
|
if (pSubObj->GetName().isEmpty())
|
|
pSubObj->SetName(pFormat->GetName());
|
|
pFormatsAndObjs[i].emplace_back( pFormat, pSubObj );
|
|
|
|
if( bUndo )
|
|
pUndo->AddObj( o3tl::narrowing<sal_uInt16>(i2), pFormat );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
rDrawView.UnGroupMarked();
|
|
// creation of <SwDrawContact> instances for the former group members and
|
|
// its connection to the Writer layout.
|
|
for ( size_t i = 0; i < nMarkCount; ++i )
|
|
{
|
|
SwUndoDrawUnGroupConnectToLayout* pUndo = nullptr;
|
|
if( bUndo )
|
|
{
|
|
pUndo = new SwUndoDrawUnGroupConnectToLayout(*this);
|
|
GetIDocumentUndoRedo().AppendUndo(std::unique_ptr<SwUndo>(pUndo));
|
|
}
|
|
|
|
while ( !pFormatsAndObjs[i].empty() )
|
|
{
|
|
SwDrawFrameFormat* pFormat( pFormatsAndObjs[i].back().first );
|
|
SdrObject* pObj( pFormatsAndObjs[i].back().second );
|
|
pFormatsAndObjs[i].pop_back();
|
|
|
|
SwDrawContact* pContact = new SwDrawContact( pFormat, pObj );
|
|
pContact->MoveObjToVisibleLayer( pObj );
|
|
pContact->ConnectToLayout();
|
|
lcl_AdjustPositioningAttr( pFormat, *pObj );
|
|
|
|
if ( bUndo )
|
|
{
|
|
pUndo->AddFormatAndObj( pFormat, pObj );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool SwDoc::DeleteSelection( SwDrawView& rDrawView )
|
|
{
|
|
bool bCallBase = false;
|
|
const SdrMarkList &rMrkList = rDrawView.GetMarkedObjectList();
|
|
if( rMrkList.GetMarkCount() )
|
|
{
|
|
GetIDocumentUndoRedo().StartUndo(SwUndoId::EMPTY, nullptr);
|
|
bool bDelMarked = true;
|
|
|
|
if( 1 == rMrkList.GetMarkCount() )
|
|
{
|
|
SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if( auto pDrawObj = dynamic_cast<SwVirtFlyDrawObj*>( pObj) )
|
|
{
|
|
SwFlyFrameFormat* pFrameFormat = pDrawObj->GetFlyFrame()->GetFormat();
|
|
if( pFrameFormat )
|
|
{
|
|
getIDocumentLayoutAccess().DelLayoutFormat( pFrameFormat );
|
|
bDelMarked = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
|
|
{
|
|
SdrObject *pObj = rMrkList.GetMark( i )->GetMarkedSdrObj();
|
|
if( dynamic_cast<const SwVirtFlyDrawObj*>( pObj) == nullptr )
|
|
{
|
|
if (SwDrawContact* pC = static_cast<SwDrawContact*>(GetUserCall(pObj)))
|
|
{
|
|
SwDrawFrameFormat* pFrameFormat = static_cast<SwDrawFrameFormat*>(pC->GetFormat());
|
|
if (pFrameFormat
|
|
&& RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId())
|
|
{
|
|
rDrawView.MarkObj(pObj, rDrawView.Imp().GetPageView(), true);
|
|
--i;
|
|
getIDocumentLayoutAccess().DelLayoutFormat(pFrameFormat);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( rMrkList.GetMarkCount() && bDelMarked )
|
|
{
|
|
SdrObject *pObj = rMrkList.GetMark( 0 )->GetMarkedSdrObj();
|
|
if( !pObj->getParentSdrObjectFromSdrObject() )
|
|
{
|
|
std::unique_ptr<SwUndoDrawDelete> pUndo;
|
|
if (GetIDocumentUndoRedo().DoesUndo())
|
|
pUndo.reset(new SwUndoDrawDelete( o3tl::narrowing<sal_uInt16>(rMrkList.GetMarkCount()), *this ));
|
|
|
|
// Destroy ContactObjects, save formats.
|
|
for( size_t i = 0; i < rMrkList.GetMarkCount(); ++i )
|
|
{
|
|
const SdrMark& rMark = *rMrkList.GetMark( i );
|
|
pObj = rMark.GetMarkedSdrObj();
|
|
assert(pObj);
|
|
SwDrawContact *pContact = static_cast<SwDrawContact*>(pObj->GetUserCall());
|
|
if( pContact ) // of course not for grouped objects
|
|
{
|
|
SwDrawFrameFormat *pFormat = static_cast<SwDrawFrameFormat*>(pContact->GetFormat());
|
|
// before delete of selection is performed, marked
|
|
// <SwDrawVirtObj>-objects have to be replaced by its
|
|
// reference objects. Thus, assert, if a
|
|
// <SwDrawVirt>-object is found in the mark list.
|
|
if ( dynamic_cast<const SwDrawVirtObj*>( pObj) != nullptr )
|
|
{
|
|
OSL_FAIL( "<SwDrawVirtObj> is still marked for delete. application will crash!" );
|
|
}
|
|
// Deletes itself!
|
|
pContact->Changed(*pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
|
|
pObj->SetUserCall( nullptr );
|
|
|
|
if( pUndo )
|
|
pUndo->AddObj( pFormat, rMark );
|
|
else
|
|
DelFrameFormat( pFormat );
|
|
}
|
|
}
|
|
|
|
if( pUndo )
|
|
{
|
|
GetIDocumentUndoRedo().AppendUndo( std::move(pUndo) );
|
|
}
|
|
}
|
|
bCallBase = true;
|
|
}
|
|
getIDocumentState().SetModified();
|
|
|
|
GetIDocumentUndoRedo().EndUndo(SwUndoId::EMPTY, nullptr);
|
|
}
|
|
|
|
return bCallBase;
|
|
}
|
|
|
|
ZSortFly::ZSortFly(const SwFrameFormat* pFrameFormat, const SwFormatAnchor* pFlyAn, sal_uInt32 nArrOrdNum)
|
|
: m_pFormat(pFrameFormat)
|
|
, m_pAnchor(pFlyAn)
|
|
, m_nOrdNum(nArrOrdNum)
|
|
{
|
|
SAL_WARN_IF(m_pFormat->Which() != RES_FLYFRMFMT && m_pFormat->Which() != RES_DRAWFRMFMT, "sw.core", "What kind of format is this?");
|
|
m_pFormat->CallSwClientNotify(sw::GetZOrderHint(m_nOrdNum));
|
|
}
|
|
|
|
/// In the Outliner, set a link to the method for field display in edit objects.
|
|
void SwDoc::SetCalcFieldValueHdl(Outliner* pOutliner)
|
|
{
|
|
pOutliner->SetCalcFieldValueHdl(LINK(this, SwDoc, CalcFieldValueHdl));
|
|
}
|
|
|
|
/// Recognise fields/URLs in the Outliner and set how they are displayed.
|
|
IMPL_LINK(SwDoc, CalcFieldValueHdl, EditFieldInfo*, pInfo, void)
|
|
{
|
|
if (!pInfo)
|
|
return;
|
|
|
|
const SvxFieldItem& rField = pInfo->GetField();
|
|
const SvxFieldData* pField = rField.GetField();
|
|
|
|
if (auto pDateField = dynamic_cast<const SvxDateField*>( pField))
|
|
{
|
|
// Date field
|
|
pInfo->SetRepresentation(
|
|
pDateField->GetFormatted(
|
|
*GetNumberFormatter(), LANGUAGE_SYSTEM) );
|
|
}
|
|
else if (auto pURLField = dynamic_cast<const SvxURLField*>( pField))
|
|
{
|
|
// URL field
|
|
switch ( pURLField->GetFormat() )
|
|
{
|
|
case SvxURLFormat::AppDefault: //!!! Can be set in App???
|
|
case SvxURLFormat::Repr:
|
|
pInfo->SetRepresentation(pURLField->GetRepresentation());
|
|
break;
|
|
|
|
case SvxURLFormat::Url:
|
|
pInfo->SetRepresentation(pURLField->GetURL());
|
|
break;
|
|
}
|
|
|
|
sal_uInt16 nChrFormat;
|
|
|
|
if (IsVisitedURL(pURLField->GetURL()))
|
|
nChrFormat = RES_POOLCHR_INET_VISIT;
|
|
else
|
|
nChrFormat = RES_POOLCHR_INET_NORMAL;
|
|
|
|
SwFormat *pFormat = getIDocumentStylePoolAccess().GetCharFormatFromPool(nChrFormat);
|
|
|
|
Color aColor(COL_LIGHTBLUE);
|
|
if (pFormat)
|
|
aColor = pFormat->GetColor().GetValue();
|
|
|
|
pInfo->SetTextColor(aColor);
|
|
}
|
|
else if (dynamic_cast<const SdrMeasureField*>( pField))
|
|
{
|
|
// Clear measure field
|
|
pInfo->SetFieldColor(std::optional<Color>());
|
|
}
|
|
else if ( auto pTimeField = dynamic_cast<const SvxExtTimeField*>( pField) )
|
|
{
|
|
// Time field
|
|
pInfo->SetRepresentation(
|
|
pTimeField->GetFormatted(*GetNumberFormatter(), LANGUAGE_SYSTEM) );
|
|
}
|
|
else
|
|
{
|
|
OSL_FAIL("unknown field command");
|
|
pInfo->SetRepresentation( OUString( '?' ) );
|
|
}
|
|
}
|
|
|
|
// #i62875#
|
|
namespace docfunc
|
|
{
|
|
bool ExistsDrawObjs( SwDoc& p_rDoc )
|
|
{
|
|
bool bExistsDrawObjs( false );
|
|
|
|
if ( p_rDoc.getIDocumentDrawModelAccess().GetDrawModel() &&
|
|
p_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 ) )
|
|
{
|
|
const SdrPage& rSdrPage( *(p_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )) );
|
|
|
|
SdrObjListIter aIter( &rSdrPage, SdrIterMode::Flat );
|
|
while( aIter.IsMore() )
|
|
{
|
|
SdrObject* pObj( aIter.Next() );
|
|
if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
|
|
!dynamic_cast<SwFlyDrawObj*>(pObj) )
|
|
{
|
|
bExistsDrawObjs = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return bExistsDrawObjs;
|
|
}
|
|
|
|
bool AllDrawObjsOnPage( SwDoc& p_rDoc )
|
|
{
|
|
bool bAllDrawObjsOnPage( true );
|
|
|
|
if ( p_rDoc.getIDocumentDrawModelAccess().GetDrawModel() &&
|
|
p_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 ) )
|
|
{
|
|
const SdrPage& rSdrPage( *(p_rDoc.getIDocumentDrawModelAccess().GetDrawModel()->GetPage( 0 )) );
|
|
|
|
SdrObjListIter aIter( &rSdrPage, SdrIterMode::Flat );
|
|
while( aIter.IsMore() )
|
|
{
|
|
SdrObject* pObj( aIter.Next() );
|
|
if ( !dynamic_cast<SwVirtFlyDrawObj*>(pObj) &&
|
|
!dynamic_cast<SwFlyDrawObj*>(pObj) )
|
|
{
|
|
SwDrawContact* pDrawContact =
|
|
dynamic_cast<SwDrawContact*>(::GetUserCall( pObj ));
|
|
if ( pDrawContact )
|
|
{
|
|
SwAnchoredDrawObject* pAnchoredDrawObj =
|
|
dynamic_cast<SwAnchoredDrawObject*>(pDrawContact->GetAnchoredObj( pObj ));
|
|
|
|
// error handling
|
|
{
|
|
if ( !pAnchoredDrawObj )
|
|
{
|
|
OSL_FAIL( "<docfunc::AllDrawObjsOnPage() - missing anchored draw object" );
|
|
bAllDrawObjsOnPage = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ( pAnchoredDrawObj->NotYetPositioned() )
|
|
{
|
|
// The drawing object isn't yet layouted.
|
|
// Thus, it isn't known, if all drawing objects are on page.
|
|
bAllDrawObjsOnPage = false;
|
|
break;
|
|
}
|
|
else if ( pAnchoredDrawObj->IsOutsidePage() )
|
|
{
|
|
bAllDrawObjsOnPage = false;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// contact object of drawing object doesn't exists.
|
|
// Thus, the drawing object isn't yet positioned.
|
|
// Thus, it isn't known, if all drawing objects are on page.
|
|
bAllDrawObjsOnPage = false;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return bAllDrawObjsOnPage;
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|