Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sfx2 / source / statbar / stbitem.cxx
blobe9d8512fa832e527c55cd7211d734a3c81b78fbc
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 .
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,
72 unsigned short nID,
73 const OUString& aCommandURL )
75 SolarMutexGuard aGuard;
77 util::URL aTargetURL;
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;
84 if ( rFrame.is() )
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;
96 if ( pModule )
97 pSlotPool = pModule->GetSlotPool();
98 else
99 pSlotPool = &(SfxSlotPool::GetSlotPool());
101 const SfxSlot* pSlot = pSlotPool->GetUnoSlot( aTargetURL.Path );
102 if ( pSlot )
104 sal_uInt16 nSlotId = pSlot->GetSlotId();
105 if ( nSlotId > 0 )
107 OUString aCmd = pSlot->GetCommand();
108 pStatusBar->SetHelpId( nSlotId, aCmd );
109 return SfxStatusBarControl::CreateControl( nSlotId, nID, pStatusBar, pModule );
113 return nullptr;
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. */
132 /* [Description]
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 ),
142 nId( nCtrlID ),
143 pBar( &rBar )
148 SfxStatusBarControl::~SfxStatusBarControl()
150 /* [Description]
152 Destructor of the SfxStatusBarControl Class. The Class and its Subclasses
153 are destroyed by SFx.
159 // XInterface
160 void SAL_CALL SfxStatusBarControl::acquire() noexcept
162 OWeakObject::acquire();
165 void SAL_CALL SfxStatusBarControl::release() noexcept
167 OWeakObject::release();
171 // XStatusListener
172 void SAL_CALL SfxStatusBarControl::statusChanged( const frame::FeatureStateEvent& rEvent )
174 SfxViewFrame* pViewFrame = nullptr;
175 uno::Reference < frame::XController > xController;
177 SolarMutexGuard aGuard;
178 if ( m_xFrame.is() )
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 );
185 if ( xDisp.is() )
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 );
195 if ( pSlot )
196 nSlotID = pSlot->GetSlotId();
198 if ( nSlotID <= 0 )
199 return;
201 if ( rEvent.Requery )
202 svt::StatusbarController::statusChanged( rEvent );
203 else
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() )
219 bool bTemp = false;
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() )
237 OUString sTemp ;
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 ) );
248 else
250 if ( pSlot )
251 pItem = pSlot->GetType()->CreateItem();
252 if ( pItem )
254 pItem->SetWhich( nSlotID );
255 pItem->PutValue( rEvent.State, 0 );
257 else
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 ),
277 0 );
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 ),
292 0 );
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 ),
306 0 );
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 );
331 if ( pOutDev )
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;
342 Click();
345 void SAL_CALL SfxStatusBarControl::doubleClick( const awt::Point& )
349 // old sfx2 interface
350 void SfxStatusBarControl::StateChangedAtStatusBarControl
352 sal_uInt16 nSID,
353 SfxItemState eState,
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.
362 /* [Description]
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() );
376 else
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 & )
387 /* [Description]
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.
395 [Return value]
397 sal_Bool TRUE
398 The event has been processed and is not intended to
399 be forwarded to StatusBar
401 FALSE
402 The event was not processed and is to be
403 be forwarded to StatusBar
407 return false;
411 bool SfxStatusBarControl::MouseMove( const MouseEvent & )
413 /* [Description]
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.
421 [Return value]
423 sal_Bool TRUE
424 The event has been processed and is not intended to
425 be forwarded to StatusBar
427 FALSE
428 The event was not processed and is to be
429 be forwarded to StatusBar
433 return false;
437 bool SfxStatusBarControl::MouseButtonUp( const MouseEvent & )
439 /* [Description]
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.
447 [Return value]
449 sal_Bool TRUE
450 The event has been processed and is not intended to
451 be forwarded to StatusBar
453 FALSE
454 The event was not processed and is to be
455 be forwarded to StatusBar
459 return false;
463 void SfxStatusBarControl::Command( const CommandEvent& )
465 /* [Description]
467 This virtual method is called when a CommandEvent is received by
468 SfxStatusBarControl.
470 The default implementation is empty.
477 void SfxStatusBarControl::Click()
479 /* [Description]
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;
487 execute( aArgs );
491 void SfxStatusBarControl::Paint
493 const UserDrawEvent& /* Reference to an UserDrawEvent */
496 /* [Description]
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
512 sal_uInt16 nSlotID,
513 sal_uInt16 nStbId,
514 StatusBar* pBar,
515 SfxModule const * pMod
518 SolarMutexGuard aGuard;
519 SfxApplication *pApp = SfxGetpApp();
521 SfxSlotPool *pSlotPool;
522 if ( pMod )
523 pSlotPool = pMod->GetSlotPool();
524 else
525 pSlotPool = &SfxSlotPool::GetSlotPool();
527 const std::type_info* aSlotType = pSlotPool->GetSlotType(nSlotID);
528 if ( aSlotType )
530 if ( pMod )
532 SfxStbCtrlFactory *pFact = pMod->GetStbCtrlFactory(*aSlotType, nSlotID);
533 if ( pFact )
534 return pFact->pCtor( nSlotID, nStbId, *pBar );
537 SfxStbCtrlFactory* pFact = pApp->GetStbCtrlFactory(*aSlotType, nSlotID);
538 if (pFact)
539 return pFact->pCtor( nSlotID, nStbId, *pBar );
542 return nullptr;
546 void SfxStatusBarControl::RegisterStatusBarControl(SfxModule* pMod, const SfxStbCtrlFactory& rFact)
548 SfxGetpApp()->RegisterStatusBarControl_Impl( pMod, rFact );
552 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */