fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / framework / source / uielement / popuptoolbarcontroller.cxx
blob004db21f70de593bf0776c56a01a45dcb6995fcb
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 <cppuhelper/implbase1.hxx>
21 #include <cppuhelper/supportsservice.hxx>
22 #include <comphelper/processfactory.hxx>
23 #include <framework/menuconfiguration.hxx>
24 #include <rtl/ref.hxx>
25 #include <svtools/imagemgr.hxx>
26 #include <svtools/miscopt.hxx>
27 #include <svtools/toolboxcontroller.hxx>
28 #include <toolkit/awt/vclxmenu.hxx>
29 #include <toolkit/helper/vclunohelper.hxx>
30 #include <tools/urlobj.hxx>
31 #include <unotools/moduleoptions.hxx>
32 #include <vcl/svapp.hxx>
33 #include <vcl/toolbox.hxx>
35 #include <com/sun/star/awt/PopupMenuDirection.hpp>
36 #include <com/sun/star/awt/XPopupMenu.hpp>
37 #include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
38 #include <com/sun/star/frame/XDispatchProvider.hpp>
39 #include <com/sun/star/frame/XPopupMenuController.hpp>
40 #include <com/sun/star/frame/XUIControllerFactory.hpp>
41 #include <com/sun/star/lang/XServiceInfo.hpp>
42 #include <com/sun/star/ucb/CommandFailedException.hpp>
43 #include <com/sun/star/ucb/ContentCreationException.hpp>
45 #define UNO_COMMAND_RECENT_FILE_LIST ".uno:RecentFileList"
47 using namespace framework;
49 namespace {
51 typedef cppu::ImplInheritanceHelper1< svt::ToolboxController,
52 css::lang::XServiceInfo >
53 ToolBarBase;
55 class PopupMenuToolbarController : public ToolBarBase
57 public:
58 virtual ~PopupMenuToolbarController();
60 // XComponent
61 virtual void SAL_CALL dispose() throw ( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
62 // XInitialization
63 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
64 // XToolbarController
65 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
66 // XStatusListener
67 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
69 protected:
70 PopupMenuToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
71 const OUString &rPopupCommand = OUString() );
72 virtual void functionExecuted( const OUString &rCommand );
73 virtual ToolBoxItemBits getDropDownStyle() const;
74 void createPopupMenuController();
76 css::uno::Reference< css::uno::XComponentContext > m_xContext;
77 bool m_bHasController;
78 css::uno::Reference< css::awt::XPopupMenu > m_xPopupMenu;
80 private:
81 OUString m_aPopupCommand;
82 css::uno::Reference< css::frame::XUIControllerFactory > m_xPopupMenuFactory;
83 css::uno::Reference< css::frame::XPopupMenuController > m_xPopupMenuController;
86 PopupMenuToolbarController::PopupMenuToolbarController(
87 const css::uno::Reference< css::uno::XComponentContext >& xContext,
88 const OUString &rPopupCommand )
89 : m_xContext( xContext )
90 , m_bHasController( false )
91 , m_aPopupCommand( rPopupCommand )
95 PopupMenuToolbarController::~PopupMenuToolbarController()
99 void SAL_CALL PopupMenuToolbarController::dispose()
100 throw ( css::uno::RuntimeException, std::exception )
102 svt::ToolboxController::dispose();
104 osl::MutexGuard aGuard( m_aMutex );
105 if( m_xPopupMenuController.is() )
107 css::uno::Reference< css::lang::XComponent > xComponent(
108 m_xPopupMenuController, css::uno::UNO_QUERY );
109 if( xComponent.is() )
113 xComponent->dispose();
115 catch (...)
118 m_xPopupMenuController.clear();
121 m_xContext.clear();
122 m_xPopupMenuFactory.clear();
123 m_xPopupMenu.clear();
126 void SAL_CALL PopupMenuToolbarController::initialize(
127 const css::uno::Sequence< css::uno::Any >& aArguments )
128 throw ( css::uno::Exception, css::uno::RuntimeException, std::exception )
130 ToolboxController::initialize( aArguments );
132 osl::MutexGuard aGuard( m_aMutex );
133 if ( !m_aPopupCommand.getLength() )
134 m_aPopupCommand = m_aCommandURL;
138 m_xPopupMenuFactory.set(
139 css::frame::thePopupMenuControllerFactory::get( m_xContext ) );
140 m_bHasController = m_xPopupMenuFactory->hasController(
141 m_aPopupCommand, getModuleName() );
143 catch (const css::uno::Exception& e)
145 SAL_INFO( "fwk.uielement", "Caught an exception: " << e.Message );
148 SolarMutexGuard aSolarLock;
149 VclPtr< ToolBox > pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ).get() );
150 if ( pToolBox )
152 ToolBoxItemBits nCurStyle( pToolBox->GetItemBits( m_nToolBoxId ) );
153 ToolBoxItemBits nSetStyle( getDropDownStyle() );
154 pToolBox->SetItemBits( m_nToolBoxId,
155 m_bHasController ?
156 nCurStyle | nSetStyle :
157 nCurStyle & ~nSetStyle );
162 void SAL_CALL PopupMenuToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
163 throw ( css::uno::RuntimeException, std::exception )
165 // TODO move to base class
167 svt::ToolboxController::statusChanged( rEvent );
168 enable( rEvent.IsEnabled );
171 css::uno::Reference< css::awt::XWindow > SAL_CALL
172 PopupMenuToolbarController::createPopupWindow()
173 throw ( css::uno::RuntimeException, std::exception )
175 css::uno::Reference< css::awt::XWindow > xRet;
177 osl::MutexGuard aGuard( m_aMutex );
178 if ( !m_bHasController )
179 return xRet;
181 createPopupMenuController();
183 SolarMutexGuard aSolarLock;
184 VclPtr< ToolBox > pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ).get() );
185 if ( !pToolBox )
186 return xRet;
188 pToolBox->SetItemDown( m_nToolBoxId, true );
189 WindowAlign eAlign( pToolBox->GetAlign() );
190 sal_uInt16 nId = m_xPopupMenu->execute(
191 css::uno::Reference< css::awt::XWindowPeer >( getParent(), css::uno::UNO_QUERY ),
192 VCLUnoHelper::ConvertToAWTRect( pToolBox->GetItemRect( m_nToolBoxId ) ),
193 ( eAlign == WINDOWALIGN_TOP || eAlign == WINDOWALIGN_BOTTOM ) ?
194 css::awt::PopupMenuDirection::EXECUTE_DOWN :
195 css::awt::PopupMenuDirection::EXECUTE_RIGHT );
196 pToolBox->SetItemDown( m_nToolBoxId, false );
198 if ( nId )
199 functionExecuted( m_xPopupMenu->getCommand( nId ) );
201 return xRet;
204 void PopupMenuToolbarController::functionExecuted( const OUString &/*rCommand*/)
208 ToolBoxItemBits PopupMenuToolbarController::getDropDownStyle() const
210 return ToolBoxItemBits::DROPDOWN;
213 void PopupMenuToolbarController::createPopupMenuController()
215 if( !m_bHasController )
216 return;
218 if ( !m_xPopupMenuController.is() )
220 css::uno::Sequence< css::uno::Any > aArgs( 2 );
221 css::beans::PropertyValue aProp;
223 aProp.Name = "Frame";
224 aProp.Value <<= m_xFrame;
225 aArgs[0] <<= aProp;
227 aProp.Name = "ModuleIdentifier";
228 aProp.Value <<= getModuleName();
229 aArgs[1] <<= aProp;
232 m_xPopupMenu.set(
233 m_xContext->getServiceManager()->createInstanceWithContext(
234 "com.sun.star.awt.PopupMenu", m_xContext ),
235 css::uno::UNO_QUERY_THROW );
236 m_xPopupMenuController.set(
237 m_xPopupMenuFactory->createInstanceWithArgumentsAndContext(
238 m_aPopupCommand, aArgs, m_xContext), css::uno::UNO_QUERY_THROW );
240 m_xPopupMenuController->setPopupMenu( m_xPopupMenu );
242 catch ( const css::uno::Exception &e )
244 m_xPopupMenu.clear();
245 SAL_INFO( "fwk.uielement", "Caught an exception: " << e.Message );
250 class WizardsToolbarController : public PopupMenuToolbarController
252 public:
253 WizardsToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
255 // XServiceInfo
256 virtual OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException) SAL_OVERRIDE;
258 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) throw (css::uno::RuntimeException) SAL_OVERRIDE;
260 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) SAL_OVERRIDE;
262 private:
263 ToolBoxItemBits getDropDownStyle() const SAL_OVERRIDE;
266 WizardsToolbarController::WizardsToolbarController(
267 const css::uno::Reference< css::uno::XComponentContext >& xContext )
268 : PopupMenuToolbarController( xContext )
272 OUString WizardsToolbarController::getImplementationName()
273 throw (css::uno::RuntimeException)
275 return OUString("org.apache.openoffice.comp.framework.WizardsToolbarController");
278 sal_Bool WizardsToolbarController::supportsService(OUString const & rServiceName)
279 throw (css::uno::RuntimeException)
281 return cppu::supportsService( this, rServiceName );
284 css::uno::Sequence<OUString> WizardsToolbarController::getSupportedServiceNames()
285 throw (css::uno::RuntimeException)
287 css::uno::Sequence< OUString > aRet(1);
288 OUString* pArray = aRet.getArray();
289 pArray[0] = "com.sun.star.frame.ToolbarController";
290 return aRet;
293 ToolBoxItemBits WizardsToolbarController::getDropDownStyle() const
295 return ToolBoxItemBits::DROPDOWNONLY;
298 class OpenToolbarController : public PopupMenuToolbarController
300 public:
301 OpenToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
303 // XServiceInfo
304 virtual OUString SAL_CALL getImplementationName() throw (css::uno::RuntimeException) SAL_OVERRIDE;
306 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) throw (css::uno::RuntimeException) SAL_OVERRIDE;
308 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() throw (css::uno::RuntimeException) SAL_OVERRIDE;
311 OpenToolbarController::OpenToolbarController(
312 const css::uno::Reference< css::uno::XComponentContext >& xContext )
313 : PopupMenuToolbarController( xContext, UNO_COMMAND_RECENT_FILE_LIST )
317 OUString OpenToolbarController::getImplementationName()
318 throw (css::uno::RuntimeException)
320 return OUString("org.apache.openoffice.comp.framework.OpenToolbarController");
323 sal_Bool OpenToolbarController::supportsService(OUString const & rServiceName)
324 throw (css::uno::RuntimeException)
326 return cppu::supportsService( this, rServiceName );
329 css::uno::Sequence<OUString> OpenToolbarController::getSupportedServiceNames()
330 throw (css::uno::RuntimeException)
332 css::uno::Sequence< OUString > aRet(1);
333 OUString* pArray = aRet.getArray();
334 pArray[0] = "com.sun.star.frame.ToolbarController";
335 return aRet;
338 class NewToolbarController : public PopupMenuToolbarController
340 public:
341 NewToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
343 // XServiceInfo
344 OUString SAL_CALL getImplementationName()
345 throw (css::uno::RuntimeException) SAL_OVERRIDE;
347 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) throw (css::uno::RuntimeException) SAL_OVERRIDE;
349 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
350 throw (css::uno::RuntimeException) SAL_OVERRIDE;
352 void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) throw (css::uno::Exception, css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
354 private:
355 void functionExecuted( const OUString &rCommand ) SAL_OVERRIDE;
356 void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) throw ( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
357 void SAL_CALL execute( sal_Int16 KeyModifier ) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
358 void setItemImage( const OUString &rCommand );
360 OUString m_aLastURL;
363 NewToolbarController::NewToolbarController(
364 const css::uno::Reference< css::uno::XComponentContext >& xContext )
365 : PopupMenuToolbarController( xContext )
369 OUString NewToolbarController::getImplementationName()
370 throw (css::uno::RuntimeException)
372 return OUString("org.apache.openoffice.comp.framework.NewToolbarController");
375 sal_Bool NewToolbarController::supportsService(OUString const & rServiceName)
376 throw (css::uno::RuntimeException)
378 return cppu::supportsService( this, rServiceName );
381 css::uno::Sequence<OUString> NewToolbarController::getSupportedServiceNames()
382 throw (css::uno::RuntimeException)
384 css::uno::Sequence< OUString > aRet(1);
385 OUString* pArray = aRet.getArray();
386 pArray[0] = "com.sun.star.frame.ToolbarController";
387 return aRet;
390 void SAL_CALL NewToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
391 throw ( css::uno::Exception, css::uno::RuntimeException, std::exception )
393 PopupMenuToolbarController::initialize( aArguments );
395 osl::MutexGuard aGuard( m_aMutex );
396 createPopupMenuController();
399 void SAL_CALL NewToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
400 throw ( css::uno::RuntimeException, std::exception )
402 if ( rEvent.IsEnabled )
404 OUString aState;
405 rEvent.State >>= aState;
408 // set the image even if the state is not a string
409 // this will set the image of the default module
410 setItemImage( aState );
412 catch (const css::ucb::CommandFailedException&)
415 catch (const css::ucb::ContentCreationException&)
420 enable( rEvent.IsEnabled );
423 void SAL_CALL NewToolbarController::execute( sal_Int16 /*KeyModifier*/ )
424 throw ( css::uno::RuntimeException, std::exception )
426 osl::MutexGuard aGuard( m_aMutex );
427 if ( !m_aLastURL.getLength() )
428 return;
430 OUString aTarget( "_default" );
431 if ( m_xPopupMenu.is() )
433 // TODO investigate how to wrap Get/SetUserValue in css::awt::XMenu
434 MenuAttributes* pMenuAttributes( 0 );
435 VCLXPopupMenu* pTkPopupMenu =
436 static_cast<VCLXPopupMenu *>( VCLXMenu::GetImplementation( m_xPopupMenu ) );
438 SolarMutexGuard aSolarMutexGuard;
439 PopupMenu* pVCLPopupMenu = pTkPopupMenu ?
440 dynamic_cast< PopupMenu * >( pTkPopupMenu->GetMenu() ) : NULL;
442 if ( pVCLPopupMenu )
443 pMenuAttributes = reinterpret_cast< MenuAttributes* >(
444 pVCLPopupMenu->GetUserValue( pVCLPopupMenu->GetCurItemId() ) );
446 if ( pMenuAttributes )
447 aTarget = pMenuAttributes->aTargetFrame;
450 css::uno::Sequence< css::beans::PropertyValue > aArgs( 1 );
451 aArgs[0].Name = "Referer";
452 aArgs[0].Value <<= OUString( "private:user" );
454 dispatchCommand( m_aLastURL, aArgs, aTarget );
457 void NewToolbarController::functionExecuted( const OUString &rCommand )
459 setItemImage( rCommand );
463 it return the existing state of the given URL in the popupmenu of this toolbox control.
465 If the given URL can be located as an action command of one menu item of the
466 popup menu of this control, we return sal_True. Otherwhise we return sal_False.
467 Further we return a fallback URL, in case we have to return sal_False. Because
468 the outside code must select a valid item of the popup menu every time ...
469 and we define it here. By the way this m ethod was written to handle
470 error situations gracefully. E.g. it can be called during creation time
471 but then we have no valid menu. For this case we know another fallback URL.
472 Then we return the private:factory/ URL of the default factory.
474 @param rPopupMenu
475 pounts to the popup menu, on which item we try to locate the given URL
476 Can be NULL! Search will be suppressed then.
478 @param sURL
479 the URL for searching
481 @param sFallback
482 contains the fallback URL in case we return FALSE
483 Must point to valid memory!
485 @param aImage
486 contains the image of the menu for the URL.
488 @return sal_True - if URL could be located as an item of the popup menu.
489 sal_False - otherwhise.
491 static bool Impl_ExistURLInMenu(
492 const css::uno::Reference< css::awt::XPopupMenu > &rPopupMenu,
493 OUString &sURL,
494 OUString &sFallback,
495 Image &aImage )
497 bool bValidFallback( false );
498 sal_uInt16 nCount( 0 );
499 if ( rPopupMenu.is() && ( nCount = rPopupMenu->getItemCount() ) != 0 && sURL.getLength() )
501 for ( sal_uInt16 n = 0; n < nCount; ++n )
503 sal_uInt16 nId = rPopupMenu->getItemId( n );
504 OUString aCmd( rPopupMenu->getCommand( nId ) );
506 if ( !bValidFallback && aCmd.getLength() )
508 sFallback = aCmd;
509 bValidFallback = true;
512 // match even if the menu command is more detailed
513 // (maybe an additional query) #i28667#
514 if ( aCmd.match( sURL ) )
516 sURL = aCmd;
517 const css::uno::Reference< css::graphic::XGraphic > xGraphic(
518 rPopupMenu->getItemImage( nId ) );
519 if ( xGraphic.is() )
520 aImage = Image( xGraphic );
521 return true;
526 if ( !bValidFallback )
528 OUStringBuffer aBuffer;
529 aBuffer.append( "private:factory/" );
530 aBuffer.append( SvtModuleOptions().GetDefaultModuleName() );
531 sFallback = aBuffer.makeStringAndClear();
534 return false;
537 /** We accept URL's here only, which exist as items of our internal popup menu.
538 All other ones will be ignored and a fallback is used.
540 void NewToolbarController::setItemImage( const OUString &rCommand )
542 SolarMutexGuard aSolarLock;
543 VclPtr< ToolBox> pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ).get() );
544 if ( !pToolBox )
545 return;
547 OUString aURL = rCommand;
548 OUString sFallback;
549 Image aMenuImage;
551 bool bValid( Impl_ExistURLInMenu( m_xPopupMenu, aURL, sFallback, aMenuImage ) );
552 if ( !bValid )
553 aURL = sFallback;
555 bool bBig = SvtMiscOptions().AreCurrentSymbolsLarge();
557 INetURLObject aURLObj( aURL );
558 Image aImage = SvFileInformationManager::GetImageNoDefault( aURLObj, bBig );
559 if ( !aImage )
560 aImage = !!aMenuImage ?
561 aMenuImage :
562 SvFileInformationManager::GetImage( aURLObj, bBig );
564 // if everything failed, just use the image associated with the toolbar item command
565 if ( !aImage )
566 return;
568 Size aBigSize( pToolBox->GetDefaultImageSize() );
569 if ( bBig && aImage.GetSizePixel() != aBigSize )
571 BitmapEx aScaleBmpEx( aImage.GetBitmapEx() );
572 aScaleBmpEx.Scale( aBigSize, BmpScaleFlag::Interpolate );
573 pToolBox->SetItemImage( m_nToolBoxId, Image( aScaleBmpEx ) );
575 else
576 pToolBox->SetItemImage( m_nToolBoxId, aImage );
578 m_aLastURL = aURL;
583 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
584 org_apache_openoffice_comp_framework_WizardsToolbarController_get_implementation(
585 css::uno::XComponentContext *context,
586 css::uno::Sequence<css::uno::Any> const &)
588 return cppu::acquire(new WizardsToolbarController(context));
591 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
592 org_apache_openoffice_comp_framework_OpenToolbarController_get_implementation(
593 css::uno::XComponentContext *context,
594 css::uno::Sequence<css::uno::Any> const &)
596 return cppu::acquire(new OpenToolbarController(context));
599 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
600 org_apache_openoffice_comp_framework_NewToolbarController_get_implementation(
601 css::uno::XComponentContext *context,
602 css::uno::Sequence<css::uno::Any> const &)
604 return cppu::acquire(new NewToolbarController(context));
607 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */