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/lang/XUnoTunnel.hpp>
26 #include <com/sun/star/frame/status/ItemStatus.hpp>
27 #include <com/sun/star/frame/status/ItemState.hpp>
28 #include <com/sun/star/awt/MouseButton.hpp>
30 #include <vcl/status.hxx>
32 #include <sfx2/app.hxx>
33 #include <sfx2/stbitem.hxx>
34 #include "sfxtypes.hxx"
35 #include <sfx2/msg.hxx>
36 #include <sfx2/bindings.hxx>
37 #include <sfx2/msgpool.hxx>
38 #include <sfx2/module.hxx>
39 #include <sfx2/dispatch.hxx>
40 #include <sfx2/unoctitm.hxx>
41 #include <sfx2/objsh.hxx>
42 #include <sfx2/sfx.hrc>
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
;
55 sal_uInt16
SfxStatusBarControl::convertAwtToVCLMouseButtons( sal_Int16 nAwtMouseButtons
)
57 sal_uInt16
nVCLMouseButtons( 0 );
59 if ( nAwtMouseButtons
& awt::MouseButton::LEFT
)
60 nVCLMouseButtons
|= MOUSE_LEFT
;
61 if ( nAwtMouseButtons
& awt::MouseButton::RIGHT
)
62 nVCLMouseButtons
|= MOUSE_RIGHT
;
63 if ( nAwtMouseButtons
& awt::MouseButton::MIDDLE
)
64 nVCLMouseButtons
|= MOUSE_MIDDLE
;
66 return nVCLMouseButtons
;
71 svt::StatusbarController
* SAL_CALL
SfxStatusBarControllerFactory(
72 const uno::Reference
< frame::XFrame
>& rFrame
,
73 StatusBar
* pStatusBar
,
75 const OUString
& aCommandURL
)
77 SolarMutexGuard aGuard
;
80 aTargetURL
.Complete
= aCommandURL
;
81 uno::Reference
< util::XURLTransformer
> xTrans( util::URLTransformer::create( ::comphelper::getProcessComponentContext() ) );
82 xTrans
->parseStrict( aTargetURL
);
84 SfxObjectShell
* pObjShell
= NULL
;
85 uno::Reference
< frame::XController
> xController
;
86 uno::Reference
< frame::XModel
> xModel
;
89 xController
= rFrame
->getController();
90 if ( xController
.is() )
91 xModel
= xController
->getModel();
96 // Get tunnel from model to retrieve the SfxObjectShell pointer from it
97 ::com::sun::star::uno::Reference
< ::com::sun::star::lang::XUnoTunnel
> xObj( xModel
, uno::UNO_QUERY
);
98 ::com::sun::star::uno::Sequence
< sal_Int8
> aSeq
= SvGlobalName( SFX_GLOBAL_CLASSID
).GetByteSequence();
101 sal_Int64 nHandle
= xObj
->getSomething( aSeq
);
103 pObjShell
= reinterpret_cast< SfxObjectShell
* >( sal::static_int_cast
< sal_IntPtr
>( nHandle
));
107 SfxModule
* pModule
= pObjShell
? pObjShell
->GetModule() : NULL
;
108 SfxSlotPool
* pSlotPool
= 0;
111 pSlotPool
= pModule
->GetSlotPool();
113 pSlotPool
= &(SfxSlotPool::GetSlotPool( NULL
));
115 const SfxSlot
* pSlot
= pSlotPool
->GetUnoSlot( aTargetURL
.Path
);
118 sal_uInt16 nSlotId
= pSlot
->GetSlotId();
121 OString
aCmd(".uno:");
122 aCmd
+= pSlot
->GetUnoName();
123 pStatusBar
->SetHelpId( nSlotId
, aCmd
);
124 return SfxStatusBarControl::CreateControl( nSlotId
, nID
, pStatusBar
, pModule
);
133 SfxStatusBarControl::SfxStatusBarControl
135 sal_uInt16 nSlotID
, /* Slot-Id which is connected to this
136 instance. If a Slot-Id is set to != 0 at
137 registration it will always be set there.
141 sal_uInt16 nCtrlID
, /* ID of this controller in the status bar */
143 StatusBar
& rBar
/* Reference to the StatusBar,for which
144 this Control was created. */
150 Constructor of the SfxStatusBarControl Class. The Subclasses are
151 created at the Factory if necessary.
153 Instances of this base class are created for all StatusBar-fields
154 for which no specific ones have been registered.
157 : svt::StatusbarController(),
166 SfxStatusBarControl::~SfxStatusBarControl()
170 Destructor of the SfxStatusBarControl Class. The Class and its Subclasses
171 are destroyed by SFx.
178 uno::Any SAL_CALL
SfxStatusBarControl::queryInterface( const uno::Type
& rType
)
179 throw( uno::RuntimeException
, std::exception
)
181 return svt::StatusbarController::queryInterface( rType
);
184 void SAL_CALL
SfxStatusBarControl::acquire() throw()
186 OWeakObject::acquire();
189 void SAL_CALL
SfxStatusBarControl::release() throw()
191 OWeakObject::release();
196 void SAL_CALL
SfxStatusBarControl::disposing( const lang::EventObject
& aEvent
)
197 throw( uno::RuntimeException
, std::exception
)
199 svt::StatusbarController::disposing( aEvent
);
204 void SAL_CALL
SfxStatusBarControl::dispose()
205 throw (uno::RuntimeException
, std::exception
)
207 svt::StatusbarController::dispose();
212 void SAL_CALL
SfxStatusBarControl::statusChanged( const frame::FeatureStateEvent
& rEvent
)
213 throw ( ::com::sun::star::uno::RuntimeException
, std::exception
)
215 SfxViewFrame
* pViewFrame
= NULL
;
216 uno::Reference
< frame::XController
> xController
;
218 SolarMutexGuard aGuard
;
220 xController
= m_xFrame
->getController();
222 uno::Reference
< frame::XDispatchProvider
> xProvider( xController
, uno::UNO_QUERY
);
223 if ( xProvider
.is() )
225 uno::Reference
< frame::XDispatch
> xDisp
= xProvider
->queryDispatch( rEvent
.FeatureURL
, OUString(), 0 );
228 uno::Reference
< lang::XUnoTunnel
> xTunnel( xDisp
, uno::UNO_QUERY
);
229 SfxOfficeDispatch
* pDisp
= NULL
;
232 sal_Int64 nImplementation
= xTunnel
->getSomething(SfxOfficeDispatch::impl_getStaticIdentifier());
233 pDisp
= reinterpret_cast< SfxOfficeDispatch
* >(sal::static_int_cast
< sal_IntPtr
>( nImplementation
));
237 pViewFrame
= pDisp
->GetDispatcher_Impl()->GetFrame();
241 sal_uInt16 nSlotID
= 0;
242 SfxSlotPool
& rPool
= SfxSlotPool::GetSlotPool( pViewFrame
);
243 const SfxSlot
* pSlot
= rPool
.GetUnoSlot( rEvent
.FeatureURL
.Path
);
245 nSlotID
= pSlot
->GetSlotId();
249 if ( rEvent
.Requery
)
250 svt::StatusbarController::statusChanged( rEvent
);
253 SfxItemState eState
= SfxItemState::DISABLED
;
254 SfxPoolItem
* pItem
= NULL
;
255 if ( rEvent
.IsEnabled
)
257 eState
= SfxItemState::DEFAULT
;
258 uno::Type pType
= rEvent
.State
.getValueType();
260 if ( pType
== cppu::UnoType
<void>::get() )
262 pItem
= new SfxVoidItem( nSlotID
);
263 eState
= SfxItemState::UNKNOWN
;
265 else if ( pType
== cppu::UnoType
<bool>::get() )
268 rEvent
.State
>>= bTemp
;
269 pItem
= new SfxBoolItem( nSlotID
, bTemp
);
271 else if ( pType
== ::cppu::UnoType
< ::cppu::UnoUnsignedShortType
>::get() )
273 sal_uInt16 nTemp
= 0;
274 rEvent
.State
>>= nTemp
;
275 pItem
= new SfxUInt16Item( nSlotID
, nTemp
);
277 else if ( pType
== cppu::UnoType
<sal_uInt32
>::get() )
279 sal_uInt32 nTemp
= 0;
280 rEvent
.State
>>= nTemp
;
281 pItem
= new SfxUInt32Item( nSlotID
, nTemp
);
283 else if ( pType
== cppu::UnoType
<OUString
>::get() )
286 rEvent
.State
>>= sTemp
;
287 pItem
= new SfxStringItem( nSlotID
, sTemp
);
289 else if ( pType
== cppu::UnoType
< ::com::sun::star::frame::status::ItemStatus
>::get() )
291 frame::status::ItemStatus aItemStatus
;
292 rEvent
.State
>>= aItemStatus
;
293 eState
= (SfxItemState
) aItemStatus
.State
;
294 pItem
= new SfxVoidItem( nSlotID
);
299 pItem
= pSlot
->GetType()->CreateItem();
302 pItem
->SetWhich( nSlotID
);
303 pItem
->PutValue( rEvent
.State
);
306 pItem
= new SfxVoidItem( nSlotID
);
310 StateChanged( nSlotID
, eState
, pItem
);
317 // XStatusbarController
319 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonDown(
320 const awt::MouseEvent
& rMouseEvent
)
321 throw ( uno::RuntimeException
, std::exception
)
323 SolarMutexGuard aGuard
;
324 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
326 ::MouseEvent
aMouseEvent( aPos
,
327 (sal_uInt16
)rMouseEvent
.ClickCount
,
328 MouseEventModifiers::NONE
,
329 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
332 return MouseButtonDown( aMouseEvent
);
337 sal_Bool SAL_CALL
SfxStatusBarControl::mouseMove(
338 const awt::MouseEvent
& rMouseEvent
)
339 throw (uno::RuntimeException
, std::exception
)
341 SolarMutexGuard aGuard
;
342 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
344 ::MouseEvent
aMouseEvent( aPos
,
345 (sal_uInt16
)rMouseEvent
.ClickCount
,
346 MouseEventModifiers::NONE
,
347 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
349 return MouseMove( aMouseEvent
);
354 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonUp(
355 const ::awt::MouseEvent
& rMouseEvent
)
356 throw ( uno::RuntimeException
, std::exception
)
358 SolarMutexGuard aGuard
;
359 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
361 ::MouseEvent
aMouseEvent( aPos
,
362 (sal_uInt16
)rMouseEvent
.ClickCount
,
363 MouseEventModifiers::NONE
,
364 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
366 return MouseButtonUp( aMouseEvent
);
371 void SAL_CALL
SfxStatusBarControl::command(
372 const awt::Point
& rPos
,
373 ::sal_Int32 nCommand
,
374 sal_Bool
/*bMouseEvent*/,
375 const ::com::sun::star::uno::Any
& /*aData*/ )
376 throw (::com::sun::star::uno::RuntimeException
, std::exception
)
378 SolarMutexGuard aGuard
;
379 ::Point
aPos( rPos
.X
, rPos
.Y
);
380 CommandEvent
aCmdEvent( aPos
, static_cast<CommandEventId
>(nCommand
), true, NULL
);
382 Command( aCmdEvent
);
387 void SAL_CALL
SfxStatusBarControl::paint(
388 const uno::Reference
< awt::XGraphics
>& xGraphics
,
389 const awt::Rectangle
& rOutputRectangle
,
391 throw ( ::uno::RuntimeException
, std::exception
)
393 SolarMutexGuard aGuard
;
395 OutputDevice
* pOutDev
= VCLUnoHelper::GetOutputDevice( xGraphics
);
398 ::Rectangle aRect
= VCLRectangle( rOutputRectangle
);
399 UserDrawEvent
aUserDrawEvent(nullptr, pOutDev
, aRect
, pBar
->GetCurItemId(), static_cast<sal_uInt16
>(nStyle
));
400 Paint( aUserDrawEvent
);
406 void SAL_CALL
SfxStatusBarControl::click( const awt::Point
& )
407 throw ( uno::RuntimeException
, std::exception
)
409 SolarMutexGuard aGuard
;
415 void SAL_CALL
SfxStatusBarControl::doubleClick( const awt::Point
& )
416 throw ( uno::RuntimeException
, std::exception
)
421 // old sfx2 interface
424 void SfxStatusBarControl::StateChanged
428 const SfxPoolItem
* pState
/* Pointer to SfxPoolItem, is only valid
429 withih this Method call. This can be a
430 Null-Pointer, a Pointer to SfxVoidItem
431 or of this Type found registered by the
432 Subclass of SfxStatusBarControl.
438 The base implementation includes items of type SfxStringItem
439 where the text is entered in the status row field and
440 SfxVoidItem, where the field is emptied. The base implementation
441 should not be called in overriding methods.
445 DBG_ASSERT( pBar
!= nullptr, "setting state to dangling StatusBar" );
447 const SfxStringItem
* pStr
= PTR_CAST( SfxStringItem
, pState
);
448 if ( eState
== SfxItemState::DEFAULT
&& pStr
)
449 pBar
->SetItemText( nSID
, pStr
->GetValue() );
452 DBG_ASSERT( eState
!= SfxItemState::DEFAULT
|| pState
->ISA(SfxVoidItem
),
453 "wrong SfxPoolItem subclass in SfxStatusBarControl" );
454 pBar
->SetItemText( nSID
, OUString() );
460 bool SfxStatusBarControl::MouseButtonDown( const MouseEvent
& )
464 This virtual method forwards the Event MouseButtonDown() of the
465 StatusBar if the mouse position is within the range of the items,
466 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
468 The default implementation is empty and returns FALSE.
473 The event has been processed and is not intended to
474 be forwarded to StatusBar
477 The event was not processed and is to be
478 be forwarded to StatusBar
487 bool SfxStatusBarControl::MouseMove( const MouseEvent
& )
491 This virtual method forwards the Event MouseMove() of the
492 StatusBar if the mouse position is within the range of the items,
493 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
495 The default implementation is empty and returns FALSE.
500 The event has been processed and is not intended to
501 be forwarded to StatusBar
504 The event was not processed and is to be
505 be forwarded to StatusBar
513 bool SfxStatusBarControl::MouseButtonUp( const MouseEvent
& )
517 This virtual method forwards the Event MouseButtonUp() of the
518 StatusBar if the mouse position is within the range of the items,
519 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
521 The default implementation is empty and returns FALSE.
526 The event has been processed and is not intended to
527 be forwarded to StatusBar
530 The event was not processed and is to be
531 be forwarded to StatusBar
540 void SfxStatusBarControl::Command( const CommandEvent
& )
544 This virtual method is called when a CommandEvent is received by
547 The default implementation is empty.
555 void SfxStatusBarControl::Click()
559 This virtual method is called when the user clicks on the
560 field in the status row that belongs to this control.
564 ::com::sun::star::uno::Sequence
< ::com::sun::star::beans::PropertyValue
> aArgs
;
570 void SfxStatusBarControl::Paint
572 const UserDrawEvent
& /* Reference to an UserDrawEvent */
577 This virtual method is called to paint the contents if the field
578 at hand is marked with SIB_USERDRAW. The output must be obtained
579 within the Rectangle of rUDEvt.GetRect() by the OutputDevice
580 given by rUDEvt.GetDevice().
582 The default implementation is empty.
590 SfxStatusBarControl
* SfxStatusBarControl::CreateControl
598 SolarMutexGuard aGuard
;
599 SfxApplication
*pApp
= SfxGetpApp();
601 SfxSlotPool
*pSlotPool
;
603 pSlotPool
= pMod
->GetSlotPool();
605 pSlotPool
= &SfxSlotPool::GetSlotPool();
607 TypeId aSlotType
= pSlotPool
->GetSlotType(nSlotID
);
612 SfxStbCtrlFactArr_Impl
*pFactories
= pMod
->GetStbCtrlFactories_Impl();
615 SfxStbCtrlFactArr_Impl
&rFactories
= *pFactories
;
616 for ( sal_uInt16 nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
617 if ( rFactories
[nFactory
].nTypeId
== aSlotType
&&
618 ( ( rFactories
[nFactory
].nSlotId
== 0 ) ||
619 ( rFactories
[nFactory
].nSlotId
== nSlotID
) ) )
620 return rFactories
[nFactory
].pCtor( nSlotID
, nStbId
, *pBar
);
624 SfxStbCtrlFactArr_Impl
&rFactories
= pApp
->GetStbCtrlFactories_Impl();
625 for ( sal_uInt16 nFactory
= 0; nFactory
< rFactories
.size(); ++nFactory
)
626 if ( rFactories
[nFactory
].nTypeId
== aSlotType
&&
627 ( ( rFactories
[nFactory
].nSlotId
== 0 ) ||
628 ( rFactories
[nFactory
].nSlotId
== nSlotID
) ) )
629 return rFactories
[nFactory
].pCtor( nSlotID
, nStbId
, *pBar
);
636 void SfxStatusBarControl::RegisterStatusBarControl(SfxModule
* pMod
, SfxStbCtrlFactory
* pFact
)
638 SfxGetpApp()->RegisterStatusBarControl_Impl( pMod
, pFact
);
642 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */