/* -*- 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 . */ #ifdef __sun #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::frame; using namespace ::com::sun::star::frame::status; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::util; using namespace ::com::sun::star::container; using namespace ::com::sun::star::ui; SFX_IMPL_TOOLBOX_CONTROL_ARG(SfxToolBoxControl, SfxStringItem, true); rtl::Reference SfxToolBoxControllerFactory( const Reference< XFrame >& rFrame, ToolBox* pToolbox, ToolBoxItemId nID, const OUString& aCommandURL ) { SolarMutexGuard aGuard; URL aTargetURL; aTargetURL.Complete = aCommandURL; Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); xTrans->parseStrict( aTargetURL ); if ( !aTargetURL.Arguments.isEmpty() ) return nullptr; Reference < XController > xController; Reference < XModel > xModel; if ( rFrame.is() ) { xController = rFrame->getController(); if ( xController.is() ) xModel = xController->getModel(); } SfxObjectShell* pObjShell = SfxObjectShell::GetShellFromComponent(xModel); SfxModule* pModule = pObjShell ? pObjShell->GetModule() : nullptr; SfxSlotPool* pSlotPool = nullptr; if ( pModule ) pSlotPool = pModule->GetSlotPool(); else pSlotPool = &(SfxSlotPool::GetSlotPool()); const SfxSlot* pSlot = pSlotPool->GetUnoSlot( aTargetURL.Path ); if ( pSlot ) { sal_uInt16 nSlotId = pSlot->GetSlotId(); if ( nSlotId > 0 ) return SfxToolBoxControl::CreateControl( nSlotId, nID, pToolbox, pModule ); } return nullptr; } struct SfxToolBoxControl_Impl { VclPtr pBox; bool bShowString; ToolBoxItemId nTbxId; sal_uInt16 nSlotId; }; SfxToolBoxControl::SfxToolBoxControl( sal_uInt16 nSlotID, ToolBoxItemId nID, ToolBox& rBox, bool bShowStringItems ) : pImpl( new SfxToolBoxControl_Impl ) { pImpl->pBox = &rBox; pImpl->bShowString = bShowStringItems; pImpl->nTbxId = nID; pImpl->nSlotId = nSlotID; } SfxToolBoxControl::~SfxToolBoxControl() { } ToolBox& SfxToolBoxControl::GetToolBox() const { return *pImpl->pBox; } ToolBoxItemId SfxToolBoxControl::GetId() const { return pImpl->nTbxId; } unsigned short SfxToolBoxControl::GetSlotId() const { return pImpl->nSlotId; } void SAL_CALL SfxToolBoxControl::dispose() { if ( m_bDisposed ) return; svt::ToolboxController::dispose(); // Remove and destroy our item window at our toolbox SolarMutexGuard aGuard; VclPtr< vcl::Window > pWindow = pImpl->pBox->GetItemWindow( pImpl->nTbxId ); pImpl->pBox->SetItemWindow( pImpl->nTbxId, nullptr ); pWindow.disposeAndClear(); } void SfxToolBoxControl::RegisterToolBoxControl( SfxModule* pMod, const SfxTbxCtrlFactory& rFact) { SfxGetpApp()->RegisterToolBoxControl_Impl( pMod, rFact ); } rtl::Reference SfxToolBoxControl::CreateControl( sal_uInt16 nSlotId, ToolBoxItemId nTbxId, ToolBox *pBox, SfxModule const * pMod ) { SolarMutexGuard aGuard; SfxApplication *pApp = SfxGetpApp(); SfxSlotPool *pSlotPool; if ( pMod ) pSlotPool = pMod->GetSlotPool(); else pSlotPool = &SfxSlotPool::GetSlotPool(); const std::type_info* aSlotType = pSlotPool->GetSlotType( nSlotId ); if ( aSlotType ) { if ( pMod ) { SfxTbxCtrlFactory *pFact = pMod->GetTbxCtrlFactory(*aSlotType, nSlotId); if ( pFact ) return pFact->pCtor( nSlotId, nTbxId, *pBox ); } SfxTbxCtrlFactory* pFact = pApp->GetTbxCtrlFactory(*aSlotType, nSlotId); if (pFact) return pFact->pCtor( nSlotId, nTbxId, *pBox ); } return nullptr; } SfxItemState SfxToolBoxControl::GetItemState( const SfxPoolItem* pState ) /* [Description] Static method for determining the status of the SfxPoolItem-pointer, used in the method . [Return value] SfxItemState SfxItemState::UNKNOWN Enabled, however no further status information is available. Typical for s, which are temporarily disabled a anyway but other than that do not change their appearance. SfxItemState::DISABLED Disabled, no further status information is available. All other displayed values should be reset to the default if possible. SfxItemState::DONTCARE Enabled but there were only ambiguous values available (i.e. none that could be queried). SfxItemState::DEFAULT Enabled and with available values which can be queried through'pState'. The type is thus by the Slot clearly defined in the entire Program. */ { return !pState ? SfxItemState::DISABLED : IsInvalidItem(pState) ? SfxItemState::DONTCARE : pState->IsVoidItem() && !pState->Which() ? SfxItemState::UNKNOWN : SfxItemState::DEFAULT; } void SfxToolBoxControl::Dispatch( const Reference< XDispatchProvider >& rProvider, const OUString& rCommand, Sequence< ::PropertyValue > const & aArgs ) { if ( rProvider.is() ) { css::util::URL aTargetURL; aTargetURL.Complete = rCommand; Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) ); xTrans->parseStrict( aTargetURL ); Reference < XDispatch > xDispatch = rProvider->queryDispatch( aTargetURL, OUString(), 0 ); if ( xDispatch.is() ) xDispatch->dispatch( aTargetURL, aArgs ); } } void SfxToolBoxControl::Dispatch( const OUString& aCommand, css::uno::Sequence< css::beans::PropertyValue > const & aArgs ) { Reference < XController > xController; SolarMutexGuard aGuard; if ( getFrameInterface().is() ) xController = getFrameInterface()->getController(); Reference < XDispatchProvider > xProvider( xController, UNO_QUERY ); if ( xProvider.is() ) { css::util::URL aTargetURL; aTargetURL.Complete = aCommand; getURLTransformer()->parseStrict( aTargetURL ); Reference < XDispatch > xDispatch = xProvider->queryDispatch( aTargetURL, OUString(), 0 ); if ( xDispatch.is() ) xDispatch->dispatch( aTargetURL, aArgs ); } } // XStatusListener void SAL_CALL SfxToolBoxControl::statusChanged( const FeatureStateEvent& rEvent ) { SfxViewFrame* pViewFrame = nullptr; Reference < XController > xController; SolarMutexGuard aGuard; if ( getFrameInterface().is() ) xController = getFrameInterface()->getController(); Reference < XDispatchProvider > xProvider( xController, UNO_QUERY ); if ( xProvider.is() ) { Reference < XDispatch > xDisp = xProvider->queryDispatch( rEvent.FeatureURL, OUString(), 0 ); if ( xDisp.is() ) { Reference< XUnoTunnel > xTunnel( xDisp, UNO_QUERY ); if (auto pDisp = comphelper::getFromUnoTunnel(xTunnel)) pViewFrame = pDisp->GetDispatcher_Impl()->GetFrame(); } } sal_uInt16 nSlotId = 0; SfxSlotPool& rPool = SfxSlotPool::GetSlotPool( pViewFrame ); const SfxSlot* pSlot = rPool.GetUnoSlot( rEvent.FeatureURL.Path ); if ( pSlot ) nSlotId = pSlot->GetSlotId(); else if ( m_aCommandURL == rEvent.FeatureURL.Path ) nSlotId = GetSlotId(); if ( nSlotId <= 0 ) return; if ( rEvent.Requery ) svt::ToolboxController::statusChanged( rEvent ); else { SfxItemState eState = SfxItemState::DISABLED; std::unique_ptr pItem; if ( rEvent.IsEnabled ) { eState = SfxItemState::DEFAULT; css::uno::Type aType = rEvent.State.getValueType(); if ( aType == cppu::UnoType::get() ) { pItem.reset(new SfxVoidItem( nSlotId )); eState = SfxItemState::UNKNOWN; } else if ( aType == cppu::UnoType::get() ) { bool bTemp = false; rEvent.State >>= bTemp ; pItem.reset(new SfxBoolItem( nSlotId, bTemp )); } else if ( aType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get()) { sal_uInt16 nTemp = 0; rEvent.State >>= nTemp ; pItem.reset(new SfxUInt16Item( nSlotId, nTemp )); } else if ( aType == cppu::UnoType::get() ) { sal_uInt32 nTemp = 0; rEvent.State >>= nTemp ; pItem.reset(new SfxUInt32Item( nSlotId, nTemp )); } else if ( aType == cppu::UnoType::get() ) { OUString sTemp ; rEvent.State >>= sTemp ; pItem.reset(new SfxStringItem( nSlotId, sTemp )); } else if ( aType == cppu::UnoType< css::frame::status::ItemStatus>::get() ) { ItemStatus aItemStatus; rEvent.State >>= aItemStatus; SfxItemState tmpState = static_cast(aItemStatus.State); // make sure no-one tries to send us a combination of states if (tmpState != SfxItemState::UNKNOWN && tmpState != SfxItemState::DISABLED && tmpState != SfxItemState::DONTCARE && tmpState != SfxItemState::DEFAULT && tmpState != SfxItemState::SET) throw css::uno::RuntimeException("unknown status"); eState = tmpState; pItem.reset(new SfxVoidItem( nSlotId )); } else if ( aType == cppu::UnoType< css::frame::status::Visibility>::get() ) { Visibility aVisibilityStatus; rEvent.State >>= aVisibilityStatus; pItem.reset(new SfxVisibilityItem( nSlotId, aVisibilityStatus.bVisible )); } else { if ( pSlot ) pItem = pSlot->GetType()->CreateItem(); if ( pItem ) { pItem->SetWhich( nSlotId ); pItem->PutValue( rEvent.State, 0 ); } else pItem.reset(new SfxVoidItem( nSlotId )); } } StateChangedAtToolBoxControl( nSlotId, eState, pItem.get() ); } } // XToolbarController void SAL_CALL SfxToolBoxControl::execute( sal_Int16 KeyModifier ) { SolarMutexGuard aGuard; Select( static_cast(KeyModifier) ); } void SAL_CALL SfxToolBoxControl::click() { SolarMutexGuard aGuard; Click(); } void SAL_CALL SfxToolBoxControl::doubleClick() { SolarMutexGuard aGuard; DoubleClick(); } Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createPopupWindow() { SolarMutexGuard aGuard; CreatePopupWindow(); return nullptr; } Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createItemWindow( const Reference< css::awt::XWindow >& rParent ) { SolarMutexGuard aGuard; return VCLUnoHelper::GetInterface( CreateItemWindow( VCLUnoHelper::GetWindow( rParent ))); } void SfxToolBoxControl::StateChangedAtToolBoxControl ( sal_uInt16 /*nSlotId*/, SfxItemState eState, const SfxPoolItem* pState ) { DBG_ASSERT( pImpl->pBox != nullptr, "setting state to dangling ToolBox" ); // enabled/disabled-Flag correcting the lump sum pImpl->pBox->EnableItem( GetId(), eState != SfxItemState::DISABLED ); ToolBoxItemBits nItemBits = pImpl->pBox->GetItemBits( GetId() ); nItemBits &= ~ToolBoxItemBits::CHECKABLE; ::TriState eTri = TRISTATE_FALSE; switch ( eState ) { case SfxItemState::DEFAULT: if ( pState ) { if ( auto pBoolItem = dynamic_cast< const SfxBoolItem* >(pState) ) { // BoolItem for checking if ( pBoolItem->GetValue() ) eTri = TRISTATE_TRUE; nItemBits |= ToolBoxItemBits::CHECKABLE; } else if ( auto pEnumItem = dynamic_cast< const SfxEnumItemInterface *>( pState ) ) { if (pEnumItem->HasBoolValue()) { // EnumItem is handled as Bool if (pEnumItem->GetBoolValue()) eTri = TRISTATE_TRUE; nItemBits |= ToolBoxItemBits::CHECKABLE; } } else if ( pImpl->bShowString ) { if (auto pStringItem = dynamic_cast< const SfxStringItem *>( pState ) ) pImpl->pBox->SetItemText(GetId(), pStringItem->GetValue() ); } } break; case SfxItemState::DONTCARE: { eTri = TRISTATE_INDET; nItemBits |= ToolBoxItemBits::CHECKABLE; } break; default: break; // do nothing } pImpl->pBox->SetItemState( GetId(), eTri ); pImpl->pBox->SetItemBits( GetId(), nItemBits ); } void SfxToolBoxControl::Select( sal_uInt16 nSelectModifier ) { svt::ToolboxController::execute( nSelectModifier ); } void SfxToolBoxControl::DoubleClick() { } void SfxToolBoxControl::Click() { } void SfxToolBoxControl::CreatePopupWindow() { } VclPtr SfxToolBoxControl::CreateItemWindow(vcl::Window*) { return VclPtr(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */