diff options
Diffstat (limited to 'binfilter/bf_forms/source/component/forms_GroupManager.cxx')
-rw-r--r-- | binfilter/bf_forms/source/component/forms_GroupManager.cxx | 465 |
1 files changed, 465 insertions, 0 deletions
diff --git a/binfilter/bf_forms/source/component/forms_GroupManager.cxx b/binfilter/bf_forms/source/component/forms_GroupManager.cxx new file mode 100644 index 000000000000..a2ddb769ed83 --- /dev/null +++ b/binfilter/bf_forms/source/component/forms_GroupManager.cxx @@ -0,0 +1,465 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * 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. + * + ************************************************************************/ + +#include "GroupManager.hxx" +#include "DatabaseForm.hxx" + + +#include <comphelper/property.hxx> + +#include <tools/solar.h> + +#include "property.hrc" + +#include <algorithm> +namespace binfilter { + +//......................................................................... +namespace frm +{ +//......................................................................... + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::sdbcx; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; + +//======================================================================== +// class OGroupCompAcc +//======================================================================== +//------------------------------------------------------------------ +OGroupCompAcc::OGroupCompAcc(const Reference<XPropertySet>& rxElement, const OGroupComp& _rGroupComp ) + :m_xComponent( rxElement ) + ,m_aGroupComp( _rGroupComp ) +{ +} + +//------------------------------------------------------------------ +sal_Bool OGroupCompAcc::operator==( const OGroupCompAcc& rCompAcc ) const +{ + return (m_xComponent == rCompAcc.GetComponent()); +} + +//------------------------------------------------------------------ +class OGroupCompAccLess : public ::std::binary_function<OGroupCompAcc, OGroupCompAcc, sal_Bool> +{ +public: + sal_Bool operator() (const OGroupCompAcc& lhs, const OGroupCompAcc& rhs) const + { + return + reinterpret_cast<sal_Int64>(lhs.m_xComponent.get()) + < reinterpret_cast<sal_Int64>(rhs.m_xComponent.get()); + } +}; + +//======================================================================== +// class OGroupComp +//======================================================================== + +//------------------------------------------------------------------ +OGroupComp::OGroupComp() + :m_nTabIndex( 0 ) + ,m_nPos( -1 ) +{ +} + +//------------------------------------------------------------------ +OGroupComp::OGroupComp(const OGroupComp& _rSource) + :m_aName( _rSource.m_aName ) + ,m_xComponent( _rSource.m_xComponent ) + ,m_nTabIndex( _rSource.m_nTabIndex ) + ,m_nPos( _rSource.m_nPos ) + ,m_xControlModel(_rSource.m_xControlModel) +{ +} + +//------------------------------------------------------------------ +OGroupComp::OGroupComp(const Reference<XPropertySet>& rxSet, sal_Int32 nInsertPos ) + :m_xComponent( rxSet ) + ,m_nTabIndex(0) + ,m_nPos( nInsertPos ) + ,m_xControlModel(rxSet,UNO_QUERY) +{ + if (m_xComponent.is()) + { + if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) ) + // Indices kleiner 0 werden wie 0 behandelt + m_nTabIndex = Max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0)); + + m_xComponent->getPropertyValue( PROPERTY_NAME ) >>= m_aName; + } +} + +//------------------------------------------------------------------ +sal_Bool OGroupComp::operator==( const OGroupComp& rComp ) const +{ + return m_nTabIndex == rComp.GetTabIndex() && m_nPos == rComp.GetPos(); +} + +//------------------------------------------------------------------ +class OGroupCompLess : public ::std::binary_function<OGroupComp, OGroupComp, sal_Bool> +{ +public: + sal_Bool operator() (const OGroupComp& lhs, const OGroupComp& rhs) const + { + sal_Bool bResult; + // TabIndex von 0 wird hinten einsortiert + if (lhs.m_nTabIndex == rhs.GetTabIndex()) + bResult = lhs.m_nPos < rhs.GetPos(); + else if (lhs.m_nTabIndex && rhs.GetTabIndex()) + bResult = lhs.m_nTabIndex < rhs.GetTabIndex(); + else + bResult = lhs.m_nTabIndex != 0; + return bResult; + } +}; + +//======================================================================== +// class OGroup +//======================================================================== + +DBG_NAME(OGroup) +//------------------------------------------------------------------ +OGroup::OGroup( const ::rtl::OUString& rGroupName ) + :m_aGroupName( rGroupName ) + ,m_nInsertPos(0) +{ + DBG_CTOR(OGroup,NULL); +} + +#ifdef DBG_UTIL +//------------------------------------------------------------------ +OGroup::OGroup( const OGroup& _rSource ) + :m_aGroupName(_rSource.m_aGroupName) + ,m_nInsertPos(_rSource.m_nInsertPos) + ,m_aCompArray(_rSource.m_aCompArray) + ,m_aCompAccArray(_rSource.m_aCompAccArray) +{ + DBG_CTOR(OGroup,NULL); +} +#endif + +//------------------------------------------------------------------ +OGroup::~OGroup() +{ + DBG_DTOR(OGroup,NULL); +} + +//------------------------------------------------------------------ +void OGroup::InsertComponent( const Reference<XPropertySet>& xSet ) +{ + OGroupComp aNewGroupComp( xSet, m_nInsertPos ); + sal_Int32 nPosInserted = insert_sorted(m_aCompArray, aNewGroupComp, OGroupCompLess()); + + OGroupCompAcc aNewGroupCompAcc( xSet, m_aCompArray[nPosInserted] ); + insert_sorted(m_aCompAccArray, aNewGroupCompAcc, OGroupCompAccLess()); + m_nInsertPos++; +} + +//------------------------------------------------------------------ +void OGroup::RemoveComponent( const Reference<XPropertySet>& rxElement ) +{ + sal_Int32 nGroupCompAccPos; + OGroupCompAcc aSearchCompAcc( rxElement, OGroupComp() ); + if ( seek_entry(m_aCompAccArray, aSearchCompAcc, nGroupCompAccPos, OGroupCompAccLess()) ) + { + OGroupCompAcc& aGroupCompAcc = m_aCompAccArray[nGroupCompAccPos]; + const OGroupComp& aGroupComp = aGroupCompAcc.GetGroupComponent(); + + sal_Int32 nGroupCompPos; + if ( seek_entry(m_aCompArray, aGroupComp, nGroupCompPos, OGroupCompLess()) ) + { + m_aCompAccArray.erase( m_aCompAccArray.begin() + nGroupCompAccPos ); + m_aCompArray.erase( m_aCompArray.begin() + nGroupCompPos ); + + /*============================================================ + Durch das Entfernen der GroupComp ist die Einfuegeposition + ungueltig geworden. Sie braucht hier aber nicht angepasst werden, + da sie fortlaufend vergeben wird und damit immer + aufsteigend eindeutig ist. + ============================================================*/ + } + else + { + DBG_ERROR( "OGroup::RemoveComponent: Component nicht in Gruppe" ); + } + } + else + { + DBG_ERROR( "OGroup::RemoveComponent: Component nicht in Gruppe" ); + } +} + +//------------------------------------------------------------------ +sal_Bool OGroup::operator==( const OGroup& rGroup ) const +{ + return m_aGroupName.equals(rGroup.GetGroupName()); +} + +//------------------------------------------------------------------ +class OGroupLess : public ::std::binary_function<OGroup, OGroup, sal_Bool> +{ +public: + sal_Bool operator() (const OGroup& lhs, const OGroup& rhs) const + { + return lhs.m_aGroupName < rhs.m_aGroupName; + } +}; + +//------------------------------------------------------------------ +Sequence< Reference<XControlModel> > OGroup::GetControlModels() const +{ + sal_Int32 nLen = m_aCompArray.size(); + Sequence<Reference<XControlModel> > aControlModelSeq( nLen ); + Reference<XControlModel>* pModels = aControlModelSeq.getArray(); + + ConstOGroupCompArrIterator aGroupComps = m_aCompArray.begin(); + for (sal_Int32 i = 0; i < nLen; ++i, ++pModels, ++aGroupComps) + { + *pModels = aGroupComps->GetControlModel(); + } + return aControlModelSeq; +} + +DBG_NAME(OGroupManager) +//------------------------------------------------------------------ +OGroupManager::OGroupManager(const Reference< XContainer >& _rxContainer) + :m_pCompGroup(new OGroup(ALL_COMPONENTS_GROUP_NAME)) + ,m_xContainer(_rxContainer) +{ + DBG_CTOR(OGroupManager,NULL); + + increment(m_refCount); + { + _rxContainer->addContainerListener(this); + } + decrement(m_refCount); +} + +//------------------------------------------------------------------ +OGroupManager::~OGroupManager() +{ + DBG_DTOR(OGroupManager,NULL); + // Alle Components und CompGroup loeschen + delete m_pCompGroup; +} + +// XPropertyChangeListener +//------------------------------------------------------------------ +void OGroupManager::disposing(const EventObject& evt) throw( RuntimeException ) +{ + Reference<XContainer> xContainer(evt.Source, UNO_QUERY); + if (xContainer.get() == m_xContainer.get()) + { + DELETEZ(m_pCompGroup); + + //////////////////////////////////////////////////////////////// + // Gruppen loeschen + m_aGroupArr.clear(); + m_xContainer.clear(); + } +} +// ----------------------------------------------------------------------------- +void OGroupManager::removeFromGroupMap(const ::rtl::OUString& _sGroupName,const Reference<XPropertySet>& _xSet) +{ + // Component aus CompGroup entfernen + m_pCompGroup->RemoveComponent( _xSet ); + + OGroupArr::iterator aFind = m_aGroupArr.find(_sGroupName); + + if ( aFind != m_aGroupArr.end() ) + { + // Gruppe vorhanden + aFind->second.RemoveComponent( _xSet ); + + // Wenn Anzahl der Gruppenelemente == 1 ist, Gruppe deaktivieren + if ( aFind->second.Count() == 1 ) + { + OActiveGroups::iterator aActiveFind = ::std::find(m_aActiveGroupMap.begin(),m_aActiveGroupMap.end(),aFind); + if ( aActiveFind != m_aActiveGroupMap.end() ) + m_aActiveGroupMap.erase(aActiveFind); + } + } + + + // Bei Component als PropertyChangeListener abmelden + _xSet->removePropertyChangeListener( PROPERTY_NAME, this ); + if (hasProperty(PROPERTY_TABINDEX, _xSet)) + _xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this ); +} +//------------------------------------------------------------------ +void SAL_CALL OGroupManager::propertyChange(const PropertyChangeEvent& evt) throw ( ::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xSet(evt.Source, UNO_QUERY); + + // Component aus Gruppe entfernen + ::rtl::OUString sGroupName; + if (evt.PropertyName == PROPERTY_NAME) + evt.OldValue >>= sGroupName; + else + xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName; + + removeFromGroupMap(sGroupName,xSet); + + // Component neu einordnen + InsertElement( xSet ); +} + +// XContainerListener +//------------------------------------------------------------------ +void SAL_CALL OGroupManager::elementInserted(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException) +{ + Reference< XPropertySet > xProps; + Event.Element >>= xProps; + if ( xProps.is() ) + InsertElement( xProps ); +} + +//------------------------------------------------------------------ +void SAL_CALL OGroupManager::elementRemoved(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xProps; + Event.Element >>= xProps; + if ( xProps.is() ) + RemoveElement( xProps ); +} + +//------------------------------------------------------------------ +void SAL_CALL OGroupManager::elementReplaced(const ContainerEvent& Event) throw ( ::com::sun::star::uno::RuntimeException) +{ + Reference<XPropertySet> xProps; + Event.ReplacedElement >>= xProps; + if ( xProps.is() ) + RemoveElement( xProps ); + + xProps.clear(); + Event.Element >>= xProps; + if ( xProps.is() ) + InsertElement( xProps ); +} + +// Other functions +//------------------------------------------------------------------ +Sequence<Reference<XControlModel> > OGroupManager::getControlModels() +{ + return m_pCompGroup->GetControlModels(); +} + +//------------------------------------------------------------------ +sal_Int32 OGroupManager::getGroupCount() +{ + return m_aActiveGroupMap.size(); +} + +//------------------------------------------------------------------ +void OGroupManager::getGroup(sal_Int32 nGroup, Sequence< Reference<XControlModel> >& _rGroup, ::rtl::OUString& _rName) +{ + OSL_ENSURE(nGroup >= 0 && nGroup < m_aActiveGroupMap.size(),"OGroupManager::getGroup: Invalid group index!"); + OGroupArr::iterator aGroupPos = m_aActiveGroupMap[nGroup]; + _rName = aGroupPos->second.GetGroupName(); + _rGroup = aGroupPos->second.GetControlModels(); +} + +//------------------------------------------------------------------ +void OGroupManager::getGroupByName(const ::rtl::OUString& _rName, Sequence< Reference<XControlModel> >& _rGroup) +{ + OGroupArr::iterator aFind = m_aGroupArr.find(_rName); + if ( aFind != m_aGroupArr.end() ) + _rGroup = aFind->second.GetControlModels(); +} + +//------------------------------------------------------------------ +void OGroupManager::InsertElement( const Reference<XPropertySet>& xSet ) +{ + // Nur ControlModels + Reference<XControlModel> xControl(xSet, UNO_QUERY); + if (!xControl.is() ) + return; + + // Component in CompGroup aufnehmen + m_pCompGroup->InsertComponent( xSet ); + + // Component in Gruppe aufnehmen + ::rtl::OUString sGroupName; + xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName; + + OGroupArr::iterator aFind = m_aGroupArr.find(sGroupName); + + if ( aFind == m_aGroupArr.end() ) + { + aFind = m_aGroupArr.insert(OGroupArr::value_type(sGroupName,OGroup(sGroupName))).first; + } + + aFind->second.InsertComponent( xSet ); + + + // Wenn Anzahl der Gruppenelemente == 2 ist, Gruppe aktivieren + if ( aFind->second.Count() == 2 ) + { + m_aActiveGroupMap.push_back( aFind ); + } + + + // Bei Component als PropertyChangeListener anmelden + xSet->addPropertyChangeListener( PROPERTY_NAME, this ); + + // Tabindex muss nicht jeder unterstuetzen + if (hasProperty(PROPERTY_TABINDEX, xSet)) + xSet->addPropertyChangeListener( PROPERTY_TABINDEX, this ); + +} + +//------------------------------------------------------------------ +void OGroupManager::RemoveElement( const Reference<XPropertySet>& xSet ) +{ + // Nur ControlModels + Reference<XControlModel> xControl(xSet, UNO_QUERY); + if (!xControl.is() ) + return; + + // Component aus Gruppe entfernen + ::rtl::OUString sGroupName; + xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName; + + removeFromGroupMap(sGroupName,xSet); +} + +//......................................................................... +} // namespace frm +//......................................................................... + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |