LibreOffice Module framework (master) 1
popuptoolbarcontroller.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <bitmaps.hlst>
21
25#include <menuconfiguration.hxx>
26#include <svtools/imagemgr.hxx>
31#include <tools/urlobj.hxx>
32#include <utility>
34#include <vcl/menu.hxx>
35#include <vcl/svapp.hxx>
36#include <vcl/toolbox.hxx>
37
38#include <com/sun/star/awt/PopupMenuDirection.hpp>
39#include <com/sun/star/awt/XPopupMenu.hpp>
40#include <com/sun/star/frame/thePopupMenuControllerFactory.hpp>
41#include <com/sun/star/frame/XPopupMenuController.hpp>
42#include <com/sun/star/frame/XStorable.hpp>
43#include <com/sun/star/frame/XSubToolbarController.hpp>
44#include <com/sun/star/frame/XUIControllerFactory.hpp>
45#include <com/sun/star/frame/XController.hpp>
46#include <com/sun/star/lang/XServiceInfo.hpp>
47#include <com/sun/star/ucb/CommandFailedException.hpp>
48#include <com/sun/star/ucb/ContentCreationException.hpp>
49#include <com/sun/star/util/XModifiable.hpp>
50
51using namespace framework;
52
53namespace
54{
55
56typedef cppu::ImplInheritanceHelper< svt::ToolboxController,
57 css::lang::XServiceInfo >
59
60class PopupMenuToolbarController : public ToolBarBase
61{
62public:
63 // XComponent
64 virtual void SAL_CALL dispose() override;
65 // XInitialization
66 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
67 // XToolbarController
68 virtual css::uno::Reference< css::awt::XWindow > SAL_CALL createPopupWindow() override;
69 // XStatusListener
70 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
71
72protected:
73 PopupMenuToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
74 OUString aPopupCommand = OUString() );
75 virtual void functionExecuted( const OUString &rCommand );
76 virtual ToolBoxItemBits getDropDownStyle() const;
77 void createPopupMenuController();
78
79 bool m_bHasController;
80 bool m_bResourceURL;
81 OUString m_aPopupCommand;
83
84private:
85 css::uno::Reference< css::frame::XUIControllerFactory > m_xPopupMenuFactory;
86 css::uno::Reference< css::frame::XPopupMenuController > m_xPopupMenuController;
87};
88
89PopupMenuToolbarController::PopupMenuToolbarController(
90 const css::uno::Reference< css::uno::XComponentContext >& xContext,
91 OUString aPopupCommand )
92 : ToolBarBase( xContext, css::uno::Reference< css::frame::XFrame >(), /*aCommandURL*/OUString() )
93 , m_bHasController( false )
94 , m_bResourceURL( false )
95 , m_aPopupCommand(std::move( aPopupCommand ))
96{
97}
98
99void SAL_CALL PopupMenuToolbarController::dispose()
100{
102
103 osl::MutexGuard aGuard( m_aMutex );
104 if( m_xPopupMenuController.is() )
105 {
106 css::uno::Reference< css::lang::XComponent > xComponent(
107 m_xPopupMenuController, css::uno::UNO_QUERY );
108 if( xComponent.is() )
109 {
110 try
111 {
112 xComponent->dispose();
113 }
114 catch (...)
115 {}
116 }
117 m_xPopupMenuController.clear();
118 }
119
120 m_xContext.clear();
121 m_xPopupMenuFactory.clear();
122 m_xPopupMenu.clear();
123}
124
125void SAL_CALL PopupMenuToolbarController::initialize(
126 const css::uno::Sequence< css::uno::Any >& aArguments )
127{
128 ToolboxController::initialize( aArguments );
129
130 osl::MutexGuard aGuard( m_aMutex );
131 if ( !m_aPopupCommand.getLength() )
132 m_aPopupCommand = m_aCommandURL;
133
134 try
135 {
136 m_xPopupMenuFactory.set(
137 css::frame::thePopupMenuControllerFactory::get( m_xContext ) );
138 m_bHasController = m_xPopupMenuFactory->hasController(
139 m_aPopupCommand, getModuleName() );
140 }
141 catch (const css::uno::Exception&)
142 {
143 TOOLS_INFO_EXCEPTION( "fwk.uielement", "" );
144 }
145
146 if ( !m_bHasController && m_aPopupCommand.startsWith( "private:resource/" ) )
147 {
148 m_bResourceURL = true;
149 m_bHasController = true;
150 }
151
152 SolarMutexGuard aSolarLock;
153 ToolBox* pToolBox = nullptr;
154 ToolBoxItemId nItemId;
155 if ( getToolboxId( nItemId, &pToolBox ) )
156 {
157 ToolBoxItemBits nCurStyle( pToolBox->GetItemBits( nItemId ) );
158 ToolBoxItemBits nSetStyle( getDropDownStyle() );
159 pToolBox->SetItemBits( nItemId,
160 m_bHasController ?
161 nCurStyle | nSetStyle :
162 nCurStyle & ~nSetStyle );
163 }
164
165}
166
167void SAL_CALL PopupMenuToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
168{
169 if ( m_bResourceURL )
170 return;
171
172 ToolBox* pToolBox = nullptr;
173 ToolBoxItemId nItemId;
174 if ( getToolboxId( nItemId, &pToolBox ) )
175 {
176 SolarMutexGuard aSolarLock;
177 pToolBox->EnableItem( nItemId, rEvent.IsEnabled );
178 bool bValue;
179 if ( rEvent.State >>= bValue )
180 pToolBox->CheckItem( nItemId, bValue );
181 }
182}
183
184css::uno::Reference< css::awt::XWindow > SAL_CALL
185PopupMenuToolbarController::createPopupWindow()
186{
187 css::uno::Reference< css::awt::XWindow > xRet;
188
189 osl::MutexGuard aGuard( m_aMutex );
190 if ( !m_bHasController )
191 return xRet;
192
193 createPopupMenuController();
194
195 SolarMutexGuard aSolarLock;
196 VclPtr< ToolBox > pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
197 if ( !pToolBox )
198 return xRet;
199
200 pToolBox->SetItemDown( m_nToolBoxId, true );
201 WindowAlign eAlign( pToolBox->GetAlign() );
202
203 // If the parent ToolBox is in popup mode (e.g. sub toolbar, overflow popup),
204 // its ToolBarManager can be disposed along with our controller, destroying
205 // m_xPopupMenu, while the latter still in execute. This should be fixed at a
206 // different level, for now just hold it here so it won't crash.
207 css::uno::Reference< css::awt::XPopupMenu > xPopupMenu ( m_xPopupMenu );
208 sal_uInt16 nId = xPopupMenu->execute(
209 css::uno::Reference< css::awt::XWindowPeer >( getParent(), css::uno::UNO_QUERY ),
210 VCLUnoHelper::ConvertToAWTRect( pToolBox->GetItemRect( m_nToolBoxId ) ),
211 ( eAlign == WindowAlign::Top || eAlign == WindowAlign::Bottom ) ?
212 css::awt::PopupMenuDirection::EXECUTE_DOWN :
213 css::awt::PopupMenuDirection::EXECUTE_RIGHT );
214 pToolBox->SetItemDown( m_nToolBoxId, false );
215
216 if ( nId )
217 functionExecuted( xPopupMenu->getCommand( nId ) );
218
219 return xRet;
220}
221
222void PopupMenuToolbarController::functionExecuted( const OUString &/*rCommand*/)
223{
224}
225
226ToolBoxItemBits PopupMenuToolbarController::getDropDownStyle() const
227{
228 return ToolBoxItemBits::DROPDOWN;
229}
230
231void PopupMenuToolbarController::createPopupMenuController()
232{
233 if( !m_bHasController )
234 return;
235
236 if ( m_xPopupMenuController.is() )
237 {
238 m_xPopupMenuController->updatePopupMenu();
239 }
240 else
241 {
242 css::uno::Sequence<css::uno::Any> aArgs {
243 css::uno::Any(comphelper::makePropertyValue("Frame", m_xFrame)),
244 css::uno::Any(comphelper::makePropertyValue("ModuleIdentifier", m_sModuleName)),
245 css::uno::Any(comphelper::makePropertyValue("InToolbar", true))
246 };
247
248 try
249 {
250 m_xPopupMenu = new VCLXPopupMenu();
251
252 if (m_bResourceURL)
253 {
254 sal_Int32 nAppendIndex = aArgs.getLength();
255 aArgs.realloc(nAppendIndex + 1);
256 aArgs.getArray()[nAppendIndex] <<= comphelper::makePropertyValue("ResourceURL", m_aPopupCommand);
257
258 m_xPopupMenuController.set( m_xContext->getServiceManager()->createInstanceWithArgumentsAndContext(
259 "com.sun.star.comp.framework.ResourceMenuController", aArgs, m_xContext), css::uno::UNO_QUERY_THROW );
260 }
261 else
262 {
263 m_xPopupMenuController.set( m_xPopupMenuFactory->createInstanceWithArgumentsAndContext(
264 m_aPopupCommand, aArgs, m_xContext), css::uno::UNO_QUERY_THROW );
265 }
266
267 m_xPopupMenuController->setPopupMenu( m_xPopupMenu );
268 }
269 catch ( const css::uno::Exception & )
270 {
271 TOOLS_INFO_EXCEPTION( "fwk.uielement", "" );
272 m_xPopupMenu.clear();
273 }
274 }
275}
276
277class GenericPopupToolbarController : public PopupMenuToolbarController
278{
279public:
280 GenericPopupToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext,
281 const css::uno::Sequence< css::uno::Any >& rxArgs );
282
283 // XInitialization
284 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& rxArgs ) override;
285
286 // XStatusListener
287 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
288
289 // XServiceInfo
290 virtual OUString SAL_CALL getImplementationName() override;
291
292 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) override;
293
294 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
295
296private:
297 bool m_bSplitButton, m_bReplaceWithLast;
298 void functionExecuted(const OUString &rCommand) override;
299 ToolBoxItemBits getDropDownStyle() const override;
300};
301
302GenericPopupToolbarController::GenericPopupToolbarController(
303 const css::uno::Reference< css::uno::XComponentContext >& xContext,
304 const css::uno::Sequence< css::uno::Any >& rxArgs )
305 : PopupMenuToolbarController( xContext )
306 , m_bReplaceWithLast( false )
307{
308 css::beans::PropertyValue aPropValue;
309 for ( const auto& arg: rxArgs )
310 {
311 if ( ( arg >>= aPropValue ) && aPropValue.Name == "Value" )
312 {
313 sal_Int32 nIdx{ 0 };
314 OUString aValue;
315 aPropValue.Value >>= aValue;
316 m_aPopupCommand = aValue.getToken(0, ';', nIdx);
317 m_bReplaceWithLast = aValue.getToken(0, ';', nIdx).toBoolean();
318 break;
319 }
320 }
321 m_bSplitButton = m_bReplaceWithLast || !m_aPopupCommand.isEmpty();
322}
323
324OUString GenericPopupToolbarController::getImplementationName()
325{
326 return "com.sun.star.comp.framework.GenericPopupToolbarController";
327}
328
329sal_Bool GenericPopupToolbarController::supportsService(OUString const & rServiceName)
330{
331 return cppu::supportsService( this, rServiceName );
332}
333
334css::uno::Sequence<OUString> GenericPopupToolbarController::getSupportedServiceNames()
335{
336 return {"com.sun.star.frame.ToolbarController"};
337}
338
339void GenericPopupToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& rxArgs )
340{
341 PopupMenuToolbarController::initialize( rxArgs );
342 if ( m_bReplaceWithLast )
343 // Create early, so we can use the menu is statusChanged method.
344 createPopupMenuController();
345}
346
347void GenericPopupToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
348{
349 SolarMutexGuard aGuard;
350
351 if ( m_bReplaceWithLast && !rEvent.IsEnabled && m_xPopupMenu.is() )
352 {
353 ToolBox* pToolBox = nullptr;
355 if ( getToolboxId( nId, &pToolBox ) && pToolBox->IsItemEnabled( nId ) )
356 {
357 Menu* pVclMenu = m_xPopupMenu->GetMenu();
358 pVclMenu->Activate();
359 pVclMenu->Deactivate();
360 }
361
362 for (sal_uInt16 i = 0, nCount = m_xPopupMenu->getItemCount(); i < nCount; ++i )
363 {
364 sal_uInt16 nItemId = m_xPopupMenu->getItemId(i);
365 if (nItemId && m_xPopupMenu->isItemEnabled(nItemId) && !m_xPopupMenu->getPopupMenu(nItemId).is())
366 {
367 functionExecuted(m_xPopupMenu->getCommand(nItemId));
368 return;
369 }
370 }
371 }
372
373 PopupMenuToolbarController::statusChanged( rEvent );
374}
375
376void GenericPopupToolbarController::functionExecuted( const OUString& rCommand )
377{
378 if ( !m_bReplaceWithLast )
379 return;
380
381 removeStatusListener( m_aCommandURL );
382
383 auto aProperties = vcl::CommandInfoProvider::GetCommandProperties(rCommand, m_sModuleName);
384 OUString aRealCommand( vcl::CommandInfoProvider::GetRealCommandForCommand(aProperties) );
385 m_aCommandURL = aRealCommand.isEmpty() ? rCommand : aRealCommand;
386 addStatusListener( m_aCommandURL );
387
388 ToolBox* pToolBox = nullptr;
390 if ( getToolboxId( nId, &pToolBox ) )
391 {
392 pToolBox->SetItemCommand( nId, rCommand );
393 pToolBox->SetHelpText( nId, OUString() ); // Will retrieve the new one from help.
395 pToolBox->SetQuickHelpText(nId, vcl::CommandInfoProvider::GetTooltipForCommand(rCommand, aProperties, m_xFrame));
396
397 Image aImage = vcl::CommandInfoProvider::GetImageForCommand(rCommand, m_xFrame, pToolBox->GetImageSize());
398 if ( !!aImage )
399 pToolBox->SetItemImage( nId, aImage );
400 }
401}
402
403ToolBoxItemBits GenericPopupToolbarController::getDropDownStyle() const
404{
405 return m_bSplitButton ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY;
406}
407
408class SaveToolbarController : public cppu::ImplInheritanceHelper< PopupMenuToolbarController,
409 css::frame::XSubToolbarController,
410 css::util::XModifyListener >
411{
412public:
413 explicit SaveToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
414
415 // XInitialization
416 virtual void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
417
418 // XSubToolbarController
419 // Make ToolBarManager ask our controller for updated image, in case of icon theme change.
420 virtual sal_Bool SAL_CALL opensSubToolbar() override;
421 virtual OUString SAL_CALL getSubToolbarName() override;
422 virtual void SAL_CALL functionSelected( const OUString& aCommand ) override;
423 virtual void SAL_CALL updateImage() override;
424
425 // XStatusListener
426 virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
427
428 // XModifyListener
429 virtual void SAL_CALL modified( const css::lang::EventObject& rEvent ) override;
430
431 // XEventListener
432 virtual void SAL_CALL disposing( const css::lang::EventObject& rEvent ) override;
433
434 // XComponent
435 virtual void SAL_CALL dispose() override;
436
437 // XServiceInfo
438 virtual OUString SAL_CALL getImplementationName() override;
439 virtual sal_Bool SAL_CALL supportsService( OUString const & rServiceName ) override;
440 virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
441
442private:
443 bool m_bReadOnly;
444 bool m_bModified;
445 css::uno::Reference< css::frame::XStorable > m_xStorable;
446 css::uno::Reference< css::util::XModifiable > m_xModifiable;
447};
448
449SaveToolbarController::SaveToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext )
450 : ImplInheritanceHelper( rxContext, ".uno:SaveAsMenu" )
451 , m_bReadOnly( false )
452 , m_bModified( false )
453{
454}
455
456void SaveToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
457{
458 PopupMenuToolbarController::initialize( aArguments );
459
460 ToolBox* pToolBox = nullptr;
462 if ( !getToolboxId( nId, &pToolBox ) )
463 return;
464
465 css::uno::Reference< css::frame::XController > xController = m_xFrame->getController();
466 if ( xController.is() )
467 m_xModifiable.set( xController->getModel(), css::uno::UNO_QUERY );
468
469 if ( m_xModifiable.is() && pToolBox->GetItemCommand( nId ) == m_aCommandURL )
470 // Will also enable the save as only mode.
471 m_xStorable.set( m_xModifiable, css::uno::UNO_QUERY );
472 else if ( !m_xModifiable.is() )
473 // Can be in table/query design.
474 m_xModifiable.set( xController, css::uno::UNO_QUERY );
475 else
476 // Simple save button, without the dropdown.
477 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) & ~ ToolBoxItemBits::DROPDOWN );
478
479 if ( m_xModifiable.is() )
480 {
481 m_xModifiable->addModifyListener( this );
482 modified( css::lang::EventObject() );
483 }
484}
485
486sal_Bool SaveToolbarController::opensSubToolbar()
487{
488 return true;
489}
490
491OUString SaveToolbarController::getSubToolbarName()
492{
493 return OUString();
494}
495
496void SaveToolbarController::functionSelected( const OUString& /*aCommand*/ )
497{
498}
499
500void SaveToolbarController::updateImage()
501{
502 SolarMutexGuard aGuard;
503 ToolBox* pToolBox = nullptr;
505 if ( !getToolboxId( nId, &pToolBox ) )
506 return;
507
508 vcl::ImageType eImageType = pToolBox->GetImageSize();
509
510 Image aImage;
511
512 if ( m_bReadOnly )
513 {
514 aImage = vcl::CommandInfoProvider::GetImageForCommand(".uno:SaveAs", m_xFrame, eImageType);
515 }
516 else if ( m_bModified )
517 {
518 if (eImageType == vcl::ImageType::Size26)
519 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_LARGE);
520 else if (eImageType == vcl::ImageType::Size32)
521 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_EXTRALARGE);
522 else
523 aImage = Image(StockImage::Yes, BMP_SAVEMODIFIED_SMALL);
524 }
525
526 if ( !aImage )
527 aImage = vcl::CommandInfoProvider::GetImageForCommand(m_aCommandURL, m_xFrame, eImageType);
528
529 if ( !!aImage )
530 pToolBox->SetItemImage( nId, aImage );
531}
532
533void SaveToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
534{
535 ToolBox* pToolBox = nullptr;
537 if ( !getToolboxId( nId, &pToolBox ) )
538 return;
539
540 bool bLastReadOnly = m_bReadOnly;
541 m_bReadOnly = m_xStorable.is() && m_xStorable->isReadonly();
542 if ( bLastReadOnly != m_bReadOnly )
543 {
544 OUString sCommand = m_bReadOnly ? OUString( ".uno:SaveAs" ) : m_aCommandURL;
547 pToolBox->SetQuickHelpText( nId,
548 vcl::CommandInfoProvider::GetTooltipForCommand(sCommand, aProperties, m_xFrame) );
549 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) & ~( m_bReadOnly ? ToolBoxItemBits::DROPDOWN : ToolBoxItemBits::DROPDOWNONLY ) );
550 pToolBox->SetItemBits( nId, pToolBox->GetItemBits( nId ) | ( m_bReadOnly ? ToolBoxItemBits::DROPDOWNONLY : ToolBoxItemBits::DROPDOWN ) );
551 updateImage();
552 }
553
554 if ( !m_bReadOnly )
555 pToolBox->EnableItem( nId, rEvent.IsEnabled );
556}
557
558void SaveToolbarController::modified( const css::lang::EventObject& /*rEvent*/ )
559{
560 bool bLastModified = m_bModified;
561 m_bModified = m_xModifiable->isModified();
562 if ( bLastModified != m_bModified )
563 updateImage();
564}
565
566void SaveToolbarController::disposing( const css::lang::EventObject& rEvent )
567{
568 if ( rEvent.Source == m_xModifiable )
569 {
570 m_xModifiable.clear();
571 m_xStorable.clear();
572 }
573 else
574 PopupMenuToolbarController::disposing( rEvent );
575}
576
577void SaveToolbarController::dispose()
578{
579 PopupMenuToolbarController::dispose();
580 if ( m_xModifiable.is() )
581 {
582 m_xModifiable->removeModifyListener( this );
583 m_xModifiable.clear();
584 }
585 m_xStorable.clear();
586}
587
588OUString SaveToolbarController::getImplementationName()
589{
590 return "com.sun.star.comp.framework.SaveToolbarController";
591}
592
593sal_Bool SaveToolbarController::supportsService( OUString const & rServiceName )
594{
595 return cppu::supportsService( this, rServiceName );
596}
597
598css::uno::Sequence< OUString > SaveToolbarController::getSupportedServiceNames()
599{
600 return {"com.sun.star.frame.ToolbarController"};
601}
602
603class NewToolbarController : public cppu::ImplInheritanceHelper<PopupMenuToolbarController, css::frame::XSubToolbarController>
604{
605public:
606 explicit NewToolbarController( const css::uno::Reference< css::uno::XComponentContext >& rxContext );
607
608 // XServiceInfo
609 OUString SAL_CALL getImplementationName() override;
610
611 virtual sal_Bool SAL_CALL supportsService(OUString const & rServiceName) override;
612
613 css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override;
614
615 void SAL_CALL initialize( const css::uno::Sequence< css::uno::Any >& aArguments ) override;
616
617 // XSubToolbarController
618 // Make ToolBarManager ask our controller for updated image, in case of icon theme change.
619 sal_Bool SAL_CALL opensSubToolbar() override { return true; }
620 OUString SAL_CALL getSubToolbarName() override { return OUString(); }
621 void SAL_CALL functionSelected( const OUString& ) override {}
622 void SAL_CALL updateImage() override;
623
624private:
625 void functionExecuted( const OUString &rCommand ) override;
626 void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& rEvent ) override;
627 void SAL_CALL execute( sal_Int16 KeyModifier ) override;
628 sal_uInt16 getMenuIdForCommand( std::u16string_view rCommand );
629
630 sal_uInt16 m_nMenuId;
631};
632
633NewToolbarController::NewToolbarController(
634 const css::uno::Reference< css::uno::XComponentContext >& xContext )
635 : ImplInheritanceHelper( xContext )
636 , m_nMenuId( 0 )
637{
638}
639
640OUString NewToolbarController::getImplementationName()
641{
642 return "org.apache.openoffice.comp.framework.NewToolbarController";
643}
644
645sal_Bool NewToolbarController::supportsService(OUString const & rServiceName)
646{
647 return cppu::supportsService( this, rServiceName );
648}
649
650css::uno::Sequence<OUString> NewToolbarController::getSupportedServiceNames()
651{
652 return {"com.sun.star.frame.ToolbarController"};
653}
654
655void SAL_CALL NewToolbarController::initialize( const css::uno::Sequence< css::uno::Any >& aArguments )
656{
657 PopupMenuToolbarController::initialize( aArguments );
658
659 osl::MutexGuard aGuard( m_aMutex );
660 createPopupMenuController();
661}
662
663void SAL_CALL NewToolbarController::statusChanged( const css::frame::FeatureStateEvent& rEvent )
664{
665 if ( rEvent.IsEnabled )
666 {
667 OUString aState;
668 rEvent.State >>= aState;
669 try
670 {
671 // set the image even if the state is not a string
672 // the toolbar item command will be used as a fallback
673 functionExecuted( aState );
674 }
675 catch (const css::ucb::CommandFailedException&)
676 {
677 }
678 catch (const css::ucb::ContentCreationException&)
679 {
680 }
681 }
682
683 enable( rEvent.IsEnabled );
684}
685
686void SAL_CALL NewToolbarController::execute( sal_Int16 /*KeyModifier*/ )
687{
688 osl::MutexGuard aGuard( m_aMutex );
689
690 OUString aURL, aTarget;
691 if ( m_xPopupMenu.is() && m_nMenuId )
692 {
693 SolarMutexGuard aSolarMutexGuard;
694 aURL = m_xPopupMenu->getCommand(m_nMenuId);
695
696 // TODO investigate how to wrap Get/SetUserValue in css::awt::XMenu
697 MenuAttributes* pMenuAttributes(static_cast<MenuAttributes*>(m_xPopupMenu->getUserValue(m_nMenuId)));
698 if ( pMenuAttributes )
699 aTarget = pMenuAttributes->aTargetFrame;
700 else
701 aTarget = "_default";
702 }
703 else
704 aURL = m_aCommandURL;
705
706 css::uno::Sequence< css::beans::PropertyValue > aArgs{ comphelper::makePropertyValue(
707 "Referer", OUString( "private:user" )) };
708
709 dispatchCommand( aURL, aArgs, aTarget );
710}
711
712void NewToolbarController::functionExecuted( const OUString &rCommand )
713{
714 m_nMenuId = getMenuIdForCommand( rCommand );
715 updateImage();
716}
717
718sal_uInt16 NewToolbarController::getMenuIdForCommand( std::u16string_view rCommand )
719{
720 if ( m_xPopupMenu.is() && !rCommand.empty() )
721 {
722 sal_uInt16 nCount = m_xPopupMenu->getItemCount();
723 for ( sal_uInt16 n = 0; n < nCount; ++n )
724 {
725 sal_uInt16 nId = m_xPopupMenu->getItemId(n);
726 OUString aCmd(m_xPopupMenu->getCommand(nId));
727
728 // match even if the menu command is more detailed
729 // (maybe an additional query) #i28667#
730 if ( aCmd.match( rCommand ) )
731 return nId;
732 }
733 }
734
735 return 0;
736}
737
738void SAL_CALL NewToolbarController::updateImage()
739{
740 SolarMutexGuard aSolarLock;
741 VclPtr< ToolBox> pToolBox = static_cast< ToolBox* >( VCLUnoHelper::GetWindow( getParent() ) );
742 if ( !pToolBox )
743 return;
744
745 OUString aURL, aImageId;
746 if ( m_xPopupMenu.is() && m_nMenuId )
747 {
748 aURL = m_xPopupMenu->getCommand(m_nMenuId);
749 MenuAttributes* pMenuAttributes(static_cast<MenuAttributes*>(m_xPopupMenu->getUserValue(m_nMenuId)));
750 if ( pMenuAttributes )
751 aImageId = pMenuAttributes->aImageId;
752 }
753 else
754 aURL = m_aCommandURL;
755
756 INetURLObject aURLObj( aImageId.isEmpty() ? aURL : aImageId );
757 vcl::ImageType eImageType( pToolBox->GetImageSize() );
758 Image aImage = SvFileInformationManager::GetImageNoDefault( aURLObj, eImageType );
759 if ( !aImage )
760 aImage = vcl::CommandInfoProvider::GetImageForCommand( aURL, m_xFrame, eImageType );
761
762 if ( !aImage )
763 return;
764
765 pToolBox->SetItemImage( m_nToolBoxId, aImage );
766}
767
768}
769
770extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
772 css::uno::XComponentContext *context,
773 css::uno::Sequence<css::uno::Any> const &args)
774{
775 return cppu::acquire(new GenericPopupToolbarController(context, args));
776}
777
778extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
780 css::uno::XComponentContext *context,
781 css::uno::Sequence<css::uno::Any> const &)
782{
783 return cppu::acquire(new SaveToolbarController(context));
784}
785
786extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
788 css::uno::XComponentContext *context,
789 css::uno::Sequence<css::uno::Any> const &)
790{
791 return cppu::acquire(new NewToolbarController(context));
792}
793
794/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
css::uno::Reference< css::lang::XComponent > m_xFrame
void Activate()
void Deactivate()
static SVT_DLLPUBLIC Image GetImageNoDefault(const INetURLObject &rURL, vcl::ImageType eImageType=vcl::ImageType::Small)
vcl::ImageType GetImageSize() const
void SetQuickHelpText(ToolBoxItemId nItemId, const OUString &rText)
OUString GetItemCommand(ToolBoxItemId nItemId) const
bool IsItemEnabled(ToolBoxItemId nItemId) const
void EnableItem(ToolBoxItemId nItemId, bool bEnable=true)
void CheckItem(ToolBoxItemId nItemId, bool bCheck=true)
void SetHelpText(ToolBoxItemId nItemId, const OUString &rText)
void SetItemCommand(ToolBoxItemId nItemId, const OUString &rCommand)
void SetItemText(ToolBoxItemId nItemId, const OUString &rText)
void SetItemImage(ToolBoxItemId nItemId, const Image &rImage)
ToolBoxItemBits GetItemBits(ToolBoxItemId nItemId) const
void SetItemBits(ToolBoxItemId nItemId, ToolBoxItemBits nBits)
static css::awt::Rectangle ConvertToAWTRect(::tools::Rectangle const &_rRect)
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
virtual void SAL_CALL dispose() override
int nCount
#define TOOLS_INFO_EXCEPTION(area, stream)
URL aURL
Reference< XModifiable2 > m_xModifiable
css::uno::Reference< css::uno::XComponentContext > m_xContext
bool m_bReadOnly
sal_Int64 n
bool dispatchCommand(const OUString &rCommand, const uno::Reference< css::frame::XFrame > &rFrame, const css::uno::Sequence< css::beans::PropertyValue > &rArguments, const uno::Reference< css::frame::XDispatchResultListener > &rListener)
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Reference
args
void dispose()
Sequence< beans::PropertyValue > GetCommandProperties(const OUString &rsCommandName, const OUString &rsModuleName)
OUString GetTooltipForCommand(const OUString &rsCommandName, const css::uno::Sequence< css::beans::PropertyValue > &rProperties, const Reference< frame::XFrame > &rxFrame)
OUString GetRealCommandForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
OUString GetModuleIdentifier(const Reference< frame::XFrame > &rxFrame)
Image GetImageForCommand(const OUString &rsCommandName, const Reference< frame::XFrame > &rxFrame, vcl::ImageType eImageType)
OUString GetLabelForCommand(const css::uno::Sequence< css::beans::PropertyValue > &rProperties)
sal_Int16 nId
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_GenericPopupToolbarController_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &args)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_SaveToolbarController_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * org_apache_openoffice_comp_framework_NewToolbarController_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Reference< XController > xController
cppu::ImplInheritanceHelper< svt::PopupWindowController, css::frame::XSubToolbarController, css::awt::XDockableWindowListener > ToolBarBase
OUString aCommand
unsigned char sal_Bool
std::mutex m_aMutex
ToolBoxItemBits
WindowAlign