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 #ifndef INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONFIGURATIONACCESS_HXX
21 #define INCLUDED_SDEXT_SOURCE_PRESENTER_PRESENTERCONFIGURATIONACCESS_HXX
22 
23 #include <rtl/ustring.hxx>
24 #include <com/sun/star/beans/XPropertySet.hpp>
25 #include <com/sun/star/container/XNameAccess.hpp>
26 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
27 #include <com/sun/star/uno/XComponentContext.hpp>
28 
29 #include <vector>
30 #include <functional>
31 
32 namespace sdext::presenter {
33 
34 /** This class gives access to the configuration.  Create an object of this
35     class for one node of the configuration.  This will be the root node.
36     From this one you can use this class in two ways.
37 
38     <p>In a stateless mode (with exception of the root node) you can use static
39     methods for obtaining child nodes, get values from properties at leaf
40     nodes and iterate over children of inner nodes.</p>
41 
42     <p>In a stateful mode use non-static methods like GoToChild() to
43     navigate to children.</p>
44 
45     <p>Note to call CommitChanges() after making changes to
46     PresenterConfigurationAccess object that was opened in READ_WRITE mode.</p>
47 */
48 class PresenterConfigurationAccess
49 {
50 public:
51     enum WriteMode { READ_WRITE, READ_ONLY };
52     typedef ::std::function<bool (
53         const OUString&,
54         const css::uno::Reference<css::beans::XPropertySet>&)> Predicate;
55     static constexpr OUStringLiteral msPresenterScreenRootName =
56         u"/org.openoffice.Office.PresenterScreen/";
57 
58     /** Create a new object to access the configuration entries below the
59         given root.
60         @param rsRootName
61             Name of the root.  You can use msPresenterScreenRootName to
62             access the configuration of the presenter screen.
63         @param eMode
64             This flag specifies whether to give read-write or read-only
65             access.
66     */
67     PresenterConfigurationAccess(
68         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
69         const OUString& rsRootName,
70         WriteMode eMode);
71 
72     ~PresenterConfigurationAccess();
73 
74     /** Return a configuration node below the root of the called object.
75         @param rsPathToNode
76             The relative path from the root (as given the constructor) to the node.
77     */
78     css::uno::Any GetConfigurationNode (
79         const OUString& rsPathToNode);
80 
81     /** Return <TRUE/> when opening the configuration (via creating a new
82         PresenterConfigurationAccess object) or previous calls to
83         GoToChild() left the called PresenterConfigurationAccess object in a
84         valid state.
85     */
86     bool IsValid() const;
87 
88     /** Move the focused node to the (possibly indirect) child specified by the given path.
89     */
90     bool GoToChild (const OUString& rsPathToNode);
91 
92     /** Move the focused node to the first direct child that fulfills the given predicate.
93     */
94     bool GoToChild (const Predicate& rPredicate);
95 
96     /** Modify the property child of the currently focused node.  Keep in
97         mind to call CommitChanges() to write the change back to the
98         configuration.
99     */
100     bool SetProperty (const OUString& rsPropertyName, const css::uno::Any& rValue);
101 
102     /** Return a configuration node below the given node.
103         @param rxNode
104             The node that acts as root to the given relative path.
105         @param rsPathToNode
106             The relative path from the given node to the requested node.
107             When this string is empty then rxNode is returned.
108         @return
109             The type of the returned node varies with the requested node.
110             It is empty when the node was not found.
111     */
112     static css::uno::Any GetConfigurationNode (
113         const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
114         const OUString& rsPathToNode);
115 
116     static css::uno::Reference<css::beans::XPropertySet> GetNodeProperties (
117         const css::uno::Reference<css::container::XHierarchicalNameAccess>& rxNode,
118         const OUString& rsPathToNode);
119 
120     /** Write any changes that have been made back to the configuration.
121         This call is ignored when the called ConfigurationAccess object was
122         not create with read-write mode.
123     */
124     void CommitChanges();
125 
126     typedef ::std::function<void (
127         const ::std::vector<css::uno::Any>&) > ItemProcessor;
128     typedef ::std::function<void (
129         const OUString&,
130         const css::uno::Reference<css::beans::XPropertySet>&) > PropertySetProcessor;
131 
132     /** Execute a functor for all elements of the given container.
133         @param rxContainer
134             The container is a XNameAccess to a list of the configuration.
135             This can be a node returned by GetConfigurationNode().
136         @param rArguments
137             The functor is called with arguments that are children of each
138             element of the container.  The set of children is specified  this
139             list.
140         @param rFunctor
141             The functor to be executed for some or all of the elements in
142             the given container.
143     */
144     static void ForAll (
145         const css::uno::Reference<css::container::XNameAccess>& rxContainer,
146         const ::std::vector<OUString>& rArguments,
147         const ItemProcessor& rProcessor);
148     static void ForAll (
149         const css::uno::Reference<css::container::XNameAccess>& rxContainer,
150         const PropertySetProcessor& rProcessor);
151 
152     static css::uno::Any Find (
153         const css::uno::Reference<css::container::XNameAccess>& rxContainer,
154         const Predicate& rPredicate);
155 
156     static bool IsStringPropertyEqual (
157         std::u16string_view rsValue,
158         const OUString& rsPropertyName,
159         const css::uno::Reference<css::beans::XPropertySet>& rxNode);
160 
161     /** This method wraps a call to getPropertyValue() and returns an empty
162         Any instead of throwing an exception when the property does not
163         exist.
164     */
165     static css::uno::Any GetProperty (
166         const css::uno::Reference<css::beans::XPropertySet>& rxProperties,
167         const OUString& rsKey);
168 
169 private:
170     css::uno::Reference<css::uno::XInterface> mxRoot;
171     css::uno::Any maNode;
172 };
173 
174 } // end of namespace sdext::tools
175 
176 #endif
177 
178 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
179