20#include <com/sun/star/awt/XVclContainerPeer.hpp>
21#include <com/sun/star/beans/XPropertySet.hpp>
22#include <com/sun/star/beans/XPropertyChangeListener.hpp>
23#include <com/sun/star/container/NoSuchElementException.hpp>
24#include <com/sun/star/uno/XComponentContext.hpp>
36#include <com/sun/star/awt/VclWindowPeerAttribute.hpp>
45struct UnoControlHolder
47 uno::Reference< awt::XControl > mxControl;
51 UnoControlHolder( OUString aName, uno::Reference< awt::XControl > xControl )
52 : mxControl(
std::move( xControl )),
57 const OUString& getName()
const {
return msName; }
58 const uno::Reference< awt::XControl >& getControl()
const {
return mxControl; }
69 typedef ::std::map< ControlIdentifier, ControlInfo >
ControlMap;
93 void getControls( uno::Sequence< uno::Reference< awt::XControl > >& _out_rControls )
const;
97 void getIdentifiers( uno::Sequence< sal_Int32 >& _out_rIdentifiers )
const;
101 uno::Reference< awt::XControl >
144 const uno::Reference< awt::XControl >& _rxControl,
145 const OUString* _pName
176 uno::Reference< awt::XControl >* pControls = _out_rControls.getArray();
179 *pControls = rEntry.second->getControl();
187 _out_rIdentifiers.realloc(
maControls.size() );
188 sal_Int32* pIdentifiers = _out_rIdentifiers.getArray();
191 *pIdentifiers = rEntry.first;
200 [&_rName](
const ControlMap::value_type& rEntry) { return rEntry.second->getName() == _rName; });
202 return loop->second->getControl();
203 return uno::Reference< awt::XControl >();
210 [&_rxControl](
const ControlMap::value_type& rEntry) { return rEntry.second->getControl().get() == _rxControl.get(); });
219 ControlMap::const_iterator
pos =
maControls.find( _nIdentifier );
222 _out_rxControl =
pos->second->getControl();
240 DBG_ASSERT( _rxNewControl.is(),
"UnoControlHolderList::replaceControlById: invalid new control!" );
247 pos->second = std::make_shared<UnoControlHolder>(
pos->second->getName(), _rxNewControl );
253 DBG_ASSERT( _rxControl.is(),
"UnoControlHolderList::impl_addControl: invalid control!" );
265 for (
ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
267 ControlMap::const_iterator existent =
maControls.find( candidateId );
271 throw uno::RuntimeException(
"out of identifiers" );
277 for (
ControlIdentifier candidateId = 0; candidateId < ::std::numeric_limits< ControlIdentifier >::max(); ++candidateId )
279 OUString candidateName(
"control_" + OUString::number( candidateId ) );
281 [&candidateName](
const ControlMap::value_type& rEntry) { return rEntry.second->getName() == candidateName; }) )
282 return candidateName;
284 throw uno::RuntimeException(
"out of identifiers" );
292 sal_Int32 nDialogStep,
293 const uno::Reference< awt::XControlContainer >& xControlContainer
296 const uno::Sequence< uno::Reference< awt::XControl > >
297 aCtrls = xControlContainer->getControls();
298 bool bCompleteVisible = (nDialogStep == 0);
299 for(
const uno::Reference< awt::XControl >& xControl : aCtrls )
304 uno::Reference< awt::XControlModel >
xModel( xControl->getModel() );
305 uno::Reference< beans::XPropertySet > xPSet
306 (
xModel, uno::UNO_QUERY );
307 uno::Reference< beans::XPropertySetInfo >
308 xInfo = xPSet->getPropertySetInfo();
310 sal_Int32 nControlStep = 0;
311 if ( xInfo->hasPropertyByName(
aPropName ) )
314 aVal >>= nControlStep;
316 bVisible = (nControlStep == 0) || (nControlStep == nDialogStep);
319 uno::Reference< awt::XWindow> xWindow
320 ( xControl, uno::UNO_QUERY );
335 uno::Reference< awt::XControlContainer > mxControlContainer;
338 explicit DialogStepChangedListener( uno::Reference< awt::XControlContainer > xControlContainer )
339 : mxControlContainer(std::move( xControlContainer )) {}
342 virtual void SAL_CALL disposing(
const lang::EventObject&
Source )
override;
345 virtual void SAL_CALL propertyChange(
const beans::PropertyChangeEvent& evt )
override;
351void SAL_CALL DialogStepChangedListener::disposing(
const lang::EventObject& )
353 mxControlContainer.clear();
356void SAL_CALL DialogStepChangedListener::propertyChange(
const beans::PropertyChangeEvent& evt )
359 sal_Int32 nDialogStep = 0;
360 evt.NewValue >>= nDialogStep;
367 :maCListeners( *this )
373 :maCListeners( *this )
376 mbDisposePeer =
false;
388 rTabController->setContainer(
this );
389 rTabController->activateTabOrder();
396 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
398 lang::EventObject aDisposeEvent;
399 aDisposeEvent.Source =
static_cast< uno::XAggregation*
>( this );
403 maDisposeListeners.disposeAndClear( aDisposeEvent );
407 const uno::Sequence< uno::Reference< awt::XControl > > aCtrls =
getControls();
409 for( uno::Reference< awt::XControl >
const & control : aCtrls )
426 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
428 uno::Reference< awt::XControl > xControl( _rEvt.Source, uno::UNO_QUERY );
438 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
445 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
453 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
455 uno::Reference< awt::XControl > xControl;
456 if ( !( _rElement >>= xControl ) || !xControl.is() )
457 throw lang::IllegalArgumentException(
458 "Elements must support the XControl interface.",
468 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
470 uno::Reference< awt::XControl > xControl;
471 if ( !
mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
472 throw container::NoSuchElementException(
473 "There is no element with the given identifier.",
482 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
484 uno::Reference< awt::XControl > xExistentControl;
485 if ( !
mpControls->getControlForIdentifier( _nIdentifier, xExistentControl ) )
486 throw container::NoSuchElementException(
487 "There is no element with the given identifier.",
491 uno::Reference< awt::XControl > xNewControl;
492 if ( !( _rElement >>= xNewControl ) )
493 throw lang::IllegalArgumentException(
494 "Elements must support the XControl interface.",
501 mpControls->replaceControlById( _nIdentifier, xNewControl );
509 container::ContainerEvent
aEvent;
511 aEvent.Accessor <<= _nIdentifier;
512 aEvent.Element <<= xNewControl;
513 aEvent.ReplacedElement <<= xExistentControl;
520 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
522 uno::Reference< awt::XControl > xControl;
523 if ( !
mpControls->getControlForIdentifier( _nIdentifier, xControl ) )
524 throw container::NoSuchElementException();
530 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
532 uno::Sequence< ::sal_Int32 > aIdentifiers;
545 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
552 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
555 uno::Reference< awt::XControlContainer > xContainer(
mxContext, uno::UNO_QUERY );
556 if( xContainer.is() )
557 xContainer->setStatusText( rStatusText );
562 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
563 uno::Sequence< uno::Reference< awt::XControl > > aControls;
570 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
571 return mpControls->getControlForName( rName );
576 if ( _rxControl.is() )
578 uno::Reference< uno::XInterface > xThis;
581 _rxControl->setContext( xThis );
582 _rxControl->addEventListener(
this );
588 OSL_PRECOND( _rxControl.is(),
"UnoControlContainer::impl_createControlPeerIfNecessary: invalid control, this will crash!" );
591 uno::Reference< awt::XWindowPeer > xMyPeer( getPeer() );
595 _rxControl->createPeer(
nullptr, xMyPeer );
603 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
612 container::ContainerEvent
aEvent;
615 aEvent.Accessor <<= *_pName;
617 aEvent.Accessor <<=
static_cast<sal_Int32
>(id);
618 aEvent.Element <<= _rxControl;
633 if ( _rxControl.is() )
635 _rxControl->removeEventListener(
this );
636 _rxControl->setContext(
nullptr );
644 uno::Reference< awt::XControl > xControl;
645 bool bHas =
mpControls->getControlForIdentifier( _nId, xControl );
646 DBG_ASSERT( bHas && xControl == _rxControl,
"UnoControlContainer::impl_removeControl: inconsistency in the parameters!" );
655 container::ContainerEvent
aEvent;
658 aEvent.Element <<= _rxControl;
665 if ( _rxControl.is() )
667 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
679 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
686 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
693 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
702 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
705 [&TabController](
const uno::Reference< awt::XTabController >& rTabController) {
706 return rTabController.get() == TabController.get(); });
709 auto n =
static_cast<sal_Int32
>(std::distance(std::cbegin(
maTabControllers), pTabController));
717 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
722 bool bVis = maComponentInfos.bVisible;
730 if ( !mbCreatingCompatiblePeer )
733 uno::Reference< awt::XControlModel >
xModel( getModel() );
734 uno::Reference< beans::XPropertySet > xPSet
735 (
xModel, uno::UNO_QUERY );
736 uno::Reference< beans::XPropertySetInfo >
737 xInfo = xPSet->getPropertySetInfo();
739 if ( xInfo->hasPropertyByName(
aPropName ) )
741 css::uno::Any aVal = xPSet->getPropertyValue(
aPropName );
742 sal_Int32 nDialogStep = 0;
743 aVal >>= nDialogStep;
744 uno::Reference< awt::XControlContainer > xContainer =
745 static_cast< awt::XControlContainer*
>(
this);
748 uno::Reference< beans::XPropertyChangeListener > xListener =
749 new DialogStepChangedListener(xContainer);
750 xPSet->addPropertyChangeListener(
aPropName, xListener );
753 uno::Sequence< uno::Reference< awt::XControl > > aCtrls =
getControls();
754 for(
auto& rCtrl : asNonConstRange(aCtrls) )
755 rCtrl->createPeer( rxToolkit, getPeer() );
757 uno::Reference< awt::XVclContainerPeer > xC( getPeer(), uno::UNO_QUERY );
759 xC->enableDialogControl(
true );
763 if( bVis && !isDesignMode() )
771 ::osl::Guard< ::osl::Mutex > aGuard( GetMutex() );
776 createPeer( uno::Reference< awt::XToolkit > (), uno::Reference< awt::XWindowPeer > () );
781 return "stardiv.Toolkit.UnoControlContainer";
787 s.realloc(s.getLength() + 2);
788 auto ps = s.getArray();
789 ps[s.getLength() - 2] =
"com.sun.star.awt.UnoControlContainer";
790 ps[s.getLength() - 1] =
"stardiv.vcl.control.ControlContainer";
803 if ( rDesc.WindowAttributes & css::awt::VclWindowPeerAttribute::VSCROLL )
805 rDesc.WindowAttributes &= ~css::awt::VclWindowPeerAttribute::VSCROLL;
806 rDesc.WindowAttributes |= css::awt::VclWindowPeerAttribute::AUTOVSCROLL;
808 if ( rDesc.WindowAttributes & css::awt::VclWindowPeerAttribute::HSCROLL )
810 rDesc.WindowAttributes &= ~css::awt::VclWindowPeerAttribute::HSCROLL;
811 rDesc.WindowAttributes |= css::awt::VclWindowPeerAttribute::AUTOHSCROLL;
815extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
817 css::uno::XComponentContext *,
818 css::uno::Sequence<css::uno::Any>
const &)
virtual sal_Bool SAL_CALL hasElements() override
void SAL_CALL removeTabController(const css::uno::Reference< css::awt::XTabController > &TabController) override
virtual ~UnoControlContainer() override
virtual void PrepareWindowDescriptor(css::awt::WindowDescriptor &rDesc) override
void SAL_CALL addTabController(const css::uno::Reference< css::awt::XTabController > &TabController) override
void impl_removeControl(sal_Int32 _nId, const css::uno::Reference< css::awt::XControl > &_rxControl)
removes the given control from the container, including necessary notifications and the like
void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &Toolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
OUString SAL_CALL getImplementationName() override
void SAL_CALL setTabControllers(const css::uno::Sequence< css::uno::Reference< css::awt::XTabController > > &TabControllers) override
css::uno::Sequence< css::uno::Reference< css::awt::XControl > > SAL_CALL getControls() override
virtual ::sal_Int32 SAL_CALL insert(const css::uno::Any &aElement) override
virtual void SAL_CALL removeByIdentifier(::sal_Int32 Identifier) override
void SAL_CALL setVisible(sal_Bool Visible) override
void SAL_CALL removeContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
css::uno::Sequence< css::uno::Reference< css::awt::XTabController > > SAL_CALL getTabControllers() override
virtual void addingControl(const css::uno::Reference< css::awt::XControl > &_rxControl)
virtual void impl_createControlPeerIfNecessary(const css::uno::Reference< css::awt::XControl > &_rxControl)
ensures that the given control has a peer, if necessary and possible
void SAL_CALL setStatusText(const OUString &StatusText) override
virtual void SAL_CALL replaceByIdentifer(::sal_Int32 Identifier, const css::uno::Any &aElement) override
css::uno::Sequence< css::uno::Reference< css::awt::XTabController > > maTabControllers
void SAL_CALL addControl(const OUString &Name, const css::uno::Reference< css::awt::XControl > &Control) override
std::unique_ptr< UnoControlHolderList > mpControls
virtual css::uno::Sequence< ::sal_Int32 > SAL_CALL getIdentifiers() override
css::uno::Reference< css::awt::XControl > SAL_CALL getControl(const OUString &aName) override
virtual css::uno::Type SAL_CALL getElementType() override
void SAL_CALL disposing(const css::lang::EventObject &Source) override
virtual css::uno::Any SAL_CALL getByIdentifier(::sal_Int32 Identifierr) override
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void SAL_CALL addContainerListener(const css::uno::Reference< css::container::XContainerListener > &xListener) override
void SAL_CALL removeControl(const css::uno::Reference< css::awt::XControl > &Control) override
void ImplActivateTabControllers()
ContainerListenerMultiplexer maCListeners
sal_Int32 impl_addControl(const css::uno::Reference< css::awt::XControl > &_rxControl, const OUString *_pName=nullptr)
adds the control to the container, does necessary notifications, and the like
virtual void removingControl(const css::uno::Reference< css::awt::XControl > &_rxControl)
void SAL_CALL dispose() override
bool empty() const
determines whether or not the list is empty
ControlIdentifier impl_addControl(const uno::Reference< awt::XControl > &_rxControl, const OUString *_pName)
adds a control
::std::map< ControlIdentifier, ControlInfo > ControlMap
ControlIdentifier addControl(const uno::Reference< awt::XControl > &_rxControl, const OUString *_pName)
adds a control with the given name to the list
void removeControlById(ControlIdentifier _nId)
removes a control from the list, given by id
ControlIdentifier getControlIdentifier(const uno::Reference< awt::XControl > &_rxControl)
returns the identifier which a control is registered for, or -1 if the control isn't registered
OUString impl_getFreeName_throw()
finds a free name
uno::Reference< awt::XControl > getControlForName(const OUString &_rName) const
returns the first control which is registered under the given name
bool getControlForIdentifier(ControlIdentifier _nIdentifier, uno::Reference< awt::XControl > &_out_rxControl) const
retrieves the control for a given id
ControlIdentifier impl_getFreeIdentifier_throw()
finds a free identifier
void replaceControlById(ControlIdentifier _nId, const uno::Reference< awt::XControl > &_rxNewControl)
replaces a control from the list with another one
std::shared_ptr< UnoControlHolder > ControlInfo
void getControls(uno::Sequence< uno::Reference< awt::XControl > > &_out_rControls) const
retrieves all controls currently in the list
sal_Int32 ControlIdentifier
void getIdentifiers(uno::Sequence< sal_Int32 > &_out_rIdentifiers) const
retrieves all identifiers of all controls currently in the list
void SAL_CALL dispose() override
void SAL_CALL setVisible(sal_Bool Visible) override
void SAL_CALL disposing(const css::lang::EventObject &Source) override
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void SAL_CALL createPeer(const css::uno::Reference< css::awt::XToolkit > &Toolkit, const css::uno::Reference< css::awt::XWindowPeer > &Parent) override
css::uno::Type const & get()
#define DBG_ASSERT(sCon, aError)
::cppu::WeakImplHelper< css::beans::XPropertyChangeListener > PropertyChangeListenerHelper
Reference< XModel > xModel
::cppu::WeakImplHelper< beans::XPropertyChangeListener > PropertyChangeListenerHelper
static void implUpdateVisibility(sal_Int32 nDialogStep, const uno::Reference< awt::XControlContainer > &xControlContainer)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stardiv_Toolkit_UnoControlContainer_get_implementation(css::uno::XComponentContext *, css::uno::Sequence< css::uno::Any > const &)