1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef SD_FRAMEWORK_FRAMEWORK_HELPER_HXX
25 #define SD_FRAMEWORK_FRAMEWORK_HELPER_HXX
26 
27 #include "ViewShell.hxx"
28 
29 #include "tools/SdGlobalResourceContainer.hxx"
30 
31 #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
32 #include <com/sun/star/drawing/framework/XView.hpp>
33 #include <com/sun/star/lang/XEventListener.hpp>
34 
35 #include <boost/scoped_ptr.hpp>
36 #include <boost/shared_ptr.hpp>
37 #include <boost/enable_shared_from_this.hpp>
38 #include <boost/function.hpp>
39 #include <map>
40 
41 namespace sd {
42 class ViewShell;
43 class ViewShellBase;
44 }
45 
46 namespace rtl {
47 class OUString;
48 }
49 
50 namespace css = ::com::sun::star;
51 namespace cssu = ::com::sun::star::uno;
52 namespace cssdf = ::com::sun::star::drawing::framework;
53 
54 namespace sd { namespace framework {
55 
56 /** The FrameworkHelper is a convenience class that simplifies the
57     access to the drawing framework.
58     It has three main tasks:
59     1. Provide frequently used strings of resource URLs and event names.
60     2. Provide shortcuts for accessing the sd framework.
61     3. Ease the migration to the drawing framwork.
62 
63     Note that a FrameworkHelper disposes itself when one of the resource
64     controllers called by it throws a DisposedException.
65 */
66 class FrameworkHelper
67     : public ::boost::enable_shared_from_this<FrameworkHelper>,
68       public SdGlobalResource
69 {
70 public:
71     // URLs of frequently used panes.
72     static const ::rtl::OUString msPaneURLPrefix;
73     static const ::rtl::OUString msCenterPaneURL;
74     static const ::rtl::OUString msFullScreenPaneURL;
75     static const ::rtl::OUString msLeftImpressPaneURL;
76     static const ::rtl::OUString msLeftDrawPaneURL;
77     static const ::rtl::OUString msSidebarPaneURL;
78 
79     // URLs of frequently used views.
80     static const ::rtl::OUString msViewURLPrefix;
81     static const ::rtl::OUString msImpressViewURL;
82     static const ::rtl::OUString msDrawViewURL;
83     static const ::rtl::OUString msOutlineViewURL;
84     static const ::rtl::OUString msNotesViewURL;
85     static const ::rtl::OUString msHandoutViewURL;
86     static const ::rtl::OUString msSlideSorterURL;
87     static const ::rtl::OUString msPresentationViewURL;
88     static const ::rtl::OUString msSidebarViewURL;
89 
90     // URLs of frequently used tool bars.
91     static const ::rtl::OUString msToolBarURLPrefix;
92     static const ::rtl::OUString msViewTabBarURL;
93 
94     // URLs of task panels.
95     static const ::rtl::OUString msTaskPanelURLPrefix;
96     static const ::rtl::OUString msAllMasterPagesTaskPanelURL;
97     static const ::rtl::OUString msRecentMasterPagesTaskPanelURL;
98     static const ::rtl::OUString msUsedMasterPagesTaskPanelURL;
99     static const ::rtl::OUString msLayoutTaskPanelURL;
100     static const ::rtl::OUString msTableDesignPanelURL;
101     static const ::rtl::OUString msCustomAnimationTaskPanelURL;
102     static const ::rtl::OUString msSlideTransitionTaskPanelURL;
103 
104     // Names of frequently used events.
105     static const ::rtl::OUString msResourceActivationRequestEvent;
106     static const ::rtl::OUString msResourceDeactivationRequestEvent;
107     static const ::rtl::OUString msResourceActivationEvent;
108     static const ::rtl::OUString msResourceDeactivationEvent;
109     static const ::rtl::OUString msResourceDeactivationEndEvent;
110     static const ::rtl::OUString msConfigurationUpdateStartEvent;
111     static const ::rtl::OUString msConfigurationUpdateEndEvent;
112 
113     // Service names of the common controllers.
114     static const ::rtl::OUString msModuleControllerService;
115     static const ::rtl::OUString msConfigurationControllerService;
116 
117     /** Return the FrameworkHelper object that is associated with the given
118         ViewShellBase.  If such an object does not yet exist, a new one is
119         created.
120     */
121     static ::boost::shared_ptr<FrameworkHelper> Instance (ViewShellBase& rBase);
122 
123     static ::boost::shared_ptr<FrameworkHelper> Instance (
124         const cssu::Reference<css::frame::XController>& rxController);
125 
126     /** Mark the FrameworkHelper object for the given ViewShellBase as
127         disposed.  A following ReleaseInstance() call will destroy the
128         FrameworkHelper object.
129 
130         Do not call this method.  It is an internally used method that can
131         not be made private.
132     */
133     static void DisposeInstance (ViewShellBase& rBase);
134 
135     /** Destroy the FrameworkHelper object for the given ViewShellBase.
136 
137         Do not call this method.  It is an internally used method that can
138         not be made private.
139     */
140     static void ReleaseInstance (ViewShellBase& rBase);
141 
142     /** Return an identifier for the given view URL.  This identifier can be
143         used in a switch statement.  See GetViewURL() for a mapping in the
144         opposite direction.
145     */
146     static ViewShell::ShellType GetViewId (const rtl::OUString& rsViewURL);
147 
148     /** Return a view URL for the given identifier.  See GetViewId() for a
149         mapping in the opposite direction.
150     */
151     static ::rtl::OUString GetViewURL (ViewShell::ShellType eType);
152 
153     /** Return a ViewShell pointer for the given XView reference.  This
154         assumes that the given reference is implemented by the
155         ViewShellWrapper class that supports the XTunnel interface.
156         @return
157             When the ViewShell pointer can not be inferred from the given
158             reference then an empty pointer is returned.
159     */
160     static ::boost::shared_ptr<ViewShell> GetViewShell (
161         const cssu::Reference<cssdf::XView>& rxView);
162 
163     typedef ::boost::function<bool(const cssdf::ConfigurationChangeEvent&)>
164         ConfigurationChangeEventFilter;
165     typedef ::boost::function<void(bool bEventSeen)> Callback;
166     typedef ::boost::function<
167         void(
168             const cssu::Reference<
169                 cssdf::XResourceId>&)
170         > ResourceFunctor;
171 
172     /** Test whether the called FrameworkHelper object is valid.
173         @return
174             When the object has already been disposed then <FALSE/> is returned.
175     */
176     bool IsValid (void);
177 
178     /** Return a pointer to the view shell that is displayed in the
179         specified pane.  See GetView() for a variant that returns a
180         reference to XView instead of a ViewShell pointer.
181         @return
182             An empty pointer is returned when for example the specified pane
183             does not exist or is not visible or does not show a view or one
184             of the involved objects does not support XUnoTunnel (where
185             necessary).
186     */
187     ::boost::shared_ptr<ViewShell> GetViewShell (const ::rtl::OUString& rsPaneURL);
188 
189     /** Return a reference to the view that is displayed in the specified
190         pane.  See GetViewShell () for a variant that returns a ViewShell
191         pointer instead of a reference to XView.
192         @param rxPaneOrViewId
193             When this ResourceId specifies a view then that view is
194             returned.  When it belongs to a pane then one view in that pane
195             is returned.
196         @return
197             An empty reference is returned when for example the specified pane
198             does not exist or is not visible or does not show a view or one
199             of the involved objects does not support XTunnel (where
200             necessary).
201     */
202     cssu::Reference<cssdf::XView> GetView (
203         const cssu::Reference<cssdf::XResourceId>& rxPaneOrViewId);
204 
205     /** Return the XWindow that is represented by the pane with the
206         given resource id.
207     */
208     cssu::Reference<css::awt::XWindow> GetPaneWindow (
209         const cssu::Reference<cssdf::XResourceId>& rxPaneId);
210 
211     /** Return the XResource object with the given resource id.
212     */
213     cssu::Reference<cssdf::XResource> GetResource (
214         const cssu::Reference<cssdf::XResourceId>& rxResourceId);
215 
216     /** Request the specified view to be displayed in the specified pane.
217         When the pane is not visible its creation is also requested.  The
218         update that creates the actual view object is done asynchronously.
219         @param rsResourceURL
220             The resource URL of the view to show.
221         @param rsAnchorURL
222             The URL of the pane in which to show the view.
223         @return
224             The resource id of the requested view is returned.  With that
225             the caller can, for example, call RunOnResourceActivation() to
226             do some initialization after the requested view becomes active.
227     */
228     cssu::Reference<cssdf::XResourceId> RequestView (
229         const ::rtl::OUString& rsResourceURL,
230         const ::rtl::OUString& rsAnchorURL);
231 
232     /** Request the activation of the specified panel in the
233         sidebar.
234         @param rsSidebarPanelURL
235             The panel that is to be activated.
236         @param bEnsurePaneIsVisible
237             When this is <TRUE/> then the sidebar pane is activated when not
238             yet active.
239             When this flag is <FALSE/> then the requested panel
240             is activated only when the task pane is already active.  When it
241             is not active then this call is silently ignored.
242         @return
243             The resource id of the requested sidebar panel is returned.  With that
244             the caller can, for example, call RunOnResourceActivation() to
245             do some initialization after the requested view becomes active.
246     */
247     cssu::Reference<cssdf::XResourceId> RequestSidebarPanel (
248         const ::rtl::OUString& rsSidebarPanelURL,
249         const bool bEnsureTaskPaneIsVisible = true);
250 
251     /** Request the deactivation of the specified resource.
252     */
253     void RequestResourceDeactivation (
254         const cssu::Reference<cssdf::XResourceId>& rxResourceId);
255 
256     /** Process a slot call that requests a view shell change.
257     */
258     void HandleModeChangeSlot (
259         sal_uLong nSlotId,
260         SfxRequest& rRequest);
261 
262     /** Run the given callback when the specified event is notified by the
263         ConfigurationManager.  When there are no pending requests and
264         therefore no events would be notified (in the foreseeable future)
265         then the callback is called immediately.
266         The callback is called with a flag that tells the callback whether
267         the event it waits for has been sent.
268     */
269     void RunOnConfigurationEvent(
270         const ::rtl::OUString& rsEventType,
271         const Callback& rCallback);
272 
273     /** Run the given callback when the specified resource has been
274         activated.  When the resource is active already when this method is
275         called then rCallback is called before this method returns.
276         @param rxResourceId
277             Wait for the activation of this resource before calling
278             rCallback.
279         @param rCallback
280             The callback to be called when the resource is activated.
281 
282     */
283     void RunOnResourceActivation(
284         const cssu::Reference<cssdf::XResourceId>& rxResourceId,
285         const Callback& rCallback);
286 
287     /** Run the given callback when the specified resource has been
288         deactivated.  When the resource is not active already when
289         this method is called then rCallback is called before this
290         method returns.
291         @param rxResourceId
292             Wait for the deactivation of this resource before calling
293             rCallback.
294         @param rCallback
295             The callback to be called when the resource is
296             deactivated.
297         @param bRunOnDeactivationEnd
298             The callback is run either when the deactivation starts
299             and the callback can still access the resource or when the
300             deactivatio is complete and the resource is no longer available.
301 
302     */
303     void RunOnResourceDeactivation(
304         const cssu::Reference<cssdf::XResourceId>& rxResourceId,
305         const Callback& rCallback,
306         const bool bRunOnDeactivationEnd);
307 
308     /** Normally the requested changes of the configuration are executed
309         asynchronously.  However, there is at least one situation (searching
310         with the Outliner) where the surrounding code does not cope with
311         this.  So, instead of calling Reschedule until the global event loop
312         executes the configuration update, this method does (almost) the
313         same without the reschedules.
314 
315         Do not use this method until there is absolutely no other way.
316     */
317     void RequestSynchronousUpdate (void);
318 
319     /** Block until the specified event is notified by the configuration
320         controller.  When the configuration controller is not processing any
321         requests the method returns immediately.
322     */
323     void WaitForEvent (const ::rtl::OUString& rsEventName) const;
324 
325     /** This is a short cut for WaitForEvent(msConfigurationUpdateEndEvent).
326         Call this method to execute the pending requests.
327     */
328     void WaitForUpdate (void) const;
329 
330     /** Explicit request for an update of the current configuration.  Call
331         this method when one of the resources managed by the sd framework
332         has been activated or deactivated from the outside, i.e. not by the
333         framework itself.  An example for this is a click on the closer
334         button of one of the side panes.
335     */
336     void UpdateConfiguration (void);
337 
338     /** Return a string representation of the given XResourceId object.
339     */
340     static ::rtl::OUString ResourceIdToString (
341         const cssu::Reference<
342             cssdf::XResourceId>& rxResourceId);
343 
344     /** Create a new XResourceId object for the given resource URL.
345     */
346     static cssu::Reference<
347         cssdf::XResourceId>
348             CreateResourceId (
349                 const ::rtl::OUString& rsResourceURL);
350 
351     /** Create a new XResourceId object for the given resource URL and a
352         single anchor URL.
353     */
354     static cssu::Reference<
355         cssdf::XResourceId>
356             CreateResourceId (
357                 const ::rtl::OUString& rsResourceURL,
358                 const ::rtl::OUString& rsAnchorURL);
359 
360     /** Create a new XResourceId object for the given resource URL and the
361         two given anchor URLs.
362     */
363     static cssu::Reference<
364         cssdf::XResourceId>
365             CreateResourceId (
366                 const ::rtl::OUString& rsResourceURL,
367                 const ::rtl::OUString& rsFirstAnchorURL,
368                 const ::rtl::OUString& rsSecondAnchorURL);
369 
370     /** Create a new XResourceId object for the given resource URL.
371     */
372     static cssu::Reference<
373         cssdf::XResourceId>
374             CreateResourceId (
375                 const ::rtl::OUString& rsResourceURL,
376                 const cssu::Reference<
377                     cssdf::XResourceId>& rxAnchor);
378 
379     cssu::Reference<cssdf::XConfigurationController>
380         GetConfigurationController (void) const;
381 
382 
383 private:
384     typedef ::std::map<
385         ViewShellBase*,
386         ::boost::shared_ptr<FrameworkHelper> > InstanceMap;
387     /** The instance map holds (at least) one FrameworkHelper instance for
388         every ViewShellBase object.
389     */
390     static InstanceMap maInstanceMap;
391     class ViewURLMap;
392     static ::boost::scoped_ptr<ViewURLMap> mpViewURLMap;
393 
394     ViewShellBase& mrBase;
395     cssu::Reference<cssdf::XConfigurationController>
396         mxConfigurationController;
397 
398     class DisposeListener;
399     friend class DisposeListener;
400     cssu::Reference<css::lang::XComponent>
401         mxDisposeListener;
402 
403     FrameworkHelper (ViewShellBase& rBase);
404     FrameworkHelper (const FrameworkHelper& rHelper); // Not implemented.
405     ~FrameworkHelper (void);
406     class Deleter; friend class Deleter;
407     FrameworkHelper& operator= (const FrameworkHelper& rHelper); // Not implemented.
408 
409     void Initialize (void);
410 
411     void Dispose (void);
412 
413     /** Run the given callback when an event of the specified type is
414         received from the ConfigurationController or when the
415         ConfigurationController has no pending change requests.
416         @param rsEventType
417             Run rCallback only on this event.
418         @param rFilter
419             This filter has to return <TRUE/> in order for rCallback to be
420             called.
421         @param rCallback
422             The callback functor to be called.
423     */
424     void RunOnEvent(
425         const ::rtl::OUString& rsEventType,
426         const ConfigurationChangeEventFilter& rFilter,
427         const Callback& rCallback) const;
428 
429     /** This disposing method is forwarded from the inner DisposeListener class.
430     */
431     void disposing (const css::lang::EventObject& rEventObject);
432 };
433 
434 
435 } } // end of namespace sd::framework
436 
437 
438 
439 namespace sd { namespace framework {
440 
441 namespace {
442 
443     class FrameworkHelperAllPassFilter
444     {
445     public:
446         bool operator() (const cssdf::ConfigurationChangeEvent&) { return true; }
447     };
448 
449 
450     class FrameworkHelperResourceIdFilter
451     {
452     public:
453         FrameworkHelperResourceIdFilter (
454             const cssu::Reference<cssdf::XResourceId>& rxResourceId);
455         bool operator() (const cssdf::ConfigurationChangeEvent& rEvent)
456         { return mxResourceId.is() && rEvent.ResourceId.is()
457                 && mxResourceId->compareTo(rEvent.ResourceId) == 0; }
458     private:
459         cssu::Reference<cssdf::XResourceId> mxResourceId;
460     };
461 
462 } // end of anonymous namespace
463 
464 
465 
466 
467 } } // end of namespace sd::framework
468 
469 
470 #endif
471