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

Quelle  fmPropBrw.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/macros.h>

#include <fmprop.hxx>
#include <fmPropBrw.hxx>
#include <svx/strings.hrc>
#include <fmservs.hxx>
#include <fmshimp.hxx>
#include <fmpgeimp.hxx>

#include <svx/dialmgr.hxx>
#include <svx/fmpage.hxx>
#include <svx/fmshell.hxx>
#include <svx/fmview.hxx>
#include <svx/sdrpagewindow.hxx>
#include <svx/svdpagv.hxx>
#include <svx/svxids.hrc>

#include <com/sun/star/awt/XControlContainer.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/form/XForm.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <com/sun/star/form/inspection/DefaultFormComponentInspectorModel.hpp>
#include <com/sun/star/frame/Frame.hpp>
#include <com/sun/star/inspection/ObjectInspector.hpp>
#include <com/sun/star/inspection/XObjectInspectorUI.hpp>
#include <com/sun/star/inspection/DefaultHelpProvider.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/util/VetoException.hpp>

#include <comphelper/processfactory.hxx>
#include <comphelper/property.hxx>
#include <comphelper/sequence.hxx>
#include <comphelper/types.hxx>
#include <cppuhelper/component_context.hxx>
#include <o3tl/deleter.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/childwin.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/objsh.hxx>
#include <comphelper/diagnose_ex.hxx>
#include <unotools/confignode.hxx>
#include <vcl/stdtext.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <vcl/weldutils.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::form;
using namespace ::com::sun::star::form::inspection;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::inspection;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::svxform;
using ::com::sun::star::awt::XWindow;

//= FmPropBrwMgr
SFX_IMPL_MODELESSDIALOGCONTOLLER(FmPropBrwMgr, SID_FM_SHOW_PROPERTIES)

FmPropBrwMgr::FmPropBrwMgr( vcl::Window* _pParent, sal_uInt16 _nId,
                            SfxBindings* _pBindings, const SfxChildWinInfo* _pInfo)
              :SfxChildWindow(_pParent, _nId)
{
    std::shared_ptr<FmPropBrw> xControl(new FmPropBrw(::comphelper::getProcessComponentContext(), _pBindings,
                                                         this, _pParent->GetFrameWeld(), _pInfo), o3tl::default_delete<FmPropBrw>());
    SetController(std::move(xControl));
    static_cast<FmPropBrw*>(GetController().get())->Initialize( _pInfo );
}

static OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj)
{
    TranslateId pClassNameResourceId;

    switch ( nClassId )
    {
        case FormComponentType::TEXTFIELD:
        {
            Reference< XInterface >  xIFace;
            aUnoObj >>= xIFace;
            pClassNameResourceId = RID_STR_PROPTITLE_EDIT;
            if (xIFace.is())
            {   // we have a chance to check if it's a formatted field model
                Reference< XServiceInfo >  xInfo(xIFace, UNO_QUERY);
                if (xInfo.is() && (xInfo->supportsService(FM_SUN_COMPONENT_FORMATTEDFIELD)))
                    pClassNameResourceId = RID_STR_PROPTITLE_FORMATTED;
                else if (!xInfo.is())
                {
                    // couldn't distinguish between formatted and edit with the service name, so try with the properties
                    Reference< XPropertySet >  xProps(xIFace, UNO_QUERY);
                    if (xProps.is())
                    {
                        Reference< XPropertySetInfo >  xPropsInfo = xProps->getPropertySetInfo();
                        if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(FM_PROP_FORMATSSUPPLIER))
                            pClassNameResourceId = RID_STR_PROPTITLE_FORMATTED;
                    }
                }
            }
        }
        break;

        case FormComponentType::COMMANDBUTTON:
            pClassNameResourceId = RID_STR_PROPTITLE_PUSHBUTTON; break;
        case FormComponentType::RADIOBUTTON:
            pClassNameResourceId = RID_STR_PROPTITLE_RADIOBUTTON; break;
        case FormComponentType::CHECKBOX:
            pClassNameResourceId = RID_STR_PROPTITLE_CHECKBOX; break;
        case FormComponentType::LISTBOX:
            pClassNameResourceId = RID_STR_PROPTITLE_LISTBOX; break;
        case FormComponentType::COMBOBOX:
            pClassNameResourceId = RID_STR_PROPTITLE_COMBOBOX; break;
        case FormComponentType::GROUPBOX:
            pClassNameResourceId = RID_STR_PROPTITLE_GROUPBOX; break;
        case FormComponentType::IMAGEBUTTON:
            pClassNameResourceId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
        case FormComponentType::FIXEDTEXT:
            pClassNameResourceId = RID_STR_PROPTITLE_FIXEDTEXT; break;
        case FormComponentType::GRIDCONTROL:
            pClassNameResourceId = RID_STR_PROPTITLE_DBGRID; break;
        case FormComponentType::FILECONTROL:
            pClassNameResourceId = RID_STR_PROPTITLE_FILECONTROL; break;
        case FormComponentType::DATEFIELD:
            pClassNameResourceId = RID_STR_PROPTITLE_DATEFIELD; break;
        case FormComponentType::TIMEFIELD:
            pClassNameResourceId = RID_STR_PROPTITLE_TIMEFIELD; break;
        case FormComponentType::NUMERICFIELD:
            pClassNameResourceId = RID_STR_PROPTITLE_NUMERICFIELD; break;
        case FormComponentType::CURRENCYFIELD:
            pClassNameResourceId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
        case FormComponentType::PATTERNFIELD:
            pClassNameResourceId = RID_STR_PROPTITLE_PATTERNFIELD; break;
        case FormComponentType::IMAGECONTROL:
            pClassNameResourceId = RID_STR_PROPTITLE_IMAGECONTROL; break;
        case FormComponentType::HIDDENCONTROL:
            pClassNameResourceId = RID_STR_PROPTITLE_HIDDEN; break;
        case FormComponentType::SCROLLBAR:
            pClassNameResourceId = RID_STR_PROPTITLE_SCROLLBAR; break;
        case FormComponentType::SPINBUTTON:
            pClassNameResourceId = RID_STR_PROPTITLE_SPINBUTTON; break;
        case FormComponentType::NAVIGATIONBAR:
            pClassNameResourceId = RID_STR_PROPTITLE_NAVBAR; break;
        case FormComponentType::CONTROL:
        default:
            pClassNameResourceId = RID_STR_CONTROL; break;
    }

    return SvxResId(pClassNameResourceId);
}

FmPropBrw::FmPropBrw(const Reference< XComponentContext >& _xORB, SfxBindings* _pBindings,
                     SfxChildWindow* _pMgr, weld::Window* _pParent, const SfxChildWinInfo* _pInfo)
    : SfxModelessDialogController(_pBindings, _pMgr, _pParent, u"svx/ui/formpropertydialog.ui"_ustr, u"FormPropertyDialog"_ustr)
    , SfxControllerItem(SID_FM_PROPERTY_CONTROL, *_pBindings)
    , m_bInitialStateChange(true)
    , m_pParent(_pParent)
    , m_nAsyncGetFocusId(nullptr)
    , m_xDialogBox(m_xBuilder->weld_box(u"dialog-vbox1"_ustr))
    , m_xContainer(m_xBuilder->weld_container(u"container"_ustr))
    , m_xORB(_xORB)
{
    m_xContainer->set_size_request(m_xContainer->get_approximate_digit_width() * 72, m_xContainer->get_text_height() * 20);

    try
    {
        // create a frame wrapper for myself
        m_xMeAsFrame = Frame::create(m_xORB);

        // transport the container area of this dialog to be the container window of the frame
        css::uno::Reference<css::awt::XWindow> xFrameContainerWindow(new weld::TransportAsXWindow(m_xContainer.get()));
        m_xMeAsFrame->initialize(xFrameContainerWindow);
        m_xMeAsFrame->setName(u"form property browser"_ustr);
    }
    catch (const Exception&)
    {
        OSL_FAIL("FmPropBrw::FmPropBrw: could not create/initialize my frame!");
        m_xMeAsFrame.clear();
    }

    if ( _pInfo )
        m_sLastActivePage = _pInfo->aExtraString;
}

FmPropBrw::~FmPropBrw()
{
    if (m_nAsyncGetFocusId)
    {
        Application::RemoveUserEvent(m_nAsyncGetFocusId);
        m_nAsyncGetFocusId = nullptr;
    }

    if (m_xBrowserController.is())
        implDetachController();
    try
    {
        // remove our own properties from the component context. We cannot ensure that the component context
        // is freed (there might be refcount problems :-\), so at least ensure the context itself
        // does hold the objects anymore
        Reference<XNameContainer> xName(m_xInspectorContext,uno::UNO_QUERY);
        if ( xName.is() )
        {
            const OUString pProps[] = { u"ContextDocument"_ustr
                                             , u"DialogParentWindow"_ustr
                                             , u"ControlContext"_ustr
                                             , u"ControlShapeAccess"_ustr };
            for (const auto & i : pProps)
                xName->removeByName( i );
        }
    }
    catch (const Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("svx");
    }
    ::SfxControllerItem::dispose();
}

OUString FmPropBrw::getCurrentPage() const
{
    OUString sCurrentPage;
    try
    {
        if ( m_xBrowserController.is() )
        {
            OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage );
        }

        if ( sCurrentPage.isEmpty() )
            sCurrentPage = m_sLastActivePage;
    }
    catchconst Exception& )
    {
        TOOLS_WARN_EXCEPTION("svx.form""caught an exception while retrieving the current page!");
    }
    return sCurrentPage;
}

void FmPropBrw::implDetachController()
{
    m_sLastActivePage = getCurrentPage();

    implSetNewSelection( InterfaceBag() );

    if ( m_xMeAsFrame.is() )
    {
        try
        {
            m_xMeAsFrame->setComponent(nullptr, nullptr);
        }
        catchconst Exception& )
        {
            TOOLS_WARN_EXCEPTION("svx.form""caught an exception while resetting the component!");
        }
    }

    // we attached a frame to the controller manually, so we need to manually tell it that it's detached, too
    if ( m_xBrowserController.is() )
    {
        m_xBrowserController->attachFrame( nullptr );
    }

    m_xBrowserController.clear();
    m_xInspectorModel.clear();
    m_xMeAsFrame.clear();
}

void FmPropBrw::Close()
{
    // suspend the controller (it is allowed to veto)
    if ( m_xMeAsFrame.is() )
    {
        try
        {
            Reference< XController > xController( m_xMeAsFrame->getController() );
            if ( xController.is() && !xController->suspend( true ) )
                return;
        }
        catchconst Exception& )
        {
            TOOLS_WARN_EXCEPTION("svx.form""caught an exception while asking the controller!");
        }
    }

    implDetachController();

    // remember our bindings: while we're closed, we're deleted, too, so accessing the bindings after this
    // would be deadly
    // 10/19/00 - 79321 - FS
    SfxBindings& rBindings = SfxControllerItem::GetBindings();

    SfxModelessDialogController::Close();

    rBindings.Invalidate(SID_FM_CTL_PROPERTIES);
    rBindings.Invalidate(SID_FM_PROPERTIES);
}

bool FmPropBrw::implIsReadOnlyModel() const
{
    try
    {
        if ( m_xInspectorModel.is() )
            return m_xInspectorModel->getIsReadOnly();
        return false;
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("svx");
    }
    return true;
}


