/* -*- 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 .
*/
/** 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(..)>
*/ staticvoid lcl_AdjustPositioningAttr( SwDrawFrameFormat* _pFrameFormat, const SdrObject& _rSdrObj )
{ const SwContact* pContact = GetUserCall( &_rSdrObj );
OSL_ENSURE( pContact, " - 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(), " - 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( " - 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();
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(), " - 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 (constauto& rTextBoxElement : pTextBoxNode->GetAllTextBoxes())
vSavedTextBoxes.emplace(rTextBoxElement);
// #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 (constauto& 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().toString());
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 (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().toString());
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));
}
// 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( " is still marked for delete. application will crash!" );
} // Deletes itself!
pContact->Changed(*pObj, SdrUserCallType::Delete, pObj->GetLastBoundRect() );
pObj->SetUserCall( nullptr );
/// 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;
if (auto pDateField = dynamic_cast<const SvxDateField*>( pField))
{ // Date field
pInfo->SetRepresentation(
pDateField->GetFormatted(
*GetNumberFormatter(), LANGUAGE_SYSTEM) );
} elseif (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;
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.