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

Quelle  svdmrkv1.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 <svx/svdmrkv.hxx>
#include <svx/svdpagv.hxx>
#include <osl/diagnose.h>


// Point Selection


bool SdrMarkView::HasMarkablePoints() const
{
    ForceUndirtyMrkPnt();
    bool bRet=false;
    if (!ImpIsFrameHandles()) {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkCount=rMarkList.GetMarkCount();
        if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
            for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
                const SdrMark* pM=rMarkList.GetMark(nMarkNum);
                const SdrObject* pObj=pM->GetMarkedSdrObj();
                bRet=pObj->IsPolyObj();
            }
        }
    }
    return bRet;
}

sal_Int32 SdrMarkView::GetMarkablePointCount() const
{
    ForceUndirtyMrkPnt();
    sal_Int32 nCount=0;
    if (!ImpIsFrameHandles()) {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkCount=rMarkList.GetMarkCount();
        if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
            for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
                const SdrMark* pM=rMarkList.GetMark(nMarkNum);
                const SdrObject* pObj=pM->GetMarkedSdrObj();
                if (pObj->IsPolyObj()) {
                    nCount+=pObj->GetPointCount();
                }
            }
        }
    }
    return nCount;
}

bool SdrMarkView::HasMarkedPoints() const
{
    ForceUndirtyMrkPnt();
    bool bRet=false;
    if (!ImpIsFrameHandles()) {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkCount=rMarkList.GetMarkCount();
        if (nMarkCount<=static_cast<size_t>(mnFrameHandlesLimit)) {
            for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
                const SdrMark* pM=rMarkList.GetMark(nMarkNum);
                const SdrUShortCont& rPts = pM->GetMarkedPoints();
                bRet = !rPts.empty();
            }
        }
    }
    return bRet;
}

bool SdrMarkView::IsPointMarkable(const SdrHdl& rHdl) const
{
    return !ImpIsFrameHandles() && !rHdl.IsPlusHdl() && rHdl.GetKind()!=SdrHdlKind::Glue && rHdl.GetKind()!=SdrHdlKind::SmartTag && rHdl.GetObj()!=nullptr && rHdl.GetObj()->IsPolyObj();
}

bool SdrMarkView::MarkPointHelper(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark)
{
    return ImpMarkPoint( pHdl, pMark, bUnmark );
}

bool SdrMarkView::ImpMarkPoint(SdrHdl* pHdl, SdrMark* pMark, bool bUnmark)
{
    if (pHdl==nullptr || pHdl->IsPlusHdl() || pHdl->GetKind()==SdrHdlKind::Glue)
        return false;

    if (pHdl->IsSelected() != bUnmark)
        return false;

    SdrObject* pObj=pHdl->GetObj();
    if (pObj==nullptr || !pObj->IsPolyObj())
        return false;

    if (pMark==nullptr)
    {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkNum=rMarkList.FindObject(pObj);
        if (nMarkNum==SAL_MAX_SIZE)
            return false;
        pMark=rMarkList.GetMark(nMarkNum);
    }
    const sal_uInt32 nHdlNum(pHdl->GetObjHdlNum());
    SdrUShortCont& rPts=pMark->GetMarkedPoints();
    if (!bUnmark)
    {
        rPts.insert(static_cast<sal_uInt16>(nHdlNum));
    }
    else
    {
        SdrUShortCont::const_iterator it = rPts.find( static_cast<sal_uInt16>(nHdlNum) );
        if (it != rPts.end())
        {
            rPts.erase(it);
        }
        else
        {
            return false// error case!
        }
    }

    pHdl->SetSelected(!bUnmark);
    if (!mbPlusHdlAlways)
    {
        if (!bUnmark)
        {
            SdrHdlList plusList(nullptr);
            pObj->AddToPlusHdlList(plusList, *pHdl);
            sal_uInt32 nCount(plusList.GetHdlCount());
            for (sal_uInt32 i=0; i<nCount; i++)
            {
                SdrHdl* pPlusHdl=plusList.GetHdl(i);
                pPlusHdl->SetObj(pObj);
                pPlusHdl->SetPageView(pMark->GetPageView());
                pPlusHdl->SetPlusHdl(true);
            }
            plusList.MoveTo(maHdlList);
        }
        else
        {
            for (size_t i = maHdlList.GetHdlCount(); i>0;)
            {
                --i;
                SdrHdl* pPlusHdl=maHdlList.GetHdl(i);
                if (pPlusHdl->IsPlusHdl() && pPlusHdl->GetSourceHdlNum()==nHdlNum)
                {
                    maHdlList.RemoveHdl(i);
                }
            }
        }
    }

    maHdlList.Sort();

    return true;
}


bool SdrMarkView::MarkPoint(SdrHdl& rHdl, bool bUnmark)
{
    ForceUndirtyMrkPnt();
    bool bRet=false;
    const SdrObject* pObj=rHdl.GetObj();
    if (IsPointMarkable(rHdl) && rHdl.IsSelected()==bUnmark) {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkNum=rMarkList.FindObject(pObj);
        if (nMarkNum!=SAL_MAX_SIZE) {
            SdrMark* pM=rMarkList.GetMark(nMarkNum);
            if (ImpMarkPoint(&rHdl,pM,bUnmark)) {
                MarkListHasChanged();
                bRet=true;
            }
        }
    }

    return bRet;
}

bool SdrMarkView::MarkPoints(const tools::Rectangle* pRect, bool bUnmark)
{
    ForceUndirtyMrkPnt();
    bool bChgd=false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    rMarkList.ForceSort();
    const SdrObject* pObj0=nullptr;
    const SdrPageView* pPV0=nullptr;
    SdrMark* pM=nullptr;
    maHdlList.Sort();
    const size_t nHdlCnt=maHdlList.GetHdlCount();
    for (size_t nHdlNum=nHdlCnt; nHdlNum>0;) {
        --nHdlNum;
        SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
        if (IsPointMarkable(*pHdl) && pHdl->IsSelected()==bUnmark) {
            const SdrObject* pObj=pHdl->GetObj();
            const SdrPageView* pPV=pHdl->GetPageView();
            if (pObj!=pObj0 || pPV!=pPV0 || pM==nullptr) { // This section is for optimization,
                const size_t nMarkNum=rMarkList.FindObject(pObj);  // so ImpMarkPoint() doesn't always
                if (nMarkNum!=SAL_MAX_SIZE) { // have to search the object in the MarkList.
                    pM=rMarkList.GetMark(nMarkNum);
                    pObj0=pObj;
                    pPV0=pPV;
                } else {
#ifdef DBG_UTIL
                    assert(pObj);
                    if (pObj->IsInserted()) {
                        OSL_FAIL("SdrMarkView::MarkPoints(const Rectangle* pRect): Selected object not found.");
                    }
#endif
                    pM=nullptr;
                }
            }
            Point aPos(pHdl->GetPos());
            if (pM!=nullptr && (pRect==nullptr || pRect->Contains(aPos))) {
                if (ImpMarkPoint(pHdl,pM,bUnmark)) bChgd=true;
            }
        }
    }
    if (bChgd) {
        MarkListHasChanged();
    }

    return bChgd;
}

void SdrMarkView::MarkNextPoint()
{
    ForceUndirtyMrkPnt();
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    rMarkList.ForceSort();
}

const tools::Rectangle& SdrMarkView::GetMarkedPointsRect() const
{
    ForceUndirtyMrkPnt();
    if (mbMarkedPointsRectsDirty) ImpSetPointsRects();
    return maMarkedPointsRect;
}

void SdrMarkView::SetPlusHandlesAlwaysVisible(bool bOn)
// TODO: Optimize HandlePaint!
    ForceUndirtyMrkPnt();
    if (bOn!=mbPlusHdlAlways) {
        mbPlusHdlAlways=bOn;
        SetMarkHandles(nullptr);
        MarkListHasChanged();
    }
}


// ImpSetPointsRects() is for PolyPoints and GluePoints!


void SdrMarkView::ImpSetPointsRects() const
{
    tools::Rectangle aPnts;
    tools::Rectangle aGlue;
    const size_t nHdlCnt=maHdlList.GetHdlCount();
    for (size_t nHdlNum=0; nHdlNum<nHdlCnt; ++nHdlNum) {
        const SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
        SdrHdlKind eKind=pHdl->GetKind();
        if ((eKind==SdrHdlKind::Poly && pHdl->IsSelected()) || eKind==SdrHdlKind::Glue) {
            Point aPt(pHdl->GetPos());
            tools::Rectangle& rR=eKind==SdrHdlKind::Glue ? aGlue : aPnts;
            if (rR.IsEmpty()) {
                rR=tools::Rectangle(aPt,aPt);
            } else {
                if (aPt.X()<rR.Left  ()) rR.SetLeft(aPt.X() );
                if (aPt.X()>rR.Right ()) rR.SetRight(aPt.X() );
                if (aPt.Y()<rR.Top   ()) rR.SetTop(aPt.Y() );
                if (aPt.Y()>rR.Bottom()) rR.SetBottom(aPt.Y() );
            }
        }
    }
    const_cast<SdrMarkView*>(this)->maMarkedPointsRect=aPnts;
    const_cast<SdrMarkView*>(this)->maMarkedGluePointsRect=aGlue;
    const_cast<SdrMarkView*>(this)->mbMarkedPointsRectsDirty=false;
}


// UndirtyMrkPnt() is for PolyPoints and GluePoints!


