Files
loongoffice/forms/source/component/GroupManager.cxx
Stephan Bergmann e57ca02849 Remove dynamic exception specifications
...(for now, from LIBO_INTERNAL_CODE only).  See the mail thread starting at
<https://lists.freedesktop.org/archives/libreoffice/2017-January/076665.html>
"Dynamic Exception Specifications" for details.

Most changes have been done automatically by the rewriting loplugin:dynexcspec
(after enabling the rewriting mode, to be committed shortly).  The way it only
removes exception specs from declarations if it also sees a definition, it
identified some dead declarations-w/o-definitions (that have been removed
manually) and some cases where a definition appeared in multiple include files
(which have also been cleaned up manually).  There's also been cases of macro
paramters (that were used to abstract over exception specs) that have become
unused now (and been removed).

Furthermore, some code needed to be cleaned up manually
(avmedia/source/quicktime/ and connectivity/source/drivers/kab/), as I had no
configurations available that would actually build that code.  Missing @throws
documentation has not been applied in such manual clean-up.

Change-Id: I3408691256c9b0c12bc5332de976743626e13960
Reviewed-on: https://gerrit.libreoffice.org/33574
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2017-01-26 12:54:43 +00:00

436 lines
14 KiB
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 "GroupManager.hxx"
#include <com/sun/star/beans/XFastPropertySet.hpp>
#include <com/sun/star/form/FormComponentType.hpp>
#include <comphelper/property.hxx>
#include <osl/diagnose.h>
#include <tools/solar.h>
#include "property.hrc"
#include <algorithm>
namespace frm
{
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::sdbc;
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::lang;
namespace
{
bool isRadioButton( const Reference< XPropertySet >& _rxComponent )
{
bool bIs = false;
if ( hasProperty( PROPERTY_CLASSID, _rxComponent ) )
{
sal_Int16 nClassId = FormComponentType::CONTROL;
_rxComponent->getPropertyValue( PROPERTY_CLASSID ) >>= nClassId;
if ( nClassId == FormComponentType::RADIOBUTTON )
bIs = true;
}
return bIs;
}
}
OGroupCompAcc::OGroupCompAcc(const Reference<XPropertySet>& rxElement, const OGroupComp& _rGroupComp )
:m_xComponent( rxElement )
,m_aGroupComp( _rGroupComp )
{
}
bool OGroupCompAcc::operator==( const OGroupCompAcc& rCompAcc ) const
{
return m_xComponent == rCompAcc.m_xComponent;
}
class OGroupCompAccLess : public ::std::binary_function<OGroupCompAcc, OGroupCompAcc, sal_Bool>
{
public:
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());
}
};
OGroupComp::OGroupComp()
:m_nPos( -1 )
,m_nTabIndex( 0 )
{
}
OGroupComp::OGroupComp(const OGroupComp& _rSource)
:m_xComponent( _rSource.m_xComponent )
,m_xControlModel(_rSource.m_xControlModel)
,m_nPos( _rSource.m_nPos )
,m_nTabIndex( _rSource.m_nTabIndex )
{
}
OGroupComp::OGroupComp(const Reference<XPropertySet>& rxSet, sal_Int32 nInsertPos )
: m_xComponent( rxSet )
, m_xControlModel(rxSet,UNO_QUERY)
, m_nPos( nInsertPos )
, m_nTabIndex(0)
{
if (m_xComponent.is())
{
if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) )
// Indices smaller than 0 are treated like 0
m_nTabIndex = std::max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0));
}
}
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:
bool operator() (const OGroupComp& lhs, const OGroupComp& rhs) const
{
bool bResult;
// TabIndex of 0 will be added at the end
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;
}
};
OGroup::OGroup( const OUString& rGroupName )
:m_aGroupName( rGroupName )
,m_nInsertPos(0)
{
}
OGroup::~OGroup()
{
}
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 );
/*
* By removing the GroupComp the insertion position has become invalid.
* We do not to change it here, however, because its passed on continuously
* and ascending distinctively.
*/
}
else
{
OSL_FAIL( "OGroup::RemoveComponent: Component not in Group" );
}
}
else
{
OSL_FAIL( "OGroup::RemoveComponent: Component not in Group" );
}
}
Sequence< Reference<XControlModel> > OGroup::GetControlModels() const
{
sal_Int32 nLen = m_aCompArray.size();
Sequence<Reference<XControlModel> > aControlModelSeq( nLen );
Reference<XControlModel>* pModels = aControlModelSeq.getArray();
OGroupCompArr::const_iterator aGroupComps = m_aCompArray.begin();
for (sal_Int32 i = 0; i < nLen; ++i, ++pModels, ++aGroupComps)
{
*pModels = aGroupComps->GetControlModel();
}
return aControlModelSeq;
}
OGroupManager::OGroupManager(const Reference< XContainer >& _rxContainer)
:m_pCompGroup( new OGroup( OUString("AllComponentGroup") ) )
,m_xContainer(_rxContainer)
{
osl_atomic_increment(&m_refCount);
{
_rxContainer->addContainerListener(this);
}
osl_atomic_decrement(&m_refCount);
}
OGroupManager::~OGroupManager()
{
}
// XPropertyChangeListener
void OGroupManager::disposing(const EventObject& evt)
{
Reference<XContainer> xContainer(evt.Source, UNO_QUERY);
if (xContainer.get() == m_xContainer.get())
{
m_pCompGroup.reset();
// delete group
m_aGroupArr.clear();
m_xContainer.clear();
}
}
void OGroupManager::removeFromGroupMap(const OUString& _sGroupName,const Reference<XPropertySet>& _xSet)
{
// remove Component from CompGroup
m_pCompGroup->RemoveComponent( _xSet );
OGroupArr::iterator aFind = m_aGroupArr.find(_sGroupName);
if ( aFind != m_aGroupArr.end() )
{
// group exists
aFind->second.RemoveComponent( _xSet );
// If the count of Group elements == 1 -> deactivate Group
sal_Int32 nCount = aFind->second.Count();
if ( nCount == 1 || nCount == 0 )
{
OActiveGroups::iterator aActiveFind = ::std::find(
m_aActiveGroupMap.begin(),
m_aActiveGroupMap.end(),
aFind
);
if ( aActiveFind != m_aActiveGroupMap.end() )
{
// the group is active. Deactivate it if the remaining component
// is *no* radio button
if ( nCount == 0 || !isRadioButton( aFind->second.GetObject( 0 ) ) )
m_aActiveGroupMap.erase( aActiveFind );
}
}
}
// Deregister as PropertyChangeListener at Component
_xSet->removePropertyChangeListener( PROPERTY_NAME, this );
if (hasProperty(PROPERTY_GROUP_NAME, _xSet))
_xSet->removePropertyChangeListener( PROPERTY_GROUP_NAME, this );
if (hasProperty(PROPERTY_TABINDEX, _xSet))
_xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this );
}
void SAL_CALL OGroupManager::propertyChange(const PropertyChangeEvent& evt)
{
Reference<XPropertySet> xSet(evt.Source, UNO_QUERY);
// remove Component from group
OUString sGroupName;
if (hasProperty( PROPERTY_GROUP_NAME, xSet ))
xSet->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
if (evt.PropertyName == PROPERTY_NAME) {
if (!sGroupName.isEmpty())
return; // group hasn't changed; ignore this name change.
// no GroupName; use Name as GroupName
evt.OldValue >>= sGroupName;
}
else if (evt.PropertyName == PROPERTY_GROUP_NAME) {
evt.OldValue >>= sGroupName;
if (sGroupName.isEmpty()) {
// No prior GroupName; fallback to Nme
xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
}
}
else
sGroupName = GetGroupName( xSet );
removeFromGroupMap(sGroupName,xSet);
// Re-insert Component
InsertElement( xSet );
}
// XContainerListener
void SAL_CALL OGroupManager::elementInserted(const ContainerEvent& Event)
{
Reference< XPropertySet > xProps;
Event.Element >>= xProps;
if ( xProps.is() )
InsertElement( xProps );
}
void SAL_CALL OGroupManager::elementRemoved(const ContainerEvent& Event)
{
Reference<XPropertySet> xProps;
Event.Element >>= xProps;
if ( xProps.is() )
RemoveElement( xProps );
}
void SAL_CALL OGroupManager::elementReplaced(const ContainerEvent& Event)
{
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, OUString& _rName)
{
OSL_ENSURE(nGroup >= 0 && (size_t)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 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 )
{
// Only ControlModels
Reference<XControlModel> xControl(xSet, UNO_QUERY);
if (!xControl.is() )
return;
// Add Component to CompGroup
m_pCompGroup->InsertComponent( xSet );
// Add Component to Group
OUString sGroupName( GetGroupName( xSet ) );
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 );
// if we have at least 2 elements in the group, then this is an "active group"
bool bActivateGroup = aFind->second.Count() == 2;
// Additionally, if the component is a radio button, then it's group becomes active,
// too. With this, we ensure that in a container with n radio buttons which all are
// in different groups the selection still works reliably (means that all radios can be
// clicked independently)
if ( aFind->second.Count() == 1 )
{
if ( isRadioButton( xSet ) )
bActivateGroup = true;
}
if ( bActivateGroup )
{
OActiveGroups::iterator aAlreadyExistent = ::std::find(
m_aActiveGroupMap.begin(),
m_aActiveGroupMap.end(),
aFind
);
if ( aAlreadyExistent == m_aActiveGroupMap.end() )
m_aActiveGroupMap.push_back( aFind );
}
// Register as PropertyChangeListener at Component
xSet->addPropertyChangeListener( PROPERTY_NAME, this );
if (hasProperty(PROPERTY_GROUP_NAME, xSet))
xSet->addPropertyChangeListener( PROPERTY_GROUP_NAME, this );
// Not everyone needs to support Tabindex
if (hasProperty(PROPERTY_TABINDEX, xSet))
xSet->addPropertyChangeListener( PROPERTY_TABINDEX, this );
}
void OGroupManager::RemoveElement( const Reference<XPropertySet>& xSet )
{
// Only ControlModels
Reference<XControlModel> xControl(xSet, UNO_QUERY);
if (!xControl.is() )
return;
// Remove Component from Group
OUString sGroupName( GetGroupName( xSet ) );
removeFromGroupMap(sGroupName,xSet);
}
OUString OGroupManager::GetGroupName( const css::uno::Reference< css::beans::XPropertySet>& xComponent )
{
if (!xComponent.is())
return OUString();
OUString sGroupName;
if (hasProperty( PROPERTY_GROUP_NAME, xComponent )) {
xComponent->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
if (sGroupName.isEmpty())
xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
}
else
xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
return sGroupName;
}
} // namespace frm
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */