/* -*- 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 <com/sun/star/embed/NoVisualAreaSizeException.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <View.hxx>
#include <editeng/outlobj.hxx>
#include <editeng/unolingu.hxx>
#include <sfx2/request.hxx>
#include <svx/obj3d.hxx>
#include <svx/fmview.hxx>
#include <editeng/outliner.hxx>
#include <svx/svxids.hrc>
#include <svx/svdograf.hxx>
#include <svx/svdoole2.hxx>
#include <svx/svdundo.hxx>
#include <vcl/settings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/app.hxx>
#include <svx/svdpagv.hxx>
#include <sfx2/docfile.hxx>
#include <svx/svdoutl.hxx>
#include <svx/sdr/contact/displayinfo.hxx>
#include <svx/svdetc.hxx>
#include <editeng/editstat.hxx>
#include <svx/dialogs.hrc>
#include <sfx2/viewfrm.hxx>
#include <vcl/EnumContext.hxx>
#include <svx/svdopage.hxx>
#include <toolkit/helper/vclunohelper.hxx>
#include <svx/xlndsit.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlnclit.hxx>
#include <svx/sidebar/ContextChangeEventMultiplexer.hxx>
#include <vcl/virdev.hxx>
#include <app.hrc>
#include <strings.hrc>
#include <Window.hxx>
#include <Client.hxx>
#include <drawdoc.hxx>
#include <DrawDocShell.hxx>
#include <sdmod.hxx>
#include <sdpage.hxx>
#include <sdresid.hxx>
#include <DrawViewShell.hxx>
#include <futext.hxx>
#include <fuinsfil.hxx>
#include <slideshow.hxx>
#include <stlpool.hxx>
#include <FrameView.hxx>
#include <ViewClipboard.hxx>
#include <undo/undomanager.hxx>
#include <svx/sdr/contact/viewobjectcontact.hxx>
#include <svx/sdr/contact/viewcontact.hxx>
#include <svx/svdotable.hxx>
#include <EventMultiplexer.hxx>
#include <ViewShellBase.hxx>
#include <ViewShellManager.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/color/bcolor.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
#include <svx/sdr/contact/objectcontact.hxx>
#include <svx/sdr/table/tablecontroller.hxx>
#include <basegfx/matrix/b2dhommatrix.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <svx/unoapi.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <comphelper/lok.hxx>
#include <sfx2/lokhelper.hxx>
#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <svl/itemiter.hxx>
#include <editeng/editeng.hxx>
#include <DrawController.hxx>
#include <memory>
#include <numeric>
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace sdr::table;
namespace sd {
View::View(
SdDrawDocument& rDrawDoc,
OutputDevice* pOutDev,
ViewShell* pViewShell)
: FmFormView(rDrawDoc, pOutDev),
mrDoc(rDrawDoc),
mpDocSh(rDrawDoc.GetDocSh()),
mpViewSh(pViewShell),
mpDropMarkerObj(nullptr),
mnDragSrcPgNum(SDRPAGE_NOTFOUND),
mnAction(DND_ACTION_NONE),
maDropErrorIdle("sd View DropError"),
maDropInsertFileIdle("sd View DropInsertFile"),
mnLockRedrawSmph(0),
mbIsDropAllowed(true),
maSmartTags(*this),
mpClipboard (new ViewClipboard (*this))
{
// #i73602# Use default from the configuration
SetBufferedOverlayAllowed(getOptionsDrawinglayer().IsOverlayBuffer_DrawImpress());
// #i74769#, #i75172# Use default from the configuration
SetBufferedOutputAllowed(getOptionsDrawinglayer().IsPaintBuffer_DrawImpress());
EnableExtendedKeyInputDispatcher(false);
EnableExtendedMouseEventDispatcher(false);
SetUseIncompatiblePathCreateInterface(false);
SetMinMoveDistancePixel(2);
SetHitTolerancePixel(2);
SetMeasureLayer(SdResId(STR_LAYER_MEASURELINES));
// Timer for delayed drop (has to be for MAC)
maDropErrorIdle.SetInvokeHandler( LINK(this, View, DropErrorHdl) );
maDropInsertFileIdle.SetInvokeHandler( LINK(this, View, DropInsertFileHdl) );
}
void View::ImplClearDrawDropMarker()
{
mpDropMarker.reset();
}
View::~View()
{
maSmartTags.Dispose();
// release content of selection clipboard, if we own the content
UpdateSelectionClipboard( true );
maDropErrorIdle.Stop();
maDropInsertFileIdle.Stop();
ImplClearDrawDropMarker();
while(PaintWindowCount())
{
// remove all registered OutDevs
DeleteWindowFromPaintView(GetFirstOutputDevice() /*GetWin(0)*/);
}
}
class ViewRedirector : public sdr::contact::ViewObjectContactRedirector
{
public:
ViewRedirector();
// all default implementations just call the same methods at the original. To do something
// different, override the method and at least do what the method does.
virtual drawinglayer::primitive2d::Primitive2DContainer createRedirectedPrimitive2DSequence(
const sdr::contact::ViewObjectContact& rOriginal,
const sdr::contact::DisplayInfo& rDisplayInfo) override;
};
ViewRedirector::ViewRedirector()
{
}
drawinglayer::primitive2d::Primitive2DContainer ViewRedirector::createRedirectedPrimitive2DSequence(
const sdr::contact::ViewObjectContact& rOriginal,
const sdr::contact::DisplayInfo& rDisplayInfo)
{
SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject();
drawinglayer::primitive2d::Primitive2DContainer xRetval;
if(pObject && pObject->getSdrPageFromSdrObject())
{
const bool bDoCreateGeometry(pObject->getSdrPageFromSdrObject()->checkVisibility( rOriginal, rDisplayInfo, true ));
if(!bDoCreateGeometry && !(( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == OBJ_PAGE )) )
return xRetval;
PresObjKind eKind(PRESOBJ_NONE);
const bool bSubContentProcessing(rDisplayInfo.GetSubContentActive());
const bool bIsMasterPageObject(pObject->getSdrPageFromSdrObject()->IsMasterPage());
const bool bIsPrinting(rOriginal.GetObjectContact().isOutputToPrinter());
const SdrPageView* pPageView = rOriginal.GetObjectContact().TryToGetSdrPageView();
const SdrPage* pVisualizedPage = GetSdrPageFromXDrawPage(rOriginal.GetObjectContact().getViewInformation2D().getVisualizedPage());
const SdPage* pObjectsSdPage = dynamic_cast< SdPage* >(pObject->getSdrPageFromSdrObject());
const bool bIsInsidePageObj(pPageView && pPageView->GetPage() != pVisualizedPage);
// check if we need to draw a placeholder border. Never do it for
// objects inside a SdrPageObj and never when printing
if(!bIsInsidePageObj && !bIsPrinting)
{
bool bCreateOutline(false);
if( pObject->IsEmptyPresObj() && dynamic_cast< SdrTextObj *>( pObject ) != nullptr )
{
if( !bSubContentProcessing || !pObject->IsNotVisibleAsMaster() )
{
eKind = pObjectsSdPage ? pObjectsSdPage->GetPresObjKind(pObject) : PRESOBJ_NONE;
bCreateOutline = true;
}
}
else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == OBJ_TEXT ) )
{
if( pObjectsSdPage )
{
eKind = pObjectsSdPage->GetPresObjKind(pObject);
if((eKind == PRESOBJ_FOOTER) || (eKind == PRESOBJ_HEADER) || (eKind == PRESOBJ_DATETIME) || (eKind == PRESOBJ_SLIDENUMBER) )
{
if( !bSubContentProcessing )
{
// only draw a boundary for header&footer objects on the masterpage itself
bCreateOutline = true;
}
}
}
}
else if( ( pObject->GetObjInventor() == SdrInventor::Default ) && ( pObject->GetObjIdentifier() == OBJ_PAGE ) )
{
// only for handout page, else this frame will be created for each
// page preview object in SlideSorter and PagePane
if(pObjectsSdPage && PageKind::Handout == pObjectsSdPage->GetPageKind())
{
bCreateOutline = true;
}
}
if(bCreateOutline)
{
// empty presentation objects get a gray frame
const svtools::ColorConfig aColorConfig;
const svtools::ColorConfigValue aColor( aColorConfig.GetColorValue( svtools::OBJECTBOUNDARIES ) );
if( aColor.bIsVisible )
{
// get basic object transformation
const basegfx::BColor aRGBColor(aColor.nColor.getBColor());
basegfx::B2DHomMatrix aObjectMatrix;
basegfx::B2DPolyPolygon aObjectPolyPolygon;
pObject->TRGetBaseGeometry(aObjectMatrix, aObjectPolyPolygon);
// create dashed border
{
// create object polygon
basegfx::B2DPolygon aPolygon(basegfx::utils::createUnitPolygon());
aPolygon.transform(aObjectMatrix);
// create line and stroke attribute
::std::vector< double > aDotDashArray;
aDotDashArray.push_back(160.0);
aDotDashArray.push_back(80.0);
const double fFullDotDashLen(::std::accumulate(aDotDashArray.begin(), aDotDashArray.end(), 0.0));
const drawinglayer::attribute::LineAttribute aLine(aRGBColor);
const drawinglayer::attribute::StrokeAttribute aStroke(aDotDashArray, fFullDotDashLen);
// create primitive and add
const drawinglayer::primitive2d::Primitive2DReference xRef(new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
aPolygon,
aLine,
aStroke));
xRetval.push_back(xRef);
}
// now paint the placeholder description, but only when masterpage
// is displayed as page directly (MasterPage view)
if(!bSubContentProcessing && bIsMasterPageObject)
{
OUString aObjectString;
switch( eKind )
{
case PRESOBJ_TITLE:
{
if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
{
static OUString aTitleAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_TITLE));
aObjectString = aTitleAreaStr;
}
break;
}
case PRESOBJ_OUTLINE:
{
static OUString aOutlineAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_OUTLINE));
aObjectString = aOutlineAreaStr;
break;
}
case PRESOBJ_FOOTER:
{
static OUString aFooterAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_FOOTER));
aObjectString = aFooterAreaStr;
break;
}
case PRESOBJ_HEADER:
{
static OUString aHeaderAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_HEADER));
aObjectString = aHeaderAreaStr;
break;
}
case PRESOBJ_DATETIME:
{
static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_DATETIME));
aObjectString = aDateTimeStr;
break;
}
case PRESOBJ_NOTES:
{
static OUString aDateTimeStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NOTES));
aObjectString = aDateTimeStr;
break;
}
case PRESOBJ_SLIDENUMBER:
{
if(pObjectsSdPage && pObjectsSdPage->GetPageKind() == PageKind::Standard)
{
static OUString aSlideAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_SLIDE));
aObjectString = aSlideAreaStr;
}
else
{
static OUString aNumberAreaStr(SdResId(STR_PLACEHOLDER_DESCRIPTION_NUMBER));
aObjectString = aNumberAreaStr;
}
break;
}
default:
{
break;
}
}
if( !aObjectString.isEmpty() )
{
// decompose object matrix to be able to place text correctly
basegfx::B2DTuple aScale;
basegfx::B2DTuple aTranslate;
double fRotate, fShearX;
aObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
// create font
SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >( pObject );
const SdrTextVertAdjust eTVA(pTextObj ? pTextObj->GetTextVerticalAdjust() : SDRTEXTVERTADJUST_CENTER);
vcl::Font aScaledVclFont;
// use a text size factor to get more reliable text sizes from the text layouter
// (and from vcl), tipp from HDU
static sal_uInt32 nTextSizeFactor(100);
// use a factor to get more linear text size calculations
aScaledVclFont.SetFontHeight( 500 * nTextSizeFactor );
// get basic geometry and get text size
drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
aTextLayouter.setFont(aScaledVclFont);
const sal_Int32 nTextLength(aObjectString.getLength());
// do not forget to use the factor again to get the width for the 500
const double fTextWidth(aTextLayouter.getTextWidth(aObjectString, 0, nTextLength) * (1.0 / nTextSizeFactor));
const double fTextHeight(aTextLayouter.getTextHeight() * (1.0 / nTextSizeFactor));
// calculate text primitive position. If text is at bottom, use top for
// the extra text and vice versa
const double fHorDist(125);
const double fVerDist(125);
const double fPosX((aTranslate.getX() + aScale.getX()) - fTextWidth - fHorDist);
const double fPosY((SDRTEXTVERTADJUST_BOTTOM == eTVA)
? aTranslate.getY() - fVerDist + fTextHeight
: (aTranslate.getY() + aScale.getY()) - fVerDist);
// get font attributes; use normally scaled font
vcl::Font aVclFont;
basegfx::B2DVector aTextSizeAttribute;
aVclFont.SetFontHeight( 500 );
const drawinglayer::attribute::FontAttribute aFontAttribute(
drawinglayer::primitive2d::getFontAttributeFromVclFont(
aTextSizeAttribute,
aVclFont,
false,
false));
// fill text matrix
const basegfx::B2DHomMatrix aTextMatrix(basegfx::utils::createScaleShearXRotateTranslateB2DHomMatrix(
aTextSizeAttribute.getX(), aTextSizeAttribute.getY(),
fShearX,
fRotate,
fPosX, fPosY));
// create DXTextArray (can be empty one)
const ::std::vector< double > aDXArray{};
// create locale; this may need some more information in the future
const css::lang::Locale aLocale;
// create primitive and add
const drawinglayer::primitive2d::Primitive2DReference xRef(
new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
aTextMatrix,
aObjectString,
0,
nTextLength,
aDXArray,
aFontAttribute,
aLocale,
aRGBColor));
xRetval.push_back(xRef);
}
}
}
}
}
if(bDoCreateGeometry)
{
xRetval.append(
sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(
rOriginal,
rDisplayInfo));
}
}
else
{
// not a SdrObject visualisation (maybe e.g. page) or no page
xRetval = sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo);
}
return xRetval;
}
/**
* The event will be forwarded to the View
*/
void View::CompleteRedraw(OutputDevice* pOutDev, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector /*=0*/)
{
// execute ??
if (mnLockRedrawSmph == 0)
{
SdrPageView* pPgView = GetSdrPageView();
if (pPgView)
{
SdPage* pPage = static_cast<SdPage*>( pPgView->GetPage() );
if( pPage )
{
SdrOutliner& rOutl = mrDoc.GetDrawOutliner();
bool bScreenDisplay(true);
if(bScreenDisplay && pOutDev && OUTDEV_PRINTER == pOutDev->GetOutDevType())
{
// #i75566# printing; suppress AutoColor BackgroundColor generation
// for visibility reasons by giving GetPageBackgroundColor()
// the needed hint
bScreenDisplay = false;
}
if(bScreenDisplay && pOutDev && pOutDev->GetPDFWriter())
{
// #i75566# PDF export; suppress AutoColor BackgroundColor generation (see above)
bScreenDisplay = false;
}
// #i75566# Name change GetBackgroundColor -> GetPageBackgroundColor and
// hint value if screen display. Only then the AutoColor mechanisms shall be applied
rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor(pPgView, bScreenDisplay) );
}
}
ViewRedirector aViewRedirector;
FmFormView::CompleteRedraw(pOutDev, rReg, pRedirector ? pRedirector : &aViewRedirector);
}
}
void View::MarkListHasChanged()
{
FmFormView::MarkListHasChanged();
if( GetMarkedObjectCount() > 0 )
maSmartTags.deselect();
}
bool View::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll)
{
bool bOk = FmFormView::SetAttributes(rSet, bReplaceAll);
return bOk;
}
void View::GetAttributes( SfxItemSet& rTargetSet, bool bOnlyHardAttr ) const
{
FmFormView::GetAttributes( rTargetSet, bOnlyHardAttr );
}
/**
* Is a presentation object selected?
*/
bool View::IsPresObjSelected(bool bOnPage, bool bOnMasterPage, bool bCheckPresObjListOnly, bool bCheckLayoutOnly) const
{
SdrMarkList* pMarkList;
if (mnDragSrcPgNum != SDRPAGE_NOTFOUND &&
mnDragSrcPgNum != GetSdrPageView()->GetPage()->GetPageNum())
{
/* Drag&Drop is in progress
Source and destination page are different:
we use the saved mark list */
pMarkList = mpDragSrcMarkList.get();
}
else
{
// We use the current mark list
pMarkList = new SdrMarkList(GetMarkedObjectList());
}
SdrMark* pMark;
SdPage* pPage;
bool bSelected = false;
bool bMasterPage = false;
for (size_t nMark = pMarkList->GetMarkCount(); nMark && !bSelected; )
{
--nMark;
// Backwards through mark list
pMark = pMarkList->GetMark(nMark);
SdrObject* pObj = pMark->GetMarkedSdrObj();
if ( pObj && ( bCheckPresObjListOnly || pObj->IsEmptyPresObj() || pObj->GetUserCall() ) )
{
pPage = static_cast<SdPage*>( pObj->getSdrPageFromSdrObject() );
bMasterPage = pPage && pPage->IsMasterPage();
if ( (bMasterPage && bOnMasterPage) || (!bMasterPage && bOnPage) )
{
if ( pPage && pPage->IsPresObj(pObj) )
{
if( bCheckLayoutOnly )
{
PresObjKind eKind = pPage->GetPresObjKind(pObj);
if((eKind != PRESOBJ_FOOTER) && (eKind != PRESOBJ_HEADER) && (eKind != PRESOBJ_DATETIME) && (eKind != PRESOBJ_SLIDENUMBER) )
bSelected = true;
}
else
{
bSelected = true;
}
}
}
}
}
if (pMarkList != mpDragSrcMarkList.get())
{
delete pMarkList;
}
return bSelected;
}
void View::SelectAll()
{
if ( IsTextEdit() )
{
OutlinerView* pOLV = GetTextEditOutlinerView();
const ::Outliner* pOutliner = GetTextEditOutliner();
pOLV->SelectRange( 0, pOutliner->GetParagraphCount() );
}
else
{
MarkAll();
}
}
bool View::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr)
{
// forward to SdrView
FmFormView::SetStyleSheet(pStyleSheet, bDontRemoveHardAttr);
return true;
}
/**
* Start text input
*/
static void SetSpellOptions( const SdDrawDocument& rDoc, EEControlBits& rCntrl )
{
bool bOnlineSpell = rDoc.GetOnlineSpell();
if( bOnlineSpell )
rCntrl |= EEControlBits::ONLINESPELLING;
else
rCntrl &= ~EEControlBits::ONLINESPELLING;
}
void OutlinerMasterViewFilter::Start(SdrOutliner *pOutl)
{
m_pOutl = pOutl;
OutlinerView* pOutlView = m_pOutl->GetView(0);
m_bReadOnly = pOutlView->IsReadOnly();
pOutlView->SetReadOnly(true);
}
void OutlinerMasterViewFilter::End()
{
if (m_pOutl)
{
OutlinerView* pOutlView = m_pOutl->GetView(0);
pOutlView->SetReadOnly(m_bReadOnly);
m_pOutl = nullptr;
}
}
SfxViewShell* View::GetSfxViewShell() const
{
SfxViewShell* pRet = nullptr;
if (mpViewSh)
pRet = &mpViewSh->GetViewShellBase();
return pRet;
}
bool View::SdrBeginTextEdit(
SdrObject* pObj, SdrPageView* pPV, vcl::Window* pWin,
bool bIsNewObj,
SdrOutliner* pOutl, OutlinerView* pGivenOutlinerView,
bool bDontDeleteOutliner, bool bOnlyOneView, bool bGrabFocus )
{
SdrPage* pPage = pObj ? pObj->getSdrPageFromSdrObject() : nullptr;
bool bMasterPage = pPage && pPage->IsMasterPage();
GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
EventMultiplexerEventId::BeginTextEdit, static_cast<void*>(pObj) );
if( pOutl==nullptr && pObj )
pOutl = SdrMakeOutliner(OutlinerMode::TextObject, pObj->getSdrModelFromSdrObject()).release();
// make draw&impress specific initialisations
if( pOutl )
{
pOutl->SetStyleSheetPool(static_cast<SfxStyleSheetPool*>( mrDoc.GetStyleSheetPool() ));
pOutl->SetCalcFieldValueHdl(LINK(SD_MOD(), SdModule, CalcFieldValueHdl));
EEControlBits nCntrl = pOutl->GetControlWord();
nCntrl |= EEControlBits::ALLOWBIGOBJS;
nCntrl |= EEControlBits::MARKFIELDS;
nCntrl |= EEControlBits::AUTOCORRECT;
nCntrl &= ~EEControlBits::ULSPACESUMMATION;
if ( mrDoc.IsSummationOfParagraphs() )
nCntrl |= EEControlBits::ULSPACESUMMATION;
SetSpellOptions( mrDoc, nCntrl );
pOutl->SetControlWord(nCntrl);
Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
if ( xSpellChecker.is() )
pOutl->SetSpeller( xSpellChecker );
Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
if( xHyphenator.is() )
pOutl->SetHyphenator( xHyphenator );
pOutl->SetDefaultLanguage( Application::GetSettings().GetLanguageTag().getLanguageType() );
}
bool bReturn = FmFormView::SdrBeginTextEdit(
pObj, pPV, pWin, bIsNewObj, pOutl,
pGivenOutlinerView, bDontDeleteOutliner,
bOnlyOneView, bGrabFocus);
if ( mpViewSh )
{
mpViewSh->GetViewShellBase().GetDrawController().FireSelectionChangeListener();
if (pObj && pObj->GetObjIdentifier() == OBJ_TABLE)
mpViewSh->UpdateScrollBars();
if (comphelper::LibreOfficeKit::isActive())
{
if (OutlinerView* pView = GetTextEditOutlinerView())
{
::tools::Rectangle aRectangle = pView->GetOutputArea();
if (pWin && pWin->GetMapMode().GetMapUnit() == MapUnit::Map100thMM)
aRectangle = OutputDevice::LogicToLogic(aRectangle, MapMode(MapUnit::Map100thMM), MapMode(MapUnit::MapTwip));
OString sRectangle = aRectangle.toString();
SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", sRectangle);
}
}
}
if (::Outliner* pOL = bReturn ? GetTextEditOutliner() : nullptr)
{
if (pObj)
{
if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == OBJ_TABLE )
{
Color aBackground;
aBackground = GetTextEditBackgroundColor(*this);
pOL->SetBackgroundColor( aBackground );
}
else
{
pObj->setSuitableOutlinerBg(*pOL);
}
}
pOL->SetParaInsertedHdl(LINK(this, View, OnParagraphInsertedHdl));
pOL->SetParaRemovingHdl(LINK(this, View, OnParagraphRemovingHdl));
}
if (bMasterPage && bReturn && pOutl)
{
const SdrTextObj* pTextObj = pOutl->GetTextObj();
const SdPage* pSdPage = pTextObj ? static_cast<const SdPage*>(pTextObj->getSdrPageFromSdrObject()) : nullptr;
const PresObjKind eKind = pSdPage ? pSdPage->GetPresObjKind(const_cast<SdrTextObj*>(pTextObj)) : PRESOBJ_NONE;
switch (eKind)
{
case PRESOBJ_TITLE:
case PRESOBJ_OUTLINE:
case PRESOBJ_TEXT:
maMasterViewFilter.Start(pOutl);
break;
default:
break;
}
}
return bReturn;
}
/** ends current text editing */
SdrEndTextEditKind View::SdrEndTextEdit(bool bDontDeleteReally)
{
maMasterViewFilter.End();
::tools::WeakReference<SdrTextObj> xObj( GetTextEditObject() );
bool bDefaultTextRestored = RestoreDefaultText( xObj.get() );
SdrEndTextEditKind eKind = FmFormView::SdrEndTextEdit(bDontDeleteReally);
if( bDefaultTextRestored )
{
if( xObj.is() && !xObj->IsEmptyPresObj() )
{
xObj->SetEmptyPresObj( true );
}
else
{
eKind = SdrEndTextEditKind::Unchanged;
}
}
else if( xObj.is() && xObj->IsEmptyPresObj() )
{
SdrTextObj* pObj = xObj.get();
if( pObj && pObj->HasText() )
{
SdrPage* pPage = pObj->getSdrPageFromSdrObject();
if( !pPage || !pPage->IsMasterPage() )
pObj->SetEmptyPresObj( false );
}
}
GetViewShell()->GetViewShellBase().GetEventMultiplexer()->MultiplexEvent(
EventMultiplexerEventId::EndTextEdit,
static_cast<void*>(xObj.get()) );
if( xObj.is() )
{
if ( mpViewSh )
{
mpViewSh->GetViewShellBase().GetDrawController().FireSelectionChangeListener();
if (comphelper::LibreOfficeKit::isActive())
SfxLokHelper::notifyOtherViews(&mpViewSh->GetViewShellBase(), LOK_CALLBACK_VIEW_LOCK, "rectangle", "EMPTY");
}
SdPage* pPage = dynamic_cast< SdPage* >( xObj->getSdrPageFromSdrObject() );
if( pPage )
pPage->onEndTextEdit( xObj.get() );
}
return eKind;
}
/** restores the default text if the given text object is currently in edit mode and
no text has been entered already. Is only useful just before text edit ends. */
bool View::RestoreDefaultText( SdrTextObj* pTextObj )
{
bool bRestored = false;
if( pTextObj && (pTextObj == GetTextEditObject()) )
{
if( !pTextObj->HasText() )
{
SdPage* pPage = dynamic_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
if(pPage)
{
bRestored = pPage->RestoreDefaultText( pTextObj );
if( bRestored )
{
SdrOutliner* pOutliner = GetTextEditOutliner();
pTextObj->SetTextEditOutliner( pOutliner );
OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
if (pOutliner)
pOutliner->SetText(*pParaObj);
}
}
}
}
return bRestored;
}
/**
* Sets the original size of the marked objects.
*/
void View::SetMarkedOriginalSize()
{
SdrUndoGroup* pUndoGroup = new SdrUndoGroup(mrDoc);
const size_t nCount = GetMarkedObjectCount();
bool bOK = false;
for( size_t i = 0; i < nCount; ++i )
{
SdrObject* pObj = GetMarkedObjectByIndex(i);
if( pObj->GetObjInventor() == SdrInventor::Default )
{
if( pObj->GetObjIdentifier() == OBJ_OLE2 )
{
uno::Reference < embed::XEmbeddedObject > xObj = static_cast<SdrOle2Obj*>(pObj)->GetObjRef();
if( xObj.is() )
{
// TODO/LEAN: working with VisualArea can switch object to running state
sal_Int64 nAspect = static_cast<SdrOle2Obj*>(pObj)->GetAspect();
Size aOleSize;
if ( nAspect == embed::Aspects::MSOLE_ICON )
{
MapMode aMap100( MapUnit::Map100thMM );
aOleSize = static_cast<SdrOle2Obj*>(pObj)->GetOrigObjSize( &aMap100 );
bOK = true;
}
else
{
MapUnit aUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
try
{
awt::Size aSz = xObj->getVisualAreaSize( nAspect );
aOleSize = OutputDevice::LogicToLogic(Size(aSz.Width, aSz.Height), MapMode(aUnit), MapMode(MapUnit::Map100thMM));
bOK = true;
}
catch( embed::NoVisualAreaSizeException& )
{}
}
if ( bOK )
{
::tools::Rectangle aDrawRect( pObj->GetLogicRect() );
pUndoGroup->AddAction( mrDoc.GetSdrUndoFactory().CreateUndoGeoObject( *pObj ) );
pObj->Resize( aDrawRect.TopLeft(), Fraction( aOleSize.Width(), aDrawRect.GetWidth() ),
Fraction( aOleSize.Height(), aDrawRect.GetHeight() ) );
}
}
}
else if( pObj->GetObjIdentifier() == OBJ_GRAF )
{
const SdrGrafObj* pSdrGrafObj = static_cast< const SdrGrafObj* >(pObj);
const Size aSize = pSdrGrafObj->getOriginalSize( );
pUndoGroup->AddAction( GetModel()->GetSdrUndoFactory().CreateUndoGeoObject(*pObj ) );
::tools::Rectangle aRect( pObj->GetLogicRect() );
aRect.SetSize( aSize );
pObj->SetLogicRect( aRect );
bOK = true;
}
}
}
if( bOK )
{
pUndoGroup->SetComment(SdResId(STR_UNDO_ORIGINALSIZE));
mpDocSh->GetUndoManager()->AddUndoAction(pUndoGroup);
}
else
delete pUndoGroup;
}
/**
* Connect OLE object to client.
*/
void View::DoConnect(SdrOle2Obj* pObj)
{
if (mpViewSh)
{
uno::Reference < embed::XEmbeddedObject > xObj( pObj->GetObjRef() );
if( xObj.is() )
{
::sd::Window* pWindow = mpViewSh->GetActiveWindow();
SfxInPlaceClient* pSdClient = mpViewSh-> GetViewShellBase().FindIPClient( xObj, pWindow );
if ( !pSdClient )
{
pSdClient = new Client(pObj, mpViewSh, pWindow);
::tools::Rectangle aRect = pObj->GetLogicRect();
{
// TODO/LEAN: working with visual area can switch object to running state
Size aDrawSize = aRect.GetSize();
MapMode aMapMode( mrDoc.GetScaleUnit() );
Size aObjAreaSize = pObj->GetOrigObjSize( &aMapMode );
Fraction aScaleWidth (aDrawSize.Width(), aObjAreaSize.Width() );
Fraction aScaleHeight(aDrawSize.Height(), aObjAreaSize.Height() );
aScaleWidth.ReduceInaccurate(10); // compatible to SdrOle2Obj
aScaleHeight.ReduceInaccurate(10);
pSdClient->SetSizeScale(aScaleWidth, aScaleHeight);
// visible area is only changed in-place!
// the object area must be set after the scaling, since it triggers resize
aRect.SetSize(aObjAreaSize);
pSdClient->SetObjArea(aRect);
}
}
}
}
}
bool View::IsMorphingAllowed() const
{
const SdrMarkList& rMarkList = GetMarkedObjectList();
bool bRet = false;
if ( rMarkList.GetMarkCount() == 2 )
{
const SdrObject* pObj1 = rMarkList.GetMark( 0 )->GetMarkedSdrObj();
const SdrObject* pObj2 = rMarkList.GetMark( 1 )->GetMarkedSdrObj();
const sal_uInt16 nKind1 = pObj1->GetObjIdentifier();
const sal_uInt16 nKind2 = pObj2->GetObjIdentifier();
if ( ( nKind1 != OBJ_TEXT && nKind2 != OBJ_TEXT ) &&
( nKind1 != OBJ_TITLETEXT && nKind2 != OBJ_TITLETEXT ) &&
( nKind1 != OBJ_OUTLINETEXT && nKind2 != OBJ_OUTLINETEXT ) &&
( nKind1 != OBJ_GRUP && nKind2 != OBJ_GRUP ) &&
( nKind1 != OBJ_LINE && nKind2 != OBJ_LINE ) &&
( nKind1 != OBJ_PLIN && nKind2 != OBJ_PLIN ) &&
( nKind1 != OBJ_PATHLINE && nKind2 != OBJ_PATHLINE ) &&
( nKind1 != OBJ_FREELINE && nKind2 != OBJ_FREELINE ) &&
( nKind1 != OBJ_PATHPLIN && nKind2 != OBJ_PATHPLIN ) &&
( nKind1 != OBJ_MEASURE && nKind2 != OBJ_MEASURE ) &&
( nKind1 != OBJ_EDGE && nKind2 != OBJ_EDGE ) &&
( nKind1 != OBJ_GRAF && nKind2 != OBJ_GRAF ) &&
( nKind1 != OBJ_OLE2 && nKind2 != OBJ_OLE2 ) &&
( nKind1 != OBJ_CAPTION && nKind2 != OBJ_CAPTION ) &&
dynamic_cast< const E3dObject *>( pObj1 ) == nullptr && dynamic_cast< const E3dObject *>( pObj2 ) == nullptr )
{
SfxItemSet aSet1( mrDoc.GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLSTYLE>{} );
SfxItemSet aSet2( mrDoc.GetPool(), svl::Items<XATTR_FILLSTYLE, XATTR_FILLSTYLE>{} );
aSet1.Put(pObj1->GetMergedItemSet());
aSet2.Put(pObj2->GetMergedItemSet());
const drawing::FillStyle eFillStyle1 = aSet1.Get( XATTR_FILLSTYLE ).GetValue();
const drawing::FillStyle eFillStyle2 = aSet2.Get( XATTR_FILLSTYLE ).GetValue();
if( ( eFillStyle1 == drawing::FillStyle_NONE || eFillStyle1 == drawing::FillStyle_SOLID ) &&
( eFillStyle2 == drawing::FillStyle_NONE || eFillStyle2 == drawing::FillStyle_SOLID ) )
bRet = true;
}
}
return bRet;
}
bool View::IsVectorizeAllowed() const
{
const SdrMarkList& rMarkList = GetMarkedObjectList();
bool bRet = false;
if( rMarkList.GetMarkCount() == 1 )
{
const SdrGrafObj* pObj = dynamic_cast< const SdrGrafObj* >(rMarkList.GetMark( 0 )->GetMarkedSdrObj());
if(pObj)
{
if(GraphicType::Bitmap == pObj->GetGraphicType() && !pObj->isEmbeddedVectorGraphicData())
{
bRet = true;
}
}
}
return bRet;
}
void View::onAccessibilityOptionsChanged()
{
if( mpViewSh )
{
::sd::Window* pWindow = mpViewSh->GetActiveWindow();
if( pWindow )
{
const StyleSettings& rStyleSettings = pWindow->GetSettings().GetStyleSettings();
sal_uInt16 nOutputSlot, nPreviewSlot;
SvtAccessibilityOptions& aAccOptions = getAccessibilityOptions();
if( mpViewSh->GetViewFrame() && mpViewSh->GetViewFrame()->GetDispatcher() )
{
if( rStyleSettings.GetHighContrastMode() )
{
nOutputSlot = SID_OUTPUT_QUALITY_CONTRAST;
}
else
{
nOutputSlot = SID_OUTPUT_QUALITY_COLOR;
}
if( rStyleSettings.GetHighContrastMode() && aAccOptions.GetIsForPagePreviews() )
{
nPreviewSlot = SID_PREVIEW_QUALITY_CONTRAST;
}
else
{
nPreviewSlot = SID_PREVIEW_QUALITY_COLOR;
}
mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nOutputSlot, SfxCallMode::ASYNCHRON );
mpViewSh->GetViewFrame()->GetDispatcher()->Execute( nPreviewSlot, SfxCallMode::ASYNCHRON );
}
mpViewSh->Invalidate();
}
}
}
IMPL_LINK( View, OnParagraphInsertedHdl, ::Outliner::ParagraphHdlParam, aParam, void )
{
SdrObject* pObj = GetTextEditObject();
if( aParam.pPara && pObj )
{
SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
if( pPage )
pPage->onParagraphInserted( aParam.pOutliner, aParam.pPara, pObj );
}
}
/**
* Handler for the deletion of the pages (paragraphs).
*/
IMPL_LINK( View, OnParagraphRemovingHdl, ::Outliner::ParagraphHdlParam, aParam, void )
{
SdrObject* pObj = GetTextEditObject();
if( aParam.pPara && pObj )
{
SdPage* pPage = dynamic_cast< SdPage* >( pObj->getSdrPageFromSdrObject() );
if( pPage )
pPage->onParagraphRemoving( aParam.pOutliner, aParam.pPara, pObj );
}
}
bool View::isRecordingUndo() const
{
if( mrDoc.IsUndoEnabled() )
{
sd::UndoManager* pUndoManager = mrDoc.GetUndoManager();
return pUndoManager && pUndoManager->IsInListAction();
}
else
{
return false;
}
}
void View::AddCustomHdl()
{
maSmartTags.addCustomHandles( maHdlList );
}
void View::updateHandles()
{
AdjustMarkHdl();
}
SdrViewContext View::GetContext() const
{
SdrViewContext eContext = SdrViewContext::Standard;
if( maSmartTags.getContext( eContext ) )
return eContext;
else
return FmFormView::GetContext();
}
bool View::HasMarkablePoints() const
{
if( maSmartTags.HasMarkablePoints() )
return true;
else
return FmFormView::HasMarkablePoints();
}
sal_Int32 View::GetMarkablePointCount() const
{
sal_Int32 nCount = FmFormView::GetMarkablePointCount();
nCount += maSmartTags.GetMarkablePointCount();
return nCount;
}
bool View::HasMarkedPoints() const
{
if( maSmartTags.HasMarkedPoints() )
return true;
else
return FmFormView::HasMarkedPoints();
}
sal_Int32 View::GetMarkedPointCount() const
{
sal_Int32 nCount = FmFormView::GetMarkedPointCount();
nCount += maSmartTags.GetMarkedPointCount();
return nCount;
}
bool View::IsPointMarkable(const SdrHdl& rHdl) const
{
if( SmartTagSet::IsPointMarkable( rHdl ) )
return true;
else
return FmFormView::IsPointMarkable( rHdl );
}
bool View::MarkPoint(SdrHdl& rHdl, bool bUnmark )
{
if( maSmartTags.MarkPoint( rHdl, bUnmark ) )
return true;
else
return FmFormView::MarkPoint( rHdl, bUnmark );
}
bool View::MarkPoints(const ::tools::Rectangle* pRect, bool bUnmark)
{
if( maSmartTags.MarkPoints( pRect, bUnmark ) )
return true;
else
return FmFormView::MarkPoints( pRect, bUnmark );
}
void View::CheckPossibilities()
{
FmFormView::CheckPossibilities();
maSmartTags.CheckPossibilities();
}
void View::OnBeginPasteOrDrop( PasteOrDropInfos* pInfo )
{
SdrOutliner* pOutliner = GetTextEditOutliner();
if (!pOutliner)
return;
// Turn character attributes of the paragraph of the insert position into
// character-level attributes, so they are not lost when OnEndPasteOrDrop()
// sets the paragraph stylesheet.
SfxItemSet aSet(pOutliner->GetParaAttribs(pInfo->nStartPara));
pOutliner->SetCharAttribs(pInfo->nStartPara, aSet);
}
/** this is called after a paste or drop operation, make sure that the newly inserted paragraphs
get the correct style sheet. */
void View::OnEndPasteOrDrop( PasteOrDropInfos* pInfo )
{
/* Style Sheet handling */
SdrTextObj* pTextObj = GetTextEditObject();
SdrOutliner* pOutliner = GetTextEditOutliner();
if( !pOutliner || !pTextObj || !pTextObj->getSdrPageFromSdrObject() )
return;
SdPage* pPage = static_cast< SdPage* >( pTextObj->getSdrPageFromSdrObject() );
const PresObjKind eKind = pPage->GetPresObjKind(pTextObj);
// outline kinds are taken care of in Outliner::ImplSetLevelDependentStyleSheet
if( eKind == PRESOBJ_OUTLINE )
return;
SfxStyleSheet* pStyleSheet = nullptr;
if( eKind != PRESOBJ_NONE )
pStyleSheet = pPage->GetStyleSheetForPresObj(eKind);
else
pStyleSheet = pTextObj->GetStyleSheet();
// just put the object style on each new paragraph
for ( sal_Int32 nPara = pInfo->nStartPara; nPara <= pInfo->nEndPara; nPara++ )
{
pOutliner->SetStyleSheet( nPara, pStyleSheet );
}
}
bool View::ShouldToggleOn(
const bool bBulletOnOffMode,
const bool bNormalBullet)
{
// If setting bullets/numbering by the dialog, always should toggle on.
if (!bBulletOnOffMode)
return true;
SdrModel* pSdrModel = GetModel();
if (!pSdrModel)
return false;
bool bToggleOn = false;
std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, *pSdrModel));
const size_t nMarkCount = GetMarkedObjectCount();
for (size_t nIndex = 0; nIndex < nMarkCount && !bToggleOn; ++nIndex)
{
SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex));
if (!pTextObj || pTextObj->IsTextEditActive())
continue;
if( dynamic_cast< const SdrTableObj *>( pTextObj ) != nullptr)
{
SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
if (!pTableObj)
continue;
CellPos aStart, aEnd;
SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
if (pTableController)
{
pTableController->getSelectedCells(aStart, aEnd);
}
else
{
aStart = SdrTableObj::getFirstCell();
aEnd = pTableObj->getLastCell();
}
sal_Int32 nColCount = pTableObj->getColumnCount();
for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow && !bToggleOn; nRow++)
{
for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol && !bToggleOn; nCol++)
{
sal_Int32 nCellIndex = nRow * nColCount + nCol;
SdrText* pText = pTableObj->getText(nCellIndex);
if (!pText || !pText->GetOutlinerParaObject())
continue;
pOutliner->SetText(*(pText->GetOutlinerParaObject()));
sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1) || bToggleOn;
pOutliner->Clear();
}
}
}
else
{
OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
if (!pParaObj)
continue;
pOutliner->SetText(*pParaObj);
sal_Int16 nStatus = pOutliner->GetBulletsNumberingStatus();
bToggleOn = (bNormalBullet && nStatus != 0) || (!bNormalBullet && nStatus != 1) || bToggleOn;
pOutliner->Clear();
}
}
return bToggleOn;
}
void View::ChangeMarkedObjectsBulletsNumbering(
const bool bToggle,
const bool bHandleBullets,
const SvxNumRule* pNumRule )
{
SdrModel* pSdrModel = GetModel();
vcl::Window* pWindow = dynamic_cast< vcl::Window* >(GetFirstOutputDevice());
if (!pSdrModel || !pWindow)
return;
const bool bUndoEnabled = pSdrModel->IsUndoEnabled();
SdrUndoGroup* pUndoGroup = bUndoEnabled ? new SdrUndoGroup(*pSdrModel) : nullptr;
const bool bToggleOn = ShouldToggleOn( bToggle, bHandleBullets );
std::unique_ptr<SdrOutliner> pOutliner(SdrMakeOutliner(OutlinerMode::TextObject, *pSdrModel));
std::unique_ptr<OutlinerView> pOutlinerView(new OutlinerView(pOutliner.get(), pWindow));
const size_t nMarkCount = GetMarkedObjectCount();
for (size_t nIndex = 0; nIndex < nMarkCount; ++nIndex)
{
SdrTextObj* pTextObj = dynamic_cast< SdrTextObj* >(GetMarkedObjectByIndex(nIndex));
if (!pTextObj || pTextObj->IsTextEditActive())
continue;
if( dynamic_cast< SdrTableObj *>( pTextObj ) != nullptr)
{
SdrTableObj* pTableObj = dynamic_cast< SdrTableObj* >(pTextObj);
if (!pTableObj)
continue;
CellPos aStart, aEnd;
SvxTableController* pTableController = dynamic_cast< SvxTableController* >(getSelectionController().get());
if (pTableController)
{
pTableController->getSelectedCells(aStart, aEnd);
}
else
{
aStart = SdrTableObj::getFirstCell();
aEnd = pTableObj->getLastCell();
}
sal_Int32 nColCount = pTableObj->getColumnCount();
for (sal_Int32 nRow = aStart.mnRow; nRow <= aEnd.mnRow; nRow++)
{
for (sal_Int32 nCol = aStart.mnCol; nCol <= aEnd.mnCol; nCol++)
{
sal_Int32 nCellIndex = nRow * nColCount + nCol;
SdrText* pText = pTableObj->getText(nCellIndex);
if (!pText || !pText->GetOutlinerParaObject())
continue;
pOutliner->SetText(*(pText->GetOutlinerParaObject()));
if (bUndoEnabled)
{
SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, nCellIndex));
pUndoGroup->AddAction(pTxtUndo);
}
if ( !bToggleOn )
{
pOutlinerView->SwitchOffBulletsNumbering();
}
else
{
pOutlinerView->ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
}
sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
pText->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
pOutliner->Clear();
}
}
// Broadcast the object change event.
if (!pTextObj->AdjustTextFrameWidthAndHeight())
{
pTextObj->SetChanged();
pTextObj->BroadcastObjectChange();
}
}
else
{
OutlinerParaObject* pParaObj = pTextObj->GetOutlinerParaObject();
if (!pParaObj)
continue;
pOutliner->SetText(*pParaObj);
if (bUndoEnabled)
{
SdrUndoObjSetText* pTxtUndo = dynamic_cast< SdrUndoObjSetText* >(pSdrModel->GetSdrUndoFactory().CreateUndoObjectSetText(*pTextObj, 0));
pUndoGroup->AddAction(pTxtUndo);
}
if ( !bToggleOn )
{
pOutlinerView->SwitchOffBulletsNumbering();
}
else
{
pOutlinerView->ApplyBulletsNumbering( bHandleBullets, pNumRule, bToggle );
}
sal_uInt32 nParaCount = pOutliner->GetParagraphCount();
pTextObj->SetOutlinerParaObject(pOutliner->CreateParaObject(0, static_cast<sal_uInt16>(nParaCount)));
pOutliner->Clear();
}
}
if ( bUndoEnabled && pUndoGroup->GetActionCount() > 0 )
{
pSdrModel->BegUndo();
pSdrModel->AddUndo(pUndoGroup);
pSdrModel->EndUndo();
}
else
delete pUndoGroup;
}
} // end of namespace sd
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V560 A part of conditional expression is always false: bToggleOn.
↑ V560 A part of conditional expression is always false: bToggleOn.