void FmPropBrw::implSetNewSelection( const InterfaceBag& _rSelection )
{
    if ( !m_xBrowserController.is() )
        return;

    try
    {
        Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW );

        // tell it the objects to inspect
        xInspector->inspect( comphelper::containerToSequence(_rSelection) );
    }
    catchconst VetoException& )
    {
        return;
    }
    catchconst Exception& )
    {
        TOOLS_WARN_EXCEPTION("svx.form""");
        return;
    }

    // set the new title according to the selected object
    OUString sTitle;

    if ( _rSelection.empty() )
    {
        sTitle = SvxResId(RID_STR_NO_PROPERTIES);
    }
    else if ( _rSelection.size() > 1 )
    {
        // no form component and (no form or no name) -> Multiselection
        sTitle = SvxResId(RID_STR_PROPERTIES_CONTROL) +
            SvxResId(RID_STR_PROPTITLE_MULTISELECT);
    }
    else
    {
        Reference< XPropertySet > xSingleSelection( *_rSelection.begin(), UNO_QUERY);
        if  ( ::comphelper::hasProperty( FM_PROP_CLASSID, xSingleSelection ) )
        {
            sal_Int16 nClassID = FormComponentType::CONTROL;
            xSingleSelection->getPropertyValue( FM_PROP_CLASSID ) >>= nClassID;

            sTitle = SvxResId(RID_STR_PROPERTIES_CONTROL) +
                GetUIHeadlineName(nClassID, Any(xSingleSelection));
        }
        else if ( Reference< XForm >( xSingleSelection, UNO_QUERY ).is() )
            sTitle = SvxResId(RID_STR_PROPERTIES_FORM);
    }

    if ( implIsReadOnlyModel() )
        sTitle += SvxResId(RID_STR_READONLY_VIEW);

    m_xDialog->set_title(sTitle);
}

void FmPropBrw::FillInfo( SfxChildWinInfo& rInfo ) const
{
    rInfo.bVisible = false;
    rInfo.aExtraString = getCurrentPage();
}

IMPL_LINK_NOARG( FmPropBrw, OnAsyncGetFocus, void*, void )
{
    m_xDialogBox->child_grab_focus();
    m_nAsyncGetFocusId = nullptr;
}

namespace
{
    bool lcl_shouldEnableHelpSection( const Reference< XComponentContext >& _rxContext )
    {
        ::utl::OConfigurationTreeRoot aConfiguration(
            ::utl::OConfigurationTreeRoot::createWithComponentContext(
                _rxContext,
                u"/org.openoffice.Office.Common/Forms/PropertyBrowser/"_ustr ) );

        bool bEnabled = false;
        OSL_VERIFY( aConfiguration.getNodeValue( u"DirectHelp"_ustr ) >>= bEnabled );
        return bEnabled;
    }
}

void FmPropBrw::impl_createPropertyBrowser_throw( FmFormShell* _pFormShell )
{
    // the document in which we live
    Reference< XInterface > xDocument;
    if ( _pFormShell && _pFormShell->GetObjectShell() )
        xDocument = _pFormShell->GetObjectShell()->GetModel();

    // the context of the controls in our document
    Reference< awt::XControlContainer > xControlContext;
    if ( _pFormShell && _pFormShell->GetFormView() )
    {
        SdrPageView* pPageView = _pFormShell->GetFormView()->GetSdrPageView();

        if(pPageView)
        {
            SdrPageWindow* pPageWindow = pPageView->GetPageWindow(0);

            if(pPageWindow)
            {
                xControlContext = pPageWindow->GetControlContainer();
            }
        }
    }

    // the default parent window for message boxes
    Reference< XWindow > xParentWindow(m_xDialog->GetXWindow());

    // the mapping from control models to control shapes
    Reference< XMap > xControlMap;
    FmFormPage* pFormPage = _pFormShell ? _pFormShell->GetCurPage() : nullptr;
    if ( pFormPage )
        xControlMap = pFormPage->GetImpl().getControlToShapeMap();

    // our own component context

    // a ComponentContext for the
    ::cppu::ContextEntry_Init aHandlerContextInfo[] =
    {
        ::cppu::ContextEntry_Init( u"ContextDocument"_ustr, Any( xDocument ) ),
        ::cppu::ContextEntry_Init( u"DialogParentWindow"_ustr, Any( xParentWindow ) ),
        ::cppu::ContextEntry_Init( u"ControlContext"_ustr, Any( xControlContext ) ),
        ::cppu::ContextEntry_Init( u"ControlShapeAccess"_ustr, Any( xControlMap ) )
    };
    m_xInspectorContext.set(
        ::cppu::createComponentContext( aHandlerContextInfo, SAL_N_ELEMENTS( aHandlerContextInfo ),
        m_xORB ) );

    bool bEnableHelpSection = lcl_shouldEnableHelpSection( m_xORB );

    // an object inspector model
    m_xInspectorModel =
            bEnableHelpSection
        ?   DefaultFormComponentInspectorModel::createWithHelpSection( m_xInspectorContext, 3, 5 )
        :   DefaultFormComponentInspectorModel::createDefault( m_xInspectorContext );

    // an object inspector
    m_xBrowserController =
        ObjectInspector::createWithModel(
            m_xInspectorContext, m_xInspectorModel
        );

    if ( !m_xBrowserController.is() )
    {
        ShowServiceNotAvailableError(m_pParent, u"com.sun.star.inspection.ObjectInspector"true);
    }
    else
    {
        m_xBrowserController->attachFrame( Reference<XFrame>(m_xMeAsFrame,UNO_QUERY_THROW) );
    }

    if ( bEnableHelpSection )
    {
        Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW );
        Reference< XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() );
        DefaultHelpProvider::create( m_xInspectorContext, xInspectorUI );
    }
}


void FmPropBrw::impl_ensurePropertyBrowser_nothrow( FmFormShell* _pFormShell )
{
    // the document in which we live
    Reference< XInterface > xDocument;
    SfxObjectShell* pObjectShell = _pFormShell ? _pFormShell->GetObjectShell() : nullptr;
    if ( pObjectShell )
        xDocument = pObjectShell->GetModel();
    if ( ( xDocument == m_xLastKnownDocument ) && m_xBrowserController.is() )
        // nothing to do
        return;

    try
    {
        // clean up any previous instances of the object inspector
        if ( m_xMeAsFrame.is() )
            m_xMeAsFrame->setComponent( nullptr, nullptr );
        else
            ::comphelper::disposeComponent( m_xBrowserController );
        m_xBrowserController.clear();
        m_xInspectorModel.clear();

        // and create a new one
        impl_createPropertyBrowser_throw( _pFormShell );
    }
    catchconst Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("svx");
    }
    m_xLastKnownDocument = std::move(xDocument);
}


void FmPropBrw::StateChangedAtToolBoxControl(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState)
{
    if (!pState  || SID_FM_PROPERTY_CONTROL != nSID)
        return;

    try
    {
        if (eState >= SfxItemState::DEFAULT)
        {
            FmFormShell* pShell = dynamic_cast<FmFormShell*>( static_cast<const SfxObjectItem*>(pState)->GetShell() );
            InterfaceBag aSelection;
            if ( pShell )
                pShell->GetImpl()->getCurrentSelection_Lock(aSelection);

            impl_ensurePropertyBrowser_nothrow( pShell );

            // set the new object to inspect
            implSetNewSelection( aSelection );

            // if this is the first time we're here, some additional things need to be done ...
            if ( m_bInitialStateChange )
            {
                // if we're just newly created, we want to have the focus
                m_nAsyncGetFocusId = Application::PostUserEvent(LINK(this, FmPropBrw, OnAsyncGetFocus));

                // and additionally, we want to show the page which was active during
                // our previous incarnation
                if ( !m_sLastActivePage.isEmpty() )
                {
                    try
                    {
                        if ( m_xBrowserController.is() )
                            m_xBrowserController->restoreViewData( Any( m_sLastActivePage ) );
                    }
                    catchconst Exception& )
                    {
                        TOOLS_WARN_EXCEPTION("svx.form",
                                             "caught an exception while setting the initial page!");
                    }
                }

                m_bInitialStateChange = false;
            }

        }
        else
        {
            implSetNewSelection( InterfaceBag() );
        }
    }
    catch (Exception&)
    {
        TOOLS_WARN_EXCEPTION("svx.form""");
    }
}

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

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

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