/* -*- 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 .
*/
// Not all of the necessary parameters were copied yet.
SdrText* pText = getActiveText();
if( pText && rSource.HasText() )
{ // before pNewOutlinerParaObject was created the same, but // set at mpText (outside this scope), but mpText might be // empty (this operator== seems not prepared for MultiText // objects). In the current form it makes only sense to // create locally and use locally on a known existing SdrText const Outliner* pEO = rSource.mpEditingOutliner;
std::optional<OutlinerParaObject> pNewOutlinerParaObject;
// Take care for vertical text animation here
SdrTextVertAdjust eRet = rSet.Get(SDRATTR_TEXT_VERTADJUST).GetValue(); bool bInEditMode = IsInEditMode();
// Take care for vertical text animation here if(!bInEditMode && eRet == SDRTEXTVERTADJUST_BLOCK)
{
SdrTextAniKind eAniKind = rSet.Get(SDRATTR_TEXT_ANIKIND).GetValue();
// #115391# This implementation is based on the object size (aRect) and the // states of IsAutoGrowWidth/Height to correctly set TextMinFrameWidth/Height void SdrTextObj::AdaptTextMinSize()
{ if (!mbTextFrame) // Only do this for text frame. return;
if (getSdrModelFromSdrObject().IsPasteResize()) // Don't do this during paste resize. return;
if( bLineWidth )
{ // Take line width into account. // When doing the hit test, avoid this. (Performance!)
pContourPolyPolygon.emplace();
// test if shadow needs to be avoided for TakeContour() const SfxItemSet& rSet = GetObjectItemSet(); bool bShadowOn = rSet.Get(SDRATTR_SHADOW).GetValue();
// #i33696# // Remember TextObject currently set at the DrawOutliner, it WILL be // replaced during calculating the outline since it uses an own paint // and that one uses the DrawOutliner, too. const SdrTextObj* pLastTextObject = rOutliner.GetTextObj();
// Since sizes may be bigger than the object bounds it is necessary to // justify the rect now.
ImpJustifyRect(rAnchorRect);
}
void SdrTextObj::TakeTextAnchorRect(tools::Rectangle& rAnchorRect) const
{
tools::Rectangle aAnkRect(getRectangle()); // the rectangle in which we anchor bool bFrame=IsTextFrame(); if (!bFrame) {
TakeUnrotatedSnapRect(aAnkRect);
}
Point aRotateRef(aAnkRect.TopLeft());
AdjustRectToTextDistance(aAnkRect);
if (bFrame) { // TODO: Optimize this. if (aAnkRect.GetWidth()<2) aAnkRect.SetRight(aAnkRect.Left()+1 ); // minimum size h and v: 2 px if (aAnkRect.GetHeight()<2) aAnkRect.SetBottom(aAnkRect.Top()+1 );
} if (maGeo.m_nRotationAngle) {
Point aTmpPt(aAnkRect.TopLeft());
RotatePoint(aTmpPt,aRotateRef,maGeo.mfSinRotationAngle,maGeo.mfCosRotationAngle);
aTmpPt-=aAnkRect.TopLeft();
aAnkRect.Move(aTmpPt.X(),aTmpPt.Y());
}
rAnchorRect=aAnkRect;
}
void SdrTextObj::TakeTextRect( SdrOutliner& rOutliner, tools::Rectangle& rTextRect, bool bNoEditText,
tools::Rectangle* pAnchorRect, bool bLineWidth ) const
{
tools::Rectangle aAnkRect; // the rectangle in which we anchor
TakeTextAnchorRect(aAnkRect);
SdrTextVertAdjust eVAdj=GetTextVerticalAdjust();
SdrTextHorzAdjust eHAdj=GetTextHorizontalAdjust();
SdrTextAniKind eAniKind=GetTextAniKind();
SdrTextAniDirection eAniDirection=GetTextAniDirection();
if (!bFitToSize && !bContourFrame)
{
tools::Long nAnkWdt=aAnkRect.GetWidth();
tools::Long nAnkHgt=aAnkRect.GetHeight(); if (bFrame)
{
tools::Long nWdt=nAnkWdt;
tools::Long nHgt=nAnkHgt;
bool bInEditMode = IsInEditMode();
if (!bInEditMode && (eAniKind==SdrTextAniKind::Scroll || eAniKind==SdrTextAniKind::Alternate || eAniKind==SdrTextAniKind::Slide))
{ // unlimited paper size for ticker text if (eAniDirection==SdrTextAniDirection::Left || eAniDirection==SdrTextAniDirection::Right) nWdt=1000000; if (eAniDirection==SdrTextAniDirection::Up || eAniDirection==SdrTextAniDirection::Down) nHgt=1000000;
}
bool bChainedFrame = IsChainable(); // Might be required for overflow check working: do limit height to frame if box is chainable. if (!bChainedFrame) { // #i119885# Do not limit/force height to geometrical frame (vice versa for vertical writing)
// New try with _BLOCK for hor and ver after completely // supporting full width for vertical text. if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !IsVerticalWriting())
{
rOutliner.SetMinAutoPaperSize(Size(nAnkWdt, 0));
rOutliner.SetMinColumnWrapHeight(nAnkHgt);
}
rOutliner.SetPaperSize(aNullSize); if (bContourFrame)
ImpSetContourPolygon( rOutliner, aAnkRect, bLineWidth );
// put text into the outliner, if available from the edit outliner
SdrText* pText = getActiveText();
OutlinerParaObject* pOutlinerParaObject = pText ? pText->GetOutlinerParaObject() : nullptr;
std::optional<OutlinerParaObject> pPara; if (mpEditingOutliner && !bNoEditText)
pPara = mpEditingOutliner->CreateParaObject(); elseif (pOutlinerParaObject)
pPara = *pOutlinerParaObject;
Point aTextPos(aAnkRect.TopLeft());
Size aTextSiz(rOutliner.GetPaperSize()); // GetPaperSize() adds a little tolerance, right?
// For draw objects containing text correct hor/ver alignment if text is bigger // than the object itself. Without that correction, the text would always be // formatted to the left edge (or top edge when vertical) of the draw object. if(!IsTextFrame())
{ if(aAnkRect.GetWidth() < aTextSiz.Width() && !IsVerticalWriting())
{ // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK, // else the alignment is wanted. if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
{
eHAdj = SDRTEXTHORZADJUST_CENTER;
}
}
if(aAnkRect.GetHeight() < aTextSiz.Height() && IsVerticalWriting())
{ // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK, // else the alignment is wanted. if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
{
eVAdj = SDRTEXTVERTADJUST_CENTER;
}
}
}
if (eHAdj==SDRTEXTHORZADJUST_CENTER || eHAdj==SDRTEXTHORZADJUST_RIGHT)
{
tools::Long nFreeWdt=aAnkRect.GetWidth()-aTextSiz.Width(); if (eHAdj==SDRTEXTHORZADJUST_CENTER)
aTextPos.AdjustX(nFreeWdt/2 ); if (eHAdj==SDRTEXTHORZADJUST_RIGHT)
aTextPos.AdjustX(nFreeWdt );
} if (eVAdj==SDRTEXTVERTADJUST_CENTER || eVAdj==SDRTEXTVERTADJUST_BOTTOM)
{
tools::Long nFreeHgt=aAnkRect.GetHeight()-aTextSiz.Height(); if (eVAdj==SDRTEXTVERTADJUST_CENTER)
aTextPos.AdjustY(nFreeHgt/2 ); if (eVAdj==SDRTEXTVERTADJUST_BOTTOM)
aTextPos.AdjustY(nFreeHgt );
} if (maGeo.m_nRotationAngle)
RotatePoint(aTextPos,aAnkRect.TopLeft(),maGeo.mfSinRotationAngle,maGeo.mfCosRotationAngle);
if (pAnchorRect)
*pAnchorRect=aAnkRect;
// rTextRect might not be correct in some cases at ContourFrame
rTextRect=tools::Rectangle(aTextPos,aTextSiz); if (bContourFrame)
rTextRect=aAnkRect;
}
if(pOut && pOut->GetOutDevType() == OUTDEV_PRINTER)
{ // check whether CharStretching is possible at all
GDIMetaFile* pMtf = pOut->GetConnectMetaFile();
OUString aTestString(u'J');
#ifdef _WIN32 // Windows zooms the font proportionally when using Size(100,500), // we don't like that. if(aSize2.Height() >= aSize1.Height() * 2)
{
bNoStretching = true;
} #endif
}
OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject(); if(pOutlinerParaObject && meTextKind != SdrObjKind::OutlineText)
{ // shouldn't currently cause any problems at OUTLINETEXT
OUString aStr2(comphelper::string::stripStart(pOutlinerParaObject->GetTextObject().GetText(0), ' '));
// avoid non expanded text portions in object name // (second condition is new) if(!aStr2.isEmpty() && aStr2.indexOf(u'\x00FF') == -1)
{ // space between ResStr and content text
aStr += " \'";
// and now add the BoundRect of the text, if necessary if ( GetOutlinerParaObject() && !IsFontwork() && !IsContourTextFrame() )
{ // using Clone()-Paint() strategy inside TakeContour() leaves a destroyed // SdrObject as pointer in DrawOutliner. Set *this again in fetching the outliner // in every case
SdrOutliner& rOutliner=ImpGetDrawOutliner();
tools::Rectangle aAnchor2;
tools::Rectangle aR;
TakeTextRect(rOutliner,aR,false,&aAnchor2);
rOutliner.Clear(); bool bFitToSize(IsFitToSize()); if (bFitToSize) aR=aAnchor2;
tools::Polygon aPol(aR); if (maGeo.m_nRotationAngle) RotatePoly(aPol,aR.TopLeft(), maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle);
Point SdrTextObj::GetSnapPoint(sal_uInt32 i) const
{
Point aP; constauto& rRectangle = getRectangle(); switch (i) { case 0: aP = rRectangle.TopLeft(); break; case 1: aP = rRectangle.TopRight(); break; case 2: aP = rRectangle.BottomLeft(); break; case 3: aP = rRectangle.BottomRight(); break; default: aP = rRectangle.Center(); break;
} if (maGeo.m_nShearAngle)
ShearPoint(aP, rRectangle.TopLeft(), maGeo.mfTanShearAngle); if (maGeo.m_nRotationAngle)
RotatePoint(aP, rRectangle.TopLeft(), maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle); return aP;
}
// Code extracted to ImpInitDrawOutliner()
ImpInitDrawOutliner( rOutl );
return rOutl;
}
// Extracted from Paint() void SdrTextObj::ImpSetupDrawOutlinerForPaint( bool bContourFrame,
SdrOutliner& rOutliner,
tools::Rectangle& rTextRect,
tools::Rectangle& rAnchorRect,
tools::Rectangle& rPaintRect,
Fraction& rFitXCorrection ) const
{ if (!bContourFrame)
{ // FitToSize can't be used together with ContourFrame for now if (IsFitToSize() || IsAutoFit())
{
EEControlBits nStat=rOutliner.GetControlWord();
nStat|=EEControlBits::STRETCHING|EEControlBits::AUTOPAGESIZE;
rOutliner.SetControlWord(nStat);
}
}
rOutliner.SetFixedCellHeight(GetMergedItem(SDRATTR_TEXT_USEFIXEDCELLHEIGHT).GetValue());
TakeTextRect(rOutliner, rTextRect, false, &rAnchorRect);
rPaintRect = rTextRect;
if (bContourFrame) return;
// FitToSize can't be used together with ContourFrame for now if (IsFitToSize())
{
ImpSetCharStretching(rOutliner,rTextRect.GetSize(),rAnchorRect.GetSize(),rFitXCorrection);
rPaintRect=rAnchorRect;
} elseif (IsAutoFit())
{
setupAutoFitText(rOutliner);
}
}
double SdrTextObj::GetFontScale() const
{
SdrOutliner& rOutliner = ImpGetDrawOutliner(); // This eventually calls setupAutoFitText
UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle()));
return rOutliner.getScalingParameters().fFontY;
}
double SdrTextObj::GetSpacingScale() const
{
SdrOutliner& rOutliner = ImpGetDrawOutliner(); // This eventually calls setupAutoFitText
UpdateOutlinerFormatting(rOutliner, o3tl::temporary(tools::Rectangle()));
SetTextSizeDirty(); if (IsTextFrame() && IsAutoGrow(*this) && bAdjustTextFrameWidthAndHeight)
{ // adapt text frame!
NbcAdjustTextFrameWidthAndHeight();
} if (!IsTextFrame())
{ // the SnapRect keeps its size
SetBoundAndSnapRectsDirty(true);
}
// always invalidate BoundRect on change
SetBoundRectDirty();
ActionChanged();
pText->ReformatText(); if (mbTextFrame)
{
NbcAdjustTextFrameWidthAndHeight();
} else
{ // the SnapRect keeps its size
SetBoundRectDirty();
SetBoundAndSnapRectsDirty(/*bNotMyself*/true);
}
SetTextSizeDirty();
ActionChanged(); // i22396 // Necessary here since we have no compare operator at the outliner // para object which may detect changes regarding the combination // of outliner para data and configuration (e.g., change of // formatting of text numerals)
GetViewContact().flushViewObjectContacts(false);
}
if( !pOutlinerParaObject && bVertical )
{ // we only need to force an outliner para object if the default of // horizontal text is changed
ForceOutlinerParaObject();
pOutlinerParaObject = GetOutlinerParaObject();
}
if (!pOutlinerParaObject ||
(pOutlinerParaObject->IsEffectivelyVertical() == bVertical)) return;
// prepare ItemSet to set exchanged width and height items
SfxItemSet aNewSet(SfxItemSet::makeFixedSfxItemSet<SDRATTR_TEXT_AUTOGROWHEIGHT, SDRATTR_TEXT_AUTOGROWHEIGHT, // Expanded item ranges to also support hor and ver adjust.
SDRATTR_TEXT_VERTADJUST, SDRATTR_TEXT_VERTADJUST,
SDRATTR_TEXT_AUTOGROWWIDTH, SDRATTR_TEXT_HORZADJUST>(*rSet.GetPool()));
// Exchange horz and vert adjusts switch (eVert)
{ case SDRTEXTVERTADJUST_TOP: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_RIGHT)); break; case SDRTEXTVERTADJUST_CENTER: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_CENTER)); break; case SDRTEXTVERTADJUST_BOTTOM: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_LEFT)); break; case SDRTEXTVERTADJUST_BLOCK: aNewSet.Put(SdrTextHorzAdjustItem(SDRTEXTHORZADJUST_BLOCK)); break;
} switch (eHorz)
{ case SDRTEXTHORZADJUST_LEFT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BOTTOM)); break; case SDRTEXTHORZADJUST_CENTER: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_CENTER)); break; case SDRTEXTHORZADJUST_RIGHT: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_TOP)); break; case SDRTEXTHORZADJUST_BLOCK: aNewSet.Put(SdrTextVertAdjustItem(SDRTEXTVERTADJUST_BLOCK)); break;
}
SetObjectItemSet(aNewSet);
pOutlinerParaObject = GetOutlinerParaObject(); if (pOutlinerParaObject)
{ // set ParaObject orientation accordingly
pOutlinerParaObject->SetVertical(bVertical);
}
bool SdrTextObj::IsTopToBottom() const
{ if (mpEditingOutliner) return mpEditingOutliner->IsTopToBottom();
if (OutlinerParaObject* pOutlinerParaObject = GetOutlinerParaObject()) return pOutlinerParaObject->IsTopToBottom();
returnfalse;
}
// transformation interface for StarOfficeAPI. This implements support for // homogeneous 3x3 matrices containing the transformation of the SdrObject. At the // moment it contains a shearX, rotation and translation, but for setting all linear // transforms like Scale, ShearX, ShearY, Rotate and Translate are supported.
// gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon // with the base geometry and returns TRUE. Otherwise it returns FALSE. bool SdrTextObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& /*rPolyPolygon*/) const
{ // get turn and shear double fRotate = toRadians(maGeo.m_nRotationAngle); double fShearX = toRadians(maGeo.m_nShearAngle);
// get aRect, this is the unrotated snaprect
tools::Rectangle aRectangle(getRectangle());
// fill other values
basegfx::B2DTuple aScale(aRectangle.GetWidth(), aRectangle.GetHeight());
basegfx::B2DTuple aTranslate(aRectangle.Left(), aRectangle.Top());
// sets the base geometry of the object using infos contained in the homogeneous 3x3 matrix. // If it's an SdrPathObj it will use the provided geometry information. The Polygon has // to use (0,0) as upper left and will be scaled to the given size in the matrix. void SdrTextObj::TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& /*rPolyPolygon*/)
{ // break up matrix
basegfx::B2DTuple aScale;
basegfx::B2DTuple aTranslate; double fRotate(0.0); double fShearX(0.0);
rMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
// if anchor is used, make position relative to it if( getSdrModelFromSdrObject().IsWriter() )
{ if(GetAnchorPos().X() || GetAnchorPos().Y())
{
aTranslate += basegfx::B2DTuple(GetAnchorPos().X(), GetAnchorPos().Y());
}
}
// build and set BaseRect (use scale)
Size aSize(basegfx::fround<tools::Long>(aScale.getX()),
basegfx::fround<tools::Long>(aScale.getY()));
tools::Rectangle aBaseRect(Point(), aSize);
SetSnapRect(aBaseRect);
// flip? if (bFlipX)
{
Mirror(Point(), Point(0, 1));
} if (bFlipY)
{
Mirror(Point(), Point(1, 0));
}
// #i78696# // fRotate is matematically correct, but aGeoStat.nRotationAngle is // mirrored -> mirror value here
aGeoStat.m_nRotationAngle = NormAngle36000(Degree100(basegfx::fround(-basegfx::rad2deg<100>(fRotate))));
aGeoStat.RecalcSinCos();
Rotate(Point(), aGeoStat.m_nRotationAngle, aGeoStat.mfSinRotationAngle, aGeoStat.mfCosRotationAngle);
}
bool SdrTextObj::IsHideContour() const
{ return !mbTextFrame // Default is: no, don't HideContour; HideContour not together with TextFrames
&& GetObjectItemSet().Get(XATTR_FORMTXTHIDEFORM).GetValue();
}
bool SdrTextObj::IsContourTextFrame() const
{ return !mbTextFrame // ContourFrame not together with normal TextFrames
&& GetObjectItemSet().Get(SDRATTR_TEXT_CONTOURFRAME).GetValue();
}
// Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a // painting rectangle. Rotation is excluded from the returned values.
GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle(
tools::Rectangle& rScrollRectangle, tools::Rectangle& rPaintRectangle)
{
GDIMetaFile* pRetval = nullptr;
SdrOutliner& rOutliner = ImpGetDrawOutliner();
tools::Rectangle aTextRect;
tools::Rectangle aAnchorRect;
tools::Rectangle aPaintRect;
Fraction aFitXCorrection(1,1); bool bContourFrame(IsContourTextFrame());
// get outliner set up. To avoid getting a somehow rotated MetaFile, // temporarily disable object rotation.
Degree100 nAngle(maGeo.m_nRotationAngle);
maGeo.m_nRotationAngle = 0_deg100;
ImpSetupDrawOutlinerForPaint( bContourFrame, rOutliner, aTextRect, aAnchorRect, aPaintRect, aFitXCorrection );
maGeo.m_nRotationAngle = nAngle;
/** called from the SdrObjEditView during text edit when the status of the edit outliner changes */ void SdrTextObj::onEditOutlinerStatusEvent( EditStatus* pEditStatus )
{ const EditStatusFlags nStat = pEditStatus->GetStatusWord(); constbool bGrowX = bool(nStat & EditStatusFlags::TEXTWIDTHCHANGED); constbool bGrowY = bool(nStat & EditStatusFlags::TextHeightChanged); if(!(mbTextFrame && (bGrowX || bGrowY))) return;
// Need to reset scaling so it searches for the fitting size again
mpEditingOutliner->resetScalingParameters();
// sucks that we cannot disable paints via // mpEditingOutliner->SetUpdateMode(FALSE) - but EditEngine skips // formatting as well, then.
setupAutoFitText(*mpEditingOutliner);
mbInDownScale = false;
}
}
/* Begin chaining code */
// XXX: Make it a method somewhere? static SdrObject *ImpGetObjByName(SdrObjList const *pObjList, std::u16string_view aObjName)
{ // scan the whole list for (const rtl::Reference<SdrObject>& pCurObj : *pObjList) if (pCurObj->GetName() == aObjName) return pCurObj.get(); // not found return nullptr;
}
// XXX: Make it a (private) method of SdrTextObj staticvoid ImpUpdateChainLinks(SdrTextObj *pTextObj, std::u16string_view aNextLinkName)
{ // XXX: Current implementation constraints text boxes to be on the same page
// No next link if (aNextLinkName.empty()) {
pTextObj->SetNextLinkInChain(nullptr); return;
}
SdrPage *pPage(pTextObj->getSdrPageFromSdrObject());
assert(pPage);
SdrTextObj *pNextTextObj = DynCastSdrTextObj
(ImpGetObjByName(pPage, aNextLinkName)); if (!pNextTextObj) {
SAL_INFO("svx.chaining", "[CHAINING] Can't find object as next link."); return;
}
pTextObj->SetNextLinkInChain(pNextTextObj);
}
bool SdrTextObj::IsChainable() const
{ // Read it as item const SfxItemSet& rSet = GetObjectItemSet();
OUString aNextLinkName = rSet.Get(SDRATTR_TEXT_CHAINNEXTNAME).GetValue();
// Update links if any inconsistency is found bool bNextLinkUnsetYet = !aNextLinkName.isEmpty() && !mpNextInChain; bool bInconsistentNextLink = mpNextInChain && mpNextInChain->GetName() != aNextLinkName; // if the link is not set despite there should be one OR if it has changed if (bNextLinkUnsetYet || bInconsistentNextLink) {
ImpUpdateChainLinks(const_cast<SdrTextObj *>(this), aNextLinkName);
}
return !aNextLinkName.isEmpty(); // XXX: Should we also check for GetNilChainingEvent? (see old code below)
/* // Check that no overflow is going on if (!GetTextChain() || GetTextChain()->GetNilChainingEvent(this)) return false;
*/
}
void SdrTextObj::onChainingEvent()
{ if (!mpEditingOutliner) return;
// Outliner for text transfer
SdrOutliner &aDrawOutliner = ImpGetDrawOutliner();
if (aTxtChainFlow.IsOverflow()) {
SAL_INFO("svx.chaining", "[CHAINING] Overflow going on"); // One outliner is for non-overflowing text, the other for overflowing text // We remove text directly from the editing outliner
aTxtChainFlow.ExecuteOverflow(mpEditingOutliner, &aDrawOutliner);
} elseif (aTxtChainFlow.IsUnderflow()) {
SAL_INFO("svx.chaining", "[CHAINING] Underflow going on"); // underflow-induced overflow
aTxtChainFlow.ExecuteUnderflow(&aDrawOutliner); bool bIsOverflowFromUnderflow = aTxtChainFlow.IsOverflow(); // handle overflow if (bIsOverflowFromUnderflow) {
SAL_INFO("svx.chaining", "[CHAINING] Overflow going on (underflow induced)"); // prevents infinite loops when setting text for editing outliner
aTxtChainFlow.ExecuteOverflow(&aDrawOutliner, &aDrawOutliner);
}
}
}
SdrTextObj* SdrTextObj::GetNextLinkInChain() const
{ /* if (GetTextChain()) return GetTextChain()->GetNextLink(this);
return NULL;
*/
return mpNextInChain;
}
void SdrTextObj::SetNextLinkInChain(SdrTextObj *pNextObj)
{ // Basically a doubly linked list implementation
SdrTextObj *pOldNextObj = mpNextInChain;
// Replace next link
mpNextInChain = pNextObj; // Deal with old next link's prev link if (pOldNextObj) {
pOldNextObj->mpPrevInChain = nullptr;
}
// Deal with new next link's prev link if (mpNextInChain) { // If there is a prev already at all and this is not already the current object if (mpNextInChain->mpPrevInChain &&
mpNextInChain->mpPrevInChain != this)
mpNextInChain->mpPrevInChain->mpNextInChain = nullptr;
mpNextInChain->mpPrevInChain = this;
}
// TODO: Introduce check for circular chains
}
SdrTextObj* SdrTextObj::GetPrevLinkInChain() const
{ /* if (GetTextChain()) return GetTextChain()->GetPrevLink(this);
return NULL;
*/
return mpPrevInChain;
}
bool SdrTextObj::GetPreventChainable() const
{ // Prevent chaining it 1) during dragging && 2) when we are editing next link return mbIsUnchainableClone || (GetNextLinkInChain() && GetNextLinkInChain()->IsInEditMode());
}
rtl::Reference<SdrObject> SdrTextObj::getFullDragClone() const
{
rtl::Reference<SdrObject> pClone = SdrAttrObj::getFullDragClone();
SdrTextObj *pTextObjClone = DynCastSdrTextObj(pClone.get()); if (pTextObjClone != nullptr) { // Avoid transferring of text for chainable object during dragging
pTextObjClone->mbIsUnchainableClone = true;
}
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.