LibreOffice Module framework (master) 1
popupmenudispatcher.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
21#include <services.h>
22#include <properties.h>
23
24#include <com/sun/star/frame/XLayoutManager2.hpp>
25#include <com/sun/star/beans/XPropertySet.hpp>
26#include <com/sun/star/uri/UriReferenceFactory.hpp>
27#include <com/sun/star/ui/XUIElement.hpp>
28
30#include <sal/log.hxx>
31#include <utility>
32#include <vcl/svapp.hxx>
33
34namespace framework{
35
36using namespace ::com::sun::star;
37using namespace ::com::sun::star::awt;
38using namespace ::com::sun::star::beans;
39using namespace ::com::sun::star::container;
40using namespace ::com::sun::star::frame;
41using namespace ::com::sun::star::lang;
42using namespace ::com::sun::star::uno;
43using namespace ::com::sun::star::util;
44using namespace ::cppu;
45using namespace ::osl;
46
48 uno::Reference< XComponentContext > xContext )
49 : m_xContext (std::move( xContext ))
50 , m_bAlreadyDisposed ( false )
51 , m_bActivateListener ( false )
52{
53}
54
56{
57 // Warn programmer if he forgot to dispose this instance.
58 // We must release all our references ...
59 // and a dtor isn't the best place to do that!
60}
61
63{
64 return "com.sun.star.comp.framework.PopupMenuControllerDispatcher";
65}
66
67sal_Bool SAL_CALL PopupMenuDispatcher::supportsService( const OUString& sServiceName )
68{
70}
71
72css::uno::Sequence< OUString > SAL_CALL PopupMenuDispatcher::getSupportedServiceNames()
73{
75}
76
77void SAL_CALL PopupMenuDispatcher::initialize( const css::uno::Sequence< css::uno::Any >& lArguments )
78{
79 css::uno::Reference< css::frame::XFrame > xFrame;
80
82 for (int a=0; a<lArguments.getLength(); ++a)
83 {
84 if (a==0)
85 {
86 lArguments[a] >>= xFrame;
88
90 uno::Reference< css::frame::XFrameActionListener > xFrameActionListener(this);
91 xFrame->addFrameActionListener( xFrameActionListener );
92 }
93 }
94}
95
96css::uno::Reference< css::frame::XDispatch >
98 const css::util::URL& rURL ,
99 const OUString& sTarget ,
100 sal_Int32 nFlags )
101{
102 if ( !rURL.Complete.startsWith( "vnd.sun.star.popup:" ) )
103 return {};
104
105 // --- SAFE ---
108 if ( !m_xUriRefFactory.is() )
109 m_xUriRefFactory = css::uri::UriReferenceFactory::create( m_xContext );
110
111 css::uno::Reference< css::container::XNameAccess > xPopupCtrlQuery( m_xPopupCtrlQuery );
112 aGuard.clear();
113 // --- SAFE ---
114
115 if ( !xPopupCtrlQuery.is() )
116 return {};
117
118 css::uno::Reference< css::frame::XDispatch > xDispatch;
119
120 try
121 {
122 // Just use the main part of the URL for popup menu controllers
123 sal_Int32 nSchemePart( 0 );
124 OUString aBaseURL( "vnd.sun.star.popup:" );
125 OUString aURL( rURL.Complete );
126
127 nSchemePart = aURL.indexOf( ':' );
128 if (( nSchemePart > 0 ) &&
129 ( aURL.getLength() > ( nSchemePart+1 )))
130 {
131 sal_Int32 nQueryPart = aURL.indexOf( '?', nSchemePart );
132 if ( nQueryPart > 0 )
133 aBaseURL += aURL.subView( nSchemePart+1, nQueryPart-(nSchemePart+1) );
134 else if ( nQueryPart == -1 )
135 aBaseURL += aURL.subView( nSchemePart+1 );
136 }
137
138 css::uno::Reference< css::frame::XDispatchProvider > xDispatchProvider;
139
140 // Find popup menu controller using the base URL
141 xPopupCtrlQuery->getByName( aBaseURL ) >>= xDispatchProvider;
142
143 // Ask popup menu dispatch provider for dispatch object
144 if ( xDispatchProvider.is() )
145 xDispatch = xDispatchProvider->queryDispatch( rURL, sTarget, nFlags );
146 }
147 catch ( const RuntimeException& )
148 {
149 throw;
150 }
151 catch ( const Exception& )
152 {
153 }
154 return xDispatch;
155}
156
157css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL
159 const css::uno::Sequence< css::frame::DispatchDescriptor >& lDescriptor )
160{
161 sal_Int32 nCount = lDescriptor.getLength();
162 css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > lDispatcher( nCount );
163 auto lDispatcherRange = asNonConstRange(lDispatcher);
164 for( sal_Int32 i=0; i<nCount; ++i )
165 {
166 lDispatcherRange[i] = queryDispatch(
167 lDescriptor[i].FeatureURL,
168 lDescriptor[i].FrameName,
169 lDescriptor[i].SearchFlags);
170 }
171 return lDispatcher;
172}
173
174void SAL_CALL PopupMenuDispatcher::dispatch( const URL& /*aURL*/, const Sequence< PropertyValue >& /*seqProperties*/ )
175{
176}
177
178void SAL_CALL PopupMenuDispatcher::addStatusListener( const uno::Reference< XStatusListener >& /*xControl*/,
179 const URL& /*aURL*/ )
180{
181}
182
183void SAL_CALL PopupMenuDispatcher::removeStatusListener( const uno::Reference< XStatusListener >& /*xControl*/,
184 const URL& /*aURL*/ )
185{
186}
187
188void SAL_CALL PopupMenuDispatcher::frameAction( const FrameActionEvent& aEvent )
189{
191 if (( aEvent.Action == css::frame::FrameAction_COMPONENT_DETACHING ) ||
192 ( aEvent.Action == css::frame::FrameAction_COMPONENT_ATTACHED ))
193 {
194 // Reset query reference to requery it again next time
195 m_xPopupCtrlQuery.clear();
196 }
197}
198
199void SAL_CALL PopupMenuDispatcher::disposing( const EventObject& )
200{
202 // Safe impossible cases
203 SAL_WARN_IF( m_bAlreadyDisposed, "fwk", "MenuDispatcher::disposing(): Object already disposed .. don't call it again!" );
204
206 return;
207
208 m_bAlreadyDisposed = true;
209
211 {
212 uno::Reference< XFrame > xFrame( m_xWeakFrame.get(), UNO_QUERY );
213 if ( xFrame.is() )
214 {
215 xFrame->removeFrameActionListener( uno::Reference< XFrameActionListener >(this) );
216 m_bActivateListener = false;
217 }
218 }
219
220 // Forget our factory.
221 m_xContext.clear();
222}
223
225{
226 if ( m_xPopupCtrlQuery.is() )
227 return;
228
229 css::uno::Reference< css::frame::XLayoutManager2 > xLayoutManager;
230 css::uno::Reference< css::frame::XFrame > xFrame( m_xWeakFrame );
231
232 if ( !xFrame.is() )
233 return;
234
235 css::uno::Reference< css::beans::XPropertySet > xPropSet( xFrame, css::uno::UNO_QUERY );
236 if ( !xPropSet.is() )
237 return;
238
239 try
240 {
241 xPropSet->getPropertyValue( FRAME_PROPNAME_ASCII_LAYOUTMANAGER ) >>= xLayoutManager;
242
243 if ( xLayoutManager.is() )
244 {
245 css::uno::Reference< css::ui::XUIElement > xMenuBar = xLayoutManager->getElement( "private:resource/menubar/menubar" );
246
247 m_xPopupCtrlQuery.set( xMenuBar, css::uno::UNO_QUERY );
248 }
249 }
250 catch ( const css::uno::RuntimeException& )
251 {
252 throw;
253 }
254 catch ( const css::uno::Exception& )
255 {
256 }
257}
258
259} // namespace framework
260
261
262extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
264 css::uno::XComponentContext* context, css::uno::Sequence<css::uno::Any> const& )
265{
266 return cppu::acquire(new framework::PopupMenuDispatcher(context));
267}
268
269/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
constexpr OUStringLiteral sServiceName
AnyEventRef aEvent
virtual OUString SAL_CALL getImplementationName() override
PopupMenuDispatcher(css::uno::Reference< css::uno::XComponentContext > xContext)
virtual void SAL_CALL dispatch(const css::util::URL &aURL, const css::uno::Sequence< css::beans::PropertyValue > &seqProperties) override
bool m_bAlreadyDisposed
factory shared with our owner to create new services!
css::uno::WeakReference< css::frame::XFrame > m_xWeakFrame
css::uno::Reference< css::uri::XUriReferenceFactory > m_xUriRefFactory
reference to query for popup controller
void SAL_CALL disposing(const css::lang::EventObject &aEvent) override
css::uno::Reference< css::container::XNameAccess > m_xPopupCtrlQuery
css::uno::WeakReference to frame (Don't use a hard css::uno::Reference. Owner can't delete us then!...
virtual css::uno::Reference< css::frame::XDispatch > SAL_CALL queryDispatch(const css::util::URL &aURL, const OUString &sTarget, sal_Int32 nFlags) override
virtual void SAL_CALL frameAction(const css::frame::FrameActionEvent &aEvent) override
bool m_bActivateListener
Protection against multiple disposing calls.
virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
virtual void SAL_CALL initialize(const css::uno::Sequence< css::uno::Any > &lArguments) override
virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener > &xControl, const css::util::URL &aURL) override
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
css::uno::Reference< css::uno::XComponentContext > m_xContext
reference to the uri reference factory
virtual css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL queryDispatches(const css::uno::Sequence< css::frame::DispatchDescriptor > &lDescriptor) override
virtual sal_Bool SAL_CALL supportsService(const OUString &sServiceName) override
int nCount
Reference< XDispatch > xDispatch
URL aURL
css::uno::Reference< css::uno::XComponentContext > m_xContext
uno_Any a
#define SAL_WARN_IF(condition, area, stream)
@ Exception
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
constexpr OUStringLiteral SERVICENAME_PROTOCOLHANDLER
Definition: services.h:32
constexpr OUStringLiteral FRAME_PROPNAME_ASCII_LAYOUTMANAGER
Definition: properties.h:30
int i
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * framework_PopupMenuDispatcher_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
Reference< XFrame > xFrame
unsigned char sal_Bool