void SdrMarkView::UndirtyMrkPnt() const
{
    bool bChg=false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    const size_t nMarkCount=rMarkList.GetMarkCount();
    for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
        SdrMark* pM=rMarkList.GetMark(nMarkNum);
        const SdrObject* pObj=pM->GetMarkedSdrObj();
        // PolyPoints
        {
            SdrUShortCont& rPts = pM->GetMarkedPoints();
            if (pObj->IsPolyObj()) {
                // Remove invalid selected points, that is, all
                // entries above the number of points in the object.
                sal_uInt32 nMax(pObj->GetPointCount());

                SdrUShortCont::const_iterator it = rPts.lower_bound(nMax);
                if( it != rPts.end() )
                {
                    rPts.erase(it, rPts.end());
                    bChg = true;
                }
            }
            else
            {
                if (!rPts.empty())
                {
                    // only fail *if* there are marked points
                    OSL_FAIL("SdrMarkView::UndirtyMrkPnt(): Selected points on an object that is not a PolyObj!");
                    rPts.clear();
                    bChg = true;
                }
            }
        }

        // GluePoints
        {
            SdrUShortCont& rPts = pM->GetMarkedGluePoints();
            const SdrGluePointList* pGPL=pObj->GetGluePointList();
            if (pGPL!=nullptr) {
                // Remove invalid selected gluepoints, that is, all entries
                // (IDs) that aren't contained in the GluePointList of the
                // object
                for(SdrUShortCont::const_iterator it = rPts.begin(); it != rPts.end(); )
                {
                    sal_uInt16 nId=*it;
                    if (pGPL->FindGluePoint(nId)==SDRGLUEPOINT_NOTFOUND) {
                        it = rPts.erase(it);
                        bChg=true;
                    }
                    else
                        ++it;
                }
            } else {
                if (!rPts.empty()) {
                    rPts.clear(); // object doesn't have any gluepoints (any more)
                    bChg=true;
                }
            }
        }
    }
    if (bChg) const_cast<SdrMarkView*>(this)->mbMarkedPointsRectsDirty=true;
    const_cast<SdrMarkView*>(this)->mbMrkPntDirty=false;
}


bool SdrMarkView::HasMarkableGluePoints() const
{
    bool bRet=false;
    if (IsGluePointEditMode()) {
        ForceUndirtyMrkPnt();
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkCount=rMarkList.GetMarkCount();
        for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
            const SdrMark* pM=rMarkList.GetMark(nMarkNum);
            const SdrObject* pObj=pM->GetMarkedSdrObj();
            const SdrGluePointList* pGPL=pObj->GetGluePointList();

            // #i38892#
            if(pGPL && pGPL->GetCount())
            {
                for(sal_uInt16 a(0); !bRet && a < pGPL->GetCount(); a++)
                {
                    if((*pGPL)[a].IsUserDefined())
                    {
                        bRet = true;
                    }
                }
            }
        }
    }
    return bRet;
}

bool SdrMarkView::HasMarkedGluePoints() const
{
    ForceUndirtyMrkPnt();
    bool bRet=false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    const size_t nMarkCount=rMarkList.GetMarkCount();
    for (size_t nMarkNum=0; nMarkNum<nMarkCount && !bRet; ++nMarkNum) {
        const SdrMark* pM=rMarkList.GetMark(nMarkNum);
        const SdrUShortCont& rPts = pM->GetMarkedGluePoints();
        bRet = !rPts.empty();
    }
    return bRet;
}

bool SdrMarkView::MarkGluePoints(const tools::Rectangle* pRect, bool bUnmark)
{
    if (!IsGluePointEditMode() && !bUnmark) return false;
    ForceUndirtyMrkPnt();
    bool bChgd=false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    rMarkList.ForceSort();
    const size_t nMarkCount=rMarkList.GetMarkCount();
    for (size_t nMarkNum=0; nMarkNum<nMarkCount; ++nMarkNum) {
        SdrMark* pM=rMarkList.GetMark(nMarkNum);
        const SdrObject* pObj=pM->GetMarkedSdrObj();
        const SdrGluePointList* pGPL=pObj->GetGluePointList();
        SdrUShortCont& rPts = pM->GetMarkedGluePoints();
        if (bUnmark && pRect==nullptr) { // UnmarkAll
            if (!rPts.empty()) {
                rPts.clear();
                bChgd=true;
            }
        } else {
            if (pGPL!=nullptr) {
                sal_uInt16 nGluePointCnt=pGPL->GetCount();
                for (sal_uInt16 nGPNum=0; nGPNum<nGluePointCnt; nGPNum++) {
                    const SdrGluePoint& rGP=(*pGPL)[nGPNum];

                    // #i38892#
                    if(rGP.IsUserDefined())
                    {
                        Point aPos(rGP.GetAbsolutePos(*pObj));
                        if (pRect==nullptr || pRect->Contains(aPos)) {
                            bool bContains = rPts.find( rGP.GetId() ) != rPts.end();
                            if (!bUnmark && !bContains) {
                                bChgd=true;
                                rPts.insert(rGP.GetId());
                            }
                            if (bUnmark && bContains) {
                                bChgd=true;
                                rPts.erase(rGP.GetId());
                            }
                        }
                    }
                }
            }
        }
    }
    if (bChgd) {
        AdjustMarkHdl();
        MarkListHasChanged();
    }
    return bChgd;
}

