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

Quelle  sdtreelb.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 <sal/log.hxx>
#include <sal/types.h>
#include <sot/formats.hxx>
#include <utility>
#include <vcl/weld.hxx>
#include <svx/svditer.hxx>
#include <sfx2/docfile.hxx>
#include <svx/svdoole2.hxx>
#include <vcl/svapp.hxx>
#include <cusshow.hxx>

#include <sfx2/viewfrm.hxx>

#include <sdtreelb.hxx>
#include <DrawDocShell.hxx>
#include <drawdoc.hxx>
#include <sdpage.hxx>
#include <sdmod.hxx>
#include <sdresid.hxx>
#include <navigatr.hxx>
#include <strings.hrc>

#include <bitmaps.hlst>
#include <customshowlist.hxx>
#include <ViewShell.hxx>
#include <DrawController.hxx>
#include <ViewShellBase.hxx>

#include <com/sun/star/embed/XEmbedPersist.hpp>
#include <com/sun/star/embed/XEmbeddedObject.hpp>
#include <com/sun/star/frame/Desktop.hpp>
#include <svtools/acceleratorexecute.hxx>
#include <svtools/embedtransfer.hxx>
#include <comphelper/servicehelper.hxx>
#include <comphelper/processfactory.hxx>

#include <vcl/commandevent.hxx>

#include <svx/svdview.hxx>
#include <DrawViewShell.hxx>

#include <svx/svdoashp.hxx>
#include <svx/sdasitm.hxx>
#include <svl/poolitem.hxx>
#include <svl/stritem.hxx>

using namespace com::sun::star;

namespace {

sd::DrawViewShell* lcl_getDrawViewShell(const SdDrawDocument* pDoc)
{
    if (!pDoc || !pDoc->GetDocSh())
        return nullptr;
    return static_cast<sd::DrawViewShell*>(pDoc->GetDocSh()->GetViewShell());
}

}

SotClipboardFormatId SdPageObjsTLV::SdPageObjsTransferable::mnListBoxDropFormatId static_cast<SotClipboardFormatId>(SAL_MAX_UINT32);

SdPageObjsTLV::SdPageObjsTransferable::SdPageObjsTransferable(
        INetBookmark aBookmark,
    ::sd::DrawDocShell& rDocShell,
    NavigatorDragType eDragType)
    : SdTransferable(rDocShell.GetDoc(), nullptr, true),
      maBookmark(std::move( aBookmark )),
      mrDocShell( rDocShell ),
      meDragType( eDragType )
{
}

SdPageObjsTLV::SdPageObjsTransferable::~SdPageObjsTransferable()
{
}

void SdPageObjsTLV::SdPageObjsTransferable::AddSupportedFormats()
{
    AddFormat(SotClipboardFormatId::NETSCAPE_BOOKMARK);
    AddFormat(SotClipboardFormatId::TREELISTBOX);
    AddFormat(GetListBoxDropFormatId());
}

bool SdPageObjsTLV::SdPageObjsTransferable::GetData( const css::datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
{
    SotClipboardFormatId nFormatId = SotExchange::GetFormat( rFlavor );
    switch (nFormatId)
    {
        case SotClipboardFormatId::NETSCAPE_BOOKMARK:
            SetINetBookmark( maBookmark, rFlavor );
            return true;

        case SotClipboardFormatId::TREELISTBOX:
        {
            css::uno::Any aTreeListBoxData; // empty for now
            SetAny(aTreeListBoxData);
            return true;
        }

        default:
            return false;
    }
}

SdPageObjsTLV::SdPageObjsTransferable* SdPageObjsTLV::SdPageObjsTransferable::getImplementation( const css::uno::Reference< css::uno::XInterface >& rxData )
    noexcept
{
    return dynamic_cast<SdPageObjsTLV::SdPageObjsTransferable*>(rxData.get());
}

SotClipboardFormatId SdPageObjsTLV::SdPageObjsTransferable::GetListBoxDropFormatId()
{
    if (mnListBoxDropFormatId == static_cast<SotClipboardFormatId>(SAL_MAX_UINT32))
        mnListBoxDropFormatId = SotExchange::RegisterFormatMimeType(u"application/x-openoffice-treelistbox-moveonly;windows_formatname=\"SV_LBOX_DD_FORMAT_MOVE\""_ustr);
    return mnListBoxDropFormatId;
}

/**
 * @return true if children of the specified string are selected
 */

bool SdPageObjsTLV::HasSelectedChildren( std::u16string_view rName )
{
    bool bChildren = false;

    if( !rName.empty() )
    {
        std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
        OUString aTmp;

        if (m_xTreeView->get_iter_first(*xEntry))
        {
            do
            {
                aTmp = m_xTreeView->get_text(*xEntry);
                if (aTmp == rName)
                {

                    // see if any of the selected nodes are subchildren of this node
                    m_xTreeView->selected_foreach([this, &bChildren, &xEntry](weld::TreeIter& rEntry){
                        std::unique_ptr<weld::TreeIter> xParent(m_xTreeView->make_iterator(&rEntry));
                        while (!bChildren && m_xTreeView->iter_parent(*xParent))
                            bChildren = m_xTreeView->iter_compare(*xParent, *xEntry) == 0;
                        return bChildren;
                    });

                    break;
                }
            }
            while (m_xTreeView->iter_next(*xEntry));
        }
    }

    return bChildren;
}

void SdPageObjsTLV::SetShowAllShapes (
    const bool bShowAllShapes,
    const bool bFillList)
{
    m_bShowAllShapes = bShowAllShapes;
    if (bFillList)
    {
        if (m_pMedium == nullptr)
            Fill(m_pDoc, m_bShowAllPages, m_aDocName);
        else
            Fill(m_pDoc, m_pMedium, m_aDocName);
    }
}

void SdPageObjsTLV::SetOrderFrontToBack(const bool bOrderFrontToBack)
{
    m_bOrderFrontToBack = bOrderFrontToBack;
}

bool SdPageObjsTLV::IsEqualToShapeList(std::unique_ptr<weld::TreeIter>& rEntry, const SdrObjList& rList,
                                       std::u16string_view rListName)
{
    if (!rEntry)
        return false;
    OUString aName = m_xTreeView->get_text(*rEntry);

    if (rListName != aName)
        return false;

    if (!m_xTreeView->iter_next(*rEntry))
        rEntry.reset();

    SdrObjListIter aIter(&rList,
                         !rList.HasObjectNavigationOrder() /* use navigation order, if available */,
                         SdrIterMode::Flat);

    while (aIter.IsMore())
    {
        SdrObject* pObj = aIter.Next();

        const OUString aObjectName(GetObjectName(pObj));

        if (!aObjectName.isEmpty())
        {
            if (!rEntry)
                return false;

            aName = m_xTreeView->get_text(*rEntry);

            if (aObjectName != aName)
                return false;

            if (pObj->IsGroupObject())
            {
                bool bRet = IsEqualToShapeList(rEntry, *pObj->GetSubList(), aObjectName);
                if (!bRet)
                    return false;
            }
            else
            {
                if (!m_xTreeView->iter_next(*rEntry))
                    rEntry.reset();
            }
        }
    }

    return true;
}

/**
 * Checks if the pages (PageKind::Standard) of a doc and the objects on the pages
 * are identical to the TreeLB.
 * If a doc is provided, this will be the used doc (important by more than
 * one document).
 */

bool SdPageObjsTLV::IsEqualToDoc( const SdDrawDocument* pInDoc )
{
    if( pInDoc )
        m_pDoc = pInDoc;

    if( !m_pDoc )
        return false;

    sd::DrawViewShell* pDrawViewShell = lcl_getDrawViewShell(m_pDoc);
    if (!pDrawViewShell)
        return false;
    PageKind eDrawViewShellPageKind = pDrawViewShell->GetPageKind();
    if (eDrawViewShellPageKind != PageKind::Standard && eDrawViewShellPageKind != PageKind::Notes)
        return false;

    std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
    if (!m_xTreeView->get_iter_first(*xEntry))
        xEntry.reset();

    // compare all pages including the objects
    sal_uInt16 nPage = 0;
    const sal_uInt16 nMaxPages = m_pDoc->GetPageCount();

    while( nPage < nMaxPages )
    {
        const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetPage( nPage ) );
        if (pPage->GetPageKind() == eDrawViewShellPageKind)
        {
            bool bRet = IsEqualToShapeList(xEntry, *pPage, pPage->GetName());
            if (!bRet)
                return false;
        }
        nPage++;
    }
    // If there are still entries in the listbox,
    // then objects (with names) or pages were deleted
    return !xEntry;
}

IMPL_LINK(SdPageObjsTLV, CommandHdl, const CommandEvent&, rCEvt, bool)
{
    if (m_bEditing)
    {
        // Set the editing flag false here because gtk3 in-place editing ends but EditedEntryHdl
        // doesn't get called. This isn't needed for sal in-place editing because EditedEntryHdl
        // gets called when focus is lost.
        m_bEditing = false;
    }

    if (rCEvt.GetCommand() == CommandEventId::ContextMenu)
    {
        m_xTreeView->grab_focus();

        // select clicked entry
        if (std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
                rCEvt.IsMouseEvent() &&  m_xTreeView->get_dest_row_at_pos(
                    rCEvt.GetMousePosPixel(), xEntry.get(), false))
        {
            m_bSelectionHandlerNavigates = true;
            m_bNavigationGrabsFocus = false;
            m_xTreeView->set_cursor(*xEntry);
            Select();
        }

        bool bRet = m_aPopupMenuHdl.Call(rCEvt);
        return bRet;
    }

    return false;
}

IMPL_LINK(SdPageObjsTLV, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
    if (m_bEditing)
        return false;

    const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
    if (m_xAccel->execute(rKeyCode))
    {
        // the accelerator consumed the event
        return true;
    }
    if (rKeyCode.GetCode() == KEY_RETURN)
    {
        std::unique_ptr<weld::TreeIter> xCursor(m_xTreeView->make_iterator());
        if (m_xTreeView->get_cursor(xCursor.get()) && m_xTreeView->iter_has_child(*xCursor))
        {
            if (m_xTreeView->get_row_expanded(*xCursor))
                m_xTreeView->collapse_row(*xCursor);
            else
                m_xTreeView->expand_row(*xCursor);
        }
        m_bNavigationGrabsFocus = true;
        m_aRowActivatedHdl.Call(*m_xTreeView);
        m_bNavigationGrabsFocus = false;
        return true;
    }
    bool bRet = m_aKeyPressHdl.Call(rKEvt);
    return bRet;
}

IMPL_LINK(SdPageObjsTLV, MousePressHdl, const MouseEvent&, rMEvt, bool)
{
    // Don't set m_bEditing false here. Sal in-place editing doesn't like that because the in-place
    // editing mouse presses also end up here.
    if (m_bEditing)
        return false;

    m_bSelectionHandlerNavigates = rMEvt.GetClicks() == 1;
    m_bNavigationGrabsFocus = rMEvt.GetClicks() != 1;
    return false;
}

IMPL_LINK_NOARG(SdPageObjsTLV, MouseReleaseHdl, const MouseEvent&, bool)
{
    if (m_bEditing)
        return false;

    if (m_aMouseReleaseHdl.IsSet() && m_aMouseReleaseHdl.Call(MouseEvent()))
        return false;

    m_bSelectionHandlerNavigates = false;
    m_bNavigationGrabsFocus = true;
    return false;
}

IMPL_LINK(SdPageObjsTLV, DragBeginHdl, bool&, rUnsetDragIcon, bool)
{
    rUnsetDragIcon = false;
    return StartDrag();
}

namespace
{
    bool CanDragSource(const weld::TreeView& rTreeView)
    {
        std::unique_ptr<weld::TreeIter> xSource(rTreeView.make_iterator());
        if (!rTreeView.get_selected(xSource.get()))
            return false;

        std::unique_ptr<weld::TreeIter> xSourceParent(rTreeView.make_iterator(xSource.get()));
        bool bSourceHasParent = rTreeView.iter_parent(*xSourceParent);
        // disallow root drag
        if (!bSourceHasParent)
            return false;

        SdrObject* pSourceObject = weld::fromId<SdrObject*>(rTreeView.get_id(*xSource));
        if (pSourceObject == reinterpret_cast<SdrObject*>(1))
            pSourceObject = nullptr;

        if (!pSourceObject)
            return false;

        SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject();
        if (!pObjectList)
            return false;

        return true;
    }
}

/**
 * StartDrag-Request
 */

bool SdPageObjsTLV::StartDrag()
{
    return !CanDragSource(*m_xTreeView) || DoDrag();
}

/**
 * Begin drag
 */

bool SdPageObjsTLV::DoDrag()
{
    if (!m_pNavigator)
        return true;

    if (!m_xHelper)
        return true;

    // Get the view.
    ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh();
    ::sd::ViewShell* pViewShell = GetViewShellForDocShell(*pDocShell);
    if (pViewShell == nullptr)
    {
        OSL_ASSERT(pViewShell!=nullptr);
        return true;
    }
    sd::View* pView = pViewShell->GetView();
    if (pView == nullptr)
    {
        OSL_ASSERT(pView!=nullptr);
        return true;
    }

    m_xDropTargetHelper->SetDrawView(pViewShell->GetDrawView());
    m_xDropTargetHelper->SetOrderFrontToBack(m_bOrderFrontToBack);

    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    bool bUserData = m_xTreeView->get_cursor(xEntry.get());

    SdrObject* pObject = nullptr;
    sal_Int64 nUserData = bUserData ? m_xTreeView->get_id(*xEntry).toInt64() : 0;
    if (nUserData != 1)
        pObject = reinterpret_cast<SdrObject*>(nUserData);
    if (pObject != nullptr)
    {
        // For shapes without a user supplied name (the automatically
        // created name does not count), a different drag and drop technique
        // is used.
        if (GetObjectName(pObject, false).isEmpty())
        {
            AddShapeToTransferable(*m_xHelper, *pObject);
            m_xHelper->SetView(pView);
            SdModule::get()->pTransferDrag = m_xHelper.get();
        }

        // Unnamed shapes have to be selected to be recognized by the
        // current drop implementation.  In order to have a consistent
        // behaviour for all shapes, every shape that is to be dragged is
        // selected first.
        SdrPageView* pPageView = pView->GetSdrPageView();
        pView->UnmarkAllObj(pPageView);
        pView->MarkObj(pObject, pPageView);
    }
    else
    {
        m_xHelper->SetView(pView);
        SdModule::get()->pTransferDrag = m_xHelper.get();
    }

    return false;
}

SdPageObjsTLVDropTarget::SdPageObjsTLVDropTarget(weld::TreeView& rTreeView)
    : DropTargetHelper(rTreeView.get_drop_target())
    , m_rTreeView(rTreeView)
    , m_pSdrView(nullptr)
{
}

/**
 * AcceptDrop-Event
 */

sal_Int8 SdPageObjsTLVDropTarget::AcceptDrop(const AcceptDropEvent& rEvt)
{
    weld::TreeView* pSource = m_rTreeView.get_drag_source();
    // only dragging within the same widget allowed
    if (!pSource || pSource != &m_rTreeView)
        return DND_ACTION_NONE;

    std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator());
    if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), true))
        return DND_ACTION_NONE;

    // disallow when root is drop target
    if (m_rTreeView.get_iter_depth(*xTarget) == 0)
        return DND_ACTION_NONE;

    // disallow if there is no source entry selected
    std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator());
    if (!m_rTreeView.get_selected(xSource.get()))
        return DND_ACTION_NONE;

    // disallow when root is source
    if (m_rTreeView.get_iter_depth(*xSource) == 0)
        return DND_ACTION_NONE;

    // disallow when the source is the parent or ancestral parent of the target
    std::unique_ptr<weld::TreeIter> xTargetParent(m_rTreeView.make_iterator(xTarget.get()));
    while (m_rTreeView.get_iter_depth(*xTargetParent) > 1)
    {
        if (!m_rTreeView.iter_parent(*xTargetParent) ||
                m_rTreeView.iter_compare(*xSource, *xTargetParent) == 0)
            return DND_ACTION_NONE;
    }

    // disallow drop when source and target are not within the same page
    std::unique_ptr<weld::TreeIter> xSourcePage(m_rTreeView.make_iterator(xSource.get()));
    std::unique_ptr<weld::TreeIter> xTargetPage(m_rTreeView.make_iterator(xTarget.get()));
    while (m_rTreeView.get_iter_depth(*xTargetPage))
        m_rTreeView.iter_parent(*xTargetPage);
    while (m_rTreeView.get_iter_depth(*xSourcePage))
        m_rTreeView.iter_parent(*xSourcePage);
    if (m_rTreeView.iter_compare(*xTargetPage, *xSourcePage) != 0)
        return DND_ACTION_NONE;

    return DND_ACTION_MOVE;
}

/**
 * ExecuteDrop-Event
 */

sal_Int8 SdPageObjsTLVDropTarget::ExecuteDrop( const ExecuteDropEvent& rEvt )
{
    weld::TreeView* pSource = m_rTreeView.get_drag_source();
    // only dragging within the same widget allowed
    if (!pSource || pSource != &m_rTreeView)
        return DND_ACTION_NONE;

    std::unique_ptr<weld::TreeIter> xSource(m_rTreeView.make_iterator());
    if (!m_rTreeView.get_selected(xSource.get()))
        return DND_ACTION_NONE;

    std::unique_ptr<weld::TreeIter> xTarget(m_rTreeView.make_iterator());
    if (!m_rTreeView.get_dest_row_at_pos(rEvt.maPosPixel, xTarget.get(), false))
        return DND_ACTION_NONE;

    auto nIterCompare = m_rTreeView.iter_compare(*xSource, *xTarget);
    if (nIterCompare == 0)
    {
        // drop position is the same as source position
        return DND_ACTION_NONE;
    }

    SdrObject* pTargetObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xTarget));
    SdrObject* pSourceObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xSource));
    if (pSourceObject == reinterpret_cast<SdrObject*>(1))
        pSourceObject = nullptr;
    if (pTargetObject == reinterpret_cast<SdrObject*>(1))
        pTargetObject = nullptr;

    if (pTargetObject != nullptr && pSourceObject != nullptr && m_pSdrView)
    {
        SdrPage* pObjectList = pSourceObject->getSdrPageFromSdrObject();

        std::unique_ptr<weld::TreeIter> xSourceParent(m_rTreeView.make_iterator(xSource.get()));
        m_rTreeView.iter_parent(*xSourceParent);
        std::unique_ptr<weld::TreeIter> xTargetParent(m_rTreeView.make_iterator(xTarget.get()));
        m_rTreeView.iter_parent(*xTargetParent);

        int nTargetPos = m_rTreeView.get_iter_index_in_parent(*xTarget);

        // Make the tree view what the model will be when it is changed below.
        m_rTreeView.move_subtree(*xSource, xTargetParent.get(), nTargetPos);
        m_rTreeView.iter_previous_sibling(*xTarget);
        m_rTreeView.set_cursor(*xTarget);

        // Remove and insert are required for moving objects into and out of groups.
        // PutMarked... by itself would suffice if this wasn't allowed.

        // Remove the source object from source parent list and insert it in the target parent list.
        SdrObject* pSourceParentObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xSourceParent));
        SdrObject* pTargetParentObject = weld::fromId<SdrObject*>(m_rTreeView.get_id(*xTargetParent));

        // Presumably there is need for a hard reference to hold on to the removed object so it is
        // guaranteed to be valid for insert back into an object list.
        rtl::Reference<SdrObject> rSourceObject;

        // remove object
        if (pSourceParentObject == reinterpret_cast<SdrObject*>(1))
        {
            rSourceObject = pObjectList->NbcRemoveObject(pSourceObject->GetOrdNum());
        }
        else
        {
            SdrObjList* pList = pSourceParentObject->GetSubList();
            rSourceObject = pList->NbcRemoveObject(pSourceObject->GetOrdNum());
        }

        // insert object
        if (pTargetParentObject == reinterpret_cast<SdrObject*>(1))
        {
            pObjectList->NbcInsertObject(rSourceObject.get());
        }
        else
        {
            SdrObjList* pList = pTargetParentObject->GetSubList();
            pList->NbcInsertObject(rSourceObject.get());
        }

        m_bOrderFrontToBack ? m_pSdrView->PutMarkedInFrontOfObj(pTargetObject) :
                              m_pSdrView->PutMarkedBehindObj(pTargetObject);
    }

    return DND_ACTION_NONE;
}

void SdPageObjsTLV::AddShapeToTransferable (
    SdTransferable& rTransferable,
    const SdrObject& rObject) const
{
    std::unique_ptr<TransferableObjectDescriptor> pObjectDescriptor(new TransferableObjectDescriptor);
    bool bIsDescriptorFillingPending (true);

    const SdrOle2Obj* pOleObject = dynamic_cast<const SdrOle2Obj*>(&rObject);
    if (pOleObject != nullptr && pOleObject->GetObjRef().is())
    {
        // If object has no persistence it must be copied as part of the document
        try
        {
            uno::Reference< embed::XEmbedPersist > xPersObj (pOleObject->GetObjRef(), uno::UNO_QUERY );
            if (xPersObj.is() && xPersObj->hasEntry())
            {
                SvEmbedTransferHelper::FillTransferableObjectDescriptor(
                    *pObjectDescriptor,
                    pOleObject->GetObjRef(),
                    pOleObject->GetGraphic(),
                    pOleObject->GetAspect());
                bIsDescriptorFillingPending = false;
            }
        }
        catch( uno::Exception& )
        {
        }
    }

    ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh();
    if (bIsDescriptorFillingPending && pDocShell!=nullptr)
    {
        pDocShell->FillTransferableObjectDescriptor(*pObjectDescriptor);
    }

    Point aDragPos (rObject.GetCurrentBoundRect().Center());
    pObjectDescriptor->maDragStartPos = aDragPos;
    if (pDocShell != nullptr)
        pObjectDescriptor->maDisplayName = pDocShell->GetMedium()->GetURLObject().GetURLNoPass();
    else
        pObjectDescriptor->maDisplayName.clear();

    rTransferable.SetStartPos(aDragPos);
    rTransferable.SetObjectDescriptor( std::move(pObjectDescriptor) );
}

::sd::ViewShell* SdPageObjsTLV::GetViewShellForDocShell (::sd::DrawDocShell& rDocShell)
{
    {
        ::sd::ViewShell* pViewShell = rDocShell.GetViewShell();
        if (pViewShell != nullptr)
            return pViewShell;
    }

    try
    {
        // Get a component enumeration from the desktop and search it for documents.
        const uno::Reference<uno::XComponentContext>& xContext( ::comphelper::getProcessComponentContext());

        uno::Reference<frame::XDesktop2> xDesktop = frame::Desktop::create(xContext);

        if ( ! xDesktop.is())
            return nullptr;

        uno::Reference<container::XIndexAccess> xFrameAccess = xDesktop->getFrames();
        if ( ! xFrameAccess.is())
            return nullptr;

        for (sal_Int32 nIndex=0,nCount=xFrameAccess->getCount(); nIndex<nCount; ++nIndex)
        {
            uno::Reference<frame::XFrame> xFrame;
            if ( ! (xFrameAccess->getByIndex(nIndex) >>= xFrame))
                continue;

            auto xController = xFrame->getController();
            ::sd::DrawController* pController = dynamic_cast<sd::DrawController*>(xController.get());
            if (pController == nullptr)
                continue;
            ::sd::ViewShellBase* pBase = pController->GetViewShellBase();
            if (pBase == nullptr)
                continue;
            if (pBase->GetDocShell() != &rDocShell)
                continue;

            const std::shared_ptr<sd::ViewShell> pViewShell (pBase->GetMainViewShell());
            if (pViewShell)
                return pViewShell.get();
        }
    }
    catch (uno::Exception &)
    {
        // When there is an exception then simply use the default value of
        // bIsEnabled and disable the controls.
    }
    return nullptr;
}

SdPageObjsTLV::SdPageObjsTLV(std::unique_ptr<weld::TreeView> xTreeView)
    : m_xTreeView(std::move(xTreeView))
    , m_xScratchIter(m_xTreeView->make_iterator())
    , m_xDropTargetHelper(new SdPageObjsTLVDropTarget(*m_xTreeView))
    , m_xAccel(::svt::AcceleratorExecute::createAcceleratorHelper())
    , m_pNavigator(nullptr)
    , m_pDoc(nullptr)
    , m_pBookmarkDoc(nullptr)
    , m_pMedium(nullptr)
    , m_pOwnMedium(nullptr)
    , m_bLinkableSelected(false)
    , m_bShowAllShapes(false)
    , m_bOrderFrontToBack(false)
    , m_bShowAllPages(false)
    , m_bSelectionHandlerNavigates(false)
    , m_bNavigationGrabsFocus(true)
    , m_eSelectionMode(SelectionMode::Single)
    , m_nSelectEventId(nullptr)
    , m_nRowActivateEventId(nullptr)
{
    m_xTreeView->connect_expanding(LINK(this, SdPageObjsTLV, RequestingChildrenHdl));
    m_xTreeView->connect_selection_changed(LINK(this, SdPageObjsTLV, SelectHdl));
    m_xTreeView->connect_row_activated(LINK(this, SdPageObjsTLV, RowActivatedHdl));
    m_xTreeView->connect_drag_begin(LINK(this, SdPageObjsTLV, DragBeginHdl));
    m_xTreeView->connect_key_press(LINK(this, SdPageObjsTLV, KeyInputHdl));
    m_xTreeView->connect_mouse_press(LINK(this, SdPageObjsTLV, MousePressHdl));
    m_xTreeView->connect_mouse_release(LINK(this, SdPageObjsTLV, MouseReleaseHdl));
    m_xTreeView->connect_editing(LINK(this, SdPageObjsTLV, EditingEntryHdl),
                                 LINK(this, SdPageObjsTLV, EditedEntryHdl));
    m_xTreeView->connect_popup_menu(LINK(this, SdPageObjsTLV, CommandHdl));

    m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 28,
                                  m_xTreeView->get_text_height() * 8);
    m_xTreeView->set_column_editables({true});
}

IMPL_LINK(SdPageObjsTLV, EditEntryAgain, void*, pTreeIter, void)
{
    m_xTreeView->grab_focus();
    std::unique_ptr<weld::TreeIter> xEntry(static_cast<weld::TreeIter*>(pTreeIter));
    m_xTreeView->start_editing(*xEntry);
}

IMPL_LINK_NOARG(SdPageObjsTLV, EditingEntryHdl, const weld::TreeIter&, bool)
{
    m_bEditing = true;
    return true;
}

IMPL_LINK(SdPageObjsTLV, EditedEntryHdl, const IterString&, rIterString, bool)
{
    m_bEditing = false;

    // Did the name change?
    if (m_xTreeView->get_text(rIterString.first) == rIterString.second)
        return true;

    // If the new name is empty or not unique, start editing again.
    if (rIterString.second.isEmpty() || m_pDoc->GetObj(rIterString.second)
        || m_pDoc->IsPageNameUnique(rIterString.second))
    {
        std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator(&rIterString.first));
        Application::PostUserEvent(LINK(this, SdPageObjsTLV, EditEntryAgain), xEntry.release());
        return false;
    }

    // set the new name
    const auto aEntryId = m_xTreeView->get_id(rIterString.first);
    if (aEntryId.toInt64() == 1)
    {
        // page name
        if (::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh())
        {
            if (::sd::ViewShell* pViewShell = GetViewShellForDocShell(*pDocShell))
            {
                SdPage* pPage = pViewShell->GetActualPage();
                pPage->SetName(rIterString.second);
            }
        }
    }
    else if (SdrObject* pCursorEntryObject = weld::fromId<SdrObject*>(aEntryId))
    {
        // object name
        pCursorEntryObject->SetName(rIterString.second);
    }

    return true;
}

IMPL_LINK_NOARG(SdPageObjsTLV, SelectHdl, weld::TreeView&, void)
{
    if (m_nSelectEventId)
        Application::RemoveUserEvent(m_nSelectEventId);
    // post the event to process select event after mouse press event
    m_nSelectEventId = Application::PostUserEvent(LINK(this, SdPageObjsTLV, AsyncSelectHdl));
}

IMPL_LINK_NOARG(SdPageObjsTLV, RowActivatedHdl, weld::TreeView&, bool)
{
    if (m_nRowActivateEventId)
        Application::RemoveUserEvent(m_nRowActivateEventId);
    // post the event to process row activate after mouse press event
    m_nRowActivateEventId = Application::PostUserEvent(LINK(this, SdPageObjsTLV, AsyncRowActivatedHdl));
    return false;
}

IMPL_LINK_NOARG(SdPageObjsTLV, AsyncSelectHdl, void*, void)
{
    Select();
}

void SdPageObjsTLV::Select()
{
    m_nSelectEventId = nullptr;

    if (m_bEditing)
        return;

    m_bLinkableSelected = true;

    m_xTreeView->selected_foreach([this](weld::TreeIter& rEntry){
        if (m_xTreeView->get_id(rEntry).toInt64() == 0)
            m_bLinkableSelected = false;
        return false;
    });

    m_aChangeHdl.Call(*m_xTreeView);

    if (m_bSelectionHandlerNavigates)
        m_aRowActivatedHdl.Call(*m_xTreeView);

    if (!m_pNavigator)
    {
        m_xHelper.clear();
        return;
    }

    ::sd::DrawDocShell* pDocShell = m_pDoc->GetDocSh();
    OUString aURL = INetURLObject(pDocShell->GetMedium()->GetPhysicalName(), INetProtocol::File).GetMainURL(INetURLObject::DecodeMechanism::NONE);
    NavigatorDragType eDragType = m_pNavigator->GetNavigatorDragType();

    OUString sSelectedEntry = get_cursor_text(); // what about multiple selections?
    aURL += "#" + sSelectedEntry;

    INetBookmark aBookmark(aURL, sSelectedEntry);
    sal_Int8 nDNDActions = DND_ACTION_COPYMOVE;

    if( eDragType == NAVIGATOR_DRAGTYPE_LINK )
        nDNDActions = DND_ACTION_LINK;  // Either COPY *or* LINK, never both!
    else if (m_pDoc->GetSdPageCount(PageKind::Standard) == 1)
    {
        // Can not move away the last slide in a document.
        nDNDActions = DND_ACTION_COPY;
    }

    // object is destroyed by internal reference mechanism
    m_xHelper.set(new SdPageObjsTLV::SdPageObjsTransferable(std::move(aBookmark), *pDocShell, eDragType));
    rtl::Reference<TransferDataContainer> xHelper(m_xHelper);
    m_xTreeView->enable_drag_source(xHelper, nDNDActions);
}

