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

Quelle  Navigator.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 <Navigator.hxx>

#include <strings.hxx>
#include <bitmaps.hlst>
#include <ReportController.hxx>
#include <UITools.hxx>
#include <reportformula.hxx>
#include <com/sun/star/report/XFixedText.hpp>
#include <com/sun/star/report/XFixedLine.hpp>
#include <com/sun/star/report/XFormattedField.hpp>
#include <com/sun/star/report/XImageControl.hpp>
#include <com/sun/star/report/XShape.hpp>
#include <helpids.h>
#include <strings.hrc>
#include <rptui_slotid.hrc>
#include <comphelper/propmultiplex.hxx>
#include <comphelper/propertyvalue.hxx>
#include <comphelper/containermultiplexer.hxx>
#include <cppuhelper/basemutex.hxx>
#include <comphelper/SelectionMultiplex.hxx>
#include <utility>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/commandevent.hxx>
#include <ReportVisitor.hxx>
#include <core_resource.hxx>
#include <rtl/ref.hxx>
#include <svx/svxids.hrc>

#include <memory>
#include <string_view>

namespace rptui
{
using namespace ::com::sun::star;
using namespace ::comphelper;

static OUString lcl_getImageId(const uno::Reference< report::XReportComponent>& _xElement)
{
    OUString sId;
    uno::Reference< report::XFixedLine> xFixedLine(_xElement,uno::UNO_QUERY);
    if ( uno::Reference< report::XFixedText>(_xElement,uno::UNO_QUERY).is() )
        sId = RID_SVXBMP_FM_FIXEDTEXT;
    else if ( xFixedLine.is() )
        sId = xFixedLine->getOrientation() ? RID_SVXBMP_INSERT_VFIXEDLINE : RID_SVXBMP_INSERT_HFIXEDLINE;
    else if ( uno::Reference< report::XFormattedField>(_xElement,uno::UNO_QUERY).is() )
        sId = RID_SVXBMP_FM_EDIT;
    else if ( uno::Reference< report::XImageControl>(_xElement,uno::UNO_QUERY).is() )
        sId = RID_SVXBMP_FM_IMAGECONTROL;
    else if ( uno::Reference< report::XShape>(_xElement,uno::UNO_QUERY).is() )
        sId = RID_SVXBMP_DRAWTBX_CS_BASIC;
    return sId;
}

static OUString lcl_getName(const uno::Reference< beans::XPropertySet>& _xElement)
{
    OSL_ENSURE(_xElement.is(),"Found report element which is NULL!");
    OUString sTempName;
    _xElement->getPropertyValue(PROPERTY_NAME) >>= sTempName;
    OUStringBuffer sName(sTempName);
    uno::Reference< report::XFixedText> xFixedText(_xElement,uno::UNO_QUERY);
    uno::Reference< report::XReportControlModel> xReportModel(_xElement,uno::UNO_QUERY);
    if ( xFixedText.is() )
    {
        sName.append(" : " + xFixedText->getLabel());
    }
    else if ( xReportModel.is() && _xElement->getPropertySetInfo()->hasPropertyByName(PROPERTY_DATAFIELD) )
    {
        ReportFormula aFormula( xReportModel->getDataField() );
        if ( aFormula.isValid() )
        {
            sName.append(" : " + aFormula.getUndecoratedContent() );
        }
    }
    return sName.makeStringAndClear();
}

class NavigatorTree : public ::cppu::BaseMutex
                    , public reportdesign::ITraverseReport
                    , public comphelper::OSelectionChangeListener
                    , public ::comphelper::OPropertyChangeListener
{
    class UserData;
    friend class UserData;
    class UserData : public ::cppu::BaseMutex
                    ,public ::comphelper::OPropertyChangeListener
                    ,public ::comphelper::OContainerListener
    {
        uno::Reference< uno::XInterface >                           m_xContent;
        ::rtl::Reference< comphelper::OPropertyChangeMultiplexer>   m_pListener;
        ::rtl::Reference< comphelper::OContainerListenerAdapter>    m_pContainerListener;
        NavigatorTree*                                              m_pTree;
    public:
        UserData(NavigatorTree* pTree, uno::Reference<uno::XInterface> xContent);
        virtual ~UserData() override;

        const uno::Reference< uno::XInterface >& getContent() const { return m_xContent; }
        void setContent(const uno::Reference< uno::XInterface >& _xContent) { m_xContent = _xContent; }

    protected:
        // OPropertyChangeListener
        virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;

        // OContainerListener
        virtual void _elementInserted( const container::ContainerEvent& _rEvent ) override;
        virtual void _elementRemoved( const container::ContainerEvent& Event ) override;
        virtual void _elementReplaced( const container::ContainerEvent& _rEvent ) override;
        virtual void _disposing(const lang::EventObject& _rSource) override;
    };

    std::unique_ptr<weld::TreeView>                                             m_xTreeView;
    OReportController&                                                          m_rController;
    std::unique_ptr<weld::TreeIter>                                             m_xMasterReport;
    ::rtl::Reference< comphelper::OPropertyChangeMultiplexer>                   m_pReportListener;
    ::rtl::Reference< comphelper::OSelectionChangeMultiplexer>                  m_pSelectionListener;

    void insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition, const UserData* pData, weld::TreeIter& rRet);

    void traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition = -1);
    void traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent);

protected:
    // OSelectionChangeListener
    virtual void _disposing(const lang::EventObject& _rSource) override;

    // OPropertyChangeListener
    virtual void _propertyChanged(const beans::PropertyChangeEvent& _rEvent) override;

    // OContainerListener Helper
    void _elementInserted( const container::ContainerEvent& _rEvent );
    void _elementRemoved( const container::ContainerEvent& Event );
    void _elementReplaced( const container::ContainerEvent& _rEvent );

public:
    NavigatorTree(std::unique_ptr<weld::TreeView>, OReportController& rController);
    virtual ~NavigatorTree() override;

    DECL_LINK(OnEntrySelDesel, weld::TreeView&, void);
    DECL_LINK(CommandHdl, const CommandEvent&, bool);

    virtual void _selectionChanged( const lang::EventObject& aEvent ) override;

    // ITraverseReport
    virtual void traverseReport(const uno::Reference< report::XReportDefinition>& xReport) override;
    virtual void traverseReportFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
    virtual void traverseReportHeader(const uno::Reference< report::XSection>& xSection) override;
    virtual void traverseReportFooter(const uno::Reference< report::XSection>& xSection) override;
    virtual void traversePageHeader(const uno::Reference< report::XSection>& xSection) override;
    virtual void traversePageFooter(const uno::Reference< report::XSection>& xSection) override;

    virtual void traverseGroups(const uno::Reference< report::XGroups>& xGroups) override;
    virtual void traverseGroup(const uno::Reference< report::XGroup>& xGroup) override;
    virtual void traverseGroupFunctions(const uno::Reference< report::XFunctions>& xFunctions) override;
    virtual void traverseGroupHeader(const uno::Reference< report::XSection>& xSection) override;
    virtual void traverseGroupFooter(const uno::Reference< report::XSection>& xSection) override;

    virtual void traverseDetail(const uno::Reference< report::XSection>& xSection) override;

    bool find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rIter);
    void removeEntry(const weld::TreeIter& rEntry, bool bRemove = true);

    void grab_focus() { m_xTreeView->grab_focus(); }

    void set_text(const weld::TreeIter& rIter, const OUString& rStr)
    {
        m_xTreeView->set_text(rIter, rStr);
    }

    void expand_row(const weld::TreeIter& rIter)
    {
        m_xTreeView->expand_row(rIter);
    }

    std::unique_ptr<weld::TreeIter> make_iterator() const
    {
        return m_xTreeView->make_iterator();
    }

    int iter_n_children(const weld::TreeIter& rIter) const
    {
        return m_xTreeView->iter_n_children(rIter);
    }
};

NavigatorTree::NavigatorTree(std::unique_ptr<weld::TreeView> xTreeView, OReportController& rController)
    : OPropertyChangeListener()
    , m_xTreeView(std::move(xTreeView))
    , m_rController(rController)
{
    m_xTreeView->set_size_request(m_xTreeView->get_approximate_digit_width() * 25, m_xTreeView->get_height_rows(18));

    m_pReportListener = new OPropertyChangeMultiplexer(this,m_rController.getReportDefinition());
    m_pReportListener->addProperty(PROPERTY_PAGEHEADERON);
    m_pReportListener->addProperty(PROPERTY_PAGEFOOTERON);
    m_pReportListener->addProperty(PROPERTY_REPORTHEADERON);
    m_pReportListener->addProperty(PROPERTY_REPORTFOOTERON);

    m_pSelectionListener = new OSelectionChangeMultiplexer(this,&m_rController);

    m_xTreeView->set_help_id(HID_REPORT_NAVIGATOR_TREE);

    m_xTreeView->set_selection_mode(SelectionMode::Multiple);

    m_xTreeView->connect_selection_changed(LINK(this, NavigatorTree, OnEntrySelDesel));
    m_xTreeView->connect_popup_menu(LINK(this, NavigatorTree, CommandHdl));
}

NavigatorTree::~NavigatorTree()
{
    m_xTreeView->all_foreach([this](weld::TreeIter& rIter) {
        UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
        delete pData;
        return false;
    });
    m_pSelectionListener->dispose();
    m_pReportListener->dispose();
}

namespace
{
    sal_uInt16 mapIdent(std::u16string_view rIdent)
    {
        if (rIdent == u"sorting")
            return SID_SORTINGANDGROUPING;
        else if (rIdent == u"page")
            return SID_PAGEHEADERFOOTER;
        else if (rIdent == u"report")
            return SID_REPORTHEADERFOOTER;
        else if (rIdent == u"function")
            return SID_RPT_NEW_FUNCTION;
        else if (rIdent == u"properties")
            return SID_SHOW_PROPERTYBROWSER;
        else if (rIdent == u"delete")
            return SID_DELETE;
        return 0;
    }
}

IMPL_LINK(NavigatorTree, CommandHdl, const CommandEvent&, rEvt, bool)
{
    bool bHandled = false;
    switch( rEvt.GetCommand())
    {
    case CommandEventId::ContextMenu:
        {
            UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_selected_id());
            if (!pData)
                break;

            uno::Reference< report::XFunctionsSupplier> xSupplier(pData->getContent(),uno::UNO_QUERY);
            uno::Reference< report::XFunctions> xFunctions(pData->getContent(),uno::UNO_QUERY);
            uno::Reference< report::XGroup> xGroup(pData->getContent(),uno::UNO_QUERY);
            bool bDeleteAllowed = m_rController.isEditable() && (xGroup.is() ||
                                      uno::Reference< report::XFunction>(pData->getContent(),uno::UNO_QUERY).is());

            std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(m_xTreeView.get(), u"modules/dbreport/ui/navigatormenu.ui"_ustr));
            std::unique_ptr<weld::Menu> xContextMenu(xBuilder->weld_menu(u"menu"_ustr));

            const OUString aIds[] = { u"sorting"_ustr, u"page"_ustr, u"report"_ustr, u"function"_ustr, u"properties"_ustr, u"delete"_ustr };
            for (size_t i = 0; i < SAL_N_ELEMENTS(aIds); ++i)
            {
                sal_uInt16 nSId = mapIdent(aIds[i]);

                if (aIds[i] == "page" || aIds[i] == "report" || aIds[i] == "properties")
                    xContextMenu->set_active(aIds[i], m_rController.isCommandChecked(nSId));
                bool bEnabled = m_rController.isCommandEnabled(nSId);
                if (nSId == SID_RPT_NEW_FUNCTION)
                    xContextMenu->set_sensitive(aIds[i], m_rController.isEditable() && (xSupplier.is() || xFunctions.is()));
                // special condition, check for function and group
                else if (nSId == SID_DELETE)
                    xContextMenu->set_sensitive(aIds[i], bDeleteAllowed);
                else
                    xContextMenu->set_sensitive(aIds[i], bEnabled);
            }

            // the point that was clicked on
            ::Point aWhere(rEvt.GetMousePosPixel());
            OUString sCurItemIdent = xContextMenu->popup_at_rect(m_xTreeView.get(), tools::Rectangle(aWhere, Size(1,1)));
            if (!sCurItemIdent.isEmpty())
            {
                sal_uInt16 nId = mapIdent(sCurItemIdent);
                uno::Sequence< beans::PropertyValue> aArgs;
                if ( nId == SID_RPT_NEW_FUNCTION )
                {
                    aArgs.realloc(1);
                    aArgs.getArray()[0].Value <<= (xFunctions.is() ? xFunctions : xSupplier->getFunctions());
                }
                else if ( nId == SID_DELETE )
                {
                    if ( xGroup.is() )
                        nId = SID_GROUP_REMOVE;
                    aArgs = { comphelper::makePropertyValue(PROPERTY_GROUP, pData->getContent()) };
                }
                m_rController.executeUnChecked(nId,aArgs);
            }

            bHandled = true;
        }
        break;
        defaultbreak;
    }

    return bHandled;
}

IMPL_LINK_NOARG(NavigatorTree, OnEntrySelDesel, weld::TreeView&, void)
{
    if ( !m_pSelectionListener->locked() )
    {
        m_pSelectionListener->lock();
        std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
        bool bEntry = m_xTreeView->get_cursor(xEntry.get());
        uno::Any aSelection;
        if (bEntry && m_xTreeView->is_selected(*xEntry))
            aSelection <<= weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry))->getContent();
        m_rController.select(aSelection);
        m_pSelectionListener->unlock();
    }
}

void NavigatorTree::_selectionChanged( const lang::EventObject& aEvent )
{
    m_pSelectionListener->lock();
    uno::Reference< view::XSelectionSupplier> xSelectionSupplier(aEvent.Source,uno::UNO_QUERY);
    uno::Any aSec = xSelectionSupplier->getSelection();
    uno::Sequence< uno::Reference< report::XReportComponent > > aSelection;
    aSec >>= aSelection;
    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    if ( !aSelection.hasElements() )
    {
        uno::Reference< uno::XInterface> xSelection(aSec,uno::UNO_QUERY);
        bool bEntry = find(xSelection, *xEntry);
        if (bEntry && !m_xTreeView->is_selected(*xEntry))
        {
            m_xTreeView->select(*xEntry);
            m_xTreeView->set_cursor(*xEntry);
        }
        else if (!bEntry)
            m_xTreeView->unselect_all();
    }
    else
    {
        for (const uno::Reference<report::XReportComponent>& rElem : aSelection)
        {
            bool bEntry = find(rElem, *xEntry);
            if (bEntry && !m_xTreeView->is_selected(*xEntry))
            {
                m_xTreeView->select(*xEntry);
                m_xTreeView->set_cursor(*xEntry);
            }
        }
    }
    m_pSelectionListener->unlock();
}

void NavigatorTree::insertEntry(const OUString& rName, const weld::TreeIter* pParent, const OUString& rImageId,
                                int nPosition, const UserData* pData, weld::TreeIter& rRet)
{
    OUString sId = pData ? weld::toId(pData) : OUString();
    m_xTreeView->insert(pParent, nPosition, &rName, &sId, nullptr, nullptr, false, &rRet);
    if (!rImageId.isEmpty())
        m_xTreeView->set_image(rRet, rImageId);
}

void NavigatorTree::traverseSection(const uno::Reference<report::XSection>& xSection, const weld::TreeIter* pParent, const OUString& rImageId, int nPosition)
{
    std::unique_ptr<weld::TreeIter> xSectionIter = m_xTreeView->make_iterator();
    std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
    insertEntry(xSection->getName(), pParent, rImageId, nPosition, new UserData(this, xSection), *xSectionIter);
    const sal_Int32 nCount = xSection->getCount();
    for (sal_Int32 i = 0; i < nCount; ++i)
    {
        uno::Reference< report::XReportComponent> xElement(xSection->getByIndex(i), uno::UNO_QUERY_THROW);
        insertEntry(lcl_getName(xElement), xSectionIter.get(), lcl_getImageId(xElement), -1new UserData(this, xElement), *xScratch);
        uno::Reference< report::XReportDefinition> xSubReport(xElement,uno::UNO_QUERY);
        if ( xSubReport.is() )
        {
            bool bMasterReport = find(xSection->getReportDefinition(), *xScratch);
            if (!bMasterReport)
                m_xMasterReport.reset();
            else
                m_xMasterReport = m_xTreeView->make_iterator(xScratch.get());
            reportdesign::OReportVisitor aSubVisitor(this);
            aSubVisitor.start(xSubReport);
        }
    }
}

