Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/sd/source/ui/func/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 17 kB image not shown  

Quelle  fuconbez.cxx   Sprache: 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 <com/sun/star/presentation/EffectNodeType.hpp>

#include <fuconbez.hxx>
#include <svx/svdopath.hxx>
#include <svl/intitem.hxx>
#include <sfx2/dispatch.hxx>
#include <svx/svdobj.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/request.hxx>
#include <sfx2/viewfrm.hxx>
#include <osl/diagnose.h>

#include <svx/svxids.hrc>
#include <svx/svdpagv.hxx>
#include <svx/xlnclit.hxx>
#include <svx/xlntrit.hxx>
#include <svx/xlnwtit.hxx>

#include <app.hrc>
#include <ViewShell.hxx>
#include <ViewShellBase.hxx>
#include <View.hxx>
#include <Window.hxx>
#include <ToolBarManager.hxx>
#include <drawdoc.hxx>
#include <sdpage.hxx>

#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

#include <CustomAnimationEffect.hxx>

using namespace ::com::sun::star::uno;

namespace sd {

/*//Extra attributes coming from parameters
    sal_uInt16  mnTransparence;  // Default: 0
    OUString    msColor;         // Default: ""
    sal_uInt16  mnWidth;         // Default: 0
    OUString    msShapeName;     // Default: ""*/
FuConstructBezierPolygon::FuConstructBezierPolygon (
    ViewShell& rViewSh,
    ::sd::Window* pWin,
    ::sd::View* pView,
    SdDrawDocument& rDoc,
    SfxRequest& rReq)
    : FuConstruct(rViewSh, pWin, pView, rDoc, rReq),
      nEditMode(SID_BEZIER_MOVE),
      mnTransparence(0),
      mnWidth(0)
{
}

namespace{

/// Checks to see if the request has a parameter of IsSticky:bool=true
/// It means that the selected command/button will stay selected after use
bool isSticky(const SfxRequest& rReq)
{
    const SfxItemSet *pArgs = rReq.GetArgs ();
    if (pArgs)
    {
        const SfxBoolItem* pIsSticky = rReq.GetArg<SfxBoolItem>(FN_PARAM_4);
        if (pIsSticky && pIsSticky->GetValue())
            return true;
    }

    return false;
}

}

rtl::Reference<FuPoor> FuConstructBezierPolygon::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq, bool bPermanent )
{
    FuConstructBezierPolygon* pFunc;
    rtl::Reference<FuPoor> xFunc( pFunc = new FuConstructBezierPolygon( rViewSh, pWin, pView, rDoc, rReq ) );
    xFunc->DoExecute(rReq);
    pFunc->SetPermanent(bPermanent || isSticky(rReq));
    return xFunc;
}

void FuConstructBezierPolygon::DoExecute( SfxRequest& rReq )
{
    FuConstruct::DoExecute( rReq );

    const SfxItemSet* pArgs = rReq.GetArgs();

    if( !pArgs )
        return;

    const SfxUnoAnyItem* pPoolItem = pArgs->GetItemIfSet( SID_ADD_MOTION_PATH );
    if( pPoolItem )
        maTargets = pPoolItem->GetValue();

    if (nSlotId != SID_DRAW_FREELINE_NOFILL)
        return;

    const SfxUInt16Item* pTransparence  = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
    const SfxStringItem* pColor         = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
    const SfxUInt16Item* pWidth         = rReq.GetArg<SfxUInt16Item>(FN_PARAM_3);
    const SfxStringItem* pShapeName     = rReq.GetArg<SfxStringItem>(SID_SHAPE_NAME);

    if (pTransparence && pTransparence->GetValue() > 0)
    {
        mnTransparence = pTransparence->GetValue();
    }
    if (pColor && !pColor->GetValue().isEmpty())
    {
        msColor = pColor->GetValue();
    }
    if (pWidth && pWidth->GetValue() > 0)
    {
        mnWidth = pWidth->GetValue();
    }
    if (pShapeName && !pShapeName->GetValue().isEmpty())
    {
        msShapeName = pShapeName->GetValue();
    }
}

bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent& rMEvt)
{
    bool bReturn = FuConstruct::MouseButtonDown(rMEvt);

    SdrViewEvent aVEvt;
    SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);

    if (eHit == SdrHitKind::Handle || rMEvt.IsMod1())
    {
        mpView->SetEditMode(SdrViewEditMode::Edit);
    }
    else
    {
        mpView->SetEditMode(SdrViewEditMode::Create);
    }

    if (aVEvt.meEvent == SdrEventKind::BeginTextEdit)
    {
        // here, we do not allow text input
        aVEvt.meEvent = SdrEventKind::BeginDragObj;
        mpView->EnableExtendedMouseEventDispatcher(false);
    }
    else
    {
        mpView->EnableExtendedMouseEventDispatcher(true);
    }

    if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT)
    {
        // insert gluepoint
        mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1());
    }
    else
    {
        mpView->MouseButtonDown(rMEvt, mpWindow->GetOutDev());

        SdrObject* pObj = mpView->GetCreateObj();

        if (pObj)
        {
            SfxItemSet aAttr(mrDoc.GetPool());
            SetStyleSheet(aAttr, pObj);
            SetAttributes(aAttr, pObj);
            pObj->SetMergedItemSet(aAttr);
        }
    }

    return bReturn;
}

bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent& rMEvt )
{
    if (rMEvt.IsLeft() && IsIgnoreUnexpectedMouseButtonUp())
        return false;

    bool bReturn = false;
    bool bCreated = false;

    SdrViewEvent aVEvt;
    mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aVEvt);

    const size_t nCount = mpView->GetSdrPageView()->GetObjList()->GetObjCount();

    if (mpView->IsInsObjPoint())
    {
        mpView->EndInsObjPoint(SdrCreateCmd::ForceEnd);
    }
    else
    {
        mpView->MouseButtonUp(rMEvt, mpWindow->GetOutDev());
    }

    if (aVEvt.meEvent == SdrEventKind::EndCreate)
    {
        bReturn = true;

        if (nCount+1 == mpView->GetSdrPageView()->GetObjList()->GetObjCount())
        {
            bCreated = true;
        }

        // trick to suppress FuDraw::DoubleClick
        bMBDown = false;

    }

    bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn;

    bool bDeleted = false;
    if( bCreated && maTargets.hasValue() )
    {
        SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( mpView->GetSdrPageView()->GetObjList()->GetObj( nCount ) );
        SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->getSdrPageFromSdrObject() : nullptr );
        if( pPage )
        {
            std::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
            if( pMainSequence )
            {
                Sequence< Any > aTargets;
                maTargets >>= aTargets;

                sal_Int32 nTCount = aTargets.getLength();
                if( nTCount > 1 )
                {
                    const Any* pTarget = aTargets.getConstArray();
                    double fDuration = 0.0;
                    *pTarget++ >>= fDuration;
                    bool bFirst = true;

                    OUString sPresetId;
                    switch(nSlotId)
                    {
                        case SID_DRAW_BEZIER_NOFILL:
                            sPresetId = "libo-motionpath-curve";
                            break;
                        case SID_DRAW_POLYGON_NOFILL:
                            sPresetId = "libo-motionpath-polygon";
                            break;
                        case SID_DRAW_FREELINE_NOFILL:
                            sPresetId = "libo-motionpath-freeform-line";
                            break;
                    }

                    while( --nTCount )
                    {
                        CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, *pTarget++, fDuration, sPresetId) );
                        if( bFirst )
                            bFirst = false;
                        else
                            pCreated->setNodeType( css::presentation::EffectNodeType::WITH_PREVIOUS );
                    }
                }
            }
        }
        mpView->DeleteMarked();
        bDeleted = true;
    }

    if ((!bPermanent && bCreated) || bDeleted)
    {
        mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
    }

    return bReturn;
}

void FuConstructBezierPolygon::Activate()
{
    mpView->EnableExtendedMouseEventDispatcher(true);

    SdrObjKind eKind;

    switch (nSlotId)
    {
        case SID_DRAW_POLYGON_NOFILL:
        case SID_DRAW_XPOLYGON_NOFILL:
        {
            eKind = SdrObjKind::PolyLine;
        }
        break;

        case SID_DRAW_POLYGON:
        case SID_DRAW_XPOLYGON:
        {
            eKind = SdrObjKind::Polygon;
        }
        break;

        case SID_DRAW_BEZIER_NOFILL:
        {
            eKind = SdrObjKind::PathLine;
        }
        break;

        case SID_DRAW_BEZIER_FILL:
        {
            eKind = SdrObjKind::PathFill;
        }
        break;

        case SID_DRAW_FREELINE_NOFILL:
        {
            eKind = SdrObjKind::FreehandLine;
        }
        break;

        case SID_DRAW_FREELINE:
        {
            eKind = SdrObjKind::FreehandFill;
        }
        break;

        default:
        {
            eKind = SdrObjKind::PathLine;
        }
        break;
    }

    mpView->SetCurrentObj(eKind);

    FuConstruct::Activate();
}

void FuConstructBezierPolygon::Deactivate()
{
    mpView->EnableExtendedMouseEventDispatcher(false);

    FuConstruct::Deactivate();
}

void FuConstructBezierPolygon::SelectionHasChanged()
{
    FuDraw::SelectionHasChanged();

    mrViewShell.GetViewShellBase().GetToolBarManager()->SelectionHasChanged(
        mrViewShell,
        *mpView);
}

namespace {
/// Returns the color based on the color names listed in core/include/tools/color.hxx
/// Feel free to extend with more color names from color.hxx
Color strToColor(std::u16string_view sColor)
{
    Color aColor = COL_AUTO;

    if (sColor == u"COL_GRAY")
        aColor = COL_GRAY;
    else if (sColor == u"COL_GRAY3")
        aColor = COL_GRAY3;
    else if (sColor == u"COL_GRAY7")
        aColor = COL_GRAY7;

    return aColor;
}
}