IMPL_LINK_NOARG(SdPageObjsTLV, AsyncRowActivatedHdl, void*, void)
{
    m_nRowActivateEventId = nullptr;
    m_aRowActivatedHdl.Call(*m_xTreeView);
}

OUString SdPageObjsTLV::GetObjectName(
    const SdrObject* pObject,
    const bool bCreate) const
{
    OUString aRet;

    if ( pObject )
    {
        aRet = pObject->GetName();

        if (aRet.isEmpty())
            if (auto pOleObj = dynamic_cast<const SdrOle2Obj* >(pObject))
                aRet = pOleObj->GetPersistName();
    }

    if (bCreate
        && m_bShowAllShapes
        && aRet.isEmpty()
        && pObject!=nullptr)
    {
        OUString sObjName;
        if (pObject->GetObjIdentifier() == SdrObjKind::CustomShape)
        {
            // taken from SdrObjCustomShape::GetCustomShapeName
            OUString aEngine(pObject->GetMergedItem(SDRATTR_CUSTOMSHAPE_ENGINE).GetValue());
            if (aEngine.isEmpty() || aEngine == "com.sun.star.drawing.EnhancedCustomShapeEngine")
            {
                OUString sShapeType;
                const SdrCustomShapeGeometryItem& rGeometryItem
                    = pObject->GetMergedItem(SDRATTR_CUSTOMSHAPE_GEOMETRY);
                const uno::Any* pAny = rGeometryItem.GetPropertyValueByName(u"Type"_ustr);
                if (pAny && (*pAny >>= sShapeType))
                    sObjName = SdResId(STR_NAVIGATOR_CUSTOMSHAPE) + u": " + sShapeType;
            }
        }
        else
            sObjName = pObject->TakeObjNameSingul();

        aRet = SdResId(STR_NAVIGATOR_SHAPE_BASE_NAME) + " (" + sObjName +")";
        aRet = aRet.replaceFirst("%1", OUString::number(pObject->GetOrdNum() + 1));
    }

    return aRet;
}

std::vector<OUString> SdPageObjsTLV::GetSelectEntryList(const int nDepth) const
{
    std::vector<OUString> aEntries;

    m_xTreeView->selected_foreach([this, nDepth, &aEntries](weld::TreeIter& rEntry){
        int nListDepth = m_xTreeView->get_iter_depth(rEntry);
        if (nListDepth == nDepth)
            aEntries.push_back(m_xTreeView->get_text(rEntry));
        return false;
    });

    return aEntries;
}

std::vector<OUString> SdPageObjsTLV::GetSelectedEntryIds() const
{
    std::vector<OUString> vEntryIds;

    m_xTreeView->selected_foreach([this, &vEntryIds](weld::TreeIter& rEntry){
        vEntryIds.push_back(m_xTreeView->get_id(rEntry));
        return false;
    });

    return vEntryIds;
}

/**
 * Checks if it is a draw file and opens the BookmarkDoc depending of
 * the provided Docs
 */

SdDrawDocument* SdPageObjsTLV::GetBookmarkDoc(SfxMedium* pMed)
{
    if (
       !m_pBookmarkDoc ||
         (pMed && (!m_pOwnMedium || m_pOwnMedium->GetName() != pMed->GetName()))
      )
    {
        // create a new BookmarkDoc if now one exists or if a new Medium is provided
        if (m_pOwnMedium != pMed)
        {
            CloseBookmarkDoc();
        }

        if (pMed)
        {
            // it looks that it is undefined if a Medium was set by Fill() already
            DBG_ASSERT( !m_pMedium, "SfxMedium confusion!" );
            delete m_pMedium;
            m_pMedium = nullptr;

            // take over this Medium (currently used only be Navigator)
            m_pOwnMedium = pMed;
        }

        DBG_ASSERT( m_pMedium || pMed, "No SfxMedium provided!" );

        if( pMed )
        {
            // in this mode the document is also owned and controlled by this instance
            m_xBookmarkDocShRef = new ::sd::DrawDocShell(SfxObjectCreateMode::STANDARD, true, DocumentType::Impress);
            if (m_xBookmarkDocShRef->DoLoad(pMed))
                m_pBookmarkDoc = m_xBookmarkDocShRef->GetDoc();
            else
                m_pBookmarkDoc = nullptr;
        }
        else if ( m_pMedium )
            // in this mode the document is owned and controlled by the SdDrawDocument
            // it can be released by calling the corresponding CloseBookmarkDoc method
            // successful creation of a document makes this the owner of the medium
            m_pBookmarkDoc = const_cast<SdDrawDocument*>(m_pDoc)->OpenBookmarkDoc(m_pMedium);

        if ( !m_pBookmarkDoc )
        {
            std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_xTreeView.get(),
                                                           VclMessageType::Warning, VclButtonsType::Ok, SdResId(STR_READ_DATA_ERROR)));
            xErrorBox->run();
            m_pMedium = nullptr; //On failure the SfxMedium is invalid
        }
    }

    return m_pBookmarkDoc;
}

/**
 * Entries are inserted only by request (double click)
 */

