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 .
20 #include <svl/stritem.hxx>
21 #include <com/sun/star/util/URL.hpp>
22 #include <com/sun/star/util/URLTransformer.hpp>
23 #include <com/sun/star/util/XURLTransformer.hpp>
24 #include <com/sun/star/frame/XController.hpp>
25 #include <com/sun/star/frame/XDispatchProvider.hpp>
26 #include <com/sun/star/lang/XUnoTunnel.hpp>
27 #include <com/sun/star/frame/status/ItemStatus.hpp>
28 #include <com/sun/star/awt/MouseButton.hpp>
30 #include <vcl/commandevent.hxx>
31 #include <vcl/event.hxx>
32 #include <vcl/status.hxx>
33 #include <vcl/svapp.hxx>
35 #include <sfx2/app.hxx>
36 #include <sfx2/stbitem.hxx>
37 #include <sfx2/msg.hxx>
38 #include <sfx2/msgpool.hxx>
39 #include <sfx2/module.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <unoctitm.hxx>
42 #include <sfx2/objsh.hxx>
44 #include <comphelper/processfactory.hxx>
45 #include <svl/eitem.hxx>
46 #include <svl/intitem.hxx>
47 #include <toolkit/helper/vclunohelper.hxx>
48 #include <toolkit/helper/convert.hxx>
49 #include <ctrlfactoryimpl.hxx>
51 using namespace ::com::sun::star
;
54 sal_uInt16
SfxStatusBarControl::convertAwtToVCLMouseButtons( sal_Int16 nAwtMouseButtons
)
56 sal_uInt16
nVCLMouseButtons( 0 );
58 if ( nAwtMouseButtons
& awt::MouseButton::LEFT
)
59 nVCLMouseButtons
|= MOUSE_LEFT
;
60 if ( nAwtMouseButtons
& awt::MouseButton::RIGHT
)
61 nVCLMouseButtons
|= MOUSE_RIGHT
;
62 if ( nAwtMouseButtons
& awt::MouseButton::MIDDLE
)
63 nVCLMouseButtons
|= MOUSE_MIDDLE
;
65 return nVCLMouseButtons
;
69 svt::StatusbarController
* SfxStatusBarControllerFactory(
70 const uno::Reference
< frame::XFrame
>& rFrame
,
71 StatusBar
* pStatusBar
,
73 const OUString
& aCommandURL
)
75 SolarMutexGuard aGuard
;
78 aTargetURL
.Complete
= aCommandURL
;
79 uno::Reference
< util::XURLTransformer
> xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
80 xTrans
->parseStrict( aTargetURL
);
82 uno::Reference
< frame::XController
> xController
;
83 uno::Reference
< frame::XModel
> xModel
;
86 xController
= rFrame
->getController();
87 if ( xController
.is() )
88 xModel
= xController
->getModel();
91 SfxObjectShell
* pObjShell
= SfxObjectShell::GetShellFromComponent(xModel
);
93 SfxModule
* pModule
= pObjShell
? pObjShell
->GetModule() : nullptr;
94 SfxSlotPool
* pSlotPool
= nullptr;
97 pSlotPool
= pModule
->GetSlotPool();
99 pSlotPool
= &(SfxSlotPool::GetSlotPool());
101 const SfxSlot
* pSlot
= pSlotPool
->GetUnoSlot( aTargetURL
.Path
);
104 sal_uInt16 nSlotId
= pSlot
->GetSlotId();
107 OString aCmd
= OStringLiteral(".uno:") + pSlot
->GetUnoName();
108 pStatusBar
->SetHelpId( nSlotId
, aCmd
);
109 return SfxStatusBarControl::CreateControl( nSlotId
, nID
, pStatusBar
, pModule
);
117 SfxStatusBarControl::SfxStatusBarControl
119 sal_uInt16 nSlotID
, /* Slot-Id which is connected to this
120 instance. If a Slot-Id is set to != 0 at
121 registration it will always be set there.
125 sal_uInt16 nCtrlID
, /* ID of this controller in the status bar */
127 StatusBar
& rBar
/* Reference to the StatusBar,for which
128 this Control was created. */
134 Constructor of the SfxStatusBarControl Class. The Subclasses are
135 created at the Factory if necessary.
137 Instances of this base class are created for all StatusBar-fields
138 for which no specific ones have been registered.
141 : svt::StatusbarController(),
149 SfxStatusBarControl::~SfxStatusBarControl()
153 Destructor of the SfxStatusBarControl Class. The Class and its Subclasses
154 are destroyed by SFx.
161 void SAL_CALL
SfxStatusBarControl::acquire() throw()
163 OWeakObject::acquire();
166 void SAL_CALL
SfxStatusBarControl::release() throw()
168 OWeakObject::release();
173 void SAL_CALL
SfxStatusBarControl::statusChanged( const frame::FeatureStateEvent
& rEvent
)
175 SfxViewFrame
* pViewFrame
= nullptr;
176 uno::Reference
< frame::XController
> xController
;
178 SolarMutexGuard aGuard
;
180 xController
= m_xFrame
->getController();
182 uno::Reference
< frame::XDispatchProvider
> xProvider( xController
, uno::UNO_QUERY
);
183 if ( xProvider
.is() )
185 uno::Reference
< frame::XDispatch
> xDisp
= xProvider
->queryDispatch( rEvent
.FeatureURL
, OUString(), 0 );
188 uno::Reference
< lang::XUnoTunnel
> xTunnel( xDisp
, uno::UNO_QUERY
);
189 SfxOfficeDispatch
* pDisp
= nullptr;
192 sal_Int64 nImplementation
= xTunnel
->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
193 pDisp
= reinterpret_cast< SfxOfficeDispatch
* >(sal::static_int_cast
< sal_IntPtr
>( nImplementation
));
197 pViewFrame
= pDisp
->GetDispatcher_Impl()->GetFrame();
201 sal_uInt16 nSlotID
= 0;
202 SfxSlotPool
& rPool
= SfxSlotPool::GetSlotPool( pViewFrame
);
203 const SfxSlot
* pSlot
= rPool
.GetUnoSlot( rEvent
.FeatureURL
.Path
);
205 nSlotID
= pSlot
->GetSlotId();
210 if ( rEvent
.Requery
)
211 svt::StatusbarController::statusChanged( rEvent
);
214 SfxItemState eState
= SfxItemState::DISABLED
;
215 std::unique_ptr
<SfxPoolItem
> pItem
;
216 if ( rEvent
.IsEnabled
)
218 eState
= SfxItemState::DEFAULT
;
219 uno::Type aType
= rEvent
.State
.getValueType();
221 if ( aType
== cppu::UnoType
<void>::get() )
223 pItem
.reset( new SfxVoidItem( nSlotID
) );
224 eState
= SfxItemState::UNKNOWN
;
226 else if ( aType
== cppu::UnoType
<bool>::get() )
229 rEvent
.State
>>= bTemp
;
230 pItem
.reset( new SfxBoolItem( nSlotID
, bTemp
) );
232 else if ( aType
== ::cppu::UnoType
< ::cppu::UnoUnsignedShortType
>::get() )
234 sal_uInt16 nTemp
= 0;
235 rEvent
.State
>>= nTemp
;
236 pItem
.reset( new SfxUInt16Item( nSlotID
, nTemp
) );
238 else if ( aType
== cppu::UnoType
<sal_uInt32
>::get() )
240 sal_uInt32 nTemp
= 0;
241 rEvent
.State
>>= nTemp
;
242 pItem
.reset( new SfxUInt32Item( nSlotID
, nTemp
) );
244 else if ( aType
== cppu::UnoType
<OUString
>::get() )
247 rEvent
.State
>>= sTemp
;
248 pItem
.reset( new SfxStringItem( nSlotID
, sTemp
) );
250 else if ( aType
== cppu::UnoType
< css::frame::status::ItemStatus
>::get() )
252 frame::status::ItemStatus aItemStatus
;
253 rEvent
.State
>>= aItemStatus
;
254 eState
= static_cast<SfxItemState
>(aItemStatus
.State
);
255 pItem
.reset( new SfxVoidItem( nSlotID
) );
260 pItem
= pSlot
->GetType()->CreateItem();
263 pItem
->SetWhich( nSlotID
);
264 pItem
->PutValue( rEvent
.State
, 0 );
267 pItem
.reset( new SfxVoidItem( nSlotID
) );
271 StateChanged( nSlotID
, eState
, pItem
.get() );
275 // XStatusbarController
276 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonDown(
277 const awt::MouseEvent
& rMouseEvent
)
279 SolarMutexGuard aGuard
;
280 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
282 ::MouseEvent
aMouseEvent( aPos
,
283 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
284 MouseEventModifiers::NONE
,
285 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
288 return MouseButtonDown( aMouseEvent
);
291 sal_Bool SAL_CALL
SfxStatusBarControl::mouseMove(
292 const awt::MouseEvent
& rMouseEvent
)
294 SolarMutexGuard aGuard
;
295 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
297 ::MouseEvent
aMouseEvent( aPos
,
298 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
299 MouseEventModifiers::NONE
,
300 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
302 return MouseMove( aMouseEvent
);
305 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonUp(
306 const ::awt::MouseEvent
& rMouseEvent
)
308 SolarMutexGuard aGuard
;
309 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
311 ::MouseEvent
aMouseEvent( aPos
,
312 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
313 MouseEventModifiers::NONE
,
314 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
316 return MouseButtonUp( aMouseEvent
);
319 void SAL_CALL
SfxStatusBarControl::command(
320 const awt::Point
& rPos
,
321 ::sal_Int32 nCommand
,
322 sal_Bool
/*bMouseEvent*/,
323 const css::uno::Any
& /*aData*/ )
325 SolarMutexGuard aGuard
;
326 ::Point
aPos( rPos
.X
, rPos
.Y
);
327 CommandEvent
aCmdEvent( aPos
, static_cast<CommandEventId
>(nCommand
), true, nullptr );
329 Command( aCmdEvent
);
332 void SAL_CALL
SfxStatusBarControl::paint(
333 const uno::Reference
< awt::XGraphics
>& xGraphics
,
334 const awt::Rectangle
& rOutputRectangle
,
335 ::sal_Int32
/*nStyle*/ )
337 SolarMutexGuard aGuard
;
339 OutputDevice
* pOutDev
= VCLUnoHelper::GetOutputDevice( xGraphics
);
342 ::tools::Rectangle aRect
= VCLRectangle( rOutputRectangle
);
343 UserDrawEvent
aUserDrawEvent(nullptr, pOutDev
, aRect
, pBar
->GetCurItemId());
344 Paint( aUserDrawEvent
);
348 void SAL_CALL
SfxStatusBarControl::click( const awt::Point
& )
350 SolarMutexGuard aGuard
;
354 void SAL_CALL
SfxStatusBarControl::doubleClick( const awt::Point
& )
358 // old sfx2 interface
359 void SfxStatusBarControl::StateChanged
363 const SfxPoolItem
* pState
/* Pointer to SfxPoolItem, is only valid
364 within this Method call. This can be a
365 Null-Pointer, a Pointer to SfxVoidItem
366 or of this Type found registered by the
367 Subclass of SfxStatusBarControl.
373 The base implementation includes items of type SfxStringItem
374 where the text is entered in the status row field and
375 SfxVoidItem, where the field is emptied. The base implementation
376 should not be called in overriding methods.
380 DBG_ASSERT( pBar
!= nullptr, "setting state to dangling StatusBar" );
382 const SfxStringItem
* pStr
= dynamic_cast<const SfxStringItem
*>( pState
);
383 if ( eState
== SfxItemState::DEFAULT
&& pStr
)
384 pBar
->SetItemText( nSID
, pStr
->GetValue() );
387 DBG_ASSERT( eState
!= SfxItemState::DEFAULT
|| pState
->IsVoidItem(),
388 "wrong SfxPoolItem subclass in SfxStatusBarControl" );
389 pBar
->SetItemText( nSID
, OUString() );
394 bool SfxStatusBarControl::MouseButtonDown( const MouseEvent
& )
398 This virtual method forwards the Event MouseButtonDown() of the
399 StatusBar if the mouse position is within the range of the items,
400 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
402 The default implementation is empty and returns FALSE.
407 The event has been processed and is not intended to
408 be forwarded to StatusBar
411 The event was not processed and is to be
412 be forwarded to StatusBar
420 bool SfxStatusBarControl::MouseMove( const MouseEvent
& )
424 This virtual method forwards the Event MouseMove() of the
425 StatusBar if the mouse position is within the range of the items,
426 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
428 The default implementation is empty and returns FALSE.
433 The event has been processed and is not intended to
434 be forwarded to StatusBar
437 The event was not processed and is to be
438 be forwarded to StatusBar
446 bool SfxStatusBarControl::MouseButtonUp( const MouseEvent
& )
450 This virtual method forwards the Event MouseButtonUp() of the
451 StatusBar if the mouse position is within the range of the items,
452 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
454 The default implementation is empty and returns FALSE.
459 The event has been processed and is not intended to
460 be forwarded to StatusBar
463 The event was not processed and is to be
464 be forwarded to StatusBar
472 void SfxStatusBarControl::Command( const CommandEvent
& )
476 This virtual method is called when a CommandEvent is received by
479 The default implementation is empty.
486 void SfxStatusBarControl::Click()
490 This virtual method is called when the user clicks on the
491 field in the status row that belongs to this control.
495 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
;
500 void SfxStatusBarControl::Paint
502 const UserDrawEvent
& /* Reference to an UserDrawEvent */
507 This virtual method is called to paint the contents if the field
508 at hand is marked with StatusBarItemBits::UserDraw. The output must be obtained
509 within the Rectangle of rUDEvt.GetRect() by the OutputDevice
510 given by rUDEvt.GetDevice().
512 The default implementation is empty.
519 SfxStatusBarControl
* SfxStatusBarControl::CreateControl
524 SfxModule
const * pMod
527 SolarMutexGuard aGuard
;
528 SfxApplication
*pApp
= SfxGetpApp();
530 SfxSlotPool
*pSlotPool
;
532 pSlotPool
= pMod
->GetSlotPool();
534 pSlotPool
= &SfxSlotPool::GetSlotPool();
536 const std::type_info
* aSlotType
= pSlotPool
->GetSlotType(nSlotID
);
541 SfxStbCtrlFactArr_Impl
*pFactories
= pMod
->GetStbCtrlFactories_Impl();
544 SfxStbCtrlFactArr_Impl
&rFactories
= *pFactories
;
545 for ( size_t nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
546 if ( rFactories
[nFactory
].nTypeId
== *aSlotType
&&
547 ( ( rFactories
[nFactory
].nSlotId
== 0 ) ||
548 ( rFactories
[nFactory
].nSlotId
== nSlotID
) ) )
549 return rFactories
[nFactory
].pCtor( nSlotID
, nStbId
, *pBar
);
553 SfxStbCtrlFactArr_Impl
&rFactories
= pApp
->GetStbCtrlFactories_Impl();
554 for ( size_t nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
555 if ( rFactories
[nFactory
].nTypeId
== *aSlotType
&&
556 ( ( rFactories
[nFactory
].nSlotId
== 0 ) ||
557 ( rFactories
[nFactory
].nSlotId
== nSlotID
) ) )
558 return rFactories
[nFactory
].pCtor( nSlotID
, nStbId
, *pBar
);
565 void SfxStatusBarControl::RegisterStatusBarControl(SfxModule
* pMod
, const SfxStbCtrlFactory
& rFact
)
567 SfxGetpApp()->RegisterStatusBarControl_Impl( pMod
, rFact
);
571 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */