2010-10-12 15:57:08 +02:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
2012-11-21 22:06:52 +00:00
|
|
|
/*
|
|
|
|
* 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 .
|
|
|
|
*/
|
2000-09-18 15:33:13 +00:00
|
|
|
|
|
|
|
#include "GroupManager.hxx"
|
2003-12-01 09:15:40 +00:00
|
|
|
#include <com/sun/star/form/FormComponentType.hpp>
|
2000-10-19 10:52:20 +00:00
|
|
|
#include <comphelper/property.hxx>
|
2018-05-27 14:07:43 +02:00
|
|
|
#include <comphelper/types.hxx>
|
New loplugin:unsignedcompare
"Find explicit casts from signed to unsigned integer in comparison against
unsigned integer, where the cast is presumably used to avoid warnings about
signed vs. unsigned comparisons, and could thus be replaced with
o3tl::make_unsigned for clairty." (compilerplugins/clang/unsignedcompare.cxx)
o3tl::make_unsigned requires its argument to be non-negative, and there is a
chance that some original code like
static_cast<sal_uInt32>(n) >= c
used the explicit cast to actually force a (potentially negative) value of
sal_Int32 to be interpreted as an unsigned sal_uInt32, rather than using the
cast to avoid a false "signed vs. unsigned comparison" warning in a case where
n is known to be non-negative. It appears that restricting this plugin to non-
equality comparisons (<, >, <=, >=) and excluding equality comparisons (==, !=)
is a useful heuristic to avoid such false positives. The only remainging false
positive I found was 0288c8ffecff4956a52b9147d441979941e8b87f "Rephrase cast
from sal_Int32 to sal_uInt32".
But which of course does not mean that there were no further false positivies
that I missed. So this commit may accidentally introduce some false hits of the
assert in o3tl::make_unsigned. At least, it passed a full (Linux ASan+UBSan
--enable-dbgutil) `make check && make screenshot`.
It is by design that o3tl::make_unsigned only accepts signed integer parameter
types (and is not defined as a nop for unsigned ones), to avoid unnecessary uses
which would in general be suspicious. But the STATIC_ARRAY_SELECT macro in
include/oox/helper/helper.hxx is used with both signed and unsigned types, so
needs a little oox::detail::make_unsigned helper function for now. (The
ultimate fix being to get rid of the macro in the first place.)
Change-Id: Ia4adc9f44c70ad1dfd608784cac39ee922c32175
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87556
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-01-27 09:30:39 +01:00
|
|
|
#include <o3tl/safeint.hxx>
|
2015-04-21 08:39:10 +02:00
|
|
|
#include <osl/diagnose.h>
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2017-10-23 22:41:33 +02:00
|
|
|
#include <frm_strings.hxx>
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2001-10-25 16:55:52 +00:00
|
|
|
#include <algorithm>
|
2022-06-21 09:03:42 +02:00
|
|
|
#include <utility>
|
2001-10-25 16:55:52 +00:00
|
|
|
|
2000-09-18 15:33:13 +00:00
|
|
|
namespace frm
|
|
|
|
{
|
2000-11-23 08:05:32 +00:00
|
|
|
using namespace ::com::sun::star::uno;
|
|
|
|
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;
|
2018-05-27 14:07:43 +02:00
|
|
|
using namespace ::comphelper;
|
2003-12-01 09:15:40 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
2000-11-23 08:05:32 +00:00
|
|
|
|
2022-06-21 09:03:42 +02:00
|
|
|
OGroupCompAcc::OGroupCompAcc(const Reference<XPropertySet>& rxElement, OGroupComp _aGroupComp )
|
2000-09-18 15:33:13 +00:00
|
|
|
:m_xComponent( rxElement )
|
2022-06-21 09:03:42 +02:00
|
|
|
,m_aGroupComp(std::move( _aGroupComp ))
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2014-05-06 12:37:38 +02:00
|
|
|
bool OGroupCompAcc::operator==( const OGroupCompAcc& rCompAcc ) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2016-10-18 14:30:22 +02:00
|
|
|
return m_xComponent == rCompAcc.m_xComponent;
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2017-07-02 17:10:53 +02:00
|
|
|
class OGroupCompAccLess
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
public:
|
2014-05-06 12:37:38 +02:00
|
|
|
bool operator() (const OGroupCompAcc& lhs, const OGroupCompAcc& rhs) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return
|
|
|
|
reinterpret_cast<sal_Int64>(lhs.m_xComponent.get())
|
|
|
|
< reinterpret_cast<sal_Int64>(rhs.m_xComponent.get());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
OGroupComp::OGroupComp()
|
2006-06-19 11:50:58 +00:00
|
|
|
:m_nPos( -1 )
|
|
|
|
,m_nTabIndex( 0 )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
OGroupComp::OGroupComp(const Reference<XPropertySet>& rxSet, sal_Int32 nInsertPos )
|
2016-11-17 13:16:30 +02:00
|
|
|
: m_xComponent( rxSet )
|
2010-11-12 11:33:12 +00:00
|
|
|
, m_xControlModel(rxSet,UNO_QUERY)
|
|
|
|
, m_nPos( nInsertPos )
|
|
|
|
, m_nTabIndex(0)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
if (m_xComponent.is())
|
|
|
|
{
|
|
|
|
if (hasProperty( PROPERTY_TABINDEX, m_xComponent ) )
|
2014-02-22 21:20:15 +01:00
|
|
|
// Indices smaller than 0 are treated like 0
|
2013-04-11 00:21:40 -03:00
|
|
|
m_nTabIndex = std::max(getINT16(m_xComponent->getPropertyValue( PROPERTY_TABINDEX )) , sal_Int16(0));
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-06 12:37:38 +02:00
|
|
|
bool OGroupComp::operator==( const OGroupComp& rComp ) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_nTabIndex == rComp.GetTabIndex() && m_nPos == rComp.GetPos();
|
|
|
|
}
|
|
|
|
|
2017-07-02 17:10:53 +02:00
|
|
|
class OGroupCompLess
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
public:
|
2014-05-06 12:37:38 +02:00
|
|
|
bool operator() (const OGroupComp& lhs, const OGroupComp& rhs) const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2014-05-06 12:37:38 +02:00
|
|
|
bool bResult;
|
2014-09-24 11:43:17 +02:00
|
|
|
// TabIndex of 0 will be added at the end
|
2000-09-18 15:33:13 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-06-21 09:03:42 +02:00
|
|
|
OGroup::OGroup( OUString sGroupName )
|
|
|
|
:m_aGroupName(std::move( sGroupName ))
|
2000-09-18 15:33:13 +00:00
|
|
|
,m_nInsertPos(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
void OGroup::InsertComponent( const Reference<XPropertySet>& xSet )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
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++;
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
void OGroup::RemoveComponent( const Reference<XPropertySet>& rxElement )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
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 );
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
/*
|
2014-09-24 11:43:17 +02:00
|
|
|
* By removing the GroupComp the insertion position has become invalid.
|
2019-08-10 23:24:48 +02:00
|
|
|
* We do not to change it here, however, because it's passed on continuously
|
2014-09-24 11:43:17 +02:00
|
|
|
* and ascending distinctively.
|
|
|
|
*/
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-09-24 11:43:17 +02:00
|
|
|
OSL_FAIL( "OGroup::RemoveComponent: Component not in Group" );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-09-24 11:43:17 +02:00
|
|
|
OSL_FAIL( "OGroup::RemoveComponent: Component not in Group" );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
Sequence< Reference<XControlModel> > OGroup::GetControlModels() const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2017-12-17 23:00:24 +03:00
|
|
|
Sequence<Reference<XControlModel> > aControlModelSeq( m_aCompArray.size() );
|
2000-11-23 08:05:32 +00:00
|
|
|
Reference<XControlModel>* pModels = aControlModelSeq.getArray();
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2017-12-17 23:00:24 +03:00
|
|
|
for (auto const& rGroupComp : m_aCompArray)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2017-12-17 23:00:24 +03:00
|
|
|
*pModels++ = rGroupComp.GetControlModel();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
return aControlModelSeq;
|
|
|
|
}
|
|
|
|
|
2001-01-05 16:59:19 +00:00
|
|
|
OGroupManager::OGroupManager(const Reference< XContainer >& _rxContainer)
|
2017-01-31 13:24:13 +02:00
|
|
|
:m_pCompGroup( new OGroup( "AllComponentGroup" ) )
|
2001-01-05 16:59:19 +00:00
|
|
|
,m_xContainer(_rxContainer)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2015-04-21 08:39:10 +02:00
|
|
|
osl_atomic_increment(&m_refCount);
|
2001-01-05 16:59:19 +00:00
|
|
|
{
|
|
|
|
_rxContainer->addContainerListener(this);
|
|
|
|
}
|
2015-04-21 08:39:10 +02:00
|
|
|
osl_atomic_decrement(&m_refCount);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
OGroupManager::~OGroupManager()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
// XPropertyChangeListener
|
2017-01-26 12:28:58 +01:00
|
|
|
void OGroupManager::disposing(const EventObject& evt)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2000-11-23 08:05:32 +00:00
|
|
|
Reference<XContainer> xContainer(evt.Source, UNO_QUERY);
|
2001-01-05 16:59:19 +00:00
|
|
|
if (xContainer.get() == m_xContainer.get())
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2017-01-16 14:13:31 +02:00
|
|
|
m_pCompGroup.reset();
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
// delete group
|
2003-03-25 17:05:07 +00:00
|
|
|
m_aGroupArr.clear();
|
2001-04-10 07:47:52 +00:00
|
|
|
m_xContainer.clear();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
void OGroupManager::removeFromGroupMap(const OUString& _sGroupName,const Reference<XPropertySet>& _xSet)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2014-02-22 21:20:15 +01:00
|
|
|
// remove Component from CompGroup
|
2003-03-25 17:05:07 +00:00
|
|
|
m_pCompGroup->RemoveComponent( _xSet );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
OGroupArr::iterator aFind = m_aGroupArr.find(_sGroupName);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
if ( aFind != m_aGroupArr.end() )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2014-02-22 21:20:15 +01:00
|
|
|
// group exists
|
2003-03-25 17:05:07 +00:00
|
|
|
aFind->second.RemoveComponent( _xSet );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// If the count of Group elements == 1 -> deactivate Group
|
2010-10-06 10:16:13 +01:00
|
|
|
sal_Int32 nCount = aFind->second.Count();
|
|
|
|
if ( nCount == 1 || nCount == 0 )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-12-01 09:15:40 +00:00
|
|
|
OActiveGroups::iterator aActiveFind = ::std::find(
|
|
|
|
m_aActiveGroupMap.begin(),
|
|
|
|
m_aActiveGroupMap.end(),
|
|
|
|
aFind
|
|
|
|
);
|
2003-03-25 17:05:07 +00:00
|
|
|
if ( aActiveFind != m_aActiveGroupMap.end() )
|
2003-12-01 09:15:40 +00:00
|
|
|
{
|
|
|
|
// the group is active. Deactivate it if the remaining component
|
|
|
|
// is *no* radio button
|
2010-10-06 10:16:13 +01:00
|
|
|
if ( nCount == 0 || !isRadioButton( aFind->second.GetObject( 0 ) ) )
|
2003-12-01 09:15:40 +00:00
|
|
|
m_aActiveGroupMap.erase( aActiveFind );
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Deregister as PropertyChangeListener at Component
|
2003-03-25 17:05:07 +00:00
|
|
|
_xSet->removePropertyChangeListener( PROPERTY_NAME, this );
|
2010-10-06 10:16:13 +01:00
|
|
|
if (hasProperty(PROPERTY_GROUP_NAME, _xSet))
|
|
|
|
_xSet->removePropertyChangeListener( PROPERTY_GROUP_NAME, this );
|
2003-03-25 17:05:07 +00:00
|
|
|
if (hasProperty(PROPERTY_TABINDEX, _xSet))
|
|
|
|
_xSet->removePropertyChangeListener( PROPERTY_TABINDEX, this );
|
|
|
|
}
|
2014-02-22 21:20:15 +01:00
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL OGroupManager::propertyChange(const PropertyChangeEvent& evt)
|
2003-03-25 17:05:07 +00:00
|
|
|
{
|
|
|
|
Reference<XPropertySet> xSet(evt.Source, UNO_QUERY);
|
|
|
|
|
2014-02-22 21:20:15 +01:00
|
|
|
// remove Component from group
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString sGroupName;
|
2010-10-06 10:16:13 +01:00
|
|
|
if (hasProperty( PROPERTY_GROUP_NAME, xSet ))
|
|
|
|
xSet->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
|
|
|
|
if (evt.PropertyName == PROPERTY_NAME) {
|
2011-12-26 15:08:46 -02:00
|
|
|
if (!sGroupName.isEmpty())
|
2010-10-06 10:16:13 +01:00
|
|
|
return; // group hasn't changed; ignore this name change.
|
2015-10-02 09:44:24 +02:00
|
|
|
// no GroupName; use Name as GroupName
|
2010-10-06 10:16:13 +01:00
|
|
|
evt.OldValue >>= sGroupName;
|
|
|
|
}
|
|
|
|
else if (evt.PropertyName == PROPERTY_GROUP_NAME) {
|
2003-03-25 17:05:07 +00:00
|
|
|
evt.OldValue >>= sGroupName;
|
2011-12-26 15:08:46 -02:00
|
|
|
if (sGroupName.isEmpty()) {
|
2019-05-14 21:23:26 +00:00
|
|
|
// No prior GroupName; fallback to Name
|
2010-10-06 10:16:13 +01:00
|
|
|
xSet->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
|
|
|
|
}
|
|
|
|
}
|
2003-03-25 17:05:07 +00:00
|
|
|
else
|
2010-10-06 10:16:13 +01:00
|
|
|
sGroupName = GetGroupName( xSet );
|
2003-03-25 17:05:07 +00:00
|
|
|
|
|
|
|
removeFromGroupMap(sGroupName,xSet);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Re-insert Component
|
2000-09-18 15:33:13 +00:00
|
|
|
InsertElement( xSet );
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
// XContainerListener
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL OGroupManager::elementInserted(const ContainerEvent& Event)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2002-10-02 13:41:04 +00:00
|
|
|
Reference< XPropertySet > xProps;
|
|
|
|
Event.Element >>= xProps;
|
|
|
|
if ( xProps.is() )
|
|
|
|
InsertElement( xProps );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL OGroupManager::elementRemoved(const ContainerEvent& Event)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2002-10-02 13:41:04 +00:00
|
|
|
Reference<XPropertySet> xProps;
|
|
|
|
Event.Element >>= xProps;
|
|
|
|
if ( xProps.is() )
|
|
|
|
RemoveElement( xProps );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2017-01-26 12:28:58 +01:00
|
|
|
void SAL_CALL OGroupManager::elementReplaced(const ContainerEvent& Event)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2002-10-02 13:41:04 +00:00
|
|
|
Reference<XPropertySet> xProps;
|
|
|
|
Event.ReplacedElement >>= xProps;
|
|
|
|
if ( xProps.is() )
|
|
|
|
RemoveElement( xProps );
|
|
|
|
|
|
|
|
xProps.clear();
|
|
|
|
Event.Element >>= xProps;
|
|
|
|
if ( xProps.is() )
|
|
|
|
InsertElement( xProps );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Other functions
|
2019-09-25 13:30:20 +02:00
|
|
|
Sequence<Reference<XControlModel> > OGroupManager::getControlModels() const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_pCompGroup->GetControlModels();
|
|
|
|
}
|
|
|
|
|
2019-09-25 13:30:20 +02:00
|
|
|
sal_Int32 OGroupManager::getGroupCount() const
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
|
|
|
return m_aActiveGroupMap.size();
|
|
|
|
}
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
void OGroupManager::getGroup(sal_Int32 nGroup, Sequence< Reference<XControlModel> >& _rGroup, OUString& _rName)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
New loplugin:unsignedcompare
"Find explicit casts from signed to unsigned integer in comparison against
unsigned integer, where the cast is presumably used to avoid warnings about
signed vs. unsigned comparisons, and could thus be replaced with
o3tl::make_unsigned for clairty." (compilerplugins/clang/unsignedcompare.cxx)
o3tl::make_unsigned requires its argument to be non-negative, and there is a
chance that some original code like
static_cast<sal_uInt32>(n) >= c
used the explicit cast to actually force a (potentially negative) value of
sal_Int32 to be interpreted as an unsigned sal_uInt32, rather than using the
cast to avoid a false "signed vs. unsigned comparison" warning in a case where
n is known to be non-negative. It appears that restricting this plugin to non-
equality comparisons (<, >, <=, >=) and excluding equality comparisons (==, !=)
is a useful heuristic to avoid such false positives. The only remainging false
positive I found was 0288c8ffecff4956a52b9147d441979941e8b87f "Rephrase cast
from sal_Int32 to sal_uInt32".
But which of course does not mean that there were no further false positivies
that I missed. So this commit may accidentally introduce some false hits of the
assert in o3tl::make_unsigned. At least, it passed a full (Linux ASan+UBSan
--enable-dbgutil) `make check && make screenshot`.
It is by design that o3tl::make_unsigned only accepts signed integer parameter
types (and is not defined as a nop for unsigned ones), to avoid unnecessary uses
which would in general be suspicious. But the STATIC_ARRAY_SELECT macro in
include/oox/helper/helper.hxx is used with both signed and unsigned types, so
needs a little oox::detail::make_unsigned helper function for now. (The
ultimate fix being to get rid of the macro in the first place.)
Change-Id: Ia4adc9f44c70ad1dfd608784cac39ee922c32175
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87556
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2020-01-27 09:30:39 +01:00
|
|
|
OSL_ENSURE(nGroup >= 0 && o3tl::make_unsigned(nGroup) < m_aActiveGroupMap.size(),"OGroupManager::getGroup: Invalid group index!");
|
2003-03-25 17:05:07 +00:00
|
|
|
OGroupArr::iterator aGroupPos = m_aActiveGroupMap[nGroup];
|
|
|
|
_rName = aGroupPos->second.GetGroupName();
|
|
|
|
_rGroup = aGroupPos->second.GetControlModels();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2013-04-07 12:06:47 +02:00
|
|
|
void OGroupManager::getGroupByName(const OUString& _rName, Sequence< Reference<XControlModel> >& _rGroup)
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-03-25 17:05:07 +00:00
|
|
|
OGroupArr::iterator aFind = m_aGroupArr.find(_rName);
|
|
|
|
if ( aFind != m_aGroupArr.end() )
|
|
|
|
_rGroup = aFind->second.GetControlModels();
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
void OGroupManager::InsertElement( const Reference<XPropertySet>& xSet )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2014-09-24 11:43:17 +02:00
|
|
|
// Only ControlModels
|
2000-11-23 08:05:32 +00:00
|
|
|
Reference<XControlModel> xControl(xSet, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!xControl.is() )
|
|
|
|
return;
|
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Add Component to CompGroup
|
2000-09-18 15:33:13 +00:00
|
|
|
m_pCompGroup->InsertComponent( xSet );
|
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Add Component to Group
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString sGroupName( GetGroupName( xSet ) );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
OGroupArr::iterator aFind = m_aGroupArr.find(sGroupName);
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
if ( aFind == m_aGroupArr.end() )
|
|
|
|
{
|
2017-08-10 16:43:55 +02:00
|
|
|
aFind = m_aGroupArr.emplace(sGroupName,OGroup(sGroupName)).first;
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
aFind->second.InsertComponent( xSet );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-12-01 09:15:40 +00:00
|
|
|
// 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;
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-12-01 09:15:40 +00:00
|
|
|
if ( bActivateGroup )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2003-12-01 09:15:40 +00:00
|
|
|
OActiveGroups::iterator aAlreadyExistent = ::std::find(
|
|
|
|
m_aActiveGroupMap.begin(),
|
|
|
|
m_aActiveGroupMap.end(),
|
|
|
|
aFind
|
|
|
|
);
|
|
|
|
if ( aAlreadyExistent == m_aActiveGroupMap.end() )
|
|
|
|
m_aActiveGroupMap.push_back( aFind );
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Register as PropertyChangeListener at Component
|
2000-09-18 15:33:13 +00:00
|
|
|
xSet->addPropertyChangeListener( PROPERTY_NAME, this );
|
2010-10-06 10:16:13 +01:00
|
|
|
if (hasProperty(PROPERTY_GROUP_NAME, xSet))
|
|
|
|
xSet->addPropertyChangeListener( PROPERTY_GROUP_NAME, this );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Not everyone needs to support Tabindex
|
2000-09-18 15:33:13 +00:00
|
|
|
if (hasProperty(PROPERTY_TABINDEX, xSet))
|
|
|
|
xSet->addPropertyChangeListener( PROPERTY_TABINDEX, this );
|
|
|
|
}
|
|
|
|
|
2000-11-23 08:05:32 +00:00
|
|
|
void OGroupManager::RemoveElement( const Reference<XPropertySet>& xSet )
|
2000-09-18 15:33:13 +00:00
|
|
|
{
|
2014-09-24 11:43:17 +02:00
|
|
|
// Only ControlModels
|
2000-11-23 08:05:32 +00:00
|
|
|
Reference<XControlModel> xControl(xSet, UNO_QUERY);
|
2000-09-18 15:33:13 +00:00
|
|
|
if (!xControl.is() )
|
|
|
|
return;
|
|
|
|
|
2014-09-24 11:43:17 +02:00
|
|
|
// Remove Component from Group
|
2013-04-07 12:06:47 +02:00
|
|
|
OUString sGroupName( GetGroupName( xSet ) );
|
2000-09-18 15:33:13 +00:00
|
|
|
|
2003-03-25 17:05:07 +00:00
|
|
|
removeFromGroupMap(sGroupName,xSet);
|
2000-09-18 15:33:13 +00:00
|
|
|
}
|
|
|
|
|
2016-04-12 12:08:00 +02:00
|
|
|
OUString OGroupManager::GetGroupName( const css::uno::Reference< css::beans::XPropertySet>& xComponent )
|
2010-10-06 10:16:13 +01:00
|
|
|
{
|
|
|
|
if (!xComponent.is())
|
2013-04-07 12:06:47 +02:00
|
|
|
return OUString();
|
|
|
|
OUString sGroupName;
|
2010-10-06 10:16:13 +01:00
|
|
|
if (hasProperty( PROPERTY_GROUP_NAME, xComponent )) {
|
|
|
|
xComponent->getPropertyValue( PROPERTY_GROUP_NAME ) >>= sGroupName;
|
2011-12-26 15:08:46 -02:00
|
|
|
if (sGroupName.isEmpty())
|
2010-10-06 10:16:13 +01:00
|
|
|
xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
xComponent->getPropertyValue( PROPERTY_NAME ) >>= sGroupName;
|
|
|
|
return sGroupName;
|
|
|
|
}
|
2000-09-18 15:33:13 +00:00
|
|
|
} // namespace frm
|
|
|
|
|
2010-10-12 15:57:08 +02:00
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|