void NavigatorTree::traverseFunctions(const uno::Reference< report::XFunctions>& xFunctions, const weld::TreeIter* pParent)
{
    std::unique_ptr<weld::TreeIter> xFunctionIter = m_xTreeView->make_iterator();
    std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
    insertEntry(RptResId(RID_STR_FUNCTIONS), pParent, RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this, xFunctions), *xFunctionIter);
    const sal_Int32 nCount = xFunctions->getCount();
    for (sal_Int32 i = 0; i< nCount; ++i)
    {
        uno::Reference< report::XFunction> xElement(xFunctions->getByIndex(i),uno::UNO_QUERY);
        insertEntry(xElement->getName(), xFunctionIter.get(), RID_SVXBMP_RPT_NEW_FUNCTION, -1, new UserData(this,xElement), *xScratch);
    }
}

bool NavigatorTree::find(const uno::Reference<uno::XInterface>& xContent, weld::TreeIter& rRet)
{
    bool bRet = false;
    if (xContent.is())
    {
        m_xTreeView->all_foreach([this, &xContent, &bRet, &rRet](weld::TreeIter& rIter) {
            UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(rIter));
            if (pData->getContent() == xContent)
            {
                m_xTreeView->copy_iterator(rIter, rRet);
                bRet = true;
                return true;
            }
            return false;
        });
    }
    return bRet;
}

// ITraverseReport

void NavigatorTree::traverseReport(const uno::Reference< report::XReportDefinition>&&nbsp;xReport)
{
    std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
    insertEntry(xReport->getName(), m_xMasterReport.get(), RID_SVXBMP_SELECT_REPORT,-1, new UserData(this, xReport), *xScratch);
}

void NavigatorTree::traverseReportFunctions(const uno::Reference< report::XFunctions>&&nbsp;xFunctions)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xFunctions->getParent(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseFunctions(xFunctions, xReport.get());
}

void NavigatorTree::traverseReportHeader(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getReportDefinition(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
}

void NavigatorTree::traverseReportFooter(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getReportDefinition(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_REPORTHEADERFOOTER);
}

void NavigatorTree::traversePageHeader(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getReportDefinition(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
}

void NavigatorTree::traversePageFooter(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getReportDefinition(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_PAGEHEADERFOOTER);
}

void NavigatorTree::traverseGroups(const uno::Reference< report::XGroups>& xGroups)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xGroups->getReportDefinition(), *xReport);
    if (!bReport)
        xReport.reset();
    std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
    insertEntry(RptResId(RID_STR_GROUPS), xReport.get(), RID_SVXBMP_SORTINGANDGROUPING, -1, new UserData(this, xGroups), *xScratch);
}

void NavigatorTree::traverseGroup(const uno::Reference< report::XGroup>& xGroup)
{
    uno::Reference< report::XGroups> xGroups(xGroup->getParent(),uno::UNO_QUERY);
    std::unique_ptr<weld::TreeIter> xGroupsIter = m_xTreeView->make_iterator();
    bool bGroups = find(xGroups, *xGroupsIter);
    OSL_ENSURE(bGroups, "No Groups inserted so far. Why!");
    if (!bGroups)
        xGroupsIter.reset();
    std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
    insertEntry(xGroup->getExpression(), xGroupsIter.get(), RID_SVXBMP_GROUP, rptui::getPositionInIndexAccess(xGroups,xGroup), new UserData(this,xGroup), *xScratch);
}

void NavigatorTree::traverseGroupFunctions(const uno::Reference< report::XFunctions>&&nbsp;xFunctions)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xFunctions->getParent(), *xReport);
    if (!bReport)
        xReport.reset();
    traverseFunctions(xFunctions, xReport.get());
}