IMPL_LINK(SdPageObjsTLV, RequestingChildrenHdl, const weld::TreeIter&, rFileEntrybool)
{
    if (!m_xTreeView->iter_has_child(rFileEntry))
    {
        if (GetBookmarkDoc())
        {
            SdrObject*   pObj = nullptr;

            OUString sImgPage(BMP_PAGE);
            OUString sImgPageObjs(BMP_PAGEOBJS);
            OUString sImgObjects(BMP_OBJECTS);
            OUString sImgOle(BMP_OLE);
            OUString sImgGraphic(BMP_GRAPHIC);

            // document name already inserted

            // only insert all "normal" ? slides with objects
            sal_uInt16 nPage = 0;
            const sal_uInt16 nMaxPages = m_pBookmarkDoc->GetPageCount();

            std::unique_ptr<weld::TreeIter> xPageEntry;
            while (nPage < nMaxPages)
            {
                SdPage* pPage = static_cast<SdPage*>(m_pBookmarkDoc->GetPage(nPage));
                if (pPage->GetPageKind() == PageKind::Standard)
                {
                    OUString sId(OUString::number(1));
                    m_xTreeView->insert(&rFileEntry, -1, &pPage->GetName(), &sId,
                                        nullptr, nullptr, false, m_xScratchIter.get());
                    m_xTreeView->set_image(*m_xScratchIter, sImgPage);

                    if (!xPageEntry)
                    {
                        xPageEntry = m_xTreeView->make_iterator(&rFileEntry);
                        (void)m_xTreeView->iter_children(*xPageEntry);
                    }
                    else
                        (void)m_xTreeView->iter_next_sibling(*xPageEntry);

                    SdrObjListIter aIter( pPage, SdrIterMode::DeepWithGroups );

                    while( aIter.IsMore() )
                    {
                        pObj = aIter.Next();
                        OUString aStr( GetObjectName( pObj ) );
                        if( !aStr.isEmpty() )
                        {
                            if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::OLE2 )
                            {
                                m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
                                                    nullptr, nullptr, false, m_xScratchIter.get());
                                m_xTreeView->set_image(*m_xScratchIter, sImgOle);
                            }
                            else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Graphic )
                            {
                                m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
                                                    nullptr, nullptr, false, m_xScratchIter.get());
                                m_xTreeView->set_image(*m_xScratchIter, sImgGraphic);
                            }
                            else
                            {
                                m_xTreeView->insert(xPageEntry.get(), -1, &aStr, nullptr,
                                                    nullptr, nullptr, false, m_xScratchIter.get());
                                m_xTreeView->set_image(*m_xScratchIter, sImgObjects);
                            }
                        }
                    }
                    if (m_xTreeView->iter_has_child(*xPageEntry))
                    {
                        m_xTreeView->set_image(*xPageEntry, sImgPageObjs);
                    }
                }
                nPage++;
            }
        }
    }
    return true;
}

void SdPageObjsTLV::SetSdNavigator(SdNavigatorWin* pNavigator)
{
    m_pNavigator = pNavigator;
}

void SdPageObjsTLV::SetViewFrame(const SfxViewFrame* pViewFrame)
{
    if (sd::ViewShellBase* pBase = sd::ViewShellBase::GetViewShellBase(pViewFrame))
    {
        css::uno::Reference< css::frame::XFrame > xFrame;
        if (std::shared_ptr<sd::ViewShell> xViewShell = pBase->GetMainViewShell())
        {
            if (SfxViewFrame* pFrame = xViewShell->GetViewFrame())
                xFrame = pFrame->GetFrame().GetFrameInterface();
        }
        m_xAccel->init(::comphelper::getProcessComponentContext(), xFrame);
    }
}

/**
 * Close and delete bookmark document
 */

void SdPageObjsTLV::CloseBookmarkDoc()
{
    if (m_xBookmarkDocShRef.is())
    {
        m_xBookmarkDocShRef->DoClose();
        m_xBookmarkDocShRef.clear();

        // Medium is owned by document, so it's destroyed already
        m_pOwnMedium = nullptr;
    }
    else if (m_pBookmarkDoc)
    {
        DBG_ASSERT(!m_pOwnMedium, "SfxMedium confusion!");
        if (m_pDoc)
        {
            // The document owns the Medium, so the Medium will be invalid after closing the document
            const_cast<SdDrawDocument*>(m_pDoc)->CloseBookmarkDoc();
            m_pMedium = nullptr;
        }
    }
    else
    {
        // perhaps mpOwnMedium provided, but no successful creation of BookmarkDoc
        delete m_pOwnMedium;
        m_pOwnMedium = nullptr;
    }

    m_pBookmarkDoc = nullptr;
}

bool SdPageObjsTLV::PageBelongsToCurrentShow(const SdPage* pPage) const
{
    // Return <TRUE/> as default when there is no custom show or when none
    // is used.  The page does then belong to the standard show.
    bool bBelongsToShow = true;

    if (m_pDoc->getPresentationSettings().mbCustomShow)
    {
        // Get the current custom show.
        SdCustomShow* pCustomShow = nullptr;
        SdCustomShowList* pShowList = const_cast<SdDrawDocument*>(m_pDoc)->GetCustomShowList();
        if (pShowList != nullptr)
        {
            sal_uLong nCurrentShowIndex = pShowList->GetCurPos();
            pCustomShow = (*pShowList)[nCurrentShowIndex].get();
        }

        // Check whether the given page is part of that custom show.
        if (pCustomShow != nullptr)
        {
            bBelongsToShow = false;
            size_t nPageCount = pCustomShow->PagesVector().size();
            for (size_t i=0; i<nPageCount && !bBelongsToShow; i++)
                if (pPage == pCustomShow->PagesVector()[i])
                    bBelongsToShow = true;
        }
    }

    return bBelongsToShow;
}

void SdPageObjsTLV::AddShapeList (
    const SdrObjList& rList,
    const SdrObject* pShape,
    const OUString& rsName,
    const bool bIsExcluded,
    const weld::TreeIter* pParentEntry)
{
    OUString aIcon(BMP_PAGE);
    if (bIsExcluded)
        aIcon = BMP_PAGE_EXCLUDED;
    else if (pShape != nullptr)
        aIcon = BMP_GROUP;

    OUString aUserData(u"1"_ustr);
    if (pShape != nullptr)
        aUserData = weld::toId(pShape);

    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    InsertEntry(pParentEntry, aUserData, rsName, aIcon, xEntry.get());

    SdrObjListIter aIter(
        &rList,
        !rList.HasObjectNavigationOrder() /* use navigation order, if available */,
        SdrIterMode::Flat);

    while( aIter.IsMore() )
    {
        SdrObject* pObj = aIter.Next();
        assert(pObj!=nullptr);

        // Get the shape name.
        OUString aStr (GetObjectName( pObj ) );
        OUString sId(weld::toId(pObj));

        if( !aStr.isEmpty() )
        {
            if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::OLE2 )
            {
                InsertEntry(xEntry.get(), sId, aStr, BMP_OLE);
            }
            else if( pObj->GetObjInventor() == SdrInventor::Default && pObj->GetObjIdentifier() == SdrObjKind::Graphic )
            {
                InsertEntry(xEntry.get(), sId, aStr, BMP_GRAPHIC);
            }
            else if (pObj->IsGroupObject())
            {
                AddShapeList(
                    *pObj->GetSubList(),
                    pObj,
                    aStr,
                    false,
                    xEntry.get());
            }
            else
            {
                InsertEntry(xEntry.get(), sId, aStr, BMP_OBJECTS); // BMP_OBJECTS
            }
        }
    }

    if (!m_xTreeView->iter_has_child(*xEntry))
        return;

    if (bIsExcluded)
        m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS_EXCLUDED);
    else
        m_xTreeView->set_image(*xEntry, BMP_PAGEOBJS);
    m_xTreeView->expand_row(*xEntry);
}

