1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
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 <comphelper/processfactory.hxx>
46 #include <comphelper/servicehelper.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
49 #include <vcl/InterimItemWindow.hxx>
50 #include <sfx2/tbxctrl.hxx>
51 #include <sfx2/dispatch.hxx>
52 #include <sfx2/msg.hxx>
53 #include <sfx2/msgpool.hxx>
54 #include <sfx2/viewfrm.hxx>
55 #include <sfx2/module.hxx>
56 #include <sfx2/app.hxx>
57 #include <sidebar/ControllerFactory.hxx>
58 #include <unoctitm.hxx>
60 using namespace ::com::sun::star
;
61 using namespace ::com::sun::star::beans
;
62 using namespace ::com::sun::star::frame
;
63 using namespace ::com::sun::star::frame::status
;
64 using namespace ::com::sun::star::lang
;
65 using namespace ::com::sun::star::uno
;
66 using namespace ::com::sun::star::util
;
67 using namespace ::com::sun::star::container
;
68 using namespace ::com::sun::star::ui
;
71 SFX_IMPL_TOOLBOX_CONTROL_ARG(SfxToolBoxControl
, SfxStringItem
, true);
73 rtl::Reference
<svt::ToolboxController
> SfxToolBoxControllerFactory( const Reference
< XFrame
>& rFrame
, ToolBox
* pToolbox
, ToolBoxItemId nID
, const OUString
& aCommandURL
)
75 SolarMutexGuard aGuard
;
78 aTargetURL
.Complete
= aCommandURL
;
79 Reference
< XURLTransformer
> xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
80 xTrans
->parseStrict( aTargetURL
);
81 if ( !aTargetURL
.Arguments
.isEmpty() )
84 Reference
< XController
> xController
;
85 Reference
< XModel
> xModel
;
88 xController
= rFrame
->getController();
89 if ( xController
.is() )
90 xModel
= xController
->getModel();
93 SfxObjectShell
* pObjShell
= SfxObjectShell::GetShellFromComponent(xModel
);
94 SfxModule
* pModule
= pObjShell
? pObjShell
->GetModule() : nullptr;
95 SfxSlotPool
* pSlotPool
= nullptr;
98 pSlotPool
= pModule
->GetSlotPool();
100 pSlotPool
= &(SfxSlotPool::GetSlotPool());
102 const SfxSlot
* pSlot
= pSlotPool
->GetUnoSlot( aTargetURL
.Path
);
105 sal_uInt16 nSlotId
= pSlot
->GetSlotId();
107 return SfxToolBoxControl::CreateControl( nSlotId
, nID
, pToolbox
, pModule
);
113 struct SfxToolBoxControl_Impl
115 VclPtr
<ToolBox
> pBox
;
117 ToolBoxItemId nTbxId
;
121 SfxToolBoxControl::SfxToolBoxControl(
125 bool bShowStringItems
)
126 : pImpl( new SfxToolBoxControl_Impl
)
129 pImpl
->bShowString
= bShowStringItems
;
131 pImpl
->nSlotId
= nSlotID
;
135 SfxToolBoxControl::~SfxToolBoxControl()
140 ToolBox
& SfxToolBoxControl::GetToolBox() const
144 ToolBoxItemId
SfxToolBoxControl::GetId() const
146 return pImpl
->nTbxId
;
148 unsigned short SfxToolBoxControl::GetSlotId() const
150 return pImpl
->nSlotId
;
154 void SAL_CALL
SfxToolBoxControl::dispose()
159 svt::ToolboxController::dispose();
161 // Remove and destroy our item window at our toolbox
162 SolarMutexGuard aGuard
;
163 VclPtr
< vcl::Window
> pWindow
= pImpl
->pBox
->GetItemWindow( pImpl
->nTbxId
);
164 pImpl
->pBox
->SetItemWindow( pImpl
->nTbxId
, nullptr );
165 pWindow
.disposeAndClear();
169 void SfxToolBoxControl::RegisterToolBoxControl( SfxModule
* pMod
, const SfxTbxCtrlFactory
& rFact
)
171 SfxGetpApp()->RegisterToolBoxControl_Impl( pMod
, rFact
);
174 rtl::Reference
<SfxToolBoxControl
> SfxToolBoxControl::CreateControl( sal_uInt16 nSlotId
, ToolBoxItemId nTbxId
, ToolBox
*pBox
, SfxModule
const * pMod
)
176 SolarMutexGuard aGuard
;
178 SfxApplication
*pApp
= SfxGetpApp();
180 SfxSlotPool
*pSlotPool
;
182 pSlotPool
= pMod
->GetSlotPool();
184 pSlotPool
= &SfxSlotPool::GetSlotPool();
185 const std::type_info
* aSlotType
= pSlotPool
->GetSlotType( nSlotId
);
190 SfxTbxCtrlFactory
*pFact
= pMod
->GetTbxCtrlFactory(*aSlotType
, nSlotId
);
192 return pFact
->pCtor( nSlotId
, nTbxId
, *pBox
);
195 SfxTbxCtrlFactory
* pFact
= pApp
->GetTbxCtrlFactory(*aSlotType
, nSlotId
);
197 return pFact
->pCtor( nSlotId
, nTbxId
, *pBox
);
203 SfxItemState
SfxToolBoxControl::GetItemState(
204 const SfxPoolItem
* pState
)
207 Static method for determining the status of the SfxPoolItem-pointer,
208 used in the method <SfxControllerItem::StateChanged(const SfxPoolItem*)>.
212 SfxItemState SfxItemState::UNKNOWN
213 Enabled, however no further status information is available.
214 Typical for <Slot>s, which are temporarily disabled a
215 anyway but other than that do not change their appearance.
217 SfxItemState::DISABLED
218 Disabled, no further status information is available.
219 All other displayed values should be reset to the default
222 SfxItemState::DONTCARE
223 Enabled but there were only ambiguous values available
224 (i.e. none that could be queried).
226 SfxItemState::DEFAULT
227 Enabled and with available values which can be queried
228 through'pState'. The type is thus by the Slot clearly
229 defined in the entire Program.
234 ? SfxItemState::DISABLED
235 : IsInvalidItem(pState
)
236 ? SfxItemState::DONTCARE
237 : pState
->IsVoidItem() && !pState
->Which()
238 ? SfxItemState::UNKNOWN
239 : SfxItemState::DEFAULT
;
242 void SfxToolBoxControl::Dispatch(
243 const Reference
< XDispatchProvider
>& rProvider
,
244 const OUString
& rCommand
,
245 Sequence
< ::PropertyValue
> const & aArgs
)
247 if ( rProvider
.is() )
249 css::util::URL aTargetURL
;
250 aTargetURL
.Complete
= rCommand
;
251 Reference
< XURLTransformer
> xTrans( URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
252 xTrans
->parseStrict( aTargetURL
);
254 Reference
< XDispatch
> xDispatch
= rProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
255 if ( xDispatch
.is() )
256 xDispatch
->dispatch( aTargetURL
, aArgs
);
260 void SfxToolBoxControl::Dispatch( const OUString
& aCommand
, css::uno::Sequence
< css::beans::PropertyValue
> const & aArgs
)
262 Reference
< XController
> xController
;
264 SolarMutexGuard aGuard
;
265 if ( getFrameInterface().is() )
266 xController
= getFrameInterface()->getController();
268 Reference
< XDispatchProvider
> xProvider( xController
, UNO_QUERY
);
269 if ( xProvider
.is() )
271 css::util::URL aTargetURL
;
272 aTargetURL
.Complete
= aCommand
;
273 getURLTransformer()->parseStrict( aTargetURL
);
275 Reference
< XDispatch
> xDispatch
= xProvider
->queryDispatch( aTargetURL
, OUString(), 0 );
276 if ( xDispatch
.is() )
277 xDispatch
->dispatch( aTargetURL
, aArgs
);
282 void SAL_CALL
SfxToolBoxControl::statusChanged( const FeatureStateEvent
& rEvent
)
284 SfxViewFrame
* pViewFrame
= nullptr;
285 Reference
< XController
> xController
;
287 SolarMutexGuard aGuard
;
288 if ( getFrameInterface().is() )
289 xController
= getFrameInterface()->getController();
291 Reference
< XDispatchProvider
> xProvider( xController
, UNO_QUERY
);
292 if ( xProvider
.is() )
294 Reference
< XDispatch
> xDisp
= xProvider
->queryDispatch( rEvent
.FeatureURL
, OUString(), 0 );
297 Reference
< XUnoTunnel
> xTunnel( xDisp
, UNO_QUERY
);
298 if (auto pDisp
= comphelper::getFromUnoTunnel
<SfxOfficeDispatch
>(xTunnel
))
299 pViewFrame
= pDisp
->GetDispatcher_Impl()->GetFrame();
303 sal_uInt16 nSlotId
= 0;
304 SfxSlotPool
& rPool
= SfxSlotPool::GetSlotPool( pViewFrame
);
305 const SfxSlot
* pSlot
= rPool
.GetUnoSlot( rEvent
.FeatureURL
.Path
);
307 nSlotId
= pSlot
->GetSlotId();
308 else if ( m_aCommandURL
== rEvent
.FeatureURL
.Path
)
309 nSlotId
= GetSlotId();
314 if ( rEvent
.Requery
)
315 svt::ToolboxController::statusChanged( rEvent
);
318 SfxItemState eState
= SfxItemState::DISABLED
;
319 std::unique_ptr
<SfxPoolItem
> pItem
;
320 if ( rEvent
.IsEnabled
)
322 eState
= SfxItemState::DEFAULT
;
323 css::uno::Type aType
= rEvent
.State
.getValueType();
325 if ( aType
== cppu::UnoType
<void>::get() )
327 pItem
.reset(new SfxVoidItem( nSlotId
));
328 eState
= SfxItemState::UNKNOWN
;
330 else if ( aType
== cppu::UnoType
<bool>::get() )
333 rEvent
.State
>>= bTemp
;
334 pItem
.reset(new SfxBoolItem( nSlotId
, bTemp
));
336 else if ( aType
== ::cppu::UnoType
< ::cppu::UnoUnsignedShortType
>::get())
338 sal_uInt16 nTemp
= 0;
339 rEvent
.State
>>= nTemp
;
340 pItem
.reset(new SfxUInt16Item( nSlotId
, nTemp
));
342 else if ( aType
== cppu::UnoType
<sal_uInt32
>::get() )
344 sal_uInt32 nTemp
= 0;
345 rEvent
.State
>>= nTemp
;
346 pItem
.reset(new SfxUInt32Item( nSlotId
, nTemp
));
348 else if ( aType
== cppu::UnoType
<OUString
>::get() )
351 rEvent
.State
>>= sTemp
;
352 pItem
.reset(new SfxStringItem( nSlotId
, sTemp
));
354 else if ( aType
== cppu::UnoType
< css::frame::status::ItemStatus
>::get() )
356 ItemStatus aItemStatus
;
357 rEvent
.State
>>= aItemStatus
;
358 SfxItemState tmpState
= static_cast<SfxItemState
>(aItemStatus
.State
);
359 // make sure no-one tries to send us a combination of states
360 if (tmpState
!= SfxItemState::UNKNOWN
&& tmpState
!= SfxItemState::DISABLED
&&
361 tmpState
!= SfxItemState::DONTCARE
&&
362 tmpState
!= SfxItemState::DEFAULT
&& tmpState
!= SfxItemState::SET
)
363 throw css::uno::RuntimeException("unknown status");
365 pItem
.reset(new SfxVoidItem( nSlotId
));
367 else if ( aType
== cppu::UnoType
< css::frame::status::Visibility
>::get() )
369 Visibility aVisibilityStatus
;
370 rEvent
.State
>>= aVisibilityStatus
;
371 pItem
.reset(new SfxVisibilityItem( nSlotId
, aVisibilityStatus
.bVisible
));
376 pItem
= pSlot
->GetType()->CreateItem();
379 pItem
->SetWhich( nSlotId
);
380 pItem
->PutValue( rEvent
.State
, 0 );
383 pItem
.reset(new SfxVoidItem( nSlotId
));
387 StateChangedAtToolBoxControl( nSlotId
, eState
, pItem
.get() );
391 // XToolbarController
392 void SAL_CALL
SfxToolBoxControl::execute( sal_Int16 KeyModifier
)
394 SolarMutexGuard aGuard
;
395 Select( static_cast<sal_uInt16
>(KeyModifier
) );
398 void SAL_CALL
SfxToolBoxControl::click()
400 SolarMutexGuard aGuard
;
404 void SAL_CALL
SfxToolBoxControl::doubleClick()
406 SolarMutexGuard aGuard
;
410 Reference
< css::awt::XWindow
> SAL_CALL
SfxToolBoxControl::createPopupWindow()
412 SolarMutexGuard aGuard
;
417 Reference
< css::awt::XWindow
> SAL_CALL
SfxToolBoxControl::createItemWindow( const Reference
< css::awt::XWindow
>& rParent
)
419 SolarMutexGuard aGuard
;
420 return VCLUnoHelper::GetInterface( CreateItemWindow( VCLUnoHelper::GetWindow( rParent
)));
423 void SfxToolBoxControl::StateChangedAtToolBoxControl
425 sal_uInt16
/*nSlotId*/,
427 const SfxPoolItem
* pState
430 DBG_ASSERT( pImpl
->pBox
!= nullptr, "setting state to dangling ToolBox" );
432 // enabled/disabled-Flag correcting the lump sum
433 pImpl
->pBox
->EnableItem( GetId(), eState
!= SfxItemState::DISABLED
);
435 ToolBoxItemBits nItemBits
= pImpl
->pBox
->GetItemBits( GetId() );
436 nItemBits
&= ~ToolBoxItemBits::CHECKABLE
;
437 ::TriState eTri
= TRISTATE_FALSE
;
440 case SfxItemState::DEFAULT
:
443 if ( auto pBoolItem
= dynamic_cast< const SfxBoolItem
* >(pState
) )
445 // BoolItem for checking
446 if ( pBoolItem
->GetValue() )
447 eTri
= TRISTATE_TRUE
;
448 nItemBits
|= ToolBoxItemBits::CHECKABLE
;
450 else if ( auto pEnumItem
= dynamic_cast< const SfxEnumItemInterface
*>( pState
) )
452 if (pEnumItem
->HasBoolValue())
454 // EnumItem is handled as Bool
455 if (pEnumItem
->GetBoolValue())
456 eTri
= TRISTATE_TRUE
;
457 nItemBits
|= ToolBoxItemBits::CHECKABLE
;
460 else if ( pImpl
->bShowString
)
462 if (auto pStringItem
= dynamic_cast< const SfxStringItem
*>( pState
) )
463 pImpl
->pBox
->SetItemText(GetId(), pStringItem
->GetValue() );
468 case SfxItemState::DONTCARE
:
470 eTri
= TRISTATE_INDET
;
471 nItemBits
|= ToolBoxItemBits::CHECKABLE
;
475 default: break; // do nothing
478 pImpl
->pBox
->SetItemState( GetId(), eTri
);
479 pImpl
->pBox
->SetItemBits( GetId(), nItemBits
);
483 void SfxToolBoxControl::Select( sal_uInt16 nSelectModifier
)
485 svt::ToolboxController::execute( nSelectModifier
);
489 void SfxToolBoxControl::DoubleClick()
494 void SfxToolBoxControl::Click()
498 void SfxToolBoxControl::CreatePopupWindow()
502 VclPtr
<InterimItemWindow
> SfxToolBoxControl::CreateItemWindow(vcl::Window
*)
504 return VclPtr
<InterimItemWindow
>();
507 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */