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 <comphelper/servicehelper.hxx>
46 #include <svl/eitem.hxx>
47 #include <svl/intitem.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include <toolkit/helper/convert.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 rtl::Reference
<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 OUString aCmd
= pSlot
->GetCommand();
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 : nSlotId( nSlotID
),
148 SfxStatusBarControl::~SfxStatusBarControl()
152 Destructor of the SfxStatusBarControl Class. The Class and its Subclasses
153 are destroyed by SFx.
160 void SAL_CALL
SfxStatusBarControl::acquire() noexcept
162 OWeakObject::acquire();
165 void SAL_CALL
SfxStatusBarControl::release() noexcept
167 OWeakObject::release();
172 void SAL_CALL
SfxStatusBarControl::statusChanged( const frame::FeatureStateEvent
& rEvent
)
174 SfxViewFrame
* pViewFrame
= nullptr;
175 uno::Reference
< frame::XController
> xController
;
177 SolarMutexGuard aGuard
;
179 xController
= m_xFrame
->getController();
181 uno::Reference
< frame::XDispatchProvider
> xProvider( xController
, uno::UNO_QUERY
);
182 if ( xProvider
.is() )
184 uno::Reference
< frame::XDispatch
> xDisp
= xProvider
->queryDispatch( rEvent
.FeatureURL
, OUString(), 0 );
187 if (auto pDisp
= dynamic_cast<SfxOfficeDispatch
*>(xDisp
.get()))
188 pViewFrame
= pDisp
->GetDispatcher_Impl()->GetFrame();
192 sal_uInt16 nSlotID
= 0;
193 SfxSlotPool
& rPool
= SfxSlotPool::GetSlotPool( pViewFrame
);
194 const SfxSlot
* pSlot
= rPool
.GetUnoSlot( rEvent
.FeatureURL
.Path
);
196 nSlotID
= pSlot
->GetSlotId();
201 if ( rEvent
.Requery
)
202 svt::StatusbarController::statusChanged( rEvent
);
205 SfxItemState eState
= SfxItemState::DISABLED
;
206 std::unique_ptr
<SfxPoolItem
> pItem
;
207 if ( rEvent
.IsEnabled
)
209 eState
= SfxItemState::DEFAULT
;
210 uno::Type aType
= rEvent
.State
.getValueType();
212 if ( aType
== cppu::UnoType
<void>::get() )
214 pItem
.reset( new SfxVoidItem( nSlotID
) );
215 eState
= SfxItemState::UNKNOWN
;
217 else if ( aType
== cppu::UnoType
<bool>::get() )
220 rEvent
.State
>>= bTemp
;
221 pItem
.reset( new SfxBoolItem( nSlotID
, bTemp
) );
223 else if ( aType
== ::cppu::UnoType
< ::cppu::UnoUnsignedShortType
>::get() )
225 sal_uInt16 nTemp
= 0;
226 rEvent
.State
>>= nTemp
;
227 pItem
.reset( new SfxUInt16Item( nSlotID
, nTemp
) );
229 else if ( aType
== cppu::UnoType
<sal_uInt32
>::get() )
231 sal_uInt32 nTemp
= 0;
232 rEvent
.State
>>= nTemp
;
233 pItem
.reset( new SfxUInt32Item( nSlotID
, nTemp
) );
235 else if ( aType
== cppu::UnoType
<OUString
>::get() )
238 rEvent
.State
>>= sTemp
;
239 pItem
.reset( new SfxStringItem( nSlotID
, sTemp
) );
241 else if ( aType
== cppu::UnoType
< css::frame::status::ItemStatus
>::get() )
243 frame::status::ItemStatus aItemStatus
;
244 rEvent
.State
>>= aItemStatus
;
245 eState
= static_cast<SfxItemState
>(aItemStatus
.State
);
246 pItem
.reset( new SfxVoidItem( nSlotID
) );
251 pItem
= pSlot
->GetType()->CreateItem();
254 pItem
->SetWhich( nSlotID
);
255 pItem
->PutValue( rEvent
.State
, 0 );
258 pItem
.reset( new SfxVoidItem( nSlotID
) );
262 StateChangedAtStatusBarControl( nSlotID
, eState
, pItem
.get() );
266 // XStatusbarController
267 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonDown(
268 const awt::MouseEvent
& rMouseEvent
)
270 SolarMutexGuard aGuard
;
271 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
273 ::MouseEvent
aMouseEvent( aPos
,
274 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
275 MouseEventModifiers::NONE
,
276 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
279 return MouseButtonDown( aMouseEvent
);
282 sal_Bool SAL_CALL
SfxStatusBarControl::mouseMove(
283 const awt::MouseEvent
& rMouseEvent
)
285 SolarMutexGuard aGuard
;
286 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
288 ::MouseEvent
aMouseEvent( aPos
,
289 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
290 MouseEventModifiers::NONE
,
291 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
293 return MouseMove( aMouseEvent
);
296 sal_Bool SAL_CALL
SfxStatusBarControl::mouseButtonUp(
297 const ::awt::MouseEvent
& rMouseEvent
)
299 SolarMutexGuard aGuard
;
300 ::Point
aPos( rMouseEvent
.X
, rMouseEvent
.Y
);
302 ::MouseEvent
aMouseEvent( aPos
,
303 static_cast<sal_uInt16
>(rMouseEvent
.ClickCount
),
304 MouseEventModifiers::NONE
,
305 convertAwtToVCLMouseButtons( rMouseEvent
.Buttons
),
307 return MouseButtonUp( aMouseEvent
);
310 void SAL_CALL
SfxStatusBarControl::command(
311 const awt::Point
& rPos
,
312 ::sal_Int32 nCommand
,
313 sal_Bool
/*bMouseEvent*/,
314 const css::uno::Any
& /*aData*/ )
316 SolarMutexGuard aGuard
;
317 ::Point
aPos( rPos
.X
, rPos
.Y
);
318 CommandEvent
aCmdEvent( aPos
, static_cast<CommandEventId
>(nCommand
), true, nullptr );
320 Command( aCmdEvent
);
323 void SAL_CALL
SfxStatusBarControl::paint(
324 const uno::Reference
< awt::XGraphics
>& xGraphics
,
325 const awt::Rectangle
& rOutputRectangle
,
326 ::sal_Int32
/*nStyle*/ )
328 SolarMutexGuard aGuard
;
330 OutputDevice
* pOutDev
= VCLUnoHelper::GetOutputDevice( xGraphics
);
333 ::tools::Rectangle aRect
= VCLRectangle( rOutputRectangle
);
334 UserDrawEvent
aUserDrawEvent(pOutDev
, aRect
, pBar
->GetCurItemId());
335 Paint( aUserDrawEvent
);
339 void SAL_CALL
SfxStatusBarControl::click( const awt::Point
& )
341 SolarMutexGuard aGuard
;
345 void SAL_CALL
SfxStatusBarControl::doubleClick( const awt::Point
& )
349 // old sfx2 interface
350 void SfxStatusBarControl::StateChangedAtStatusBarControl
354 const SfxPoolItem
* pState
/* Pointer to SfxPoolItem, is only valid
355 within this Method call. This can be a
356 Null-Pointer, a Pointer to SfxVoidItem
357 or of this Type found registered by the
358 Subclass of SfxStatusBarControl.
364 The base implementation includes items of type SfxStringItem
365 where the text is entered in the status row field and
366 SfxVoidItem, where the field is emptied. The base implementation
367 should not be called in overriding methods.
371 DBG_ASSERT( pBar
!= nullptr, "setting state to dangling StatusBar" );
373 const SfxStringItem
* pStr
= dynamic_cast<const SfxStringItem
*>( pState
);
374 if ( eState
== SfxItemState::DEFAULT
&& pStr
)
375 pBar
->SetItemText( nSID
, pStr
->GetValue() );
378 DBG_ASSERT( eState
!= SfxItemState::DEFAULT
|| pState
->IsVoidItem(),
379 "wrong SfxPoolItem subclass in SfxStatusBarControl" );
380 pBar
->SetItemText( nSID
, OUString() );
385 bool SfxStatusBarControl::MouseButtonDown( const MouseEvent
& )
389 This virtual method forwards the Event MouseButtonDown() of the
390 StatusBar if the mouse position is within the range of the items,
391 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
393 The default implementation is empty and returns FALSE.
398 The event has been processed and is not intended to
399 be forwarded to StatusBar
402 The event was not processed and is to be
403 be forwarded to StatusBar
411 bool SfxStatusBarControl::MouseMove( const MouseEvent
& )
415 This virtual method forwards the Event MouseMove() of the
416 StatusBar if the mouse position is within the range of the items,
417 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
419 The default implementation is empty and returns FALSE.
424 The event has been processed and is not intended to
425 be forwarded to StatusBar
428 The event was not processed and is to be
429 be forwarded to StatusBar
437 bool SfxStatusBarControl::MouseButtonUp( const MouseEvent
& )
441 This virtual method forwards the Event MouseButtonUp() of the
442 StatusBar if the mouse position is within the range of the items,
443 or if the mouse was captured by <SfxStatusBarControl::CaptureMouse()>
445 The default implementation is empty and returns FALSE.
450 The event has been processed and is not intended to
451 be forwarded to StatusBar
454 The event was not processed and is to be
455 be forwarded to StatusBar
463 void SfxStatusBarControl::Command( const CommandEvent
& )
467 This virtual method is called when a CommandEvent is received by
470 The default implementation is empty.
477 void SfxStatusBarControl::Click()
481 This virtual method is called when the user clicks on the
482 field in the status row that belongs to this control.
486 css::uno::Sequence
< css::beans::PropertyValue
> aArgs
;
491 void SfxStatusBarControl::Paint
493 const UserDrawEvent
& /* Reference to an UserDrawEvent */
498 This virtual method is called to paint the contents if the field
499 at hand is marked with StatusBarItemBits::UserDraw. The output must be obtained
500 within the Rectangle of rUDEvt.GetRect() by the OutputDevice
501 given by rUDEvt.GetDevice().
503 The default implementation is empty.
510 rtl::Reference
<SfxStatusBarControl
> SfxStatusBarControl::CreateControl
515 SfxModule
const * pMod
518 SolarMutexGuard aGuard
;
519 SfxApplication
*pApp
= SfxGetpApp();
521 SfxSlotPool
*pSlotPool
;
523 pSlotPool
= pMod
->GetSlotPool();
525 pSlotPool
= &SfxSlotPool::GetSlotPool();
527 const std::type_info
* aSlotType
= pSlotPool
->GetSlotType(nSlotID
);
532 SfxStbCtrlFactory
*pFact
= pMod
->GetStbCtrlFactory(*aSlotType
, nSlotID
);
534 return pFact
->pCtor( nSlotID
, nStbId
, *pBar
);
537 SfxStbCtrlFactory
* pFact
= pApp
->GetStbCtrlFactory(*aSlotType
, nSlotID
);
539 return pFact
->pCtor( nSlotID
, nStbId
, *pBar
);
546 void SfxStatusBarControl::RegisterStatusBarControl(SfxModule
* pMod
, const SfxStbCtrlFactory
& rFact
)
548 SfxGetpApp()->RegisterStatusBarControl_Impl( pMod
, rFact
);
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */