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 #pragma once
21 
22 #include <com/sun/star/frame/XDispatchProviderInterception.hpp>
23 #include <com/sun/star/frame/XStatusListener.hpp>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <cppuhelper/implbase2.hxx>
26 #include "featuredispatcher.hxx"
27 #include <vector>
28 #include <map>
29 #include <memory>
30 
31 
32 namespace frm
33 {
34 
35 
36     class UrlTransformer;
37     class ControlFeatureInterception;
38 
39 
40     //= OFormNavigationHelper
41 
42     typedef ::cppu::ImplHelper2 <   css::frame::XDispatchProviderInterception
43                                 ,   css::frame::XStatusListener
44                                 >   OFormNavigationHelper_Base;
45 
46     class OFormNavigationHelper
47                         :public OFormNavigationHelper_Base
48                         ,public IFeatureDispatcher
49     {
50     private:
51         struct FeatureInfo
52         {
53             css::util::URL                                             aURL;
54             css::uno::Reference< css::frame::XDispatch >               xDispatcher;
55             bool                                                       bCachedState;
56             css::uno::Any                                              aCachedAdditionalState;
57 
FeatureInfofrm::OFormNavigationHelper::FeatureInfo58             FeatureInfo() : bCachedState( false ) { }
59         };
60         typedef ::std::map< sal_Int16, FeatureInfo >    FeatureMap;
61 
62     private:
63         css::uno::Reference< css::uno::XComponentContext >
64                             m_xORB;
65         ::std::unique_ptr< ControlFeatureInterception >
66                             m_pFeatureInterception;
67 
68         // all supported features
69         FeatureMap          m_aSupportedFeatures;
70         // all features which we have an external dispatcher for
71         sal_Int32           m_nConnectedFeatures;
72 
73     protected:
74         OFormNavigationHelper( const css::uno::Reference< css::uno::XComponentContext >& _rxORB );
75         virtual ~OFormNavigationHelper();
76 
77         // XComponent
78         /// @throws css::uno::RuntimeException
79         void dispose(  );
80 
81         // XDispatchProviderInterception
82         virtual void SAL_CALL registerDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& Interceptor ) override;
83         virtual void SAL_CALL releaseDispatchProviderInterceptor( const css::uno::Reference< css::frame::XDispatchProviderInterceptor >& Interceptor ) override;
84 
85         // XStatusListener
86         virtual void SAL_CALL statusChanged( const css::frame::FeatureStateEvent& State ) override;
87 
88         // XEventListener
89         virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
90 
91         // IFeatureDispatcher
92         virtual void            dispatch( sal_Int16 _nFeatureId ) const override;
93         virtual void            dispatchWithArgument( sal_Int16 _nFeatureId, const char* _pParamName, const css::uno::Any& _rParamValue ) const override;
94         virtual bool            isEnabled( sal_Int16 _nFeatureId ) const override;
95         virtual bool            getBooleanState( sal_Int16 _nFeatureId ) const override;
96         virtual OUString getStringState( sal_Int16 _nFeatureId ) const override;
97         virtual sal_Int32       getIntegerState( sal_Int16 _nFeatureId ) const override;
98 
99         // own overridables
100         /** is called when the interceptors have.
101             <p>The default implementations simply calls <member>updateDispatches</member>,
102             derived classes can prevent this in certain cases, or do additional handling.</p>
103         */
104         virtual void    interceptorsChanged( );
105 
106         /** called when the status of a feature changed
107 
108             <p>The default implementation does nothing.</p>
109 
110             <p>If the feature in question does support more state information that just the
111             enabled/disabled state, then this additional information is to be retrieved in
112             a separate call.</p>
113 
114             @param _nFeatureId
115                 the id of the feature
116             @param _bEnabled
117                 determines if the features is enabled or disabled
118             @see getBooleanState
119         */
120         virtual void    featureStateChanged( sal_Int16 _nFeatureId, bool _bEnabled );
121 
122         /** notification for (potential) changes in the state of all features
123             <p>The base class implementation does nothing. Derived classes could force
124             their peer to update it's state, depending on the result of calls to
125             <member>IFeatureDispatcher::isEnabled</member>.</p>
126         */
127         virtual void    allFeatureStatesChanged( );
128 
129         /** retrieves the list of supported features
130             <p>To be overridden by derived classes</p>
131             @param _rFeatureIds
132                 the array of features to support. Out parameter to fill by the derivee's implementation
133             @pure
134         */
135         virtual void    getSupportedFeatures( ::std::vector< sal_Int16 >& /* [out] */ _rFeatureIds ) = 0;
136 
137     protected:
138         /** update all our dispatches which are controlled by our dispatch interceptors
139         */
140         void    updateDispatches();
141 
142         /** connect to the dispatch interceptors
143         */
144         void    connectDispatchers();
145 
146         /** disconnect from the dispatch interceptors
147         */
148         void    disconnectDispatchers();
149 
150         /** queries the interceptor chain for a dispatcher for the given URL
151         */
152         css::uno::Reference< css::frame::XDispatch >
153                 queryDispatch( const css::util::URL& _rURL );
154 
155         /** invalidates the set of supported features
156 
157             <p>This will invalidate all structures which are tied to the set of supported
158             features. All dispatches will be disconnected.<br/>
159             No automatic re-connection to potential external dispatchers is done, instead,
160             you have to call updateDispatches explicitly, if necessary.</p>
161         */
162         void    invalidateSupportedFeaturesSet();
163 
164     private:
165         /** initialize m_aSupportedFeatures, if necessary
166         */
167         void    initializeSupportedFeatures();
168     };
169 
170     /** helper class mapping between feature ids and feature URLs
171     */
172     class OFormNavigationMapper
173     {
174     private:
175         ::std::unique_ptr< UrlTransformer >   m_pUrlTransformer;
176 
177     public:
178         OFormNavigationMapper(
179             const css::uno::Reference< css::uno::XComponentContext >& _rxORB
180         );
181         ~OFormNavigationMapper( );
182 
183         /** retrieves the ASCII representation of a feature URL belonging to an id
184 
185             @complexity O(log n)
186             @return NULL if the given id is not a known feature id (which is a valid usage)
187         */
188         static const char* getFeatureURLAscii( sal_Int16 _nFeatureId );
189 
190         /** retrieves the feature URL belonging to a feature id
191 
192             @complexity O(log n), with n being the number of all potentially known URLs
193             @return
194                 <TRUE/> if and only if the given id is a known feature id
195                 (which is a valid usage)
196         */
197         bool        getFeatureURL( sal_Int16 _nFeatureId, css::util::URL& /* [out] */ _rURL );
198 
199         /** retrieves the feature id belonging to a feature URL
200 
201             @complexity O(n), with n being the number of all potentially known URLs
202             @return
203                 the id of the feature URL, or -1 if the URl is not known
204                 (which is a valid usage)
205         */
206         static sal_Int16 getFeatureId( const OUString& _rCompleteURL );
207 
208     private:
209         OFormNavigationMapper( const OFormNavigationMapper& ) = delete;
210         OFormNavigationMapper& operator=( const OFormNavigationMapper& ) = delete;
211     };
212 
213 
214 }   // namespace frm
215 
216 
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
218