/**
 * Fill TreeLB with pages and objects
 */

void SdPageObjsTLV::Fill(const SdDrawDocument* pInDoc, bool bAllPages, const OUString&&nbsp;rDocName)
{
    OUString aSelection = m_xTreeView->get_selected_text();
    clear();

    m_pDoc = pInDoc;
    m_aDocName = rDocName;
    m_bShowAllPages = bAllPages;
    m_pMedium = nullptr;

    // first insert all pages including objects
    sal_uInt16 nPage = 0;
    const sal_uInt16 nMaxPages = m_pDoc->GetPageCount();

    PageKind eDrawViewShellPageKind = PageKind::Standard;
    if (sd::DrawViewShell* pDrawViewShell = lcl_getDrawViewShell(m_pDoc))
        eDrawViewShellPageKind = pDrawViewShell->GetPageKind();

    while( nPage < nMaxPages )
    {
        const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetPage( nPage ) );
        PageKind ePagePageKind = pPage->GetPageKind();
        if ((m_bShowAllPages ||
             (ePagePageKind == PageKind::Standard &&
              eDrawViewShellPageKind == PageKind::Standard) ||
             (ePagePageKind == PageKind::Notes &&
              eDrawViewShellPageKind == PageKind::Notes)) &&
                ePagePageKind != PageKind::Handout) //#94954# never list the normal handout page ( handout-masterpage is used instead )
        {
            bool bPageExcluded = pPage->IsExcluded();

            bool bPageBelongsToShow = PageBelongsToCurrentShow (pPage);
            bPageExcluded |= !bPageBelongsToShow;

            AddShapeList(*pPage, nullptr, pPage->GetName(), bPageExcluded, nullptr);
        }
        nPage++;
    }

    // then insert all master pages including objects
    if( m_bShowAllPages )
    {
        nPage = 0;
        const sal_uInt16 nMaxMasterPages = m_pDoc->GetMasterPageCount();

        while( nPage < nMaxMasterPages )
        {
            const SdPage* pPage = static_cast<const SdPage*>( m_pDoc->GetMasterPage( nPage ) );
            AddShapeList(*pPage, nullptr, pPage->GetName(), false, nullptr);
            nPage++;
        }
    }
    if (!aSelection.isEmpty())
    {
        m_xTreeView->all_foreach([this, &aSelection](weld::TreeIter& rEntry){
            if (m_xTreeView->get_text(rEntry) == aSelection)
            {
                m_xTreeView->select(rEntry);
                return true;
            }
            return false;
        });
    }
}

/**
 * We insert only the first entry. Children are created on demand.
 */

void SdPageObjsTLV::Fill( const SdDrawDocument* pInDoc, SfxMedium* pInMedium,
                          const OUString& rDocName )
{
    m_pDoc = pInDoc;

    // this object now owns the Medium
    m_pMedium = pInMedium;
    m_aDocName = rDocName;

    OUString sId(OUString::number(1));
    // insert document name
    m_xTreeView->insert(nullptr, -1, &m_aDocName, &sId, nullptr, nullptr, true, m_xScratchIter.get());
    m_xTreeView->set_image(*m_xScratchIter, BMP_DOC_OPEN);
}

/**
 * select an entry in TreeLB
 */

bool SdPageObjsTLV::SelectEntry( std::u16string_view rName )
{
    bool bFound = false;

    if (!rName.empty())
    {
        std::unique_ptr<weld::TreeIter> xEntry(m_xTreeView->make_iterator());
        OUString aTmp;

        if (m_xTreeView->get_iter_first(*xEntry))
        {
            do
            {
                aTmp = m_xTreeView->get_text(*xEntry);
                if (aTmp == rName)
                {
                    m_xTreeView->set_cursor(*xEntry);
                    m_xTreeView->select(*xEntry);
                    bFound = true;
                    break;
                }
            }
            while (m_xTreeView->iter_next(*xEntry));
        }
    }

    return bFound;
}

void SdPageObjsTLV::SelectEntry(const SdrObject *pObj)
{
    if (pObj)
    {
        m_xTreeView->all_foreach([this, &pObj](weld::TreeIter& rEntry){
            if (weld::fromId<SdrObject*>(m_xTreeView->get_id(rEntry)) == pObj)
            {
                // Only scroll to the row of the first selected. And only when the treeview
                // doesn't have the focus.
                if (!m_xTreeView->has_focus() && m_xTreeView->get_selected_rows().empty())
                    m_xTreeView->set_cursor(rEntry);
                m_xTreeView->select(rEntry);
                return true;
            }
            return false;
        });
    }
}

SdPageObjsTLV::~SdPageObjsTLV()
{
    if (m_nSelectEventId)
        Application::RemoveUserEvent(m_nSelectEventId);
    if (m_nRowActivateEventId)
        Application::RemoveUserEvent(m_nRowActivateEventId);

    if (m_pBookmarkDoc)
        CloseBookmarkDoc();
    else
    {
        // no document was created from m_pMedium, so this object is still the owner of it
        delete m_pMedium;
    }
    m_xAccel.reset();
}

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

Messung V0.5
C=90 H=98 G=94

¤ Dauer der Verarbeitung: 0.5 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.