bool SdrMarkView::PickGluePoint(const Point& rPnt, SdrObject*& rpObj, sal_uInt16& rnId, SdrPageView*& rpPV) const
{
    rpObj=nullptr; rpPV=nullptr; rnId=0;
    if (!IsGluePointEditMode()) return false;
    OutputDevice* pOut=mpActualOutDev.get();
    if (pOut==nullptr) pOut=GetFirstOutputDevice();
    if (pOut==nullptr) return false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    rMarkList.ForceSort();
    const size_t nMarkCount=rMarkList.GetMarkCount();
    size_t nMarkNum=nMarkCount;
    while (nMarkNum>0) {
        nMarkNum--;
        const SdrMark* pM=rMarkList.GetMark(nMarkNum);
        SdrObject* pObj=pM->GetMarkedSdrObj();
        SdrPageView* pPV=pM->GetPageView();
        const SdrGluePointList* pGPL=pObj->GetGluePointList();
        if (pGPL!=nullptr) {
            sal_uInt16 nNum=pGPL->HitTest(rPnt,*pOut,pObj);
            if (nNum!=SDRGLUEPOINT_NOTFOUND)
            {
                // #i38892#
                const SdrGluePoint& rCandidate = (*pGPL)[nNum];

                if(rCandidate.IsUserDefined())
                {
                    rpObj=pObj;
                    rnId=(*pGPL)[nNum].GetId();
                    rpPV=pPV;
                    return true;
                }
            }
        }
    }
    return false;
}

bool SdrMarkView::MarkGluePoint(const SdrObject* pObj, sal_uInt16 nId, bool bUnmark)
{
    if (!IsGluePointEditMode()) return false;
    ForceUndirtyMrkPnt();
    bool bChgd=false;
    if (pObj!=nullptr) {
        const SdrMarkList& rMarkList = GetMarkedObjectList();
        const size_t nMarkPos=rMarkList.FindObject(pObj);
        if (nMarkPos!=SAL_MAX_SIZE) {
            SdrMark* pM=rMarkList.GetMark(nMarkPos);
            SdrUShortCont& rPts = pM->GetMarkedGluePoints();
            bool bContains = rPts.find( nId ) != rPts.end();
            if (!bUnmark && !bContains) {
                bChgd=true;
                rPts.insert(nId);
            }
            if (bUnmark && bContains) {
                bChgd=true;
                rPts.erase(nId);
            }
        } else {
            // TODO: implement implicit selection of objects
        }
    }
    if (bChgd) {
        AdjustMarkHdl();
        MarkListHasChanged();
    }
    return bChgd;
}

bool SdrMarkView::IsGluePointMarked(const SdrObject* pObj, sal_uInt16 nId) const
{
    ForceUndirtyMrkPnt();
    bool bRet=false;
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    const size_t nPos=rMarkList.FindObject(pObj); // casting to NonConst
    if (nPos!=SAL_MAX_SIZE) {
        const SdrMark* pM=rMarkList.GetMark(nPos);
        const SdrUShortCont& rPts = pM->GetMarkedGluePoints();
        bRet = rPts.find( nId ) != rPts.end();
    }
    return bRet;
}

SdrHdl* SdrMarkView::GetGluePointHdl(const SdrObject* pObj, sal_uInt16 nId) const
{
    ForceUndirtyMrkPnt();
    const size_t nHdlCnt=maHdlList.GetHdlCount();
    for (size_t nHdlNum=0; nHdlNum<nHdlCnt; ++nHdlNum) {
        SdrHdl* pHdl=maHdlList.GetHdl(nHdlNum);
        if (pHdl->GetObj()==pObj &&
            pHdl->GetKind()==SdrHdlKind::Glue &&
            pHdl->GetObjHdlNum()==nId ) return pHdl;
    }
    return nullptr;
}

void SdrMarkView::MarkNextGluePoint()
{
    ForceUndirtyMrkPnt();
    const SdrMarkList& rMarkList = GetMarkedObjectList();
    rMarkList.ForceSort();
}

const tools::Rectangle& SdrMarkView::GetMarkedGluePointsRect() const
{
    ForceUndirtyMrkPnt();
    if (mbMarkedPointsRectsDirty) ImpSetPointsRects();
    return maMarkedGluePointsRect;
}

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

Messung V0.5
C=95 H=96 G=95

¤ 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.