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