/************************************************************************* * * $RCSfile: propcontroller.cxx,v $ * * $Revision: 1.18 $ * * last change: $Author: fs $ $Date: 2002-01-09 14:01:46 $ * * The Contents of this file are made available subject to the terms of * either of the following licenses * * - GNU Lesser General Public License Version 2.1 * - Sun Industry Standards Source License Version 1.1 * * Sun Microsystems Inc., October, 2000 * * GNU Lesser General Public License Version 2.1 * ============================================= * Copyright 2000 by Sun Microsystems, Inc. * 901 San Antonio Road, Palo Alto, CA 94303, USA * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1, as published by the Free Software Foundation. * * This library 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 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * * Sun Industry Standards Source License Version 1.1 * ================================================= * The contents of this file are subject to the Sun Industry Standards * Source License Version 1.1 (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.openoffice.org/license.html. * * Software provided under this License is provided on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS, * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. * See the License for the specific provisions governing your rights and * obligations concerning the Software. * * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. * * Copyright: 2000 by Sun Microsystems, Inc. * * All Rights Reserved. * * Contributor(s): _______________________________________ * * ************************************************************************/ #ifndef _EXTENSIONS_PROPCTRLR_PROPCONTROLLER_HXX_ #include "propcontroller.hxx" #endif #ifndef _EXTENSIONS_FORMSCTRLR_PCRSTRINGS_HXX_ #include "pcrstrings.hxx" #endif #ifndef _TOOLS_DEBUG_HXX #include #endif #ifndef _COMPHELPER_TYPES_HXX_ #include #endif #ifndef _COMPHELPER_EXTRACT_HXX_ #include #endif #ifndef _CPPUHELPER_TYPEPROVIDER_HXX_ #include #endif #ifndef _EXTENSIONS_PROPCTRLR_PROPERTYEDITOR_HXX_ #include "propertyeditor.hxx" #endif #ifndef _EXTENSIONS_PROPCTRLR_PROPRESID_HRC_ #include "propresid.hrc" #endif #ifndef _EXTENSIONS_PROPCTRLR_PROPHELPID_HRC_ #include "prophelpid.hrc" #endif #ifndef _COM_SUN_STAR_BEANS_XINTROSPECTION_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_PROPERTYCONCEPT_HPP_ #include #endif #ifndef _COM_SUN_STAR_CONTAINER_XCHILD_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XFORM_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XFORMCOMPONENT_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XGRIDCOLUMNFACTORY_HPP_ #include #endif #ifndef _COM_SUN_STAR_FORM_XFORMCONTROLLER_HPP_ #include #endif #ifndef _COM_SUN_STAR_BEANS_PROPERTYATTRIBUTE_HPP_ #include #endif #ifndef _COM_SUN_STAR_AWT_XWINDOW_HPP_ #include #endif #ifndef _TOOLKIT_AWT_VCLXWINDOW_HXX_ #include #endif #ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_ #include #endif #ifndef _COMPHELPER_PROPERTY_HXX_ #include #endif #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_ #include "modulepcr.hxx" #endif #ifndef _EXTENSIONS_FORMSCTRLR_FORMSTRINGS_HXX_ #include "formstrings.hxx" #endif //------------------------------------------------------------------------ // !!! outside the namespace !!! extern "C" void SAL_CALL createRegistryInfo_OPropertyBrowserController() { static ::pcr::OMultiInstanceAutoRegistration< ::pcr::OPropertyBrowserController > aAutoRegistration; } //............................................................................ namespace pcr { //............................................................................ using namespace ::com::sun::star; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::awt; using namespace ::com::sun::star::form; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::script; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::container; using namespace ::com::sun::star::frame; using namespace ::comphelper; #define THISREF() static_cast< XController* >(this) //======================================================================== //= OPropertyBrowserController //======================================================================== DBG_NAME(OPropertyBrowserController) //------------------------------------------------------------------------ OPropertyBrowserController::OPropertyBrowserController(const Reference< XMultiServiceFactory >& _rxORB) :OPropertyChangeListener(m_aMutex) ,OPropertyBrowserController_PropertyBase1(m_aBHelper) ,m_xORB(_rxORB) ,m_aDisposeListeners(m_aMutex) ,m_pPropertyInfo(NULL) ,m_pChangeMultiplexer(NULL) ,m_pView(NULL) ,m_bHasListSource( sal_False ) ,m_bHasCursorSource( sal_False ) ,m_nGenericPageId(0) ,m_nDataPageId(0) ,m_nEventPageId(0) ,m_sStandard(ModuleRes(RID_STR_STANDARD)) ,m_bContainerFocusListening(sal_False) { DBG_CTOR(OPropertyBrowserController,NULL); if (m_xORB.is()) { m_xTypeConverter = Reference< XTypeConverter >( m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.script.Converter")), UNO_QUERY ); DBG_ASSERT(m_xTypeConverter.is(), "OPropertyBrowserController::OPropertyBrowserController: could not instantiate the type converter service!"); // TODO: perhaps an exception } initFormStuff(); registerProperty(PROPERTY_INTROSPECTEDOBJECT, OWN_PROPERTY_ID_INTROSPECTEDOBJECT, PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT, &m_xIntrospecteeAsProperty, ::getCppuType(&m_xIntrospecteeAsProperty)); registerProperty(PROPERTY_CURRENTPAGE, OWN_PROPERTY_ID_CURRENTPAGE, PropertyAttribute::BOUND | PropertyAttribute::TRANSIENT, &m_sPageSelection, ::getCppuType(&m_sPageSelection)); } //------------------------------------------------------------------------ OPropertyBrowserController::~OPropertyBrowserController() { deinitFormStuff(); // stop listening for property changes stopIntrospection(); DBG_DTOR(OPropertyBrowserController,NULL); } //------------------------------------------------------------------------ void OPropertyBrowserController::startContainerWindowListening() { if (m_bContainerFocusListening) return; if (m_xFrame.is()) { Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow(); if (xContainerWindow.is()) { xContainerWindow->addFocusListener(this); m_bContainerFocusListening = sal_True; } } DBG_ASSERT(m_bContainerFocusListening, "OPropertyBrowserController::startContainerWindowListening: unable to start listening (inconsistence)!"); } //------------------------------------------------------------------------ void OPropertyBrowserController::stopContainerWindowListening() { if (!m_bContainerFocusListening) return; if (m_xFrame.is()) { Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow(); if (xContainerWindow.is()) { xContainerWindow->removeFocusListener(this); m_bContainerFocusListening = sal_False; } } DBG_ASSERT(!m_bContainerFocusListening, "OPropertyBrowserController::stopContainerWindowListening: unable to stop listening (inconsistence)!"); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::attachFrame( const Reference< XFrame >& _rxFrame ) throw(RuntimeException) { if (_rxFrame.is() && haveView()) throw RuntimeException(::rtl::OUString::createFromAscii("Unable to attach to a second frame."),*this); // revoke as focus listener from the old container window stopContainerWindowListening(); m_xFrame = _rxFrame; if (!m_xFrame.is()) return; // TODO: this construction perhaps should be done outside. Don't know the exact meaning of attachFrame. // Maybe it is intended to only announce the frame to the controller, and the instance doing this // announcement is responsible for calling setComponent, too. Reference< XWindow > xContainerWindow = m_xFrame->getContainerWindow(); VCLXWindow* pContainerWindow = VCLXWindow::GetImplementation(xContainerWindow); Window* pParentWin = pContainerWindow ? pContainerWindow->GetWindow() : NULL; if (!pParentWin) throw RuntimeException(::rtl::OUString::createFromAscii("The frame is invalid. Unable to extract the container window."),*this); if (Construct(pParentWin)) m_xFrame->setComponent(VCLUnoHelper::GetInterface(m_pView), this); startContainerWindowListening(); } //------------------------------------------------------------------------ sal_Bool SAL_CALL OPropertyBrowserController::attachModel( const Reference< XModel >& xModel ) throw(RuntimeException) { DBG_ERROR("OPropertyBrowserController::attachModel: models not supported!"); return sal_False; } //------------------------------------------------------------------------ sal_Bool SAL_CALL OPropertyBrowserController::suspend( sal_Bool bSuspend ) throw(RuntimeException) { stopContainerWindowListening(); // TODO return sal_True; } //------------------------------------------------------------------------ Any SAL_CALL OPropertyBrowserController::getViewData( ) throw(RuntimeException) { // have no view data return Any(); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::restoreViewData( const Any& Data ) throw(RuntimeException) { // have no view data } //------------------------------------------------------------------------ Reference< XModel > SAL_CALL OPropertyBrowserController::getModel( ) throw(RuntimeException) { // have no model return Reference< XModel >(); } //------------------------------------------------------------------------ Reference< XFrame > SAL_CALL OPropertyBrowserController::getFrame( ) throw(RuntimeException) { return m_xFrame; } //------------------------------------------------------------------------ Any SAL_CALL OPropertyBrowserController::queryInterface( const Type& _rType ) throw(RuntimeException) { Any aReturn = OPropertyBrowserController_Base::queryInterface(_rType); if (!aReturn.hasValue()) aReturn = OPropertyBrowserController_PropertyBase1::queryInterface(_rType); return aReturn; } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::acquire( ) throw() { OPropertyBrowserController_Base::acquire(); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::release( ) throw() { OPropertyBrowserController_Base::release(); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::dispose( ) throw(RuntimeException) { // say our dispose listeners goodbye ::com::sun::star::lang::EventObject aEvt; aEvt.Source = static_cast< ::cppu::OWeakObject* >(this); m_aDisposeListeners.disposeAndClear(aEvt); if (haveView()) m_pView->setActiveController(NULL); // don't delete explicitly (this is done by the frame we reside in) m_pView = NULL; Reference< XComponent > xViewAsComp( m_xView, UNO_QUERY ); if ( xViewAsComp.is() ) xViewAsComp->removeEventListener( this ); m_xView.clear( ); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::addEventListener( const Reference< XEventListener >& _rxListener ) throw(RuntimeException) { m_aDisposeListeners.addInterface(_rxListener); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::removeEventListener( const Reference< XEventListener >& _rxListener ) throw(RuntimeException) { m_aDisposeListeners.removeInterface(_rxListener); } //------------------------------------------------------------------------ ::rtl::OUString SAL_CALL OPropertyBrowserController::getImplementationName( ) throw(RuntimeException) { return getImplementationName_Static(); } //------------------------------------------------------------------------ sal_Bool SAL_CALL OPropertyBrowserController::supportsService( const ::rtl::OUString& ServiceName ) throw(RuntimeException) { Sequence< ::rtl::OUString > aSupported(getSupportedServiceNames()); const ::rtl::OUString* pArray = aSupported.getConstArray(); for (sal_Int32 i = 0; i < aSupported.getLength(); ++i, ++pArray) if (pArray->equals(ServiceName)) return sal_True; return sal_False; } //------------------------------------------------------------------------ Sequence< ::rtl::OUString > SAL_CALL OPropertyBrowserController::getSupportedServiceNames( ) throw(RuntimeException) { return getSupportedServiceNames_Static(); } //------------------------------------------------------------------------ ::rtl::OUString OPropertyBrowserController::getImplementationName_Static( ) throw(RuntimeException) { return ::rtl::OUString::createFromAscii("org.openoffice.comp.form.ui.OPropertyBrowserController"); } //------------------------------------------------------------------------ Sequence< ::rtl::OUString > OPropertyBrowserController::getSupportedServiceNames_Static( ) throw(RuntimeException) { Sequence< ::rtl::OUString > aSupported(1); aSupported[0] = ::rtl::OUString::createFromAscii("com.sun.star.form.PropertyBrowserController"); return aSupported; } //------------------------------------------------------------------------ Reference< XInterface > SAL_CALL OPropertyBrowserController::Create(const Reference< XMultiServiceFactory >& _rxORB) { return static_cast(new OPropertyBrowserController(_rxORB)); } //------------------------------------------------------------------------ Sequence< Type > SAL_CALL OPropertyBrowserController::getTypes( ) throw(RuntimeException) { static ::cppu::OTypeCollection aTypes( ::getCppuType( static_cast< Reference< XPropertySet >* >(NULL) ), ::getCppuType( static_cast< Reference< XMultiPropertySet >* >(NULL) ), ::getCppuType( static_cast< Reference< XFastPropertySet >* >(NULL) ), OPropertyBrowserController_Base::getTypes()); return aTypes.getTypes(); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::focusGained( const FocusEvent& _rSource ) throw (RuntimeException) { Reference< XWindow > xSourceWindow(_rSource.Source, UNO_QUERY); Reference< XWindow > xContainerWindow; if (m_xFrame.is()) xContainerWindow = m_xFrame->getContainerWindow(); if (xContainerWindow.get() == xSourceWindow.get()) { // our container window got the focus if (getPropertyBox()) getPropertyBox()->GrabFocus(); } } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::focusLost( const FocusEvent& _rSource ) throw (RuntimeException) { // not interested in } //------------------------------------------------------------------------ awt::Size SAL_CALL OPropertyBrowserController::getMinimumSize( ) throw (RuntimeException) { return awt::Size( 250, 300 ); } //------------------------------------------------------------------------ awt::Size SAL_CALL OPropertyBrowserController::getPreferredSize( ) throw (RuntimeException) { return getMinimumSize( ); // TODO: depending on the strings we have on our current page } //------------------------------------------------------------------------ awt::Size SAL_CALL OPropertyBrowserController::calcAdjustedSize( const awt::Size& _rNewSize ) throw (RuntimeException) { awt::Size aMinSize = getMinimumSize( ); awt::Size aAdjustedSize( _rNewSize ); if ( aAdjustedSize.Width < aMinSize.Width ) aAdjustedSize.Width = aMinSize.Width; if ( aAdjustedSize.Height < aMinSize.Height ) aAdjustedSize.Height = aMinSize.Height; return aAdjustedSize; } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::disposing( const EventObject& _rSource ) throw(RuntimeException) { Reference< XWindow > xSourceWindow(_rSource.Source, UNO_QUERY); if (xSourceWindow.get() == m_xView.get()) { m_xView = NULL; m_pView = NULL; } #ifdef DBG_UTIL else { Reference< XWindow > xContainer; if (m_xFrame.is()) xContainer = m_xFrame->getContainerWindow(); DBG_ASSERT(xContainer.get() == xSourceWindow.get(), "OPropertyBrowserController::disposing: where does this come from?"); } #endif } //------------------------------------------------------------------------ Sequence< sal_Int8 > SAL_CALL OPropertyBrowserController::getImplementationId( ) throw(RuntimeException) { static ::cppu::OImplementationId aId; return aId.getImplementationId(); } //------------------------------------------------------------------------ Reference< XPropertySetInfo > SAL_CALL OPropertyBrowserController::getPropertySetInfo( ) throw(RuntimeException) { return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()); } //------------------------------------------------------------------------ ::cppu::IPropertyArrayHelper& SAL_CALL OPropertyBrowserController::getInfoHelper() { return *getArrayHelper(); } //------------------------------------------------------------------------ ::cppu::IPropertyArrayHelper* OPropertyBrowserController::createArrayHelper( ) const { Sequence< Property > aProps; describeProperties(aProps); return new cppu::OPropertyArrayHelper(aProps); } //------------------------------------------------------------------------ IMPL_LINK(OPropertyBrowserController, OnPageActivation, void*, EMPTYARG) { syncViewToProperty(); return 0L; } //------------------------------------------------------------------------ void OPropertyBrowserController::syncViewToProperty() { if (!haveView()) return; ::rtl::OUString sOldSelection = m_sPageSelection; m_sPageSelection = ::rtl::OUString(); const sal_uInt16 nCurrentPage = m_pView->getActivaPage(); if ((sal_uInt16)-1 != nCurrentPage) if (nCurrentPage == m_nGenericPageId) m_sPageSelection = ::rtl::OUString::createFromAscii("Generic"); else if (nCurrentPage == m_nDataPageId) m_sPageSelection = ::rtl::OUString::createFromAscii("Data"); else if (nCurrentPage == m_nEventPageId) m_sPageSelection = ::rtl::OUString::createFromAscii("Events"); if (sOldSelection != m_sPageSelection) { // fire the property change Any aOldValue; aOldValue <<= sOldSelection; Any aNewValue; aNewValue <<= m_sPageSelection; sal_Int32 nHandle = OWN_PROPERTY_ID_CURRENTPAGE; fire(&nHandle, &aNewValue, &aOldValue, 1, sal_False); } } //------------------------------------------------------------------------ void OPropertyBrowserController::syncPropertyToView() { sal_uInt16 nNewPage = (sal_uInt16)-1; if (0 == m_sPageSelection.compareToAscii("Generic")) nNewPage = m_nGenericPageId; else if (0 == m_sPageSelection.compareToAscii("Data")) nNewPage = m_nDataPageId; else if (0 == m_sPageSelection.compareToAscii("Events")) nNewPage = m_nEventPageId; if (haveView()) m_pView->activatePage(nNewPage); // just in case ... syncViewToProperty(); } //------------------------------------------------------------------------ void SAL_CALL OPropertyBrowserController::setFastPropertyValue_NoBroadcast(sal_Int32 _nHandle, const Any& _rValue) throw (Exception) { OPropertyBrowserController_PropertyBase1::setFastPropertyValue_NoBroadcast(_nHandle, _rValue); switch (_nHandle) { case OWN_PROPERTY_ID_INTROSPECTEDOBJECT: // it was my introspectee bindToObject(m_xIntrospecteeAsProperty); break; case OWN_PROPERTY_ID_CURRENTPAGE: syncPropertyToView(); break; } } //------------------------------------------------------------------------ sal_Bool OPropertyBrowserController::Construct(Window* _pParentWin) { DBG_ASSERT(!haveView(), "OPropertyBrowserController::Construct: already have a view!"); DBG_ASSERT(_pParentWin, "OPropertyBrowserController::Construct: invalid parent window!"); m_pView = new OPropertyBrowserView(m_xORB, _pParentWin); m_pView->setActiveController(this); m_pView->setPageActivationHandler(LINK(this, OPropertyBrowserController, OnPageActivation)); // add as dispose listener for our view. The view is disposed by the frame we're plugged into, // and this disposal _deletes_ the view, so it would be deadly if we use our m_pView member // after that m_xView = VCLUnoHelper::GetInterface(m_pView); Reference< XComponent > xViewAsComp(m_xView, UNO_QUERY); if (xViewAsComp.is()) xViewAsComp->addEventListener(this); if (haveView()) getPropertyBox()->SetLineListener(this); return sal_True; } //------------------------------------------------------------------------ void OPropertyBrowserController::_propertyChanged(const PropertyChangeEvent& _rEvent) throw( RuntimeException) { if (!haveView()) return; Property aProp = getIntrospecteeProperty(_rEvent.PropertyName); if (aProp.Name.getLength()) { DBG_ASSERT(aProp.Name == _rEvent.PropertyName, "OPropertyBrowserController::_propertyChanged: getIntrospecteeProperty returned nonsense!"); ::rtl::OUString sNewValue = AnyToString(_rEvent.NewValue, aProp, m_pPropertyInfo->getPropertyId(_rEvent.PropertyName)); getPropertyBox()->SetPropertyValue(_rEvent.PropertyName, sNewValue); } } //------------------------------------------------------------------------ void OPropertyBrowserController::_disposing(const EventObject& _rSource) throw( RuntimeException) { #ifdef DBG_UTIL Reference< XInterface > xIntrospectee; ::cppu::extractInterface(xIntrospectee, m_aIntrospectee); DBG_ASSERT( Reference< XInterface >(_rSource.Source, UNO_QUERY).get() == xIntrospectee.get(), "OPropertyBrowserController::_disposing: where does this come from?"); #endif bindToObject(Reference< XPropertySet >()); } //------------------------------------------------------------------------ void OPropertyBrowserController::startPropertyListening() { DBG_ASSERT(!isListening(), "OPropertyBrowserController::startPropertyListening: already listening!"); if (!isListening() && m_xPropValueAccess.is()) { m_pChangeMultiplexer = new OPropertyChangeMultiplexer(this, m_xPropValueAccess); m_pChangeMultiplexer->acquire(); m_pChangeMultiplexer->addProperty(::rtl::OUString()); } } //------------------------------------------------------------------------ void OPropertyBrowserController::stopPropertyListening() { DBG_ASSERT(isListening(), "OPropertyBrowserController::stopPropertyListening: not listening currently!"); if (isListening()) { m_pChangeMultiplexer->dispose(); m_pChangeMultiplexer->release(); m_pChangeMultiplexer = NULL; } } //------------------------------------------------------------------------ void OPropertyBrowserController::stopIntrospection() { // stop listening for property changes if (isListening()) stopPropertyListening(); // destroy the view first. So any pending commits can be done ... if (haveView()) { // remove the pages if (m_nGenericPageId) getPropertyBox()->RemovePage(m_nDataPageId); if (m_nDataPageId) getPropertyBox()->RemovePage(m_nDataPageId); if (m_nEventPageId) getPropertyBox()->RemovePage(m_nEventPageId); m_nGenericPageId = m_nDataPageId = m_nEventPageId = 0; } m_aIntrospectee.clear(); m_aObjectProperties.realloc(0); m_aObjectListenerTypes.realloc(0); m_xEventManager = NULL; m_xPropStateAccess = NULL; m_xPropValueAccess = NULL; m_xIntrospection = NULL; m_xObjectParent = NULL; m_nClassId = 0; m_bHasListSource = m_bHasCursorSource = sal_False; // and some heavily form specific stuff, again cleanupRowsetConnection(); } //------------------------------------------------------------------------ ::rtl::OUString OPropertyBrowserController::GetPropertyValue(const ::rtl::OUString& _rPropName) { ::rtl::OUString aStrVal; try { if (m_xPropValueAccess.is()) { Property aProp = getIntrospecteeProperty(_rPropName); DBG_ASSERT(aProp.Name.getLength(), "OPropertyBrowserController::GetPropertyValue: invalid property name!"); if (aProp.Name.getLength()) { Any aVal( m_xPropValueAccess->getPropertyValue(_rPropName ) ); aStrVal = AnyToString(aVal, aProp, m_pPropertyInfo->getPropertyId(_rPropName)); } } } catch (Exception&) { DBG_ERROR("OPropertyBrowserController::GetPropertyValue : caught an exception !"); } return aStrVal; } //------------------------------------------------------------------------ void OPropertyBrowserController::bindToObject(const Reference< XPropertySet >& _rxObject) { try { if (haveView()) { // hide the property box so that it does not flicker getPropertyBox()->Hide(); // clear the property box getPropertyBox()->ClearAll(); } // stop inspecting the old object stopIntrospection(); // TODO: notify the listeners that our object has been reset (to NULL, for the moment) // external instances may want to adjust the title to this new situation // TODO: the following is very form specific Reference< XForm > xForm(_rxObject, UNO_QUERY); Reference< XFormComponent > xControl(_rxObject, UNO_QUERY); Reference< XEventAttacherManager > xEvManager; if (haveView()) m_pView->SetHelpId(HID_FM_DLG_PROP_CONTROL); Any aAdditionalEvents; if (xForm.is()) { // it's a form. Create a (temporary) form controller for the additional events Reference< XFormController > xController(m_xORB->createInstance(SERVICE_FORMCONTROLLER), UNO_QUERY); xController->setModel(Reference< ::com::sun::star::awt::XTabControllerModel > (xForm,UNO_QUERY)); aAdditionalEvents <<= xController; // set the new object, do the inspections setObject(makeAny(xForm), aAdditionalEvents); if (haveView()) m_pView->SetHelpId(HID_FM_DLG_PROP_FORM); // now we do not need the controller anymore, it is just a helper ::comphelper::disposeComponent(xController); } else if (xControl.is()) { if (haveView()) m_pView->SetHelpId(HID_FM_DLG_PROP_CONTROL); setObject(makeAny(xControl), aAdditionalEvents); } else { // perhaps it's a grid column Reference< XGridColumnFactory > xGrid; Reference< XChild > xChild(_rxObject, UNO_QUERY); if (xChild.is()) xGrid = Reference< XGridColumnFactory > (xChild->getParent(),UNO_QUERY); if (xGrid.is()) { if (haveView()) m_pView->SetHelpId(HID_FM_DLG_PROP_GRIDCTR); setObject(makeAny(_rxObject), aAdditionalEvents); } else // it's something else setObject(makeAny(_rxObject), aAdditionalEvents); } // propagate the new object to our view // TODO: check whether or not the view really needs to know this if (haveView()) m_pView->setObject(_rxObject); // update the user interface if (haveObject()) UpdateUI(); // show the property box, again if (haveView()) { // activate a default page if (m_nGenericPageId) getPropertyBox()->SetPage( m_nGenericPageId ); else if (m_nDataPageId) getPropertyBox()->SetPage( m_nDataPageId ); else if (m_nEventPageId) getPropertyBox()->SetPage( m_nEventPageId ); syncViewToProperty(); getPropertyBox()->Show(); // activate the old page syncPropertyToView(); } } catch(Exception&) { DBG_ERROR("OPropertyBrowserController::bindToObject: caught an exception !"); } } //------------------------------------------------------------------------ sal_Bool OPropertyBrowserController::setObject(const ::com::sun::star::uno::Any& _rIntrospectee, const ::com::sun::star::uno::Any& _rControl) { try { ////////////////////////////////////////////////////////////////////// // get the introspection service Reference< XIntrospection > xIntrospection(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.beans.Introspection")), UNO_QUERY); if( !xIntrospection.is()) return sal_False; ////////////////////////////////////////////////////////////////////// // inspect the object m_xIntrospection = xIntrospection->inspect( _rIntrospectee ); if( !m_xIntrospection.is() ) return sal_False; ////////////////////////////////////////////////////////////////////// // remember the object m_aIntrospectee = _rIntrospectee; ////////////////////////////////////////////////////////////////////// // the other interfaces to the object or some of it's relatives ::cppu::extractInterface(m_xPropValueAccess, m_aIntrospectee); m_xPropStateAccess = Reference< XPropertyState >::query(m_xPropValueAccess); Reference< XChild > xChild(m_xPropValueAccess, UNO_QUERY); if(xChild.is()) { m_xObjectParent = Reference< XInterface >(xChild->getParent()); m_xEventManager = Reference< XEventAttacherManager > (m_xObjectParent, UNO_QUERY); } ////////////////////////////////////////////////////////////////////// // tell our property box we're the controller if (haveView()) { // add the page for the default properties m_nGenericPageId = getPropertyBox()->AppendPage( String(ModuleRes(RID_STR_PROPPAGE_DEFAULT)), HID_FM_PROPDLG_TAB_GENERAL); } ////////////////////////////////////////////////////////////////////// // get the properties, and sort them by relative pos Sequence< Property > aProperties(m_xIntrospection->getProperties(PropertyConcept::ALL)); // transfer all the props to a map DECLARE_STL_STDKEY_MAP( sal_Int32, Property, OrderedPropertyMap ); OrderedPropertyMap aSortProperties; const Property* pSourceProps = aProperties.getConstArray(); const Property* pSourcePropsEnd = pSourceProps + aProperties.getLength(); for (; pSourceProps < pSourcePropsEnd; ++pSourceProps) { sal_Int32 nRelativePosition = m_pPropertyInfo->getPropertyPos(m_pPropertyInfo->getPropertyId(pSourceProps->Name)); aSortProperties[nRelativePosition] = *pSourceProps; } // and copy them into the sequence, now that they're sorted m_aObjectProperties.realloc(aSortProperties.size()); Property* pCopyDest = m_aObjectProperties.getArray(); for ( ConstOrderedPropertyMapIterator aCopySource = aSortProperties.begin(); aCopySource != aSortProperties.end(); ++aCopySource, ++pCopyDest ) *pCopyDest = aCopySource->second; ////////////////////////////////////////////////////////////////////// // get the model and the control listeners Sequence< Type > aModelListeners; Sequence< Type > aControlListeners; aModelListeners = m_xIntrospection->getSupportedListeners(); // if we don't have a control, try to create one (temporarily) Reference< XInterface > xTemporaryControl; Any aControl(_rControl); if (!aControl.hasValue()) { try { ::rtl::OUString sControlService; if (m_xPropValueAccess.is()) m_xPropValueAccess->getPropertyValue(PROPERTY_DEFAULTCONTROL) >>= sControlService; xTemporaryControl = m_xORB->createInstance(sControlService); aControl <<= xTemporaryControl; } catch(Exception&) { } } // inspect the control for listeners if (aControl.hasValue()) { Reference< XIntrospection > xMVCIntrospection(m_xORB->createInstance(::rtl::OUString::createFromAscii("com.sun.star.beans.Introspection")), UNO_QUERY); Reference< XIntrospectionAccess > xAccess; if( xMVCIntrospection.is() ) xAccess = xMVCIntrospection->inspect(aControl); if (xAccess.is()) aControlListeners = xAccess->getSupportedListeners(); } // dispose the temporary control if (xTemporaryControl.is()) { ::comphelper::disposeComponent(xTemporaryControl); xTemporaryControl = NULL; } // merge the two lists // we use a set for this to avoid duplicates DECLARE_STL_SET( Type, TypeLessByName, TypeBag ); TypeBag aListenerCollection; // insert the model listeners const Type* pListenerLoop = aModelListeners.getConstArray(); const Type* pListenerLoopEnd = pListenerLoop + aModelListeners.getLength(); for (; pListenerLoop != pListenerLoopEnd; ++pListenerLoop) aListenerCollection.insert(*pListenerLoop); // insert the control listener pListenerLoop = aControlListeners.getConstArray(); pListenerLoopEnd = pListenerLoop + aControlListeners.getLength(); for (; pListenerLoop != pListenerLoopEnd; ++pListenerLoop) if (aListenerCollection.end() == aListenerCollection.find(*pListenerLoop)) aListenerCollection.insert(*pListenerLoop); // now that they're disambiguated, copy these types into our member m_aObjectListenerTypes.realloc(aListenerCollection.size()); { Type* aCopyDest = m_aObjectListenerTypes.getArray(); for ( ConstTypeBagIterator aCopySource = aListenerCollection.begin(); aCopySource != aListenerCollection.end(); ++aCopySource, ++aCopyDest ) *aCopyDest = *aCopySource; } // retrieve the class id of the introspectee (if appliable) // TODO: this is form dependent, again ... if (::comphelper::hasProperty(PROPERTY_CLASSID, m_xPropValueAccess)) m_nClassId = ::comphelper::getINT16(m_xPropValueAccess->getPropertyValue(PROPERTY_CLASSID)); else m_nClassId = 0; // start the listening for property changes startPropertyListening(); } catch(Exception&) { DBG_ERROR("OPropertyBrowserController::setObject : caught an exception !"); return sal_False; } // append the data page for the // TODO: this is form-specific if (haveView()) m_nDataPageId = getPropertyBox()->AppendPage( String(ModuleRes(RID_STR_PROPPAGE_DATA)), HID_FM_PROPDLG_TAB_DATA ); return sal_True; } //------------------------------------------------------------------------ sal_Int32 OPropertyBrowserController::GetStringPos(const String& _rEntry, const Sequence< ::rtl::OUString >& _rEntries) { const ::rtl::OUString* pStart = _rEntries.getConstArray(); const ::rtl::OUString* pEnd = pStart + _rEntries.getLength(); const ::rtl::OUString sCompare(_rEntry); for (const ::rtl::OUString* pEntries = pStart; pEntries != pEnd; ++pEntries) { if (sCompare == *pEntries) return pEntries - pStart; } return -1; } //------------------------------------------------------------------------ Property OPropertyBrowserController::getIntrospecteeProperty( const ::rtl::OUString& _rName ) { const Property* pStart = m_aObjectProperties.getConstArray(); const Property* pEnd = pStart + m_aObjectProperties.getLength(); for (const Property* pLoop = pStart; pLoop != pEnd; ++pLoop) { if (pLoop->Name == _rName) return *pLoop; } return Property(); } //------------------------------------------------------------------------ ::rtl::OUString OPropertyBrowserController::convertSimpleToString(const Any& _rValue) { ::rtl::OUString sReturn; if (m_xTypeConverter.is()) { // TODO: using the type converter every time is somewhat expensive, isn't it? try { Any aConvertedToString; aConvertedToString = m_xTypeConverter->convertToSimpleType(_rValue, TypeClass_STRING); aConvertedToString >>= sReturn; } catch(CannotConvertException&) { } catch(IllegalArgumentException&) { } } return sReturn; } //------------------------------------------------------------------------ sal_Int16 OPropertyBrowserController::getControlType() const { sal_Int16 nControlType = CONTROL_TYPE_UNKNOWN; if ( m_xIntrospecteeAsProperty.is() ) { Reference< XPropertySetInfo > xPropInfo = m_xIntrospecteeAsProperty->getPropertySetInfo(); if ( xPropInfo.is() ) { if ( xPropInfo->hasPropertyByName( PROPERTY_WIDTH ) && xPropInfo->hasPropertyByName( PROPERTY_HEIGHT ) && xPropInfo->hasPropertyByName( PROPERTY_POSITIONX ) && xPropInfo->hasPropertyByName( PROPERTY_POSITIONY ) ) { nControlType = CONTROL_TYPE_DIALOG; } else { nControlType = CONTROL_TYPE_FORM; } } } return nControlType; } //............................................................................ } // namespace pcr //............................................................................ /************************************************************************* * history: * $Log: not supported by cvs2svn $ * Revision 1.17 2001/12/13 09:14:26 fs * preparations for #95343# - support the XLayoutConstraints interface * * Revision 1.16 2001/10/19 12:58:51 tbe * #92755# Assign Standard Values for Basic Controls in Designmode * * Revision 1.15 2001/08/06 14:52:59 fs * #87690# don't set connections on rowsets permanently - instead dispose connections which we created ourself upon switching to a new object * * Revision 1.14 2001/06/11 11:33:04 fs * #86096# changed the implementation name for consistency * * Revision 1.13 2001/05/30 13:41:46 fs * #86838# be a focus listener on the container window, forward the focus to the property box * * Revision 1.12 2001/03/22 10:04:09 fs * when binding to a new object, _first_ destroy the view, _then_ stop listening * * Revision 1.11 2001/03/20 08:37:11 fs * #85148# when inspecting the control, care for a NULL access * * Revision 1.10 2001/03/15 09:02:28 fs * cppuhelper/extract -> comphelper/extract * * Revision 1.9 2001/02/23 15:08:45 tbe * AnyToString didn't get property id * * Revision 1.8 2001/02/20 08:50:31 fs * do a syncViewToProperty when selecting a page * * Revision 1.7 2001/02/19 16:56:58 fs * UpdateUI: do default page selection * * Revision 1.6 2001/02/19 14:08:05 fs * #83649# correctly eval the return value of getIntrospecteeProperty / #84041# infrastructure for activating pages from outside * * Revision 1.5 2001/02/05 08:58:27 fs * #83468# +m_nClassId * * Revision 1.4 2001/01/24 14:14:18 fs * bindToObject: pass non-form-related objects to setObject, too * * Revision 1.3 2001/01/18 14:45:10 rt * #65293# semicolon removed * * Revision 1.2 2001/01/12 14:44:49 fs * don't hold the form info service statically - caused problems 'cause it was the last ModuleResourceClient and destroyed upon unloaded the library * * Revision 1.1 2001/01/12 11:31:03 fs * initial checkin - outsourced the form property browser * * * Revision 1.0 08.01.01 09:33:47 fs ************************************************************************/