void FuConstructBezierPolygon::SetAttributes(SfxItemSet& rAttr, SdrObject *pObj)
{
    if (nSlotId == SID_DRAW_FREELINE_NOFILL)
    {
        if (mnTransparence > 0 && mnTransparence <= 100)
            rAttr.Put(XLineTransparenceItem(mnTransparence));
        if (!msColor.isEmpty())
            rAttr.Put(XLineColorItem(OUString(), strToColor(msColor)));
        if (mnWidth > 0)
            rAttr.Put(XLineWidthItem(mnWidth));
        if (!msShapeName.isEmpty())
            pObj->SetName(msShapeName);
    }
}

/**
 * Set current bezier edit mode
 */

void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode)
{
    nEditMode = nMode;
    ForcePointer();

    SfxBindings& rBindings = mrViewShell.GetViewFrame()->GetBindings();
    rBindings.Invalidate(SID_BEZIER_MOVE);
    rBindings.Invalidate(SID_BEZIER_INSERT);
}

rtl::Reference<SdrObject> FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID, const ::tools::Rectangle& rRectangle)
{
    // case SID_DRAW_POLYGON:
    // case SID_DRAW_POLYGON_NOFILL:
    // case SID_DRAW_XPOLYGON:
    // case SID_DRAW_XPOLYGON_NOFILL:
    // case SID_DRAW_FREELINE:
    // case SID_DRAW_FREELINE_NOFILL:
    // case SID_DRAW_BEZIER_FILL:          // BASIC
    // case SID_DRAW_BEZIER_NOFILL:        // BASIC

    rtl::Reference<SdrObject> pObj(SdrObjFactory::MakeNewObject(
        mpView->getSdrModelFromSdrView(),
        mpView->GetCurrentObjInventor(),
        mpView->GetCurrentObjIdentifier()));

    if(pObj)
    {
        ifauto pPathObj = dynamic_cast< SdrPathObj *>( pObj.get() ) )
        {
            basegfx::B2DPolyPolygon aPoly;

            switch(nID)
            {
                case SID_DRAW_BEZIER_FILL:
                {
                    const sal_Int32 nWdt(rRectangle.GetWidth() / 2);
                    const sal_Int32 nHgt(rRectangle.GetHeight() / 2);
                    const basegfx::B2DPolygon aInnerPoly(basegfx::utils::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()), nWdt, nHgt));

                    aPoly.append(aInnerPoly);
                    break;
                }
                case SID_DRAW_BEZIER_NOFILL:
                {
                    basegfx::B2DPolygon aInnerPoly;

                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));

                    const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom());
                    aInnerPoly.appendBezierSegment(
                        aCenterBottom,
                        aCenterBottom,
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));

                    const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top());
                    aInnerPoly.appendBezierSegment(
                        aCenterTop,
                        aCenterTop,
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));

                    aPoly.append(aInnerPoly);
                    break;
                }
                case SID_DRAW_FREELINE:
                case SID_DRAW_FREELINE_NOFILL:
                {
                    basegfx::B2DPolygon aInnerPoly;

                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));

                    aInnerPoly.appendBezierSegment(
                        basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()),
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()),
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));

                    aInnerPoly.appendBezierSegment(
                        basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()),
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()),
                        basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));

                    if(SID_DRAW_FREELINE == nID)
                    {
                        aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
                    }
                    else
                    {
                        aInnerPoly.setClosed(true);
                    }

                    aPoly.append(aInnerPoly);
                    break;
                }
                case SID_DRAW_XPOLYGON:
                case SID_DRAW_XPOLYGON_NOFILL:
                {
                    basegfx::B2DPolygon aInnerPoly;

                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Center().Y()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));

                    if(SID_DRAW_XPOLYGON_NOFILL == nID)
                    {
                        aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
                    }
                    else
                    {
                        aInnerPoly.setClosed(true);
                    }

                    aPoly.append(aInnerPoly);
                    break;
                }
                case SID_DRAW_POLYGON:
                case SID_DRAW_POLYGON_NOFILL:
                {
                    basegfx::B2DPolygon aInnerPoly;
                    const sal_Int32 nWdt(rRectangle.GetWidth());
                    const sal_Int32 nHgt(rRectangle.GetHeight());

                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top()));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100));
                    aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right()));

                    if(SID_DRAW_POLYGON_NOFILL == nID)
                    {
                        aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
                    }
                    else
                    {
                        aInnerPoly.setClosed(true);
                    }

                    aPoly.append(aInnerPoly);
                    break;
                }
            }

            pPathObj->SetPathPoly(aPoly);
        }
        else
        {
            OSL_FAIL("Object is NO path object");
        }

        pObj->SetLogicRect(rRectangle);
    }

    return pObj;
}

// end of namespace sd

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=92 H=97 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.