void NavigatorTree::traverseGroupHeader(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getGroup(), *xReport);
    OSL_ENSURE(bReport, "No group found");
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPHEADER, 1);
}

void NavigatorTree::traverseGroupFooter(const uno::Reference< report::XSection>& xSection)
{
    std::unique_ptr<weld::TreeIter> xReport = m_xTreeView->make_iterator();
    bool bReport = find(xSection->getGroup(), *xReport);
    OSL_ENSURE(bReport, "No group found");
    if (!bReport)
        xReport.reset();
    traverseSection(xSection, xReport.get(), RID_SVXBMP_GROUPFOOTER);
}

void NavigatorTree::traverseDetail(const uno::Reference< report::XSection>& xSection)
{
    uno::Reference< report::XReportDefinition> xReport = xSection->getReportDefinition();
    std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
    bool bParent = find(xReport, *xParent);
    if (!bParent)
        xParent.reset();
    traverseSection(xSection, xParent.get(), RID_SVXBMP_ICON_DETAIL);
}

void NavigatorTree::_propertyChanged(const beans::PropertyChangeEvent& _rEvent)
{
    uno::Reference< report::XReportDefinition> xReport(_rEvent.Source,uno::UNO_QUERY);
    if ( !xReport.is() )
        return;

    bool bEnabled = false;
    _rEvent.NewValue >>= bEnabled;
    if ( !bEnabled )
        return;

    std::unique_ptr<weld::TreeIter> xParent = m_xTreeView->make_iterator();
    bool bParent = find(xReport, *xParent);
    if (!bParent)
        xParent.reset();
    if ( _rEvent.PropertyName == PROPERTY_REPORTHEADERON )
    {
        int nPos = xReport->getReportHeaderOn() ? 2 : 1;
        traverseSection(xReport->getReportHeader(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
    }
    else if ( _rEvent.PropertyName == PROPERTY_PAGEHEADERON )
    {
        traverseSection(xReport->getPageHeader(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER,1);
    }
    else if ( _rEvent.PropertyName == PROPERTY_PAGEFOOTERON )
        traverseSection(xReport->getPageFooter(),xParent.get(), RID_SVXBMP_PAGEHEADERFOOTER);
    else if ( _rEvent.PropertyName == PROPERTY_REPORTFOOTERON )
    {
        int nPos = -1;
        if (xReport->getPageFooterOn() && xParent)
            nPos = m_xTreeView->iter_n_children(*xParent) - 1;
        traverseSection(xReport->getReportFooter(),xParent.get(),RID_SVXBMP_REPORTHEADERFOOTER,nPos);
    }
}

void NavigatorTree::_elementInserted( const container::ContainerEvent& _rEvent )
{
    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    bool bEntry = find(_rEvent.Source, *xEntry);
    if (!bEntry)
        xEntry.reset();
    uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY_THROW);
    OUString sName;
    uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
    if ( xInfo.is() )
    {
        if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
            xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
        else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
            xProp->getPropertyValue(PROPERTY_EXPRESSION) >>= sName;
    }
    uno::Reference< report::XGroup> xGroup(xProp,uno::UNO_QUERY);
    if ( xGroup.is() )
    {
        reportdesign::OReportVisitor aSubVisitor(this);
        aSubVisitor.start(xGroup);
    }
    else
    {
        uno::Reference< report::XReportComponent> xElement(xProp,uno::UNO_QUERY);
        if ( xProp.is() )
            sName = lcl_getName(xProp);
        std::unique_ptr<weld::TreeIter> xScratch = m_xTreeView->make_iterator();
        insertEntry(sName, xEntry.get(), (!xElement.is() ? RID_SVXBMP_RPT_NEW_FUNCTION : lcl_getImageId(xElement)),
                    -1, new UserData(this,xProp), *xScratch);
    }
    if (bEntry && !m_xTreeView->get_row_expanded(*xEntry))
        m_xTreeView->expand_row(*xEntry);
}

void NavigatorTree::_elementRemoved( const container::ContainerEvent& _rEvent )
{
    uno::Reference<beans::XPropertySet> xProp(_rEvent.Element,uno::UNO_QUERY);
    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    bool bEntry = find(xProp, *xEntry);
    OSL_ENSURE(bEntry,"NavigatorTree::_elementRemoved: No Entry found!");

    if (bEntry)
    {
        removeEntry(*xEntry);
    }
}

void NavigatorTree::_elementReplaced( const container::ContainerEvent& _rEvent )
{
    uno::Reference<beans::XPropertySet> xProp(_rEvent.ReplacedElement,uno::UNO_QUERY);
    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    bool bEntry = find(xProp, *xEntry);
    if (bEntry)
    {
        UserData* pData = weld::fromId<UserData*>(m_xTreeView->get_id(*xEntry));
        xProp.set(_rEvent.Element,uno::UNO_QUERY);
        pData->setContent(xProp);
        OUString sName;
        xProp->getPropertyValue(PROPERTY_NAME) >>= sName;
        m_xTreeView->set_text(*xEntry, sName);
    }
}

void NavigatorTree::_disposing(const lang::EventObject& _rSource)
{
    std::unique_ptr<weld::TreeIter> xEntry = m_xTreeView->make_iterator();
    if (find(_rSource.Source, *xEntry))
        removeEntry(*xEntry);
}

void NavigatorTree::removeEntry(const weld::TreeIter& rEntry, bool bRemove)
{
    std::unique_ptr<weld::TreeIter> xChild = m_xTreeView->make_iterator(&rEntry);
    bool bChild = m_xTreeView->iter_children(*xChild);
    while (bChild)
    {
        removeEntry(*xChild, false);
        bChild = m_xTreeView->iter_next_sibling(*xChild);
    }
    delete weld::fromId<UserData*>(m_xTreeView->get_id(rEntry));
    if (bRemove)
        m_xTreeView->remove(rEntry);
}

NavigatorTree::UserData::UserData(NavigatorTree* pTree,uno::Reference<uno::XInterface> xContent)
    : OPropertyChangeListener()
    , OContainerListener(m_aMutex)
    , m_xContent(std::move(xContent))
    , m_pTree(pTree)
{
    uno::Reference<beans::XPropertySet> xProp(m_xContent,uno::UNO_QUERY);
    if ( xProp.is() )
    {
        uno::Reference< beans::XPropertySetInfo> xInfo = xProp->getPropertySetInfo();
        if ( xInfo.is() )
        {
            m_pListener = new ::comphelper::OPropertyChangeMultiplexer(this,xProp);
            if ( xInfo->hasPropertyByName(PROPERTY_NAME) )
                m_pListener->addProperty(PROPERTY_NAME);
            else if ( xInfo->hasPropertyByName(PROPERTY_EXPRESSION) )
                m_pListener->addProperty(PROPERTY_EXPRESSION);
            if ( xInfo->hasPropertyByName(PROPERTY_DATAFIELD) )
                m_pListener->addProperty(PROPERTY_DATAFIELD);
            if ( xInfo->hasPropertyByName(PROPERTY_LABEL) )
                m_pListener->addProperty(PROPERTY_LABEL);
            if ( xInfo->hasPropertyByName(PROPERTY_HEADERON) )
                m_pListener->addProperty(PROPERTY_HEADERON);
            if ( xInfo->hasPropertyByName(PROPERTY_FOOTERON) )
                m_pListener->addProperty(PROPERTY_FOOTERON);
        }
    }
    uno::Reference< container::XContainer> xContainer(m_xContent,uno::UNO_QUERY);
    if ( xContainer.is() )
    {
        m_pContainerListener = new ::comphelper::OContainerListenerAdapter(this,xContainer);
    }
}

NavigatorTree::UserData::~UserData()
{
    if ( m_pContainerListener.is() )
        m_pContainerListener->dispose();
    if ( m_pListener.is() )
        m_pListener->dispose();
}

// OPropertyChangeListener
void NavigatorTree::UserData::_propertyChanged(const beans::PropertyChangeEvent&&nbsp;_rEvent)
{
    std::unique_ptr<weld::TreeIter> xEntry = m_pTree->make_iterator();
    bool bEntry = m_pTree->find(_rEvent.Source, *xEntry);
    OSL_ENSURE(bEntry,"No entry could be found! Why not!");
    if (!bEntry)
        return;
    const bool bFooterOn = (PROPERTY_FOOTERON == _rEvent.PropertyName);
    try
    {
        if ( bFooterOn || PROPERTY_HEADERON == _rEvent.PropertyName )
        {
            sal_Int32 nPos = 1;
            uno::Reference< report::XGroup> xGroup(_rEvent.Source,uno::UNO_QUERY);
            ::std::function<bool(OGroupHelper *)> pIsOn = ::std::mem_fn(&OGroupHelper::getHeaderOn);
            ::std::function<uno::Reference<report::XSection>(OGroupHelper *)> pMemFunSection = ::std::mem_fn(&OGroupHelper::getHeader);
            if ( bFooterOn )
            {
                pIsOn = ::std::mem_fn(&OGroupHelper::getFooterOn);
                pMemFunSection = ::std::mem_fn(&OGroupHelper::getFooter);
                nPos = m_pTree->iter_n_children(*xEntry) - 1;
            }

            OGroupHelper aGroupHelper(xGroup);
            if ( pIsOn(&aGroupHelper) )
            {
                if ( bFooterOn )
                    ++nPos;
                m_pTree->traverseSection(pMemFunSection(&aGroupHelper),xEntry.get(),bFooterOn ? RID_SVXBMP_GROUPFOOTER : RID_SVXBMP_GROUPHEADER,nPos);
            }
        }
        else if ( PROPERTY_EXPRESSION == _rEvent.PropertyName)
        {
            OUString sNewName;
            _rEvent.NewValue >>= sNewName;
            m_pTree->set_text(*xEntry, sNewName);
        }
        else if ( PROPERTY_DATAFIELD == _rEvent.PropertyName || PROPERTY_LABEL == _rEvent.PropertyName || PROPERTY_NAME == _rEvent.PropertyName )
        {
            uno::Reference<beans::XPropertySet> xProp(_rEvent.Source,uno::UNO_QUERY);
            m_pTree->set_text(*xEntry, lcl_getName(xProp));
        }
    }
    catch(const uno::Exception &)
    {}
}

void NavigatorTree::UserData::_elementInserted( const container::ContainerEvent& ;_rEvent )
{
    m_pTree->_elementInserted( _rEvent );
}

void NavigatorTree::UserData::_elementRemoved( const container::ContainerEvent& _rEvent )
{
    m_pTree->_elementRemoved( _rEvent );
}

void NavigatorTree::UserData::_elementReplaced( const container::ContainerEvent& ;_rEvent )
{
    m_pTree->_elementReplaced( _rEvent );
}

void NavigatorTree::UserData::_disposing(const lang::EventObject& _rSource)
{
    m_pTree->_disposing( _rSource );
}

ONavigator::ONavigator(weld::Window* pParent, OReportController& rController)
    : GenericDialogController(pParent, u"modules/dbreport/ui/floatingnavigator.ui"_ustr, u"FloatingNavigator"_ustr)
    , m_xReport(rController.getReportDefinition())
    , m_xNavigatorTree(std::make_unique<NavigatorTree>(m_xBuilder->weld_tree_view(u"treeview"_ustr), rController))
{
    reportdesign::OReportVisitor aVisitor(m_xNavigatorTree.get());
    aVisitor.start(m_xReport);
    std::unique_ptr<weld::TreeIter> xScratch = m_xNavigatorTree->make_iterator();
    if (m_xNavigatorTree->find(m_xReport, *xScratch))
        m_xNavigatorTree->expand_row(*xScratch);
    lang::EventObject aEvent(rController);
    m_xNavigatorTree->_selectionChanged(aEvent);
    m_xNavigatorTree->grab_focus();

    m_xDialog->connect_container_focus_changed(LINK(this, ONavigator, FocusChangeHdl));
}

ONavigator::~ONavigator()
{
}

IMPL_LINK_NOARG(ONavigator, FocusChangeHdl, weld::Container&, void)
{
    if (m_xDialog->has_toplevel_focus())
        m_xNavigatorTree->grab_focus();
}

// rptui

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

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

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