diff options
Diffstat (limited to 'svx/source/form/fmPropBrw.cxx')
-rw-r--r-- | svx/source/form/fmPropBrw.cxx | 722 |
1 files changed, 722 insertions, 0 deletions
diff --git a/svx/source/form/fmPropBrw.cxx b/svx/source/form/fmPropBrw.cxx new file mode 100644 index 000000000000..bcc275896410 --- /dev/null +++ b/svx/source/form/fmPropBrw.cxx @@ -0,0 +1,722 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include "fmhelp.hrc" +#include "fmprop.hrc" +#include "fmPropBrw.hxx" +#include "fmresids.hrc" +#include "fmservs.hxx" +#include "fmshimp.hxx" +#include "fmpgeimp.hxx" + +#include "svx/dialmgr.hxx" +#include "svx/fmpage.hxx" +#include "svx/fmshell.hxx" +#include "svx/sdrpagewindow.hxx" +#include "svx/svdpagv.hxx" +#include "svx/svxids.hrc" + +/** === begin UNO includes === **/ +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/awt/XLayoutConstrains.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/container/XChild.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/inspection/ObjectInspector.hpp> +#include <com/sun/star/inspection/ObjectInspectorModel.hpp> +#include <com/sun/star/form/inspection/DefaultFormComponentInspectorModel.hpp> +#include <com/sun/star/inspection/XObjectInspectorUI.hpp> +#include <com/sun/star/inspection/DefaultHelpProvider.hpp> +/** === end UNO includes === **/ + +#include <comphelper/processfactory.hxx> +#include <comphelper/property.hxx> +#include <cppuhelper/component_context.hxx> +#include <sfx2/bindings.hxx> +#include <sfx2/childwin.hxx> +#include <sfx2/dispatch.hxx> +#include <sfx2/objitem.hxx> +#include <sfx2/objsh.hxx> +#include <sfx2/viewfrm.hxx> +#include <toolkit/unohlp.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> +#include <tools/shl.hxx> +#include <unotools/confignode.hxx> +#include <vcl/stdtext.hxx> + +#include <algorithm> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::inspection; +using namespace ::com::sun::star::form::inspection; +using ::com::sun::star::awt::XWindow; + +/*************************************************************************/ +//======================================================================== +//= FmPropBrwMgr +//======================================================================== +//----------------------------------------------------------------------- +SFX_IMPL_FLOATINGWINDOW(FmPropBrwMgr, SID_FM_SHOW_PROPERTIES) + +//----------------------------------------------------------------------- +FmPropBrwMgr::FmPropBrwMgr( Window* _pParent, sal_uInt16 _nId, + SfxBindings* _pBindings, SfxChildWinInfo* _pInfo) + :SfxChildWindow(_pParent, _nId) +{ + pWindow = new FmPropBrw( ::comphelper::getProcessServiceFactory(), _pBindings, this, _pParent, _pInfo ); + eChildAlignment = SFX_ALIGN_NOALIGNMENT; + ((SfxFloatingWindow*)pWindow)->Initialize( _pInfo ); +} + +//======================================================================== +//======================================================================== +const long STD_WIN_SIZE_X = 300; +const long STD_WIN_SIZE_Y = 350; + +const long STD_MIN_SIZE_X = 250; +const long STD_MIN_SIZE_Y = 250; + +const long STD_WIN_POS_X = 50; +const long STD_WIN_POS_Y = 50; +const long WIN_BORDER = 2; +const long MIN_WIN_SIZE_X = 50; +const long MIN_WIN_SIZE_Y = 50; + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::svxform; + +::rtl::OUString GetUIHeadlineName(sal_Int16 nClassId, const Any& aUnoObj) +{ + sal_uInt16 nClassNameResourceId = 0; + + switch ( nClassId ) + { + case FormComponentType::TEXTFIELD: + { + Reference< XInterface > xIFace; + aUnoObj >>= xIFace; + nClassNameResourceId = 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))) + nClassNameResourceId = 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)) + nClassNameResourceId = RID_STR_PROPTITLE_FORMATTED; + } + } + } + } + break; + + case FormComponentType::COMMANDBUTTON: + nClassNameResourceId = RID_STR_PROPTITLE_PUSHBUTTON; break; + case FormComponentType::RADIOBUTTON: + nClassNameResourceId = RID_STR_PROPTITLE_RADIOBUTTON; break; + case FormComponentType::CHECKBOX: + nClassNameResourceId = RID_STR_PROPTITLE_CHECKBOX; break; + case FormComponentType::LISTBOX: + nClassNameResourceId = RID_STR_PROPTITLE_LISTBOX; break; + case FormComponentType::COMBOBOX: + nClassNameResourceId = RID_STR_PROPTITLE_COMBOBOX; break; + case FormComponentType::GROUPBOX: + nClassNameResourceId = RID_STR_PROPTITLE_GROUPBOX; break; + case FormComponentType::IMAGEBUTTON: + nClassNameResourceId = RID_STR_PROPTITLE_IMAGEBUTTON; break; + case FormComponentType::FIXEDTEXT: + nClassNameResourceId = RID_STR_PROPTITLE_FIXEDTEXT; break; + case FormComponentType::GRIDCONTROL: + nClassNameResourceId = RID_STR_PROPTITLE_DBGRID; break; + case FormComponentType::FILECONTROL: + nClassNameResourceId = RID_STR_PROPTITLE_FILECONTROL; break; + case FormComponentType::DATEFIELD: + nClassNameResourceId = RID_STR_PROPTITLE_DATEFIELD; break; + case FormComponentType::TIMEFIELD: + nClassNameResourceId = RID_STR_PROPTITLE_TIMEFIELD; break; + case FormComponentType::NUMERICFIELD: + nClassNameResourceId = RID_STR_PROPTITLE_NUMERICFIELD; break; + case FormComponentType::CURRENCYFIELD: + nClassNameResourceId = RID_STR_PROPTITLE_CURRENCYFIELD; break; + case FormComponentType::PATTERNFIELD: + nClassNameResourceId = RID_STR_PROPTITLE_PATTERNFIELD; break; + case FormComponentType::IMAGECONTROL: + nClassNameResourceId = RID_STR_PROPTITLE_IMAGECONTROL; break; + case FormComponentType::HIDDENCONTROL: + nClassNameResourceId = RID_STR_PROPTITLE_HIDDEN; break; + case FormComponentType::SCROLLBAR: + nClassNameResourceId = RID_STR_PROPTITLE_SCROLLBAR; break; + case FormComponentType::SPINBUTTON: + nClassNameResourceId = RID_STR_PROPTITLE_SPINBUTTON; break; + case FormComponentType::NAVIGATIONBAR: + nClassNameResourceId = RID_STR_PROPTITLE_NAVBAR; break; + case FormComponentType::CONTROL: + default: + nClassNameResourceId = RID_STR_CONTROL; break; + } + + if ( !nClassNameResourceId ) + return ::rtl::OUString(); + + return ::rtl::OUString( String( SVX_RES( nClassNameResourceId ) ) ); +} + +//======================================================================== +// class FmPropBrw +//======================================================================== +DBG_NAME(FmPropBrw); +//------------------------------------------------------------------------ +FmPropBrw::FmPropBrw( const Reference< XMultiServiceFactory >& _xORB, SfxBindings* _pBindings, + SfxChildWindow* _pMgr, Window* _pParent, const SfxChildWinInfo* _pInfo ) + :SfxFloatingWindow(_pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_3DLOOK|WB_ROLLABLE) ) + ,SfxControllerItem(SID_FM_PROPERTY_CONTROL, *_pBindings) + ,m_bInitialStateChange(sal_True) + ,m_bInStateChange( false ) + ,m_xORB(_xORB) +{ + DBG_CTOR(FmPropBrw,NULL); + + ::Size aPropWinSize(STD_WIN_SIZE_X,STD_WIN_SIZE_Y); + SetMinOutputSizePixel(::Size(STD_MIN_SIZE_X,STD_MIN_SIZE_Y)); + SetOutputSizePixel(aPropWinSize); + SetUniqueId(UID_FORMPROPBROWSER_FRAME); + + try + { + // create a frame wrapper for myself + m_xMeAsFrame = Reference< XFrame >(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Frame")), UNO_QUERY); + if (m_xMeAsFrame.is()) + { + // create an intermediate window, which is to be the container window of the frame + // Do *not* use |this| as container window for the frame, this would result in undefined + // responsiblity for this window (as soon as we initialize a frame with a window, the frame + // is responsible for it's life time, but |this| is controlled by the belonging SfxChildWindow) + // #i34249# - 2004-09-27 - fs@openoffice.org + Window* pContainerWindow = new Window( this ); + pContainerWindow->Show(); + m_xFrameContainerWindow = VCLUnoHelper::GetInterface ( pContainerWindow ); + + m_xMeAsFrame->initialize( m_xFrameContainerWindow ); + m_xMeAsFrame->setName(::rtl::OUString::createFromAscii("form property browser")); + if ( _pBindings->GetDispatcher() ) + { + ::com::sun::star::uno::Reference < ::com::sun::star::frame::XFramesSupplier > + xSupp ( _pBindings->GetDispatcher()->GetFrame()->GetFrame().GetFrameInterface(), ::com::sun::star::uno::UNO_QUERY ); +// if ( xSupp.is() ) +// xSupp->getFrames()->append( m_xMeAsFrame ); + // Don't append frame to frame hierachy to prevent UI_DEACTIVATE messages + // #i31834# - 2004-07-27 - cd@openoffice.org + } + } + } + catch (Exception&) + { + DBG_ERROR("FmPropBrw::FmPropBrw: could not create/initialize my frame!"); + m_xMeAsFrame.clear(); + } + + if (m_xMeAsFrame.is()) + _pMgr->SetFrame( m_xMeAsFrame ); + + + if ( m_xBrowserComponentWindow.is() ) + m_xBrowserComponentWindow->setVisible( sal_True ); + + if ( _pInfo ) + m_sLastActivePage = _pInfo->aExtraString; +} + +//------------------------------------------------------------------------ +void FmPropBrw::Resize() +{ + SfxFloatingWindow::Resize(); + + if ( m_xFrameContainerWindow.is() ) + { + try + { + ::Size aOutputSize( GetOutputSizePixel() ); + m_xFrameContainerWindow->setPosSize( 0, 0, aOutputSize.Width(), aOutputSize.Height(), awt::PosSize::POSSIZE ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::Resize: caught an exception!" ); + } + } +} + +//------------------------------------------------------------------------ +FmPropBrw::~FmPropBrw() +{ + 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 ::rtl::OUString pProps[] = { ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContextDocument" ) ) + , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogParentWindow" ) ) + , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) ) + , ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlShapeAccess" ) ) }; + for ( size_t i = 0; i < sizeof(pProps)/sizeof(pProps[0]); ++i ) + xName->removeByName( pProps[i] ); + } + } + catch (const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + DBG_DTOR(FmPropBrw,NULL); +} + +//----------------------------------------------------------------------- +::rtl::OUString FmPropBrw::getCurrentPage() const +{ + ::rtl::OUString sCurrentPage; + try + { + if ( m_xBrowserController.is() ) + { + OSL_VERIFY( m_xBrowserController->getViewData() >>= sCurrentPage ); + } + + if ( !sCurrentPage.getLength() ) + sCurrentPage = m_sLastActivePage; + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::getCurrentPage: 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(NULL, NULL); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::implDetachController: 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 + // 96068 - 09.01.2002 - fs@openoffice.org + if ( m_xBrowserController.is() ) + m_xBrowserController->attachFrame( NULL ); + + m_xBrowserController.clear(); + m_xInspectorModel.clear(); + m_xMeAsFrame.clear(); +} + +//----------------------------------------------------------------------- +sal_Bool 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( sal_True ) ) + return sal_False; + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::Close: caught an exception while asking the controller!" ); + } + } + + implDetachController(); + + if( IsRollUp() ) + RollDown(); + + // 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(); + + sal_Bool bClose = SfxFloatingWindow::Close(); + + if (bClose) + { + rBindings.Invalidate(SID_FM_CTL_PROPERTIES); + rBindings.Invalidate(SID_FM_PROPERTIES); + } + + return bClose; +} + +//----------------------------------------------------------------------- +bool FmPropBrw::implIsReadOnlyModel() const +{ + try + { + if ( m_xInspectorModel.is() ) + return m_xInspectorModel->getIsReadOnly(); + return false; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return true; +} + +//----------------------------------------------------------------------- +void FmPropBrw::implSetNewSelection( const InterfaceBag& _rSelection ) +{ + if ( m_xBrowserController.is() ) + { + try + { + Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW ); + + // tell it the objects to inspect + Sequence< Reference< XInterface > > aSelection( _rSelection.size() ); + ::std::copy( _rSelection.begin(), _rSelection.end(), aSelection.getArray() ); + + xInspector->inspect( aSelection ); + } + catch( const VetoException& ) + { + return; + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::implSetNewSelection: caught an unexpected exception!" ); + return; + } + + // set the new title according to the selected object + String sTitle; + + if ( _rSelection.empty() ) + { + sTitle = String( SVX_RES( RID_STR_NO_PROPERTIES ) ); + } + else if ( _rSelection.size() > 1 ) + { + // no form component and (no form or no name) -> Multiselection + sTitle = String( SVX_RES( RID_STR_PROPERTIES_CONTROL ) ); + sTitle += String( SVX_RES( 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 = String( SVX_RES( RID_STR_PROPERTIES_CONTROL ) ); + sTitle += String( GetUIHeadlineName( nClassID, makeAny( xSingleSelection ) ) ); + } + else if ( Reference< XForm >( xSingleSelection, UNO_QUERY ).is() ) + sTitle = String( SVX_RES( RID_STR_PROPERTIES_FORM ) ); + } + + if ( implIsReadOnlyModel() ) + sTitle += String( SVX_RES( RID_STR_READONLY_VIEW ) ); + + SetText( sTitle ); + + // #95343# --------------------------------- + Reference< ::com::sun::star::awt::XLayoutConstrains > xLayoutConstrains( m_xBrowserController, UNO_QUERY ); + if( xLayoutConstrains.is() ) + { + ::Size aConstrainedSize; + ::com::sun::star::awt::Size aMinSize = xLayoutConstrains->getMinimumSize(); + + sal_Int32 nLeft(0), nTop(0), nRight(0), nBottom(0); + GetBorder( nLeft, nTop, nRight, nBottom ); + aMinSize.Width += nLeft + nRight + 8; + aMinSize.Height += nTop + nBottom + 8; + + aConstrainedSize.setHeight( aMinSize.Height ); + aConstrainedSize.setWidth( aMinSize.Width ); + SetMinOutputSizePixel( aConstrainedSize ); + aConstrainedSize = GetOutputSizePixel(); + sal_Bool bResize = sal_False; + if( aConstrainedSize.Width() < aMinSize.Width ) + { + aConstrainedSize.setWidth( aMinSize.Width ); + bResize = sal_True; + } + if( aConstrainedSize.Height() < aMinSize.Height ) + { + aConstrainedSize.setHeight( aMinSize.Height ); + bResize = sal_True; + } + if( bResize ) + SetOutputSizePixel( aConstrainedSize ); + } + } +} + +//----------------------------------------------------------------------- +void FmPropBrw::FillInfo( SfxChildWinInfo& rInfo ) const +{ + rInfo.bVisible = sal_False; + rInfo.aExtraString = getCurrentPage(); +} + +//----------------------------------------------------------------------- +IMPL_LINK( FmPropBrw, OnAsyncGetFocus, void*, /*NOTINTERESTEDIN*/ ) +{ + if (m_xBrowserComponentWindow.is()) + m_xBrowserComponentWindow->setFocus(); + return 0L; +} + +//----------------------------------------------------------------------- +namespace +{ + static bool lcl_shouldEnableHelpSection( const Reference< XMultiServiceFactory >& _rxFactory ) + { + const ::rtl::OUString sConfigName( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Forms/PropertyBrowser/" ) ); + const ::rtl::OUString sPropertyName( RTL_CONSTASCII_USTRINGPARAM( "DirectHelp" ) ); + + ::utl::OConfigurationTreeRoot aConfiguration( + ::utl::OConfigurationTreeRoot::createWithServiceFactory( _rxFactory, sConfigName ) ); + + bool bEnabled = false; + OSL_VERIFY( aConfiguration.getNodeValue( sPropertyName ) >>= 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(0L); + + if(pPageWindow) + { + xControlContext = pPageWindow->GetControlContainer(); + } + } + } + + // the default parent window for message boxes + Reference< XWindow > xParentWindow( VCLUnoHelper::GetInterface ( this ) ); + + // the mapping from control models to control shapes + Reference< XMap > xControlMap; + FmFormPage* pFormPage = _pFormShell ? _pFormShell->GetCurPage() : NULL; + if ( pFormPage ) + xControlMap = pFormPage->GetImpl().getControlToShapeMap(); + + // our own component context + Reference< XPropertySet > xFactoryProperties( m_xORB, UNO_QUERY_THROW ); + Reference< XComponentContext > xOwnContext( + xFactoryProperties->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ), + UNO_QUERY_THROW ); + + // a ComponentContext for the + ::cppu::ContextEntry_Init aHandlerContextInfo[] = + { + ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ContextDocument" ) ), makeAny( xDocument ) ), + ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DialogParentWindow" ) ), makeAny( xParentWindow ) ), + ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlContext" ) ), makeAny( xControlContext ) ), + ::cppu::ContextEntry_Init( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ControlShapeAccess" ) ), makeAny( xControlMap ) ) + }; + m_xInspectorContext.set( + ::cppu::createComponentContext( aHandlerContextInfo, sizeof( aHandlerContextInfo ) / sizeof( aHandlerContextInfo[0] ), + xOwnContext ) ); + + 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 = m_xBrowserController.query( + ObjectInspector::createWithModel( + m_xInspectorContext, m_xInspectorModel + ) ); + + if ( !m_xBrowserController.is() ) + { + ::rtl::OUString sServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.inspection.ObjectInspector" ) ); + ShowServiceNotAvailableError( GetParent(), sServiceName, sal_True ); + } + else + { + m_xBrowserController->attachFrame( m_xMeAsFrame ); + m_xBrowserComponentWindow = m_xMeAsFrame->getComponentWindow(); + DBG_ASSERT( m_xBrowserComponentWindow.is(), "FmPropBrw::impl_createPropertyBrowser_throw: attached the controller, but have no component window!" ); + } + + if ( bEnableHelpSection ) + { + Reference< XObjectInspector > xInspector( m_xBrowserController, UNO_QUERY_THROW ); + Reference< XObjectInspectorUI > xInspectorUI( xInspector->getInspectorUI() ); + Reference< XInterface > xDefaultHelpProvider( 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() : NULL; + 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( NULL, NULL ); + else + ::comphelper::disposeComponent( m_xBrowserController ); + m_xBrowserController.clear(); + m_xInspectorModel.clear(); + m_xBrowserComponentWindow.clear(); + + // and create a new one + impl_createPropertyBrowser_throw( _pFormShell ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + m_xLastKnownDocument = xDocument; +} + +//----------------------------------------------------------------------- +void FmPropBrw::StateChanged(sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState) +{ + if (!pState || SID_FM_PROPERTY_CONTROL != nSID) + return; + + m_bInStateChange = true; + try + { + if (eState >= SFX_ITEM_AVAILABLE) + { + FmFormShell* pShell = PTR_CAST(FmFormShell,((SfxObjectItem*)pState)->GetShell()); + InterfaceBag aSelection; + if ( pShell ) + pShell->GetImpl()->getCurrentSelection( 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 + PostUserEvent( LINK( this, FmPropBrw, OnAsyncGetFocus ) ); + + // and additionally, we want to show the page which was active during + // our previous incarnation + if ( m_sLastActivePage.getLength() ) + { + try + { + if ( m_xBrowserController.is() ) + m_xBrowserController->restoreViewData( makeAny( m_sLastActivePage ) ); + } + catch( const Exception& ) + { + OSL_ENSURE( sal_False, "FmPropBrw::StateChanged: caught an exception while setting the initial page!" ); + } + } + + m_bInitialStateChange = sal_False; + } + + } + else + { + implSetNewSelection( InterfaceBag() ); + } + } + catch (Exception&) + { + DBG_ERROR("FmPropBrw::StateChanged: Exception occured!"); + } + m_bInStateChange = false; +} |