Bump version to 21.06.18.1
[LibreOffice.git] / sfx2 / source / toolbox / tbxitem.cxx
blob99ae9ff3e7e5831c97336bdd716ec3bc81c416a3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #ifdef __sun
22 #include <ctime>
23 #endif
25 #include <com/sun/star/uno/Reference.h>
26 #include <com/sun/star/frame/XFrame.hpp>
27 #include <com/sun/star/awt/XWindow.hpp>
28 #include <com/sun/star/util/URL.hpp>
29 #include <com/sun/star/util/URLTransformer.hpp>
30 #include <com/sun/star/util/XURLTransformer.hpp>
31 #include <com/sun/star/frame/XController.hpp>
32 #include <com/sun/star/frame/XDispatchProvider.hpp>
33 #include <com/sun/star/lang/XUnoTunnel.hpp>
34 #include <com/sun/star/beans/PropertyValue.hpp>
35 #include <com/sun/star/frame/status/ItemStatus.hpp>
36 #include <com/sun/star/ui/XUIElementFactory.hpp>
37 #include <com/sun/star/frame/status/Visibility.hpp>
38 #include <svl/eitem.hxx>
39 #include <svl/stritem.hxx>
40 #include <svl/intitem.hxx>
41 #include <svl/visitem.hxx>
42 #include <vcl/svapp.hxx>
43 #include <vcl/toolbox.hxx>
45 #include <svtools/framestatuslistener.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <vcl/taskpanelist.hxx>
48 #include <vcl/event.hxx>
49 #include <toolkit/helper/vclunohelper.hxx>
51 #include <vcl/InterimItemWindow.hxx>
52 #include <sfx2/tbxctrl.hxx>
53 #include <sfx2/dispatch.hxx>
54 #include <sfx2/msg.hxx>
55 #include <sfx2/msgpool.hxx>
56 #include <sfx2/viewfrm.hxx>
57 #include <sfx2/module.hxx>
58 #include <sfx2/app.hxx>
59 #include <sidebar/ControllerFactory.hxx>
60 #include <unoctitm.hxx>
61 #include <ctrlfactoryimpl.hxx>
63 using namespace ::com::sun::star;
64 using namespace ::com::sun::star::beans;
65 using namespace ::com::sun::star::frame;
66 using namespace ::com::sun::star::frame::status;
67 using namespace ::com::sun::star::lang;
68 using namespace ::com::sun::star::uno;
69 using namespace ::com::sun::star::util;
70 using namespace ::com::sun::star::container;
71 using namespace ::com::sun::star::ui;
74 SFX_IMPL_TOOLBOX_CONTROL_ARG(SfxToolBoxControl, SfxStringItem, true);
76 svt::ToolboxController* SfxToolBoxControllerFactory( const Reference< XFrame >& rFrame, ToolBox* pToolbox, unsigned short nID, const OUString& aCommandURL )
78 SolarMutexGuard aGuard;
80 URL aTargetURL;
81 aTargetURL.Complete = aCommandURL;
82 Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
83 xTrans->parseStrict( aTargetURL );
84 if ( !aTargetURL.Arguments.isEmpty() )
85 return nullptr;
87 Reference < XController > xController;
88 Reference < XModel > xModel;
89 if ( rFrame.is() )
91 xController = rFrame->getController();
92 if ( xController.is() )
93 xModel = xController->getModel();
96 SfxObjectShell* pObjShell = SfxObjectShell::GetShellFromComponent(xModel);
97 SfxModule* pModule = pObjShell ? pObjShell->GetModule() : nullptr;
98 SfxSlotPool* pSlotPool = nullptr;
100 if ( pModule )
101 pSlotPool = pModule->GetSlotPool();
102 else
103 pSlotPool = &(SfxSlotPool::GetSlotPool());
105 const SfxSlot* pSlot = pSlotPool->GetUnoSlot( aTargetURL.Path );
106 if ( pSlot )
108 sal_uInt16 nSlotId = pSlot->GetSlotId();
109 if ( nSlotId > 0 )
110 return SfxToolBoxControl::CreateControl( nSlotId, nID, pToolbox, pModule );
113 return nullptr;
116 struct SfxToolBoxControl_Impl
118 VclPtr<ToolBox> pBox;
119 bool bShowString;
120 sal_uInt16 nTbxId;
121 sal_uInt16 nSlotId;
124 SfxToolBoxControl::SfxToolBoxControl(
125 sal_uInt16 nSlotID,
126 sal_uInt16 nID,
127 ToolBox& rBox,
128 bool bShowStringItems )
129 : pImpl( new SfxToolBoxControl_Impl )
131 pImpl->pBox = &rBox;
132 pImpl->bShowString = bShowStringItems;
133 pImpl->nTbxId = nID;
134 pImpl->nSlotId = nSlotID;
138 SfxToolBoxControl::~SfxToolBoxControl()
143 ToolBox& SfxToolBoxControl::GetToolBox() const
145 return *pImpl->pBox;
147 unsigned short SfxToolBoxControl::GetId() const
149 return pImpl->nTbxId;
151 unsigned short SfxToolBoxControl::GetSlotId() const
153 return pImpl->nSlotId;
157 void SAL_CALL SfxToolBoxControl::dispose()
159 if ( m_bDisposed )
160 return;
162 svt::ToolboxController::dispose();
164 // Remove and destroy our item window at our toolbox
165 SolarMutexGuard aGuard;
166 VclPtr< vcl::Window > pWindow = pImpl->pBox->GetItemWindow( pImpl->nTbxId );
167 pImpl->pBox->SetItemWindow( pImpl->nTbxId, nullptr );
168 pWindow.disposeAndClear();
172 void SfxToolBoxControl::RegisterToolBoxControl( SfxModule* pMod, const SfxTbxCtrlFactory& rFact)
174 SfxGetpApp()->RegisterToolBoxControl_Impl( pMod, rFact );
177 SfxToolBoxControl* SfxToolBoxControl::CreateControl( sal_uInt16 nSlotId, sal_uInt16 nTbxId, ToolBox *pBox, SfxModule const * pMod )
179 SolarMutexGuard aGuard;
181 SfxApplication *pApp = SfxGetpApp();
183 SfxSlotPool *pSlotPool;
184 if ( pMod )
185 pSlotPool = pMod->GetSlotPool();
186 else
187 pSlotPool = &SfxSlotPool::GetSlotPool();
188 const std::type_info* aSlotType = pSlotPool->GetSlotType( nSlotId );
189 if ( aSlotType )
191 SfxToolBoxControl *pCtrl;
192 if ( pMod )
194 SfxTbxCtrlFactArr_Impl *pFactories = pMod->GetTbxCtrlFactories_Impl();
195 if ( pFactories )
197 SfxTbxCtrlFactArr_Impl &rFactories = *pFactories;
198 sal_uInt16 nFactory;
199 const sal_uInt16 nCount = rFactories.size();
201 // search for a factory with the given slot id
202 for( nFactory = 0; nFactory < nCount; ++nFactory )
203 if( (rFactories[nFactory].nTypeId == *aSlotType) && (rFactories[nFactory].nSlotId == nSlotId) )
204 break;
206 if( nFactory == nCount )
208 // if no factory exists for the given slot id, see if we
209 // have a generic factory with the correct slot type and slot id == 0
210 for ( nFactory = 0; nFactory < nCount; ++nFactory )
211 if( (rFactories[nFactory].nTypeId == *aSlotType) && (rFactories[nFactory].nSlotId == 0) )
212 break;
215 if( nFactory < nCount )
217 pCtrl = rFactories[nFactory].pCtor( nSlotId, nTbxId, *pBox );
218 return pCtrl;
223 SfxTbxCtrlFactArr_Impl &rFactories = pApp->GetTbxCtrlFactories_Impl();
224 sal_uInt16 nFactory;
225 const sal_uInt16 nCount = rFactories.size();
227 for( nFactory = 0; nFactory < nCount; ++nFactory )
228 if( (rFactories[nFactory].nTypeId == *aSlotType) && (rFactories[nFactory].nSlotId == nSlotId) )
229 break;
231 if( nFactory == nCount )
233 // if no factory exists for the given slot id, see if we
234 // have a generic factory with the correct slot type and slot id == 0
235 for( nFactory = 0; nFactory < nCount; ++nFactory )
236 if( (rFactories[nFactory].nTypeId == *aSlotType) && (rFactories[nFactory].nSlotId == 0) )
237 break;
240 if( nFactory < nCount )
242 pCtrl = rFactories[nFactory].pCtor( nSlotId, nTbxId, *pBox );
243 return pCtrl;
247 return nullptr;
250 SfxItemState SfxToolBoxControl::GetItemState(
251 const SfxPoolItem* pState )
252 /* [Description]
254 Static method for determining the status of the SfxPoolItem-pointer,
255 used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>.
257 [Return value]
259 SfxItemState SfxItemState::UNKNOWN
260 Enabled, however no further status information is available.
261 Typical for <Slot>s, which are temporarily disabled a
262 anyway but other than that do not change their appearance.
264 SfxItemState::DISABLED
265 Disabled, no further status information is available.
266 All other displayed values should be reset to the default
267 if possible.
269 SfxItemState::DONTCARE
270 Enabled but there were only ambiguous values available
271 (i.e. none that could be queried).
273 SfxItemState::DEFAULT
274 Enabled and with available values which can be queried
275 through'pState'. The type is thus by the Slot clearly
276 defined in the entire Program.
280 return !pState
281 ? SfxItemState::DISABLED
282 : IsInvalidItem(pState)
283 ? SfxItemState::DONTCARE
284 : pState->IsVoidItem() && !pState->Which()
285 ? SfxItemState::UNKNOWN
286 : SfxItemState::DEFAULT;
289 void SfxToolBoxControl::Dispatch(
290 const Reference< XDispatchProvider >& rProvider,
291 const OUString& rCommand,
292 Sequence< ::PropertyValue > const & aArgs )
294 if ( rProvider.is() )
296 css::util::URL aTargetURL;
297 aTargetURL.Complete = rCommand;
298 Reference < XURLTransformer > xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
299 xTrans->parseStrict( aTargetURL );
301 Reference < XDispatch > xDispatch = rProvider->queryDispatch( aTargetURL, OUString(), 0 );
302 if ( xDispatch.is() )
303 xDispatch->dispatch( aTargetURL, aArgs );
307 void SfxToolBoxControl::Dispatch( const OUString& aCommand, css::uno::Sequence< css::beans::PropertyValue > const & aArgs )
309 Reference < XController > xController;
311 SolarMutexGuard aGuard;
312 if ( getFrameInterface().is() )
313 xController = getFrameInterface()->getController();
315 Reference < XDispatchProvider > xProvider( xController, UNO_QUERY );
316 if ( xProvider.is() )
318 css::util::URL aTargetURL;
319 aTargetURL.Complete = aCommand;
320 getURLTransformer()->parseStrict( aTargetURL );
322 Reference < XDispatch > xDispatch = xProvider->queryDispatch( aTargetURL, OUString(), 0 );
323 if ( xDispatch.is() )
324 xDispatch->dispatch( aTargetURL, aArgs );
328 // XStatusListener
329 void SAL_CALL SfxToolBoxControl::statusChanged( const FeatureStateEvent& rEvent )
331 SfxViewFrame* pViewFrame = nullptr;
332 Reference < XController > xController;
334 SolarMutexGuard aGuard;
335 if ( getFrameInterface().is() )
336 xController = getFrameInterface()->getController();
338 Reference < XDispatchProvider > xProvider( xController, UNO_QUERY );
339 if ( xProvider.is() )
341 Reference < XDispatch > xDisp = xProvider->queryDispatch( rEvent.FeatureURL, OUString(), 0 );
342 if ( xDisp.is() )
344 Reference< XUnoTunnel > xTunnel( xDisp, UNO_QUERY );
345 SfxOfficeDispatch* pDisp = nullptr;
346 if ( xTunnel.is() )
348 sal_Int64 nImplementation = xTunnel->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
349 pDisp = reinterpret_cast< SfxOfficeDispatch* >( sal::static_int_cast< sal_IntPtr >( nImplementation ));
352 if ( pDisp )
353 pViewFrame = pDisp->GetDispatcher_Impl()->GetFrame();
357 sal_uInt16 nSlotId = 0;
358 SfxSlotPool& rPool = SfxSlotPool::GetSlotPool( pViewFrame );
359 const SfxSlot* pSlot = rPool.GetUnoSlot( rEvent.FeatureURL.Path );
360 if ( pSlot )
361 nSlotId = pSlot->GetSlotId();
362 else if ( m_aCommandURL == rEvent.FeatureURL.Path )
363 nSlotId = GetSlotId();
365 if ( nSlotId <= 0 )
366 return;
368 if ( rEvent.Requery )
369 svt::ToolboxController::statusChanged( rEvent );
370 else
372 SfxItemState eState = SfxItemState::DISABLED;
373 std::unique_ptr<SfxPoolItem> pItem;
374 if ( rEvent.IsEnabled )
376 eState = SfxItemState::DEFAULT;
377 css::uno::Type aType = rEvent.State.getValueType();
379 if ( aType == cppu::UnoType<void>::get() )
381 pItem.reset(new SfxVoidItem( nSlotId ));
382 eState = SfxItemState::UNKNOWN;
384 else if ( aType == cppu::UnoType<bool>::get() )
386 bool bTemp = false;
387 rEvent.State >>= bTemp ;
388 pItem.reset(new SfxBoolItem( nSlotId, bTemp ));
390 else if ( aType == ::cppu::UnoType< ::cppu::UnoUnsignedShortType >::get())
392 sal_uInt16 nTemp = 0;
393 rEvent.State >>= nTemp ;
394 pItem.reset(new SfxUInt16Item( nSlotId, nTemp ));
396 else if ( aType == cppu::UnoType<sal_uInt32>::get() )
398 sal_uInt32 nTemp = 0;
399 rEvent.State >>= nTemp ;
400 pItem.reset(new SfxUInt32Item( nSlotId, nTemp ));
402 else if ( aType == cppu::UnoType<OUString>::get() )
404 OUString sTemp ;
405 rEvent.State >>= sTemp ;
406 pItem.reset(new SfxStringItem( nSlotId, sTemp ));
408 else if ( aType == cppu::UnoType< css::frame::status::ItemStatus>::get() )
410 ItemStatus aItemStatus;
411 rEvent.State >>= aItemStatus;
412 SfxItemState tmpState = static_cast<SfxItemState>(aItemStatus.State);
413 // make sure no-one tries to send us a combination of states
414 if (tmpState != SfxItemState::UNKNOWN && tmpState != SfxItemState::DISABLED &&
415 tmpState != SfxItemState::READONLY && tmpState != SfxItemState::DONTCARE &&
416 tmpState != SfxItemState::DEFAULT && tmpState != SfxItemState::SET)
417 throw css::uno::RuntimeException("unknown status");
418 eState = tmpState;
419 pItem.reset(new SfxVoidItem( nSlotId ));
421 else if ( aType == cppu::UnoType< css::frame::status::Visibility>::get() )
423 Visibility aVisibilityStatus;
424 rEvent.State >>= aVisibilityStatus;
425 pItem.reset(new SfxVisibilityItem( nSlotId, aVisibilityStatus.bVisible ));
427 else
429 if ( pSlot )
430 pItem = pSlot->GetType()->CreateItem();
431 if ( pItem )
433 pItem->SetWhich( nSlotId );
434 pItem->PutValue( rEvent.State, 0 );
436 else
437 pItem.reset(new SfxVoidItem( nSlotId ));
441 StateChanged( nSlotId, eState, pItem.get() );
445 // XToolbarController
446 void SAL_CALL SfxToolBoxControl::execute( sal_Int16 KeyModifier )
448 SolarMutexGuard aGuard;
449 Select( static_cast<sal_uInt16>(KeyModifier) );
452 void SAL_CALL SfxToolBoxControl::click()
454 SolarMutexGuard aGuard;
455 Click();
458 void SAL_CALL SfxToolBoxControl::doubleClick()
460 SolarMutexGuard aGuard;
461 DoubleClick();
464 Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createPopupWindow()
466 SolarMutexGuard aGuard;
467 CreatePopupWindow();
468 return nullptr;
471 Reference< css::awt::XWindow > SAL_CALL SfxToolBoxControl::createItemWindow( const Reference< css::awt::XWindow >& rParent )
473 SolarMutexGuard aGuard;
474 return VCLUnoHelper::GetInterface( CreateItemWindow( VCLUnoHelper::GetWindow( rParent )));
477 void SfxToolBoxControl::StateChanged
479 sal_uInt16 nId,
480 SfxItemState eState,
481 const SfxPoolItem* pState
484 DBG_ASSERT( pImpl->pBox != nullptr, "setting state to dangling ToolBox" );
486 // enabled/disabled-Flag correcting the lump sum
487 pImpl->pBox->EnableItem( GetId(), eState != SfxItemState::DISABLED );
489 ToolBoxItemBits nItemBits = pImpl->pBox->GetItemBits( GetId() );
490 nItemBits &= ~ToolBoxItemBits::CHECKABLE;
491 ::TriState eTri = TRISTATE_FALSE;
492 switch ( eState )
494 case SfxItemState::DEFAULT:
495 if ( pState )
497 if ( auto pBoolItem = dynamic_cast< const SfxBoolItem* >(pState) )
499 // BoolItem for checking
500 if ( pBoolItem->GetValue() )
501 eTri = TRISTATE_TRUE;
502 nItemBits |= ToolBoxItemBits::CHECKABLE;
504 else if ( dynamic_cast< const SfxEnumItemInterface *>( pState ) != nullptr &&
505 static_cast<const SfxEnumItemInterface *>(pState)->HasBoolValue())
507 // EnumItem is handled as Bool
508 if ( static_cast<const SfxEnumItemInterface *>(pState)->GetBoolValue() )
509 eTri = TRISTATE_TRUE;
510 nItemBits |= ToolBoxItemBits::CHECKABLE;
512 else if ( pImpl->bShowString && dynamic_cast< const SfxStringItem *>( pState ) != nullptr )
513 pImpl->pBox->SetItemText(nId, static_cast<const SfxStringItem*>(pState)->GetValue() );
515 break;
517 case SfxItemState::DONTCARE:
519 eTri = TRISTATE_INDET;
520 nItemBits |= ToolBoxItemBits::CHECKABLE;
522 break;
524 default: break; // do nothing
527 pImpl->pBox->SetItemState( GetId(), eTri );
528 pImpl->pBox->SetItemBits( GetId(), nItemBits );
532 void SfxToolBoxControl::Select( sal_uInt16 nSelectModifier )
534 svt::ToolboxController::execute( nSelectModifier );
538 void SfxToolBoxControl::DoubleClick()
543 void SfxToolBoxControl::Click()
547 void SfxToolBoxControl::CreatePopupWindow()
551 VclPtr<InterimItemWindow> SfxToolBoxControl::CreateItemWindow(vcl::Window*)
553 return VclPtr<InterimItemWindow>();
556 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */