Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / onlinehelp / helptopic.h
1 /*
2  * This file is part of the GROMACS molecular simulation package.
3  *
4  * Copyright (c) 2012,2014, by the GROMACS development team, led by
5  * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
6  * and including many others, as listed in the AUTHORS file in the
7  * top-level source directory and at http://www.gromacs.org.
8  *
9  * GROMACS is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * as published by the Free Software Foundation; either version 2.1
12  * of the License, or (at your option) any later version.
13  *
14  * GROMACS is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with GROMACS; if not, see
21  * http://www.gnu.org/licenses, or write to the Free Software Foundation,
22  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA.
23  *
24  * If you want to redistribute modifications to GROMACS, please
25  * consider that scientific software is very special. Version
26  * control is crucial - bugs must be traceable. We will be happy to
27  * consider code for inclusion in the official distribution, but
28  * derived work must not be called official GROMACS. Details are found
29  * in the README & COPYING files - if they are missing, get the
30  * official version at http://www.gromacs.org.
31  *
32  * To help us fund GROMACS development, we humbly ask that you cite
33  * the research papers on the package. Check out http://www.gromacs.org.
34  */
35 /*! \libinternal \file
36  * \brief
37  * Declares helper classes and functions for implementing
38  * gmx::HelpTopicInterface.
39  *
40  * \author Teemu Murtola <teemu.murtola@gmail.com>
41  * \inlibraryapi
42  * \ingroup module_onlinehelp
43  */
44 #ifndef GMX_ONLINEHELP_HELPTOPIC_H
45 #define GMX_ONLINEHELP_HELPTOPIC_H
46
47 #include "gromacs/onlinehelp/helptopicinterface.h"
48 #include "gromacs/utility/common.h"
49 #include "gromacs/utility/stringutil.h"
50 #include "gromacs/utility/uniqueptr.h"
51
52 namespace gmx
53 {
54
55 /*! \cond libapi */
56 /*! \libinternal \brief
57  * Helper for writing simple help text.
58  *
59  * \param[in] context Context for writing the help.
60  * \param[in] topic   Topic to write the help for (used for title).
61  * \param[in] text    Text to write for the topic.
62  * \throws    std::bad_alloc if out of memory.
63  * \throws    FileIOError on any I/O error.
64  *
65  * Formats basic help by writing a title (obtained from \p topic), followed by
66  * \p text with markup substituted and lines properly wrapped.
67  *
68  * \inlibraryapi
69  */
70 void writeBasicHelpTopic(const HelpWriterContext  &context,
71                          const HelpTopicInterface &topic,
72                          const std::string        &text);
73 //! \endcond
74
75 /*! \libinternal \brief
76  * Abstract base class for help topics that have simple text and no subtopics.
77  *
78  * This class implements subtopic-related methods from HelpTopicInterface such
79  * that there are no subtopics.  writeHelp() is also implemented such that it
80  * uses writeBasicHelpTopic() to write out the text returned by a new virtual
81  * method helpText().
82  *
83  * \see SimpleHelpTopic
84  *
85  * \inlibraryapi
86  * \ingroup module_onlinehelp
87  */
88 class AbstractSimpleHelpTopic : public HelpTopicInterface
89 {
90     public:
91         virtual const char *name() const  = 0;
92         virtual const char *title() const = 0;
93
94         virtual bool hasSubTopics() const;
95         virtual const HelpTopicInterface *findSubTopic(const char *name) const;
96
97         virtual void writeHelp(const HelpWriterContext &context) const;
98
99     protected:
100         /*! \brief
101          * Returns the help text for this topic.
102          *
103          * writeHelp() calls this method to obtain the actual text to format
104          * for the topic.  Markup substitution etc. is done automatically by
105          * writeHelp().
106          */
107         virtual std::string helpText() const = 0;
108 };
109
110 /*! \libinternal \brief
111  * Abstract base class for help topics that have simple text and subtopics.
112  *
113  * This class implements an internal container for subtopics and provides
114  * public methods for adding subtopics (as HelpTopicInterface objects).
115  * Subtopic-related methods from HelpTopicInterface are implemented to access
116  * the internal container.  writeHelp() is also implemented such that it
117  * uses writeBasicHelpTopic() to write out the text returned by a new virtual
118  * method helpText(), and a list of subtopics is written after the actual text.
119  *
120  * \see CompositeHelpTopic
121  *
122  * \inlibraryapi
123  * \ingroup module_onlinehelp
124  */
125 class AbstractCompositeHelpTopic : public HelpTopicInterface
126 {
127     public:
128         AbstractCompositeHelpTopic();
129         virtual ~AbstractCompositeHelpTopic();
130
131         virtual const char *name() const  = 0;
132         virtual const char *title() const = 0;
133
134         virtual bool hasSubTopics() const;
135         virtual const HelpTopicInterface *findSubTopic(const char *name) const;
136
137         virtual void writeHelp(const HelpWriterContext &context) const;
138
139         /*! \brief
140          * Adds a given topic as a subtopic of this topic.
141          *
142          * \param   topic  Topis to add.
143          * \throws  std::bad_alloc if out of memory.
144          *
145          * This topic takes ownership of the object.
146          *
147          * \see registerSubTopic()
148          */
149         void addSubTopic(HelpTopicPointer topic);
150         /*! \brief
151          * Registers a subtopic of a certain type to this topic.
152          *
153          * \tparam  Topic  Type of topic to register.
154          * \throws  std::bad_alloc if out of memory.
155          *
156          * \p Topic must be default-constructible and implement
157          * HelpTopicInterface.
158          *
159          * This method is provided as a convenient alternative to addSubTopic()
160          * for cases where each topic is implemented by a different type
161          * (which is a common case outside unit tests).
162          */
163         template <class Topic>
164         void registerSubTopic()
165         {
166             addSubTopic(HelpTopicPointer(new Topic));
167         }
168
169     protected:
170         //! \copydoc gmx::AbstractSimpleHelpTopic::helpText()
171         virtual std::string helpText() const = 0;
172
173         /*! \brief
174          * Writes the list of subtopics.
175          *
176          * \param[in] context Context for writing the help.
177          * \param[in] title  Title for the written list.
178          * \returns   true if anything was printed.
179          * \throws    std::bad_alloc if out of memory.
180          * \throws    FileIOError on any I/O error.
181          *
182          * Subtopics with empty titles are skipped from the list.
183          * If there would be no subtopics in the list, \p title is not printed
184          * either.
185          *
186          * This method is provided for cases where helpText() does not provide
187          * the needed flexibility and the derived class needs to override
188          * writeHelp().  This method can then be called to print the same
189          * subtopic list that is printed by the default writeHelp()
190          * implementation.
191          */
192         bool writeSubTopicList(const HelpWriterContext &context,
193                                const std::string       &title) const;
194
195     private:
196         class Impl;
197
198         PrivateImplPointer<Impl> impl_;
199 };
200
201 /*! \cond libapi */
202 /*! \libinternal \brief
203  * Smart pointer type to manage a AbstractCompositeHelpTopic object.
204  *
205  * \inlibraryapi
206  */
207 typedef gmx_unique_ptr<AbstractCompositeHelpTopic>::type
208     CompositeHelpTopicPointer;
209 //! \endcond
210
211 /*! \libinternal \brief
212  * Template for simple implementation of AbstractSimpleHelpTopic.
213  *
214  * \tparam HelpText Struct that defines the data for the topic.
215  *
216  * \p HelpText should have public static members \c "const char name[]",
217  * \c "const char title[]" and \c "const char *const text[]".
218  *
219  * Typical use:
220  * \code
221    struct ExampleHelpText
222    {
223        static const char name[];
224        static const char title[];
225        static const char *const text[];
226    };
227
228    const char ExampleHelpText::name[] = "example";
229    const char ExampleHelpText::title[] =
230        "Example title";
231    const char *const ExampleHelpText::text[] = {
232        "Text for the topic.",
233        "More text for the topic."
234    };
235
236    typedef SimpleHelpTopic<ExampleHelpText> ExampleHelpTopic;
237  * \endcode
238  *
239  * \inlibraryapi
240  * \ingroup module_onlinehelp
241  */
242 template <class HelpText>
243 class SimpleHelpTopic : public AbstractSimpleHelpTopic
244 {
245     public:
246         virtual const char *name() const
247         {
248             return HelpText::name;
249         }
250         virtual const char *title() const
251         {
252             return HelpText::title;
253         }
254
255     protected:
256         virtual std::string helpText() const
257         {
258             return concatenateStrings(HelpText::text);
259         }
260 };
261
262 /*! \libinternal \brief
263  * Template for simple implementation of AbstractCompositeHelpTopic.
264  *
265  * \tparam HelpText Struct that defines the data for the topic.
266  *
267  * Used similarly to SimpleHelpTopic.
268  * \p HelpText should satisfy the same criteria as for SimpleHelpTopic.
269  *
270  * \see SimpleHelpTopic
271  *
272  * \inlibraryapi
273  * \ingroup module_onlinehelp
274  */
275 template <class HelpText>
276 class CompositeHelpTopic : public AbstractCompositeHelpTopic
277 {
278     public:
279         virtual const char *name() const
280         {
281             return HelpText::name;
282         }
283         virtual const char *title() const
284         {
285             return HelpText::title;
286         }
287
288     protected:
289         virtual std::string helpText() const
290         {
291             return concatenateStrings(HelpText::text);
292         }
293 };
294
295 } // namespace gmx
296
297 #endif